lua-cli 2.5.4 → 2.5.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.
@@ -85,7 +85,14 @@ export async function pushCommand() {
85
85
  writeProgress("šŸ”„ Pushing version to server...");
86
86
  const result = await pushVersion(apiKey, agentId, skillId, skillDeployData);
87
87
  if (result.success && result.data) {
88
- writeSuccess(`āœ… Version ${result.data.version} of "${selectedSkill.name}" pushed successfully`);
88
+ const pushedVersion = result.data.version;
89
+ writeSuccess(`āœ… Version ${pushedVersion} of "${selectedSkill.name}" pushed successfully`);
90
+ // Update YAML with the version returned from server (in case it's different)
91
+ if (pushedVersion !== selectedSkill.version) {
92
+ writeInfo(`šŸ“ Updating YAML with server version: ${pushedVersion}`);
93
+ updateSkillVersionInYaml(selectedSkill.name, pushedVersion);
94
+ selectedSkill.version = pushedVersion;
95
+ }
89
96
  // Ask if user wants to deploy now
90
97
  const deployAnswer = await safePrompt([
91
98
  {
@@ -96,7 +103,7 @@ export async function pushCommand() {
96
103
  }
97
104
  ]);
98
105
  if (deployAnswer && deployAnswer.deployNow) {
99
- await deployVersionAfterPush(apiKey, config.agent.agentId, selectedSkill, result.data.version);
106
+ await deployVersionAfterPush(apiKey, config.agent.agentId, selectedSkill, pushedVersion);
100
107
  }
101
108
  }
102
109
  else if (result.error) {
@@ -145,6 +152,9 @@ async function deployVersionAfterPush(apiKey, agentId, selectedSkill, pushedVers
145
152
  writeProgress("šŸ”„ Publishing version...");
146
153
  const publishResponse = await publishVersion(apiKey, agentId, selectedSkill.skillId, pushedVersion);
147
154
  writeSuccess(`\nāœ… Version ${pushedVersion} of "${selectedSkill.name}" deployed successfully to production\n`);
155
+ // Update YAML with deployed version (should already be updated from push, but ensure consistency)
156
+ writeInfo(`šŸ“ Ensuring YAML is updated with deployed version: ${pushedVersion}`);
157
+ updateSkillVersionInYaml(selectedSkill.name, pushedVersion);
148
158
  }
149
159
  catch (error) {
150
160
  console.error('\nāŒ Error deploying version:', error);
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Skills Interfaces
3
+ * Structures for skill management
4
+ */
5
+ /**
6
+ * Tool definition within a skill version
7
+ */
8
+ export interface SkillTool {
9
+ name: string;
10
+ description: string;
11
+ }
12
+ /**
13
+ * Skill version information
14
+ */
15
+ export interface SkillVersion {
16
+ id: string;
17
+ version: string;
18
+ description: string;
19
+ active: boolean;
20
+ context: string;
21
+ tools: SkillTool[];
22
+ }
23
+ /**
24
+ * Skill information
25
+ */
26
+ export interface Skill {
27
+ id: string;
28
+ name: string;
29
+ description: string;
30
+ public: boolean;
31
+ active: boolean;
32
+ createdAt: string;
33
+ updatedAt: string;
34
+ versions: SkillVersion[];
35
+ }
36
+ /**
37
+ * Response from get all skills API endpoint
38
+ */
39
+ export interface GetSkillsResponse {
40
+ skills: Skill[];
41
+ }
42
+ /**
43
+ * Response from delete skill API endpoint
44
+ * If deleted is false and deactivated is true, the skill has versions
45
+ * and cannot be deleted, so it was deactivated instead
46
+ */
47
+ export interface DeleteSkillResponse {
48
+ message: string;
49
+ deleted: boolean;
50
+ deactivated: boolean;
51
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Skills Interfaces
3
+ * Structures for skill management
4
+ */
5
+ export {};
@@ -2,4 +2,8 @@ export declare function copyTemplateFiles(templateDir: string, targetDir: string
2
2
  export declare function createSkillYaml(agentId: string, orgId: string, skillName?: string, skillId?: string, persona?: string, welcomeMessage?: string): void;
3
3
  export declare function readSkillYaml(): any;
4
4
  export declare function readSkillConfig(): any;
5
+ /**
6
+ * Update only the agent information in an existing YAML file
7
+ */
8
+ export declare function updateYamlAgent(agentId: string, orgId: string, persona?: string, welcomeMessage?: string): void;
5
9
  export declare function updateSkillYamlPersona(persona: string, welcomeMessage?: string): void;
@@ -78,6 +78,33 @@ export function readSkillConfig() {
78
78
  // Read YAML config file
79
79
  return readSkillYaml();
80
80
  }
81
+ /**
82
+ * Update only the agent information in an existing YAML file
83
+ */
84
+ export function updateYamlAgent(agentId, orgId, persona, welcomeMessage) {
85
+ const yamlPath = path.join(process.cwd(), 'lua.skill.yaml');
86
+ if (!fs.existsSync(yamlPath)) {
87
+ throw new Error('lua.skill.yaml not found');
88
+ }
89
+ const config = readSkillYaml();
90
+ // Update agent information
91
+ config.agent = config.agent || {};
92
+ config.agent.agentId = agentId;
93
+ config.agent.orgId = orgId;
94
+ if (persona) {
95
+ config.agent.persona = persona;
96
+ }
97
+ if (welcomeMessage) {
98
+ config.agent.welcomeMessage = welcomeMessage;
99
+ }
100
+ // Write back to file
101
+ const yamlContent = dump(config, {
102
+ indent: 2,
103
+ lineWidth: -1,
104
+ noRefs: true
105
+ });
106
+ fs.writeFileSync(yamlPath, yamlContent);
107
+ }
81
108
  export function updateSkillYamlPersona(persona, welcomeMessage) {
82
109
  const yamlPath = path.join(process.cwd(), 'lua.skill.yaml');
83
110
  if (!fs.existsSync(yamlPath)) {
@@ -32,3 +32,16 @@ export declare function selectBaseAgentType(agentTypes: AgentType[]): AgentType;
32
32
  * @throws Error if agent creation fails
33
33
  */
34
34
  export declare function createNewAgent(apiKey: string, agentType: AgentType, businessConfig: BusinessConfig, metadata: Record<string, any>, features: Record<string, boolean>): Promise<AgentCreationResult>;
35
+ /**
36
+ * Fetches detailed agent information for an existing agent.
37
+ * Used when selecting an existing agent during init.
38
+ *
39
+ * @param apiKey - User's API key
40
+ * @param agentId - Agent ID to fetch
41
+ * @returns Agent details including persona and welcome message
42
+ * @throws Error if fetch fails
43
+ */
44
+ export declare function fetchExistingAgentDetails(apiKey: string, agentId: string): Promise<{
45
+ persona?: string;
46
+ welcomeMessage?: string;
47
+ }>;
@@ -127,3 +127,16 @@ async function fetchAgentDetails(agentApi, agentId) {
127
127
  welcomeMessage: agentDetailsResult.data.welcomeMessage
128
128
  };
129
129
  }
130
+ /**
131
+ * Fetches detailed agent information for an existing agent.
132
+ * Used when selecting an existing agent during init.
133
+ *
134
+ * @param apiKey - User's API key
135
+ * @param agentId - Agent ID to fetch
136
+ * @returns Agent details including persona and welcome message
137
+ * @throws Error if fetch fails
138
+ */
139
+ export async function fetchExistingAgentDetails(apiKey, agentId) {
140
+ const agentApi = new AgentApi(BASE_URLS.API, apiKey);
141
+ return fetchAgentDetails(agentApi, agentId);
142
+ }
@@ -12,3 +12,23 @@ import { SkillConfig } from '../types/compile.types.js';
12
12
  * @returns Updated skills array with valid skill IDs
13
13
  */
14
14
  export declare function ensureSkillsExistInYaml(skillsArray: any[], config: SkillConfig): Promise<any[]>;
15
+ /**
16
+ * Updates the YAML file with skills from the deploy.json file.
17
+ * This ensures the YAML reflects what's actually in the compiled code.
18
+ * Only updates skill entries that already exist in YAML (preserves skillId).
19
+ * Removes skills from YAML that are no longer in deploy.json.
20
+ *
21
+ * @param deployJsonPath - Path to the deploy.json file
22
+ * @param config - Current skill configuration
23
+ */
24
+ export declare function syncYamlWithDeployJson(deployJsonPath: string, config: SkillConfig): Promise<void>;
25
+ /**
26
+ * Syncs the server skills with the YAML configuration.
27
+ * Performs a two-way sync:
28
+ * 1. Deletes/deactivates skills from server that aren't in YAML
29
+ * 2. Updates YAML with active version numbers from server
30
+ *
31
+ * @param config - The skill configuration from lua.skill.yaml
32
+ * @returns Array of messages about sync operations
33
+ */
34
+ export declare function syncServerSkillsWithYaml(config: SkillConfig): Promise<string[]>;
@@ -146,3 +146,162 @@ async function updateYamlWithSkills(skills, config) {
146
146
  });
147
147
  fs.writeFileSync(yamlPath, yamlContent);
148
148
  }
149
+ /**
150
+ * Updates the YAML file with skills from the deploy.json file.
151
+ * This ensures the YAML reflects what's actually in the compiled code.
152
+ * Only updates skill entries that already exist in YAML (preserves skillId).
153
+ * Removes skills from YAML that are no longer in deploy.json.
154
+ *
155
+ * @param deployJsonPath - Path to the deploy.json file
156
+ * @param config - Current skill configuration
157
+ */
158
+ export async function syncYamlWithDeployJson(deployJsonPath, config) {
159
+ try {
160
+ // Read deploy.json
161
+ if (!fs.existsSync(deployJsonPath)) {
162
+ console.warn("āš ļø deploy.json not found. Skipping YAML sync.");
163
+ return;
164
+ }
165
+ const deployData = JSON.parse(fs.readFileSync(deployJsonPath, 'utf8'));
166
+ const deploySkills = deployData.skills || [];
167
+ // Create map of deploy skills by name
168
+ const deploySkillsMap = new Map();
169
+ deploySkills.forEach((skill) => {
170
+ deploySkillsMap.set(skill.name, skill);
171
+ });
172
+ // Get existing YAML skills
173
+ const existingYamlSkills = config?.skills || [];
174
+ // Update YAML skills to match deploy.json
175
+ const updatedSkills = existingYamlSkills
176
+ .filter((yamlSkill) => {
177
+ // Keep only skills that exist in deploy.json
178
+ return deploySkillsMap.has(yamlSkill.name);
179
+ })
180
+ .map((yamlSkill) => {
181
+ // Update version and description from deploy.json if available
182
+ const deploySkill = deploySkillsMap.get(yamlSkill.name);
183
+ return {
184
+ name: yamlSkill.name,
185
+ version: deploySkill?.version || yamlSkill.version || SKILL_DEFAULTS.VERSION,
186
+ skillId: yamlSkill.skillId || ''
187
+ };
188
+ });
189
+ // Add new skills from deploy.json that aren't in YAML yet
190
+ deploySkills.forEach((deploySkill) => {
191
+ const existsInYaml = updatedSkills.some((s) => s.name === deploySkill.name);
192
+ if (!existsInYaml) {
193
+ updatedSkills.push({
194
+ name: deploySkill.name,
195
+ version: deploySkill.version || SKILL_DEFAULTS.VERSION,
196
+ skillId: '' // Will be created via API later
197
+ });
198
+ }
199
+ });
200
+ // Update YAML file
201
+ await updateYamlWithSkills(updatedSkills, config);
202
+ console.log("āœ… YAML synced with deploy.json");
203
+ }
204
+ catch (error) {
205
+ console.error("āŒ Error syncing YAML with deploy.json:", error);
206
+ }
207
+ }
208
+ /**
209
+ * Syncs the server skills with the YAML configuration.
210
+ * Performs a two-way sync:
211
+ * 1. Deletes/deactivates skills from server that aren't in YAML
212
+ * 2. Updates YAML with active version numbers from server
213
+ *
214
+ * @param config - The skill configuration from lua.skill.yaml
215
+ * @returns Array of messages about sync operations
216
+ */
217
+ export async function syncServerSkillsWithYaml(config) {
218
+ const messages = [];
219
+ let yamlNeedsUpdate = false;
220
+ try {
221
+ // Validate prerequisites
222
+ const apiKey = await loadApiKey();
223
+ if (!apiKey) {
224
+ console.warn("āš ļø No API key found. Skipping server sync.");
225
+ return messages;
226
+ }
227
+ const agentId = config?.agent?.agentId;
228
+ if (!agentId) {
229
+ console.warn("āš ļø No agent ID found in lua.skill.yaml. Skipping server sync.");
230
+ return messages;
231
+ }
232
+ // Get skills from server
233
+ const skillApi = new SkillApi(BASE_URLS.API, apiKey, agentId);
234
+ const serverSkillsResponse = await skillApi.getSkills();
235
+ if (!serverSkillsResponse.success || !serverSkillsResponse.data?.skills) {
236
+ console.warn("āš ļø Could not retrieve server skills. Skipping server sync.");
237
+ return messages;
238
+ }
239
+ const serverSkills = serverSkillsResponse.data.skills;
240
+ const yamlSkills = config?.skills || [];
241
+ // Create maps for efficient lookup
242
+ const yamlSkillsMap = new Map(yamlSkills
243
+ .filter((skill) => skill.skillId)
244
+ .map((skill) => [skill.skillId, skill]));
245
+ const serverSkillsMap = new Map(serverSkills.map(skill => [skill.id, skill]));
246
+ // Part 1: Delete skills from server that aren't in YAML
247
+ const skillsToDelete = serverSkills.filter(serverSkill => !yamlSkillsMap.has(serverSkill.id));
248
+ for (const skill of skillsToDelete) {
249
+ try {
250
+ const deleteResponse = await skillApi.deleteSkill(skill.id);
251
+ if (deleteResponse.success && deleteResponse.data) {
252
+ if (deleteResponse.data.deleted) {
253
+ const msg = `āœ… Deleted skill "${skill.name}" from server`;
254
+ messages.push(msg);
255
+ console.log(msg);
256
+ }
257
+ else if (deleteResponse.data.deactivated) {
258
+ const msg = `āš ļø Skill "${skill.name}" has versions and cannot be deleted. It has been deactivated instead.`;
259
+ messages.push(msg);
260
+ console.warn(msg);
261
+ }
262
+ }
263
+ else {
264
+ const msg = `āŒ Failed to delete skill "${skill.name}": ${deleteResponse.error?.message || 'Unknown error'}`;
265
+ messages.push(msg);
266
+ console.error(msg);
267
+ }
268
+ }
269
+ catch (error) {
270
+ const msg = `āŒ Error deleting skill "${skill.name}": ${error}`;
271
+ messages.push(msg);
272
+ console.error(msg);
273
+ }
274
+ }
275
+ // Part 2: Sync version numbers from server to YAML
276
+ const updatedYamlSkills = yamlSkills.map((yamlSkill) => {
277
+ const serverSkill = serverSkillsMap.get(yamlSkill.skillId);
278
+ if (serverSkill && serverSkill.versions && serverSkill.versions.length > 0) {
279
+ // Find the active version on the server
280
+ const activeVersion = serverSkill.versions.find((v) => v.active);
281
+ if (activeVersion && activeVersion.version !== yamlSkill.version) {
282
+ const msg = `šŸ“ Updated "${yamlSkill.name}" version in YAML: ${yamlSkill.version} → ${activeVersion.version}`;
283
+ messages.push(msg);
284
+ console.log(msg);
285
+ yamlNeedsUpdate = true;
286
+ return {
287
+ ...yamlSkill,
288
+ version: activeVersion.version
289
+ };
290
+ }
291
+ }
292
+ return yamlSkill;
293
+ });
294
+ // Update YAML file if versions changed
295
+ if (yamlNeedsUpdate) {
296
+ await updateYamlWithSkills(updatedYamlSkills, config);
297
+ console.log("āœ… YAML versions synced with server");
298
+ }
299
+ if (skillsToDelete.length === 0 && !yamlNeedsUpdate) {
300
+ console.log("āœ… Server and YAML are fully in sync");
301
+ }
302
+ }
303
+ catch (error) {
304
+ console.error("āŒ Error syncing server skills:", error);
305
+ }
306
+ return messages;
307
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lua-cli",
3
- "version": "2.5.4",
3
+ "version": "2.5.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",
@@ -19,7 +19,7 @@
19
19
  "axios": "^1.6.0",
20
20
  "inquirer": "^12.9.6",
21
21
  "js-yaml": "^4.1.0",
22
- "lua-cli": "^2.5.3",
22
+ "lua-cli": "^2.5.6",
23
23
  "openai": "^5.23.0",
24
24
  "uuid": "^13.0.0",
25
25
  "zod": "^3.24.1"