luxlabs 1.0.11 → 1.0.13

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.
@@ -20,6 +20,7 @@ const chalk = require('chalk');
20
20
  const fs = require('fs');
21
21
  const path = require('path');
22
22
  const ora = require('ora');
23
+ const { loadConfig, getProjectId, getStudioApiUrl } = require('../lib/config');
23
24
 
24
25
  /**
25
26
  * Show help for ab-tests commands
@@ -37,15 +38,16 @@ function showHelp() {
37
38
  console.log(chalk.dim(' Get details for a specific variant within a test'));
38
39
  console.log(chalk.dim(' Options: --json (JSON output)\n'));
39
40
  console.log(chalk.yellow('Lifecycle Commands (called by agent after implementing changes):\n'));
40
- console.log(chalk.white(' lux ab-tests create-finished <test-id> --interface <id>'));
41
+ console.log(chalk.white(' lux ab-tests create-finished <test-id> --interface <id> --project <id>'));
41
42
  console.log(chalk.dim(' Sync a new A/B test to PostHog after implementation'));
42
43
  console.log(chalk.dim(' Updates status to "active"\n'));
43
- console.log(chalk.white(' lux ab-tests update-finished <test-id> --interface <id>'));
44
+ console.log(chalk.white(' lux ab-tests update-finished <test-id> --interface <id> --project <id>'));
44
45
  console.log(chalk.dim(' Sync updated A/B test to PostHog after code changes'));
45
46
  console.log(chalk.dim(' Updates status to "active"\n'));
46
- console.log(chalk.white(' lux ab-tests delete-finished <test-id> --interface <id>'));
47
+ console.log(chalk.white(' lux ab-tests delete-finished <test-id> --interface <id> --project <id>'));
47
48
  console.log(chalk.dim(' Remove A/B test from PostHog and database after code removal'));
48
49
  console.log(chalk.dim(' Deletes test completely\n'));
50
+ console.log(chalk.dim('Note: Project ID can be auto-detected from .lux.json if present.\n'));
49
51
  }
50
52
 
51
53
  /**
@@ -385,7 +387,7 @@ async function getVariant(testKey, variantKey, interfaceId, options) {
385
387
  * Parse command options from args array
386
388
  */
387
389
  function parseOptions(args) {
388
- const options = { json: false, interface: null };
390
+ const options = { json: false, interface: null, project: null };
389
391
  const remaining = [];
390
392
 
391
393
  for (let i = 0; i < args.length; i++) {
@@ -397,6 +399,11 @@ function parseOptions(args) {
397
399
  if (i + 1 < args.length) {
398
400
  options.interface = args[++i];
399
401
  }
402
+ } else if (arg === '--project' || arg === '-p') {
403
+ // Next arg is the project ID
404
+ if (i + 1 < args.length) {
405
+ options.project = args[++i];
406
+ }
400
407
  } else if (!arg.startsWith('-')) {
401
408
  remaining.push(arg);
402
409
  }
@@ -406,27 +413,24 @@ function parseOptions(args) {
406
413
  }
407
414
 
408
415
  /**
409
- * Get credentials from config file
416
+ * Get credentials using the shared config system
410
417
  */
411
- function getCredentials() {
412
- const os = require('os');
413
- const configPath = path.join(os.homedir(), '.lux', 'config.json');
414
-
415
- if (!fs.existsSync(configPath)) {
418
+ function getCredentials(options) {
419
+ // Use the shared config system from lib/config.js
420
+ const config = loadConfig();
421
+ if (!config || !config.apiKey || !config.orgId) {
416
422
  return null;
417
423
  }
418
424
 
419
- try {
420
- const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
421
- return {
422
- apiKey: config.apiKey,
423
- orgId: config.orgId,
424
- projectId: config.projectId,
425
- apiUrl: config.apiUrl || 'https://v2.uselux.ai'
426
- };
427
- } catch (e) {
428
- return null;
429
- }
425
+ // Get projectId from options or the shared config system
426
+ let projectId = options?.project || getProjectId();
427
+
428
+ return {
429
+ apiKey: config.apiKey,
430
+ orgId: config.orgId,
431
+ projectId: projectId,
432
+ apiUrl: getStudioApiUrl()
433
+ };
430
434
  }
431
435
 
432
436
  /**
@@ -543,12 +547,17 @@ async function createFinished(testId, options) {
543
547
  const spinner = ora('Syncing new A/B test to PostHog...').start();
544
548
 
545
549
  try {
546
- const creds = getCredentials();
550
+ const creds = getCredentials(options);
547
551
  if (!creds || !creds.apiKey) {
548
552
  spinner.fail('Not authenticated. Run "lux login" first.');
549
553
  return;
550
554
  }
551
555
 
556
+ if (!creds.projectId) {
557
+ spinner.fail('Could not determine project ID. Use --project <id> to specify, or ensure .lux.json contains projectId.');
558
+ return;
559
+ }
560
+
552
561
  const interfaceId = getInterfaceId(options);
553
562
  if (!interfaceId) {
554
563
  spinner.fail('Could not determine interface ID. Use --interface <id> to specify.');
@@ -576,12 +585,17 @@ async function updateFinished(testId, options) {
576
585
  const spinner = ora('Syncing A/B test changes to PostHog...').start();
577
586
 
578
587
  try {
579
- const creds = getCredentials();
588
+ const creds = getCredentials(options);
580
589
  if (!creds || !creds.apiKey) {
581
590
  spinner.fail('Not authenticated. Run "lux login" first.');
582
591
  return;
583
592
  }
584
593
 
594
+ if (!creds.projectId) {
595
+ spinner.fail('Could not determine project ID. Use --project <id> to specify, or ensure .lux.json contains projectId.');
596
+ return;
597
+ }
598
+
585
599
  const interfaceId = getInterfaceId(options);
586
600
  if (!interfaceId) {
587
601
  spinner.fail('Could not determine interface ID. Use --interface <id> to specify.');
@@ -608,12 +622,17 @@ async function deleteFinished(testId, options) {
608
622
  const spinner = ora('Removing A/B test from PostHog...').start();
609
623
 
610
624
  try {
611
- const creds = getCredentials();
625
+ const creds = getCredentials(options);
612
626
  if (!creds || !creds.apiKey) {
613
627
  spinner.fail('Not authenticated. Run "lux login" first.');
614
628
  return;
615
629
  }
616
630
 
631
+ if (!creds.projectId) {
632
+ spinner.fail('Could not determine project ID. Use --project <id> to specify, or ensure .lux.json contains projectId.');
633
+ return;
634
+ }
635
+
617
636
  const interfaceId = getInterfaceId(options);
618
637
  if (!interfaceId) {
619
638
  spinner.fail('Could not determine interface ID. Use --interface <id> to specify.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luxlabs",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
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",