projax 3.3.58 → 3.3.63

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 (84) hide show
  1. package/README.md +10 -1
  2. package/dist/electron/preload.d.ts +1 -0
  3. package/dist/electron/renderer/assets/index-CmtZriN5.js +66 -0
  4. package/dist/electron/renderer/index.html +1 -1
  5. package/dist/electron/script-runner.js +52 -20
  6. package/dist/index.js +14 -10
  7. package/dist/prxi.js +877 -109
  8. package/dist/prxi.tsx +1249 -177
  9. package/dist/script-runner.js +52 -20
  10. package/package.json +1 -1
  11. package/coverage/base.css +0 -224
  12. package/coverage/block-navigation.js +0 -87
  13. package/coverage/core-bridge.ts.html +0 -292
  14. package/coverage/favicon.png +0 -0
  15. package/coverage/index.html +0 -191
  16. package/coverage/lcov-report/base.css +0 -224
  17. package/coverage/lcov-report/block-navigation.js +0 -87
  18. package/coverage/lcov-report/core-bridge.ts.html +0 -292
  19. package/coverage/lcov-report/favicon.png +0 -0
  20. package/coverage/lcov-report/index.html +0 -191
  21. package/coverage/lcov-report/port-extractor.ts.html +0 -1174
  22. package/coverage/lcov-report/port-scanner.ts.html +0 -301
  23. package/coverage/lcov-report/port-utils.ts.html +0 -670
  24. package/coverage/lcov-report/prettify.css +0 -1
  25. package/coverage/lcov-report/prettify.js +0 -2
  26. package/coverage/lcov-report/script-runner.ts.html +0 -3346
  27. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  28. package/coverage/lcov-report/sorter.js +0 -210
  29. package/coverage/lcov-report/test-parser.ts.html +0 -799
  30. package/coverage/lcov.info +0 -1338
  31. package/coverage/port-extractor.ts.html +0 -1174
  32. package/coverage/port-scanner.ts.html +0 -301
  33. package/coverage/port-utils.ts.html +0 -670
  34. package/coverage/prettify.css +0 -1
  35. package/coverage/prettify.js +0 -2
  36. package/coverage/script-runner.ts.html +0 -3346
  37. package/coverage/sort-arrow-sprite.png +0 -0
  38. package/coverage/sorter.js +0 -210
  39. package/coverage/test-parser.ts.html +0 -799
  40. package/dist/__tests__/core-bridge.test.d.ts +0 -1
  41. package/dist/__tests__/core-bridge.test.js +0 -135
  42. package/dist/__tests__/port-extractor.test.d.ts +0 -1
  43. package/dist/__tests__/port-extractor.test.js +0 -407
  44. package/dist/__tests__/port-scanner.test.d.ts +0 -1
  45. package/dist/__tests__/port-scanner.test.js +0 -170
  46. package/dist/__tests__/port-utils.test.d.ts +0 -1
  47. package/dist/__tests__/port-utils.test.js +0 -127
  48. package/dist/__tests__/script-runner.test.d.ts +0 -1
  49. package/dist/__tests__/script-runner.test.js +0 -491
  50. package/dist/__tests__/test-parser.test.d.ts +0 -1
  51. package/dist/__tests__/test-parser.test.js +0 -276
  52. package/dist/api/__tests__/database.test.d.ts +0 -2
  53. package/dist/api/__tests__/database.test.d.ts.map +0 -1
  54. package/dist/api/__tests__/database.test.js +0 -485
  55. package/dist/api/__tests__/database.test.js.map +0 -1
  56. package/dist/api/__tests__/routes.test.d.ts +0 -2
  57. package/dist/api/__tests__/routes.test.d.ts.map +0 -1
  58. package/dist/api/__tests__/routes.test.js +0 -484
  59. package/dist/api/__tests__/routes.test.js.map +0 -1
  60. package/dist/api/__tests__/scanner.test.d.ts +0 -2
  61. package/dist/api/__tests__/scanner.test.d.ts.map +0 -1
  62. package/dist/api/__tests__/scanner.test.js +0 -403
  63. package/dist/api/__tests__/scanner.test.js.map +0 -1
  64. package/dist/core/__tests__/database.test.d.ts +0 -1
  65. package/dist/core/__tests__/database.test.js +0 -557
  66. package/dist/core/__tests__/detector.test.d.ts +0 -1
  67. package/dist/core/__tests__/detector.test.js +0 -375
  68. package/dist/core/__tests__/index.test.d.ts +0 -1
  69. package/dist/core/__tests__/index.test.js +0 -469
  70. package/dist/core/__tests__/scanner.test.d.ts +0 -1
  71. package/dist/core/__tests__/scanner.test.js +0 -406
  72. package/dist/core/__tests__/settings.test.d.ts +0 -1
  73. package/dist/core/__tests__/settings.test.js +0 -280
  74. package/dist/electron/core/__tests__/database.test.d.ts +0 -1
  75. package/dist/electron/core/__tests__/database.test.js +0 -557
  76. package/dist/electron/core/__tests__/detector.test.d.ts +0 -1
  77. package/dist/electron/core/__tests__/detector.test.js +0 -375
  78. package/dist/electron/core/__tests__/index.test.d.ts +0 -1
  79. package/dist/electron/core/__tests__/index.test.js +0 -469
  80. package/dist/electron/core/__tests__/scanner.test.d.ts +0 -1
  81. package/dist/electron/core/__tests__/scanner.test.js +0 -406
  82. package/dist/electron/core/__tests__/settings.test.d.ts +0 -1
  83. package/dist/electron/core/__tests__/settings.test.js +0 -280
  84. package/jest.config.js +0 -26
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' http://localhost:* ws://localhost:*;" />
7
7
  <title>projax</title>
8
- <script type="module" crossorigin src="./assets/index-Cj4QON0s.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-CmtZriN5.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="./assets/index-DfocdjIj.css">
10
10
  </head>
11
11
  <body>
@@ -51,6 +51,38 @@ const os = __importStar(require("os"));
51
51
  const child_process_1 = require("child_process");
52
52
  const core_bridge_1 = require("./core-bridge");
53
53
  const port_utils_1 = require("./port-utils");
54
+ /**
55
+ * Safe console logging that handles EPIPE errors gracefully
56
+ * This prevents uncaught exceptions when stdout/stderr are closed
57
+ */
58
+ function safeLog(...args) {
59
+ try {
60
+ console.log(...args);
61
+ }
62
+ catch (error) {
63
+ // Silently ignore EPIPE errors (pipe closed)
64
+ if (error?.code !== 'EPIPE') {
65
+ // For other errors, try to write to stderr as fallback
66
+ try {
67
+ process.stderr.write(`[log] ${args.join(' ')}\n`);
68
+ }
69
+ catch {
70
+ // Give up - output streams are not available
71
+ }
72
+ }
73
+ }
74
+ }
75
+ function safeError(...args) {
76
+ try {
77
+ console.error(...args);
78
+ }
79
+ catch (error) {
80
+ // Silently ignore EPIPE errors
81
+ if (error?.code !== 'EPIPE') {
82
+ // No fallback for stderr errors
83
+ }
84
+ }
85
+ }
54
86
  /**
55
87
  * Detect the project type based on files in the directory
56
88
  */
@@ -278,19 +310,19 @@ function getProjectScripts(projectPath) {
278
310
  async function handlePortConflict(port, projectName, force) {
279
311
  const processInfo = await (0, port_utils_1.getProcessOnPort)(port);
280
312
  if (!processInfo) {
281
- console.error(`Port ${port} appears to be in use, but couldn't identify the process.`);
313
+ safeError(`Port ${port} appears to be in use, but couldn't identify the process.`);
282
314
  return false;
283
315
  }
284
- console.error(`\n⚠️ Port ${port} is already in use by process ${processInfo.pid} (${processInfo.command})`);
316
+ safeError(`\n⚠️ Port ${port} is already in use by process ${processInfo.pid} (${processInfo.command})`);
285
317
  if (force) {
286
- console.log(`Killing process ${processInfo.pid} on port ${port}...`);
318
+ safeLog(`Killing process ${processInfo.pid} on port ${port}...`);
287
319
  const killed = await (0, port_utils_1.killProcessOnPort)(port);
288
320
  if (killed) {
289
- console.log(`✓ Process killed. Retrying...\n`);
321
+ safeLog(`✓ Process killed. Retrying...\n`);
290
322
  return true;
291
323
  }
292
324
  else {
293
- console.error(`Failed to kill process on port ${port}`);
325
+ safeError(`Failed to kill process on port ${port}`);
294
326
  return false;
295
327
  }
296
328
  }
@@ -307,16 +339,16 @@ async function handlePortConflict(port, projectName, force) {
307
339
  if (answer.kill) {
308
340
  const killed = await (0, port_utils_1.killProcessOnPort)(port);
309
341
  if (killed) {
310
- console.log(`✓ Process killed. Retrying...\n`);
342
+ safeLog(`✓ Process killed. Retrying...\n`);
311
343
  return true;
312
344
  }
313
345
  else {
314
- console.error(`Failed to kill process on port ${port}`);
346
+ safeError(`Failed to kill process on port ${port}`);
315
347
  return false;
316
348
  }
317
349
  }
318
350
  else {
319
- console.log('Cancelled.');
351
+ safeLog('Cancelled.');
320
352
  return false;
321
353
  }
322
354
  }
@@ -416,8 +448,8 @@ function runScript(projectPath, scriptName, args = [], force = false) {
416
448
  commandArgs = [...parts.slice(1), ...args];
417
449
  break;
418
450
  }
419
- console.log(`Running: ${command} ${commandArgs.join(' ')}`);
420
- console.log(`In directory: ${projectPath}\n`);
451
+ safeLog(`Running: ${command} ${commandArgs.join(' ')}`);
452
+ safeLog(`In directory: ${projectPath}\n`);
421
453
  // Capture stderr for reactive port conflict detection
422
454
  let stderrOutput = '';
423
455
  let stdoutOutput = '';
@@ -681,7 +713,7 @@ async function stopScript(pid) {
681
713
  }
682
714
  catch (error) {
683
715
  // Process may have already exited
684
- console.error(`Error killing process ${pid}:`, error);
716
+ safeError(`Error killing process ${pid}:`, error);
685
717
  }
686
718
  }
687
719
  // Remove from tracking regardless of whether kill succeeded
@@ -689,7 +721,7 @@ async function stopScript(pid) {
689
721
  return true;
690
722
  }
691
723
  catch (error) {
692
- console.error(`Error stopping script ${pid}:`, error);
724
+ safeError(`Error stopping script ${pid}:`, error);
693
725
  return false;
694
726
  }
695
727
  }
@@ -869,9 +901,9 @@ function runScriptInBackground(projectPath, projectName, scriptName, args = [],
869
901
  // Unref so parent can exit and process runs independently
870
902
  child.unref();
871
903
  // Show minimal output
872
- console.log(`✓ Started "${projectName}" (${scriptName}) in background [PID: ${child.pid}]`);
873
- console.log(` Logs: ${logFile}`);
874
- console.log(` Command: ${command} ${commandArgs.join(' ')}\n`);
904
+ safeLog(`✓ Started "${projectName}" (${scriptName}) in background [PID: ${child.pid}]`);
905
+ safeLog(` Logs: ${logFile}`);
906
+ safeLog(` Command: ${command} ${commandArgs.join(' ')}\n`);
875
907
  // For background processes, we can't easily do reactive detection
876
908
  // But we can check the log file after a short delay for port conflicts and URLs
877
909
  setTimeout(async () => {
@@ -883,9 +915,9 @@ function runScriptInBackground(projectPath, projectName, scriptName, args = [],
883
915
  // Check for port conflicts
884
916
  const port = (0, port_utils_1.extractPortFromError)(logContent);
885
917
  if (port) {
886
- console.error(`\n⚠️ Port conflict detected in background process: port ${port} is in use`);
887
- console.error(` Check log file: ${logFile}`);
888
- console.error(` Use: prx <project> <script> --force to auto-resolve port conflicts\n`);
918
+ safeError(`\n⚠️ Port conflict detected in background process: port ${port} is in use`);
919
+ safeError(` Check log file: ${logFile}`);
920
+ safeError(` Use: prx <project> <script> --force to auto-resolve port conflicts\n`);
889
921
  }
890
922
  // Extract URLs from output
891
923
  const urls = extractUrlsFromOutput(logContent);
@@ -986,10 +1018,10 @@ async function checkAndParseTestResults(logFile, projectPath, scriptName) {
986
1018
  // Save test results to database
987
1019
  db.addTestResult(project.id, scriptName, parsed.passed, parsed.failed, parsed.skipped, parsed.total, parsed.duration, parsed.coverage, parsed.framework, logContent.slice(-5000) // Store last 5000 chars of output
988
1020
  );
989
- console.log(`\n📊 Test results saved: ${parsed.passed} passed, ${parsed.failed} failed, ${parsed.skipped} skipped`);
1021
+ safeLog(`\n📊 Test results saved: ${parsed.passed} passed, ${parsed.failed} failed, ${parsed.skipped} skipped`);
990
1022
  }
991
1023
  catch (error) {
992
1024
  // Silently fail - test parsing is optional
993
- console.error('Error parsing test results:', error);
1025
+ safeError('Error parsing test results:', error);
994
1026
  }
995
1027
  }
package/dist/index.js CHANGED
@@ -433,15 +433,11 @@ function displayLogo() {
433
433
  const program = new commander_1.Command();
434
434
  program
435
435
  .name('prx')
436
- .description('Project management dashboard CLI')
436
+ .description('Project management dashboard - launches interactive TUI by default. Use --help for CLI commands.')
437
437
  .version(packageJson.version)
438
438
  .addHelpText('beforeAll', displayLogo());
439
- // Interactive terminal UI command (hidden - in beta)
440
- program
441
- .command('prxi', { hidden: true }) // Hide from help output while in beta
442
- .alias('i')
443
- .description('Launch interactive terminal UI (beta)')
444
- .action(async () => {
439
+ // Launch the interactive TUI
440
+ async function launchTUI() {
445
441
  try {
446
442
  await ensureAPIServerRunning(true);
447
443
  // Find the prxi source file - use CLI's embedded prxi.tsx
@@ -461,7 +457,7 @@ program
461
457
  path.join(__dirname, '..', '..', '..', 'node_modules', '.bin', 'tsx'), // When running from workspace root
462
458
  'tsx', // Fallback to PATH
463
459
  ];
464
- let tsxBin = tsxPaths.find(p => p === 'tsx' || fs.existsSync(p));
460
+ const tsxBin = tsxPaths.find(p => p === 'tsx' || fs.existsSync(p));
465
461
  if (!tsxBin) {
466
462
  console.error('Error: tsx not found. Please install dependencies: npm install');
467
463
  process.exit(1);
@@ -503,10 +499,16 @@ program
503
499
  }
504
500
  }
505
501
  catch (error) {
506
- console.error('Error launching prxi:', error instanceof Error ? error.message : error);
502
+ console.error('Error launching TUI:', error instanceof Error ? error.message : error);
507
503
  process.exit(1);
508
504
  }
509
- });
505
+ }
506
+ // Interactive terminal UI command (kept for backwards compatibility)
507
+ program
508
+ .command('prxi', { hidden: true })
509
+ .alias('i')
510
+ .description('Launch interactive terminal UI')
511
+ .action(launchTUI);
510
512
  // Add project command
511
513
  program
512
514
  .command('add')
@@ -2275,6 +2277,8 @@ program
2275
2277
  }
2276
2278
  }
2277
2279
  }
2280
+ // Default action: launch TUI when no command is provided
2281
+ program.action(launchTUI);
2278
2282
  // If we get here, proceed with normal command parsing
2279
2283
  // Don't show logo twice - it's already in addHelpText
2280
2284
  program.parse();