lua-cli 3.0.0-alpha.1 → 3.0.0-alpha.11

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.
Files changed (66) hide show
  1. package/dist/api/chat.api.service.d.ts +8 -0
  2. package/dist/api/chat.api.service.js +55 -0
  3. package/dist/api/job.api.service.d.ts +16 -7
  4. package/dist/api/job.api.service.js +21 -5
  5. package/dist/api/postprocessor.api.service.d.ts +61 -1
  6. package/dist/api/postprocessor.api.service.js +35 -0
  7. package/dist/api/preprocessor.api.service.d.ts +61 -1
  8. package/dist/api/preprocessor.api.service.js +35 -0
  9. package/dist/api-exports.d.ts +27 -7
  10. package/dist/api-exports.js +48 -30
  11. package/dist/cli/command-definitions.js +13 -6
  12. package/dist/commands/chat.js +71 -39
  13. package/dist/commands/compile.js +16 -2
  14. package/dist/commands/dev.js +23 -2
  15. package/dist/commands/push.d.ts +3 -2
  16. package/dist/commands/push.js +536 -6
  17. package/dist/commands/test.js +18 -2
  18. package/dist/common/job.instance.d.ts +3 -0
  19. package/dist/common/job.instance.js +8 -0
  20. package/dist/config/constants.d.ts +6 -5
  21. package/dist/config/constants.js +12 -10
  22. package/dist/interfaces/chat.d.ts +30 -1
  23. package/dist/interfaces/jobs.d.ts +21 -0
  24. package/dist/services/auth.d.ts +8 -2
  25. package/dist/services/auth.js +35 -3
  26. package/dist/types/skill.d.ts +75 -56
  27. package/dist/types/skill.js +53 -59
  28. package/dist/utils/bundling.d.ts +13 -4
  29. package/dist/utils/bundling.js +83 -26
  30. package/dist/utils/compile.js +27 -6
  31. package/dist/utils/dev-api.d.ts +42 -2
  32. package/dist/utils/dev-api.js +177 -4
  33. package/dist/utils/dev-server.d.ts +1 -1
  34. package/dist/utils/dev-server.js +4 -4
  35. package/dist/utils/dynamic-job-bundler.d.ts +17 -0
  36. package/dist/utils/dynamic-job-bundler.js +143 -0
  37. package/dist/utils/pre-bundle-jobs.d.ts +26 -0
  38. package/dist/utils/pre-bundle-jobs.js +176 -0
  39. package/dist/utils/sandbox-storage.d.ts +48 -0
  40. package/dist/utils/sandbox-storage.js +114 -0
  41. package/dist/utils/sandbox.d.ts +2 -2
  42. package/dist/utils/sandbox.js +23 -8
  43. package/package.json +1 -1
  44. package/template/env.example +5 -0
  45. package/template/lua.skill.yaml +47 -0
  46. package/template/package-lock.json +10505 -0
  47. package/template/package.json +2 -1
  48. package/template/src/index.ts +65 -3
  49. package/template/src/tools/CreateInlineJob.ts +42 -0
  50. package/API_REFERENCE.md +0 -1408
  51. package/CHANGELOG.md +0 -236
  52. package/CLI_REFERENCE.md +0 -908
  53. package/GETTING_STARTED.md +0 -1040
  54. package/INSTANCE_TYPES.md +0 -1158
  55. package/README.md +0 -865
  56. package/TEMPLATE_GUIDE.md +0 -1398
  57. package/USER_DATA_INSTANCE.md +0 -621
  58. package/template/AGENT_CONFIGURATION.md +0 -251
  59. package/template/COMPLEX_JOB_EXAMPLES.md +0 -795
  60. package/template/DYNAMIC_JOB_CREATION.md +0 -371
  61. package/template/TOOL_EXAMPLES.md +0 -655
  62. package/template/WEBHOOKS_JOBS_QUICKSTART.md +0 -318
  63. package/template/WEBHOOK_JOB_EXAMPLES.md +0 -817
  64. package/template/src/index-agent-example.ts +0 -201
  65. package/template/src/postprocessors/ResponseFormatter.ts +0 -151
  66. package/template/src/preprocessors/MessageFilter.ts +0 -91
@@ -70,16 +70,23 @@ Examples:
70
70
  program
71
71
  .command("push [type]")
72
72
  .description("☁️ Push skill, webhook, job, or persona version to server")
73
+ .option('--force', 'Skip all confirmation prompts (auto-confirm)')
74
+ .option('--auto-deploy', 'Automatically deploy to production after push')
73
75
  .addHelpText('after', `
74
76
  Arguments:
75
- type Optional: 'skill', 'webhook', 'job', or 'persona' (prompts if not provided)
77
+ type Optional: 'skill', 'webhook', 'job', 'preprocessor', 'postprocessor', 'persona', or 'all' (prompts if not provided)
78
+
79
+ Options:
80
+ --force Skip all confirmation prompts
81
+ --auto-deploy Automatically deploy to production after push
76
82
 
77
83
  Examples:
78
- $ lua push Interactive selection
79
- $ lua push skill Push a skill directly
80
- $ lua push webhook Push a webhook directly
81
- $ lua push job Push a job directly
82
- $ lua push persona Push a persona directly
84
+ $ lua push Interactive selection
85
+ $ lua push skill Push a skill directly
86
+ $ lua push webhook Push a webhook directly
87
+ $ lua push job Push a job directly
88
+ $ lua push all --force Push all components from YAML without prompts
89
+ $ lua push all --force --auto-deploy Push and deploy all to production
83
90
  `)
84
91
  .action(pushCommand);
85
92
  program
@@ -8,8 +8,8 @@ import { loadApiKey, checkApiKey } from '../services/auth.js';
8
8
  import { readSkillConfig } from '../utils/files.js';
9
9
  import { withErrorHandling, writeProgress, writeSuccess } from '../utils/cli.js';
10
10
  import { compileCommand } from './compile.js';
11
- import { pushSkillsToSandbox } from '../utils/dev-api.js';
12
- import { getAllSandboxSkillIds } from '../utils/sandbox-storage.js';
11
+ import { pushSkillsToSandbox, pushProcessorsToSandbox } from '../utils/dev-api.js';
12
+ import { getAllSandboxSkillIds, getAllSandboxPreProcessorIds, getAllSandboxPostProcessorIds } from '../utils/sandbox-storage.js';
13
13
  import ChatApi from '../api/chat.api.service.js';
14
14
  import { BASE_URLS } from '../config/constants.js';
15
15
  import { readDeployJson, validateConfig, validateDeployData, validateAgentConfig, } from '../utils/dev-helpers.js';
@@ -66,7 +66,7 @@ export async function chatCommand() {
66
66
  }, "chat");
67
67
  }
68
68
  /**
69
- * Sets up the sandbox environment by compiling and pushing skills
69
+ * Sets up the sandbox environment by compiling and pushing skills, preprocessors, and postprocessors
70
70
  */
71
71
  async function setupSandboxEnvironment(chatEnv, config) {
72
72
  writeProgress("🔄 Setting up sandbox environment...");
@@ -84,8 +84,31 @@ async function setupSandboxEnvironment(chatEnv, config) {
84
84
  process.exit(1);
85
85
  }
86
86
  writeSuccess(`✅ Pushed ${Object.keys(sandboxIds).length} skills to sandbox`);
87
+ // Push preprocessors and postprocessors to sandbox
88
+ const fs = await import('fs');
89
+ const path = await import('path');
90
+ const preprocessorsPath = path.join(process.cwd(), 'dist', 'preprocessors.json');
91
+ const postprocessorsPath = path.join(process.cwd(), 'dist', 'postprocessors.json');
92
+ let bundledPreProcessors = [];
93
+ let bundledPostProcessors = [];
94
+ if (fs.existsSync(preprocessorsPath)) {
95
+ bundledPreProcessors = JSON.parse(fs.readFileSync(preprocessorsPath, 'utf8'));
96
+ }
97
+ if (fs.existsSync(postprocessorsPath)) {
98
+ bundledPostProcessors = JSON.parse(fs.readFileSync(postprocessorsPath, 'utf8'));
99
+ }
100
+ if (bundledPreProcessors.length > 0 || bundledPostProcessors.length > 0) {
101
+ writeProgress("🔄 Pushing processors to sandbox...");
102
+ const processorCounts = await pushProcessorsToSandbox(chatEnv.apiKey, chatEnv.agentId, config, bundledPreProcessors, bundledPostProcessors, true);
103
+ if (processorCounts.preprocessors > 0 || processorCounts.postprocessors > 0) {
104
+ writeSuccess(`✅ Pushed ${processorCounts.preprocessors} preprocessor(s) and ${processorCounts.postprocessors} postprocessor(s) to sandbox`);
105
+ }
106
+ }
87
107
  // Store deploy data for skill overrides
88
108
  chatEnv.deployData = deployData;
109
+ // Get processor overrides for sandbox
110
+ chatEnv.preprocessorOverrides = await getAllSandboxPreProcessorIds(config);
111
+ chatEnv.postprocessorOverrides = await getAllSandboxPostProcessorIds(config);
89
112
  // Check for persona in config
90
113
  if (config.agent?.persona) {
91
114
  chatEnv.persona = config.agent.persona;
@@ -100,8 +123,10 @@ async function startChatLoop(chatEnv) {
100
123
  console.log(`Environment: ${chatEnv.type === 'sandbox' ? '🔧 Sandbox' : '🚀 Production'}`);
101
124
  console.log("Press Ctrl+C to exit");
102
125
  console.log("=".repeat(60) + "\n");
103
- // Welcome message
104
- console.log("🌙 Assistant: Hi there! How can I help you today?\n");
126
+ // Welcome message from config or default
127
+ const config = readSkillConfig();
128
+ const welcomeMessage = config?.agent?.welcomeMessage || "Hi there! How can I help you today?";
129
+ console.log(`🌙 Assistant: ${welcomeMessage}\n`);
105
130
  // Create readline interface
106
131
  const rl = readline.createInterface({
107
132
  input: process.stdin,
@@ -123,28 +148,41 @@ async function startChatLoop(chatEnv) {
123
148
  rl.prompt();
124
149
  return;
125
150
  }
151
+ // Start typing indicator
152
+ const typingInterval = startTypingIndicator();
153
+ let firstChunk = true;
126
154
  try {
127
- // Show typing indicator with animated dots
128
- const typingInterval = startTypingIndicator();
129
- let response = null;
155
+ // Create a callback that stops typing on first chunk
156
+ const handleChunk = (chunk) => {
157
+ if (firstChunk) {
158
+ // Stop typing indicator and show assistant label
159
+ stopTypingIndicator(typingInterval);
160
+ process.stdout.write('🌙 Assistant: ');
161
+ firstChunk = false;
162
+ }
163
+ // Write the chunk immediately
164
+ process.stdout.write(chunk);
165
+ };
130
166
  if (chatEnv.type === 'sandbox') {
131
- // Send to sandbox with skill overrides
132
- response = await sendSandboxMessage(chatEnv, message);
167
+ // Send to sandbox with skill overrides (streaming)
168
+ await sendSandboxMessageStream(chatEnv, message, handleChunk);
133
169
  }
134
170
  else {
135
- // Send to production
136
- response = await sendProductionMessage(chatEnv, message);
171
+ // Send to production (streaming)
172
+ await sendProductionMessageStream(chatEnv, message, handleChunk);
137
173
  }
138
- // Stop typing indicator
139
- stopTypingIndicator(typingInterval);
140
- if (response) {
141
- console.log(`🌙 Assistant: ${response}\n`);
142
- }
143
- else {
144
- console.log("🌙 Assistant: ❌ Failed to get response. Please try again.\n");
174
+ // If no chunks arrived, stop the typing indicator
175
+ if (firstChunk) {
176
+ stopTypingIndicator(typingInterval);
145
177
  }
178
+ // Add newline after response
179
+ console.log('\n');
146
180
  }
147
181
  catch (error) {
182
+ // Make sure typing indicator is stopped on error
183
+ if (firstChunk) {
184
+ stopTypingIndicator(typingInterval);
185
+ }
148
186
  console.error(`\n❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}\n`);
149
187
  }
150
188
  rl.prompt();
@@ -179,16 +217,16 @@ function stopTypingIndicator(interval) {
179
217
  process.stdout.write('\r\x1b[K');
180
218
  }
181
219
  /**
182
- * Sends a message to the sandbox environment with skill overrides
220
+ * Sends a message to the sandbox environment with skill overrides (streaming)
183
221
  */
184
- async function sendSandboxMessage(chatEnv, message) {
222
+ async function sendSandboxMessageStream(chatEnv, message, onChunk) {
185
223
  if (!chatEnv.deployData) {
186
- return "Sandbox environment not properly initialized.";
224
+ throw new Error("Sandbox environment not properly initialized.");
187
225
  }
188
226
  // Get all sandbox skill IDs for skill override
189
227
  const allSkillOverrides = await getAllSandboxSkillIds(chatEnv.deployData);
190
228
  if (allSkillOverrides.length === 0) {
191
- return "No sandbox skills found. Please try running the command again.";
229
+ throw new Error("No sandbox skills found. Please try running the command again.");
192
230
  }
193
231
  const chatRequest = {
194
232
  messages: [
@@ -198,24 +236,21 @@ async function sendSandboxMessage(chatEnv, message) {
198
236
  }
199
237
  ],
200
238
  navigate: true,
201
- skillOverride: allSkillOverrides
239
+ skillOverride: allSkillOverrides,
240
+ preprocessorOverride: chatEnv.preprocessorOverrides || [],
241
+ postprocessorOverride: chatEnv.postprocessorOverrides || []
202
242
  };
203
243
  // Add persona override if available
204
244
  if (chatEnv.persona) {
205
245
  chatRequest.personaOverride = chatEnv.persona;
206
246
  }
207
247
  const chatApi = new ChatApi(BASE_URLS.CHAT, chatEnv.apiKey);
208
- const response = await chatApi.sendMessage(chatEnv.agentId, chatRequest);
209
- if (!response.success) {
210
- console.error(`❌ Chat API error: ${response.error?.message || 'Unknown error'}`);
211
- return null;
212
- }
213
- return response.data?.text || null;
248
+ await chatApi.sendMessageStream(chatEnv.agentId, chatRequest, onChunk);
214
249
  }
215
250
  /**
216
- * Sends a message to the production environment
251
+ * Sends a message to the production environment (streaming)
217
252
  */
218
- async function sendProductionMessage(chatEnv, message) {
253
+ async function sendProductionMessageStream(chatEnv, message, onChunk) {
219
254
  const chatRequest = {
220
255
  messages: [
221
256
  {
@@ -224,13 +259,10 @@ async function sendProductionMessage(chatEnv, message) {
224
259
  }
225
260
  ],
226
261
  navigate: true,
227
- skillOverride: []
262
+ skillOverride: [],
263
+ preprocessorOverride: [],
264
+ postprocessorOverride: []
228
265
  };
229
266
  const chatApi = new ChatApi(BASE_URLS.CHAT, chatEnv.apiKey);
230
- const response = await chatApi.sendMessage(chatEnv.agentId, chatRequest);
231
- if (!response.success) {
232
- console.error(`❌ Chat API error: ${response.error?.message || 'Unknown error'}`);
233
- return null;
234
- }
235
- return response.data?.text || null;
267
+ await chatApi.sendMessageStream(chatEnv.agentId, chatRequest, onChunk);
236
268
  }
@@ -78,9 +78,23 @@ export async function compileCommand() {
78
78
  const tools = await detectTools(indexFile, project, skillFilePaths);
79
79
  writeProgress(`📦 Found ${tools.length} tools to bundle...`);
80
80
  // Step 3: Bundle each tool and extract metadata
81
+ const { preBundleJobsInSource, replaceJobPlaceholders } = await import('../utils/pre-bundle-jobs.js');
81
82
  for (const tool of tools) {
82
- await bundleTool(tool, distDir);
83
- await extractExecuteCode(tool, project);
83
+ // Step 3a: Pre-bundle any Jobs.create() in the tool source
84
+ const { modifiedSource, jobBundles } = await preBundleJobsInSource(tool.filePath, project, distDir);
85
+ // Step 3b: Bundle the tool (with placeholders for job execute functions)
86
+ await bundleTool(tool, distDir, modifiedSource);
87
+ // Step 3c: Replace placeholders in the bundled tool file
88
+ if (jobBundles.size > 0) {
89
+ const toolBundlePath = path.join(distDir, 'tools', `${tool.className}.js`);
90
+ if (fs.existsSync(toolBundlePath)) {
91
+ let bundledToolCode = fs.readFileSync(toolBundlePath, 'utf8');
92
+ bundledToolCode = replaceJobPlaceholders(bundledToolCode, jobBundles);
93
+ fs.writeFileSync(toolBundlePath, bundledToolCode);
94
+ }
95
+ }
96
+ // Step 3d: Extract execute code
97
+ await extractExecuteCode(tool, project, distDir);
84
98
  }
85
99
  // Step 4: Bundle the main index file
86
100
  await bundleMainIndex(indexPath, distDir);
@@ -7,7 +7,7 @@ import { compileCommand } from './compile.js';
7
7
  import { checkApiKey, loadApiKey } from '../services/auth.js';
8
8
  import { readSkillConfig } from '../utils/files.js';
9
9
  import { withErrorHandling, writeProgress, writeSuccess } from '../utils/cli.js';
10
- import { pushSkillsToSandbox } from '../utils/dev-api.js';
10
+ import { pushSkillsToSandbox, pushProcessorsToSandbox } from '../utils/dev-api.js';
11
11
  import { createChatServer } from '../utils/dev-server.js';
12
12
  import { createFileWatcher } from '../utils/dev-watcher.js';
13
13
  import { readConfigVersion, readDeployJson, extractSkillId, validateConfig, validateDeployData, validateAgentConfig, } from '../utils/dev-helpers.js';
@@ -75,6 +75,26 @@ export async function devCommand() {
75
75
  process.exit(1);
76
76
  }
77
77
  writeSuccess(`✅ Pushed ${Object.keys(sandboxIds).length} skills to sandbox`);
78
+ // Step 6b: Push preprocessors and postprocessors to sandbox
79
+ const fs = await import('fs');
80
+ const path = await import('path');
81
+ const preprocessorsPath = path.join(process.cwd(), 'dist', 'preprocessors.json');
82
+ const postprocessorsPath = path.join(process.cwd(), 'dist', 'postprocessors.json');
83
+ let bundledPreProcessors = [];
84
+ let bundledPostProcessors = [];
85
+ if (fs.existsSync(preprocessorsPath)) {
86
+ bundledPreProcessors = JSON.parse(fs.readFileSync(preprocessorsPath, 'utf8'));
87
+ }
88
+ if (fs.existsSync(postprocessorsPath)) {
89
+ bundledPostProcessors = JSON.parse(fs.readFileSync(postprocessorsPath, 'utf8'));
90
+ }
91
+ if (bundledPreProcessors.length > 0 || bundledPostProcessors.length > 0) {
92
+ writeProgress("🔄 Pushing processors to sandbox...");
93
+ const processorCounts = await pushProcessorsToSandbox(apiKey, agentId, updatedConfig, bundledPreProcessors, bundledPostProcessors, true);
94
+ if (processorCounts.preprocessors > 0 || processorCounts.postprocessors > 0) {
95
+ writeSuccess(`✅ Pushed ${processorCounts.preprocessors} preprocessor(s) and ${processorCounts.postprocessors} postprocessor(s) to sandbox`);
96
+ }
97
+ }
78
98
  // Use the first skill's sandbox ID for the web interface
79
99
  const firstSkillName = Object.keys(sandboxIds)[0];
80
100
  const sandboxSkillId = sandboxIds[firstSkillName];
@@ -83,7 +103,8 @@ export async function devCommand() {
83
103
  process.exit(1);
84
104
  }
85
105
  // Step 7: Start web server for chat interface
86
- const { server, wss, broadcastLog } = createChatServer(apiKey, agentId, skillId, sandboxSkillId, DEV_SERVER_PORT);
106
+ const { server, wss, broadcastLog } = createChatServer(apiKey, agentId, skillId, sandboxSkillId, DEV_SERVER_PORT, updatedConfig // Pass config for processor overrides
107
+ );
87
108
  // Step 8: Open browser to chat interface
88
109
  try {
89
110
  await open(`http://localhost:${DEV_SERVER_PORT}`);
@@ -17,7 +17,8 @@
17
17
  *
18
18
  * Note: This does NOT deploy to production. Use `lua deploy` for that.
19
19
  *
20
- * @param type - Optional type argument ('skill' or 'persona')
20
+ * @param type - Optional type argument ('skill', 'persona', 'webhook', 'job', 'preprocessor', 'postprocessor', or 'all')
21
+ * @param cmdObj - Commander command object with options
21
22
  * @returns Promise that resolves when push completes
22
23
  */
23
- export declare function pushCommand(type?: string): Promise<void>;
24
+ export declare function pushCommand(type?: string, cmdObj?: any): Promise<void>;