lua-cli 3.0.3 → 3.1.0-alpha.2

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.
Files changed (43) hide show
  1. package/README.md +8 -1
  2. package/dist/api/job.api.service.d.ts +3 -1
  3. package/dist/api/job.api.service.js +7 -2
  4. package/dist/api/logs.api.service.d.ts +11 -13
  5. package/dist/api/logs.api.service.js +20 -17
  6. package/dist/api/marketplace.api.service.d.ts +25 -0
  7. package/dist/api/marketplace.api.service.js +105 -0
  8. package/dist/api/user.data.api.service.js +7 -2
  9. package/dist/cli/command-definitions.d.ts +6 -0
  10. package/dist/cli/command-definitions.js +25 -1
  11. package/dist/commands/env.d.ts +11 -0
  12. package/dist/commands/env.js +1 -79
  13. package/dist/commands/index.d.ts +1 -0
  14. package/dist/commands/index.js +1 -0
  15. package/dist/commands/logs.js +128 -68
  16. package/dist/commands/marketplace.d.ts +12 -0
  17. package/dist/commands/marketplace.js +1593 -0
  18. package/dist/commands/persona.js +9 -4
  19. package/dist/common/job.instance.js +1 -3
  20. package/dist/common/user.instance.d.ts +5 -2
  21. package/dist/common/user.instance.js +55 -21
  22. package/dist/config/constants.d.ts +1 -1
  23. package/dist/config/constants.js +5 -1
  24. package/dist/index.js +6 -4
  25. package/dist/interfaces/index.d.ts +5 -4
  26. package/dist/interfaces/marketplace.d.ts +99 -0
  27. package/dist/interfaces/marketplace.js +2 -0
  28. package/dist/interfaces/user.d.ts +19 -0
  29. package/dist/interfaces/user.js +1 -0
  30. package/dist/types/compile.types.d.ts +48 -41
  31. package/dist/types/compile.types.js +1 -0
  32. package/dist/utils/env-loader.utils.d.ts +9 -0
  33. package/dist/utils/env-loader.utils.js +88 -0
  34. package/dist/utils/job-management.d.ts +3 -3
  35. package/dist/utils/postprocessor-management.d.ts +3 -3
  36. package/dist/utils/preprocessor-management.d.ts +3 -3
  37. package/dist/utils/semver.d.ts +27 -0
  38. package/dist/utils/semver.js +75 -0
  39. package/dist/utils/skill-management.d.ts +4 -4
  40. package/dist/utils/webhook-management.d.ts +3 -3
  41. package/dist/web/app.js +3 -3
  42. package/package.json +1 -1
  43. package/template/README.md +13 -0
package/README.md CHANGED
@@ -12,6 +12,7 @@
12
12
  ## ✨ Features
13
13
 
14
14
  - 🤖 **LuaAgent** - Unified agent configuration with persona, skills, webhooks, and jobs
15
+ - 🛒 **Marketplace** - Publish and install verified skills from the community
15
16
  - 🛠️ **Custom Tools** - Build TypeScript tools with full type safety and Zod validation
16
17
  - 🪝 **Webhooks** - HTTP endpoints for external integrations (Stripe, Shopify, etc.)
17
18
  - ⏰ **Scheduled Jobs** - Cron-based and one-time background tasks
@@ -289,6 +290,12 @@ lua auth configure # Set up API key
289
290
  lua init # Initialize new project
290
291
  ```
291
292
 
293
+ ### Marketplace
294
+
295
+ ```bash
296
+ lua marketplace # Access the skills marketplace (Creator & Installer)
297
+ ```
298
+
292
299
  ### Development
293
300
 
294
301
  ```bash
@@ -311,7 +318,7 @@ lua deploy # Deploy version to production
311
318
  lua production # View production status
312
319
  lua env # Manage environment variables
313
320
  lua persona # Update agent persona
314
- lua logs # View agent logs
321
+ lua logs # View and filter agent logs (interactive)
315
322
  lua skills # Manage skills
316
323
  lua webhooks # Manage webhooks
317
324
  lua jobs # Manage scheduled jobs
@@ -83,7 +83,9 @@ export default class JobApi extends HttpClient {
83
83
  * @returns Promise resolving to an ApiResponse containing an array of jobs with their versions
84
84
  * @throws Error if the API request fails or the agent is not found
85
85
  */
86
- getJobs(): Promise<ApiResponse<GetJobsResponse>>;
86
+ getJobs(options?: {
87
+ includeDynamic?: boolean;
88
+ }): Promise<ApiResponse<GetJobsResponse>>;
87
89
  /**
88
90
  * Retrieves a job by its unique identifier
89
91
  * @param jobId - The unique identifier of the job to retrieve
@@ -22,8 +22,13 @@ export default class JobApi extends HttpClient {
22
22
  * @returns Promise resolving to an ApiResponse containing an array of jobs with their versions
23
23
  * @throws Error if the API request fails or the agent is not found
24
24
  */
25
- async getJobs() {
26
- return this.httpGet(`/developer/jobs/${this.agentId}`, {
25
+ async getJobs(options = {}) {
26
+ const queryParams = new URLSearchParams();
27
+ if (options.includeDynamic) {
28
+ queryParams.append('includeDynamic', 'true');
29
+ }
30
+ const url = `/developer/jobs/${this.agentId}?${queryParams.toString()}`;
31
+ return this.httpGet(url, {
27
32
  Authorization: `Bearer ${this.apiKey}`,
28
33
  });
29
34
  }
@@ -15,21 +15,19 @@ export default class LogsApi extends HttpClient {
15
15
  constructor(baseUrl: string, apiKey: string);
16
16
  /**
17
17
  * Retrieves logs for an agent
18
- * @param agentId - The unique identifier of the agent
18
+ * @param agentId - The ID of the agent
19
19
  * @param limit - Number of logs per page (default: 20)
20
20
  * @param page - Page number (default: 1)
21
+ * @param skillId - Optional skill ID to filter logs
22
+ * @param logType - Optional log type to filter logs
21
23
  * @returns Promise resolving to an ApiResponse containing logs and pagination
22
- * @throws Error if the API request fails
23
24
  */
24
- getAgentLogs(agentId: string, limit?: number, page?: number): Promise<ApiResponse<LogsResponse>>;
25
- /**
26
- * Retrieves logs for a specific skill
27
- * @param agentId - The unique identifier of the agent
28
- * @param skillId - The unique identifier of the skill
29
- * @param limit - Number of logs per page (default: 20)
30
- * @param page - Page number (default: 1)
31
- * @returns Promise resolving to an ApiResponse containing logs and pagination
32
- * @throws Error if the API request fails
33
- */
34
- getSkillLogs(agentId: string, skillId: string, limit?: number, page?: number): Promise<ApiResponse<LogsResponse>>;
25
+ getAgentLogs(agentId: string, limit: number, page: number, filters?: {
26
+ primitiveType?: "skill" | "job" | "webhook" | "preprocessor" | "postprocessor";
27
+ primitiveId?: string;
28
+ primitiveName?: string;
29
+ toolId?: string;
30
+ toolName?: string;
31
+ logType?: string;
32
+ }): Promise<ApiResponse<LogsResponse>>;
35
33
  }
@@ -15,28 +15,31 @@ export default class LogsApi extends HttpClient {
15
15
  }
16
16
  /**
17
17
  * Retrieves logs for an agent
18
- * @param agentId - The unique identifier of the agent
18
+ * @param agentId - The ID of the agent
19
19
  * @param limit - Number of logs per page (default: 20)
20
20
  * @param page - Page number (default: 1)
21
+ * @param skillId - Optional skill ID to filter logs
22
+ * @param logType - Optional log type to filter logs
21
23
  * @returns Promise resolving to an ApiResponse containing logs and pagination
22
- * @throws Error if the API request fails
23
24
  */
24
- async getAgentLogs(agentId, limit = 20, page = 1) {
25
- return this.httpGet(`/developer/agents/${agentId}/logs?limit=${limit}&page=${page}`, {
26
- Authorization: `Bearer ${this.apiKey}`,
25
+ async getAgentLogs(agentId, limit, page, filters = {}) {
26
+ const queryParams = new URLSearchParams({
27
+ limit: limit.toString(),
28
+ page: page.toString(),
27
29
  });
28
- }
29
- /**
30
- * Retrieves logs for a specific skill
31
- * @param agentId - The unique identifier of the agent
32
- * @param skillId - The unique identifier of the skill
33
- * @param limit - Number of logs per page (default: 20)
34
- * @param page - Page number (default: 1)
35
- * @returns Promise resolving to an ApiResponse containing logs and pagination
36
- * @throws Error if the API request fails
37
- */
38
- async getSkillLogs(agentId, skillId, limit = 20, page = 1) {
39
- return this.httpGet(`/developer/skills/${agentId}/${skillId}/logs?limit=${limit}&page=${page}`, {
30
+ if (filters.primitiveType)
31
+ queryParams.append("primitiveType", filters.primitiveType);
32
+ if (filters.primitiveId)
33
+ queryParams.append("primitiveId", filters.primitiveId);
34
+ if (filters.primitiveName)
35
+ queryParams.append("primitiveName", filters.primitiveName);
36
+ if (filters.toolId)
37
+ queryParams.append("toolId", filters.toolId);
38
+ if (filters.toolName)
39
+ queryParams.append("toolName", filters.toolName);
40
+ if (filters.logType)
41
+ queryParams.append("logType", filters.logType);
42
+ return this.httpGet(`/developer/agents/${agentId}/logs?${queryParams.toString()}`, {
40
43
  Authorization: `Bearer ${this.apiKey}`,
41
44
  });
42
45
  }
@@ -0,0 +1,25 @@
1
+ import { MarketplaceSkillWithVersionsResponse, MarketplaceVersionResponse, SkillResponse, UnpublishVersionResponse, UnlistSkillResponse } from "../interfaces/marketplace.js";
2
+ export declare class MarketplaceApiService {
3
+ private apiKey;
4
+ private baseUrl;
5
+ constructor(apiKey: string);
6
+ private _fetch;
7
+ listSkill(data: any): Promise<MarketplaceSkillWithVersionsResponse>;
8
+ updateSkill(marketplaceSkillId: string, data: any): Promise<MarketplaceSkillWithVersionsResponse>;
9
+ unlistSkill(marketplaceSkillId: string): Promise<UnlistSkillResponse>;
10
+ publishVersion(marketplaceSkillId: string, data: any): Promise<MarketplaceVersionResponse>;
11
+ unpublishVersion(marketplaceSkillId: string, versionId: string): Promise<UnpublishVersionResponse>;
12
+ getCreatorSkills(): Promise<MarketplaceSkillWithVersionsResponse[]>;
13
+ searchSkills(filters?: {
14
+ search?: string;
15
+ name?: string;
16
+ creatorId?: string;
17
+ publishedVersionsOnly?: boolean;
18
+ }): Promise<MarketplaceSkillWithVersionsResponse[]>;
19
+ getSkillById(marketplaceSkillId: string): Promise<MarketplaceSkillWithVersionsResponse>;
20
+ getSkillVersions(marketplaceSkillId: string): Promise<MarketplaceVersionResponse[]>;
21
+ installSkill(marketplaceSkillId: string, agentId: string, data: any): Promise<SkillResponse>;
22
+ updateInstallation(marketplaceSkillId: string, agentId: string, data: any): Promise<SkillResponse>;
23
+ uninstallSkill(marketplaceSkillId: string, agentId: string): Promise<SkillResponse>;
24
+ getInstalledSkills(agentId: string): Promise<SkillResponse[]>;
25
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Marketplace API Service
3
+ * Handles all communication with the Lua Marketplace API.
4
+ */
5
+ import { BASE_URLS } from "../config/constants.js";
6
+ export class MarketplaceApiService {
7
+ constructor(apiKey) {
8
+ this.baseUrl = BASE_URLS.API;
9
+ this.apiKey = apiKey;
10
+ }
11
+ async _fetch(endpoint, options = {}) {
12
+ const url = `${this.baseUrl}${endpoint}`;
13
+ const headers = {
14
+ Authorization: `Bearer ${this.apiKey}`,
15
+ "Content-Type": "application/json",
16
+ ...options.headers,
17
+ };
18
+ const response = await fetch(url, { ...options, headers });
19
+ if (!response.ok) {
20
+ const errorText = await response.text();
21
+ throw new Error(`API Error: ${response.status} ${response.statusText} - ${errorText}`);
22
+ }
23
+ if (response.status === 204) {
24
+ // No content
25
+ return null;
26
+ }
27
+ return response.json();
28
+ }
29
+ // --- Creator Methods ---
30
+ async listSkill(data) {
31
+ return this._fetch("/marketplace/skills/list", {
32
+ method: "POST",
33
+ body: JSON.stringify(data),
34
+ });
35
+ }
36
+ async updateSkill(marketplaceSkillId, data) {
37
+ return this._fetch(`/marketplace/skills/${marketplaceSkillId}`, {
38
+ method: "PATCH",
39
+ body: JSON.stringify(data),
40
+ });
41
+ }
42
+ async unlistSkill(marketplaceSkillId) {
43
+ return this._fetch(`/marketplace/skills/${marketplaceSkillId}/unlist`, {
44
+ method: "PUT",
45
+ });
46
+ }
47
+ async publishVersion(marketplaceSkillId, data) {
48
+ return this._fetch(`/marketplace/skills/${marketplaceSkillId}/versions/publish`, {
49
+ method: "POST",
50
+ body: JSON.stringify(data),
51
+ });
52
+ }
53
+ async unpublishVersion(marketplaceSkillId, versionId) {
54
+ return this._fetch(`/marketplace/skills/${marketplaceSkillId}/unpublish`, {
55
+ method: "PUT",
56
+ body: JSON.stringify({ versionId }),
57
+ });
58
+ }
59
+ async getCreatorSkills() {
60
+ return this._fetch("/marketplace/creator/skills");
61
+ }
62
+ // --- Installer Methods ---
63
+ async searchSkills(filters) {
64
+ const params = new URLSearchParams();
65
+ if (filters?.search) {
66
+ params.append("search", filters.search);
67
+ }
68
+ if (filters?.name) {
69
+ params.append("name", filters.name);
70
+ }
71
+ if (filters?.creatorId) {
72
+ params.append("creatorId", filters.creatorId);
73
+ }
74
+ if (filters?.publishedVersionsOnly !== undefined) {
75
+ params.append("publishedVersionsOnly", String(filters.publishedVersionsOnly));
76
+ }
77
+ return this._fetch(`/marketplace/skills?${params.toString()}`);
78
+ }
79
+ async getSkillById(marketplaceSkillId) {
80
+ return this._fetch(`/marketplace/skills/${marketplaceSkillId}`);
81
+ }
82
+ async getSkillVersions(marketplaceSkillId) {
83
+ return this._fetch(`/marketplace/skills/${marketplaceSkillId}/versions`);
84
+ }
85
+ async installSkill(marketplaceSkillId, agentId, data) {
86
+ return this._fetch(`/marketplace/install/${marketplaceSkillId}/${agentId}`, {
87
+ method: "POST",
88
+ body: JSON.stringify(data),
89
+ });
90
+ }
91
+ async updateInstallation(marketplaceSkillId, agentId, data) {
92
+ return this._fetch(`/marketplace/install/${marketplaceSkillId}/${agentId}`, {
93
+ method: "PUT",
94
+ body: JSON.stringify(data),
95
+ });
96
+ }
97
+ async uninstallSkill(marketplaceSkillId, agentId) {
98
+ return this._fetch(`/marketplace/install/${marketplaceSkillId}/${agentId}`, {
99
+ method: "DELETE",
100
+ });
101
+ }
102
+ async getInstalledSkills(agentId) {
103
+ return this._fetch(`/marketplace/installations/${agentId}`);
104
+ }
105
+ }
@@ -29,7 +29,10 @@ export default class UserDataApi extends HttpClient {
29
29
  if (!response.success) {
30
30
  throw new Error(response.error?.message || 'Failed to get user data');
31
31
  }
32
- return new UserDataInstance(this, response.data);
32
+ // Extract profile data and remove from response
33
+ const profile = response.data?._luaProfile;
34
+ const { _luaProfile, ...data } = response.data || {};
35
+ return new UserDataInstance(this, data, profile);
33
36
  }
34
37
  /**
35
38
  * Updates the current user's data for the specific agent
@@ -44,7 +47,9 @@ export default class UserDataApi extends HttpClient {
44
47
  if (!response.success) {
45
48
  throw new Error(response.error?.message || 'Failed to update user data');
46
49
  }
47
- return response.data;
50
+ // Extract profile if present and remove from response
51
+ const { _luaProfile, ...cleanData } = response.data || {};
52
+ return cleanData;
48
53
  }
49
54
  /**
50
55
  * Clears all user data for the current user and specific agent
@@ -14,6 +14,12 @@ import { Command } from "commander";
14
14
  * @param program - Commander program instance
15
15
  */
16
16
  export declare function setupAuthCommands(program: Command): void;
17
+ /**
18
+ * Sets up marketplace commands.
19
+ *
20
+ * @param program - Commander program instance
21
+ */
22
+ export declare function setupMarketplaceCommands(program: Command): void;
17
23
  /**
18
24
  * Sets up skill management commands.
19
25
  *
@@ -2,7 +2,7 @@
2
2
  * Command Definitions
3
3
  * Centralized command structure for the CLI
4
4
  */
5
- import { configureCommand, initCommand, destroyCommand, apiKeyCommand, compileCommand, testCommand, pushCommand, deployCommand, chatCommand, chatClearCommand, envCommand, personaCommand, productionCommand, resourcesCommand, adminCommand, docsCommand, channelsCommand, logsCommand, completionCommand, skillsCommand, webhooksCommand, jobsCommand, featuresCommand, preprocessorsCommand, postprocessorsCommand } from "../commands/index.js";
5
+ import { configureCommand, initCommand, destroyCommand, apiKeyCommand, compileCommand, testCommand, pushCommand, deployCommand, chatCommand, chatClearCommand, envCommand, personaCommand, productionCommand, resourcesCommand, adminCommand, docsCommand, channelsCommand, logsCommand, completionCommand, skillsCommand, webhooksCommand, jobsCommand, featuresCommand, preprocessorsCommand, postprocessorsCommand, marketplaceCommand } from "../commands/index.js";
6
6
  /**
7
7
  * Sets up authentication-related commands.
8
8
  *
@@ -36,6 +36,30 @@ Examples:
36
36
  .description("Display your stored API key")
37
37
  .action(apiKeyCommand);
38
38
  }
39
+ /**
40
+ * Sets up marketplace commands.
41
+ *
42
+ * @param program - Commander program instance
43
+ */
44
+ export function setupMarketplaceCommands(program) {
45
+ program
46
+ .command("marketplace [role]")
47
+ .description("🛍️ Browse, install, and manage marketplace skills")
48
+ .addHelpText('after', `
49
+ Arguments:
50
+ role Optional: 'create' or 'install' (prompts if not provided)
51
+
52
+ Features:
53
+ • Creator: List, publish, update, unlist skills and manage versions
54
+ • Installer: Browse, search, install, and manage marketplace skills
55
+
56
+ Examples:
57
+ $ lua marketplace Interactive selection
58
+ $ lua marketplace create Creator actions directly
59
+ $ lua marketplace install Installer actions directly
60
+ `)
61
+ .action(marketplaceCommand);
62
+ }
39
63
  /**
40
64
  * Sets up skill management commands.
41
65
  *
@@ -2,6 +2,17 @@
2
2
  * Environment Variables Command
3
3
  * Manages environment variables for sandbox and production environments
4
4
  */
5
+ import DeveloperApi from '../api/developer.api.service.js';
6
+ export interface EnvVariable {
7
+ key: string;
8
+ value: string;
9
+ }
10
+ export interface EnvCommandContext {
11
+ environment: 'sandbox' | 'production';
12
+ agentId: string;
13
+ apiKey: string;
14
+ developerApi?: DeveloperApi;
15
+ }
5
16
  /**
6
17
  * Main env command - manages environment variables
7
18
  *
@@ -11,6 +11,7 @@ import { withErrorHandling, writeProgress, writeSuccess } from '../utils/cli.js'
11
11
  import { BASE_URLS } from '../config/constants.js';
12
12
  import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
13
13
  import DeveloperApi from '../api/developer.api.service.js';
14
+ import { loadEnvironmentVariables } from '../utils/env-loader.utils.js';
14
15
  /**
15
16
  * Main env command - manages environment variables
16
17
  *
@@ -154,85 +155,6 @@ async function manageEnvironmentVariables(context) {
154
155
  }
155
156
  }
156
157
  }
157
- /**
158
- * Load environment variables based on context
159
- */
160
- async function loadEnvironmentVariables(context) {
161
- if (context.environment === 'sandbox') {
162
- return loadSandboxEnvVariables();
163
- }
164
- else {
165
- return loadProductionEnvVariables(context);
166
- }
167
- }
168
- /**
169
- * Load sandbox environment variables from .env file
170
- */
171
- function loadSandboxEnvVariables() {
172
- const envFilePath = path.join(process.cwd(), '.env');
173
- if (!fs.existsSync(envFilePath)) {
174
- return [];
175
- }
176
- try {
177
- const content = fs.readFileSync(envFilePath, 'utf8');
178
- return parseEnvContent(content);
179
- }
180
- catch (error) {
181
- console.error('❌ Error reading .env file:', error);
182
- return [];
183
- }
184
- }
185
- /**
186
- * Load production environment variables from API
187
- */
188
- async function loadProductionEnvVariables(context) {
189
- try {
190
- if (!context.developerApi) {
191
- throw new Error('Developer API not initialized');
192
- }
193
- const response = await context.developerApi.getEnvironmentVariables();
194
- if (!response.success) {
195
- throw new Error(response.error?.message || 'Failed to load environment variables');
196
- }
197
- // The API returns environment variables nested in a 'data' property
198
- // Response structure: { success: true, data: { data: { KEY: "value", ... }, _id: "...", ... } }
199
- const envData = response.data?.data || response.data;
200
- if (envData && typeof envData === 'object') {
201
- // Filter out metadata fields like _id, agentId, createdAt, updatedAt, __v
202
- const metadataKeys = ['_id', 'agentId', 'data', 'createdAt', 'updatedAt', '__v'];
203
- return Object.entries(envData)
204
- .filter(([key]) => !metadataKeys.includes(key))
205
- .map(([key, value]) => ({
206
- key,
207
- value: String(value)
208
- }));
209
- }
210
- return [];
211
- }
212
- catch (error) {
213
- console.error('❌ Error loading production env variables:', error);
214
- return [];
215
- }
216
- }
217
- /**
218
- * Parse .env file content into variables
219
- */
220
- function parseEnvContent(content) {
221
- if (!content.trim())
222
- return [];
223
- return content
224
- .split('\n')
225
- .map(line => line.trim())
226
- .filter(line => line && !line.startsWith('#'))
227
- .map(line => {
228
- const [key, ...valueParts] = line.split('=');
229
- return {
230
- key: key?.trim() || '',
231
- value: valueParts.join('=') || ''
232
- };
233
- })
234
- .filter(item => item.key);
235
- }
236
158
  /**
237
159
  * Convert variables array to .env file content
238
160
  */
@@ -24,3 +24,4 @@ export { jobsCommand } from "./jobs.js";
24
24
  export { featuresCommand } from "./features.js";
25
25
  export { preprocessorsCommand } from "./preprocessors.js";
26
26
  export { postprocessorsCommand } from "./postprocessors.js";
27
+ export { marketplaceCommand } from "./marketplace.js";
@@ -24,3 +24,4 @@ export { jobsCommand } from "./jobs.js";
24
24
  export { featuresCommand } from "./features.js";
25
25
  export { preprocessorsCommand } from "./preprocessors.js";
26
26
  export { postprocessorsCommand } from "./postprocessors.js";
27
+ export { marketplaceCommand } from "./marketplace.js";