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
@@ -388,9 +388,11 @@ async function listPersonaVersions(context) {
388
388
  choices: sortedVersions.map((version, index) => {
389
389
  const date = new Date(version.createdDate);
390
390
  const dateStr = date.toLocaleDateString();
391
- const deployedMark = version.isCurrent ? ' ⭐ CURRENT' : '';
391
+ const timeStr = date.toLocaleTimeString();
392
+ const status = version.status === 'draft' ? '[DRAFT]' : '';
393
+ const currentMark = version.isCurrent ? ' ⭐ CURRENT' : '';
392
394
  return {
393
- name: `Version ${version.version} (${dateStr})${deployedMark}`,
395
+ name: `Version ${version.version} ${status} - (${dateStr}) ${timeStr} ${currentMark}`,
394
396
  value: index
395
397
  };
396
398
  })
@@ -415,7 +417,9 @@ async function viewVersionDetails(versions) {
415
417
  console.log(`Persona Version ${version.version}`);
416
418
  console.log("=".repeat(60));
417
419
  console.log(`Created: ${date.toLocaleString()}`);
418
- console.log(`Status: ${version.isCurrent ? ' CURRENT' : 'Available'}`);
420
+ const versionStatus = version.status === 'draft' ? '🔨 DRAFT' : '';
421
+ console.log(`Version Status: ${versionStatus}`);
422
+ console.log(`Active Status: ${version.isCurrent ? '⭐ CURRENT' : 'Available'}`);
419
423
  if (version.createdBy) {
420
424
  console.log(`Created by: ${version.createdBy}`);
421
425
  }
@@ -480,8 +484,9 @@ async function deployPersonaVersion(context) {
480
484
  const dateStr = date.toLocaleDateString();
481
485
  const timeStr = date.toLocaleTimeString();
482
486
  const currentMark = v.isCurrent ? ' ⭐ CURRENTLY DEPLOYED' : '';
487
+ const status = v.status === "draft" ? "[DRAFT]" : "";
483
488
  return {
484
- name: `Version ${v.version} - ${dateStr} ${timeStr}${currentMark}`,
489
+ name: `Version ${v.version} ${status} - (${dateStr}) ${timeStr} ${currentMark}`,
485
490
  value: v.version
486
491
  };
487
492
  })
@@ -2,7 +2,6 @@
2
2
  * Job Instance
3
3
  * Provides a convenient interface for interacting with a job
4
4
  */
5
- import UserDataInstance from './user.instance.js';
6
5
  import UserDataApi from '../api/user.data.api.service.js';
7
6
  import { BASE_URLS } from '../config/constants.js';
8
7
  /**
@@ -97,8 +96,7 @@ export class JobInstance {
97
96
  }
98
97
  }
99
98
  async user() {
100
- const result = await this.userApi.get();
101
- return new UserDataInstance(this.userApi, result);
99
+ return await this.userApi.get();
102
100
  }
103
101
  /**
104
102
  * Converts the job instance to JSON.
@@ -1,21 +1,24 @@
1
1
  import { Message } from "../interfaces/message.js";
2
2
  import { UserDataAPI } from "../types/index.js";
3
+ import { ImmutableUserProfile, UserAgentData } from "../interfaces/user.js";
3
4
  /**
4
5
  * User data instance class providing a fluent API for managing user data
5
6
  * Provides methods for updating and clearing data
6
7
  * Supports direct property access (e.g., user.name) instead of user.data.name
7
8
  */
8
9
  export default class UserDataInstance {
9
- data: Record<string, any>;
10
+ data: UserAgentData;
10
11
  private userAPI;
12
+ _luaProfile: ImmutableUserProfile;
11
13
  [key: string]: any;
12
14
  /**
13
15
  * Creates a new UserDataInstance with proxy support for direct property access
14
16
  * @param api - The UserDataAPI instance for making API calls
15
17
  * @param data - The user data from the API
18
+ * @param profile - The immutable user profile data
16
19
  * @returns Proxied instance that allows direct access to data properties
17
20
  */
18
- constructor(api: UserDataAPI, data: any);
21
+ constructor(api: UserDataAPI, data: any, profile?: ImmutableUserProfile);
19
22
  /**
20
23
  * Custom toJSON method to control what gets serialized when logging
21
24
  * @returns Serialized user data
@@ -8,17 +8,34 @@ export default class UserDataInstance {
8
8
  * Creates a new UserDataInstance with proxy support for direct property access
9
9
  * @param api - The UserDataAPI instance for making API calls
10
10
  * @param data - The user data from the API
11
+ * @param profile - The immutable user profile data
11
12
  * @returns Proxied instance that allows direct access to data properties
12
13
  */
13
- constructor(api, data) {
14
+ constructor(api, data, profile) {
14
15
  // Ensure data is always an object, never null or undefined
15
- this.data = data && typeof data === 'object' ? data : {};
16
+ this.data = data && typeof data === "object" ? data : {};
16
17
  // Make userAPI non-enumerable so it doesn't show up in console.log
17
- Object.defineProperty(this, 'userAPI', {
18
+ Object.defineProperty(this, "userAPI", {
18
19
  value: api,
19
20
  writable: true,
20
21
  enumerable: false,
21
- configurable: true
22
+ configurable: true,
23
+ });
24
+ // Make _luaProfile non-enumerable and immutable
25
+ Object.defineProperty(this, "_luaProfile", {
26
+ get() {
27
+ return (profile || {
28
+ userId: "",
29
+ fullName: "",
30
+ mobileNumbers: [],
31
+ emailAddresses: [],
32
+ });
33
+ },
34
+ set(_) {
35
+ // silently ignore any attempts to modify
36
+ },
37
+ enumerable: false,
38
+ configurable: false,
22
39
  });
23
40
  // Return a proxy that allows direct property access
24
41
  return new Proxy(this, {
@@ -28,21 +45,31 @@ export default class UserDataInstance {
28
45
  return Reflect.get(target, prop, receiver);
29
46
  }
30
47
  // Otherwise, try to get it from the data object (with null check)
31
- if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {
48
+ if (typeof prop === "string" &&
49
+ target.data &&
50
+ typeof target.data === "object" &&
51
+ prop in target.data) {
32
52
  return target.data[prop];
33
53
  }
34
54
  return undefined;
35
55
  },
36
56
  set(target, prop, value, receiver) {
37
57
  // Reserved properties that should be set on the instance itself
38
- const reservedProps = ['data', 'userAPI', 'update', 'clear', 'toJSON'];
39
- if (typeof prop === 'string' && reservedProps.includes(prop)) {
58
+ const reservedProps = [
59
+ "data",
60
+ "userAPI",
61
+ "update",
62
+ "clear",
63
+ "toJSON",
64
+ "_luaProfile",
65
+ ];
66
+ if (typeof prop === "string" && reservedProps.includes(prop)) {
40
67
  return Reflect.set(target, prop, value, receiver);
41
68
  }
42
69
  // All other properties get set on the data object
43
- if (typeof prop === 'string') {
70
+ if (typeof prop === "string") {
44
71
  // Initialize data object if it doesn't exist
45
- if (!target.data || typeof target.data !== 'object') {
72
+ if (!target.data || typeof target.data !== "object") {
46
73
  target.data = {};
47
74
  }
48
75
  target.data[prop] = value;
@@ -55,7 +82,9 @@ export default class UserDataInstance {
55
82
  if (prop in target) {
56
83
  return true;
57
84
  }
58
- if (typeof prop === 'string' && target.data && typeof target.data === 'object') {
85
+ if (typeof prop === "string" &&
86
+ target.data &&
87
+ typeof target.data === "object") {
59
88
  return prop in target.data;
60
89
  }
61
90
  return false;
@@ -63,7 +92,9 @@ export default class UserDataInstance {
63
92
  ownKeys(target) {
64
93
  // Return both instance keys and data keys (with null check)
65
94
  const instanceKeys = Reflect.ownKeys(target);
66
- const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];
95
+ const dataKeys = target.data && typeof target.data === "object"
96
+ ? Object.keys(target.data)
97
+ : [];
67
98
  return [...new Set([...instanceKeys, ...dataKeys])];
68
99
  },
69
100
  getOwnPropertyDescriptor(target, prop) {
@@ -73,16 +104,19 @@ export default class UserDataInstance {
73
104
  return instanceDesc;
74
105
  }
75
106
  // Then check if it's a data property (with null check)
76
- if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {
107
+ if (typeof prop === "string" &&
108
+ target.data &&
109
+ typeof target.data === "object" &&
110
+ prop in target.data) {
77
111
  return {
78
112
  configurable: true,
79
113
  enumerable: true,
80
114
  writable: true,
81
- value: target.data[prop]
115
+ value: target.data[prop],
82
116
  };
83
117
  }
84
118
  return undefined;
85
- }
119
+ },
86
120
  });
87
121
  }
88
122
  /**
@@ -96,7 +130,7 @@ export default class UserDataInstance {
96
130
  * Custom inspect method for Node.js console.log
97
131
  * @returns Formatted user data for console output
98
132
  */
99
- [Symbol.for('nodejs.util.inspect.custom')]() {
133
+ [Symbol.for("nodejs.util.inspect.custom")]() {
100
134
  return this.data;
101
135
  }
102
136
  /**
@@ -108,11 +142,11 @@ export default class UserDataInstance {
108
142
  async update(data) {
109
143
  try {
110
144
  const response = await this.userAPI.update(data);
111
- this.data = response.data;
145
+ this.data = response;
112
146
  return this.data;
113
147
  }
114
148
  catch (error) {
115
- throw new Error('Failed to update user data');
149
+ throw new Error("Failed to update user data");
116
150
  }
117
151
  }
118
152
  /**
@@ -126,7 +160,7 @@ export default class UserDataInstance {
126
160
  return true;
127
161
  }
128
162
  catch (error) {
129
- throw new Error('Failed to clear user data');
163
+ throw new Error("Failed to clear user data");
130
164
  }
131
165
  }
132
166
  /**
@@ -140,7 +174,7 @@ export default class UserDataInstance {
140
174
  return true;
141
175
  }
142
176
  catch (error) {
143
- throw new Error('Failed to save user data');
177
+ throw new Error("Failed to save user data");
144
178
  }
145
179
  }
146
180
  /**
@@ -155,7 +189,7 @@ export default class UserDataInstance {
155
189
  return true;
156
190
  }
157
191
  catch (error) {
158
- throw new Error('Failed to send message');
192
+ throw new Error("Failed to send message");
159
193
  }
160
194
  }
161
195
  //get chat history
@@ -164,7 +198,7 @@ export default class UserDataInstance {
164
198
  return await this.userAPI.getChatHistory();
165
199
  }
166
200
  catch (error) {
167
- throw new Error('Failed to get chat history');
201
+ throw new Error("Failed to get chat history");
168
202
  }
169
203
  }
170
204
  }
@@ -5,7 +5,7 @@
5
5
  * Base URLs for the API, Auth, and Chat - Development
6
6
  */
7
7
  export declare const BASE_URLS: {
8
- readonly API: "https://api.heylua.ai";
8
+ readonly API: "http://localhost:3001";
9
9
  readonly AUTH: "https://auth.heylua.ai";
10
10
  readonly CHAT: "https://api.heylua.ai";
11
11
  readonly WEBHOOK: "https://webhook.heylua.ai";
@@ -11,7 +11,11 @@
11
11
  * Base URLs for the API, Auth, and Chat - Development
12
12
  */
13
13
  export const BASE_URLS = {
14
- API: 'https://api.heylua.ai',
14
+ // API: 'https://api.heylua.ai',
15
+ // AUTH: 'https://auth.heylua.ai',
16
+ // CHAT: 'https://api.heylua.ai',
17
+ // WEBHOOK: 'https://webhook.heylua.ai',
18
+ API: 'http://localhost:3001',
15
19
  AUTH: 'https://auth.heylua.ai',
16
20
  CHAT: 'https://api.heylua.ai',
17
21
  WEBHOOK: 'https://webhook.heylua.ai',
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * For more information: https://docs.heylua.ai
10
10
  */
11
11
  import { Command } from "commander";
12
- import { setupAuthCommands, setupSkillCommands } from "./cli/command-definitions.js";
12
+ import { setupAuthCommands, setupSkillCommands, setupMarketplaceCommands } from "./cli/command-definitions.js";
13
13
  import { readFileSync } from "fs";
14
14
  import { fileURLToPath } from "url";
15
15
  import { dirname, join } from "path";
@@ -63,12 +63,14 @@ Examples:
63
63
  $ lua admin 🔧 Open admin dashboard
64
64
  $ lua docs 📖 Open documentation
65
65
  $ lua completion 🎯 Enable shell autocomplete
66
-
67
- 🌙 Documentation: https://docs.heylua.ai
68
- 🌙 Support: https://heylua.ai/support
66
+ $ lua marketplace 🛍️ Interact with the Lua Marketplace
67
+
68
+ 🌙 Documentation: https://docs.heylua.ai
69
+ 🌙 Support: https://heylua.ai/support
69
70
  `);
70
71
  // Set up all command groups
71
72
  setupAuthCommands(program);
72
73
  setupSkillCommands(program);
74
+ setupMarketplaceCommands(program);
73
75
  // Parse command-line arguments
74
76
  program.parse(process.argv);
@@ -4,7 +4,8 @@
4
4
  * This file serves as the main entry point for all interface definitions.
5
5
  * It re-exports interfaces and DTOs from various modules for convenient importing.
6
6
  */
7
- export { CreateWebhookDTO, PushWebhookVersionDTO, UpdateWebhookVersionDTO, WebhookVersion, Webhook, GetWebhooksResponse, DeleteWebhookResponse, CreateWebhookResponse, PushWebhookVersionResponse, } from './webhooks.js';
8
- export { CreateJobDTO, PushJobVersionDTO, UpdateJobVersionDTO, JobSchedule, JobScheduleType, JobRetryConfig, JobVersion, JobExecutionStatus, JobExecution, JobStatus, Job, GetJobsResponse, DeleteJobResponse, CreateJobResponse, PushJobVersionResponse, JobExecutionResponse, GetJobExecutionsResponse, } from './jobs.js';
9
- export { ApiResponse, Pagination, } from './common.js';
10
- export { SkillTool, SkillVersion, Skill, GetSkillsResponse, DeleteSkillResponse, } from './skills.js';
7
+ export { CreateWebhookDTO, PushWebhookVersionDTO, UpdateWebhookVersionDTO, WebhookVersion, Webhook, GetWebhooksResponse, DeleteWebhookResponse, CreateWebhookResponse, PushWebhookVersionResponse, } from "./webhooks.js";
8
+ export { CreateJobDTO, PushJobVersionDTO, UpdateJobVersionDTO, JobSchedule, JobScheduleType, JobRetryConfig, JobVersion, JobExecutionStatus, JobExecution, JobStatus, Job, GetJobsResponse, DeleteJobResponse, CreateJobResponse, PushJobVersionResponse, JobExecutionResponse, GetJobExecutionsResponse, } from "./jobs.js";
9
+ export { ApiResponse, Pagination } from "./common.js";
10
+ export { SkillTool, SkillVersion, Skill, GetSkillsResponse, DeleteSkillResponse, } from "./skills.js";
11
+ export { ImmutableUserProfile, UserAgentData } from "./user.js";
@@ -0,0 +1,99 @@
1
+ export interface EnvVarMetadata {
2
+ description: string;
3
+ required: boolean;
4
+ example?: string;
5
+ }
6
+ /**
7
+ * Marketplace Skill Version Response
8
+ */
9
+ export interface MarketplaceVersionResponse {
10
+ id: string;
11
+ marketplaceSkillId: string;
12
+ version: string;
13
+ description: string;
14
+ changelog?: string;
15
+ context?: any;
16
+ tools?: any;
17
+ envVarsMetadata?: Record<string, EnvVarMetadata>;
18
+ approvalStatus: string;
19
+ published: boolean;
20
+ approvalNotes?: string;
21
+ approvedBy?: string;
22
+ approvedAt?: Date | string;
23
+ createdBy: string;
24
+ createdAt: Date | string;
25
+ }
26
+ /**
27
+ * Complete Marketplace Skill Response with all details and versions
28
+ */
29
+ export interface MarketplaceSkillWithVersionsResponse {
30
+ id: string;
31
+ name: string;
32
+ displayName: string;
33
+ description: string;
34
+ longDescription?: string;
35
+ category?: string;
36
+ tags: string[];
37
+ creatorId: string;
38
+ sourceSkillId: string;
39
+ listed: boolean;
40
+ verified: boolean;
41
+ featured: boolean;
42
+ published: boolean;
43
+ installCount: number;
44
+ activeInstallCount: number;
45
+ iconUrl?: string;
46
+ screenshots?: string[];
47
+ repositoryUrl?: string;
48
+ documentationUrl?: string;
49
+ listedAt?: Date | string;
50
+ createdAt: Date | string;
51
+ updatedAt: Date | string;
52
+ versions: MarketplaceVersionResponse[];
53
+ versionsCount: number;
54
+ pendingVersionsCount: number;
55
+ approvedVersionsCount: number;
56
+ }
57
+ /**
58
+ * Skill Response (including installed marketplace skills)
59
+ */
60
+ export interface SkillResponse {
61
+ id: string;
62
+ name: string;
63
+ title: string;
64
+ description: string;
65
+ public: boolean;
66
+ agentId: string;
67
+ active: boolean;
68
+ activeVersionId?: string;
69
+ version?: any;
70
+ versionContext?: string;
71
+ installedFromMarketplace: boolean;
72
+ marketplaceSkillId?: string;
73
+ marketplaceInstallMetadata?: {
74
+ installedVersionId: string;
75
+ installedBy: string;
76
+ installedAt: Date | string;
77
+ };
78
+ createdBy: string;
79
+ createdAt: Date | string;
80
+ updatedAt: Date | string;
81
+ }
82
+ /**
83
+ * Unpublish Version Response
84
+ */
85
+ export interface UnpublishVersionResponse {
86
+ message: string;
87
+ success: boolean;
88
+ skillUnlisted: boolean;
89
+ versionId: string;
90
+ }
91
+ /**
92
+ * Unlist Skill Response
93
+ */
94
+ export interface UnlistSkillResponse {
95
+ message: string;
96
+ success: boolean;
97
+ unlisted: boolean;
98
+ versionsUnpublished: number;
99
+ }
@@ -0,0 +1,2 @@
1
+ // ==================== MARKETPLACE RESPONSE INTERFACES ====================
2
+ export {};
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Immutable user profile information from Lua's user database
3
+ */
4
+ export interface ImmutableUserProfile {
5
+ userId: string;
6
+ fullName: string;
7
+ mobileNumbers: string[];
8
+ emailAddresses: string[];
9
+ }
10
+ /**
11
+ * Base user agent data structure
12
+ */
13
+ export interface UserAgentData extends Record<string, any> {
14
+ /**
15
+ * @deprecated Use `user._luaProfile.userId` instead. This property is kept for backwards compatibility and will be removed in a future version.
16
+ * Note: This refers only to the Lua userId. If you use a custom `userId` property in your app that is not the Lua user ID, ignore this deprecation notice.
17
+ */
18
+ userId?: string;
19
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -47,47 +47,54 @@ export interface JobMetadata {
47
47
  /**
48
48
  * Configuration from lua.skill.yaml
49
49
  */
50
- export interface SkillConfig {
51
- skill?: {
52
- name?: string;
53
- version?: string;
54
- skillId?: string;
55
- description?: string;
56
- context?: string;
57
- env?: Record<string, string>;
58
- };
59
- agent?: {
60
- agentId?: string;
61
- orgId?: string;
62
- persona?: string;
63
- welcomeMessage?: string;
64
- };
65
- skills?: Array<{
66
- name: string;
67
- version: string;
68
- skillId: string;
69
- }>;
70
- webhooks?: Array<{
71
- name: string;
72
- version: string;
73
- webhookId: string;
74
- }>;
75
- jobs?: Array<{
76
- name: string;
77
- version: string;
78
- jobId: string;
79
- schedule?: any;
80
- }>;
81
- preprocessors?: Array<{
82
- name: string;
83
- version: string;
84
- preprocessorId: string;
85
- }>;
86
- postprocessors?: Array<{
87
- name: string;
88
- version: string;
89
- postprocessorId: string;
90
- }>;
50
+ export interface LegacyYamlConfigSkill {
51
+ name?: string;
52
+ version?: string;
53
+ skillId?: string;
54
+ description?: string;
55
+ context?: string;
56
+ env?: Record<string, string>;
57
+ }
58
+ export interface YamlConfigAgent {
59
+ agentId?: string;
60
+ orgId?: string;
61
+ persona?: string;
62
+ welcomeMessage?: string;
63
+ }
64
+ export interface YamlConfigSkill {
65
+ name: string;
66
+ version: string;
67
+ skillId: string;
68
+ }
69
+ export interface YamlConfigWebhook {
70
+ name: string;
71
+ version: string;
72
+ webhookId: string;
73
+ }
74
+ export interface YamlConfigJob {
75
+ name: string;
76
+ version: string;
77
+ jobId: string;
78
+ schedule?: any;
79
+ }
80
+ export interface YamlConfigPreprocessor {
81
+ name: string;
82
+ version: string;
83
+ preprocessorId: string;
84
+ }
85
+ export interface YamlConfigPostprocessor {
86
+ name: string;
87
+ version: string;
88
+ postprocessorId: string;
89
+ }
90
+ export interface YamlConfig {
91
+ skill?: LegacyYamlConfigSkill;
92
+ agent?: YamlConfigAgent;
93
+ skills?: YamlConfigSkill[];
94
+ webhooks?: YamlConfigWebhook[];
95
+ jobs?: YamlConfigJob[];
96
+ preprocessors?: YamlConfigPreprocessor[];
97
+ postprocessors?: YamlConfigPostprocessor[];
91
98
  }
92
99
  /**
93
100
  * Deployment data format for new deployment system
@@ -1,4 +1,5 @@
1
1
  /**
2
2
  * Type definitions for compile command
3
3
  */
4
+ ;
4
5
  export {};
@@ -0,0 +1,9 @@
1
+ import { EnvCommandContext, EnvVariable } from "../commands/env";
2
+ /**
3
+ * Load environment variables based on context
4
+ */
5
+ export declare function loadEnvironmentVariables(context: EnvCommandContext): Promise<EnvVariable[]>;
6
+ /**
7
+ * Load sandbox environment variables from .env file
8
+ */
9
+ export declare function loadSandboxEnvVariables(): EnvVariable[];
@@ -0,0 +1,88 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ /**
4
+ * Load environment variables based on context
5
+ */
6
+ export async function loadEnvironmentVariables(context) {
7
+ if (context.environment === "sandbox") {
8
+ return loadSandboxEnvVariables();
9
+ }
10
+ else {
11
+ return loadProductionEnvVariables(context);
12
+ }
13
+ }
14
+ /**
15
+ * Load sandbox environment variables from .env file
16
+ */
17
+ export function loadSandboxEnvVariables() {
18
+ const envFilePath = path.join(process.cwd(), ".env");
19
+ if (!fs.existsSync(envFilePath)) {
20
+ return [];
21
+ }
22
+ try {
23
+ const content = fs.readFileSync(envFilePath, "utf8");
24
+ return parseEnvContent(content);
25
+ }
26
+ catch (error) {
27
+ console.error("❌ Error reading .env file:", error);
28
+ return [];
29
+ }
30
+ }
31
+ /**
32
+ * Load production environment variables from API
33
+ */
34
+ async function loadProductionEnvVariables(context) {
35
+ try {
36
+ if (!context.developerApi) {
37
+ throw new Error("Developer API not initialized");
38
+ }
39
+ const response = await context.developerApi.getEnvironmentVariables();
40
+ if (!response.success) {
41
+ throw new Error(response.error?.message || "Failed to load environment variables");
42
+ }
43
+ // The API returns environment variables nested in a 'data' property
44
+ // Response structure: { success: true, data: { data: { KEY: "value", ... }, _id: "...", ... } }
45
+ const envData = response.data?.data || response.data;
46
+ if (envData && typeof envData === "object") {
47
+ // Filter out metadata fields like _id, agentId, createdAt, updatedAt, __v
48
+ const metadataKeys = [
49
+ "_id",
50
+ "agentId",
51
+ "data",
52
+ "createdAt",
53
+ "updatedAt",
54
+ "__v",
55
+ ];
56
+ return Object.entries(envData)
57
+ .filter(([key]) => !metadataKeys.includes(key))
58
+ .map(([key, value]) => ({
59
+ key,
60
+ value: String(value),
61
+ }));
62
+ }
63
+ return [];
64
+ }
65
+ catch (error) {
66
+ console.error("❌ Error loading production env variables:", error);
67
+ return [];
68
+ }
69
+ }
70
+ /**
71
+ * Parse .env file content into variables
72
+ */
73
+ function parseEnvContent(content) {
74
+ if (!content.trim())
75
+ return [];
76
+ return content
77
+ .split("\n")
78
+ .map((line) => line.trim())
79
+ .filter((line) => line && !line.startsWith("#"))
80
+ .map((line) => {
81
+ const [key, ...valueParts] = line.split("=");
82
+ return {
83
+ key: key?.trim() || "",
84
+ value: valueParts.join("=") || "",
85
+ };
86
+ })
87
+ .filter((item) => item.key);
88
+ }