agent-browser-priv 0.28.0-priv.1 → 0.28.0-priv.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/README.md CHANGED
@@ -74,6 +74,12 @@ agent-browser upgrade
74
74
 
75
75
  Detects your installation method (npm, Homebrew, or Cargo) and runs the appropriate update command automatically.
76
76
 
77
+ `agent-browser doctor` reports the installed Patchright backend version, the
78
+ Patchright version pinned by the current `agent-browser` release, and npm latest
79
+ when network checks are enabled. Patchright updates are release-controlled:
80
+ after upgrading `agent-browser`, run `agent-browser install` to refresh the
81
+ backend to the version pinned by that release.
82
+
77
83
  ### Requirements
78
84
 
79
85
  - **Patchright backend** - Run `agent-browser install` to install pinned Patchright and its browser artifacts for the default local backend. Requires Node.js and npm for install and runtime launch.
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-browser-priv",
3
- "version": "0.28.0-priv.1",
3
+ "version": "0.28.0-priv.2",
4
4
  "description": "Browser automation CLI for AI agents",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.1.3",
@@ -29,7 +29,9 @@
29
29
  "build:docker": "docker build --platform linux/amd64 -t agent-browser-builder -f docker/Dockerfile.build .",
30
30
  "release": "pnpm run version:sync && pnpm run build:all-platforms",
31
31
  "postinstall": "node scripts/postinstall.js",
32
- "build:dashboard": "cd packages/dashboard && pnpm build"
32
+ "build:dashboard": "cd packages/dashboard && pnpm build",
33
+ "runtime:update-check": "node scripts/check-runtime-updates.mjs",
34
+ "runtime:update-patchright": "node scripts/update-patchright-version.mjs"
33
35
  },
34
36
  "keywords": [
35
37
  "browser",
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFileSync } from 'node:child_process';
4
+ import { readFileSync } from 'node:fs';
5
+ import { dirname, join } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const rootDir = join(dirname(fileURLToPath(import.meta.url)), '..');
9
+ const installRsPath = join(rootDir, 'cli/src/install.rs');
10
+ const trackingPath = join(rootDir, 'priv/version-tracking.json');
11
+
12
+ function readJson(path) {
13
+ return JSON.parse(readFileSync(path, 'utf8'));
14
+ }
15
+
16
+ function readPatchrightPin() {
17
+ const source = readFileSync(installRsPath, 'utf8');
18
+ const match = source.match(/pub const PATCHRIGHT_VERSION:\s*&str\s*=\s*"([^"]+)"/);
19
+ if (!match) {
20
+ throw new Error('Could not find PATCHRIGHT_VERSION in cli/src/install.rs');
21
+ }
22
+ return match[1];
23
+ }
24
+
25
+ function npmLatest(packageName) {
26
+ return execFileSync('npm', ['view', packageName, 'version'], {
27
+ cwd: rootDir,
28
+ encoding: 'utf8',
29
+ timeout: 20_000,
30
+ stdio: ['ignore', 'pipe', 'pipe'],
31
+ }).trim();
32
+ }
33
+
34
+ function upstreamTags() {
35
+ const output = execFileSync(
36
+ 'git',
37
+ [
38
+ 'ls-remote',
39
+ '--tags',
40
+ '--refs',
41
+ 'https://github.com/vercel-labs/agent-browser.git',
42
+ 'refs/tags/v*',
43
+ ],
44
+ {
45
+ cwd: rootDir,
46
+ encoding: 'utf8',
47
+ timeout: 20_000,
48
+ stdio: ['ignore', 'pipe', 'pipe'],
49
+ },
50
+ );
51
+ return output
52
+ .trim()
53
+ .split('\n')
54
+ .filter(Boolean)
55
+ .map((line) => line.split(/\s+/)[1]?.replace('refs/tags/', ''))
56
+ .filter(Boolean)
57
+ .filter((tag) => /^v\d+\.\d+\.\d+/.test(tag));
58
+ }
59
+
60
+ function parseVersion(version) {
61
+ const cleaned = version.replace(/^v/, '').split('-')[0];
62
+ const parts = cleaned.split('.').map((part) => Number.parseInt(part, 10));
63
+ return [parts[0] || 0, parts[1] || 0, parts[2] || 0];
64
+ }
65
+
66
+ function compareVersions(a, b) {
67
+ const pa = parseVersion(a);
68
+ const pb = parseVersion(b);
69
+ for (let i = 0; i < 3; i += 1) {
70
+ if (pa[i] !== pb[i]) return pa[i] - pb[i];
71
+ }
72
+ return a.localeCompare(b);
73
+ }
74
+
75
+ function latestTag(tags) {
76
+ if (tags.length === 0) return null;
77
+ return [...tags].sort(compareVersions).at(-1);
78
+ }
79
+
80
+ function buildReport() {
81
+ const tracking = readJson(trackingPath);
82
+ const patchrightPinned = readPatchrightPin();
83
+ const patchrightLatest = npmLatest('patchright');
84
+ const latestUpstreamTag = latestTag(upstreamTags());
85
+
86
+ return {
87
+ patchright: {
88
+ pinned: patchrightPinned,
89
+ latest: patchrightLatest,
90
+ outdated: patchrightPinned !== patchrightLatest,
91
+ tracking_matches_source: tracking.patchright_pin === patchrightPinned,
92
+ },
93
+ agent_browser: {
94
+ tracked_upstream_tag: tracking.agent_browser_upstream_tag,
95
+ latest_upstream_tag: latestUpstreamTag,
96
+ outdated: Boolean(
97
+ latestUpstreamTag &&
98
+ compareVersions(latestUpstreamTag, tracking.agent_browser_upstream_tag) > 0,
99
+ ),
100
+ },
101
+ tracking: {
102
+ path: 'priv/version-tracking.json',
103
+ policy: tracking.policy,
104
+ },
105
+ };
106
+ }
107
+
108
+ function printHuman(report) {
109
+ console.log('Runtime update check');
110
+ console.log('');
111
+ console.log(
112
+ `Patchright: pinned ${report.patchright.pinned}, npm latest ${report.patchright.latest}`,
113
+ );
114
+ console.log(
115
+ ` status: ${report.patchright.outdated ? 'outdated' : 'current'}`,
116
+ );
117
+ console.log(
118
+ ` tracking: ${report.patchright.tracking_matches_source ? 'matches source' : 'does not match source'}`,
119
+ );
120
+ console.log('');
121
+ console.log(
122
+ `agent-browser upstream: tracked ${report.agent_browser.tracked_upstream_tag}, latest ${report.agent_browser.latest_upstream_tag ?? 'unknown'}`,
123
+ );
124
+ console.log(
125
+ ` status: ${report.agent_browser.outdated ? 'sync available' : 'current'}`,
126
+ );
127
+ }
128
+
129
+ const report = buildReport();
130
+
131
+ if (process.argv.includes('--json')) {
132
+ console.log(JSON.stringify(report, null, 2));
133
+ } else {
134
+ printHuman(report);
135
+ }
136
+
137
+ if (!report.patchright.tracking_matches_source) {
138
+ process.exitCode = 1;
139
+ }
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFileSync } from 'node:child_process';
4
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
5
+ import { tmpdir } from 'node:os';
6
+ import { dirname, join } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const rootDir = join(dirname(fileURLToPath(import.meta.url)), '..');
10
+ const installRsPath = join(rootDir, 'cli/src/install.rs');
11
+ const trackingPath = join(rootDir, 'priv/version-tracking.json');
12
+
13
+ function usage() {
14
+ console.error('Usage: node scripts/update-patchright-version.mjs <version|latest>');
15
+ }
16
+
17
+ function npmLatest() {
18
+ return execFileSync('npm', ['view', 'patchright', 'version'], {
19
+ cwd: rootDir,
20
+ encoding: 'utf8',
21
+ timeout: 20_000,
22
+ stdio: ['ignore', 'pipe', 'pipe'],
23
+ }).trim();
24
+ }
25
+
26
+ function validateVersion(version) {
27
+ if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(version)) {
28
+ throw new Error(`Invalid Patchright version: ${version}`);
29
+ }
30
+ }
31
+
32
+ function buildPackageFiles(version) {
33
+ const packageJson = {
34
+ name: 'patchright',
35
+ private: true,
36
+ type: 'module',
37
+ dependencies: {
38
+ patchright: version,
39
+ },
40
+ };
41
+
42
+ const dir = mkdtempSync(join(tmpdir(), 'agent-browser-patchright-'));
43
+ try {
44
+ writeFileSync(join(dir, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\n`);
45
+ execFileSync(
46
+ 'npm',
47
+ [
48
+ 'install',
49
+ '--package-lock-only',
50
+ '--ignore-scripts',
51
+ '--omit=dev',
52
+ '--no-audit',
53
+ '--fund=false',
54
+ ],
55
+ {
56
+ cwd: dir,
57
+ stdio: 'inherit',
58
+ timeout: 60_000,
59
+ },
60
+ );
61
+ const packageLock = JSON.parse(readFileSync(join(dir, 'package-lock.json'), 'utf8'));
62
+ if (packageLock.packages?.['']) {
63
+ delete packageLock.packages[''].name;
64
+ }
65
+ return {
66
+ packageJson: `${JSON.stringify(packageJson, null, 2)}\n`,
67
+ packageLock: `${JSON.stringify(packageLock, null, 2)}\n`,
68
+ };
69
+ } finally {
70
+ rmSync(dir, { recursive: true, force: true });
71
+ }
72
+ }
73
+
74
+ function replaceRawString(source, name, value) {
75
+ const pattern = new RegExp(`let ${name} = r#"(.*?)"#;`, 's');
76
+ if (!pattern.test(source)) {
77
+ throw new Error(`Could not find raw string ${name} in cli/src/install.rs`);
78
+ }
79
+ return source.replace(pattern, `let ${name} = r#"${value}"#;`);
80
+ }
81
+
82
+ function updateInstallRs(version, packageJson, packageLock) {
83
+ let source = readFileSync(installRsPath, 'utf8');
84
+ source = source.replace(
85
+ /pub const PATCHRIGHT_VERSION:\s*&str\s*=\s*"[^"]+";/,
86
+ `pub const PATCHRIGHT_VERSION: &str = "${version}";`,
87
+ );
88
+ source = replaceRawString(source, 'package_json', packageJson);
89
+ source = replaceRawString(source, 'package_lock', packageLock);
90
+ writeFileSync(installRsPath, source);
91
+ }
92
+
93
+ function updateTracking(version) {
94
+ const tracking = JSON.parse(readFileSync(trackingPath, 'utf8'));
95
+ tracking.patchright_pin = version;
96
+ writeFileSync(trackingPath, `${JSON.stringify(tracking, null, 2)}\n`);
97
+ }
98
+
99
+ const requested = process.argv[2];
100
+ if (!requested) {
101
+ usage();
102
+ process.exit(1);
103
+ }
104
+
105
+ const version = requested === 'latest' ? npmLatest() : requested;
106
+ validateVersion(version);
107
+
108
+ const { packageJson, packageLock } = buildPackageFiles(version);
109
+ updateInstallRs(version, packageJson, packageLock);
110
+ updateTracking(version);
111
+
112
+ console.log(`Updated Patchright backend pin to ${version}`);
@@ -402,6 +402,8 @@ agent-browser doctor --json # structured output for programmatic co
402
402
  ```
403
403
 
404
404
  `doctor` auto-cleans stale socket/pid/version sidecar files on every run.
405
+ For the default Patchright backend, it also reports the installed Patchright
406
+ version, the release pin, and npm latest when network checks are enabled.
405
407
  Destructive actions require `--fix`. Exit code is `0` if all checks pass
406
408
  (warnings OK), `1` if any fail.
407
409