luxlabs 1.0.20 → 1.0.21

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 (2) hide show
  1. package/lib/config.js +62 -39
  2. package/package.json +1 -1
package/lib/config.js CHANGED
@@ -4,48 +4,78 @@ const os = require('os');
4
4
 
5
5
  // Shared storage directory (used by both Electron app and CLI)
6
6
  const LUX_STUDIO_DIR = path.join(os.homedir(), '.lux-studio');
7
- const ACTIVE_ORG_FILE = path.join(LUX_STUDIO_DIR, 'active-org.json');
7
+ const UNIFIED_CONFIG_FILE = path.join(LUX_STUDIO_DIR, 'config.json');
8
8
  const INTERFACE_FILE = '.lux/interface.json';
9
9
 
10
+ // Cache for unified config to avoid repeated file reads
11
+ let _unifiedConfigCache = null;
12
+ let _unifiedConfigMtime = null;
13
+
10
14
  /**
11
- * Load active org from shared storage
12
- * Returns { orgId, orgName } or null
15
+ * Load the unified config file (~/.lux-studio/config.json)
16
+ * This is the single source of truth used by both Electron app and CLI
13
17
  */
14
- function loadActiveOrg() {
15
- if (!fs.existsSync(ACTIVE_ORG_FILE)) {
18
+ function loadUnifiedConfig() {
19
+ if (!fs.existsSync(UNIFIED_CONFIG_FILE)) {
16
20
  return null;
17
21
  }
18
22
 
19
23
  try {
20
- const content = fs.readFileSync(ACTIVE_ORG_FILE, 'utf8');
21
- return JSON.parse(content);
24
+ // Check if file has changed since last read
25
+ const stats = fs.statSync(UNIFIED_CONFIG_FILE);
26
+ if (_unifiedConfigCache && _unifiedConfigMtime && stats.mtimeMs === _unifiedConfigMtime) {
27
+ return _unifiedConfigCache;
28
+ }
29
+
30
+ const content = fs.readFileSync(UNIFIED_CONFIG_FILE, 'utf8');
31
+ _unifiedConfigCache = JSON.parse(content);
32
+ _unifiedConfigMtime = stats.mtimeMs;
33
+ return _unifiedConfigCache;
22
34
  } catch (error) {
23
35
  return null;
24
36
  }
25
37
  }
26
38
 
27
39
  /**
28
- * Load credentials for a specific org
29
- * Returns { apiKey, orgId, orgName } or null
40
+ * Load active org from unified config
41
+ * Returns { orgId, orgName } or null
30
42
  */
31
- function loadOrgCredentials(orgId) {
32
- const credentialsPath = path.join(LUX_STUDIO_DIR, orgId, 'credentials.json');
33
-
34
- if (!fs.existsSync(credentialsPath)) {
43
+ function loadActiveOrg() {
44
+ const unifiedConfig = loadUnifiedConfig();
45
+ if (!unifiedConfig || !unifiedConfig.currentOrg) {
35
46
  return null;
36
47
  }
37
48
 
38
- try {
39
- const content = fs.readFileSync(credentialsPath, 'utf8');
40
- return JSON.parse(content);
41
- } catch (error) {
49
+ const orgId = unifiedConfig.currentOrg;
50
+ const orgData = unifiedConfig.orgs?.[orgId];
51
+
52
+ return {
53
+ orgId,
54
+ orgName: orgData?.name || null,
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Load credentials for a specific org from unified config
60
+ * Returns { apiKey, orgId, orgName } or null
61
+ */
62
+ function loadOrgCredentials(orgId) {
63
+ const unifiedConfig = loadUnifiedConfig();
64
+ if (!unifiedConfig || !unifiedConfig.orgs?.[orgId]) {
42
65
  return null;
43
66
  }
67
+
68
+ const orgData = unifiedConfig.orgs[orgId];
69
+ return {
70
+ apiKey: orgData.apiKey,
71
+ orgId: orgId,
72
+ orgName: orgData.name || null,
73
+ };
44
74
  }
45
75
 
46
76
  /**
47
77
  * Load config for the currently active org
48
- * Reads from ~/.lux-studio/active-org.json to get org, then loads credentials
78
+ * Reads from unified ~/.lux-studio/config.json
49
79
  */
50
80
  function loadConfig() {
51
81
  // Check for env vars first (for CI/automation)
@@ -56,22 +86,22 @@ function loadConfig() {
56
86
  };
57
87
  }
58
88
 
59
- // Load active org from shared storage
60
- const activeOrg = loadActiveOrg();
61
- if (!activeOrg || !activeOrg.orgId) {
89
+ const unifiedConfig = loadUnifiedConfig();
90
+ if (!unifiedConfig || !unifiedConfig.currentOrg) {
62
91
  return null;
63
92
  }
64
93
 
65
- // Load credentials for that org
66
- const credentials = loadOrgCredentials(activeOrg.orgId);
67
- if (!credentials) {
94
+ const orgId = unifiedConfig.currentOrg;
95
+ const orgData = unifiedConfig.orgs?.[orgId];
96
+
97
+ if (!orgData || !orgData.apiKey) {
68
98
  return null;
69
99
  }
70
100
 
71
101
  return {
72
- apiKey: credentials.apiKey,
73
- orgId: credentials.orgId,
74
- orgName: credentials.orgName,
102
+ apiKey: orgData.apiKey,
103
+ orgId: orgId,
104
+ orgName: orgData.name || null,
75
105
  };
76
106
  }
77
107
 
@@ -283,22 +313,14 @@ function deleteLocalFlow(flowId) {
283
313
  }
284
314
 
285
315
  /**
286
- * Get the current project ID from org config
316
+ * Get the current project ID from unified config
287
317
  * Defaults to 'default' if not set
288
318
  */
289
319
  function getProjectId() {
290
- const orgId = getOrgId();
291
- if (!orgId) return 'default';
320
+ const unifiedConfig = loadUnifiedConfig();
321
+ if (!unifiedConfig) return 'default';
292
322
 
293
- const orgConfigPath = path.join(LUX_STUDIO_DIR, orgId, 'config.json');
294
- if (!fs.existsSync(orgConfigPath)) return 'default';
295
-
296
- try {
297
- const orgConfig = JSON.parse(fs.readFileSync(orgConfigPath, 'utf8'));
298
- return orgConfig.currentProject || 'default';
299
- } catch {
300
- return 'default';
301
- }
323
+ return unifiedConfig.currentProject || 'default';
302
324
  }
303
325
 
304
326
  /**
@@ -392,6 +414,7 @@ module.exports = {
392
414
  saveConfig,
393
415
  loadActiveOrg,
394
416
  loadOrgCredentials,
417
+ loadUnifiedConfig,
395
418
  loadInterfaceConfig,
396
419
  saveInterfaceConfig,
397
420
  getApiUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luxlabs",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "description": "CLI tool for Lux - Upload and deploy interfaces from your terminal",
5
5
  "author": "Jason Henkel <jason@uselux.ai>",
6
6
  "license": "SEE LICENSE IN LICENSE",