projax 1.0.1 → 1.3.0

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 (57) hide show
  1. package/dist/api/database.d.ts +34 -0
  2. package/dist/api/database.d.ts.map +1 -0
  3. package/dist/api/database.js +318 -0
  4. package/dist/api/database.js.map +1 -0
  5. package/dist/api/index.d.ts +5 -0
  6. package/dist/api/index.d.ts.map +1 -0
  7. package/dist/api/index.js +130 -0
  8. package/dist/api/index.js.map +1 -0
  9. package/dist/api/migrate.d.ts +2 -0
  10. package/dist/api/migrate.d.ts.map +1 -0
  11. package/dist/api/migrate.js +158 -0
  12. package/dist/api/migrate.js.map +1 -0
  13. package/dist/api/package.json +27 -0
  14. package/dist/api/routes/index.d.ts +3 -0
  15. package/dist/api/routes/index.d.ts.map +1 -0
  16. package/dist/api/routes/index.js +17 -0
  17. package/dist/api/routes/index.js.map +1 -0
  18. package/dist/api/routes/projects.d.ts +3 -0
  19. package/dist/api/routes/projects.d.ts.map +1 -0
  20. package/dist/api/routes/projects.js +198 -0
  21. package/dist/api/routes/projects.js.map +1 -0
  22. package/dist/api/routes/settings.d.ts +3 -0
  23. package/dist/api/routes/settings.d.ts.map +1 -0
  24. package/dist/api/routes/settings.js +33 -0
  25. package/dist/api/routes/settings.js.map +1 -0
  26. package/dist/api/services/scanner.d.ts +9 -0
  27. package/dist/api/services/scanner.d.ts.map +1 -0
  28. package/dist/api/services/scanner.js +172 -0
  29. package/dist/api/services/scanner.js.map +1 -0
  30. package/dist/api/types.d.ts +48 -0
  31. package/dist/api/types.d.ts.map +1 -0
  32. package/dist/api/types.js +3 -0
  33. package/dist/api/types.js.map +1 -0
  34. package/dist/core/database.d.ts +15 -5
  35. package/dist/core/database.js +136 -208
  36. package/dist/core/detector.d.ts +5 -0
  37. package/dist/core/detector.js +135 -0
  38. package/dist/core/index.d.ts +1 -2
  39. package/dist/core/index.js +2 -4
  40. package/dist/core/scanner.js +2 -105
  41. package/dist/core/settings.d.ts +50 -0
  42. package/dist/core/settings.js +102 -0
  43. package/dist/electron/main.js +86 -28
  44. package/dist/electron/port-scanner.js +4 -4
  45. package/dist/electron/preload.d.ts +1 -1
  46. package/dist/electron/renderer/assets/index-7KIJIiIM.js +42 -0
  47. package/dist/electron/renderer/assets/{index-CdMlFqhB.js → index-BRymlmJj.js} +10 -10
  48. package/dist/electron/renderer/assets/{index-DohAcUCg.css → index-ezVMxZrM.css} +1 -1
  49. package/dist/electron/renderer/index.html +2 -2
  50. package/dist/electron/script-runner.js +4 -4
  51. package/dist/index.js +253 -88
  52. package/dist/port-scanner.js +4 -4
  53. package/dist/script-runner.js +4 -4
  54. package/package.json +13 -11
  55. package/dist/electron/renderer/assets/index-BZ6USRnW.js +0 -42
  56. package/dist/electron/renderer/assets/index-DNtxfrZe.js +0 -42
  57. package/dist/electron/renderer/assets/index-khk3K-qG.css +0 -1
package/dist/index.js CHANGED
@@ -37,26 +37,147 @@ Object.defineProperty(exports, "__esModule", { value: true });
37
37
  const commander_1 = require("commander");
38
38
  const path = __importStar(require("path"));
39
39
  const fs = __importStar(require("fs"));
40
- const core_1 = require("./core");
40
+ const http = __importStar(require("http"));
41
+ const projax_core_1 = require("projax-core");
41
42
  const script_runner_1 = require("./script-runner");
42
43
  const port_scanner_1 = require("./port-scanner");
43
44
  // Read version from package.json
44
45
  const packageJson = require('../package.json');
45
- // ASCII logo for projax
46
+ // Function to check API status
47
+ async function checkAPIStatus() {
48
+ const dataDir = path.join(require('os').homedir(), '.projax');
49
+ const portFile = path.join(dataDir, 'api-port.txt');
50
+ let port = null;
51
+ if (fs.existsSync(portFile)) {
52
+ try {
53
+ const portStr = fs.readFileSync(portFile, 'utf-8').trim();
54
+ port = parseInt(portStr, 10) || null;
55
+ }
56
+ catch {
57
+ // Ignore
58
+ }
59
+ }
60
+ if (!port) {
61
+ // Try common ports
62
+ const ports = [3001, 3002, 3003, 3004, 3005];
63
+ for (const p of ports) {
64
+ try {
65
+ const result = await new Promise((resolve) => {
66
+ const req = http.get(`http://localhost:${p}/health`, (res) => {
67
+ resolve(res.statusCode === 200);
68
+ });
69
+ req.on('error', () => resolve(false));
70
+ req.setTimeout(500, () => {
71
+ req.destroy();
72
+ resolve(false);
73
+ });
74
+ });
75
+ if (result) {
76
+ port = p;
77
+ break;
78
+ }
79
+ }
80
+ catch {
81
+ // Continue
82
+ }
83
+ }
84
+ }
85
+ if (port) {
86
+ try {
87
+ const result = await new Promise((resolve) => {
88
+ const req = http.get(`http://localhost:${port}/health`, (res) => {
89
+ resolve(res.statusCode === 200);
90
+ });
91
+ req.on('error', () => resolve(false));
92
+ req.setTimeout(500, () => {
93
+ req.destroy();
94
+ resolve(false);
95
+ });
96
+ });
97
+ return { running: result, port };
98
+ }
99
+ catch {
100
+ return { running: false, port };
101
+ }
102
+ }
103
+ return { running: false, port: null };
104
+ }
105
+ // Function to start the API server
106
+ async function startAPIServer(silent = false) {
107
+ const { spawn } = require('child_process');
108
+ const apiPath = path.join(__dirname, '..', '..', 'api', 'dist', 'index.js');
109
+ if (!fs.existsSync(apiPath)) {
110
+ if (!silent) {
111
+ console.error('Error: API server not found. Please build it first: npm run build --workspace=packages/api');
112
+ }
113
+ return false;
114
+ }
115
+ if (!silent) {
116
+ console.log('Starting API server...');
117
+ }
118
+ try {
119
+ spawn('node', [apiPath], {
120
+ detached: true,
121
+ stdio: 'ignore',
122
+ }).unref();
123
+ if (!silent) {
124
+ console.log('✓ API server started');
125
+ }
126
+ return true;
127
+ }
128
+ catch (error) {
129
+ if (!silent) {
130
+ console.error('Error starting API server:', error instanceof Error ? error.message : error);
131
+ }
132
+ return false;
133
+ }
134
+ }
135
+ // Function to ensure API server is running (auto-start if needed)
136
+ async function ensureAPIServerRunning(silent = true) {
137
+ const apiStatus = await checkAPIStatus();
138
+ if (apiStatus.running) {
139
+ // API is already running, nothing to do
140
+ return;
141
+ }
142
+ // API is not running, start it
143
+ if (!silent) {
144
+ console.log('Starting API server...');
145
+ }
146
+ const started = await startAPIServer(silent);
147
+ if (!started) {
148
+ // Failed to start, but don't throw - let the command continue
149
+ // The error message was already shown if not silent
150
+ return;
151
+ }
152
+ // Wait a bit for the API server to start up
153
+ await new Promise(resolve => setTimeout(resolve, 1000));
154
+ // Verify it's running
155
+ const verifyStatus = await checkAPIStatus();
156
+ if (!verifyStatus.running && !silent) {
157
+ console.warn('⚠️ API server may not have started successfully. Check logs if needed.');
158
+ }
159
+ }
160
+ // ASCII logo for projax - using a clearer style that shows all 6 letters
46
161
  function displayLogo() {
47
162
  return `
48
- ╔═══════════════════════════════════════╗
49
- ║ ║
50
- ║ ██████╗ ██████╗ ██████╗ ██╗ ║
51
- ██╔══██╗██╔══██╗██╔═══██╗ ██║ ║
52
- ║ ██████╔╝██████╔╝██║ ██║ ██║ ║
53
- ██╔═══╝ ██╔══██╗██║ ██║██ ██║
54
- ██║ ██║ ██║╚██████╔╝╚█████╔╝
55
- ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚════╝
56
-
57
- Project Management CLI
58
-
59
- ╚═══════════════════════════════════════╝
163
+ PROJAX ${packageJson.version}
164
+
165
+ `;
166
+ return `
167
+ ╔═══════════════════════════════════════════════════════╗
168
+
169
+ ██████╗ ██████╗ ██████╗ ██╗ ██╗ █████╗ ██╗
170
+ ██╔══██╗██╔══██╗██╔═══██╗ ██║ ██║██╔══██╗╚██╗
171
+ ██████╔╝██████╔╝██║ ██║ ███████║╚█████╔╝ ╚██║
172
+ ██╔═══╝ ██╔══██╗██║ ██║██ ██╔══██║██╔══██╗ ██║
173
+ ██║ ██║ ██║╚██████╔╝╚█████╔╝██║╚█████╔╝ ██║
174
+ ║ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚════╝ ╚═╝ ╚════╝ ╚═╝ ║
175
+ ║ ║
176
+ ║ Version ${packageJson.version} ║
177
+ ║ ║
178
+ ║ Use "prx api" to check API server status ║
179
+ ║ ║
180
+ ╚═══════════════════════════════════════════════════════╝
60
181
  `;
61
182
  }
62
183
  const program = new commander_1.Command();
@@ -107,7 +228,7 @@ program
107
228
  console.error(`Error: Path is not a directory: ${resolvedPath}`);
108
229
  process.exit(1);
109
230
  }
110
- const db = (0, core_1.getDatabaseManager)();
231
+ const db = (0, projax_core_1.getDatabaseManager)();
111
232
  const existingProject = db.getProjectByPath(resolvedPath);
112
233
  if (existingProject) {
113
234
  console.log(`Project already exists: ${existingProject.name} (ID: ${existingProject.id})`);
@@ -152,7 +273,7 @@ program
152
273
  ]);
153
274
  if (scanAnswer.scan) {
154
275
  console.log('Scanning for tests...');
155
- const result = (0, core_1.scanProject)(project.id);
276
+ const result = (0, projax_core_1.scanProject)(project.id);
156
277
  console.log(`✓ Found ${result.testsFound} test file(s)`);
157
278
  if (result.tests.length > 0) {
158
279
  console.log(' Test files:');
@@ -193,8 +314,8 @@ program
193
314
  .option('--ports', 'Show detailed port information per script')
194
315
  .action(async (options) => {
195
316
  try {
196
- const db = (0, core_1.getDatabaseManager)();
197
- const projects = (0, core_1.getAllProjects)();
317
+ const db = (0, projax_core_1.getDatabaseManager)();
318
+ const projects = (0, projax_core_1.getAllProjects)();
198
319
  if (projects.length === 0) {
199
320
  console.log('No projects tracked yet. Use "prx add" to add a project.');
200
321
  return;
@@ -301,17 +422,17 @@ program
301
422
  .argument('[project]', 'Project ID or name to scan (leave empty to scan all)')
302
423
  .action(async (projectIdentifier) => {
303
424
  try {
304
- const db = (0, core_1.getDatabaseManager)();
425
+ const db = (0, projax_core_1.getDatabaseManager)();
305
426
  if (projectIdentifier) {
306
427
  // Find project by ID or name
307
- const projects = (0, core_1.getAllProjects)();
428
+ const projects = (0, projax_core_1.getAllProjects)();
308
429
  const project = projects.find((p) => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
309
430
  if (!project) {
310
431
  console.error(`Error: Project not found: ${projectIdentifier}`);
311
432
  process.exit(1);
312
433
  }
313
434
  console.log(`Scanning project: ${project.name}...`);
314
- const result = (0, core_1.scanProject)(project.id);
435
+ const result = (0, projax_core_1.scanProject)(project.id);
315
436
  console.log(`✓ Found ${result.testsFound} test file(s)`);
316
437
  if (result.tests.length > 0) {
317
438
  console.log('\nTest files:');
@@ -340,7 +461,7 @@ program
340
461
  else {
341
462
  // Scan all projects
342
463
  console.log('Scanning all projects...\n');
343
- const results = (0, core_1.scanAllProjects)();
464
+ const results = (0, projax_core_1.scanAllProjects)();
344
465
  for (const result of results) {
345
466
  console.log(`${result.project.name}: ${result.testsFound} test file(s)`);
346
467
  }
@@ -372,8 +493,8 @@ program
372
493
  .argument('<newName>', 'New name for the project')
373
494
  .action((projectIdentifier, newName) => {
374
495
  try {
375
- const db = (0, core_1.getDatabaseManager)();
376
- const projects = (0, core_1.getAllProjects)();
496
+ const db = (0, projax_core_1.getDatabaseManager)();
497
+ const projects = (0, projax_core_1.getAllProjects)();
377
498
  const project = projects.find(p => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
378
499
  if (!project) {
379
500
  console.error(`Error: Project not found: ${projectIdentifier}`);
@@ -400,8 +521,8 @@ program
400
521
  .option('-f, --force', 'Skip confirmation')
401
522
  .action(async (projectIdentifier, options) => {
402
523
  try {
403
- const db = (0, core_1.getDatabaseManager)();
404
- const projects = (0, core_1.getAllProjects)();
524
+ const db = (0, projax_core_1.getDatabaseManager)();
525
+ const projects = (0, projax_core_1.getAllProjects)();
405
526
  const project = projects.find(p => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
406
527
  if (!project) {
407
528
  console.error(`Error: Project not found: ${projectIdentifier}`);
@@ -422,7 +543,7 @@ program
422
543
  return;
423
544
  }
424
545
  }
425
- (0, core_1.removeProject)(project.id);
546
+ (0, projax_core_1.removeProject)(project.id);
426
547
  console.log(`✓ Removed project: ${project.name}`);
427
548
  }
428
549
  catch (error) {
@@ -437,7 +558,7 @@ program
437
558
  .argument('[project]', 'Project ID or name (leave empty for interactive selection)')
438
559
  .action(async (projectIdentifier) => {
439
560
  try {
440
- const projects = (0, core_1.getAllProjects)();
561
+ const projects = (0, projax_core_1.getAllProjects)();
441
562
  if (projects.length === 0) {
442
563
  console.error('Error: No projects tracked yet. Use "prx add" to add a project.');
443
564
  process.exit(1);
@@ -501,7 +622,7 @@ program
501
622
  .argument('[project]', 'Project ID or name (leave empty for interactive selection)')
502
623
  .action(async (projectIdentifier) => {
503
624
  try {
504
- const projects = (0, core_1.getAllProjects)();
625
+ const projects = (0, projax_core_1.getAllProjects)();
505
626
  if (projects.length === 0) {
506
627
  console.error('Error: No projects tracked yet. Use "prx add" to add a project.');
507
628
  process.exit(1);
@@ -551,7 +672,7 @@ program
551
672
  .argument('[project]', 'Project ID or name (leave empty for interactive selection)')
552
673
  .action(async (projectIdentifier) => {
553
674
  try {
554
- const projects = (0, core_1.getAllProjects)();
675
+ const projects = (0, projax_core_1.getAllProjects)();
555
676
  if (projects.length === 0) {
556
677
  console.error('Error: No projects tracked yet. Use "prx add" to add a project.');
557
678
  process.exit(1);
@@ -596,55 +717,57 @@ program
596
717
  process.exit(1);
597
718
  }
598
719
  });
599
- // Start Electron UI command
720
+ // Start Desktop UI command
600
721
  program
601
722
  .command('web')
602
- .description('Start the Electron web interface')
723
+ .description('Start the Desktop web interface')
603
724
  .option('--dev', 'Start in development mode (with hot reload)')
604
725
  .action(async (options) => {
605
726
  try {
606
- // Check for bundled Electron app first (in dist/electron when installed globally)
607
- // Then check for local development (packages/cli/dist -> packages/electron)
608
- const bundledElectronPath = path.join(__dirname, 'electron');
609
- const bundledElectronMain = path.join(bundledElectronPath, 'main.js');
610
- const localElectronPath = path.join(__dirname, '..', '..', 'electron');
611
- const localElectronMain = path.join(localElectronPath, 'dist', 'main.js');
612
- // Check if bundled electron exists (global install)
613
- const hasBundledElectron = fs.existsSync(bundledElectronMain);
614
- // Check if local electron exists (development mode)
615
- const isLocalDev = fs.existsSync(localElectronPath) && fs.existsSync(path.join(localElectronPath, 'package.json'));
616
- let electronPackagePath;
617
- let electronMainPath;
618
- if (hasBundledElectron) {
619
- // Bundled Electron app (global install)
620
- electronPackagePath = bundledElectronPath;
621
- electronMainPath = bundledElectronMain;
727
+ // Ensure API server is running before starting Desktop app
728
+ await ensureAPIServerRunning(false);
729
+ // Check for bundled Desktop app first (in dist/desktop when installed globally)
730
+ // Then check for local development (packages/cli/dist -> packages/desktop)
731
+ const bundledDesktopPath = path.join(__dirname, 'desktop');
732
+ const bundledDesktopMain = path.join(bundledDesktopPath, 'main.js');
733
+ const localDesktopPath = path.join(__dirname, '..', '..', 'desktop');
734
+ const localDesktopMain = path.join(localDesktopPath, 'dist', 'main.js');
735
+ // Check if bundled desktop exists (global install)
736
+ const hasBundledDesktop = fs.existsSync(bundledDesktopMain);
737
+ // Check if local desktop exists (development mode)
738
+ const isLocalDev = fs.existsSync(localDesktopPath) && fs.existsSync(path.join(localDesktopPath, 'package.json'));
739
+ let desktopPackagePath;
740
+ let desktopMainPath;
741
+ if (hasBundledDesktop) {
742
+ // Bundled Desktop app (global install)
743
+ desktopPackagePath = bundledDesktopPath;
744
+ desktopMainPath = bundledDesktopMain;
622
745
  }
623
746
  else if (isLocalDev) {
624
747
  // Local development - use relative path
625
- electronPackagePath = localElectronPath;
626
- electronMainPath = localElectronMain;
748
+ desktopPackagePath = localDesktopPath;
749
+ desktopMainPath = localDesktopMain;
627
750
  }
628
751
  else {
629
- console.error('Error: Electron app not found.');
630
- console.error('\nThe Electron web interface is not available.');
752
+ console.error('Error: Desktop app not found.');
753
+ console.error('\nThe Desktop web interface is not available.');
631
754
  console.error('This may be a packaging issue. Please report this error.');
632
755
  process.exit(1);
633
756
  }
634
757
  if (options.dev) {
635
- // Development mode - start Vite dev server and Electron
758
+ // Development mode - start Vite dev server and Desktop app
636
759
  if (!isLocalDev) {
637
760
  console.error('Error: Development mode is only available in local development.');
638
- console.error('The Electron app must be built for production use.');
761
+ console.error('The Desktop app must be built for production use.');
639
762
  process.exit(1);
640
763
  }
641
- console.log('Starting Electron app in development mode...');
764
+ console.log('Starting Desktop app in development mode...');
642
765
  console.log('Starting Vite dev server on port 7898...');
643
766
  const { spawn } = require('child_process');
644
767
  const electron = require('electron');
645
768
  // Start Vite dev server in background
646
769
  const viteProcess = spawn('npm', ['run', 'dev:renderer'], {
647
- cwd: electronPackagePath,
770
+ cwd: desktopPackagePath,
648
771
  stdio: 'pipe',
649
772
  detached: false,
650
773
  });
@@ -654,8 +777,8 @@ program
654
777
  // Wait for Vite to be ready
655
778
  if (output.includes('Local:') || output.includes('ready')) {
656
779
  setTimeout(() => {
657
- console.log('\nStarting Electron window...');
658
- spawn(electron, [electronMainPath], {
780
+ console.log('\nStarting Desktop window...');
781
+ spawn(electron, [desktopMainPath], {
659
782
  stdio: 'inherit',
660
783
  detached: true,
661
784
  env: { ...process.env, NODE_ENV: 'development' },
@@ -674,44 +797,44 @@ program
674
797
  return;
675
798
  }
676
799
  // Production mode - check if built
677
- if (!fs.existsSync(electronMainPath)) {
800
+ if (!fs.existsSync(desktopMainPath)) {
678
801
  if (!isLocalDev) {
679
- console.error('Error: Electron app is not built.');
680
- console.error('The @projax/electron package needs to be built.');
802
+ console.error('Error: Desktop app is not built.');
803
+ console.error('The @projax/desktop package needs to be built.');
681
804
  console.error('Please contact the package maintainer or build it locally.');
682
805
  process.exit(1);
683
806
  }
684
- console.log('Electron app not built.');
685
- console.log('Building Electron app...');
807
+ console.log('Desktop app not built.');
808
+ console.log('Building Desktop app...');
686
809
  const { execSync } = require('child_process');
687
810
  try {
688
- // When in local dev, electronPackagePath points to packages/electron
811
+ // When in local dev, desktopPackagePath points to packages/desktop
689
812
  // So go up two levels to get to project root
690
- const projectRoot = path.join(electronPackagePath, '..', '..');
691
- execSync('npm run build:electron', {
813
+ const projectRoot = path.join(desktopPackagePath, '..', '..');
814
+ execSync('npm run build:desktop', {
692
815
  cwd: projectRoot,
693
816
  stdio: 'inherit'
694
817
  });
695
818
  }
696
819
  catch (error) {
697
820
  console.error('\nBuild failed. Try running in dev mode: prx web --dev');
698
- console.error('Or manually build: npm run build:electron');
821
+ console.error('Or manually build: npm run build:desktop');
699
822
  process.exit(1);
700
823
  }
701
824
  }
702
825
  // Check if renderer is built
703
826
  let rendererIndex;
704
- if (hasBundledElectron) {
705
- // Bundled: renderer is in dist/electron/renderer
706
- rendererIndex = path.join(electronPackagePath, 'renderer', 'index.html');
827
+ if (hasBundledDesktop) {
828
+ // Bundled: renderer is in dist/desktop/renderer
829
+ rendererIndex = path.join(desktopPackagePath, 'renderer', 'index.html');
707
830
  }
708
831
  else {
709
832
  // Local dev: renderer is in dist/renderer
710
- rendererIndex = path.join(electronPackagePath, 'dist', 'renderer', 'index.html');
833
+ rendererIndex = path.join(desktopPackagePath, 'dist', 'renderer', 'index.html');
711
834
  }
712
835
  if (!fs.existsSync(rendererIndex)) {
713
- if (hasBundledElectron) {
714
- console.error('Error: Renderer files not found in bundled Electron app.');
836
+ if (hasBundledDesktop) {
837
+ console.error('Error: Renderer files not found in bundled Desktop app.');
715
838
  console.error('This is a packaging issue. Please report this error.');
716
839
  process.exit(1);
717
840
  }
@@ -724,9 +847,9 @@ program
724
847
  // Ensure NODE_ENV is not set to development when using bundled files
725
848
  process.env.NODE_ENV = 'production';
726
849
  }
727
- // Automatically rebuild better-sqlite3 for Electron if needed
850
+ // Automatically rebuild better-sqlite3 for Desktop/Electron if needed
728
851
  // This ensures it's compiled for Electron's Node.js version
729
- if (hasBundledElectron) {
852
+ if (hasBundledDesktop) {
730
853
  try {
731
854
  const electronPkg = require('electron/package.json');
732
855
  let rebuild;
@@ -746,7 +869,7 @@ program
746
869
  const nodeModulesDir = path.dirname(betterSqlite3Dir); // .../node_modules
747
870
  // The package root is the directory containing node_modules (i.e., projax package root)
748
871
  const packageRoot = path.dirname(nodeModulesDir); // .../projax
749
- console.log('Ensuring better-sqlite3 is built for Electron...');
872
+ console.log('Ensuring better-sqlite3 is built for Desktop/Electron...');
750
873
  try {
751
874
  await new Promise((resolve, reject) => {
752
875
  rebuild({
@@ -756,7 +879,7 @@ program
756
879
  force: true,
757
880
  })
758
881
  .then(() => {
759
- console.log('✓ better-sqlite3 ready for Electron');
882
+ console.log('✓ better-sqlite3 ready for Desktop/Electron');
760
883
  resolve();
761
884
  })
762
885
  .catch((err) => {
@@ -776,24 +899,66 @@ program
776
899
  }
777
900
  }
778
901
  catch (checkError) {
779
- // If we can't check, just continue - the error will show when Electron tries to use it
902
+ // If we can't check, just continue - the error will show when Desktop app tries to use it
780
903
  }
781
904
  }
782
- console.log('Starting Electron app...');
905
+ console.log('Starting Desktop app...');
783
906
  const { spawn } = require('child_process');
784
907
  const electron = require('electron');
785
- spawn(electron, [electronMainPath], {
908
+ spawn(electron, [desktopMainPath], {
786
909
  stdio: 'inherit',
787
910
  detached: true,
788
911
  env: { ...process.env },
789
912
  }).unref();
790
913
  }
791
914
  catch (error) {
792
- console.error('Error starting Electron app:', error instanceof Error ? error.message : error);
915
+ console.error('Error starting Desktop app:', error instanceof Error ? error.message : error);
793
916
  console.log('\nTroubleshooting:');
794
917
  console.log('1. Try dev mode: prx web --dev');
795
- console.log('2. Or build manually: npm run build:electron');
796
- console.log('3. Or run dev server: cd packages/electron && npm run dev');
918
+ console.log('2. Or build manually: npm run build:desktop');
919
+ console.log('3. Or run dev server: cd packages/desktop && npm run dev');
920
+ process.exit(1);
921
+ }
922
+ });
923
+ // API command - show API info and manage API server
924
+ program
925
+ .command('api')
926
+ .description('Show API server information and status')
927
+ .option('-s, --start', 'Start the API server')
928
+ .option('-k, --kill', 'Stop the API server')
929
+ .action(async (options) => {
930
+ try {
931
+ const apiStatus = await checkAPIStatus();
932
+ if (options.start) {
933
+ const started = await startAPIServer(false);
934
+ if (!started) {
935
+ process.exit(1);
936
+ }
937
+ return;
938
+ }
939
+ if (options.kill) {
940
+ console.log('Stopping API server...');
941
+ // This would require process management - for now just inform user
942
+ console.log('Note: API server process management not yet implemented.');
943
+ console.log('Please stop the API server manually if needed.');
944
+ return;
945
+ }
946
+ // Show status
947
+ console.log('\nAPI Server Status:');
948
+ console.log(` Running: ${apiStatus.running ? 'Yes' : 'No'}`);
949
+ if (apiStatus.port) {
950
+ console.log(` Port: ${apiStatus.port}`);
951
+ console.log(` URL: http://localhost:${apiStatus.port}`);
952
+ console.log(` Health: http://localhost:${apiStatus.port}/health`);
953
+ console.log(` API Base: http://localhost:${apiStatus.port}/api`);
954
+ }
955
+ else {
956
+ console.log(' Port: Not detected');
957
+ }
958
+ console.log('');
959
+ }
960
+ catch (error) {
961
+ console.error('Error checking API status:', error instanceof Error ? error.message : error);
797
962
  process.exit(1);
798
963
  }
799
964
  });
@@ -805,9 +970,9 @@ program
805
970
  .action(async (projectIdentifier) => {
806
971
  try {
807
972
  const { scanProjectPorts, scanAllProjectPorts } = await Promise.resolve().then(() => __importStar(require('./port-scanner')));
808
- const db = (0, core_1.getDatabaseManager)();
973
+ const db = (0, projax_core_1.getDatabaseManager)();
809
974
  if (projectIdentifier) {
810
- const projects = (0, core_1.getAllProjects)();
975
+ const projects = (0, projax_core_1.getAllProjects)();
811
976
  const project = projects.find((p) => p.id.toString() === projectIdentifier || p.name === projectIdentifier);
812
977
  if (!project) {
813
978
  console.error(`Error: Project not found: ${projectIdentifier}`);
@@ -830,7 +995,7 @@ program
830
995
  else {
831
996
  console.log('Scanning ports for all projects...\n');
832
997
  await scanAllProjectPorts();
833
- const projects = (0, core_1.getAllProjects)();
998
+ const projects = (0, projax_core_1.getAllProjects)();
834
999
  for (const project of projects) {
835
1000
  const ports = db.getProjectPorts(project.id);
836
1001
  if (ports.length > 0) {
@@ -850,14 +1015,14 @@ program
850
1015
  // Check if first argument is not a known command
851
1016
  (async () => {
852
1017
  const args = process.argv.slice(2);
853
- const knownCommands = ['add', 'list', 'scan', 'remove', 'rn', 'rename', 'cd', 'pwd', 'web', 'scripts', 'scan-ports', '--help', '-h', '--version', '-V'];
1018
+ const knownCommands = ['add', 'list', 'scan', 'remove', 'rn', 'rename', 'cd', 'pwd', 'web', 'scripts', 'scan-ports', 'api', '--help', '-h', '--version', '-V'];
854
1019
  // If we have at least 1 argument and first is not a known command, treat as project identifier
855
1020
  if (args.length >= 1 && !knownCommands.includes(args[0])) {
856
1021
  const projectIdentifier = args[0];
857
1022
  // Check if it's actually a project (not a flag)
858
1023
  if (!projectIdentifier.startsWith('-')) {
859
1024
  try {
860
- const projects = (0, core_1.getAllProjects)();
1025
+ const projects = (0, projax_core_1.getAllProjects)();
861
1026
  // Try to find project by ID (if identifier is numeric) or by name
862
1027
  let project;
863
1028
  const numericId = parseInt(projectIdentifier, 10);
@@ -36,14 +36,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.scanProjectPorts = scanProjectPorts;
37
37
  exports.scanAllProjectPorts = scanAllProjectPorts;
38
38
  exports.shouldRescanPorts = shouldRescanPorts;
39
- const core_1 = require("./core");
39
+ const projax_core_1 = require("projax-core");
40
40
  const port_extractor_1 = require("./port-extractor");
41
41
  const fs = __importStar(require("fs"));
42
42
  /**
43
43
  * Scan and index ports for a specific project
44
44
  */
45
45
  async function scanProjectPorts(projectId) {
46
- const db = (0, core_1.getDatabaseManager)();
46
+ const db = (0, projax_core_1.getDatabaseManager)();
47
47
  const project = db.getProject(projectId);
48
48
  if (!project) {
49
49
  throw new Error(`Project with id ${projectId} not found`);
@@ -64,7 +64,7 @@ async function scanProjectPorts(projectId) {
64
64
  * Scan ports for all projects
65
65
  */
66
66
  async function scanAllProjectPorts() {
67
- const db = (0, core_1.getDatabaseManager)();
67
+ const db = (0, projax_core_1.getDatabaseManager)();
68
68
  const projects = db.getAllProjects();
69
69
  for (const project of projects) {
70
70
  try {
@@ -81,7 +81,7 @@ async function scanAllProjectPorts() {
81
81
  * Returns true if ports haven't been scanned in the last 24 hours
82
82
  */
83
83
  function shouldRescanPorts(projectId) {
84
- const db = (0, core_1.getDatabaseManager)();
84
+ const db = (0, projax_core_1.getDatabaseManager)();
85
85
  const ports = db.getProjectPorts(projectId);
86
86
  if (ports.length === 0) {
87
87
  return true; // No ports found, should scan
@@ -48,7 +48,7 @@ const fs = __importStar(require("fs"));
48
48
  const path = __importStar(require("path"));
49
49
  const os = __importStar(require("os"));
50
50
  const child_process_1 = require("child_process");
51
- const core_1 = require("./core");
51
+ const projax_core_1 = require("projax-core");
52
52
  const port_utils_1 = require("./port-utils");
53
53
  /**
54
54
  * Detect the project type based on files in the directory
@@ -324,7 +324,7 @@ async function handlePortConflict(port, projectName, force) {
324
324
  * Check ports proactively before script execution
325
325
  */
326
326
  async function checkPortsBeforeExecution(projectPath, scriptName, force) {
327
- const db = (0, core_1.getDatabaseManager)();
327
+ const db = (0, projax_core_1.getDatabaseManager)();
328
328
  const project = db.getProjectByPath(projectPath);
329
329
  if (!project)
330
330
  return true; // Can't check if project not in DB
@@ -447,7 +447,7 @@ function runScript(projectPath, scriptName, args = [], force = false) {
447
447
  const errorOutput = stderrOutput + stdoutOutput;
448
448
  const port = (0, port_utils_1.extractPortFromError)(errorOutput);
449
449
  if (port) {
450
- const db = (0, core_1.getDatabaseManager)();
450
+ const db = (0, projax_core_1.getDatabaseManager)();
451
451
  const project = db.getProjectByPath(projectPath);
452
452
  const projectName = project?.name || 'project';
453
453
  const resolved = await handlePortConflict(port, projectName, force);
@@ -801,7 +801,7 @@ function runScriptInBackground(projectPath, projectName, scriptName, args = [],
801
801
  // Also check for URLs from detected ports
802
802
  setTimeout(async () => {
803
803
  try {
804
- const db = (0, core_1.getDatabaseManager)();
804
+ const db = (0, projax_core_1.getDatabaseManager)();
805
805
  const project = db.getProjectByPath(projectPath);
806
806
  if (project) {
807
807
  const ports = db.getProjectPorts(project.id);