@impeccable/detect 2.0.4 → 2.0.5

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.
package/LICENSE CHANGED
@@ -3,7 +3,7 @@ Business Source License 1.1
3
3
  Parameters
4
4
 
5
5
  Licensor: Paul Bakaus
6
- Licensed Work: Impeccable Detect 2.0.2
6
+ Licensed Work: Impeccable Detect 2.0.4
7
7
  The Licensed Work is (c) 2026 Paul Bakaus.
8
8
  Additional Use Grant: You may make use of the Licensed Work, provided that
9
9
  you do not use the Licensed Work for a Commercial
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impeccable/detect",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "Deterministic UI anti-pattern detector for design quality analysis",
5
5
  "author": "Paul Bakaus",
6
6
  "license": "BSL-1.1",
@@ -2450,9 +2450,12 @@ async function findOpenPort(start = 8400) {
2450
2450
  });
2451
2451
  }
2452
2452
 
2453
+ const LIVE_PID_FILE = path.join((await import('node:os')).default.tmpdir(), 'impeccable-live.json');
2454
+
2453
2455
  async function liveCli() {
2454
2456
  const args = process.argv.slice(2);
2455
2457
  const helpMode = args.includes('--help');
2458
+ const stopMode = args.includes('stop');
2456
2459
  const portArg = args.find(a => a.startsWith('--port='));
2457
2460
  const requestedPort = portArg ? parseInt(portArg.split('=')[1], 10) : null;
2458
2461
 
@@ -2462,13 +2465,32 @@ async function liveCli() {
2462
2465
  Start a local server that serves the browser detection overlay script.
2463
2466
  Inject the script into any page to scan for anti-patterns in real time.
2464
2467
 
2468
+ Commands:
2469
+ live Start the server (default)
2470
+ live stop Stop a running live server
2471
+
2465
2472
  Options:
2466
2473
  --port=PORT Use a specific port (default: auto-detect unused port)
2467
2474
  --help Show this help message
2468
2475
 
2469
2476
  The server provides:
2470
2477
  /detect.js The detection overlay script (inject via <script> tag)
2471
- /scan Trigger a scan and return JSON results`);
2478
+ /health Health check endpoint
2479
+ /stop Stop the server remotely`);
2480
+ process.exit(0);
2481
+ }
2482
+
2483
+ // Stop a running server
2484
+ if (stopMode) {
2485
+ try {
2486
+ const info = JSON.parse(fs.readFileSync(LIVE_PID_FILE, 'utf-8'));
2487
+ const res = await fetch(`http://localhost:${info.port}/stop`);
2488
+ if (res.ok) {
2489
+ console.log(`Stopped live server on port ${info.port}.`);
2490
+ }
2491
+ } catch {
2492
+ console.log('No running live server found.');
2493
+ }
2472
2494
  process.exit(0);
2473
2495
  }
2474
2496
 
@@ -2485,6 +2507,12 @@ The server provides:
2485
2507
 
2486
2508
  const port = requestedPort || await findOpenPort();
2487
2509
 
2510
+ const shutdown = () => {
2511
+ try { fs.unlinkSync(LIVE_PID_FILE); } catch { /* ignore */ }
2512
+ server.close();
2513
+ process.exit(0);
2514
+ };
2515
+
2488
2516
  const server = http.default.createServer((req, res) => {
2489
2517
  // CORS headers for cross-origin injection
2490
2518
  res.setHeader('Access-Control-Allow-Origin', '*');
@@ -2496,7 +2524,11 @@ The server provides:
2496
2524
  res.end(browserScript);
2497
2525
  } else if (req.url === '/health') {
2498
2526
  res.writeHead(200, { 'Content-Type': 'application/json' });
2499
- res.end(JSON.stringify({ status: 'ok', version: '2.0.2' }));
2527
+ res.end(JSON.stringify({ status: 'ok', port }));
2528
+ } else if (req.url === '/stop') {
2529
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
2530
+ res.end('stopping');
2531
+ shutdown();
2500
2532
  } else {
2501
2533
  res.writeHead(404);
2502
2534
  res.end('Not found');
@@ -2504,20 +2536,20 @@ The server provides:
2504
2536
  });
2505
2537
 
2506
2538
  server.listen(port, '127.0.0.1', () => {
2539
+ // Write PID file so `live stop` can find us
2540
+ fs.writeFileSync(LIVE_PID_FILE, JSON.stringify({ pid: process.pid, port }));
2541
+
2507
2542
  const url = `http://localhost:${port}`;
2508
2543
  console.log(`Impeccable live detection server running on ${url}\n`);
2509
2544
  console.log(`Inject into any page:`);
2510
2545
  console.log(` const s = document.createElement('script');`);
2511
2546
  console.log(` s.src = '${url}/detect.js';`);
2512
2547
  console.log(` document.head.appendChild(s);\n`);
2513
- console.log(`Or add to HTML:`);
2514
- console.log(` <script src="${url}/detect.js"><\/script>\n`);
2515
- console.log(`Press Ctrl+C to stop.`);
2548
+ console.log(`Stop: npx @impeccable/detect live stop`);
2516
2549
  });
2517
2550
 
2518
- // Graceful shutdown
2519
- process.on('SIGINT', () => { server.close(); process.exit(0); });
2520
- process.on('SIGTERM', () => { server.close(); process.exit(0); });
2551
+ process.on('SIGINT', shutdown);
2552
+ process.on('SIGTERM', shutdown);
2521
2553
  }
2522
2554
 
2523
2555
  // ---------------------------------------------------------------------------