lua-cli 3.0.0-alpha.5 → 3.0.0-alpha.6

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.
@@ -18,10 +18,7 @@
18
18
  * Note: This does NOT deploy to production. Use `lua deploy` for that.
19
19
  *
20
20
  * @param type - Optional type argument ('skill', 'persona', 'webhook', 'job', 'preprocessor', 'postprocessor', or 'all')
21
- * @param options - Command options (force, autoDeploy)
21
+ * @param cmdObj - Commander command object with options
22
22
  * @returns Promise that resolves when push completes
23
23
  */
24
- export declare function pushCommand(type?: string, options?: {
25
- force?: boolean;
26
- autoDeploy?: boolean;
27
- }): Promise<void>;
24
+ export declare function pushCommand(type?: string, cmdObj?: any): Promise<void>;
@@ -32,15 +32,20 @@ import PostProcessorApi from '../api/postprocessor.api.service.js';
32
32
  * Note: This does NOT deploy to production. Use `lua deploy` for that.
33
33
  *
34
34
  * @param type - Optional type argument ('skill', 'persona', 'webhook', 'job', 'preprocessor', 'postprocessor', or 'all')
35
- * @param options - Command options (force, autoDeploy)
35
+ * @param cmdObj - Commander command object with options
36
36
  * @returns Promise that resolves when push completes
37
37
  */
38
- export async function pushCommand(type, options) {
38
+ export async function pushCommand(type, cmdObj) {
39
39
  return withErrorHandling(async () => {
40
+ // Extract options from Commander command object
41
+ const options = {
42
+ force: cmdObj?.force || false,
43
+ autoDeploy: cmdObj?.autoDeploy || false
44
+ };
40
45
  let selectedType;
41
46
  // Handle 'all' type with force flag
42
47
  if (type === 'all') {
43
- if (!options?.force) {
48
+ if (!options.force) {
44
49
  console.error('āŒ The "all" type requires the --force flag');
45
50
  console.log('\nUsage:');
46
51
  console.log(' lua push all --force Push all components without prompts');
@@ -1058,6 +1063,9 @@ async function deployVersionAfterPush(apiKey, agentId, selectedSkill, pushedVers
1058
1063
  */
1059
1064
  async function pushAllCommand(options) {
1060
1065
  writeProgress("šŸš€ Push All - Pushing all components to server...\n");
1066
+ if (options.autoDeploy) {
1067
+ writeInfo("šŸš€ Auto-deploy to production is ENABLED\n");
1068
+ }
1061
1069
  // Step 1: Compile first
1062
1070
  writeProgress("šŸ“¦ Compiling project...");
1063
1071
  await compileCommand();
@@ -1080,7 +1088,24 @@ async function pushAllCommand(options) {
1080
1088
  process.exit(1);
1081
1089
  }
1082
1090
  const deployData = JSON.parse(fs.readFileSync(deployJsonPath, 'utf8'));
1083
- // Track results
1091
+ // Step 3b: Read bundled webhooks and jobs from dist/
1092
+ const webhooksJsonPath = path.join(process.cwd(), 'dist', 'webhooks.json');
1093
+ const jobsJsonPath = path.join(process.cwd(), 'dist', 'jobs.json');
1094
+ const preprocessorsJsonPath = path.join(process.cwd(), 'dist', 'preprocessors.json');
1095
+ const postprocessorsJsonPath = path.join(process.cwd(), 'dist', 'postprocessors.json');
1096
+ const bundledWebhooks = fs.existsSync(webhooksJsonPath)
1097
+ ? JSON.parse(fs.readFileSync(webhooksJsonPath, 'utf8'))
1098
+ : [];
1099
+ const bundledJobs = fs.existsSync(jobsJsonPath)
1100
+ ? JSON.parse(fs.readFileSync(jobsJsonPath, 'utf8'))
1101
+ : [];
1102
+ const bundledPreprocessors = fs.existsSync(preprocessorsJsonPath)
1103
+ ? JSON.parse(fs.readFileSync(preprocessorsJsonPath, 'utf8'))
1104
+ : [];
1105
+ const bundledPostprocessors = fs.existsSync(postprocessorsJsonPath)
1106
+ ? JSON.parse(fs.readFileSync(postprocessorsJsonPath, 'utf8'))
1107
+ : [];
1108
+ // Track results for both push and deploy
1084
1109
  const results = {
1085
1110
  skills: [],
1086
1111
  webhooks: [],
@@ -1088,6 +1113,12 @@ async function pushAllCommand(options) {
1088
1113
  preprocessors: [],
1089
1114
  postprocessors: []
1090
1115
  };
1116
+ // Track what needs to be deployed
1117
+ const toDeploySkills = [];
1118
+ const toDeployWebhooks = [];
1119
+ const toDeployJobs = [];
1120
+ const toDeployPreprocessors = [];
1121
+ const toDeployPostprocessors = [];
1091
1122
  // Step 4: Push all skills
1092
1123
  if (config.skills && config.skills.length > 0) {
1093
1124
  writeProgress(`\nšŸ“¦ Pushing ${config.skills.length} skill(s)...`);
@@ -1122,14 +1153,17 @@ async function pushAllCommand(options) {
1122
1153
  inputSchema: skillData.inputSchema,
1123
1154
  outputSchema: skillData.outputSchema,
1124
1155
  });
1156
+ if (!pushResult.success) {
1157
+ console.error(` āŒ Failed to push ${skillConfig.name}:`, pushResult.error?.message);
1158
+ continue;
1159
+ }
1125
1160
  // Update YAML with new version
1126
1161
  updateSkillVersionInYaml(skillConfig.name, newVersion);
1127
1162
  results.skills.push({ name: skillConfig.name, version: newVersion, skillId });
1128
1163
  writeSuccess(` āœ… ${skillConfig.name} v${newVersion} pushed`);
1129
- // Auto-deploy if requested
1164
+ // Queue for deployment if requested
1130
1165
  if (options.autoDeploy) {
1131
- await publishVersion(apiKey, agentId, skillId, newVersion);
1132
- writeSuccess(` šŸš€ ${skillConfig.name} v${newVersion} deployed to production`);
1166
+ toDeploySkills.push({ skillId, version: newVersion, name: skillConfig.name });
1133
1167
  }
1134
1168
  }
1135
1169
  catch (error) {
@@ -1142,9 +1176,9 @@ async function pushAllCommand(options) {
1142
1176
  writeProgress(`\nšŸŖ Pushing ${config.webhooks.length} webhook(s)...`);
1143
1177
  for (const webhookConfig of config.webhooks) {
1144
1178
  try {
1145
- const webhookData = deployData.webhooks?.find((w) => w.name === webhookConfig.name);
1179
+ const webhookData = bundledWebhooks.find((w) => w.name === webhookConfig.name);
1146
1180
  if (!webhookData) {
1147
- console.warn(`āš ļø Webhook "${webhookConfig.name}" not found in deploy.json, skipping`);
1181
+ console.warn(`āš ļø Webhook "${webhookConfig.name}" not found in compiled data, skipping`);
1148
1182
  continue;
1149
1183
  }
1150
1184
  // Validate webhookId and version exist
@@ -1188,18 +1222,9 @@ async function pushAllCommand(options) {
1188
1222
  updateWebhookVersionInYaml(webhookConfig.name, newVersion);
1189
1223
  results.webhooks.push({ name: webhookConfig.name, version: newVersion });
1190
1224
  writeSuccess(` āœ… ${webhookConfig.name} v${newVersion} pushed`);
1191
- // Auto-deploy if requested
1225
+ // Queue for deployment if requested
1192
1226
  if (options.autoDeploy) {
1193
- const deployResponse = await fetch(`${BASE_URLS.API}/developer/webhooks/${agentId}/${webhookConfig.webhookId}/${newVersion}/publish`, {
1194
- method: 'PUT',
1195
- headers: {
1196
- 'Authorization': `Bearer ${apiKey}`,
1197
- 'Content-Type': 'application/json'
1198
- }
1199
- });
1200
- if (deployResponse.ok) {
1201
- writeSuccess(` šŸš€ ${webhookConfig.name} v${newVersion} deployed to production`);
1202
- }
1227
+ toDeployWebhooks.push({ webhookId: webhookConfig.webhookId, version: newVersion, name: webhookConfig.name });
1203
1228
  }
1204
1229
  }
1205
1230
  catch (error) {
@@ -1212,9 +1237,9 @@ async function pushAllCommand(options) {
1212
1237
  writeProgress(`\nā° Pushing ${config.jobs.length} job(s)...`);
1213
1238
  for (const jobConfig of config.jobs) {
1214
1239
  try {
1215
- const jobData = deployData.jobs?.find((j) => j.name === jobConfig.name);
1240
+ const jobData = bundledJobs.find((j) => j.name === jobConfig.name);
1216
1241
  if (!jobData) {
1217
- console.warn(`āš ļø Job "${jobConfig.name}" not found in deploy.json, skipping`);
1242
+ console.warn(`āš ļø Job "${jobConfig.name}" not found in compiled data, skipping`);
1218
1243
  continue;
1219
1244
  }
1220
1245
  // Validate jobId and version exist
@@ -1259,18 +1284,9 @@ async function pushAllCommand(options) {
1259
1284
  updateJobVersionInYaml(jobConfig.name, newVersion);
1260
1285
  results.jobs.push({ name: jobConfig.name, version: newVersion });
1261
1286
  writeSuccess(` āœ… ${jobConfig.name} v${newVersion} pushed`);
1262
- // Auto-deploy if requested
1287
+ // Queue for deployment if requested
1263
1288
  if (options.autoDeploy) {
1264
- const deployResponse = await fetch(`${BASE_URLS.API}/developer/jobs/${agentId}/${jobConfig.jobId}/${newVersion}/publish`, {
1265
- method: 'PUT',
1266
- headers: {
1267
- 'Authorization': `Bearer ${apiKey}`,
1268
- 'Content-Type': 'application/json'
1269
- }
1270
- });
1271
- if (deployResponse.ok) {
1272
- writeSuccess(` šŸš€ ${jobConfig.name} v${newVersion} deployed to production`);
1273
- }
1289
+ toDeployJobs.push({ jobId: jobConfig.jobId, version: newVersion, name: jobConfig.name });
1274
1290
  }
1275
1291
  }
1276
1292
  catch (error) {
@@ -1284,9 +1300,9 @@ async function pushAllCommand(options) {
1284
1300
  const preprocessorService = new PreProcessorApi(BASE_URLS.API, apiKey, agentId);
1285
1301
  for (const processorConfig of config.preprocessors) {
1286
1302
  try {
1287
- const processorData = deployData.preprocessors?.find((p) => p.name === processorConfig.name);
1303
+ const processorData = bundledPreprocessors.find((p) => p.name === processorConfig.name);
1288
1304
  if (!processorData) {
1289
- console.warn(`āš ļø Preprocessor "${processorConfig.name}" not found in deploy.json, skipping`);
1305
+ console.warn(`āš ļø Preprocessor "${processorConfig.name}" not found in compiled data, skipping`);
1290
1306
  continue;
1291
1307
  }
1292
1308
  // Validate preprocessorId and version exist
@@ -1323,12 +1339,9 @@ async function pushAllCommand(options) {
1323
1339
  updateProcessorVersionInYaml('preprocessors', processorConfig.name, newVersion);
1324
1340
  results.preprocessors.push({ name: processorConfig.name, version: newVersion });
1325
1341
  writeSuccess(` āœ… ${processorConfig.name} v${newVersion} pushed`);
1326
- // Auto-deploy if requested
1342
+ // Queue for deployment if requested
1327
1343
  if (options.autoDeploy) {
1328
- const deployResult = await preprocessorService.publishPreProcessorVersion(preprocessorId, newVersion);
1329
- if (deployResult.success) {
1330
- writeSuccess(` šŸš€ ${processorConfig.name} v${newVersion} deployed to production`);
1331
- }
1344
+ toDeployPreprocessors.push({ preprocessorId, version: newVersion, name: processorConfig.name });
1332
1345
  }
1333
1346
  }
1334
1347
  catch (error) {
@@ -1342,9 +1355,9 @@ async function pushAllCommand(options) {
1342
1355
  const postprocessorService = new PostProcessorApi(BASE_URLS.API, apiKey, agentId);
1343
1356
  for (const processorConfig of config.postprocessors) {
1344
1357
  try {
1345
- const processorData = deployData.postprocessors?.find((p) => p.name === processorConfig.name);
1358
+ const processorData = bundledPostprocessors.find((p) => p.name === processorConfig.name);
1346
1359
  if (!processorData) {
1347
- console.warn(`āš ļø Postprocessor "${processorConfig.name}" not found in deploy.json, skipping`);
1360
+ console.warn(`āš ļø Postprocessor "${processorConfig.name}" not found in compiled data, skipping`);
1348
1361
  continue;
1349
1362
  }
1350
1363
  // Validate postprocessorId and version exist
@@ -1381,12 +1394,9 @@ async function pushAllCommand(options) {
1381
1394
  updateProcessorVersionInYaml('postprocessors', processorConfig.name, newVersion);
1382
1395
  results.postprocessors.push({ name: processorConfig.name, version: newVersion });
1383
1396
  writeSuccess(` āœ… ${processorConfig.name} v${newVersion} pushed`);
1384
- // Auto-deploy if requested
1397
+ // Queue for deployment if requested
1385
1398
  if (options.autoDeploy) {
1386
- const deployResult = await postprocessorService.publishPostProcessorVersion(postprocessorId, newVersion);
1387
- if (deployResult.success) {
1388
- writeSuccess(` šŸš€ ${processorConfig.name} v${newVersion} deployed to production`);
1389
- }
1399
+ toDeployPostprocessors.push({ postprocessorId, version: newVersion, name: processorConfig.name });
1390
1400
  }
1391
1401
  }
1392
1402
  catch (error) {
@@ -1394,7 +1404,104 @@ async function pushAllCommand(options) {
1394
1404
  }
1395
1405
  }
1396
1406
  }
1397
- // Step 9: Print summary
1407
+ // Step 9: Deploy all components if autoDeploy is enabled
1408
+ if (options.autoDeploy && (toDeploySkills.length > 0 || toDeployWebhooks.length > 0 || toDeployJobs.length > 0 || toDeployPreprocessors.length > 0 || toDeployPostprocessors.length > 0)) {
1409
+ writeProgress('\nšŸš€ Deploying all pushed versions to production...');
1410
+ writeInfo('ā±ļø Waiting for server to process versions (5 seconds)...\n');
1411
+ // Wait for server to process all pushed versions
1412
+ await new Promise(resolve => setTimeout(resolve, 5000));
1413
+ // Deploy all skills
1414
+ if (toDeploySkills.length > 0) {
1415
+ writeProgress(`šŸ“¦ Deploying ${toDeploySkills.length} skill(s)...`);
1416
+ for (const skill of toDeploySkills) {
1417
+ const deployed = await retryDeploy(() => publishVersion(apiKey, agentId, skill.skillId, skill.version), skill.name, skill.version, 2 // Only 2 retries since we already waited
1418
+ );
1419
+ if (deployed) {
1420
+ writeSuccess(` šŸš€ ${skill.name} v${skill.version} deployed`);
1421
+ }
1422
+ else {
1423
+ console.warn(` āš ļø ${skill.name} deployment failed`);
1424
+ }
1425
+ }
1426
+ }
1427
+ // Deploy all webhooks
1428
+ if (toDeployWebhooks.length > 0) {
1429
+ writeProgress(`šŸŖ Deploying ${toDeployWebhooks.length} webhook(s)...`);
1430
+ for (const webhook of toDeployWebhooks) {
1431
+ const deployed = await retryDeploy(async () => {
1432
+ const response = await fetch(`${BASE_URLS.API}/developer/webhooks/${agentId}/${webhook.webhookId}/${webhook.version}/publish`, {
1433
+ method: 'PUT',
1434
+ headers: {
1435
+ 'Authorization': `Bearer ${apiKey}`,
1436
+ 'Content-Type': 'application/json'
1437
+ }
1438
+ });
1439
+ if (!response.ok) {
1440
+ throw new Error(`HTTP ${response.status}`);
1441
+ }
1442
+ }, webhook.name, webhook.version, 2);
1443
+ if (deployed) {
1444
+ writeSuccess(` šŸš€ ${webhook.name} v${webhook.version} deployed`);
1445
+ }
1446
+ else {
1447
+ console.warn(` āš ļø ${webhook.name} deployment failed`);
1448
+ }
1449
+ }
1450
+ }
1451
+ // Deploy all jobs
1452
+ if (toDeployJobs.length > 0) {
1453
+ writeProgress(`ā° Deploying ${toDeployJobs.length} job(s)...`);
1454
+ for (const job of toDeployJobs) {
1455
+ const deployed = await retryDeploy(async () => {
1456
+ const response = await fetch(`${BASE_URLS.API}/developer/jobs/${agentId}/${job.jobId}/${job.version}/publish`, {
1457
+ method: 'PUT',
1458
+ headers: {
1459
+ 'Authorization': `Bearer ${apiKey}`,
1460
+ 'Content-Type': 'application/json'
1461
+ }
1462
+ });
1463
+ if (!response.ok) {
1464
+ throw new Error(`HTTP ${response.status}`);
1465
+ }
1466
+ }, job.name, job.version, 2);
1467
+ if (deployed) {
1468
+ writeSuccess(` šŸš€ ${job.name} v${job.version} deployed`);
1469
+ }
1470
+ else {
1471
+ console.warn(` āš ļø ${job.name} deployment failed`);
1472
+ }
1473
+ }
1474
+ }
1475
+ // Deploy all preprocessors
1476
+ if (toDeployPreprocessors.length > 0) {
1477
+ writeProgress(`šŸ“„ Deploying ${toDeployPreprocessors.length} preprocessor(s)...`);
1478
+ const preprocessorService = new PreProcessorApi(BASE_URLS.API, apiKey, agentId);
1479
+ for (const processor of toDeployPreprocessors) {
1480
+ const deployed = await retryDeploy(() => preprocessorService.publishPreProcessorVersion(processor.preprocessorId, processor.version), processor.name, processor.version, 2);
1481
+ if (deployed) {
1482
+ writeSuccess(` šŸš€ ${processor.name} v${processor.version} deployed`);
1483
+ }
1484
+ else {
1485
+ console.warn(` āš ļø ${processor.name} deployment failed`);
1486
+ }
1487
+ }
1488
+ }
1489
+ // Deploy all postprocessors
1490
+ if (toDeployPostprocessors.length > 0) {
1491
+ writeProgress(`šŸ“¤ Deploying ${toDeployPostprocessors.length} postprocessor(s)...`);
1492
+ const postprocessorService = new PostProcessorApi(BASE_URLS.API, apiKey, agentId);
1493
+ for (const processor of toDeployPostprocessors) {
1494
+ const deployed = await retryDeploy(() => postprocessorService.publishPostProcessorVersion(processor.postprocessorId, processor.version), processor.name, processor.version, 2);
1495
+ if (deployed) {
1496
+ writeSuccess(` šŸš€ ${processor.name} v${processor.version} deployed`);
1497
+ }
1498
+ else {
1499
+ console.warn(` āš ļø ${processor.name} deployment failed`);
1500
+ }
1501
+ }
1502
+ }
1503
+ }
1504
+ // Step 10: Print summary
1398
1505
  writeSuccess('\nāœ… Push All Complete!\n');
1399
1506
  if (results.skills.length > 0) {
1400
1507
  console.log(`šŸ› ļø Skills (${results.skills.length}):`);
@@ -1435,3 +1542,25 @@ function bumpPatchVersion(version) {
1435
1542
  const newPatch = parseInt(patch, 10) + 1;
1436
1543
  return `${major}.${minor}.${newPatch}`;
1437
1544
  }
1545
+ /**
1546
+ * Retry deployment with exponential backoff
1547
+ * The server needs time to process pushed versions before they can be deployed
1548
+ */
1549
+ async function retryDeploy(deployFn, componentName, version, maxRetries = 3) {
1550
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
1551
+ try {
1552
+ const delay = attempt * 2000; // 2s, 4s, 6s (longer delays)
1553
+ await new Promise(resolve => setTimeout(resolve, delay));
1554
+ await deployFn();
1555
+ return true;
1556
+ }
1557
+ catch (error) {
1558
+ if (attempt === maxRetries) {
1559
+ console.error(` [Retry ${attempt}/${maxRetries}] Deploy failed: ${error.message}`);
1560
+ return false;
1561
+ }
1562
+ // Continue to next retry silently
1563
+ }
1564
+ }
1565
+ return false;
1566
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lua-cli",
3
- "version": "3.0.0-alpha.5",
3
+ "version": "3.0.0-alpha.6",
4
4
  "description": "Command-line interface for Lua AI platform - develop, test, and deploy LuaSkills with custom tools",
5
5
  "readmeFilename": "README.md",
6
6
  "main": "dist/api-exports.js",
@@ -1,47 +1,69 @@
1
1
  agent:
2
2
  agentId: baseAgent_agent_1760922427216_fk9w0ezhh
3
3
  orgId: 026cc41b-e013-4474-9b65-5a15f8881f92
4
- persona: |
5
- Meet Vivienne, the vibrant and dynamic assistant at V3 Test, a lively retail and consumer goods store that specializes in bringing a splash of color and excitement to everyday life. Vivienne embodies the brand's energetic and fun personality, always ready to engage with customers in a way that makes shopping an enjoyable and memorable experience. Her role is to be the friendly face and knowledgeable guide for anyone who steps into the store, whether they're looking for the latest fashion trends or a unique gift for a loved one.
4
+ persona: >
5
+ Meet Vivienne, the vibrant and dynamic assistant at V3 Test, a lively retail and consumer goods store that
6
+ specializes in bringing a splash of color and excitement to everyday life. Vivienne embodies the brand's energetic
7
+ and fun personality, always ready to engage with customers in a way that makes shopping an enjoyable and memorable
8
+ experience. Her role is to be the friendly face and knowledgeable guide for anyone who steps into the store, whether
9
+ they're looking for the latest fashion trends or a unique gift for a loved one.
6
10
 
7
- V3 Test is all about creating a joyful and spirited shopping environment, and Vivienne is the perfect personification of this ethos. She is lively, approachable, and always ready with a smile, making every interaction feel like a conversation with a good friend. Her voice is warm and enthusiastic, with a hint of playfulness that puts customers at ease and encourages them to explore the store's offerings.
8
11
 
9
- Vivienne's target customers are diverse, ranging from young adults in their twenties who are fashion-forward and tech-savvy, to busy parents looking for quality products that add a touch of fun to their family life. She understands the fast-paced lifestyle of her customers and is adept at tailoring her approach to meet their individual needs, whether they're in a hurry or have time to browse.
12
+ V3 Test is all about creating a joyful and spirited shopping environment, and Vivienne is the perfect
13
+ personification of this ethos. She is lively, approachable, and always ready with a smile, making every interaction
14
+ feel like a conversation with a good friend. Her voice is warm and enthusiastic, with a hint of playfulness that
15
+ puts customers at ease and encourages them to explore the store's offerings.
10
16
 
11
- Her sales approach is consultative and friendly, focusing on understanding the customer's needs and preferences before suggesting products that align with their style and personality. Vivienne is confident in her recommendations, always ready to upsell when appropriate, but never pushy. She believes in building relationships with customers, ensuring they leave the store not only with products they love but also with a positive impression of the brand.
12
17
 
13
- In terms of communication style, Vivienne strikes a perfect balance between being informal and efficient. She is warm and engaging, making customers feel valued and appreciated, while also being mindful of their time. Her interactions are peppered with humor and light-hearted banter, creating a shopping experience that is both enjoyable and efficient. Whether it's through in-person interactions or digital communication, Vivienne ensures that every customer feels like a part of the V3 Test family.
18
+ Vivienne's target customers are diverse, ranging from young adults in their twenties who are fashion-forward and
19
+ tech-savvy, to busy parents looking for quality products that add a touch of fun to their family life. She
20
+ understands the fast-paced lifestyle of her customers and is adept at tailoring her approach to meet their
21
+ individual needs, whether they're in a hurry or have time to browse.
22
+
23
+
24
+ Her sales approach is consultative and friendly, focusing on understanding the customer's needs and preferences
25
+ before suggesting products that align with their style and personality. Vivienne is confident in her
26
+ recommendations, always ready to upsell when appropriate, but never pushy. She believes in building relationships
27
+ with customers, ensuring they leave the store not only with products they love but also with a positive impression
28
+ of the brand.
29
+
30
+
31
+ In terms of communication style, Vivienne strikes a perfect balance between being informal and efficient. She is
32
+ warm and engaging, making customers feel valued and appreciated, while also being mindful of their time. Her
33
+ interactions are peppered with humor and light-hearted banter, creating a shopping experience that is both enjoyable
34
+ and efficient. Whether it's through in-person interactions or digital communication, Vivienne ensures that every
35
+ customer feels like a part of the V3 Test family.
14
36
  welcomeMessage: Hi, I am your AI assistant. How can I help you today?
15
37
  skills:
16
38
  - name: general-skill
17
39
  version: 0.0.4
18
40
  skillId: 1faf9b3a-e352-4e63-a6c4-a3deca815361
19
41
  - name: user-data-skill
20
- version: 0.0.2
42
+ version: 0.0.12
21
43
  skillId: e0c382c1-f469-4880-962a-a756ea3c1411
22
44
  - name: product-skill
23
- version: 0.0.2
45
+ version: 0.0.12
24
46
  skillId: d4cdc7bc-6d42-4232-902d-2b9cf68bd74a
25
47
  - name: basket-skill
26
- version: 0.0.2
48
+ version: 0.0.11
27
49
  skillId: 5b06c5ff-7cf3-49c4-8641-142270c81db4
28
50
  - name: order-skill
29
- version: 0.0.2
51
+ version: 0.0.11
30
52
  skillId: d4045304-7c30-4750-9edd-340eb1357a39
31
53
  - name: custom-data-skill
32
- version: 0.0.2
54
+ version: 0.0.10
33
55
  skillId: 83fe411c-90a1-4bd3-9271-ac8e03d6a3be
34
56
  - name: payment-skill
35
- version: 0.0.2
57
+ version: 0.0.10
36
58
  skillId: f2248c02-c6c6-4c3a-89bf-ff09ec11529a
37
59
  jobs:
38
60
  - name: test-job
39
- version: 1.0.2
61
+ version: 1.0.9
40
62
  jobId: d66b73a0-f944-4718-b6a2-f07bfeabd625
41
63
  schedule:
42
64
  type: once
43
65
  executeAt: '2025-10-20T01:08:04.639Z'
44
66
  webhooks:
45
67
  - name: test-webhook
46
- version: 1.0.1
68
+ version: 1.0.8
47
69
  webhookId: c967fd58-1d4d-49b6-8fa6-ec36b4d23e7f
@@ -20,7 +20,7 @@
20
20
  "inquirer": "^12.9.6",
21
21
  "stripe": "^17.5.0",
22
22
  "js-yaml": "^4.1.0",
23
- "lua-cli": "^3.0.0-alpha.5",
23
+ "lua-cli": "^3.0.0-alpha.6",
24
24
  "openai": "^5.23.0",
25
25
  "uuid": "^13.0.0",
26
26
  "zod": "^3.24.1"