@omercnet/paseo-shared-browser 0.4.2-next.129.1 → 0.4.2
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/client/browser.tsx +15 -15
- package/index.client.tsx +1 -1
- package/index.server.ts +1 -1
- package/package.json +7 -10
- package/paseo-plugin.json +4 -1
- package/scripts/prepare-dependencies.mjs +1 -1
- package/scripts/prepare-runtime.mjs +4 -4
- package/server/agent-browser-runtime.ts +28 -16
- package/server/browser-policy.ts +10 -10
- package/server/browser.ts +5 -5
- package/server/mcp-entry.ts +3 -3
- package/server/supervisor-client.ts +4 -4
- package/server/supervisor.ts +4 -4
package/client/browser.tsx
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
+
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
1
2
|
import {
|
|
2
3
|
type PluginClientContext,
|
|
3
4
|
type PluginWorkspacePanelProps,
|
|
4
5
|
useRpc,
|
|
5
6
|
} from "@getpaseo/plugin/client";
|
|
6
7
|
import { Icon, Modal, ScrollView, TextInput } from "@getpaseo/plugin/client/react-native";
|
|
7
|
-
import {
|
|
8
|
-
import { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
|
|
9
9
|
import {
|
|
10
10
|
ActivityIndicator,
|
|
11
|
-
type GestureResponderEvent,
|
|
12
11
|
Image,
|
|
13
|
-
type LayoutChangeEvent,
|
|
14
12
|
PanResponder,
|
|
15
13
|
Pressable,
|
|
16
|
-
type StyleProp,
|
|
17
14
|
StyleSheet,
|
|
18
15
|
Text,
|
|
16
|
+
View,
|
|
17
|
+
type GestureResponderEvent,
|
|
18
|
+
type LayoutChangeEvent,
|
|
19
|
+
type StyleProp,
|
|
19
20
|
type TextInputProps,
|
|
20
21
|
type TextStyle,
|
|
21
|
-
View,
|
|
22
22
|
type ViewStyle,
|
|
23
23
|
} from "react-native";
|
|
24
24
|
import {
|
|
25
|
+
DEVICE_PRESETS,
|
|
26
|
+
MAX_VIEWPORT,
|
|
27
|
+
MIN_VIEWPORT,
|
|
25
28
|
acquireControlRpc,
|
|
26
29
|
applyDevicePresetRpc,
|
|
27
30
|
attachBrowserRpc,
|
|
28
|
-
type BrowserFrame,
|
|
29
|
-
type BrowserInputEvent,
|
|
30
|
-
type BrowserState,
|
|
31
31
|
captureBrowserRpc,
|
|
32
|
-
DEVICE_PRESETS,
|
|
33
|
-
type DevicePresetId,
|
|
34
32
|
detachBrowserRpc,
|
|
35
|
-
didBrowserRuntimeRestart,
|
|
36
|
-
isBrowserStateCurrent,
|
|
37
33
|
listOpenBrowserWorkspacesRpc,
|
|
38
|
-
MAX_VIEWPORT,
|
|
39
|
-
MIN_VIEWPORT,
|
|
40
34
|
navigateBrowserRpc,
|
|
41
35
|
releaseControlRpc,
|
|
42
36
|
resizeBrowserRpc,
|
|
43
37
|
sendBrowserInputRpc,
|
|
38
|
+
didBrowserRuntimeRestart,
|
|
39
|
+
isBrowserStateCurrent,
|
|
40
|
+
type BrowserFrame,
|
|
41
|
+
type BrowserInputEvent,
|
|
42
|
+
type BrowserState,
|
|
43
|
+
type DevicePresetId,
|
|
44
44
|
} from "../shared/browser";
|
|
45
45
|
|
|
46
46
|
const SPACE = {
|
package/index.client.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PluginClientContext } from "@getpaseo/plugin/client";
|
|
2
|
-
import {
|
|
2
|
+
import { SharedBrowserPanel, contributeSharedBrowserClient } from "./client/browser";
|
|
3
3
|
|
|
4
4
|
export default function contribute(client: PluginClientContext) {
|
|
5
5
|
client.addWorkspacePanel({
|
package/index.server.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import type { PluginServerContext } from "@getpaseo/plugin/server";
|
|
1
2
|
import { randomBytes } from "node:crypto";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
4
|
import { join } from "node:path";
|
|
4
|
-
import type { PluginServerContext } from "@getpaseo/plugin/server";
|
|
5
5
|
import {
|
|
6
6
|
bindAgentTicket,
|
|
7
7
|
cleanupBrowserServer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omercnet/paseo-shared-browser",
|
|
3
|
-
"version": "0.4.2
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "One real Chromium session per Paseo workspace, shared live across every connected client.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"browser",
|
|
@@ -39,14 +39,12 @@
|
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"typecheck": "tsc --noEmit",
|
|
42
|
+
"lint": "oxlint --deny-warnings .",
|
|
43
|
+
"format": "oxfmt --ignore-path .formatignore .",
|
|
44
|
+
"format:check": "oxfmt --check --ignore-path .formatignore .",
|
|
42
45
|
"prepare:runtime": "node scripts/prepare-runtime.mjs",
|
|
43
46
|
"test:unit": "node --test scripts/prepare-dependencies.test.mjs && vitest run tests/contracts.test.ts tests/lease.test.ts tests/runtime-lifecycle.test.ts tests/agent-access.test.ts",
|
|
44
|
-
"test:smoke": "vitest run tests/browser.smoke.test.ts --testTimeout=30000"
|
|
45
|
-
"check": "biome check --error-on-warnings .",
|
|
46
|
-
"check:write": "biome check --write .",
|
|
47
|
-
"test": "run-s test:ci:*",
|
|
48
|
-
"test:ci:unit": "npm run test:unit",
|
|
49
|
-
"build": "node ../.github/scripts/build-plugin.mjs"
|
|
47
|
+
"test:smoke": "vitest run tests/browser.smoke.test.ts --testTimeout=30000"
|
|
50
48
|
},
|
|
51
49
|
"dependencies": {
|
|
52
50
|
"@getpaseo/plugin": "0.8.0",
|
|
@@ -56,13 +54,12 @@
|
|
|
56
54
|
"zod": "4.4.3"
|
|
57
55
|
},
|
|
58
56
|
"devDependencies": {
|
|
59
|
-
"@biomejs/biome": "^2.5.14",
|
|
60
57
|
"@getpaseo/plugin": "0.9.0-beta.1",
|
|
61
|
-
"@getpaseo/server": "0.9.0-beta.1",
|
|
62
58
|
"@tanstack/react-query": "^5.90.11",
|
|
63
59
|
"@types/node": "^22.0.0",
|
|
64
60
|
"@types/react": "~19.2.0",
|
|
65
|
-
"
|
|
61
|
+
"oxfmt": "0.66.0",
|
|
62
|
+
"oxlint": "1.81.0",
|
|
66
63
|
"react": "19.1.0",
|
|
67
64
|
"react-native": "0.81.5",
|
|
68
65
|
"typescript": "^7.0.0",
|
package/paseo-plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { execFileSync } from "node:child_process";
|
|
2
3
|
import { existsSync } from "node:fs";
|
|
3
|
-
import { createRequire } from "node:module";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { resolveDependencyRoot } from "./prepare-dependencies.mjs";
|
|
2
|
+
import { build } from "esbuild";
|
|
1
3
|
import { execFile } from "node:child_process";
|
|
2
|
-
import { constants } from "node:fs";
|
|
3
4
|
import {
|
|
4
5
|
access,
|
|
5
6
|
chmod,
|
|
@@ -12,12 +13,11 @@ import {
|
|
|
12
13
|
symlink,
|
|
13
14
|
writeFile,
|
|
14
15
|
} from "node:fs/promises";
|
|
16
|
+
import { constants } from "node:fs";
|
|
15
17
|
import { arch, homedir, platform, userInfo } from "node:os";
|
|
16
18
|
import { dirname, join, resolve } from "node:path";
|
|
17
|
-
import { fileURLToPath } from "node:url";
|
|
18
19
|
import { promisify } from "node:util";
|
|
19
|
-
import {
|
|
20
|
-
import { resolveDependencyRoot } from "./prepare-dependencies.mjs";
|
|
20
|
+
import { fileURLToPath } from "node:url";
|
|
21
21
|
|
|
22
22
|
const execFileAsync = promisify(execFile);
|
|
23
23
|
const expectedVersion = "0.37.1";
|
|
@@ -3,14 +3,14 @@ import { chmod, mkdir, readFile, rm } from "node:fs/promises";
|
|
|
3
3
|
import { isAbsolute, resolve } from "node:path";
|
|
4
4
|
import { promisify } from "node:util";
|
|
5
5
|
import {
|
|
6
|
-
attachToTarget,
|
|
7
6
|
CdpConnection,
|
|
8
|
-
|
|
9
|
-
type CdpSession,
|
|
10
|
-
type CdpTarget,
|
|
7
|
+
CdpSession,
|
|
11
8
|
CdpUnavailableError,
|
|
12
9
|
CdpUnknownOutcomeError,
|
|
10
|
+
attachToTarget,
|
|
13
11
|
listPageTargets,
|
|
12
|
+
type CdpEvent,
|
|
13
|
+
type CdpTarget,
|
|
14
14
|
} from "./cdp";
|
|
15
15
|
|
|
16
16
|
const execFileAsync = promisify(execFile);
|
|
@@ -164,7 +164,9 @@ function parseJsonOutput(stdout: string): unknown {
|
|
|
164
164
|
for (const line of lines) {
|
|
165
165
|
try {
|
|
166
166
|
return JSON.parse(line);
|
|
167
|
-
} catch {
|
|
167
|
+
} catch {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
168
170
|
}
|
|
169
171
|
throw new AgentBrowserIncompatibleError("agent-browser returned invalid JSON");
|
|
170
172
|
}
|
|
@@ -506,7 +508,9 @@ export class AgentBrowserRuntime {
|
|
|
506
508
|
|
|
507
509
|
async mouseMove(x: number, y: number): Promise<void> {
|
|
508
510
|
this.assertPoint(x, y);
|
|
509
|
-
await (
|
|
511
|
+
await (
|
|
512
|
+
await this.requirePage()
|
|
513
|
+
).send(
|
|
510
514
|
"Input.dispatchMouseEvent",
|
|
511
515
|
{
|
|
512
516
|
type: "mouseMoved",
|
|
@@ -526,7 +530,9 @@ export class AgentBrowserRuntime {
|
|
|
526
530
|
clickCount = 1,
|
|
527
531
|
): Promise<void> {
|
|
528
532
|
this.assertPoint(x, y);
|
|
529
|
-
await (
|
|
533
|
+
await (
|
|
534
|
+
await this.requirePage()
|
|
535
|
+
).send(
|
|
530
536
|
"Input.dispatchMouseEvent",
|
|
531
537
|
{
|
|
532
538
|
type: "mousePressed",
|
|
@@ -543,7 +549,9 @@ export class AgentBrowserRuntime {
|
|
|
543
549
|
|
|
544
550
|
async mouseUp(x: number, y: number, button: MouseButton = "left", clickCount = 1): Promise<void> {
|
|
545
551
|
this.assertPoint(x, y);
|
|
546
|
-
await (
|
|
552
|
+
await (
|
|
553
|
+
await this.requirePage()
|
|
554
|
+
).send(
|
|
547
555
|
"Input.dispatchMouseEvent",
|
|
548
556
|
{
|
|
549
557
|
type: "mouseReleased",
|
|
@@ -560,7 +568,9 @@ export class AgentBrowserRuntime {
|
|
|
560
568
|
|
|
561
569
|
async wheel(x: number, y: number, deltaX: number, deltaY: number): Promise<void> {
|
|
562
570
|
this.assertPoint(x, y);
|
|
563
|
-
await (
|
|
571
|
+
await (
|
|
572
|
+
await this.requirePage()
|
|
573
|
+
).send(
|
|
564
574
|
"Input.dispatchMouseEvent",
|
|
565
575
|
{
|
|
566
576
|
type: "mouseWheel",
|
|
@@ -580,7 +590,9 @@ export class AgentBrowserRuntime {
|
|
|
580
590
|
}
|
|
581
591
|
|
|
582
592
|
async keyDown(key: string, code = key): Promise<void> {
|
|
583
|
-
await (
|
|
593
|
+
await (
|
|
594
|
+
await this.requirePage()
|
|
595
|
+
).send(
|
|
584
596
|
"Input.dispatchKeyEvent",
|
|
585
597
|
{
|
|
586
598
|
type: "keyDown",
|
|
@@ -594,11 +606,9 @@ export class AgentBrowserRuntime {
|
|
|
594
606
|
}
|
|
595
607
|
|
|
596
608
|
async keyUp(key: string, code = key): Promise<void> {
|
|
597
|
-
await (
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
{ mutation: true },
|
|
601
|
-
);
|
|
609
|
+
await (
|
|
610
|
+
await this.requirePage()
|
|
611
|
+
).send("Input.dispatchKeyEvent", { type: "keyUp", key, code }, { mutation: true });
|
|
602
612
|
this.heldKeys.delete(key);
|
|
603
613
|
}
|
|
604
614
|
|
|
@@ -607,7 +617,9 @@ export class AgentBrowserRuntime {
|
|
|
607
617
|
points: Array<{ x: number; y: number; id?: number }>,
|
|
608
618
|
): Promise<void> {
|
|
609
619
|
for (const point of points) this.assertPoint(point.x, point.y);
|
|
610
|
-
await (
|
|
620
|
+
await (
|
|
621
|
+
await this.requirePage()
|
|
622
|
+
).send(
|
|
611
623
|
"Input.dispatchTouchEvent",
|
|
612
624
|
{
|
|
613
625
|
type,
|
package/server/browser-policy.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { randomBytes } from "node:crypto";
|
|
2
1
|
import type { RpcInput } from "@getpaseo/plugin";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
3
|
import {
|
|
4
|
-
type applyDevicePresetRpc,
|
|
5
|
-
type BrowserFrame,
|
|
6
|
-
type BrowserInputEvent,
|
|
7
|
-
type BrowserState,
|
|
8
|
-
DEFAULT_VIEWPORT,
|
|
9
4
|
DEVICE_PRESETS,
|
|
10
|
-
|
|
5
|
+
DEFAULT_VIEWPORT,
|
|
11
6
|
FRAME_MAX_BYTES,
|
|
12
7
|
MAX_VIEWPORT,
|
|
13
8
|
MIN_VIEWPORT,
|
|
14
9
|
mapDisplayedPoint,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
applyDevicePresetRpc,
|
|
11
|
+
navigateBrowserRpc,
|
|
12
|
+
resizeBrowserRpc,
|
|
13
|
+
sendBrowserInputRpc,
|
|
14
|
+
type BrowserFrame,
|
|
15
|
+
type BrowserInputEvent,
|
|
16
|
+
type BrowserState,
|
|
17
|
+
type DevicePresetId,
|
|
18
18
|
type Viewport,
|
|
19
19
|
} from "../shared/browser";
|
|
20
20
|
import type { JsonValue } from "./runtime-protocol";
|
package/server/browser.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import type { RpcInput, RpcOutput } from "@getpaseo/plugin";
|
|
2
|
+
import type { PluginHandlerContext } from "@getpaseo/plugin/server";
|
|
1
3
|
import { spawn } from "node:child_process";
|
|
2
4
|
import { randomUUID } from "node:crypto";
|
|
3
5
|
import { access } from "node:fs/promises";
|
|
4
6
|
import { homedir } from "node:os";
|
|
5
7
|
import { join } from "node:path";
|
|
6
|
-
import
|
|
7
|
-
import type { PluginHandlerContext } from "@getpaseo/plugin/server";
|
|
8
|
-
import type {
|
|
8
|
+
import {
|
|
9
9
|
acquireControlRpc,
|
|
10
10
|
applyDevicePresetRpc,
|
|
11
11
|
attachBrowserRpc,
|
|
@@ -18,15 +18,15 @@ import type {
|
|
|
18
18
|
sendBrowserInputRpc,
|
|
19
19
|
} from "../shared/browser";
|
|
20
20
|
import type { JsonValue } from "./runtime-protocol";
|
|
21
|
-
import { resolveSupervisorPaths } from "./supervisor";
|
|
22
21
|
import { SupervisorClient } from "./supervisor-client";
|
|
22
|
+
import { resolveSupervisorPaths } from "./supervisor";
|
|
23
23
|
|
|
24
|
+
export { SessionManager, normalizeBrowserUrl } from "./browser-policy";
|
|
24
25
|
export type {
|
|
25
26
|
BrowserRuntimeClient,
|
|
26
27
|
SessionManagerOptions,
|
|
27
28
|
WorkspaceValidator,
|
|
28
29
|
} from "./browser-policy";
|
|
29
|
-
export { normalizeBrowserUrl, SessionManager } from "./browser-policy";
|
|
30
30
|
|
|
31
31
|
type AttachInput = RpcInput<typeof attachBrowserRpc>;
|
|
32
32
|
type AttachOutput = RpcOutput<typeof attachBrowserRpc>;
|
package/server/mcp-entry.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { homedir } from "node:os";
|
|
2
|
-
import { join } from "node:path";
|
|
3
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import type { JsonValue } from "./runtime-protocol";
|
|
7
|
-
import { resolveSupervisorPaths } from "./supervisor";
|
|
8
7
|
import { AgentSupervisorClient } from "./supervisor-client";
|
|
8
|
+
import { resolveSupervisorPaths } from "./supervisor";
|
|
9
9
|
|
|
10
10
|
const TICKET_ENV = "PASEO_SHARED_BROWSER_TICKET";
|
|
11
11
|
const MIN_VIEWPORT = { width: 320, height: 480 } as const;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
1
|
import { readFile, stat } from "node:fs/promises";
|
|
3
2
|
import { createConnection, type Socket } from "node:net";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
4
|
import {
|
|
5
|
+
RUNTIME_PROTOCOL_VERSION,
|
|
6
|
+
RuntimeProtocolError,
|
|
7
|
+
isRuntimeResponse,
|
|
5
8
|
type AgentBrowserOperation,
|
|
6
9
|
type BridgeLease,
|
|
7
|
-
isRuntimeResponse,
|
|
8
10
|
type JsonValue,
|
|
9
|
-
RUNTIME_PROTOCOL_VERSION,
|
|
10
11
|
type RuntimeDescriptor,
|
|
11
|
-
RuntimeProtocolError,
|
|
12
12
|
type RuntimeRequest,
|
|
13
13
|
type RuntimeResponse,
|
|
14
14
|
type RuntimeResult,
|
package/server/supervisor.ts
CHANGED
|
@@ -7,15 +7,15 @@ import type { BrowserFrame, BrowserInputEvent, BrowserState, Viewport } from "..
|
|
|
7
7
|
import { SessionManager } from "./browser-policy";
|
|
8
8
|
import { CdpUnknownOutcomeError } from "./cdp";
|
|
9
9
|
import {
|
|
10
|
-
type BridgeLease,
|
|
11
10
|
DEFAULT_BRIDGE_HEARTBEAT_MS,
|
|
12
11
|
DEFAULT_BRIDGE_TIMEOUT_MS,
|
|
13
12
|
DEFAULT_ORPHAN_GRACE_MS,
|
|
14
|
-
type JsonValue,
|
|
15
|
-
parseRuntimeRequest,
|
|
16
13
|
RUNTIME_PROTOCOL_VERSION,
|
|
17
|
-
type RuntimeDescriptor,
|
|
18
14
|
RuntimeProtocolError,
|
|
15
|
+
parseRuntimeRequest,
|
|
16
|
+
type BridgeLease,
|
|
17
|
+
type JsonValue,
|
|
18
|
+
type RuntimeDescriptor,
|
|
19
19
|
type RuntimeRequest,
|
|
20
20
|
type RuntimeResponse,
|
|
21
21
|
type RuntimeResult,
|