lua-cli 2.3.0 → 2.4.0

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 (56) hide show
  1. package/dist/api/products.api.service.js +1 -0
  2. package/dist/cli/command-definitions.d.ts +0 -8
  3. package/dist/cli/command-definitions.js +51 -18
  4. package/dist/commands/chat.d.ts +17 -0
  5. package/dist/commands/chat.js +236 -0
  6. package/dist/commands/chatClear.d.ts +15 -0
  7. package/dist/commands/chatClear.js +75 -0
  8. package/dist/commands/deploy.d.ts +7 -5
  9. package/dist/commands/deploy.js +34 -15
  10. package/dist/commands/env.d.ts +19 -0
  11. package/dist/commands/env.js +434 -0
  12. package/dist/commands/index.d.ts +6 -0
  13. package/dist/commands/index.js +6 -0
  14. package/dist/commands/init.js +6 -6
  15. package/dist/commands/persona.d.ts +15 -0
  16. package/dist/commands/persona.js +503 -0
  17. package/dist/commands/production.d.ts +15 -0
  18. package/dist/commands/production.js +532 -0
  19. package/dist/commands/push.d.ts +7 -5
  20. package/dist/commands/push.js +100 -21
  21. package/dist/commands/resources.d.ts +17 -0
  22. package/dist/commands/resources.js +361 -0
  23. package/dist/common/data.entry.instance.js +6 -2
  24. package/dist/common/http.client.js +7 -0
  25. package/dist/config/compile.constants.d.ts +4 -3
  26. package/dist/config/compile.constants.js +3 -7
  27. package/dist/config/constants.d.ts +6 -0
  28. package/dist/config/constants.js +11 -0
  29. package/dist/errors/auth.error.d.ts +15 -0
  30. package/dist/errors/auth.error.js +27 -0
  31. package/dist/errors/index.d.ts +4 -0
  32. package/dist/errors/index.js +4 -0
  33. package/dist/index.d.ts +0 -9
  34. package/dist/index.js +30 -11
  35. package/dist/interfaces/agent.d.ts +33 -49
  36. package/dist/services/auth.d.ts +1 -2
  37. package/dist/services/auth.js +3 -4
  38. package/dist/utils/bundling.js +61 -0
  39. package/dist/utils/cli.js +6 -0
  40. package/dist/utils/deploy-helpers.d.ts +22 -0
  41. package/dist/utils/deploy-helpers.js +61 -2
  42. package/dist/utils/deployment.js +33 -1
  43. package/dist/utils/dev-server.js +255 -0
  44. package/dist/utils/init-agent.js +3 -3
  45. package/dist/utils/prompt-handler.d.ts +12 -0
  46. package/dist/utils/prompt-handler.js +31 -0
  47. package/dist/utils/push-helpers.d.ts +47 -3
  48. package/dist/utils/push-helpers.js +167 -10
  49. package/dist/utils/sandbox.js +18 -5
  50. package/dist/web/app.css +1302 -465
  51. package/dist/web/app.js +53 -46
  52. package/package.json +1 -1
  53. package/template/package.json +1 -1
  54. package/template/src/tools/BasketTool.ts +4 -1
  55. package/template/src/tools/ProductsTool.ts +7 -7
  56. package/dist/web/tools-page.css +0 -381
@@ -5,19 +5,23 @@
5
5
  import { compileCommand } from './compile.js';
6
6
  import { checkApiKey, loadApiKey } from '../services/auth.js';
7
7
  import { readSkillConfig } from '../utils/files.js';
8
- import { withErrorHandling, writeProgress, writeSuccess } from '../utils/cli.js';
9
- import { readDeployJson, confirmVersionPush, validatePushConfig, validateDeployData, } from '../utils/push-helpers.js';
8
+ import { withErrorHandling, writeProgress, writeSuccess, writeInfo } from '../utils/cli.js';
9
+ import { safePrompt } from '../utils/prompt-handler.js';
10
+ import { readDeployJson, validatePushConfig, validateDeployData, promptSkillSelection, promptVersionConfirmOrUpdate, getAvailableSkills, updateSkillVersionInYaml, getSkillDeployData, } from '../utils/push-helpers.js';
10
11
  import { pushVersion } from '../utils/push-api.js';
12
+ import { fetchVersions, publishVersion, } from '../utils/deploy-api.js';
11
13
  /**
12
14
  * Main push command - pushes a skill version to the server.
13
15
  *
14
16
  * This command performs the following steps:
15
17
  * 1. Validates configuration has required fields
16
- * 2. Prompts for user confirmation
17
- * 3. Authenticates the user
18
- * 4. Compiles the skill
19
- * 5. Validates deploy.json matches configuration
20
- * 6. Pushes version to server
18
+ * 2. Prompts user to select a skill (if multiple skills exist)
19
+ * 3. Prompts to confirm or update version
20
+ * 4. Authenticates the user
21
+ * 5. Compiles the skill (always, to ensure deploy.json is current)
22
+ * 6. Validates deploy.json matches configuration for selected skill
23
+ * 7. Extracts the specific skill's deploy data
24
+ * 8. Pushes version to server
21
25
  *
22
26
  * Use this command to:
23
27
  * - Upload a new version of your skill
@@ -33,14 +37,33 @@ export async function pushCommand() {
33
37
  // Step 1: Validate configuration
34
38
  const config = readSkillConfig();
35
39
  validatePushConfig(config);
36
- const version = config.skill.version;
37
- // Step 2: Confirm with user
38
- const confirmed = await confirmVersionPush(version);
39
- if (!confirmed) {
40
- console.log("❌ Push cancelled.");
41
- process.exit(0);
40
+ // Step 2: Get available skills and prompt for selection
41
+ const availableSkills = getAvailableSkills(config);
42
+ if (availableSkills.length === 0) {
43
+ console.error("❌ No skills found in configuration. Please compile your skill first using 'lua compile'.");
44
+ process.exit(1);
45
+ }
46
+ let selectedSkill;
47
+ if (availableSkills.length === 1) {
48
+ // Only one skill, use it automatically
49
+ selectedSkill = availableSkills[0];
50
+ writeInfo(`📦 Pushing skill: ${selectedSkill.name}`);
51
+ }
52
+ else {
53
+ // Multiple skills, prompt for selection
54
+ selectedSkill = await promptSkillSelection(availableSkills);
55
+ writeInfo(`📦 Selected skill: ${selectedSkill.name}`);
56
+ }
57
+ // Step 3: Confirm or update version
58
+ const confirmedVersion = await promptVersionConfirmOrUpdate(selectedSkill.version);
59
+ let versionUpdated = false;
60
+ if (confirmedVersion !== selectedSkill.version) {
61
+ writeInfo(`📝 Updating version from ${selectedSkill.version} to ${confirmedVersion}`);
62
+ updateSkillVersionInYaml(selectedSkill.name, confirmedVersion);
63
+ selectedSkill.version = confirmedVersion;
64
+ versionUpdated = true;
42
65
  }
43
- // Step 3: Authenticate
66
+ // Step 4: Authenticate
44
67
  const apiKey = await loadApiKey();
45
68
  if (!apiKey) {
46
69
  console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
@@ -48,19 +71,33 @@ export async function pushCommand() {
48
71
  }
49
72
  const userData = await checkApiKey(apiKey);
50
73
  writeProgress("✅ Authenticated");
51
- // Step 4: Compile the skill
74
+ // Step 5: Compile the skill (always compile to ensure up-to-date, or if version was updated)
52
75
  writeProgress("🔄 Compiling skill...");
53
76
  await compileCommand();
54
- // Step 5: Validate deploy data
77
+ // Step 6: Validate deploy data for the selected skill
55
78
  const deployData = readDeployJson();
56
- validateDeployData(deployData, version);
57
- // Step 6: Push version to server
79
+ validateDeployData(deployData, selectedSkill);
80
+ // Step 7: Extract the specific skill's deploy data
81
+ const skillDeployData = getSkillDeployData(deployData, selectedSkill.name);
82
+ // Step 8: Push version to server
58
83
  const agentId = config.agent.agentId;
59
- const skillId = config.skill.skillId;
84
+ const skillId = selectedSkill.skillId;
60
85
  writeProgress("🔄 Pushing version to server...");
61
- const result = await pushVersion(apiKey, agentId, skillId, deployData);
86
+ const result = await pushVersion(apiKey, agentId, skillId, skillDeployData);
62
87
  if (result.success && result.data) {
63
- writeSuccess(`✅ Version ${result.data.version} pushed successfully`);
88
+ writeSuccess(`✅ Version ${result.data.version} of "${selectedSkill.name}" pushed successfully`);
89
+ // Ask if user wants to deploy now
90
+ const deployAnswer = await safePrompt([
91
+ {
92
+ type: 'confirm',
93
+ name: 'deployNow',
94
+ message: 'Would you like to deploy this version to production now?',
95
+ default: false
96
+ }
97
+ ]);
98
+ if (deployAnswer && deployAnswer.deployNow) {
99
+ await deployVersionAfterPush(apiKey, config.agent.agentId, selectedSkill, result.data.version);
100
+ }
64
101
  }
65
102
  else if (result.error) {
66
103
  console.error(`❌ ${result.error.message}`);
@@ -72,3 +109,45 @@ export async function pushCommand() {
72
109
  }
73
110
  }, "push");
74
111
  }
112
+ /**
113
+ * Deploy a version immediately after pushing
114
+ */
115
+ async function deployVersionAfterPush(apiKey, agentId, selectedSkill, pushedVersion) {
116
+ try {
117
+ writeProgress("\n🔄 Fetching available versions...");
118
+ // Fetch versions to verify the pushed version exists
119
+ const versionsResponse = await fetchVersions(apiKey, agentId, selectedSkill.skillId);
120
+ if (!versionsResponse.versions || versionsResponse.versions.length === 0) {
121
+ console.error("❌ No versions available. The push may have failed.");
122
+ return;
123
+ }
124
+ // Show warning
125
+ console.log("\n⚠️ WARNING: You are about to deploy to PRODUCTION!");
126
+ console.log("⚠️ This will affect ALL users immediately.\n");
127
+ const confirmAnswer = await safePrompt([
128
+ {
129
+ type: 'confirm',
130
+ name: 'confirm',
131
+ message: 'Are you absolutely sure you want to deploy?',
132
+ default: false
133
+ }
134
+ ]);
135
+ if (!confirmAnswer || !confirmAnswer.confirm) {
136
+ console.log("\n❌ Deployment cancelled. Version pushed but not deployed.\n");
137
+ return;
138
+ }
139
+ // Find the pushed version in the list
140
+ const versionToDeploy = versionsResponse.versions.find((v) => v.version === pushedVersion);
141
+ if (!versionToDeploy) {
142
+ console.error(`\n❌ Version ${pushedVersion} not found in available versions.\n`);
143
+ return;
144
+ }
145
+ writeProgress("🔄 Publishing version...");
146
+ const publishResponse = await publishVersion(apiKey, agentId, selectedSkill.skillId, pushedVersion);
147
+ writeSuccess(`\n✅ Version ${pushedVersion} of "${selectedSkill.name}" deployed successfully to production\n`);
148
+ }
149
+ catch (error) {
150
+ console.error('\n❌ Error deploying version:', error);
151
+ console.log('💡 You can deploy later using: lua deploy\n');
152
+ }
153
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Resources Command
3
+ * Manages agent resources (knowledge base documents)
4
+ */
5
+ /**
6
+ * Main resources command - manages agent resources
7
+ *
8
+ * Features:
9
+ * - List all resources
10
+ * - Create new resources
11
+ * - Update existing resources
12
+ * - Delete resources
13
+ * - View resource content
14
+ *
15
+ * @returns Promise that resolves when command completes
16
+ */
17
+ export declare function resourcesCommand(): Promise<void>;
@@ -0,0 +1,361 @@
1
+ /**
2
+ * Resources Command
3
+ * Manages agent resources (knowledge base documents)
4
+ */
5
+ import { loadApiKey, checkApiKey } from '../services/auth.js';
6
+ import { readSkillConfig } from '../utils/files.js';
7
+ import { withErrorHandling, writeProgress, writeSuccess } from '../utils/cli.js';
8
+ import { BASE_URLS } from '../config/constants.js';
9
+ import { safePrompt } from '../utils/prompt-handler.js';
10
+ import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
11
+ /**
12
+ * Main resources command - manages agent resources
13
+ *
14
+ * Features:
15
+ * - List all resources
16
+ * - Create new resources
17
+ * - Update existing resources
18
+ * - Delete resources
19
+ * - View resource content
20
+ *
21
+ * @returns Promise that resolves when command completes
22
+ */
23
+ export async function resourcesCommand() {
24
+ return withErrorHandling(async () => {
25
+ // Step 1: Load configuration
26
+ const config = readSkillConfig();
27
+ validateConfig(config);
28
+ validateAgentConfig(config);
29
+ const agentId = config.agent.agentId;
30
+ // Step 2: Authenticate
31
+ const apiKey = await loadApiKey();
32
+ if (!apiKey) {
33
+ console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
34
+ process.exit(1);
35
+ }
36
+ await checkApiKey(apiKey);
37
+ writeProgress("✅ Authenticated");
38
+ const context = {
39
+ agentId,
40
+ apiKey,
41
+ };
42
+ // Step 3: Start management loop
43
+ await manageResources(context);
44
+ }, "resources");
45
+ }
46
+ /**
47
+ * Main resources management loop
48
+ */
49
+ async function manageResources(context) {
50
+ let continueManaging = true;
51
+ while (continueManaging) {
52
+ // Load current resources
53
+ const resources = await loadResources(context);
54
+ console.log("\n" + "=".repeat(60));
55
+ console.log("📚 Agent Resources");
56
+ console.log("=".repeat(60) + "\n");
57
+ if (resources.length === 0) {
58
+ console.log("ℹ️ No resources configured.\n");
59
+ console.log("💡 Resources are knowledge base documents your agent can reference.\n");
60
+ }
61
+ else {
62
+ resources.forEach((resource, index) => {
63
+ const preview = resource.content.length > 60
64
+ ? resource.content.substring(0, 60) + '...'
65
+ : resource.content;
66
+ console.log(`${index + 1}. ${resource.name}`);
67
+ console.log(` Preview: ${preview}`);
68
+ console.log();
69
+ });
70
+ }
71
+ const actionAnswer = await safePrompt([
72
+ {
73
+ type: 'list',
74
+ name: 'action',
75
+ message: 'What would you like to do?',
76
+ choices: [
77
+ { name: '➕ Create new resource', value: 'create' },
78
+ { name: '✏️ Update existing resource', value: 'update' },
79
+ { name: '🗑️ Delete resource', value: 'delete' },
80
+ { name: '👁️ View resource content', value: 'view' },
81
+ { name: '🔄 Refresh list', value: 'refresh' },
82
+ { name: '❌ Exit', value: 'exit' }
83
+ ]
84
+ }
85
+ ]);
86
+ if (!actionAnswer)
87
+ return;
88
+ const { action } = actionAnswer;
89
+ switch (action) {
90
+ case 'create':
91
+ await createResource(context);
92
+ break;
93
+ case 'update':
94
+ await updateResource(context, resources);
95
+ break;
96
+ case 'delete':
97
+ await deleteResource(context, resources);
98
+ break;
99
+ case 'view':
100
+ await viewResource(resources);
101
+ break;
102
+ case 'refresh':
103
+ // Just loop again
104
+ break;
105
+ case 'exit':
106
+ continueManaging = false;
107
+ console.log("\n👋 Goodbye!\n");
108
+ break;
109
+ }
110
+ }
111
+ }
112
+ /**
113
+ * Load resources from API
114
+ */
115
+ async function loadResources(context) {
116
+ try {
117
+ const response = await fetch(`${BASE_URLS.API}/admin/agents/${context.agentId}/resources`, {
118
+ method: 'GET',
119
+ headers: {
120
+ 'accept': 'application/json',
121
+ 'Authorization': `Bearer ${context.apiKey}`
122
+ }
123
+ });
124
+ if (!response.ok) {
125
+ return [];
126
+ }
127
+ const data = await response.json();
128
+ if (Array.isArray(data)) {
129
+ return data;
130
+ }
131
+ else if (data.data && Array.isArray(data.data)) {
132
+ return data.data;
133
+ }
134
+ return [];
135
+ }
136
+ catch (error) {
137
+ console.error('⚠️ Error loading resources');
138
+ return [];
139
+ }
140
+ }
141
+ /**
142
+ * Create a new resource
143
+ */
144
+ async function createResource(context) {
145
+ const answers = await safePrompt([
146
+ {
147
+ type: 'input',
148
+ name: 'name',
149
+ message: 'Resource name:',
150
+ validate: (input) => {
151
+ if (!input.trim())
152
+ return 'Resource name is required';
153
+ return true;
154
+ }
155
+ },
156
+ {
157
+ type: 'editor',
158
+ name: 'content',
159
+ message: 'Resource content (will open in your default editor):',
160
+ validate: (input) => {
161
+ if (!input.trim())
162
+ return 'Resource content cannot be empty';
163
+ return true;
164
+ }
165
+ }
166
+ ]);
167
+ if (!answers)
168
+ return;
169
+ writeProgress("🔄 Creating resource...");
170
+ try {
171
+ const response = await fetch(`${BASE_URLS.API}/admin/agents/${context.agentId}/resources`, {
172
+ method: 'POST',
173
+ headers: {
174
+ 'accept': 'application/json',
175
+ 'Authorization': `Bearer ${context.apiKey}`,
176
+ 'Content-Type': 'application/json'
177
+ },
178
+ body: JSON.stringify({
179
+ name: answers.name.trim(),
180
+ content: answers.content.trim()
181
+ })
182
+ });
183
+ if (!response.ok) {
184
+ const errorText = await response.text();
185
+ throw new Error(`HTTP error! status: ${response.status} - ${errorText}`);
186
+ }
187
+ writeSuccess(`✅ Resource "${answers.name}" created successfully`);
188
+ }
189
+ catch (error) {
190
+ console.error('❌ Error creating resource:', error);
191
+ }
192
+ }
193
+ /**
194
+ * Update an existing resource
195
+ */
196
+ async function updateResource(context, resources) {
197
+ if (resources.length === 0) {
198
+ console.log("\nℹ️ No resources to update.\n");
199
+ return;
200
+ }
201
+ const selectAnswer = await safePrompt([
202
+ {
203
+ type: 'list',
204
+ name: 'selectedId',
205
+ message: 'Select resource to update:',
206
+ choices: resources.map(r => ({
207
+ name: r.name,
208
+ value: r.id
209
+ }))
210
+ }
211
+ ]);
212
+ if (!selectAnswer)
213
+ return;
214
+ const selectedResource = resources.find(r => r.id === selectAnswer.selectedId);
215
+ const updateAnswers = await safePrompt([
216
+ {
217
+ type: 'input',
218
+ name: 'name',
219
+ message: 'Resource name:',
220
+ default: selectedResource.name,
221
+ validate: (input) => {
222
+ if (!input.trim())
223
+ return 'Resource name is required';
224
+ return true;
225
+ }
226
+ },
227
+ {
228
+ type: 'editor',
229
+ name: 'content',
230
+ message: 'Resource content (will open in your default editor):',
231
+ default: selectedResource.content,
232
+ validate: (input) => {
233
+ if (!input.trim())
234
+ return 'Resource content cannot be empty';
235
+ return true;
236
+ }
237
+ }
238
+ ]);
239
+ if (!updateAnswers)
240
+ return;
241
+ writeProgress("🔄 Updating resource...");
242
+ try {
243
+ const response = await fetch(`${BASE_URLS.API}/admin/agents/${context.agentId}/resources/${selectAnswer.selectedId}`, {
244
+ method: 'PUT',
245
+ headers: {
246
+ 'accept': 'application/json',
247
+ 'Authorization': `Bearer ${context.apiKey}`,
248
+ 'Content-Type': 'application/json'
249
+ },
250
+ body: JSON.stringify({
251
+ name: updateAnswers.name.trim(),
252
+ content: updateAnswers.content.trim()
253
+ })
254
+ });
255
+ if (!response.ok) {
256
+ const errorText = await response.text();
257
+ throw new Error(`HTTP error! status: ${response.status} - ${errorText}`);
258
+ }
259
+ writeSuccess(`✅ Resource "${updateAnswers.name}" updated successfully`);
260
+ }
261
+ catch (error) {
262
+ console.error('❌ Error updating resource:', error);
263
+ }
264
+ }
265
+ /**
266
+ * Delete a resource
267
+ */
268
+ async function deleteResource(context, resources) {
269
+ if (resources.length === 0) {
270
+ console.log("\nℹ️ No resources to delete.\n");
271
+ return;
272
+ }
273
+ const selectAnswer = await safePrompt([
274
+ {
275
+ type: 'list',
276
+ name: 'selectedId',
277
+ message: 'Select resource to delete:',
278
+ choices: resources.map(r => ({
279
+ name: r.name,
280
+ value: r.id
281
+ }))
282
+ }
283
+ ]);
284
+ if (!selectAnswer)
285
+ return;
286
+ const selectedResource = resources.find(r => r.id === selectAnswer.selectedId);
287
+ const confirmAnswer = await safePrompt([
288
+ {
289
+ type: 'confirm',
290
+ name: 'confirm',
291
+ message: `Are you sure you want to delete "${selectedResource.name}"?`,
292
+ default: false
293
+ }
294
+ ]);
295
+ if (!confirmAnswer || !confirmAnswer.confirm) {
296
+ console.log("\nℹ️ Deletion cancelled.\n");
297
+ return;
298
+ }
299
+ writeProgress("🔄 Deleting resource...");
300
+ try {
301
+ const response = await fetch(`${BASE_URLS.API}/admin/agents/${context.agentId}/resources/${selectAnswer.selectedId}`, {
302
+ method: 'DELETE',
303
+ headers: {
304
+ 'accept': '*/*',
305
+ 'Authorization': `Bearer ${context.apiKey}`
306
+ }
307
+ });
308
+ if (!response.ok) {
309
+ const errorText = await response.text();
310
+ throw new Error(`HTTP error! status: ${response.status} - ${errorText}`);
311
+ }
312
+ writeSuccess(`✅ Resource "${selectedResource.name}" deleted successfully`);
313
+ }
314
+ catch (error) {
315
+ console.error('❌ Error deleting resource:', error);
316
+ }
317
+ }
318
+ /**
319
+ * View a resource's full content
320
+ */
321
+ async function viewResource(resources) {
322
+ if (resources.length === 0) {
323
+ console.log("\nℹ️ No resources to view.\n");
324
+ return;
325
+ }
326
+ const selectAnswer = await safePrompt([
327
+ {
328
+ type: 'list',
329
+ name: 'selectedId',
330
+ message: 'Select resource to view:',
331
+ choices: resources.map(r => ({
332
+ name: r.name,
333
+ value: r.id
334
+ }))
335
+ }
336
+ ]);
337
+ if (!selectAnswer)
338
+ return;
339
+ const resource = resources.find(r => r.id === selectAnswer.selectedId);
340
+ console.log("\n" + "=".repeat(60));
341
+ console.log(`📄 Resource: ${resource.name}`);
342
+ console.log("=".repeat(60));
343
+ if (resource.createdAt) {
344
+ const date = new Date(resource.createdAt);
345
+ console.log(`Created: ${date.toLocaleString()}`);
346
+ }
347
+ if (resource.updatedAt) {
348
+ const date = new Date(resource.updatedAt);
349
+ console.log(`Updated: ${date.toLocaleString()}`);
350
+ }
351
+ console.log("=".repeat(60) + "\n");
352
+ console.log(resource.content);
353
+ console.log("\n" + "=".repeat(60) + "\n");
354
+ await safePrompt([
355
+ {
356
+ type: 'input',
357
+ name: 'continue',
358
+ message: 'Press Enter to continue...'
359
+ }
360
+ ]);
361
+ }
@@ -29,7 +29,9 @@ export default class DataEntryInstance {
29
29
  toJSON() {
30
30
  return {
31
31
  ...this.data,
32
- score: this.score
32
+ score: this.score,
33
+ id: this.id,
34
+ collectionName: this.collectionName
33
35
  };
34
36
  }
35
37
  /**
@@ -39,7 +41,9 @@ export default class DataEntryInstance {
39
41
  [Symbol.for('nodejs.util.inspect.custom')]() {
40
42
  return {
41
43
  ...this.data,
42
- score: this.score
44
+ score: this.score,
45
+ id: this.id,
46
+ collectionName: this.collectionName
43
47
  };
44
48
  }
45
49
  /**
@@ -1,3 +1,4 @@
1
+ import { AuthenticationError } from "../errors/auth.error.js";
1
2
  /**
2
3
  * Generic HTTP client with common error handling
3
4
  * Provides a base class for all API service classes with standardized HTTP methods
@@ -28,6 +29,9 @@ export class HttpClient {
28
29
  });
29
30
  // Check if response is ok (status 200-299)
30
31
  if (!response.ok) {
32
+ if (response.status === 401) {
33
+ throw new AuthenticationError("Invalid API key");
34
+ }
31
35
  return {
32
36
  success: false,
33
37
  error: {
@@ -55,6 +59,9 @@ export class HttpClient {
55
59
  };
56
60
  }
57
61
  catch (error) {
62
+ if (AuthenticationError.isAuthenticationError(error)) {
63
+ throw error;
64
+ }
58
65
  // Handle network errors, timeouts, etc.
59
66
  return {
60
67
  success: false,
@@ -33,10 +33,11 @@ export declare const SKILL_DEFAULTS: {
33
33
  };
34
34
  /**
35
35
  * External packages that should not be bundled with tools
36
- * These are either lua-cli modules, native modules, or modules
37
- * that should be provided by the runtime environment
36
+ * These are native modules, or modules that should be provided by the runtime environment
37
+ * Note: lua-cli is NOT in this list because it's handled by the sandboxGlobalsPlugin
38
+ * which transforms imports to use sandbox globals instead
38
39
  */
39
- export declare const EXTERNAL_PACKAGES: readonly ["lua-cli/skill", "lua-cli", "lua-cli/user-data-api", "lua-cli/product-api", "lua-cli/custom-data-api", "zod", "keytar", "esbuild", "commander", "inquirer", "node-fetch", "ws", "socket.io-client", "ts-morph"];
40
+ export declare const EXTERNAL_PACKAGES: readonly ["zod", "keytar", "esbuild", "commander", "inquirer", "node-fetch", "ws", "socket.io-client", "ts-morph"];
40
41
  /**
41
42
  * Common esbuild configuration for tool bundling
42
43
  */
@@ -32,15 +32,11 @@ export const SKILL_DEFAULTS = {
32
32
  };
33
33
  /**
34
34
  * External packages that should not be bundled with tools
35
- * These are either lua-cli modules, native modules, or modules
36
- * that should be provided by the runtime environment
35
+ * These are native modules, or modules that should be provided by the runtime environment
36
+ * Note: lua-cli is NOT in this list because it's handled by the sandboxGlobalsPlugin
37
+ * which transforms imports to use sandbox globals instead
37
38
  */
38
39
  export const EXTERNAL_PACKAGES = [
39
- 'lua-cli/skill',
40
- 'lua-cli',
41
- 'lua-cli/user-data-api',
42
- 'lua-cli/product-api',
43
- 'lua-cli/custom-data-api',
44
40
  'zod',
45
41
  'keytar',
46
42
  'esbuild',
@@ -1,5 +1,11 @@
1
+ /**
2
+ * Base URLs for the API, Auth, and Chat - Production
3
+ */
1
4
  export declare const BASE_URLS: {
2
5
  readonly API: "https://api.heylua.ai";
3
6
  readonly AUTH: "https://auth.heylua.ai";
4
7
  readonly CHAT: "https://api.heylua.ai";
5
8
  };
9
+ /**
10
+ * Base URLs for the API, Auth, and Chat - Development
11
+ */
@@ -1,5 +1,16 @@
1
+ /**
2
+ * Base URLs for the API, Auth, and Chat - Production
3
+ */
1
4
  export const BASE_URLS = {
2
5
  API: 'https://api.heylua.ai',
3
6
  AUTH: 'https://auth.heylua.ai',
4
7
  CHAT: 'https://api.heylua.ai',
5
8
  };
9
+ /**
10
+ * Base URLs for the API, Auth, and Chat - Development
11
+ */
12
+ // export const BASE_URLS = {
13
+ // API: 'http://localhost:3022',
14
+ // AUTH: 'https://auth.heylua.ai',
15
+ // CHAT: 'http://localhost:3001',
16
+ // } as const;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Authentication Error
3
+ * Thrown when API requests fail with 401 Unauthorized status
4
+ */
5
+ export declare class AuthenticationError extends Error {
6
+ readonly statusCode: number;
7
+ readonly isAuthenticationError: boolean;
8
+ constructor(message?: string);
9
+ /**
10
+ * Checks if an error is an AuthenticationError
11
+ * @param error - The error to check
12
+ * @returns True if the error is an AuthenticationError
13
+ */
14
+ static isAuthenticationError(error: unknown): error is AuthenticationError;
15
+ }