quilltap 4.10.0-dev.36 → 4.10.0-dev.41

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/bin/quilltap.js +22 -2
  2. package/package.json +1 -1
package/bin/quilltap.js CHANGED
@@ -486,6 +486,18 @@ function verifyPidIsNode(pid, expectedArgv0) {
486
486
 
487
487
  const HEARTBEAT_FRESH_MS = 5 * 60 * 1000;
488
488
 
489
+ /**
490
+ * The freshness window in words, derived from the constant the check actually
491
+ * uses — so the sentence `--lock-clean` prints cannot drift away from the
492
+ * behaviour it describes.
493
+ */
494
+ function describeFreshWindow() {
495
+ const seconds = Math.round(HEARTBEAT_FRESH_MS / 1000);
496
+ if (seconds % 60 !== 0) return `${seconds} seconds`;
497
+ const minutes = seconds / 60;
498
+ return minutes === 1 ? '1 minute' : `${minutes} minutes`;
499
+ }
500
+
489
501
  /**
490
502
  * Decide whether a lock record belongs to a live process.
491
503
  *
@@ -628,9 +640,17 @@ function handleLockCommand(dataDir, opts) {
628
640
  console.log('Stop the running instance first, or use --lock-override to force.');
629
641
  process.exit(1);
630
642
  } else if (heartbeatFresh) {
643
+ // Reached only when `alive` is false — the arm above has already claimed
644
+ // every confirmed-live case — so this must not assert that anything is
645
+ // running. Freshness alone is the deliberate fallback (bug 126) for
646
+ // environments where PID checks are unreliable; the refusal is right,
647
+ // and what it says is simply what was tested.
631
648
  const ageStr = Math.round(heartbeatAgeMs / 1000) + 's';
632
- console.log(`Lock is still being refreshed (heartbeat ${ageStr} ago) — its holder is alive. Cannot clean.`);
633
- console.log('Stop the running instance first, or use --lock-override to force.');
649
+ console.log(`Lock heartbeat is still fresh (${ageStr} ago). Cannot clean.`);
650
+ console.log(
651
+ `A lock counts as held until its heartbeat is ${describeFreshWindow()} stale, even if its process has gone. ` +
652
+ 'Wait it out, or use --lock-override to force.'
653
+ );
634
654
  process.exit(1);
635
655
  } else if (alive && !isNode) {
636
656
  console.log(`Lock references PID ${lock.pid} which is alive but does NOT look like a Quilltap process.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quilltap",
3
- "version": "4.10.0-dev.36",
3
+ "version": "4.10.0-dev.41",
4
4
  "description": "Self-hosted AI workspace for writers, worldbuilders, and roleplayers. Run with npx quilltap.",
5
5
  "author": {
6
6
  "name": "Charles Sebold",