autokap 1.4.2 → 1.4.3

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/dist/cli.js +19 -0
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -557,15 +557,31 @@ program
557
557
  .option('--lookback-days <n>', 'How far back to look for launches', '1')
558
558
  .option('--debug', 'Verbose logging', false)
559
559
  .action(async (opts) => {
560
+ // Log immediately on boot — before any other call — so Cloud Run logs
561
+ // show evidence the new command is reachable. If the next line silently
562
+ // crashes (missing dep, bad import) we at least see the boot.
563
+ logger.info(`[crm-run] booted — autokap CLI ${version}`);
560
564
  if (opts.debug) {
561
565
  const { setDebugEnabled } = await import('./logger.js');
562
566
  setDebugEnabled(true);
563
567
  logger.info('[crm-run] Debug mode enabled — verbose logging on');
564
568
  }
569
+ // Self-kill after 20 min so a hung scraper exits before the backend
570
+ // reconcile cron (25 min) gets to it. Ensures the Cloud Run instance
571
+ // doesn't leak and the run row gets force-failed quickly.
572
+ const SELF_TIMEOUT_MS = 20 * 60 * 1000;
573
+ const selfTimeout = setTimeout(() => {
574
+ logger.error(`[crm-run] Self-kill: scraper exceeded ${SELF_TIMEOUT_MS / 60000}min budget — exiting non-zero`);
575
+ process.exit(1);
576
+ }, SELF_TIMEOUT_MS);
577
+ selfTimeout.unref?.();
565
578
  const runToken = process.env.AUTOKAP_RUN_TOKEN?.trim();
566
579
  const runId = opts.runId?.trim() || process.env.AUTOKAP_RUN_ID?.trim();
567
580
  const config = await readConfig();
568
581
  const apiBaseUrl = process.env.AUTOKAP_API_BASE_URL?.trim().replace(/\/+$/, '') || config?.apiBaseUrl;
582
+ logger.info(`[crm-run] env check — runId=${runId ?? '<missing>'} ` +
583
+ `apiBaseUrl=${apiBaseUrl ?? '<missing>'} ` +
584
+ `runToken=${runToken ? `${runToken.slice(0, 12)}…` : '<missing>'}`);
569
585
  if (!runToken) {
570
586
  fatal('[crm-run] Missing AUTOKAP_RUN_TOKEN');
571
587
  }
@@ -577,6 +593,7 @@ program
577
593
  }
578
594
  const parsedLookback = Number.parseInt(opts.lookbackDays, 10);
579
595
  const lookbackDays = Math.max(1, Math.min(7, Number.isFinite(parsedLookback) ? parsedLookback : 1));
596
+ logger.info(`[crm-run] starting campaign — lookbackDays=${lookbackDays}`);
580
597
  try {
581
598
  const { runCampaign } = await import('./crm/run-campaign.js');
582
599
  const result = await runCampaign({
@@ -586,11 +603,13 @@ program
586
603
  runToken,
587
604
  logger,
588
605
  });
606
+ clearTimeout(selfTimeout);
589
607
  logger.success(`[crm-run] Done — scraped=${result.scraped} inserted=${result.inserted} ` +
590
608
  `disqualified=${result.disqualified} skipped=${result.skipped}`);
591
609
  process.exit(0);
592
610
  }
593
611
  catch (error) {
612
+ clearTimeout(selfTimeout);
594
613
  logger.error(`[crm-run] Failed: ${error.message}`);
595
614
  process.exit(1);
596
615
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autokap",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "AI-powered CLI tool for capturing clean screenshots of websites",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",