rechrome 1.23.3 → 1.23.4

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 (3) hide show
  1. package/package.json +1 -1
  2. package/serve.js +40 -3
  3. package/serve.ts +40 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rechrome",
3
- "version": "1.23.3",
3
+ "version": "1.23.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/snomiao/rechrome.git"
package/serve.js CHANGED
@@ -84,6 +84,36 @@ function noteSession(sess: string, now: number): void {
84
84
  }
85
85
  }
86
86
 
87
+ /**
88
+ * Did this returned command actually prove the relay is answering?
89
+ *
90
+ * The watchdog above clears its streaks whenever a command returns instead of timing out,
91
+ * on the reasoning that a reply — even a failing one — means the relay is alive. That holds
92
+ * for errors produced BY the browser, but not for ones the CLI raises locally before it ever
93
+ * opens a connection. `Browser '<id>' is not open` is the important case: it is emitted the
94
+ * instant a session is missing, which is precisely the state the per-session heal CREATES by
95
+ * closing a wedged session. So the sequence was:
96
+ *
97
+ * timeout, timeout → per-session heal closes the session
98
+ * "browser is not open" → returned fast, counted as success, globalStreak reset to 0
99
+ * timeout, timeout → heal again … forever
100
+ *
101
+ * WATCHDOG_TIMEOUTS (3) could therefore never be reached on a genuinely dead relay, and the
102
+ * daemon-level restart that exists to fix exactly that never fired — leaving `oxmgr restart
103
+ * rechrome` by hand as the only cure (observed 2026-08-05: three manual restarts in one
104
+ * session, each buying only a handful of commands).
105
+ *
106
+ * Returning false here does NOT count against the relay; it just refuses to forgive the
107
+ * timeouts already recorded.
108
+ */
109
+ export function provesRelayAlive(o: { stdout: string; stderr: string }): boolean {
110
+ const out = `${o.stdout ?? ""}\n${o.stderr ?? ""}`;
111
+ // Both spellings the CLI uses for "no such session" (cli-client/output.js).
112
+ if (/Browser '[^']*' is not open/i.test(out)) return false;
113
+ if (/is not open, please run open first/i.test(out)) return false;
114
+ return true;
115
+ }
116
+
87
117
  export function inferSilentExtensionFailure(options: {
88
118
  status: number;
89
119
  stdout: string;
@@ -543,8 +573,10 @@ export async function serve() {
543
573
 
544
574
  log(`exit: ${status}${stdout.trim() ? ` | ${stdout.trim().slice(0, 200)}` : ""}`);
545
575
 
546
- // Relay self-heal (see notes at SESSION_CLOSE_TIMEOUTS): a command that RETURNS — even
547
- // non-zero — proves the relay answered, so clear the streaks; a TIMEOUT means it didn't.
576
+ // Relay self-heal (see notes at SESSION_CLOSE_TIMEOUTS). A command that RETURNS usually
577
+ // proves the relay answered — but NOT when the CLI short-circuited locally without ever
578
+ // reaching it (provesRelayAlive). Treating those as success reset the global streak on
579
+ // every per-session heal, so WATCHDOG_TIMEOUTS could never be reached. See that helper.
548
580
  if (timedOut) {
549
581
  consecutiveTimeouts++;
550
582
  const streak = (sessionTimeouts.get(namespacedSession) ?? 0) + 1;
@@ -565,9 +597,14 @@ export async function serve() {
565
597
  log(`relay wedged: ${consecutiveTimeouts} consecutive timeouts, no success between — exiting for oxmgr (--restart always) to respawn clean; extension WS will reconnect (Chrome untouched)`);
566
598
  setTimeout(() => process.exit(1), 100); // brief delay to flush this response
567
599
  }
568
- } else {
600
+ } else if (provesRelayAlive({ stdout, stderr })) {
569
601
  consecutiveTimeouts = 0;
570
602
  sessionTimeouts.delete(namespacedSession);
603
+ } else {
604
+ // Returned, but proved nothing about the relay (local short-circuit). Leave BOTH
605
+ // streaks untouched: not a timeout, so don't punish it — but don't let it forgive
606
+ // the timeouts that came before, which is the bug this branch exists to fix.
607
+ log(`inconclusive: session=${namespacedSession} did not reach the relay — streaks kept (globalStreak=${consecutiveTimeouts})`);
571
608
  }
572
609
 
573
610
  // Detect files mentioned in output
package/serve.ts CHANGED
@@ -84,6 +84,36 @@ function noteSession(sess: string, now: number): void {
84
84
  }
85
85
  }
86
86
 
87
+ /**
88
+ * Did this returned command actually prove the relay is answering?
89
+ *
90
+ * The watchdog above clears its streaks whenever a command returns instead of timing out,
91
+ * on the reasoning that a reply — even a failing one — means the relay is alive. That holds
92
+ * for errors produced BY the browser, but not for ones the CLI raises locally before it ever
93
+ * opens a connection. `Browser '<id>' is not open` is the important case: it is emitted the
94
+ * instant a session is missing, which is precisely the state the per-session heal CREATES by
95
+ * closing a wedged session. So the sequence was:
96
+ *
97
+ * timeout, timeout → per-session heal closes the session
98
+ * "browser is not open" → returned fast, counted as success, globalStreak reset to 0
99
+ * timeout, timeout → heal again … forever
100
+ *
101
+ * WATCHDOG_TIMEOUTS (3) could therefore never be reached on a genuinely dead relay, and the
102
+ * daemon-level restart that exists to fix exactly that never fired — leaving `oxmgr restart
103
+ * rechrome` by hand as the only cure (observed 2026-08-05: three manual restarts in one
104
+ * session, each buying only a handful of commands).
105
+ *
106
+ * Returning false here does NOT count against the relay; it just refuses to forgive the
107
+ * timeouts already recorded.
108
+ */
109
+ export function provesRelayAlive(o: { stdout: string; stderr: string }): boolean {
110
+ const out = `${o.stdout ?? ""}\n${o.stderr ?? ""}`;
111
+ // Both spellings the CLI uses for "no such session" (cli-client/output.ts).
112
+ if (/Browser '[^']*' is not open/i.test(out)) return false;
113
+ if (/is not open, please run open first/i.test(out)) return false;
114
+ return true;
115
+ }
116
+
87
117
  export function inferSilentExtensionFailure(options: {
88
118
  status: number;
89
119
  stdout: string;
@@ -543,8 +573,10 @@ export async function serve() {
543
573
 
544
574
  log(`exit: ${status}${stdout.trim() ? ` | ${stdout.trim().slice(0, 200)}` : ""}`);
545
575
 
546
- // Relay self-heal (see notes at SESSION_CLOSE_TIMEOUTS): a command that RETURNS — even
547
- // non-zero — proves the relay answered, so clear the streaks; a TIMEOUT means it didn't.
576
+ // Relay self-heal (see notes at SESSION_CLOSE_TIMEOUTS). A command that RETURNS usually
577
+ // proves the relay answered — but NOT when the CLI short-circuited locally without ever
578
+ // reaching it (provesRelayAlive). Treating those as success reset the global streak on
579
+ // every per-session heal, so WATCHDOG_TIMEOUTS could never be reached. See that helper.
548
580
  if (timedOut) {
549
581
  consecutiveTimeouts++;
550
582
  const streak = (sessionTimeouts.get(namespacedSession) ?? 0) + 1;
@@ -565,9 +597,14 @@ export async function serve() {
565
597
  log(`relay wedged: ${consecutiveTimeouts} consecutive timeouts, no success between — exiting for oxmgr (--restart always) to respawn clean; extension WS will reconnect (Chrome untouched)`);
566
598
  setTimeout(() => process.exit(1), 100); // brief delay to flush this response
567
599
  }
568
- } else {
600
+ } else if (provesRelayAlive({ stdout, stderr })) {
569
601
  consecutiveTimeouts = 0;
570
602
  sessionTimeouts.delete(namespacedSession);
603
+ } else {
604
+ // Returned, but proved nothing about the relay (local short-circuit). Leave BOTH
605
+ // streaks untouched: not a timeout, so don't punish it — but don't let it forgive
606
+ // the timeouts that came before, which is the bug this branch exists to fix.
607
+ log(`inconclusive: session=${namespacedSession} did not reach the relay — streaks kept (globalStreak=${consecutiveTimeouts})`);
571
608
  }
572
609
 
573
610
  // Detect files mentioned in output