lua-cli 3.2.0 → 3.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.
- package/dist/api/logs.api.service.d.ts +1 -1
- package/dist/api/logs.api.service.js.map +1 -1
- package/dist/api/products.api.service.d.ts +17 -5
- package/dist/api/products.api.service.js +21 -9
- package/dist/api/products.api.service.js.map +1 -1
- package/dist/api/webhook.api.service.d.ts +4 -0
- package/dist/api/webhook.api.service.js.map +1 -1
- package/dist/api-exports.d.ts +19 -7
- package/dist/api-exports.js +20 -5
- package/dist/api-exports.js.map +1 -1
- package/dist/cli/command-definitions.js +323 -88
- package/dist/cli/command-definitions.js.map +1 -1
- package/dist/commands/apiKey.d.ts +5 -2
- package/dist/commands/apiKey.js +8 -2
- package/dist/commands/apiKey.js.map +1 -1
- package/dist/commands/channels.d.ts +4 -9
- package/dist/commands/channels.js +140 -84
- package/dist/commands/channels.js.map +1 -1
- package/dist/commands/chat.d.ts +4 -2
- package/dist/commands/chat.js +126 -32
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/chatClear.d.ts +3 -2
- package/dist/commands/chatClear.js +16 -15
- package/dist/commands/chatClear.js.map +1 -1
- package/dist/commands/compile.d.ts +5 -4
- package/dist/commands/compile.js +73 -9
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/deploy.d.ts +5 -24
- package/dist/commands/deploy.js +75 -48
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/destroy.d.ts +5 -2
- package/dist/commands/destroy.js +14 -2
- package/dist/commands/destroy.js.map +1 -1
- package/dist/commands/env.d.ts +3 -1
- package/dist/commands/env.js +322 -122
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/features.d.ts +5 -9
- package/dist/commands/features.js +249 -129
- package/dist/commands/features.js.map +1 -1
- package/dist/commands/init.d.ts +7 -1
- package/dist/commands/init.js +242 -59
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/jobs.d.ts +5 -13
- package/dist/commands/jobs.js +523 -360
- package/dist/commands/jobs.js.map +1 -1
- package/dist/commands/logs.d.ts +5 -10
- package/dist/commands/logs.js +259 -103
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/marketplace.d.ts +23 -2
- package/dist/commands/marketplace.js +530 -7
- package/dist/commands/marketplace.js.map +1 -1
- package/dist/commands/mcp.d.ts +5 -11
- package/dist/commands/mcp.js +304 -294
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/persona.d.ts +5 -9
- package/dist/commands/persona.js +349 -232
- package/dist/commands/persona.js.map +1 -1
- package/dist/commands/postprocessors.d.ts +6 -2
- package/dist/commands/postprocessors.js +387 -280
- package/dist/commands/postprocessors.js.map +1 -1
- package/dist/commands/preprocessors.d.ts +6 -2
- package/dist/commands/preprocessors.js +387 -280
- package/dist/commands/preprocessors.js.map +1 -1
- package/dist/commands/production.d.ts +5 -8
- package/dist/commands/production.js +317 -228
- package/dist/commands/production.js.map +1 -1
- package/dist/commands/push.js +385 -427
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/resources.d.ts +5 -10
- package/dist/commands/resources.js +219 -154
- package/dist/commands/resources.js.map +1 -1
- package/dist/commands/skills.d.ts +5 -9
- package/dist/commands/skills.js +435 -275
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/sync.d.ts +10 -8
- package/dist/commands/sync.js +110 -19
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/test.d.ts +1 -11
- package/dist/commands/test.js +395 -438
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/webhooks.d.ts +5 -11
- package/dist/commands/webhooks.js +431 -287
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/interfaces/index.d.ts +1 -1
- package/dist/interfaces/mcp.d.ts +39 -19
- package/dist/interfaces/mcp.js +3 -0
- package/dist/interfaces/mcp.js.map +1 -1
- package/dist/interfaces/product.d.ts +26 -0
- package/dist/interfaces/skills.d.ts +5 -0
- package/dist/types/api-contracts.d.ts +8 -4
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/skill.d.ts +146 -35
- package/dist/types/skill.js +31 -37
- package/dist/types/skill.js.map +1 -1
- package/dist/utils/bundling.d.ts +17 -0
- package/dist/utils/bundling.js +96 -0
- package/dist/utils/bundling.js.map +1 -1
- package/dist/utils/compile.d.ts +4 -0
- package/dist/utils/compile.js +5 -0
- package/dist/utils/compile.js.map +1 -1
- package/dist/utils/dev-helpers.d.ts +3 -2
- package/dist/utils/dev-helpers.js +3 -5
- package/dist/utils/dev-helpers.js.map +1 -1
- package/dist/utils/job-management.d.ts +4 -1
- package/dist/utils/job-management.js +15 -29
- package/dist/utils/job-management.js.map +1 -1
- package/dist/utils/mcp-server-management.d.ts +5 -2
- package/dist/utils/mcp-server-management.js +27 -43
- package/dist/utils/mcp-server-management.js.map +1 -1
- package/dist/utils/push-helpers.d.ts +1 -1
- package/dist/utils/push-helpers.js +5 -1
- package/dist/utils/push-helpers.js.map +1 -1
- package/dist/utils/skill-management.d.ts +7 -2
- package/dist/utils/skill-management.js +21 -30
- package/dist/utils/skill-management.js.map +1 -1
- package/dist/utils/webhook-management.d.ts +4 -1
- package/dist/utils/webhook-management.js +15 -29
- package/dist/utils/webhook-management.js.map +1 -1
- package/package.json +1 -1
- package/template/package.json +1 -1
package/dist/commands/push.js
CHANGED
|
@@ -10,7 +10,7 @@ import { checkApiKey, loadApiKey } from '../services/auth.js';
|
|
|
10
10
|
import { readSkillConfig } from '../utils/files.js';
|
|
11
11
|
import { withErrorHandling, writeProgress, writeSuccess, writeInfo } from '../utils/cli.js';
|
|
12
12
|
import { safePrompt } from '../utils/prompt-handler.js';
|
|
13
|
-
import { readDeployJson, validatePushConfig, validateDeployData,
|
|
13
|
+
import { readDeployJson, validatePushConfig, validateDeployData, promptVersionConfirmOrUpdate, getAvailableSkills, updateSkillVersionInYaml, getSkillDeployData, } from '../utils/push-helpers.js';
|
|
14
14
|
import { pushVersion } from '../utils/push-api.js';
|
|
15
15
|
import { fetchVersions, publishVersion, } from '../utils/deploy-api.js';
|
|
16
16
|
import { BASE_URLS } from '../config/constants.js';
|
|
@@ -18,6 +18,127 @@ import PreProcessorApi from '../api/preprocessor.api.service.js';
|
|
|
18
18
|
import PostProcessorApi from '../api/postprocessor.api.service.js';
|
|
19
19
|
import DeveloperApi from '../api/developer.api.service.js';
|
|
20
20
|
import { loadPersonaFromCode } from '../utils/agent-code-utils.js';
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Core Push Helpers (shared by all push functions)
|
|
23
|
+
// ============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Authenticates the user and returns the API key
|
|
26
|
+
* Exits with error if authentication fails
|
|
27
|
+
*/
|
|
28
|
+
async function authenticateOrFail() {
|
|
29
|
+
const apiKey = await loadApiKey();
|
|
30
|
+
if (!apiKey) {
|
|
31
|
+
console.log("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
await checkApiKey(apiKey);
|
|
35
|
+
return apiKey;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Selects an entity from a list, either by options.entityName or interactive prompt
|
|
39
|
+
* @param items - Array of items to select from
|
|
40
|
+
* @param options - Push options with entityName
|
|
41
|
+
* @param config - Configuration for selection behavior
|
|
42
|
+
*/
|
|
43
|
+
async function selectEntityOrFail(items, options, config) {
|
|
44
|
+
const { entityType, nameFields = ['id', 'name'], formatChoice } = config;
|
|
45
|
+
if (items.length === 0) {
|
|
46
|
+
console.log(`❌ No ${entityType}s found in lua.skill.yaml.`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
// Non-interactive: find by name
|
|
50
|
+
if (options.entityName) {
|
|
51
|
+
const found = items.find((item) => nameFields.some(field => item[field] === options.entityName));
|
|
52
|
+
if (!found) {
|
|
53
|
+
console.log(`❌ ${entityType} "${options.entityName}" not found`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
writeInfo(`📦 Selected ${entityType}: ${found.name}`);
|
|
57
|
+
return found;
|
|
58
|
+
}
|
|
59
|
+
// Single item: use it automatically
|
|
60
|
+
if (items.length === 1) {
|
|
61
|
+
writeInfo(`📦 Pushing ${entityType}: ${items[0].name}`);
|
|
62
|
+
return items[0];
|
|
63
|
+
}
|
|
64
|
+
// Multiple items: prompt for selection
|
|
65
|
+
const answer = await safePrompt([
|
|
66
|
+
{
|
|
67
|
+
type: 'list',
|
|
68
|
+
name: 'selected',
|
|
69
|
+
message: `Select a ${entityType} to push:`,
|
|
70
|
+
choices: items.map((item) => ({
|
|
71
|
+
name: formatChoice ? formatChoice(item) : `${item.name} (v${item.version})`,
|
|
72
|
+
value: item
|
|
73
|
+
}))
|
|
74
|
+
}
|
|
75
|
+
]);
|
|
76
|
+
if (!answer) {
|
|
77
|
+
console.log("Push cancelled.");
|
|
78
|
+
process.exit(0);
|
|
79
|
+
}
|
|
80
|
+
writeInfo(`📦 Selected ${entityType}: ${answer.selected.name}`);
|
|
81
|
+
return answer.selected;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Resolves version from options or interactive prompt
|
|
85
|
+
* Validates semantic versioning format
|
|
86
|
+
*/
|
|
87
|
+
async function resolveVersionOrFail(currentVersion, options) {
|
|
88
|
+
if (options.version) {
|
|
89
|
+
if (!/^\d+\.\d+\.\d+/.test(options.version)) {
|
|
90
|
+
console.log(`❌ Invalid version format: "${options.version}". Use semantic versioning (e.g., 1.0.5)`);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
writeInfo(`📝 Using version: ${options.version}`);
|
|
94
|
+
return options.version;
|
|
95
|
+
}
|
|
96
|
+
return await promptVersionConfirmOrUpdate(currentVersion);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Loads bundled entity data from dist folder
|
|
100
|
+
* @returns The bundled data for the entity, or exits if not found
|
|
101
|
+
*/
|
|
102
|
+
function loadBundledEntityData(filename, entityName, entityType) {
|
|
103
|
+
const bundledPath = path.join(process.cwd(), 'dist', filename);
|
|
104
|
+
if (!fs.existsSync(bundledPath)) {
|
|
105
|
+
console.log(`❌ Bundled ${entityType.toLowerCase()} data not found.`);
|
|
106
|
+
console.log("💡 Please ensure your code is properly compiled.");
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
const bundled = JSON.parse(fs.readFileSync(bundledPath, 'utf8'));
|
|
110
|
+
const bundledData = bundled.find((item) => item.name === entityName) || {};
|
|
111
|
+
if (!bundledData || Object.keys(bundledData).length === 0) {
|
|
112
|
+
console.log(`\n❌ ${entityType} "${entityName}" not found in compiled code.`);
|
|
113
|
+
console.log("💡 This may have been removed or commented out in your code.");
|
|
114
|
+
console.log(`💡 Please uncomment the ${entityType.toLowerCase()} or remove it from lua.skill.yaml.`);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
return bundledData;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Determines if we should deploy after push based on options or prompt
|
|
121
|
+
*/
|
|
122
|
+
async function shouldDeployAfterPush(options) {
|
|
123
|
+
// Auto-deploy flag takes precedence
|
|
124
|
+
if (options.autoDeploy) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
// Force mode skips the prompt (no deploy)
|
|
128
|
+
if (options.force) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
// Interactive: ask user
|
|
132
|
+
const answer = await safePrompt([
|
|
133
|
+
{
|
|
134
|
+
type: 'confirm',
|
|
135
|
+
name: 'deployNow',
|
|
136
|
+
message: 'Would you like to deploy this version to production now?',
|
|
137
|
+
default: false
|
|
138
|
+
}
|
|
139
|
+
]);
|
|
140
|
+
return answer?.deployNow || false;
|
|
141
|
+
}
|
|
21
142
|
/**
|
|
22
143
|
* Main push command - pushes a skill or persona version to the server.
|
|
23
144
|
*
|
|
@@ -42,7 +163,9 @@ export async function pushCommand(type, cmdObj) {
|
|
|
42
163
|
// Extract options from Commander command object
|
|
43
164
|
const options = {
|
|
44
165
|
force: cmdObj?.force || false,
|
|
45
|
-
autoDeploy: cmdObj?.autoDeploy || false
|
|
166
|
+
autoDeploy: cmdObj?.autoDeploy || false,
|
|
167
|
+
entityName: cmdObj?.name || null,
|
|
168
|
+
version: cmdObj?.version || null
|
|
46
169
|
};
|
|
47
170
|
let selectedType;
|
|
48
171
|
// Handle 'all' type with force flag
|
|
@@ -56,6 +179,14 @@ export async function pushCommand(type, cmdObj) {
|
|
|
56
179
|
}
|
|
57
180
|
return await pushAllCommand(options);
|
|
58
181
|
}
|
|
182
|
+
// Validate that entityName without type is not allowed
|
|
183
|
+
if (options.entityName && !type) {
|
|
184
|
+
console.error('❌ Type must be specified when using the --name option.');
|
|
185
|
+
console.log('\nUsage:');
|
|
186
|
+
console.log(' lua push skill --name mySkill --version 1.0.5 Push specific skill');
|
|
187
|
+
console.log(' lua push webhook --name myWebhook --version 2.0.0 Push specific webhook');
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
59
190
|
// Step 1: Check if type was provided as argument
|
|
60
191
|
if (type) {
|
|
61
192
|
// Validate the provided type
|
|
@@ -101,123 +232,86 @@ export async function pushCommand(type, cmdObj) {
|
|
|
101
232
|
}
|
|
102
233
|
// Step 3: Route to appropriate function
|
|
103
234
|
if (selectedType === 'skill') {
|
|
104
|
-
await pushSkillVersion();
|
|
235
|
+
await pushSkillVersion(options);
|
|
105
236
|
}
|
|
106
237
|
else if (selectedType === 'webhook') {
|
|
107
|
-
await pushWebhookVersion();
|
|
238
|
+
await pushWebhookVersion(options);
|
|
108
239
|
}
|
|
109
240
|
else if (selectedType === 'job') {
|
|
110
|
-
await pushJobVersion();
|
|
241
|
+
await pushJobVersion(options);
|
|
111
242
|
}
|
|
112
243
|
else if (selectedType === 'preprocessor') {
|
|
113
|
-
await pushPreProcessorVersion();
|
|
244
|
+
await pushPreProcessorVersion(options);
|
|
114
245
|
}
|
|
115
246
|
else if (selectedType === 'postprocessor') {
|
|
116
|
-
await pushPostProcessorVersion();
|
|
247
|
+
await pushPostProcessorVersion(options);
|
|
117
248
|
}
|
|
118
249
|
else if (selectedType === 'mcp') {
|
|
119
|
-
await pushMCPServerVersion();
|
|
250
|
+
await pushMCPServerVersion(options);
|
|
120
251
|
}
|
|
121
252
|
else {
|
|
122
|
-
await pushPersonaVersion();
|
|
253
|
+
await pushPersonaVersion(options);
|
|
123
254
|
}
|
|
124
255
|
}, "push");
|
|
125
256
|
}
|
|
126
257
|
/**
|
|
127
258
|
* Push skill version to the server.
|
|
128
|
-
*
|
|
129
|
-
* This function performs the following steps:
|
|
130
|
-
* 1. Validates configuration has required fields
|
|
131
|
-
* 2. Prompts user to select a skill (if multiple skills exist)
|
|
132
|
-
* 3. Prompts to confirm or update version
|
|
133
|
-
* 4. Authenticates the user
|
|
134
|
-
* 5. Compiles the skill (always, to ensure deploy.json is current)
|
|
135
|
-
* 6. Validates deploy.json matches configuration for selected skill
|
|
136
|
-
* 7. Extracts the specific skill's deploy data
|
|
137
|
-
* 8. Pushes version to server
|
|
138
|
-
*
|
|
139
|
-
* @returns Promise that resolves when push completes
|
|
140
259
|
*/
|
|
141
|
-
async function pushSkillVersion() {
|
|
260
|
+
async function pushSkillVersion(options = {}) {
|
|
142
261
|
// Step 1: Validate configuration
|
|
143
262
|
const yamlConfig = readSkillConfig();
|
|
144
263
|
validatePushConfig(yamlConfig);
|
|
145
264
|
const config = yamlConfig;
|
|
146
|
-
// Step 2: Get available skills and
|
|
265
|
+
// Step 2: Get available skills and select
|
|
147
266
|
const availableSkills = getAvailableSkills(config);
|
|
148
267
|
if (availableSkills.length === 0) {
|
|
149
|
-
console.
|
|
268
|
+
console.log("❌ No skills found in configuration. Please compile your skill first using 'lua compile'.");
|
|
150
269
|
process.exit(1);
|
|
151
270
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
else {
|
|
159
|
-
// Multiple skills, prompt for selection
|
|
160
|
-
selectedSkill = await promptSkillSelection(availableSkills);
|
|
161
|
-
writeInfo(`📦 Selected skill: ${selectedSkill.name}`);
|
|
162
|
-
}
|
|
163
|
-
// Step 3: Confirm or update version
|
|
164
|
-
const confirmedVersion = await promptVersionConfirmOrUpdate(selectedSkill.version);
|
|
165
|
-
let versionUpdated = false;
|
|
271
|
+
const selectedSkill = await selectEntityOrFail(availableSkills, options, {
|
|
272
|
+
entityType: 'skill',
|
|
273
|
+
nameFields: ['skillId', 'name']
|
|
274
|
+
});
|
|
275
|
+
// Step 3: Handle version
|
|
276
|
+
const confirmedVersion = await resolveVersionOrFail(selectedSkill.version, options);
|
|
166
277
|
if (confirmedVersion !== selectedSkill.version) {
|
|
167
278
|
writeInfo(`📝 Updating version from ${selectedSkill.version} to ${confirmedVersion}`);
|
|
168
279
|
updateSkillVersionInYaml(selectedSkill.name, confirmedVersion);
|
|
169
280
|
selectedSkill.version = confirmedVersion;
|
|
170
|
-
versionUpdated = true;
|
|
171
281
|
}
|
|
172
282
|
// Step 4: Authenticate
|
|
173
|
-
const apiKey = await
|
|
174
|
-
if (!apiKey) {
|
|
175
|
-
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
176
|
-
process.exit(1);
|
|
177
|
-
}
|
|
178
|
-
const userData = await checkApiKey(apiKey);
|
|
283
|
+
const apiKey = await authenticateOrFail();
|
|
179
284
|
writeProgress("✅ Authenticated");
|
|
180
|
-
// Step 5: Compile the skill
|
|
285
|
+
// Step 5: Compile the skill
|
|
181
286
|
writeProgress("🔄 Compiling skill...");
|
|
182
287
|
await compileCommand();
|
|
183
|
-
// Step 6: Validate deploy data
|
|
288
|
+
// Step 6: Validate and extract deploy data
|
|
184
289
|
const deployData = readDeployJson();
|
|
185
290
|
validateDeployData(deployData, selectedSkill);
|
|
186
|
-
// Step 7: Extract the specific skill's deploy data
|
|
187
291
|
const skillDeployData = getSkillDeployData(deployData, selectedSkill.name);
|
|
188
|
-
// Step
|
|
189
|
-
const agentId = config.agent.agentId;
|
|
190
|
-
const skillId = selectedSkill.skillId;
|
|
292
|
+
// Step 7: Push version to server
|
|
191
293
|
writeProgress("🔄 Pushing version to server...");
|
|
192
|
-
const result = await pushVersion(apiKey, agentId, skillId, skillDeployData);
|
|
294
|
+
const result = await pushVersion(apiKey, config.agent.agentId, selectedSkill.skillId, skillDeployData);
|
|
193
295
|
if (result.success && result.data) {
|
|
194
296
|
const pushedVersion = result.data.version;
|
|
195
297
|
writeSuccess(`✅ Version ${pushedVersion} of "${selectedSkill.name}" pushed successfully`);
|
|
196
|
-
// Update YAML with the version returned from server
|
|
298
|
+
// Update YAML with the version returned from server
|
|
197
299
|
if (pushedVersion !== selectedSkill.version) {
|
|
198
300
|
writeInfo(`📝 Updating YAML with server version: ${pushedVersion}`);
|
|
199
301
|
updateSkillVersionInYaml(selectedSkill.name, pushedVersion);
|
|
200
302
|
selectedSkill.version = pushedVersion;
|
|
201
303
|
}
|
|
202
|
-
//
|
|
203
|
-
|
|
204
|
-
{
|
|
205
|
-
type: 'confirm',
|
|
206
|
-
name: 'deployNow',
|
|
207
|
-
message: 'Would you like to deploy this version to production now?',
|
|
208
|
-
default: false
|
|
209
|
-
}
|
|
210
|
-
]);
|
|
211
|
-
if (deployAnswer && deployAnswer.deployNow) {
|
|
304
|
+
// Step 8: Deploy if requested
|
|
305
|
+
if (await shouldDeployAfterPush(options)) {
|
|
212
306
|
await deployVersionAfterPush(apiKey, config.agent.agentId, selectedSkill, pushedVersion);
|
|
213
307
|
}
|
|
214
308
|
}
|
|
215
309
|
else if (result.error) {
|
|
216
|
-
console.
|
|
310
|
+
console.log(`❌ ${result.error.message}`);
|
|
217
311
|
process.exit(1);
|
|
218
312
|
}
|
|
219
313
|
else {
|
|
220
|
-
console.
|
|
314
|
+
console.log("❌ Failed to push version. Please try again.");
|
|
221
315
|
process.exit(1);
|
|
222
316
|
}
|
|
223
317
|
}
|
|
@@ -233,17 +327,17 @@ async function pushSkillVersion() {
|
|
|
233
327
|
*
|
|
234
328
|
* @returns Promise that resolves when push completes
|
|
235
329
|
*/
|
|
236
|
-
async function pushPersonaVersion() {
|
|
330
|
+
async function pushPersonaVersion(options = {}) {
|
|
237
331
|
// Step 1: Validate configuration
|
|
238
332
|
const config = readSkillConfig();
|
|
239
333
|
if (!config || !config.agent?.agentId) {
|
|
240
|
-
console.
|
|
334
|
+
console.log("❌ No agent configuration found. Please run 'lua init' first.");
|
|
241
335
|
process.exit(1);
|
|
242
336
|
}
|
|
243
337
|
// Step 2: Load current persona from code
|
|
244
338
|
const currentPersona = loadPersonaFromCode();
|
|
245
339
|
if (!currentPersona || !currentPersona.trim()) {
|
|
246
|
-
console.
|
|
340
|
+
console.log("❌ No persona found in configuration. Please edit your persona first using 'lua persona'.");
|
|
247
341
|
process.exit(1);
|
|
248
342
|
}
|
|
249
343
|
writeInfo(`📦 Pushing persona for agent: ${config.agent.agentId}`);
|
|
@@ -254,26 +348,23 @@ async function pushPersonaVersion() {
|
|
|
254
348
|
console.log("\nPersona preview:");
|
|
255
349
|
console.log(preview);
|
|
256
350
|
console.log();
|
|
257
|
-
// Step 3: Confirm push
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
351
|
+
// Step 3: Confirm push (skip if --force provided)
|
|
352
|
+
if (!options.force) {
|
|
353
|
+
const confirmAnswer = await safePrompt([
|
|
354
|
+
{
|
|
355
|
+
type: 'confirm',
|
|
356
|
+
name: 'confirm',
|
|
357
|
+
message: 'Create new persona version?',
|
|
358
|
+
default: true
|
|
359
|
+
}
|
|
360
|
+
]);
|
|
361
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
362
|
+
console.log("\n❌ Push cancelled.\n");
|
|
363
|
+
return;
|
|
264
364
|
}
|
|
265
|
-
]);
|
|
266
|
-
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
267
|
-
console.log("\n❌ Push cancelled.\n");
|
|
268
|
-
return;
|
|
269
365
|
}
|
|
270
366
|
// Step 4: Authenticate
|
|
271
|
-
const apiKey = await
|
|
272
|
-
if (!apiKey) {
|
|
273
|
-
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
274
|
-
process.exit(1);
|
|
275
|
-
}
|
|
276
|
-
await checkApiKey(apiKey);
|
|
367
|
+
const apiKey = await authenticateOrFail();
|
|
277
368
|
writeProgress("✅ Authenticated");
|
|
278
369
|
// Step 5: Push persona version to server
|
|
279
370
|
writeProgress("🔄 Creating persona version...");
|
|
@@ -293,16 +384,8 @@ async function pushPersonaVersion() {
|
|
|
293
384
|
const data = await response.json();
|
|
294
385
|
const versionNum = data.version || data.data?.version || 'N/A';
|
|
295
386
|
writeSuccess(`✅ Persona version ${versionNum} created successfully`);
|
|
296
|
-
// Step 6:
|
|
297
|
-
|
|
298
|
-
{
|
|
299
|
-
type: 'confirm',
|
|
300
|
-
name: 'deployNow',
|
|
301
|
-
message: 'Would you like to deploy this persona version to production now?',
|
|
302
|
-
default: false
|
|
303
|
-
}
|
|
304
|
-
]);
|
|
305
|
-
if (deployAnswer && deployAnswer.deployNow) {
|
|
387
|
+
// Step 6: Deploy if requested
|
|
388
|
+
if (await shouldDeployAfterPush(options)) {
|
|
306
389
|
await deployPersonaVersionAfterPush(apiKey, config.agent.agentId, versionNum);
|
|
307
390
|
}
|
|
308
391
|
else {
|
|
@@ -310,7 +393,7 @@ async function pushPersonaVersion() {
|
|
|
310
393
|
}
|
|
311
394
|
}
|
|
312
395
|
catch (error) {
|
|
313
|
-
console.
|
|
396
|
+
console.log('❌ Error creating persona version:', error);
|
|
314
397
|
process.exit(1);
|
|
315
398
|
}
|
|
316
399
|
}
|
|
@@ -367,90 +450,53 @@ async function deployPersonaVersionAfterPush(apiKey, agentId, versionNum) {
|
|
|
367
450
|
* 5. Push to server
|
|
368
451
|
* 6. Optionally deploy immediately
|
|
369
452
|
*/
|
|
370
|
-
async function pushWebhookVersion() {
|
|
453
|
+
async function pushWebhookVersion(options = {}) {
|
|
371
454
|
try {
|
|
372
|
-
// Step 1:
|
|
455
|
+
// Step 1: Compile
|
|
373
456
|
writeProgress("📦 Compiling project...");
|
|
374
457
|
await compileCommand();
|
|
375
458
|
writeSuccess("✅ Compilation complete");
|
|
376
459
|
// Step 2: Authenticate
|
|
377
|
-
const apiKey = await
|
|
378
|
-
if (!apiKey) {
|
|
379
|
-
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
380
|
-
process.exit(1);
|
|
381
|
-
}
|
|
382
|
-
await checkApiKey(apiKey);
|
|
460
|
+
const apiKey = await authenticateOrFail();
|
|
383
461
|
writeSuccess("✅ Authentication verified");
|
|
384
462
|
// Step 3: Read configuration
|
|
385
463
|
const config = readSkillConfig();
|
|
386
464
|
if (!config?.agent?.agentId) {
|
|
387
|
-
console.
|
|
465
|
+
console.log("❌ No agent ID found in lua.skill.yaml. Please run 'lua init' first.");
|
|
388
466
|
process.exit(1);
|
|
389
467
|
}
|
|
390
468
|
const webhooks = config.webhooks || [];
|
|
391
469
|
if (webhooks.length === 0) {
|
|
392
|
-
console.
|
|
470
|
+
console.log("❌ No webhooks found in lua.skill.yaml.");
|
|
393
471
|
console.log("💡 Make sure you have created a webhook using LuaWebhook in your code.");
|
|
394
472
|
process.exit(1);
|
|
395
473
|
}
|
|
396
|
-
// Step 4: Select webhook
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}))
|
|
406
|
-
}
|
|
407
|
-
]);
|
|
408
|
-
if (!webhookAnswer) {
|
|
409
|
-
console.log("Push cancelled.");
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
const selectedWebhook = webhookAnswer.selectedWebhook;
|
|
413
|
-
// Step 4.5: Load bundled webhook data
|
|
414
|
-
const bundledWebhooksPath = path.join(process.cwd(), 'dist', 'webhooks.json');
|
|
415
|
-
let bundledWebhookData = {};
|
|
416
|
-
if (fs.existsSync(bundledWebhooksPath)) {
|
|
417
|
-
const bundledWebhooks = JSON.parse(fs.readFileSync(bundledWebhooksPath, 'utf8'));
|
|
418
|
-
bundledWebhookData = bundledWebhooks.find((w) => w.name === selectedWebhook.name) || {};
|
|
419
|
-
// Validate that the webhook exists in compiled code
|
|
420
|
-
if (!bundledWebhookData || Object.keys(bundledWebhookData).length === 0) {
|
|
421
|
-
console.error(`\n❌ Webhook "${selectedWebhook.name}" not found in compiled code.`);
|
|
422
|
-
console.log("💡 This webhook may have been removed or commented out in your code.");
|
|
423
|
-
console.log("💡 Please uncomment the webhook or remove it from lua.skill.yaml.");
|
|
424
|
-
process.exit(1);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
console.error('❌ Bundled webhook data not found.');
|
|
429
|
-
console.log("💡 Please ensure your webhook code is properly compiled.");
|
|
430
|
-
process.exit(1);
|
|
431
|
-
}
|
|
432
|
-
// Step 5: Confirm or update version (same as skills)
|
|
433
|
-
const confirmedVersion = await promptVersionConfirmOrUpdate(selectedWebhook.version);
|
|
434
|
-
let versionToPush = confirmedVersion;
|
|
474
|
+
// Step 4: Select webhook
|
|
475
|
+
const selectedWebhook = await selectEntityOrFail(webhooks, options, {
|
|
476
|
+
entityType: 'webhook',
|
|
477
|
+
nameFields: ['id', 'webhookId', 'name']
|
|
478
|
+
});
|
|
479
|
+
// Step 5: Load and validate bundled data
|
|
480
|
+
const bundledWebhookData = loadBundledEntityData('webhooks.json', selectedWebhook.name, 'Webhook');
|
|
481
|
+
// Step 6: Handle version
|
|
482
|
+
const confirmedVersion = await resolveVersionOrFail(selectedWebhook.version, options);
|
|
435
483
|
if (confirmedVersion !== selectedWebhook.version) {
|
|
436
484
|
writeInfo(`📝 Updating version from ${selectedWebhook.version} to ${confirmedVersion}`);
|
|
437
485
|
updateWebhookVersionInYaml(selectedWebhook.name, confirmedVersion);
|
|
438
|
-
versionToPush = confirmedVersion;
|
|
439
486
|
}
|
|
440
|
-
// Step
|
|
487
|
+
// Step 7: Prepare and push webhook data
|
|
441
488
|
const webhookData = {
|
|
442
489
|
name: selectedWebhook.name,
|
|
443
|
-
version:
|
|
490
|
+
version: confirmedVersion,
|
|
444
491
|
description: bundledWebhookData.description || selectedWebhook.description || `Webhook: ${selectedWebhook.name}`,
|
|
445
492
|
webhookId: selectedWebhook.webhookId,
|
|
446
493
|
querySchema: bundledWebhookData.querySchema,
|
|
447
494
|
headerSchema: bundledWebhookData.headerSchema,
|
|
448
495
|
bodySchema: bundledWebhookData.bodySchema,
|
|
449
|
-
code: bundledWebhookData.code,
|
|
450
|
-
executeFunction: bundledWebhookData.executeFunction
|
|
496
|
+
code: bundledWebhookData.code,
|
|
497
|
+
executeFunction: bundledWebhookData.executeFunction
|
|
451
498
|
};
|
|
452
|
-
|
|
453
|
-
writeProgress(`\n🚀 Pushing ${selectedWebhook.name} v${versionToPush} to server...`);
|
|
499
|
+
writeProgress(`\n🚀 Pushing ${selectedWebhook.name} v${confirmedVersion} to server...`);
|
|
454
500
|
const response = await fetch(`${BASE_URLS.API}/developer/webhooks/${config.agent.agentId}/${selectedWebhook.webhookId}/version`, {
|
|
455
501
|
method: 'POST',
|
|
456
502
|
headers: {
|
|
@@ -461,31 +507,23 @@ async function pushWebhookVersion() {
|
|
|
461
507
|
});
|
|
462
508
|
if (!response.ok) {
|
|
463
509
|
const errorText = await response.text();
|
|
464
|
-
console.
|
|
510
|
+
console.log(`\n❌ Push Error: ${response.status} - ${errorText}\n`);
|
|
465
511
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
466
512
|
}
|
|
467
|
-
|
|
468
|
-
writeSuccess(`\n✅ Successfully pushed ${selectedWebhook.name} v${
|
|
513
|
+
await response.json();
|
|
514
|
+
writeSuccess(`\n✅ Successfully pushed ${selectedWebhook.name} v${confirmedVersion}\n`);
|
|
469
515
|
writeInfo(`📦 Webhook URL (id): ${BASE_URLS.WEBHOOK}/${config.agent.agentId}/${selectedWebhook.webhookId}`);
|
|
470
516
|
writeInfo(`🔗 Webhook URL (name): ${BASE_URLS.WEBHOOK}/${config.agent.agentId}/${selectedWebhook.name}`);
|
|
471
|
-
// Step 8:
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
type: 'confirm',
|
|
475
|
-
name: 'deployNow',
|
|
476
|
-
message: 'Would you like to deploy this webhook version to production now?',
|
|
477
|
-
default: false
|
|
478
|
-
}
|
|
479
|
-
]);
|
|
480
|
-
if (deployAnswer && deployAnswer.deployNow) {
|
|
481
|
-
await deployWebhookVersionAfterPush(apiKey, config.agent.agentId, selectedWebhook, versionToPush);
|
|
517
|
+
// Step 8: Deploy if requested
|
|
518
|
+
if (await shouldDeployAfterPush(options)) {
|
|
519
|
+
await deployWebhookVersionAfterPush(apiKey, config.agent.agentId, selectedWebhook, confirmedVersion);
|
|
482
520
|
}
|
|
483
521
|
else {
|
|
484
522
|
writeInfo("💡 You can deploy this version later using: lua webhooks production");
|
|
485
523
|
}
|
|
486
524
|
}
|
|
487
525
|
catch (error) {
|
|
488
|
-
console.
|
|
526
|
+
console.log('❌ Error pushing webhook version:', error);
|
|
489
527
|
process.exit(1);
|
|
490
528
|
}
|
|
491
529
|
}
|
|
@@ -574,82 +612,53 @@ function updateJobVersionInYaml(jobName, newVersion) {
|
|
|
574
612
|
/**
|
|
575
613
|
* Push job version to the server (simplified version)
|
|
576
614
|
*/
|
|
577
|
-
async function pushJobVersion() {
|
|
615
|
+
async function pushJobVersion(options = {}) {
|
|
578
616
|
try {
|
|
617
|
+
// Step 1: Compile
|
|
579
618
|
writeProgress("📦 Compiling project...");
|
|
580
619
|
await compileCommand();
|
|
581
620
|
writeSuccess("✅ Compilation complete");
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
process.exit(1);
|
|
586
|
-
}
|
|
587
|
-
await checkApiKey(apiKey);
|
|
621
|
+
// Step 2: Authenticate
|
|
622
|
+
const apiKey = await authenticateOrFail();
|
|
623
|
+
// Step 3: Read configuration
|
|
588
624
|
const config = readSkillConfig();
|
|
589
625
|
if (!config?.agent?.agentId) {
|
|
590
|
-
console.
|
|
626
|
+
console.log("❌ No agent ID found in lua.skill.yaml.");
|
|
591
627
|
process.exit(1);
|
|
592
628
|
}
|
|
593
629
|
const jobs = config.jobs || [];
|
|
594
630
|
if (jobs.length === 0) {
|
|
595
|
-
console.
|
|
631
|
+
console.log("❌ No jobs found in lua.skill.yaml.");
|
|
596
632
|
console.log("💡 Make sure you have created a job using LuaJob in your code.");
|
|
597
633
|
process.exit(1);
|
|
598
634
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
}
|
|
609
|
-
]);
|
|
610
|
-
if (!jobAnswer)
|
|
611
|
-
return;
|
|
612
|
-
const selectedJob = jobAnswer.selectedJob;
|
|
613
|
-
// Load bundled job data
|
|
614
|
-
const bundledJobsPath = path.join(process.cwd(), 'dist', 'jobs.json');
|
|
615
|
-
let bundledJobData = {};
|
|
616
|
-
if (fs.existsSync(bundledJobsPath)) {
|
|
617
|
-
const bundledJobs = JSON.parse(fs.readFileSync(bundledJobsPath, 'utf8'));
|
|
618
|
-
bundledJobData = bundledJobs.find((j) => j.name === selectedJob.name) || {};
|
|
619
|
-
// Validate that the job exists in compiled code
|
|
620
|
-
if (!bundledJobData || Object.keys(bundledJobData).length === 0) {
|
|
621
|
-
console.error(`\n❌ Job "${selectedJob.name}" not found in compiled code.`);
|
|
622
|
-
console.log("💡 This job may have been removed or commented out in your code.");
|
|
623
|
-
console.log("💡 Please uncomment the job or remove it from lua.skill.yaml.");
|
|
624
|
-
process.exit(1);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
else {
|
|
628
|
-
console.error('❌ Bundled job data not found.');
|
|
629
|
-
console.log("💡 Please ensure your job code is properly compiled.");
|
|
630
|
-
process.exit(1);
|
|
631
|
-
}
|
|
632
|
-
// Confirm or update version (same as skills and webhooks)
|
|
633
|
-
const confirmedVersion = await promptVersionConfirmOrUpdate(selectedJob.version);
|
|
634
|
-
let versionToPush = confirmedVersion;
|
|
635
|
+
// Step 4: Select job
|
|
636
|
+
const selectedJob = await selectEntityOrFail(jobs, options, {
|
|
637
|
+
entityType: 'job',
|
|
638
|
+
nameFields: ['id', 'jobId', 'name']
|
|
639
|
+
});
|
|
640
|
+
// Step 5: Load bundled data
|
|
641
|
+
const bundledJobData = loadBundledEntityData('jobs.json', selectedJob.name, 'Job');
|
|
642
|
+
// Step 6: Handle version
|
|
643
|
+
const confirmedVersion = await resolveVersionOrFail(selectedJob.version, options);
|
|
635
644
|
if (confirmedVersion !== selectedJob.version) {
|
|
636
645
|
writeInfo(`📝 Updating version from ${selectedJob.version} to ${confirmedVersion}`);
|
|
637
646
|
updateJobVersionInYaml(selectedJob.name, confirmedVersion);
|
|
638
|
-
versionToPush = confirmedVersion;
|
|
639
647
|
}
|
|
648
|
+
// Step 7: Prepare and push
|
|
640
649
|
const jobData = {
|
|
641
650
|
name: selectedJob.name,
|
|
642
|
-
version:
|
|
651
|
+
version: confirmedVersion,
|
|
643
652
|
description: bundledJobData.description || selectedJob.description || `Job: ${selectedJob.name}`,
|
|
644
653
|
jobId: selectedJob.jobId,
|
|
645
654
|
schedule: bundledJobData.schedule || selectedJob.schedule,
|
|
646
655
|
timeout: bundledJobData.timeout,
|
|
647
656
|
retry: bundledJobData.retry,
|
|
648
|
-
code: bundledJobData.code,
|
|
649
|
-
executeFunction: bundledJobData.executeFunction,
|
|
650
|
-
metadata: bundledJobData.metadata || selectedJob.metadata
|
|
657
|
+
code: bundledJobData.code,
|
|
658
|
+
executeFunction: bundledJobData.executeFunction,
|
|
659
|
+
metadata: bundledJobData.metadata || selectedJob.metadata
|
|
651
660
|
};
|
|
652
|
-
writeProgress(`\n🚀 Pushing ${selectedJob.name} v${
|
|
661
|
+
writeProgress(`\n🚀 Pushing ${selectedJob.name} v${confirmedVersion} to server...`);
|
|
653
662
|
const response = await fetch(`${BASE_URLS.API}/developer/jobs/${config.agent.agentId}/${selectedJob.jobId}/version`, {
|
|
654
663
|
method: 'POST',
|
|
655
664
|
headers: {
|
|
@@ -660,28 +669,20 @@ async function pushJobVersion() {
|
|
|
660
669
|
});
|
|
661
670
|
if (!response.ok) {
|
|
662
671
|
const errorText = await response.text();
|
|
663
|
-
console.
|
|
672
|
+
console.log(`\n❌ Push Error: ${response.status} - ${errorText}\n`);
|
|
664
673
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
665
674
|
}
|
|
666
|
-
writeSuccess(`\n✅ Successfully pushed ${selectedJob.name} v${
|
|
667
|
-
//
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
type: 'confirm',
|
|
671
|
-
name: 'deployNow',
|
|
672
|
-
message: 'Would you like to deploy this job version to production now?',
|
|
673
|
-
default: false
|
|
674
|
-
}
|
|
675
|
-
]);
|
|
676
|
-
if (deployAnswer && deployAnswer.deployNow) {
|
|
677
|
-
await deployJobVersionAfterPush(apiKey, config.agent.agentId, selectedJob, versionToPush);
|
|
675
|
+
writeSuccess(`\n✅ Successfully pushed ${selectedJob.name} v${confirmedVersion}\n`);
|
|
676
|
+
// Step 8: Deploy if requested
|
|
677
|
+
if (await shouldDeployAfterPush(options)) {
|
|
678
|
+
await deployJobVersionAfterPush(apiKey, config.agent.agentId, selectedJob, confirmedVersion);
|
|
678
679
|
}
|
|
679
680
|
else {
|
|
680
681
|
writeInfo("💡 You can deploy this version later using: lua jobs production");
|
|
681
682
|
}
|
|
682
683
|
}
|
|
683
684
|
catch (error) {
|
|
684
|
-
console.
|
|
685
|
+
console.log('❌ Error pushing job version:', error);
|
|
685
686
|
process.exit(1);
|
|
686
687
|
}
|
|
687
688
|
}
|
|
@@ -730,96 +731,71 @@ async function deployJobVersionAfterPush(apiKey, agentId, selectedJob, pushedVer
|
|
|
730
731
|
/**
|
|
731
732
|
* Push preprocessor version to the server.
|
|
732
733
|
*/
|
|
733
|
-
async function pushPreProcessorVersion() {
|
|
734
|
+
async function pushPreProcessorVersion(options = {}) {
|
|
734
735
|
try {
|
|
736
|
+
// Step 1: Compile
|
|
735
737
|
writeProgress("📦 Compiling project...");
|
|
736
738
|
await compileCommand();
|
|
737
739
|
writeSuccess("✅ Compilation complete");
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
process.exit(1);
|
|
742
|
-
}
|
|
743
|
-
await checkApiKey(apiKey);
|
|
740
|
+
// Step 2: Authenticate
|
|
741
|
+
const apiKey = await authenticateOrFail();
|
|
742
|
+
// Step 3: Read configuration
|
|
744
743
|
const config = readSkillConfig();
|
|
745
744
|
if (!config?.agent?.agentId) {
|
|
746
|
-
console.
|
|
745
|
+
console.log("❌ No agent ID found in lua.skill.yaml.");
|
|
747
746
|
process.exit(1);
|
|
748
747
|
}
|
|
749
748
|
const preprocessors = config.preprocessors || [];
|
|
750
749
|
if (preprocessors.length === 0) {
|
|
751
|
-
console.
|
|
750
|
+
console.log("❌ No preprocessors found in lua.skill.yaml.");
|
|
752
751
|
process.exit(1);
|
|
753
752
|
}
|
|
754
|
-
//
|
|
755
|
-
const
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
description: bundledData.description || selected.description,
|
|
790
|
-
preprocessorId: selected.preprocessorId,
|
|
791
|
-
code: bundledData.code,
|
|
792
|
-
executeFunction: bundledData.executeFunction,
|
|
793
|
-
async: Boolean(bundledData.async ?? false) // Ensure boolean type
|
|
794
|
-
};
|
|
795
|
-
writeProgress(`\n🚀 Pushing ${selected.name} v${confirmedVersion}...`);
|
|
796
|
-
const api = new PreProcessorApi(BASE_URLS.API, apiKey, config.agent.agentId);
|
|
797
|
-
const result = await api.pushPreProcessor(selected.preprocessorId, versionData);
|
|
798
|
-
if (result.success) {
|
|
799
|
-
writeSuccess(`\n✅ PreProcessor "${selected.name}" v${confirmedVersion} pushed successfully\n`);
|
|
800
|
-
// Ask if user wants to deploy now
|
|
801
|
-
const deployAnswer = await safePrompt([
|
|
802
|
-
{
|
|
803
|
-
type: 'confirm',
|
|
804
|
-
name: 'deployNow',
|
|
805
|
-
message: 'Would you like to deploy this preprocessor version to production now?',
|
|
806
|
-
default: false
|
|
807
|
-
}
|
|
808
|
-
]);
|
|
809
|
-
if (deployAnswer && deployAnswer.deployNow) {
|
|
810
|
-
await deployPreProcessorVersionAfterPush(apiKey, config.agent.agentId, selected, confirmedVersion);
|
|
811
|
-
}
|
|
812
|
-
else {
|
|
813
|
-
writeInfo("💡 You can deploy this version later using: lua preprocessors production");
|
|
814
|
-
}
|
|
753
|
+
// Step 4: Select preprocessor
|
|
754
|
+
const selected = await selectEntityOrFail(preprocessors, options, {
|
|
755
|
+
entityType: 'preprocessor',
|
|
756
|
+
nameFields: ['id', 'preprocessorId', 'name']
|
|
757
|
+
});
|
|
758
|
+
// Step 5: Load bundled data
|
|
759
|
+
const bundledData = loadBundledEntityData('preprocessors.json', selected.name, 'PreProcessor');
|
|
760
|
+
if (!bundledData.code) {
|
|
761
|
+
console.log(`❌ PreProcessor "${selected.name}" has no code in compiled output.`);
|
|
762
|
+
process.exit(1);
|
|
763
|
+
}
|
|
764
|
+
// Step 6: Handle version
|
|
765
|
+
const confirmedVersion = await resolveVersionOrFail(selected.version, options);
|
|
766
|
+
if (confirmedVersion !== selected.version) {
|
|
767
|
+
writeInfo(`📝 Updating version from ${selected.version} to ${confirmedVersion}`);
|
|
768
|
+
updateProcessorVersionInYaml('preprocessors', selected.name, confirmedVersion);
|
|
769
|
+
}
|
|
770
|
+
// Step 7: Prepare and push
|
|
771
|
+
const versionData = {
|
|
772
|
+
name: selected.name,
|
|
773
|
+
version: confirmedVersion,
|
|
774
|
+
description: bundledData.description || selected.description,
|
|
775
|
+
preprocessorId: selected.preprocessorId,
|
|
776
|
+
code: bundledData.code,
|
|
777
|
+
executeFunction: bundledData.executeFunction,
|
|
778
|
+
async: Boolean(bundledData.async ?? false)
|
|
779
|
+
};
|
|
780
|
+
writeProgress(`\n🚀 Pushing ${selected.name} v${confirmedVersion}...`);
|
|
781
|
+
const api = new PreProcessorApi(BASE_URLS.API, apiKey, config.agent.agentId);
|
|
782
|
+
const result = await api.pushPreProcessor(selected.preprocessorId, versionData);
|
|
783
|
+
if (result.success) {
|
|
784
|
+
writeSuccess(`\n✅ PreProcessor "${selected.name}" v${confirmedVersion} pushed successfully\n`);
|
|
785
|
+
// Step 8: Deploy if requested
|
|
786
|
+
if (await shouldDeployAfterPush(options)) {
|
|
787
|
+
await deployPreProcessorVersionAfterPush(apiKey, config.agent.agentId, selected, confirmedVersion);
|
|
815
788
|
}
|
|
816
789
|
else {
|
|
817
|
-
|
|
790
|
+
writeInfo("💡 You can deploy this version later using: lua preprocessors production");
|
|
818
791
|
}
|
|
819
792
|
}
|
|
793
|
+
else {
|
|
794
|
+
console.log(`❌ Failed to push: ${result.error?.message}`);
|
|
795
|
+
}
|
|
820
796
|
}
|
|
821
797
|
catch (error) {
|
|
822
|
-
console.
|
|
798
|
+
console.log('❌ Error pushing preprocessor:', error);
|
|
823
799
|
process.exit(1);
|
|
824
800
|
}
|
|
825
801
|
}
|
|
@@ -861,95 +837,70 @@ async function deployPreProcessorVersionAfterPush(apiKey, agentId, selected, pus
|
|
|
861
837
|
/**
|
|
862
838
|
* Push postprocessor version to the server.
|
|
863
839
|
*/
|
|
864
|
-
async function pushPostProcessorVersion() {
|
|
840
|
+
async function pushPostProcessorVersion(options = {}) {
|
|
865
841
|
try {
|
|
842
|
+
// Step 1: Compile
|
|
866
843
|
writeProgress("📦 Compiling project...");
|
|
867
844
|
await compileCommand();
|
|
868
845
|
writeSuccess("✅ Compilation complete");
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
process.exit(1);
|
|
873
|
-
}
|
|
874
|
-
await checkApiKey(apiKey);
|
|
846
|
+
// Step 2: Authenticate
|
|
847
|
+
const apiKey = await authenticateOrFail();
|
|
848
|
+
// Step 3: Read configuration
|
|
875
849
|
const config = readSkillConfig();
|
|
876
850
|
if (!config?.agent?.agentId) {
|
|
877
|
-
console.
|
|
851
|
+
console.log("❌ No agent ID found in lua.skill.yaml.");
|
|
878
852
|
process.exit(1);
|
|
879
853
|
}
|
|
880
854
|
const postprocessors = config.postprocessors || [];
|
|
881
855
|
if (postprocessors.length === 0) {
|
|
882
|
-
console.
|
|
856
|
+
console.log("❌ No postprocessors found in lua.skill.yaml.");
|
|
883
857
|
process.exit(1);
|
|
884
858
|
}
|
|
885
|
-
//
|
|
886
|
-
const
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
version: confirmedVersion,
|
|
920
|
-
description: bundledData.description || selected.description,
|
|
921
|
-
postprocessorId: selected.postprocessorId,
|
|
922
|
-
code: bundledData.code,
|
|
923
|
-
executeFunction: bundledData.executeFunction
|
|
924
|
-
};
|
|
925
|
-
writeProgress(`\n🚀 Pushing ${selected.name} v${confirmedVersion}...`);
|
|
926
|
-
const api = new PostProcessorApi(BASE_URLS.API, apiKey, config.agent.agentId);
|
|
927
|
-
const result = await api.pushPostProcessor(selected.postprocessorId, versionData);
|
|
928
|
-
if (result.success) {
|
|
929
|
-
writeSuccess(`\n✅ PostProcessor "${selected.name}" v${confirmedVersion} pushed successfully\n`);
|
|
930
|
-
// Ask if user wants to deploy now
|
|
931
|
-
const deployAnswer = await safePrompt([
|
|
932
|
-
{
|
|
933
|
-
type: 'confirm',
|
|
934
|
-
name: 'deployNow',
|
|
935
|
-
message: 'Would you like to deploy this postprocessor version to production now?',
|
|
936
|
-
default: false
|
|
937
|
-
}
|
|
938
|
-
]);
|
|
939
|
-
if (deployAnswer && deployAnswer.deployNow) {
|
|
940
|
-
await deployPostProcessorVersionAfterPush(apiKey, config.agent.agentId, selected, confirmedVersion);
|
|
941
|
-
}
|
|
942
|
-
else {
|
|
943
|
-
writeInfo("💡 You can deploy this version later using: lua postprocessors production");
|
|
944
|
-
}
|
|
859
|
+
// Step 4: Select postprocessor
|
|
860
|
+
const selected = await selectEntityOrFail(postprocessors, options, {
|
|
861
|
+
entityType: 'postprocessor',
|
|
862
|
+
nameFields: ['id', 'postprocessorId', 'name']
|
|
863
|
+
});
|
|
864
|
+
// Step 5: Load bundled data
|
|
865
|
+
const bundledData = loadBundledEntityData('postprocessors.json', selected.name, 'PostProcessor');
|
|
866
|
+
if (!bundledData.code) {
|
|
867
|
+
console.log(`❌ PostProcessor "${selected.name}" has no code in compiled output.`);
|
|
868
|
+
process.exit(1);
|
|
869
|
+
}
|
|
870
|
+
// Step 6: Handle version
|
|
871
|
+
const confirmedVersion = await resolveVersionOrFail(selected.version, options);
|
|
872
|
+
if (confirmedVersion !== selected.version) {
|
|
873
|
+
writeInfo(`📝 Updating version from ${selected.version} to ${confirmedVersion}`);
|
|
874
|
+
updateProcessorVersionInYaml('postprocessors', selected.name, confirmedVersion);
|
|
875
|
+
}
|
|
876
|
+
// Step 7: Prepare and push
|
|
877
|
+
const versionData = {
|
|
878
|
+
name: selected.name,
|
|
879
|
+
version: confirmedVersion,
|
|
880
|
+
description: bundledData.description || selected.description,
|
|
881
|
+
postprocessorId: selected.postprocessorId,
|
|
882
|
+
code: bundledData.code,
|
|
883
|
+
executeFunction: bundledData.executeFunction
|
|
884
|
+
};
|
|
885
|
+
writeProgress(`\n🚀 Pushing ${selected.name} v${confirmedVersion}...`);
|
|
886
|
+
const api = new PostProcessorApi(BASE_URLS.API, apiKey, config.agent.agentId);
|
|
887
|
+
const result = await api.pushPostProcessor(selected.postprocessorId, versionData);
|
|
888
|
+
if (result.success) {
|
|
889
|
+
writeSuccess(`\n✅ PostProcessor "${selected.name}" v${confirmedVersion} pushed successfully\n`);
|
|
890
|
+
// Step 8: Deploy if requested
|
|
891
|
+
if (await shouldDeployAfterPush(options)) {
|
|
892
|
+
await deployPostProcessorVersionAfterPush(apiKey, config.agent.agentId, selected, confirmedVersion);
|
|
945
893
|
}
|
|
946
894
|
else {
|
|
947
|
-
|
|
895
|
+
writeInfo("💡 You can deploy this version later using: lua postprocessors production");
|
|
948
896
|
}
|
|
949
897
|
}
|
|
898
|
+
else {
|
|
899
|
+
console.log(`❌ Failed to push: ${result.error?.message}`);
|
|
900
|
+
}
|
|
950
901
|
}
|
|
951
902
|
catch (error) {
|
|
952
|
-
console.
|
|
903
|
+
console.log('❌ Error pushing postprocessor:', error);
|
|
953
904
|
process.exit(1);
|
|
954
905
|
}
|
|
955
906
|
}
|
|
@@ -1011,65 +962,78 @@ function updateProcessorVersionInYaml(processorType, processorName, newVersion)
|
|
|
1011
962
|
/**
|
|
1012
963
|
* Push MCP Server to the server
|
|
1013
964
|
*/
|
|
1014
|
-
async function pushMCPServerVersion() {
|
|
965
|
+
async function pushMCPServerVersion(options = {}) {
|
|
1015
966
|
try {
|
|
1016
|
-
// Step 1:
|
|
967
|
+
// Step 1: Compile
|
|
1017
968
|
writeProgress("📦 Compiling project...");
|
|
1018
969
|
await compileCommand();
|
|
1019
970
|
writeSuccess("✅ Compilation complete");
|
|
1020
971
|
// Step 2: Authenticate
|
|
1021
|
-
const apiKey = await
|
|
1022
|
-
if (!apiKey) {
|
|
1023
|
-
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
1024
|
-
process.exit(1);
|
|
1025
|
-
}
|
|
1026
|
-
await checkApiKey(apiKey);
|
|
972
|
+
const apiKey = await authenticateOrFail();
|
|
1027
973
|
writeSuccess("✅ Authentication verified");
|
|
1028
974
|
// Step 3: Read configuration
|
|
1029
975
|
const config = readSkillConfig();
|
|
1030
976
|
if (!config?.agent?.agentId) {
|
|
1031
|
-
console.
|
|
977
|
+
console.log("❌ No agent ID found in lua.skill.yaml. Please run 'lua init' first.");
|
|
1032
978
|
process.exit(1);
|
|
1033
979
|
}
|
|
1034
980
|
const mcpServers = config.mcpServers || [];
|
|
1035
981
|
if (mcpServers.length === 0) {
|
|
1036
|
-
console.
|
|
982
|
+
console.log("❌ No MCP servers found in lua.skill.yaml.");
|
|
1037
983
|
console.log("💡 Make sure you have defined MCP servers in your LuaAgent configuration.");
|
|
1038
984
|
process.exit(1);
|
|
1039
985
|
}
|
|
1040
|
-
// Step 4: Load bundled MCP server data
|
|
986
|
+
// Step 4: Load bundled MCP server data
|
|
1041
987
|
const bundledServersPath = path.join(process.cwd(), 'dist', 'mcp-servers.json');
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
bundledServers = JSON.parse(fs.readFileSync(bundledServersPath, 'utf8'));
|
|
1045
|
-
}
|
|
1046
|
-
else {
|
|
1047
|
-
console.error('❌ Bundled MCP server data not found.');
|
|
988
|
+
if (!fs.existsSync(bundledServersPath)) {
|
|
989
|
+
console.log('❌ Bundled MCP server data not found.');
|
|
1048
990
|
console.log("💡 Please ensure your MCP servers are properly compiled.");
|
|
1049
991
|
process.exit(1);
|
|
1050
992
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
name: `${server.name} (${server.transport})`,
|
|
1061
|
-
value: { ...server, mcpServerId: yamlEntry?.mcpServerId }
|
|
1062
|
-
};
|
|
1063
|
-
})
|
|
993
|
+
const bundledServers = JSON.parse(fs.readFileSync(bundledServersPath, 'utf8'));
|
|
994
|
+
// Step 5: Select MCP server (special handling - uses bundled data with YAML IDs)
|
|
995
|
+
let selectedServer;
|
|
996
|
+
let bundledServerData;
|
|
997
|
+
if (options.entityName) {
|
|
998
|
+
bundledServerData = bundledServers.find((s) => s.id === options.entityName || s.mcpServerId === options.entityName || s.name === options.entityName);
|
|
999
|
+
if (!bundledServerData) {
|
|
1000
|
+
console.log(`❌ MCP server "${options.entityName}" not found`);
|
|
1001
|
+
process.exit(1);
|
|
1064
1002
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1003
|
+
const yamlEntry = mcpServers.find((s) => s.name === bundledServerData.name);
|
|
1004
|
+
selectedServer = { ...bundledServerData, mcpServerId: yamlEntry?.mcpServerId };
|
|
1005
|
+
writeInfo(`📦 Selected MCP server: ${selectedServer.name}`);
|
|
1006
|
+
}
|
|
1007
|
+
else if (bundledServers.length === 1) {
|
|
1008
|
+
bundledServerData = bundledServers[0];
|
|
1009
|
+
const yamlEntry = mcpServers.find((s) => s.name === bundledServerData.name);
|
|
1010
|
+
selectedServer = { ...bundledServerData, mcpServerId: yamlEntry?.mcpServerId };
|
|
1011
|
+
writeInfo(`📦 Pushing MCP server: ${selectedServer.name}`);
|
|
1012
|
+
}
|
|
1013
|
+
else {
|
|
1014
|
+
const serverAnswer = await safePrompt([
|
|
1015
|
+
{
|
|
1016
|
+
type: 'list',
|
|
1017
|
+
name: 'selectedServer',
|
|
1018
|
+
message: 'Select an MCP server to push:',
|
|
1019
|
+
choices: bundledServers.map((server) => {
|
|
1020
|
+
const yamlEntry = mcpServers.find((s) => s.name === server.name);
|
|
1021
|
+
return {
|
|
1022
|
+
name: `${server.name} (${server.transport})`,
|
|
1023
|
+
value: { ...server, mcpServerId: yamlEntry?.mcpServerId }
|
|
1024
|
+
};
|
|
1025
|
+
})
|
|
1026
|
+
}
|
|
1027
|
+
]);
|
|
1028
|
+
if (!serverAnswer) {
|
|
1029
|
+
console.log("Push cancelled.");
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
selectedServer = serverAnswer.selectedServer;
|
|
1033
|
+
bundledServerData = selectedServer;
|
|
1069
1034
|
}
|
|
1070
|
-
const selectedServer = serverAnswer.selectedServer;
|
|
1071
|
-
const bundledServerData = selectedServer;
|
|
1072
1035
|
// Step 6: Prepare server data for push
|
|
1036
|
+
// Include resolver fields for function-based env/headers/url resolution
|
|
1073
1037
|
const serverData = {
|
|
1074
1038
|
name: bundledServerData.name,
|
|
1075
1039
|
transport: bundledServerData.transport,
|
|
@@ -1077,28 +1041,22 @@ async function pushMCPServerVersion() {
|
|
|
1077
1041
|
...(bundledServerData.transport === 'stdio' ? {
|
|
1078
1042
|
command: bundledServerData.command,
|
|
1079
1043
|
args: bundledServerData.args,
|
|
1080
|
-
env: bundledServerData.env
|
|
1044
|
+
env: bundledServerData.env,
|
|
1045
|
+
envResolver: bundledServerData.envResolver, // Compressed function for runtime resolution
|
|
1081
1046
|
} : {
|
|
1082
1047
|
url: bundledServerData.url,
|
|
1083
|
-
|
|
1048
|
+
urlResolver: bundledServerData.urlResolver, // Compressed function for runtime resolution
|
|
1049
|
+
headers: bundledServerData.headers,
|
|
1050
|
+
headersResolver: bundledServerData.headersResolver, // Compressed function for runtime resolution
|
|
1084
1051
|
})
|
|
1085
1052
|
};
|
|
1086
|
-
// Step 7: Push to server (upsert)
|
|
1087
1053
|
writeProgress(`\n🚀 Pushing MCP server "${selectedServer.name}" to server...`);
|
|
1088
1054
|
const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, config.agent.agentId);
|
|
1089
1055
|
const result = await developerApi.upsertMCPServer(serverData);
|
|
1090
1056
|
if (result.success && result.data) {
|
|
1091
1057
|
writeSuccess(`\n✅ MCP server "${selectedServer.name}" pushed successfully\n`);
|
|
1092
|
-
//
|
|
1093
|
-
|
|
1094
|
-
{
|
|
1095
|
-
type: 'confirm',
|
|
1096
|
-
name: 'activateNow',
|
|
1097
|
-
message: 'Would you like to activate this MCP server now?',
|
|
1098
|
-
default: false
|
|
1099
|
-
}
|
|
1100
|
-
]);
|
|
1101
|
-
if (activateAnswer && activateAnswer.activateNow) {
|
|
1058
|
+
// Step 7: Activate if requested (MCP uses activate instead of deploy)
|
|
1059
|
+
if (await shouldDeployAfterPush(options)) {
|
|
1102
1060
|
writeProgress("🔄 Activating MCP server...");
|
|
1103
1061
|
const activateResult = await developerApi.activateMCPServer(result.data.id);
|
|
1104
1062
|
if (activateResult.success) {
|
|
@@ -1106,7 +1064,7 @@ async function pushMCPServerVersion() {
|
|
|
1106
1064
|
writeInfo("💡 The server's tools are now available to your agent.");
|
|
1107
1065
|
}
|
|
1108
1066
|
else {
|
|
1109
|
-
console.
|
|
1067
|
+
console.log(`❌ Failed to activate: ${activateResult.error?.message}`);
|
|
1110
1068
|
}
|
|
1111
1069
|
}
|
|
1112
1070
|
else {
|
|
@@ -1114,11 +1072,11 @@ async function pushMCPServerVersion() {
|
|
|
1114
1072
|
}
|
|
1115
1073
|
}
|
|
1116
1074
|
else {
|
|
1117
|
-
console.
|
|
1075
|
+
console.log(`❌ Failed to push: ${result.error?.message}`);
|
|
1118
1076
|
}
|
|
1119
1077
|
}
|
|
1120
1078
|
catch (error) {
|
|
1121
|
-
console.
|
|
1079
|
+
console.log('❌ Error pushing MCP server:', error);
|
|
1122
1080
|
process.exit(1);
|
|
1123
1081
|
}
|
|
1124
1082
|
}
|