lua-cli 2.5.7 → 2.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/agent.api.service.d.ts +45 -0
- package/dist/api/agent.api.service.js +54 -0
- package/dist/api/user.data.api.service.d.ts +15 -0
- package/dist/api/user.data.api.service.js +31 -0
- package/dist/cli/command-definitions.js +77 -5
- package/dist/commands/completion.d.ts +11 -0
- package/dist/commands/completion.js +209 -0
- package/dist/commands/env.d.ts +3 -2
- package/dist/commands/env.js +42 -17
- package/dist/commands/features.d.ts +16 -0
- package/dist/commands/features.js +352 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.js +3 -0
- package/dist/commands/persona.d.ts +3 -2
- package/dist/commands/persona.js +43 -18
- package/dist/commands/push.d.ts +9 -13
- package/dist/commands/push.js +271 -82
- package/dist/commands/skills.d.ts +16 -0
- package/dist/commands/skills.js +438 -0
- package/dist/common/data.entry.instance.d.ts +7 -0
- package/dist/common/data.entry.instance.js +15 -0
- package/dist/common/order.instance.d.ts +6 -0
- package/dist/common/order.instance.js +14 -0
- package/dist/common/product.instance.d.ts +6 -0
- package/dist/common/product.instance.js +14 -0
- package/dist/common/user.instance.d.ts +14 -0
- package/dist/common/user.instance.js +29 -0
- package/dist/index.js +14 -3
- package/dist/interfaces/agent.d.ts +31 -0
- package/dist/interfaces/message.d.ts +18 -0
- package/dist/interfaces/message.js +1 -0
- package/dist/types/api-contracts.d.ts +9 -0
- package/dist/types/api-contracts.js +0 -7
- package/dist/web/app.css +152 -736
- package/dist/web/app.js +45 -45
- package/package.json +2 -2
- package/template/package.json +1 -1
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills Command
|
|
3
|
+
* Manages agent skills for sandbox and production environments
|
|
4
|
+
*/
|
|
5
|
+
import { loadApiKey, checkApiKey } from '../services/auth.js';
|
|
6
|
+
import { readSkillConfig } from '../utils/files.js';
|
|
7
|
+
import { withErrorHandling, writeProgress, writeSuccess, writeInfo } 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 skills command - manages agent skills
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - Environment selection (sandbox/staging or production)
|
|
16
|
+
* - Sandbox: view local skills from configuration
|
|
17
|
+
* - Production: view deployed skills, versions, and deploy new versions
|
|
18
|
+
*
|
|
19
|
+
* @param env - Optional environment argument ('sandbox', 'staging', or 'production')
|
|
20
|
+
* @returns Promise that resolves when command completes
|
|
21
|
+
*/
|
|
22
|
+
export async function skillsCommand(env) {
|
|
23
|
+
return withErrorHandling(async () => {
|
|
24
|
+
// Step 1: Load configuration first (to get agentId)
|
|
25
|
+
const config = readSkillConfig();
|
|
26
|
+
validateConfig(config);
|
|
27
|
+
validateAgentConfig(config);
|
|
28
|
+
const agentId = config.agent.agentId;
|
|
29
|
+
// Step 2: Authenticate
|
|
30
|
+
const apiKey = await loadApiKey();
|
|
31
|
+
if (!apiKey) {
|
|
32
|
+
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
await checkApiKey(apiKey);
|
|
36
|
+
writeProgress("✅ Authenticated");
|
|
37
|
+
let selectedEnvironment;
|
|
38
|
+
// Step 3: Check if environment was provided as argument
|
|
39
|
+
if (env) {
|
|
40
|
+
// Normalize the environment (staging is an alias for sandbox)
|
|
41
|
+
const normalizedEnv = env.toLowerCase();
|
|
42
|
+
if (normalizedEnv === 'sandbox' || normalizedEnv === 'staging') {
|
|
43
|
+
selectedEnvironment = 'sandbox';
|
|
44
|
+
}
|
|
45
|
+
else if (normalizedEnv === 'production') {
|
|
46
|
+
selectedEnvironment = 'production';
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.error(`❌ Invalid environment: "${env}". Must be "sandbox", "staging", or "production".`);
|
|
50
|
+
console.log('\nUsage:');
|
|
51
|
+
console.log(' lua skills - Interactive selection');
|
|
52
|
+
console.log(' lua skills sandbox - View sandbox skills directly');
|
|
53
|
+
console.log(' lua skills staging - View staging skills (alias for sandbox)');
|
|
54
|
+
console.log(' lua skills production - Manage production skills directly');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Step 4: Prompt for environment selection
|
|
60
|
+
const envAnswer = await safePrompt([
|
|
61
|
+
{
|
|
62
|
+
type: 'list',
|
|
63
|
+
name: 'environment',
|
|
64
|
+
message: 'Select environment:',
|
|
65
|
+
choices: [
|
|
66
|
+
{ name: '🔧 Sandbox (local skills)', value: 'sandbox' },
|
|
67
|
+
{ name: '🚀 Production (deployed skills)', value: 'production' }
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
]);
|
|
71
|
+
if (!envAnswer)
|
|
72
|
+
return;
|
|
73
|
+
selectedEnvironment = envAnswer.environment;
|
|
74
|
+
}
|
|
75
|
+
const context = {
|
|
76
|
+
environment: selectedEnvironment,
|
|
77
|
+
agentId,
|
|
78
|
+
apiKey,
|
|
79
|
+
};
|
|
80
|
+
// Step 5: Start management based on environment
|
|
81
|
+
if (selectedEnvironment === 'sandbox') {
|
|
82
|
+
await manageSandboxSkills(context, config);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
await manageProductionSkills(context, config);
|
|
86
|
+
}
|
|
87
|
+
}, "skills");
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Manage sandbox skills - view local configuration
|
|
91
|
+
*/
|
|
92
|
+
async function manageSandboxSkills(context, config) {
|
|
93
|
+
let continueManaging = true;
|
|
94
|
+
while (continueManaging) {
|
|
95
|
+
console.log("\n" + "=".repeat(60));
|
|
96
|
+
console.log("🔧 Sandbox Skills");
|
|
97
|
+
console.log("=".repeat(60) + "\n");
|
|
98
|
+
const skills = config.skills || [];
|
|
99
|
+
if (skills.length === 0) {
|
|
100
|
+
console.log("ℹ️ No skills found in configuration.");
|
|
101
|
+
console.log("💡 Run 'lua compile' to add skills to your configuration.\n");
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
console.log("Local skills in lua.skill.yaml:\n");
|
|
105
|
+
skills.forEach((skill, index) => {
|
|
106
|
+
console.log(`${index + 1}. 📦 ${skill.name}`);
|
|
107
|
+
console.log(` Version: ${skill.version}`);
|
|
108
|
+
console.log(` Skill ID: ${skill.skillId}`);
|
|
109
|
+
console.log();
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const actionAnswer = await safePrompt([
|
|
113
|
+
{
|
|
114
|
+
type: 'list',
|
|
115
|
+
name: 'action',
|
|
116
|
+
message: 'What would you like to do?',
|
|
117
|
+
choices: [
|
|
118
|
+
{ name: '🔄 Refresh list', value: 'refresh' },
|
|
119
|
+
{ name: '📦 Compile skills', value: 'compile' },
|
|
120
|
+
{ name: '☁️ Push a skill', value: 'push' },
|
|
121
|
+
{ name: '❌ Exit', value: 'exit' }
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
]);
|
|
125
|
+
if (!actionAnswer)
|
|
126
|
+
return;
|
|
127
|
+
const { action } = actionAnswer;
|
|
128
|
+
switch (action) {
|
|
129
|
+
case 'refresh':
|
|
130
|
+
// Reload config
|
|
131
|
+
const newConfig = readSkillConfig();
|
|
132
|
+
config.skills = newConfig.skills;
|
|
133
|
+
break;
|
|
134
|
+
case 'compile':
|
|
135
|
+
console.log("\n💡 Run 'lua compile' in your terminal to compile your skills.\n");
|
|
136
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
137
|
+
break;
|
|
138
|
+
case 'push':
|
|
139
|
+
console.log("\n💡 Run 'lua push skill' in your terminal to push a skill.\n");
|
|
140
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
141
|
+
break;
|
|
142
|
+
case 'exit':
|
|
143
|
+
continueManaging = false;
|
|
144
|
+
console.log("\n👋 Goodbye!\n");
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Manage production skills - view and deploy versions
|
|
151
|
+
*/
|
|
152
|
+
async function manageProductionSkills(context, config) {
|
|
153
|
+
let continueManaging = true;
|
|
154
|
+
while (continueManaging) {
|
|
155
|
+
console.log("\n" + "=".repeat(60));
|
|
156
|
+
console.log("🚀 Production Skills");
|
|
157
|
+
console.log("=".repeat(60) + "\n");
|
|
158
|
+
const actionAnswer = await safePrompt([
|
|
159
|
+
{
|
|
160
|
+
type: 'list',
|
|
161
|
+
name: 'action',
|
|
162
|
+
message: 'What would you like to do?',
|
|
163
|
+
choices: [
|
|
164
|
+
{ name: '👁️ View deployed skills', value: 'view' },
|
|
165
|
+
{ name: '📜 View skill versions', value: 'versions' },
|
|
166
|
+
{ name: '🚀 Deploy a version', value: 'deploy' },
|
|
167
|
+
{ name: '❌ Exit', value: 'exit' }
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
]);
|
|
171
|
+
if (!actionAnswer)
|
|
172
|
+
return;
|
|
173
|
+
const { action } = actionAnswer;
|
|
174
|
+
switch (action) {
|
|
175
|
+
case 'view':
|
|
176
|
+
await viewDeployedSkills(context, config);
|
|
177
|
+
break;
|
|
178
|
+
case 'versions':
|
|
179
|
+
await viewSkillVersions(context, config);
|
|
180
|
+
break;
|
|
181
|
+
case 'deploy':
|
|
182
|
+
await deploySkillVersion(context, config);
|
|
183
|
+
break;
|
|
184
|
+
case 'exit':
|
|
185
|
+
continueManaging = false;
|
|
186
|
+
console.log("\n👋 Goodbye!\n");
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* View deployed skills in production
|
|
193
|
+
*/
|
|
194
|
+
async function viewDeployedSkills(context, config) {
|
|
195
|
+
writeProgress("🔄 Loading skill information...");
|
|
196
|
+
try {
|
|
197
|
+
const skills = config.skills || [];
|
|
198
|
+
if (skills.length === 0) {
|
|
199
|
+
console.log("\nℹ️ No skills found in configuration.\n");
|
|
200
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
console.log("\n" + "=".repeat(60));
|
|
204
|
+
console.log("⚙️ Production Skills");
|
|
205
|
+
console.log("=".repeat(60) + "\n");
|
|
206
|
+
// Fetch version info for each skill
|
|
207
|
+
for (const skill of skills) {
|
|
208
|
+
try {
|
|
209
|
+
const response = await fetch(`${BASE_URLS.API}/developer/skills/${context.agentId}/${skill.skillId}/versions`, {
|
|
210
|
+
method: 'GET',
|
|
211
|
+
headers: {
|
|
212
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
213
|
+
'Content-Type': 'application/json'
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
if (response.ok) {
|
|
217
|
+
const data = await response.json();
|
|
218
|
+
const versions = data.data?.versions || data.versions || [];
|
|
219
|
+
const activeVersionId = data.data?.activeVersionId || data.activeVersionId;
|
|
220
|
+
// Find active version
|
|
221
|
+
const activeVersion = versions.find((v) => v.skillId === activeVersionId);
|
|
222
|
+
console.log(`📦 ${skill.name}`);
|
|
223
|
+
console.log(` Skill ID: ${skill.skillId}`);
|
|
224
|
+
if (activeVersion) {
|
|
225
|
+
console.log(` Deployed Version: ${activeVersion.version} ⭐`);
|
|
226
|
+
const date = new Date(activeVersion.createdAt);
|
|
227
|
+
console.log(` Deployed: ${date.toLocaleString()}`);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
console.log(` Deployed Version: Not deployed`);
|
|
231
|
+
}
|
|
232
|
+
console.log(` Total Versions: ${versions.length}`);
|
|
233
|
+
console.log();
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
console.log(`📦 ${skill.name}`);
|
|
237
|
+
console.log(` Skill ID: ${skill.skillId}`);
|
|
238
|
+
console.log(` Status: Unable to fetch version info`);
|
|
239
|
+
console.log();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
console.log(`📦 ${skill.name}`);
|
|
244
|
+
console.log(` Skill ID: ${skill.skillId}`);
|
|
245
|
+
console.log(` Status: Error loading versions`);
|
|
246
|
+
console.log();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
console.log("=".repeat(60) + "\n");
|
|
250
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
console.error('❌ Error loading skill information:', error);
|
|
254
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* View versions for a specific skill
|
|
259
|
+
*/
|
|
260
|
+
async function viewSkillVersions(context, config) {
|
|
261
|
+
const skills = config.skills || [];
|
|
262
|
+
if (skills.length === 0) {
|
|
263
|
+
console.log("\nℹ️ No skills found in configuration.\n");
|
|
264
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
// Prompt to select a skill
|
|
268
|
+
const skillAnswer = await safePrompt([
|
|
269
|
+
{
|
|
270
|
+
type: 'list',
|
|
271
|
+
name: 'selectedSkill',
|
|
272
|
+
message: 'Select a skill to view versions:',
|
|
273
|
+
choices: skills.map((skill) => ({
|
|
274
|
+
name: `${skill.name} (${skill.skillId})`,
|
|
275
|
+
value: skill
|
|
276
|
+
}))
|
|
277
|
+
}
|
|
278
|
+
]);
|
|
279
|
+
if (!skillAnswer)
|
|
280
|
+
return;
|
|
281
|
+
const selectedSkill = skillAnswer.selectedSkill;
|
|
282
|
+
writeProgress(`🔄 Loading versions for ${selectedSkill.name}...`);
|
|
283
|
+
try {
|
|
284
|
+
const response = await fetch(`${BASE_URLS.API}/developer/skills/${context.agentId}/${selectedSkill.skillId}/versions`, {
|
|
285
|
+
method: 'GET',
|
|
286
|
+
headers: {
|
|
287
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
288
|
+
'Content-Type': 'application/json'
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
if (!response.ok) {
|
|
292
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
293
|
+
}
|
|
294
|
+
const data = await response.json();
|
|
295
|
+
const versions = data.data?.versions || data.versions || [];
|
|
296
|
+
const activeVersionId = data.data?.activeVersionId || data.activeVersionId;
|
|
297
|
+
if (versions.length === 0) {
|
|
298
|
+
console.log(`\nℹ️ No versions found for ${selectedSkill.name}.\n`);
|
|
299
|
+
console.log("💡 Push a version first using 'lua push skill'.\n");
|
|
300
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
console.log("\n" + "=".repeat(60));
|
|
304
|
+
console.log(`📜 Versions for ${selectedSkill.name}`);
|
|
305
|
+
console.log("=".repeat(60) + "\n");
|
|
306
|
+
// Sort versions by date (newest first)
|
|
307
|
+
const sortedVersions = versions.sort((a, b) => {
|
|
308
|
+
const dateA = new Date(a.createdAt).getTime();
|
|
309
|
+
const dateB = new Date(b.createdAt).getTime();
|
|
310
|
+
return dateB - dateA;
|
|
311
|
+
});
|
|
312
|
+
sortedVersions.forEach((version, index) => {
|
|
313
|
+
const isActive = version.skillId === activeVersionId;
|
|
314
|
+
const date = new Date(version.createdAt);
|
|
315
|
+
console.log(`${index + 1}. Version ${version.version}${isActive ? ' ⭐ DEPLOYED' : ''}`);
|
|
316
|
+
console.log(` Created: ${date.toLocaleString()}`);
|
|
317
|
+
console.log(` Version ID: ${version.skillId}`);
|
|
318
|
+
console.log();
|
|
319
|
+
});
|
|
320
|
+
console.log("=".repeat(60) + "\n");
|
|
321
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
console.error('❌ Error loading versions:', error);
|
|
325
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Deploy a skill version to production
|
|
330
|
+
*/
|
|
331
|
+
async function deploySkillVersion(context, config) {
|
|
332
|
+
const skills = config.skills || [];
|
|
333
|
+
if (skills.length === 0) {
|
|
334
|
+
console.log("\nℹ️ No skills found in configuration.\n");
|
|
335
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
// Prompt to select a skill
|
|
339
|
+
const skillAnswer = await safePrompt([
|
|
340
|
+
{
|
|
341
|
+
type: 'list',
|
|
342
|
+
name: 'selectedSkill',
|
|
343
|
+
message: 'Select a skill to deploy:',
|
|
344
|
+
choices: skills.map((skill) => ({
|
|
345
|
+
name: `${skill.name} (${skill.skillId})`,
|
|
346
|
+
value: skill
|
|
347
|
+
}))
|
|
348
|
+
}
|
|
349
|
+
]);
|
|
350
|
+
if (!skillAnswer)
|
|
351
|
+
return;
|
|
352
|
+
const selectedSkill = skillAnswer.selectedSkill;
|
|
353
|
+
writeProgress(`🔄 Loading versions for ${selectedSkill.name}...`);
|
|
354
|
+
try {
|
|
355
|
+
const response = await fetch(`${BASE_URLS.API}/developer/skills/${context.agentId}/${selectedSkill.skillId}/versions`, {
|
|
356
|
+
method: 'GET',
|
|
357
|
+
headers: {
|
|
358
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
359
|
+
'Content-Type': 'application/json'
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
if (!response.ok) {
|
|
363
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
364
|
+
}
|
|
365
|
+
const data = await response.json();
|
|
366
|
+
const versions = data.data?.versions || data.versions || [];
|
|
367
|
+
const activeVersionId = data.data?.activeVersionId || data.activeVersionId;
|
|
368
|
+
if (versions.length === 0) {
|
|
369
|
+
console.log(`\nℹ️ No versions found for ${selectedSkill.name}.\n`);
|
|
370
|
+
console.log("💡 Push a version first using 'lua push skill'.\n");
|
|
371
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
// Sort versions by date (newest first)
|
|
375
|
+
const sortedVersions = versions.sort((a, b) => {
|
|
376
|
+
const dateA = new Date(a.createdAt).getTime();
|
|
377
|
+
const dateB = new Date(b.createdAt).getTime();
|
|
378
|
+
return dateB - dateA;
|
|
379
|
+
});
|
|
380
|
+
// Prompt to select a version
|
|
381
|
+
const versionAnswer = await safePrompt([
|
|
382
|
+
{
|
|
383
|
+
type: 'list',
|
|
384
|
+
name: 'selectedVersion',
|
|
385
|
+
message: 'Select a version to deploy:',
|
|
386
|
+
choices: sortedVersions.map((version) => {
|
|
387
|
+
const isActive = version.skillId === activeVersionId;
|
|
388
|
+
const date = new Date(version.createdAt);
|
|
389
|
+
return {
|
|
390
|
+
name: `Version ${version.version} (${date.toLocaleDateString()})${isActive ? ' ⭐ CURRENT' : ''}`,
|
|
391
|
+
value: version
|
|
392
|
+
};
|
|
393
|
+
})
|
|
394
|
+
}
|
|
395
|
+
]);
|
|
396
|
+
if (!versionAnswer)
|
|
397
|
+
return;
|
|
398
|
+
const selectedVersion = versionAnswer.selectedVersion;
|
|
399
|
+
// Show warning
|
|
400
|
+
console.log("\n⚠️ WARNING: You are about to deploy to PRODUCTION!");
|
|
401
|
+
console.log("⚠️ This will affect ALL users immediately.\n");
|
|
402
|
+
console.log(`Skill: ${selectedSkill.name}`);
|
|
403
|
+
console.log(`Version: ${selectedVersion.version}\n`);
|
|
404
|
+
const confirmAnswer = await safePrompt([
|
|
405
|
+
{
|
|
406
|
+
type: 'confirm',
|
|
407
|
+
name: 'confirm',
|
|
408
|
+
message: 'Are you absolutely sure you want to deploy this version?',
|
|
409
|
+
default: false
|
|
410
|
+
}
|
|
411
|
+
]);
|
|
412
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
413
|
+
console.log("\n❌ Deployment cancelled.\n");
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
writeProgress("🔄 Deploying version...");
|
|
417
|
+
const deployResponse = await fetch(`${BASE_URLS.API}/developer/skills/${context.agentId}/${selectedSkill.skillId}/${selectedVersion.version}/publish`, {
|
|
418
|
+
method: 'POST',
|
|
419
|
+
headers: {
|
|
420
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
421
|
+
'Content-Type': 'application/json'
|
|
422
|
+
},
|
|
423
|
+
body: JSON.stringify({})
|
|
424
|
+
});
|
|
425
|
+
if (!deployResponse.ok) {
|
|
426
|
+
const errorText = await deployResponse.text();
|
|
427
|
+
console.error(`\n❌ Deploy Error: ${deployResponse.status} - ${errorText}\n`);
|
|
428
|
+
throw new Error(`HTTP error! status: ${deployResponse.status}`);
|
|
429
|
+
}
|
|
430
|
+
writeSuccess(`\n✅ Version ${selectedVersion.version} of "${selectedSkill.name}" deployed successfully to production\n`);
|
|
431
|
+
writeInfo("💡 The new version is now active for all users.");
|
|
432
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
console.error('\n❌ Error deploying version:', error);
|
|
436
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
@@ -39,4 +39,11 @@ export default class DataEntryInstance {
|
|
|
39
39
|
* @throws Error if the deletion fails
|
|
40
40
|
*/
|
|
41
41
|
delete(): Promise<boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* Saves the data entry
|
|
44
|
+
* @param searchText - Optional search text for vector search indexing
|
|
45
|
+
* @returns Promise resolving to true if saving was successful
|
|
46
|
+
* @throws Error if the save operation fails
|
|
47
|
+
*/
|
|
48
|
+
save(searchText?: string): Promise<boolean>;
|
|
42
49
|
}
|
|
@@ -144,4 +144,19 @@ export default class DataEntryInstance {
|
|
|
144
144
|
throw new Error('Failed to clear user data');
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Saves the data entry
|
|
149
|
+
* @param searchText - Optional search text for vector search indexing
|
|
150
|
+
* @returns Promise resolving to true if saving was successful
|
|
151
|
+
* @throws Error if the save operation fails
|
|
152
|
+
*/
|
|
153
|
+
async save(searchText) {
|
|
154
|
+
try {
|
|
155
|
+
await this.customDataAPI.update(this.collectionName, this.id, { data: this.data, searchText: searchText });
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
throw new Error('Failed to save data entry');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
147
162
|
}
|
|
@@ -40,4 +40,10 @@ export default class OrderInstance {
|
|
|
40
40
|
* @throws Error if the data update fails
|
|
41
41
|
*/
|
|
42
42
|
update(data: Record<string, any>): Promise<any>;
|
|
43
|
+
/**
|
|
44
|
+
* Saves the order's data
|
|
45
|
+
* @returns Promise resolving to true if saving was successful
|
|
46
|
+
* @throws Error if the save operation fails
|
|
47
|
+
*/
|
|
48
|
+
save(): Promise<boolean>;
|
|
43
49
|
}
|
|
@@ -170,4 +170,18 @@ export default class OrderInstance {
|
|
|
170
170
|
id: this.id
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Saves the order's data
|
|
175
|
+
* @returns Promise resolving to true if saving was successful
|
|
176
|
+
* @throws Error if the save operation fails
|
|
177
|
+
*/
|
|
178
|
+
async save() {
|
|
179
|
+
try {
|
|
180
|
+
await this.orderAPI.updateData(this.data, this.id);
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
throw new Error('Failed to save order data');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
173
187
|
}
|
|
@@ -33,4 +33,10 @@ export default class ProductInstance {
|
|
|
33
33
|
* @throws Error if the deletion fails or the product is not found
|
|
34
34
|
*/
|
|
35
35
|
delete(): Promise<Product>;
|
|
36
|
+
/**
|
|
37
|
+
* Saves the product's data
|
|
38
|
+
* @returns Promise resolving to true if saving was successful
|
|
39
|
+
* @throws Error if the save operation fails
|
|
40
|
+
*/
|
|
41
|
+
save(): Promise<boolean>;
|
|
36
42
|
}
|
|
@@ -127,4 +127,18 @@ export default class ProductInstance {
|
|
|
127
127
|
}
|
|
128
128
|
return this.data;
|
|
129
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Saves the product's data
|
|
132
|
+
* @returns Promise resolving to true if saving was successful
|
|
133
|
+
* @throws Error if the save operation fails
|
|
134
|
+
*/
|
|
135
|
+
async save() {
|
|
136
|
+
try {
|
|
137
|
+
await this.productAPI.update(this.data, this.data.id);
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw new Error('Failed to save product data');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
130
144
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Message } from "../interfaces/message.js";
|
|
1
2
|
import { UserDataAPI } from "../types/index.js";
|
|
2
3
|
/**
|
|
3
4
|
* User data instance class providing a fluent API for managing user data
|
|
@@ -33,4 +34,17 @@ export default class UserDataInstance {
|
|
|
33
34
|
* @throws Error if the clear operation fails
|
|
34
35
|
*/
|
|
35
36
|
clear(): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Saves the user's data
|
|
39
|
+
* @returns Promise resolving to true if saving was successful
|
|
40
|
+
* @throws Error if the save operation fails
|
|
41
|
+
*/
|
|
42
|
+
save(): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Sends a message to a specific user conversation for the agent
|
|
45
|
+
* @param messages - An array of messages to send (can be text, image, or file types)
|
|
46
|
+
* @returns Promise resolving to the response data from the server
|
|
47
|
+
* @throws Error if the message sending fails or the request is unsuccessful
|
|
48
|
+
*/
|
|
49
|
+
send(messages: Message[]): Promise<any>;
|
|
36
50
|
}
|
|
@@ -129,4 +129,33 @@ export default class UserDataInstance {
|
|
|
129
129
|
throw new Error('Failed to clear user data');
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Saves the user's data
|
|
134
|
+
* @returns Promise resolving to true if saving was successful
|
|
135
|
+
* @throws Error if the save operation fails
|
|
136
|
+
*/
|
|
137
|
+
async save() {
|
|
138
|
+
try {
|
|
139
|
+
await this.userAPI.update(this.data);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
throw new Error('Failed to save user data');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Sends a message to a specific user conversation for the agent
|
|
148
|
+
* @param messages - An array of messages to send (can be text, image, or file types)
|
|
149
|
+
* @returns Promise resolving to the response data from the server
|
|
150
|
+
* @throws Error if the message sending fails or the request is unsuccessful
|
|
151
|
+
*/
|
|
152
|
+
async send(messages) {
|
|
153
|
+
try {
|
|
154
|
+
await this.userAPI.sendMessage(messages);
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
throw new Error('Failed to send message');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
132
161
|
}
|
package/dist/index.js
CHANGED
|
@@ -37,13 +37,24 @@ Examples:
|
|
|
37
37
|
$ lua init 🚀 Initialize a new project
|
|
38
38
|
$ lua compile 📦 Compile your skills
|
|
39
39
|
$ lua test 🧪 Test tools interactively
|
|
40
|
-
$ lua push ☁️ Push to server
|
|
40
|
+
$ lua push ☁️ Push to server (interactive)
|
|
41
|
+
$ lua push skill ☁️ Push skill directly
|
|
42
|
+
$ lua push persona ☁️ Push persona directly
|
|
41
43
|
$ lua deploy 🚀 Deploy to production
|
|
42
44
|
$ lua chat 💬 Start interactive chat
|
|
43
|
-
$ lua env ⚙️ Manage environment variables
|
|
44
|
-
$ lua
|
|
45
|
+
$ lua env ⚙️ Manage environment variables (interactive)
|
|
46
|
+
$ lua env staging ⚙️ Manage staging env vars directly
|
|
47
|
+
$ lua env production ⚙️ Manage production env vars directly
|
|
48
|
+
$ lua persona 🤖 Manage agent persona (interactive)
|
|
49
|
+
$ lua persona staging 🤖 Manage staging persona directly
|
|
50
|
+
$ lua persona production 🤖 Manage production persona directly
|
|
51
|
+
$ lua skills ⚙️ Manage skills (interactive)
|
|
52
|
+
$ lua skills staging ⚙️ View staging skills directly
|
|
53
|
+
$ lua skills production ⚙️ Manage production skills directly
|
|
54
|
+
$ lua features 🎯 Manage agent features
|
|
45
55
|
$ lua admin 🔧 Open admin dashboard
|
|
46
56
|
$ lua docs 📖 Open documentation
|
|
57
|
+
$ lua completion 🎯 Enable shell autocomplete
|
|
47
58
|
|
|
48
59
|
🌙 Documentation: https://docs.heylua.ai
|
|
49
60
|
🌙 Support: https://heylua.ai/support
|
|
@@ -307,3 +307,34 @@ export interface CreateEmailChannelResponse {
|
|
|
307
307
|
forwardTo: string;
|
|
308
308
|
status: string;
|
|
309
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Agent feature configuration.
|
|
312
|
+
* Represents a feature that can be enabled/disabled for an agent.
|
|
313
|
+
*/
|
|
314
|
+
export interface AgentFeature {
|
|
315
|
+
name: string;
|
|
316
|
+
title: string;
|
|
317
|
+
context: string;
|
|
318
|
+
active: boolean;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Response from get agent features API.
|
|
322
|
+
*/
|
|
323
|
+
export interface GetAgentFeaturesResponse {
|
|
324
|
+
features: AgentFeature[];
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Request payload for updating an agent feature.
|
|
328
|
+
* At least one of active or featureContext must be provided.
|
|
329
|
+
*/
|
|
330
|
+
export interface UpdateAgentFeatureRequest {
|
|
331
|
+
featureName: string;
|
|
332
|
+
active?: boolean;
|
|
333
|
+
featureContext?: string;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Response from updating an agent feature.
|
|
337
|
+
*/
|
|
338
|
+
export interface UpdateAgentFeatureResponse {
|
|
339
|
+
message: string;
|
|
340
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type TextMessage = {
|
|
2
|
+
type: "text";
|
|
3
|
+
text: string;
|
|
4
|
+
};
|
|
5
|
+
export type ImageMessage = {
|
|
6
|
+
type: "image";
|
|
7
|
+
image: string;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
};
|
|
10
|
+
export type FileMessage = {
|
|
11
|
+
type: "file";
|
|
12
|
+
data: string;
|
|
13
|
+
mimeType: string;
|
|
14
|
+
};
|
|
15
|
+
export type Message = TextMessage | ImageMessage | FileMessage;
|
|
16
|
+
export interface SendMessageRequest {
|
|
17
|
+
messages: Message[];
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|