rechrome 1.28.1 → 1.29.0

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/README.md CHANGED
@@ -88,13 +88,14 @@ On the host (the machine with Chrome):
88
88
  rech listener add share --listen local --prefix=rechrome --port 13776 --profile you@example.com
89
89
  tailscale serve --bg --set-path=/rechrome 13776
90
90
  rech listener set share --public-url https://host.example.ts.net/rechrome/
91
- rech url you@example.com --listener share # prints the URL to share — it contains a secret key
91
+ rech share you@example.com # prints the URL to share — it contains a secret key
92
92
  ```
93
93
 
94
94
  `rech listener add` prints these follow-up lines with your port filled in. For scripts,
95
95
  `rech listener port share` prints the port (`$(rech listener port share)` in bash or PowerShell).
96
96
 
97
- On the other machine, inside the project that should use it:
97
+ On the other machine, inside the project that should use it (or just open the link in a
98
+ browser: it shows these commands, per shell, with a Copy button):
98
99
 
99
100
  ```bash
100
101
  rech connect 'https://host.example.ts.net/rechrome/?profile=you%40example.com#key=…'
@@ -106,13 +107,13 @@ rech open https://example.com
106
107
  interactions, but not `eval`/`run-code` or filesystem commands (see [Remote access](#remote-access)).
107
108
 
108
109
  On a trusted LAN without a proxy, `rech setup --listen lan --profile you@example.com` binds the
109
- profile to your LAN address directly (plain HTTP); share the result of `rech url`.
110
+ profile to your LAN address directly (plain HTTP); share the result of `rech share`.
110
111
 
111
112
  ### 5. Manage access
112
113
 
113
114
  ```bash
114
- rech url ls # every listener × profile, local and public URLs (keys hidden)
115
- rech url you@example.com --listener share # print one URL again (add --save to use it in this project)
115
+ rech share ls # everything shared: listener × profile, local and public URLs (keys hidden)
116
+ rech share you@example.com # print one URL again (add --save to use it in this project)
116
117
  rech listener allow share teammate@example.com
117
118
  rech listener deny share teammate@example.com
118
119
  rech listener rotate-key share # revoke: every URL for this listener stops working
@@ -193,7 +194,7 @@ Connection parameters also accept URL fragments:
193
194
  RECHROME_URL='https://your-host.ts.net/rechrome/?profile=qa#key=DAEMON_KEY' rech status
194
195
  ```
195
196
 
196
- `rech setup` prints and saves this URI format. Retrieve it later with `rech url qa` (alias: `rech profile qa --print-uri`), or omit `qa` to use the configured profile. `profiles` remains an alias. The command prints only the URI to stdout, using the configured `RECHROME_URL` endpoint; `--listener local` selects a local listener instead. For example: `rech profile qa --print-uri --listener local`. The output contains a secret daemon key.
197
+ `rech setup` prints and saves this URI format. Retrieve it later with `rech share qa` (alias: `rech profile qa --print-uri`), or omit `qa` to use the configured profile. `profiles` remains an alias. The command prints only the URI to stdout, using the configured `RECHROME_URL` endpoint; `--listener local` selects a local listener instead. For example: `rech profile qa --print-uri --listener local`. The output contains a secret daemon key.
197
198
 
198
199
  Direct connections use the root path, such as `http://127.0.0.1:13775/?profile=qa#key=DAEMON_KEY`. A prefix is optional and only added when explicitly configured with `--prefix`, for example for a proxy mounted at `/rechrome/`. Tailscale can also serve at the root without a prefix.
199
200
 
@@ -207,7 +208,7 @@ cp .env.example .env.local
207
208
 
208
209
  | Variable | Description | Default |
209
210
  | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
210
- | `RECHROME_URL` | Connection URL, saved by `rech setup` / `rech connect` / `rech url --save`. Also accepts `?extension_id=`, `?token=`, `?profile=` query params | — |
211
+ | `RECHROME_URL` | Connection URL, saved by `rech setup` / `rech connect` / `rech share --save`. Also accepts `?extension_id=`, `?token=`, `?profile=` query params | — |
211
212
  | `PLAYWRIGHT_CLI` | Override the playwright-cli command/path (defaults to the bundled `@playwright/cli`; set this only for a custom or forked CLI) | bundled `@playwright/cli` |
212
213
  | `RECH_HOST` | Legacy bind address, used only before listeners.json is configured | `127.0.0.1` |
213
214
  | `PLAYWRIGHT_MCP_EXTENSION_ID` | Chrome extension ID (client overrides server) | — |
package/daemon-manager.js CHANGED
@@ -24,13 +24,14 @@ function oxmgrHasWinfix(version) {
24
24
  function pickDaemonManager(opts) {
25
25
  const override = opts.override?.toLowerCase();
26
26
  if (override === "oxmgr" && !opts.oxmgrBin) {
27
- throw new Error("RECH_DAEMON_MANAGER=oxmgr, but oxmgr is not on PATH. Install oxmgr and add it to PATH, or install pm2 with `bun add -g pm2` and set RECH_DAEMON_MANAGER=pm2.");
27
+ throw new Error("RECH_DAEMON_MANAGER=oxmgr, but oxmgr is not on PATH. Install it with `bun i -g oxmgr` and ensure the global bin directory is on PATH.");
28
28
  }
29
29
  if (override === "pm2" && !opts.pm2Bin) {
30
30
  throw new Error("RECH_DAEMON_MANAGER=pm2, but pm2 is not on PATH. Install it with `bun add -g pm2` and ensure the global bin directory is on PATH.");
31
31
  }
32
32
  if (!opts.oxmgrBin && !opts.pm2Bin) {
33
- throw new Error("No daemon process manager found on PATH (oxmgr or pm2). Install pm2 with `bun add -g pm2`, ensure the global bin directory is on PATH, then rerun `bunx rechrome setup`.");
33
+ const install = opts.isWindows ? "Install oxmgr with `bun i -g oxmgr` (on Windows, pm2 via `bun add -g pm2` is preferred unless oxmgr is the +winfix build)" : "Install oxmgr with `bun i -g oxmgr`";
34
+ throw new Error(`No daemon process manager found on PATH (oxmgr or pm2). ${install}, ensure the global bin directory is on PATH, then rerun \`bunx rechrome setup\`.`);
34
35
  }
35
36
  const oxmgr = { id: "oxmgr", bin: opts.oxmgrBin ?? "oxmgr" };
36
37
  const pm2 = { id: "pm2", bin: opts.pm2Bin ?? "pm2" };
@@ -62,9 +63,27 @@ function oxmgrInstallCommand(env) {
62
63
  return ["npm", "i", "-g", "oxmgr"];
63
64
  return ["bun", "i", "-g", "oxmgr"];
64
65
  }
66
+ var PM2_DEPRECATION = "pm2 is deprecated as the rech daemon manager; install oxmgr (`bun i -g oxmgr`) and rerun `rech setup` to migrate.";
67
+ function isDeprecatedPm2Fallback(mgr, opts) {
68
+ return mgr.id === "pm2" && !opts.isWindows && !opts.override;
69
+ }
70
+ function listsProcess(id, output, name) {
71
+ if (id === "pm2") {
72
+ try {
73
+ const list = JSON.parse(output);
74
+ return Array.isArray(list) && list.some((p) => p?.name === name);
75
+ } catch {
76
+ return false;
77
+ }
78
+ }
79
+ return output.split(/[\s\u2502|\u2503]+/).includes(name);
80
+ }
65
81
  export {
66
82
  OXMGR_WINFIX_BASE,
83
+ PM2_DEPRECATION,
67
84
  compareVersion,
85
+ isDeprecatedPm2Fallback,
86
+ listsProcess,
68
87
  oxmgrHasWinfix,
69
88
  oxmgrInstallCommand,
70
89
  pickDaemonManager
package/daemon-manager.ts CHANGED
@@ -58,13 +58,18 @@ export function pickDaemonManager(opts: {
58
58
  }): DaemonManager {
59
59
  const override = opts.override?.toLowerCase();
60
60
  if (override === "oxmgr" && !opts.oxmgrBin) {
61
- throw new Error("RECH_DAEMON_MANAGER=oxmgr, but oxmgr is not on PATH. Install oxmgr and add it to PATH, or install pm2 with `bun add -g pm2` and set RECH_DAEMON_MANAGER=pm2.");
61
+ throw new Error("RECH_DAEMON_MANAGER=oxmgr, but oxmgr is not on PATH. Install it with `bun i -g oxmgr` and ensure the global bin directory is on PATH.");
62
62
  }
63
63
  if (override === "pm2" && !opts.pm2Bin) {
64
64
  throw new Error("RECH_DAEMON_MANAGER=pm2, but pm2 is not on PATH. Install it with `bun add -g pm2` and ensure the global bin directory is on PATH.");
65
65
  }
66
66
  if (!opts.oxmgrBin && !opts.pm2Bin) {
67
- throw new Error("No daemon process manager found on PATH (oxmgr or pm2). Install pm2 with `bun add -g pm2`, ensure the global bin directory is on PATH, then rerun `bunx rechrome setup`.");
67
+ // oxmgr is the recommended manager. On Windows stock oxmgr is only used when pm2 is
68
+ // absent (see below), so pm2 stays a documented alternative there.
69
+ const install = opts.isWindows
70
+ ? "Install oxmgr with `bun i -g oxmgr` (on Windows, pm2 via `bun add -g pm2` is preferred unless oxmgr is the +winfix build)"
71
+ : "Install oxmgr with `bun i -g oxmgr`";
72
+ throw new Error(`No daemon process manager found on PATH (oxmgr or pm2). ${install}, ensure the global bin directory is on PATH, then rerun \`bunx rechrome setup\`.`);
68
73
  }
69
74
  const oxmgr: DaemonManager = { id: "oxmgr", bin: opts.oxmgrBin ?? "oxmgr" };
70
75
  const pm2: DaemonManager = { id: "pm2", bin: opts.pm2Bin ?? "pm2" };
@@ -97,3 +102,29 @@ export function oxmgrInstallCommand(env: { npm_config_user_agent?: string; npm_e
97
102
  if (/(^|\/)(npm|npx)(-cli\.js|\.cmd|\.exe)?$/i.test(execPath)) return ["npm", "i", "-g", "oxmgr"];
98
103
  return ["bun", "i", "-g", "oxmgr"];
99
104
  }
105
+
106
+ export const PM2_DEPRECATION =
107
+ "pm2 is deprecated as the rech daemon manager; install oxmgr (`bun i -g oxmgr`) and rerun `rech setup` to migrate.";
108
+
109
+ // Whether `mgr` is pm2 only as a stopgap because oxmgr is missing: the case where the user
110
+ // should be nudged to oxmgr. Never on Windows, where pm2 is the deliberate choice over stock
111
+ // (non-winfix) oxmgr and installing oxmgr would not change the pick, and never for an explicit
112
+ // RECH_DAEMON_MANAGER=pm2.
113
+ export function isDeprecatedPm2Fallback(mgr: DaemonManager, opts: { isWindows: boolean; override?: string | null }): boolean {
114
+ return mgr.id === "pm2" && !opts.isWindows && !opts.override;
115
+ }
116
+
117
+ // Whether a manager's process list (pm2 `jlist` JSON / oxmgr `list` table) registers exactly
118
+ // `name`. A substring test false-positives on other processes whose names, paths or args
119
+ // mention it (a pm2 app running from a `.../rechrome/...` checkout, or legacy `rechrome-serve`).
120
+ export function listsProcess(id: DaemonManager["id"], output: string, name: string): boolean {
121
+ if (id === "pm2") {
122
+ try {
123
+ const list = JSON.parse(output);
124
+ return Array.isArray(list) && list.some((p: { name?: unknown } | null) => p?.name === name);
125
+ } catch {
126
+ return false;
127
+ }
128
+ }
129
+ return output.split(/[\s│|┃]+/).includes(name);
130
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rechrome",
3
- "version": "1.28.1",
3
+ "version": "1.29.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/snomiao/rechrome.git"