@omercnet/paseo-shared-browser 1.0.1-next.176.1 → 1.0.1

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
@@ -77,9 +77,9 @@ paseo plugin ls
77
77
  ```
78
78
 
79
79
  When Paseo acquires the npm package, it runs the `npm run prepare:runtime` build hook automatically. The
80
- hook installs the pinned browser runtime, builds both `supervisor.cjs` and `shared-browser-mcp.cjs`
81
- under a versioned directory in `$PASEO_HOME/plugin-data/shared-browser`, then atomically updates the
82
- `runtime-current` pointer. Existing processes keep using their immutable runtime during an update.
80
+ hook installs the pinned browser runtime and builds both `supervisor.cjs` and
81
+ `shared-browser-mcp.cjs` under
82
+ `$PASEO_HOME/plugin-data/shared-browser/runtime`.
83
83
 
84
84
  The build requires Node.js 24 or newer and npm on the daemon host. On Linux x64, macOS, and
85
85
  Windows, runtime preparation installs and stages the platform's Chrome for Testing distribution. On
@@ -125,8 +125,8 @@ The plugin recognizes only these deployment overrides:
125
125
  | Variable | Meaning |
126
126
  | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
127
127
  | `PASEO_HOME` | Paseo data root. Defaults to `~/.paseo`; browser runtime, supervisor IPC, and profiles live below `plugin-data/shared-browser`. |
128
- | `PASEO_SHARED_BROWSER_AGENT_BROWSER_BINARY` | Absolute path to the pinned `agent-browser` executable. Defaults to the active runtime's `node_modules/.bin/agent-browser` (`agent-browser.exe` on Windows). |
129
- | `PASEO_SHARED_BROWSER_CHROMIUM_EXECUTABLE` | Absolute path to Chromium. Defaults to the active runtime's `chromium/chrome` (`chrome.exe` on Windows). On Linux ARM64, installation automatically links `/usr/bin/chromium`; use this override for another compatible, non-Snap location. |
128
+ | `PASEO_SHARED_BROWSER_AGENT_BROWSER_BINARY` | Absolute path to the pinned `agent-browser` executable. Defaults to `$PASEO_HOME/plugin-data/shared-browser/runtime/node_modules/.bin/agent-browser` (`agent-browser.exe` on Windows). |
129
+ | `PASEO_SHARED_BROWSER_CHROMIUM_EXECUTABLE` | Absolute path to Chromium. Defaults to `$PASEO_HOME/plugin-data/shared-browser/runtime/chromium/chrome` (`chrome.exe` on Windows). On Linux ARM64, installation automatically links `/usr/bin/chromium`; use this override for another compatible, non-Snap location. |
130
130
  | `PASEO_SHARED_BROWSER_CHROMIUM_ARGS` | Optional Chromium arguments passed through the managed runtime. Intended for host requirements such as `--no-sandbox` in an already-isolated CI runner; do not disable the browser sandbox on a general-purpose host. |
131
131
 
132
132
  User-supplied `AGENT_BROWSER_*` variables are deliberately ignored.
package/index.server.ts CHANGED
@@ -19,7 +19,6 @@ import {
19
19
  issueAgentTicket,
20
20
  revokeAgentBrowserAccess,
21
21
  } from "./server/browser";
22
- import { resolveBrowserRuntimeRoot } from "./server/runtime-path";
23
22
  import {
24
23
  acquireControlRpc,
25
24
  applyDevicePresetRpc,
@@ -63,7 +62,7 @@ function paseoHome(): string {
63
62
  }
64
63
 
65
64
  function mcpBundlePath(): string {
66
- return join(resolveBrowserRuntimeRoot(paseoHome()), "shared-browser-mcp.cjs");
65
+ return join(paseoHome(), "plugin-data", "shared-browser", "runtime", "shared-browser-mcp.cjs");
67
66
  }
68
67
 
69
68
  export default function contribute(server: PluginServerContext) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omercnet/paseo-shared-browser",
3
- "version": "1.0.1-next.176.1",
3
+ "version": "1.0.1",
4
4
  "description": "One real Chromium session per Paseo workspace, shared live across every connected client.",
5
5
  "keywords": [
6
6
  "browser",
@@ -29,7 +29,6 @@
29
29
  "client",
30
30
  "scripts/prepare-dependencies.mjs",
31
31
  "scripts/prepare-runtime.mjs",
32
- "scripts/replace-runtime.mjs",
33
32
  "server",
34
33
  "shared",
35
34
  "paseo-plugin.json"
@@ -1,14 +1,23 @@
1
1
  import { execFile } from "node:child_process";
2
- import { randomUUID } from "node:crypto";
3
2
  import { constants } from "node:fs";
4
- import { access, chmod, cp, lstat, mkdir, readdir, rm, symlink, writeFile } from "node:fs/promises";
3
+ import {
4
+ access,
5
+ chmod,
6
+ cp,
7
+ lstat,
8
+ mkdir,
9
+ readdir,
10
+ rename,
11
+ rm,
12
+ symlink,
13
+ writeFile,
14
+ } from "node:fs/promises";
5
15
  import { createRequire } from "node:module";
6
16
  import { arch, homedir, platform, userInfo } from "node:os";
7
17
  import { dirname, join, resolve } from "node:path";
8
18
  import { fileURLToPath } from "node:url";
9
19
  import { promisify } from "node:util";
10
20
  import { build } from "esbuild";
11
- import { replaceRuntime } from "./replace-runtime.mjs";
12
21
 
13
22
  const require = createRequire(import.meta.url);
14
23
 
@@ -25,7 +34,7 @@ const projectRoot = dirname(dirname(fileURLToPath(import.meta.url)));
25
34
  const paseoHome = process.env.PASEO_HOME || join(homedir(), ".paseo");
26
35
  const pluginDataRoot = join(paseoHome, "plugin-data", "shared-browser");
27
36
  const runtimeRoot = join(pluginDataRoot, "runtime");
28
- const stagingRoot = join(pluginDataRoot, `.runtime-${randomUUID()}`);
37
+ const stagingRoot = join(pluginDataRoot, `.runtime-${process.pid}`);
29
38
  const runtimeModules = join(stagingRoot, "node_modules");
30
39
  const packagedAgentBrowser = resolveDependencyRoot("agent-browser");
31
40
  const runtimeEntry = join(
@@ -248,6 +257,6 @@ await applyPrivatePermissions(stagingRoot);
248
257
  if (hostPlatform !== "win32") {
249
258
  await validateChromium(await requireExecutable(chromiumEntry, "Staged Chromium executable"));
250
259
  }
251
- await replaceRuntime(stagingRoot, runtimeRoot);
260
+ await rename(stagingRoot, runtimeRoot);
252
261
 
253
- console.log(`Prepared immutable Shared Browser runtime assets in ${stagingRoot}`);
262
+ console.log(`Prepared immutable Shared Browser runtime assets in ${runtimeRoot}`);
package/server/browser.ts CHANGED
@@ -17,7 +17,6 @@ import type {
17
17
  resizeBrowserRpc,
18
18
  sendBrowserInputRpc,
19
19
  } from "../shared/browser";
20
- import { resolveBrowserRuntimeRoot } from "./runtime-path";
21
20
  import type { JsonValue } from "./runtime-protocol";
22
21
  import { resolveSupervisorPaths } from "./supervisor";
23
22
  import { SupervisorClient } from "./supervisor-client";
@@ -157,7 +156,13 @@ let productionStart: Promise<RemoteBrowserManager> | null = null;
157
156
  let productionStopped = false;
158
157
 
159
158
  async function launchSupervisor(): Promise<void> {
160
- const supervisorPath = join(resolveBrowserRuntimeRoot(paseoHome()), "supervisor.cjs");
159
+ const supervisorPath = join(
160
+ paseoHome(),
161
+ "plugin-data",
162
+ "shared-browser",
163
+ "runtime",
164
+ "supervisor.cjs",
165
+ );
161
166
  try {
162
167
  await access(supervisorPath);
163
168
  } catch {
@@ -2,7 +2,6 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { AgentBrowserRuntime, type BrowserViewport } from "./agent-browser-runtime";
5
- import { resolveBrowserRuntimeRoot } from "./runtime-path";
6
5
  import type { JsonValue } from "./runtime-protocol";
7
6
  import type { RuntimeOwner } from "./supervisor";
8
7
 
@@ -24,9 +23,7 @@ function paseoHome(): string {
24
23
  export async function createRuntimeOwner(
25
24
  options: RuntimeOwnerOptions = {},
26
25
  ): Promise<RuntimeOwner<OwnedRuntime>> {
27
- const home = paseoHome();
28
- const root = join(home, "plugin-data", "shared-browser");
29
- const runtimeRoot = resolveBrowserRuntimeRoot(home);
26
+ const root = join(paseoHome(), "plugin-data", "shared-browser");
30
27
  const ipcDirectory =
31
28
  process.platform === "win32"
32
29
  ? join(root, "ipc")
@@ -37,14 +34,15 @@ export async function createRuntimeOwner(
37
34
  const binaryPath =
38
35
  process.env.PASEO_SHARED_BROWSER_AGENT_BROWSER_BINARY ??
39
36
  join(
40
- runtimeRoot,
37
+ root,
38
+ "runtime",
41
39
  "node_modules",
42
40
  ".bin",
43
41
  process.platform === "win32" ? "agent-browser.exe" : "agent-browser",
44
42
  );
45
43
  const executablePath =
46
44
  process.env.PASEO_SHARED_BROWSER_CHROMIUM_EXECUTABLE ??
47
- join(runtimeRoot, "chromium", process.platform === "win32" ? "chrome.exe" : "chrome");
45
+ join(root, "runtime", "chromium", process.platform === "win32" ? "chrome.exe" : "chrome");
48
46
  return {
49
47
  async create(workspaceId) {
50
48
  const hash = createHash("sha256").update(workspaceId).digest("hex");
@@ -1,15 +0,0 @@
1
- import { access, rename, rm, writeFile } from "node:fs/promises";
2
- import { basename, dirname, join } from "node:path";
3
-
4
- export async function replaceRuntime(stagingRoot, runtimeRoot) {
5
- await access(stagingRoot);
6
- const pluginDataRoot = dirname(runtimeRoot);
7
- const pointer = join(pluginDataRoot, "runtime-current");
8
- const pendingPointer = join(pluginDataRoot, `.runtime-current-${process.pid}`);
9
- await writeFile(pendingPointer, `${basename(stagingRoot)}\n`, { mode: 0o600 });
10
- try {
11
- await rename(pendingPointer, pointer);
12
- } finally {
13
- await rm(pendingPointer, { force: true });
14
- }
15
- }
@@ -1,21 +0,0 @@
1
- import { readFileSync } from "node:fs";
2
- import { join } from "node:path";
3
-
4
- export function resolveBrowserRuntimeRoot(paseoHome: string): string {
5
- const pluginDataRoot = join(paseoHome, "plugin-data", "shared-browser");
6
- let directory: string;
7
- try {
8
- directory = readFileSync(join(pluginDataRoot, "runtime-current"), "utf8").trim();
9
- } catch (error) {
10
- if ((error as NodeJS.ErrnoException).code === "ENOENT") return join(pluginDataRoot, "runtime");
11
- throw error;
12
- }
13
- if (
14
- !/^\.runtime-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(
15
- directory,
16
- )
17
- ) {
18
- throw new Error("Shared Browser runtime pointer is invalid");
19
- }
20
- return join(pluginDataRoot, directory);
21
- }