lua-cli 2.3.2 → 2.4.1
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/products.api.service.js +1 -0
- package/dist/cli/command-definitions.d.ts +0 -8
- package/dist/cli/command-definitions.js +51 -18
- package/dist/commands/chat.d.ts +17 -0
- package/dist/commands/chat.js +236 -0
- package/dist/commands/chatClear.d.ts +15 -0
- package/dist/commands/chatClear.js +75 -0
- package/dist/commands/env.d.ts +19 -0
- package/dist/commands/env.js +434 -0
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.js +6 -0
- package/dist/commands/persona.d.ts +15 -0
- package/dist/commands/persona.js +503 -0
- package/dist/commands/production.d.ts +15 -0
- package/dist/commands/production.js +532 -0
- package/dist/commands/push.js +56 -0
- package/dist/commands/resources.d.ts +17 -0
- package/dist/commands/resources.js +361 -0
- package/dist/common/data.entry.instance.js +6 -2
- package/dist/config/compile.constants.d.ts +4 -3
- package/dist/config/compile.constants.js +3 -7
- package/dist/config/constants.d.ts +6 -0
- package/dist/config/constants.js +11 -0
- package/dist/index.d.ts +0 -9
- package/dist/index.js +30 -11
- package/dist/utils/bundling.js +61 -0
- package/dist/utils/prompt-handler.d.ts +12 -0
- package/dist/utils/prompt-handler.js +31 -0
- package/dist/utils/push-helpers.js +36 -31
- package/dist/utils/sandbox.js +2 -2
- package/dist/web/app.js +1 -1
- package/package.json +1 -1
- package/template/package-lock.json +1 -1
- package/template/src/tools/BasketTool.ts +4 -1
- package/template/src/tools/ProductsTool.ts +7 -7
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persona Command
|
|
3
|
+
* Manages agent persona for sandbox and production environments
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import yaml from 'js-yaml';
|
|
8
|
+
import inquirer from 'inquirer';
|
|
9
|
+
import { loadApiKey, checkApiKey } from '../services/auth.js';
|
|
10
|
+
import { readSkillConfig } from '../utils/files.js';
|
|
11
|
+
import { withErrorHandling, writeProgress, writeSuccess, writeInfo } from '../utils/cli.js';
|
|
12
|
+
import { BASE_URLS } from '../config/constants.js';
|
|
13
|
+
import { safePrompt } from '../utils/prompt-handler.js';
|
|
14
|
+
import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
|
|
15
|
+
/**
|
|
16
|
+
* Main persona command - manages agent persona
|
|
17
|
+
*
|
|
18
|
+
* Features:
|
|
19
|
+
* - Environment selection (sandbox or production)
|
|
20
|
+
* - Sandbox: view, edit, save persona + create versions
|
|
21
|
+
* - Production: list versions, view details, deploy versions
|
|
22
|
+
*
|
|
23
|
+
* @returns Promise that resolves when command completes
|
|
24
|
+
*/
|
|
25
|
+
export async function personaCommand() {
|
|
26
|
+
return withErrorHandling(async () => {
|
|
27
|
+
// Step 1: Load configuration first (to get agentId)
|
|
28
|
+
const config = readSkillConfig();
|
|
29
|
+
validateConfig(config);
|
|
30
|
+
validateAgentConfig(config);
|
|
31
|
+
const agentId = config.agent.agentId;
|
|
32
|
+
// Step 2: Authenticate
|
|
33
|
+
const apiKey = await loadApiKey();
|
|
34
|
+
if (!apiKey) {
|
|
35
|
+
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
await checkApiKey(apiKey);
|
|
39
|
+
writeProgress("✅ Authenticated");
|
|
40
|
+
// Step 3: Select environment
|
|
41
|
+
const envAnswer = await safePrompt([
|
|
42
|
+
{
|
|
43
|
+
type: 'list',
|
|
44
|
+
name: 'environment',
|
|
45
|
+
message: 'Select environment:',
|
|
46
|
+
choices: [
|
|
47
|
+
{ name: '🔧 Sandbox (edit and test)', value: 'sandbox' },
|
|
48
|
+
{ name: '🚀 Production (view and deploy versions)', value: 'production' }
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
]);
|
|
52
|
+
if (!envAnswer)
|
|
53
|
+
return;
|
|
54
|
+
const context = {
|
|
55
|
+
environment: envAnswer.environment,
|
|
56
|
+
agentId,
|
|
57
|
+
apiKey,
|
|
58
|
+
};
|
|
59
|
+
// Step 4: Start management based on environment
|
|
60
|
+
if (envAnswer.environment === 'sandbox') {
|
|
61
|
+
await manageSandboxPersona(context);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
await manageProductionPersona(context);
|
|
65
|
+
}
|
|
66
|
+
}, "persona");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Manage sandbox persona - edit and save
|
|
70
|
+
*/
|
|
71
|
+
async function manageSandboxPersona(context) {
|
|
72
|
+
let continueManaging = true;
|
|
73
|
+
while (continueManaging) {
|
|
74
|
+
// Load current persona
|
|
75
|
+
const currentPersona = loadSandboxPersona();
|
|
76
|
+
// Show menu
|
|
77
|
+
console.log("\n" + "=".repeat(60));
|
|
78
|
+
console.log("🌙 Sandbox Persona Management");
|
|
79
|
+
console.log("=".repeat(60) + "\n");
|
|
80
|
+
if (currentPersona && currentPersona.trim()) {
|
|
81
|
+
const preview = currentPersona.length > 100
|
|
82
|
+
? currentPersona.substring(0, 100) + '...'
|
|
83
|
+
: currentPersona;
|
|
84
|
+
console.log("Current persona:");
|
|
85
|
+
console.log(preview);
|
|
86
|
+
console.log();
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.log("ℹ️ No persona configured.\n");
|
|
90
|
+
}
|
|
91
|
+
const actionAnswer = await safePrompt([
|
|
92
|
+
{
|
|
93
|
+
type: 'list',
|
|
94
|
+
name: 'action',
|
|
95
|
+
message: 'What would you like to do?',
|
|
96
|
+
choices: [
|
|
97
|
+
{ name: '👁️ View full persona', value: 'view' },
|
|
98
|
+
{ name: '✏️ Edit persona', value: 'edit' },
|
|
99
|
+
{ name: '📦 Create version (push to production)', value: 'create_version' },
|
|
100
|
+
{ name: '📋 List versions', value: 'list_versions' },
|
|
101
|
+
{ name: '❌ Exit', value: 'exit' }
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
]);
|
|
105
|
+
if (!actionAnswer)
|
|
106
|
+
return;
|
|
107
|
+
const { action } = actionAnswer;
|
|
108
|
+
switch (action) {
|
|
109
|
+
case 'view':
|
|
110
|
+
await viewPersona(currentPersona);
|
|
111
|
+
break;
|
|
112
|
+
case 'edit':
|
|
113
|
+
await editSandboxPersona(context, currentPersona);
|
|
114
|
+
break;
|
|
115
|
+
case 'create_version':
|
|
116
|
+
await createPersonaVersion(context, currentPersona);
|
|
117
|
+
break;
|
|
118
|
+
case 'list_versions':
|
|
119
|
+
await listPersonaVersions(context);
|
|
120
|
+
break;
|
|
121
|
+
case 'exit':
|
|
122
|
+
continueManaging = false;
|
|
123
|
+
console.log("\n👋 Goodbye!\n");
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Manage production persona - view and deploy versions
|
|
130
|
+
*/
|
|
131
|
+
async function manageProductionPersona(context) {
|
|
132
|
+
let continueManaging = true;
|
|
133
|
+
while (continueManaging) {
|
|
134
|
+
console.log("\n" + "=".repeat(60));
|
|
135
|
+
console.log("🌙 Production Persona Management");
|
|
136
|
+
console.log("=".repeat(60) + "\n");
|
|
137
|
+
const actionAnswer = await safePrompt([
|
|
138
|
+
{
|
|
139
|
+
type: 'list',
|
|
140
|
+
name: 'action',
|
|
141
|
+
message: 'What would you like to do?',
|
|
142
|
+
choices: [
|
|
143
|
+
{ name: '👁️ View persona versions', value: 'view' },
|
|
144
|
+
{ name: '🚀 Deploy persona version', value: 'deploy' },
|
|
145
|
+
{ name: '❌ Exit', value: 'exit' }
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
]);
|
|
149
|
+
if (!actionAnswer)
|
|
150
|
+
return;
|
|
151
|
+
const { action } = actionAnswer;
|
|
152
|
+
switch (action) {
|
|
153
|
+
case 'view':
|
|
154
|
+
await listPersonaVersions(context);
|
|
155
|
+
break;
|
|
156
|
+
case 'deploy':
|
|
157
|
+
await deployPersonaVersion(context);
|
|
158
|
+
break;
|
|
159
|
+
case 'exit':
|
|
160
|
+
continueManaging = false;
|
|
161
|
+
console.log("\n👋 Goodbye!\n");
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Load sandbox persona from lua.skill.yaml
|
|
168
|
+
*/
|
|
169
|
+
function loadSandboxPersona() {
|
|
170
|
+
try {
|
|
171
|
+
const config = readSkillConfig();
|
|
172
|
+
return config.agent?.persona || '';
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
return '';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Save sandbox persona to lua.skill.yaml
|
|
180
|
+
*/
|
|
181
|
+
function saveSandboxPersona(persona) {
|
|
182
|
+
try {
|
|
183
|
+
const configPath = path.join(process.cwd(), 'lua.skill.yaml');
|
|
184
|
+
// Read current config
|
|
185
|
+
const fileContent = fs.readFileSync(configPath, 'utf8');
|
|
186
|
+
const config = yaml.load(fileContent);
|
|
187
|
+
// Ensure agent object exists
|
|
188
|
+
if (!config.agent) {
|
|
189
|
+
config.agent = {};
|
|
190
|
+
}
|
|
191
|
+
// Update persona
|
|
192
|
+
config.agent.persona = persona;
|
|
193
|
+
// Write back to file
|
|
194
|
+
const newContent = yaml.dump(config, {
|
|
195
|
+
lineWidth: -1,
|
|
196
|
+
noRefs: true
|
|
197
|
+
});
|
|
198
|
+
fs.writeFileSync(configPath, newContent, 'utf8');
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
console.error('❌ Error saving persona to lua.skill.yaml:', error);
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* View full persona content
|
|
208
|
+
*/
|
|
209
|
+
async function viewPersona(persona) {
|
|
210
|
+
console.log("\n" + "=".repeat(60));
|
|
211
|
+
console.log("Agent Persona");
|
|
212
|
+
console.log("=".repeat(60));
|
|
213
|
+
if (persona && persona.trim()) {
|
|
214
|
+
console.log(persona);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
console.log("No persona configured.");
|
|
218
|
+
}
|
|
219
|
+
console.log("=".repeat(60) + "\n");
|
|
220
|
+
await inquirer.prompt([
|
|
221
|
+
{
|
|
222
|
+
type: 'input',
|
|
223
|
+
name: 'continue',
|
|
224
|
+
message: 'Press Enter to continue...'
|
|
225
|
+
}
|
|
226
|
+
]);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Edit sandbox persona
|
|
230
|
+
*/
|
|
231
|
+
async function editSandboxPersona(context, currentPersona) {
|
|
232
|
+
// Provide helpful default if empty
|
|
233
|
+
const defaultPersona = currentPersona || `# Write your agent persona here
|
|
234
|
+
#
|
|
235
|
+
# Example:
|
|
236
|
+
# You are a helpful customer service assistant for [Your Company].
|
|
237
|
+
# You help users with product inquiries and order management.
|
|
238
|
+
# You are friendly, professional, and knowledgeable.`;
|
|
239
|
+
const personaAnswer = await safePrompt([
|
|
240
|
+
{
|
|
241
|
+
type: 'editor',
|
|
242
|
+
name: 'newPersona',
|
|
243
|
+
message: 'Edit persona (will open in your default editor):',
|
|
244
|
+
default: defaultPersona,
|
|
245
|
+
validate: (input) => {
|
|
246
|
+
if (!input.trim()) {
|
|
247
|
+
return 'Persona cannot be empty';
|
|
248
|
+
}
|
|
249
|
+
// Remove comment lines for validation
|
|
250
|
+
const withoutComments = input.split('\n')
|
|
251
|
+
.filter((line) => !line.trim().startsWith('#'))
|
|
252
|
+
.join('\n')
|
|
253
|
+
.trim();
|
|
254
|
+
if (!withoutComments) {
|
|
255
|
+
return 'Persona cannot be empty (only comments found)';
|
|
256
|
+
}
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
]);
|
|
261
|
+
if (!personaAnswer)
|
|
262
|
+
return;
|
|
263
|
+
const { newPersona } = personaAnswer;
|
|
264
|
+
const trimmedPersona = newPersona.trim();
|
|
265
|
+
writeProgress("🔄 Saving persona to lua.skill.yaml...");
|
|
266
|
+
const success = saveSandboxPersona(trimmedPersona);
|
|
267
|
+
if (success) {
|
|
268
|
+
writeSuccess("✅ Persona saved to lua.skill.yaml successfully");
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
console.error("❌ Failed to save persona to lua.skill.yaml");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Create a new persona version
|
|
276
|
+
*/
|
|
277
|
+
async function createPersonaVersion(context, currentPersona) {
|
|
278
|
+
if (!currentPersona || !currentPersona.trim()) {
|
|
279
|
+
console.log("\n❌ No persona to create version from. Please edit and save a persona first.\n");
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
console.log("\n⚠️ This will create a new persona version that can be deployed to production.");
|
|
283
|
+
const confirmAnswer = await safePrompt([
|
|
284
|
+
{
|
|
285
|
+
type: 'confirm',
|
|
286
|
+
name: 'confirm',
|
|
287
|
+
message: 'Create new persona version?',
|
|
288
|
+
default: true
|
|
289
|
+
}
|
|
290
|
+
]);
|
|
291
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
292
|
+
console.log("\nℹ️ Version creation cancelled.\n");
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
writeProgress("🔄 Creating persona version...");
|
|
296
|
+
try {
|
|
297
|
+
const response = await fetch(`${BASE_URLS.API}/developer/agents/${context.agentId}/persona/version`, {
|
|
298
|
+
method: 'POST',
|
|
299
|
+
headers: {
|
|
300
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
301
|
+
'Content-Type': 'application/json'
|
|
302
|
+
},
|
|
303
|
+
body: JSON.stringify({ persona: currentPersona })
|
|
304
|
+
});
|
|
305
|
+
if (!response.ok) {
|
|
306
|
+
const errorText = await response.text();
|
|
307
|
+
throw new Error(`HTTP error! status: ${response.status}, ${errorText}`);
|
|
308
|
+
}
|
|
309
|
+
const data = await response.json();
|
|
310
|
+
const versionNum = data.version || data.data?.version || 'N/A';
|
|
311
|
+
writeSuccess(`✅ Persona version created successfully (version: ${versionNum})`);
|
|
312
|
+
writeInfo("💡 You can deploy this version from the production environment.");
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
console.error('❌ Error creating persona version:', error);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* List persona versions
|
|
320
|
+
*/
|
|
321
|
+
async function listPersonaVersions(context) {
|
|
322
|
+
writeProgress("🔄 Loading persona versions...");
|
|
323
|
+
try {
|
|
324
|
+
const response = await fetch(`${BASE_URLS.API}/developer/agents/${context.agentId}/persona/versions`, {
|
|
325
|
+
method: 'GET',
|
|
326
|
+
headers: {
|
|
327
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
328
|
+
'Content-Type': 'application/json'
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
if (!response.ok) {
|
|
332
|
+
const errorText = await response.text();
|
|
333
|
+
console.error(`\n❌ API Error: ${response.status} - ${errorText}\n`);
|
|
334
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
335
|
+
}
|
|
336
|
+
const data = await response.json();
|
|
337
|
+
// Handle different response formats
|
|
338
|
+
let versions = [];
|
|
339
|
+
if (Array.isArray(data)) {
|
|
340
|
+
versions = data;
|
|
341
|
+
}
|
|
342
|
+
else if (data.data && Array.isArray(data.data)) {
|
|
343
|
+
versions = data.data;
|
|
344
|
+
}
|
|
345
|
+
else if (data.versions && Array.isArray(data.versions)) {
|
|
346
|
+
versions = data.versions;
|
|
347
|
+
}
|
|
348
|
+
if (versions.length === 0) {
|
|
349
|
+
console.log("\nℹ️ No persona versions found.\n");
|
|
350
|
+
console.log("💡 Create a version first from sandbox mode.\n");
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
// Sort versions by date (newest first)
|
|
354
|
+
const sortedVersions = versions.sort((a, b) => {
|
|
355
|
+
return b.createdDate - a.createdDate;
|
|
356
|
+
});
|
|
357
|
+
// Let user select a version to view
|
|
358
|
+
const versionAnswer = await safePrompt([
|
|
359
|
+
{
|
|
360
|
+
type: 'list',
|
|
361
|
+
name: 'selectedVersionIndex',
|
|
362
|
+
message: 'Select a persona version to view:',
|
|
363
|
+
choices: sortedVersions.map((version, index) => {
|
|
364
|
+
const date = new Date(version.createdDate);
|
|
365
|
+
const dateStr = date.toLocaleDateString();
|
|
366
|
+
const deployedMark = version.isCurrent ? ' ⭐ CURRENT' : '';
|
|
367
|
+
return {
|
|
368
|
+
name: `Version ${version.version} (${dateStr})${deployedMark}`,
|
|
369
|
+
value: index
|
|
370
|
+
};
|
|
371
|
+
})
|
|
372
|
+
}
|
|
373
|
+
]);
|
|
374
|
+
if (!versionAnswer)
|
|
375
|
+
return;
|
|
376
|
+
// Show the selected version's full persona
|
|
377
|
+
await viewVersionDetails([sortedVersions[versionAnswer.selectedVersionIndex]]);
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
console.error('❌ Error loading persona versions:', error);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* View details of a specific version
|
|
385
|
+
*/
|
|
386
|
+
async function viewVersionDetails(versions) {
|
|
387
|
+
const version = versions[0]; // Already pre-selected
|
|
388
|
+
const date = new Date(version.createdDate);
|
|
389
|
+
console.log("\n" + "=".repeat(60));
|
|
390
|
+
console.log(`Persona Version ${version.version}`);
|
|
391
|
+
console.log("=".repeat(60));
|
|
392
|
+
console.log(`Created: ${date.toLocaleString()}`);
|
|
393
|
+
console.log(`Status: ${version.isCurrent ? '⭐ CURRENT' : 'Available'}`);
|
|
394
|
+
if (version.createdBy) {
|
|
395
|
+
console.log(`Created by: ${version.createdBy}`);
|
|
396
|
+
}
|
|
397
|
+
console.log("=".repeat(60) + "\n");
|
|
398
|
+
console.log(version.persona);
|
|
399
|
+
console.log("\n" + "=".repeat(60) + "\n");
|
|
400
|
+
await inquirer.prompt([
|
|
401
|
+
{
|
|
402
|
+
type: 'input',
|
|
403
|
+
name: 'continue',
|
|
404
|
+
message: 'Press Enter to continue...'
|
|
405
|
+
}
|
|
406
|
+
]);
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Deploy a persona version to production
|
|
410
|
+
*/
|
|
411
|
+
async function deployPersonaVersion(context) {
|
|
412
|
+
writeProgress("🔄 Loading persona versions...");
|
|
413
|
+
try {
|
|
414
|
+
const response = await fetch(`${BASE_URLS.API}/developer/agents/${context.agentId}/persona/versions`, {
|
|
415
|
+
method: 'GET',
|
|
416
|
+
headers: {
|
|
417
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
418
|
+
'Content-Type': 'application/json'
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
if (!response.ok) {
|
|
422
|
+
const errorText = await response.text();
|
|
423
|
+
console.error(`\n❌ API Error: ${response.status} - ${errorText}\n`);
|
|
424
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
425
|
+
}
|
|
426
|
+
const data = await response.json();
|
|
427
|
+
// Handle different response formats
|
|
428
|
+
let versions = [];
|
|
429
|
+
if (Array.isArray(data)) {
|
|
430
|
+
versions = data;
|
|
431
|
+
}
|
|
432
|
+
else if (data.data && Array.isArray(data.data)) {
|
|
433
|
+
versions = data.data;
|
|
434
|
+
}
|
|
435
|
+
else if (data.versions && Array.isArray(data.versions)) {
|
|
436
|
+
versions = data.versions;
|
|
437
|
+
}
|
|
438
|
+
if (versions.length === 0) {
|
|
439
|
+
console.log("\nℹ️ No persona versions available to deploy.\n");
|
|
440
|
+
console.log("💡 Create a version first from sandbox mode.\n");
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
// Sort versions by date (newest first)
|
|
444
|
+
const sortedVersions = versions.sort((a, b) => b.createdDate - a.createdDate);
|
|
445
|
+
console.log("\n" + "=".repeat(60));
|
|
446
|
+
console.log("🌙 Select Persona Version to Deploy");
|
|
447
|
+
console.log("=".repeat(60) + "\n");
|
|
448
|
+
const versionAnswer = await safePrompt([
|
|
449
|
+
{
|
|
450
|
+
type: 'list',
|
|
451
|
+
name: 'selectedVersion',
|
|
452
|
+
message: 'Select version to deploy:',
|
|
453
|
+
choices: sortedVersions.map((v) => {
|
|
454
|
+
const date = new Date(v.createdDate);
|
|
455
|
+
const dateStr = date.toLocaleDateString();
|
|
456
|
+
const timeStr = date.toLocaleTimeString();
|
|
457
|
+
const currentMark = v.isCurrent ? ' ⭐ CURRENTLY DEPLOYED' : '';
|
|
458
|
+
return {
|
|
459
|
+
name: `Version ${v.version} - ${dateStr} ${timeStr}${currentMark}`,
|
|
460
|
+
value: v.version
|
|
461
|
+
};
|
|
462
|
+
})
|
|
463
|
+
}
|
|
464
|
+
]);
|
|
465
|
+
if (!versionAnswer)
|
|
466
|
+
return;
|
|
467
|
+
const { selectedVersion } = versionAnswer;
|
|
468
|
+
// Show confirmation
|
|
469
|
+
console.log("\n⚠️ WARNING: You are about to deploy to PRODUCTION!");
|
|
470
|
+
console.log("⚠️ This will affect ALL users immediately.\n");
|
|
471
|
+
const confirmAnswer = await safePrompt([
|
|
472
|
+
{
|
|
473
|
+
type: 'confirm',
|
|
474
|
+
name: 'confirm',
|
|
475
|
+
message: 'Are you absolutely sure you want to deploy this persona version?',
|
|
476
|
+
default: false
|
|
477
|
+
}
|
|
478
|
+
]);
|
|
479
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
480
|
+
console.log("\n❌ Deployment cancelled.\n");
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
writeProgress("🔄 Deploying persona version...");
|
|
484
|
+
const deployResponse = await fetch(`${BASE_URLS.API}/developer/agents/${context.agentId}/persona/version/${selectedVersion}`, {
|
|
485
|
+
method: 'POST',
|
|
486
|
+
headers: {
|
|
487
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
488
|
+
'Content-Type': 'application/json'
|
|
489
|
+
},
|
|
490
|
+
body: JSON.stringify({})
|
|
491
|
+
});
|
|
492
|
+
if (!deployResponse.ok) {
|
|
493
|
+
const errorText = await deployResponse.text();
|
|
494
|
+
console.error(`\n❌ Deploy Error: ${deployResponse.status} - ${errorText}\n`);
|
|
495
|
+
throw new Error(`HTTP error! status: ${deployResponse.status}`);
|
|
496
|
+
}
|
|
497
|
+
writeSuccess(`✅ Persona version ${selectedVersion} deployed successfully to production`);
|
|
498
|
+
writeInfo("💡 The new persona is now active for all users.");
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
console.error('❌ Error deploying persona version:', error);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production Command
|
|
3
|
+
* Overview and management of production environment
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Main production command - overview of production environment
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - View current persona and versions
|
|
10
|
+
* - View deployed skills and versions
|
|
11
|
+
* - Manage environment variables
|
|
12
|
+
*
|
|
13
|
+
* @returns Promise that resolves when command completes
|
|
14
|
+
*/
|
|
15
|
+
export declare function productionCommand(): Promise<void>;
|