agent-browser-stealth 0.17.0-fork.2 → 0.24.0-fork.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.
Files changed (122) hide show
  1. package/README.md +1256 -240
  2. package/bin/agent-browser-darwin-arm64 +0 -0
  3. package/bin/agent-browser-darwin-x64 +0 -0
  4. package/bin/agent-browser-linux-arm64 +0 -0
  5. package/bin/agent-browser-linux-x64 +0 -0
  6. package/bin/agent-browser-win32-x64.exe +0 -0
  7. package/bin/agent-browser.js +13 -2
  8. package/extensions/tab-group-cdp/content-script.js +425 -0
  9. package/extensions/tab-group-cdp/icons/icon.svg +7 -0
  10. package/extensions/tab-group-cdp/manifest.json +34 -0
  11. package/extensions/tab-group-cdp/page-bridge.js +133 -0
  12. package/extensions/tab-group-cdp/service-worker.js +2249 -0
  13. package/extensions/tab-group-cdp/sidepanel.css +258 -0
  14. package/extensions/tab-group-cdp/sidepanel.html +28 -0
  15. package/extensions/tab-group-cdp/sidepanel.js +1225 -0
  16. package/package.json +17 -69
  17. package/scripts/build-all-platforms.sh +6 -0
  18. package/scripts/check-version-sync.js +14 -2
  19. package/scripts/copy-native.js +8 -50
  20. package/scripts/postinstall.js +149 -165
  21. package/scripts/windows-debug/provision.sh +220 -0
  22. package/scripts/windows-debug/run.sh +92 -0
  23. package/scripts/windows-debug/start.sh +43 -0
  24. package/scripts/windows-debug/stop.sh +28 -0
  25. package/scripts/windows-debug/sync.sh +27 -0
  26. package/skills/agent-browser/SKILL.md +256 -159
  27. package/skills/agent-browser/references/authentication.md +101 -0
  28. package/skills/agent-browser/references/commands.md +34 -2
  29. package/skills/agent-browser/references/snapshot-refs.md +25 -0
  30. package/skills/agentcore/SKILL.md +115 -0
  31. package/skills/dogfood/SKILL.md +4 -2
  32. package/skills/electron/SKILL.md +26 -2
  33. package/skills/slack/SKILL.md +0 -9
  34. package/skills/slack/references/slack-tasks.md +2 -8
  35. package/skills/vercel-sandbox/SKILL.md +280 -0
  36. package/bin/agent-browser-local +0 -0
  37. package/bin/agent-browser-stealth +0 -0
  38. package/bin/agent-browser-stealth.d +0 -1
  39. package/dist/action-policy.d.ts +0 -14
  40. package/dist/action-policy.d.ts.map +0 -1
  41. package/dist/action-policy.js +0 -253
  42. package/dist/action-policy.js.map +0 -1
  43. package/dist/actions.d.ts +0 -21
  44. package/dist/actions.d.ts.map +0 -1
  45. package/dist/actions.js +0 -2139
  46. package/dist/actions.js.map +0 -1
  47. package/dist/auth-cli.d.ts +0 -2
  48. package/dist/auth-cli.d.ts.map +0 -1
  49. package/dist/auth-cli.js +0 -97
  50. package/dist/auth-cli.js.map +0 -1
  51. package/dist/auth-vault.d.ts +0 -36
  52. package/dist/auth-vault.d.ts.map +0 -1
  53. package/dist/auth-vault.js +0 -125
  54. package/dist/auth-vault.js.map +0 -1
  55. package/dist/browser.d.ts +0 -665
  56. package/dist/browser.d.ts.map +0 -1
  57. package/dist/browser.js +0 -3210
  58. package/dist/browser.js.map +0 -1
  59. package/dist/confirmation.d.ts +0 -8
  60. package/dist/confirmation.d.ts.map +0 -1
  61. package/dist/confirmation.js +0 -30
  62. package/dist/confirmation.js.map +0 -1
  63. package/dist/daemon.d.ts +0 -78
  64. package/dist/daemon.d.ts.map +0 -1
  65. package/dist/daemon.js +0 -744
  66. package/dist/daemon.js.map +0 -1
  67. package/dist/diff.d.ts +0 -18
  68. package/dist/diff.d.ts.map +0 -1
  69. package/dist/diff.js +0 -271
  70. package/dist/diff.js.map +0 -1
  71. package/dist/domain-filter.d.ts +0 -28
  72. package/dist/domain-filter.d.ts.map +0 -1
  73. package/dist/domain-filter.js +0 -149
  74. package/dist/domain-filter.js.map +0 -1
  75. package/dist/encryption.d.ts +0 -73
  76. package/dist/encryption.d.ts.map +0 -1
  77. package/dist/encryption.js +0 -171
  78. package/dist/encryption.js.map +0 -1
  79. package/dist/ios-actions.d.ts +0 -11
  80. package/dist/ios-actions.d.ts.map +0 -1
  81. package/dist/ios-actions.js +0 -228
  82. package/dist/ios-actions.js.map +0 -1
  83. package/dist/ios-manager.d.ts +0 -266
  84. package/dist/ios-manager.d.ts.map +0 -1
  85. package/dist/ios-manager.js +0 -1073
  86. package/dist/ios-manager.js.map +0 -1
  87. package/dist/protocol.d.ts +0 -26
  88. package/dist/protocol.d.ts.map +0 -1
  89. package/dist/protocol.js +0 -990
  90. package/dist/protocol.js.map +0 -1
  91. package/dist/snapshot.d.ts +0 -67
  92. package/dist/snapshot.d.ts.map +0 -1
  93. package/dist/snapshot.js +0 -514
  94. package/dist/snapshot.js.map +0 -1
  95. package/dist/state-utils.d.ts +0 -77
  96. package/dist/state-utils.d.ts.map +0 -1
  97. package/dist/state-utils.js +0 -178
  98. package/dist/state-utils.js.map +0 -1
  99. package/dist/stealth.d.ts +0 -41
  100. package/dist/stealth.d.ts.map +0 -1
  101. package/dist/stealth.js +0 -1743
  102. package/dist/stealth.js.map +0 -1
  103. package/dist/stream-server.d.ts +0 -117
  104. package/dist/stream-server.d.ts.map +0 -1
  105. package/dist/stream-server.js +0 -309
  106. package/dist/stream-server.js.map +0 -1
  107. package/dist/types.d.ts +0 -973
  108. package/dist/types.d.ts.map +0 -1
  109. package/dist/types.js +0 -2
  110. package/dist/types.js.map +0 -1
  111. package/scripts/check-creepjs-headless.js +0 -137
  112. package/scripts/check-daemon-pid-recovery.js +0 -148
  113. package/scripts/check-sannysoft-webdriver.js +0 -112
  114. package/scripts/check-stealth-regression.js +0 -199
  115. package/scripts/check-turnstile-testkey.ts +0 -125
  116. package/scripts/clawhub-sync.sh +0 -27
  117. package/scripts/sync-upstream.sh +0 -142
  118. package/scripts/verify-bundled-binaries.js +0 -71
  119. package/scripts/verify-native-version.js +0 -48
  120. package/scripts/verify-packed-host-binary.js +0 -88
  121. package/scripts/verify-registry-host-binary.js +0 -120
  122. package/skills/agent-browser-stealth/SKILL.md +0 -127
@@ -1,125 +0,0 @@
1
- #!/usr/bin/env tsx
2
-
3
- /**
4
- * Deterministic Turnstile check using Cloudflare official testing sitekey.
5
- *
6
- * Usage:
7
- * pnpm run check:turnstile-testkey
8
- * pnpm run check:turnstile-testkey -- --headed
9
- */
10
-
11
- import http from 'node:http';
12
- import { BrowserManager } from '../src/browser.js';
13
-
14
- const args = process.argv.slice(2);
15
- const headed = args.includes('--headed');
16
- const waitMsRaw = args.includes('--wait-ms')
17
- ? args[args.indexOf('--wait-ms') + 1]
18
- : undefined;
19
- const waitMs = Number.isFinite(Number(waitMsRaw)) ? Number(waitMsRaw) : 9000;
20
-
21
- const html = `<!doctype html>
22
- <html lang="en">
23
- <head>
24
- <meta charset="utf-8" />
25
- <title>agent-browser turnstile testkey</title>
26
- </head>
27
- <body>
28
- <h1>Turnstile Testkey Probe</h1>
29
- <div class="cf-turnstile" data-sitekey="1x00000000000000000000AA" data-callback="onTurnstileToken"></div>
30
- <script>
31
- window.__turnstileToken = '';
32
- function onTurnstileToken(token) {
33
- window.__turnstileToken = token || '';
34
- }
35
- </script>
36
- <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
37
- </body>
38
- </html>`;
39
-
40
- function createServer(): Promise<http.Server> {
41
- const server = http.createServer((_, res) => {
42
- res.writeHead(200, {
43
- 'Content-Type': 'text/html; charset=utf-8',
44
- 'Cache-Control': 'no-store',
45
- });
46
- res.end(html);
47
- });
48
-
49
- return new Promise((resolve, reject) => {
50
- server.on('error', reject);
51
- server.listen(0, '127.0.0.1', () => resolve(server));
52
- });
53
- }
54
-
55
- function closeServer(server: http.Server): Promise<void> {
56
- return new Promise((resolve) => server.close(() => resolve()));
57
- }
58
-
59
- async function main(): Promise<void> {
60
- const server = await createServer();
61
- const address = server.address();
62
- if (!address || typeof address === 'string') {
63
- await closeServer(server);
64
- throw new Error('Unable to start local HTTP server for Turnstile probe');
65
- }
66
-
67
- const localUrl = `http://127.0.0.1:${address.port}/`;
68
- const browser = new BrowserManager();
69
-
70
- try {
71
- await browser.launch({
72
- id: 'turnstile-testkey',
73
- action: 'launch',
74
- browser: 'chromium',
75
- stealth: true,
76
- headless: !headed,
77
- });
78
-
79
- const page = browser.getPage();
80
- await page.goto(localUrl, { waitUntil: 'domcontentloaded', timeout: 45_000 });
81
- await page.waitForTimeout(waitMs);
82
-
83
- const result = await page.evaluate(() => {
84
- const hidden = document.querySelector('input[name="cf-turnstile-response"]') as
85
- | HTMLInputElement
86
- | null;
87
- const hiddenValue = hidden?.value || '';
88
- const callbackValue =
89
- typeof (window as any).__turnstileToken === 'string'
90
- ? (window as any).__turnstileToken
91
- : '';
92
- const token = hiddenValue || callbackValue || '';
93
-
94
- return {
95
- url: location.href,
96
- title: document.title || '',
97
- tokenLength: token.length,
98
- tokenSample: token.slice(0, 40),
99
- isDummyToken: token.includes('DUMMY'),
100
- hiddenFieldLength: hiddenValue.length,
101
- callbackLength: callbackValue.length,
102
- widgetCount: document.querySelectorAll('.cf-turnstile').length,
103
- };
104
- });
105
-
106
- const report = {
107
- timestamp: new Date().toISOString(),
108
- headed,
109
- waitMs,
110
- ok: result.isDummyToken,
111
- result,
112
- };
113
-
114
- console.log(JSON.stringify(report, null, 2));
115
- process.exit(result.isDummyToken ? 0 : 1);
116
- } finally {
117
- await browser.close().catch(() => {});
118
- await closeServer(server);
119
- }
120
- }
121
-
122
- main().catch((error) => {
123
- console.error(error instanceof Error ? error.message : String(error));
124
- process.exit(1);
125
- });
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
5
- cd "$ROOT_DIR"
6
- SKILL_NAME="agent-browser-stealth"
7
-
8
- if ! command -v pnpm >/dev/null 2>&1; then
9
- echo "pnpm is required for ClawHub sync"
10
- exit 1
11
- fi
12
-
13
- if [ ! -f "skills/${SKILL_NAME}/SKILL.md" ]; then
14
- echo "Missing skill file: skills/${SKILL_NAME}/SKILL.md"
15
- exit 1
16
- fi
17
-
18
- # Sync only this fork-owned skill to avoid permission errors on other skills.
19
- TMP_DIR="$(mktemp -d)"
20
- trap 'rm -rf "$TMP_DIR"' EXIT
21
- mkdir -p "$TMP_DIR/skills"
22
- cp -R "skills/${SKILL_NAME}" "$TMP_DIR/skills/${SKILL_NAME}"
23
-
24
- echo "Syncing local skill '${SKILL_NAME}' to ClawHub..."
25
- cd "$TMP_DIR"
26
- pnpm dlx clawhub@latest sync --all --root ./skills
27
- echo "ClawHub sync completed."
@@ -1,142 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- UPSTREAM_REMOTE="upstream"
5
- UPSTREAM_BRANCH="main"
6
- BASE_BRANCH="main"
7
- TRACK_BRANCH="upstream-main"
8
- SYNC_BRANCH=""
9
- PUSH_BRANCH=false
10
-
11
- usage() {
12
- cat <<'EOF'
13
- Synchronize upstream changes into a dedicated sync branch.
14
-
15
- Usage:
16
- ./scripts/sync-upstream.sh [options]
17
-
18
- Options:
19
- --push Push the created sync branch to origin
20
- --upstream-remote <name> Upstream remote name (default: upstream)
21
- --upstream-branch <name> Upstream branch to sync from (default: main)
22
- --base-branch <name> Local base branch for sync branch (default: main)
23
- --track-branch <name> Local branch tracking upstream (default: upstream-main)
24
- --sync-branch <name> Explicit sync branch name (default: sync/YYYY-MM-DD)
25
- -h, --help Show this help message
26
- EOF
27
- }
28
-
29
- while [[ $# -gt 0 ]]; do
30
- case "$1" in
31
- --push)
32
- PUSH_BRANCH=true
33
- shift
34
- ;;
35
- --upstream-remote)
36
- UPSTREAM_REMOTE="${2:-}"
37
- shift 2
38
- ;;
39
- --upstream-branch)
40
- UPSTREAM_BRANCH="${2:-}"
41
- shift 2
42
- ;;
43
- --base-branch)
44
- BASE_BRANCH="${2:-}"
45
- shift 2
46
- ;;
47
- --track-branch)
48
- TRACK_BRANCH="${2:-}"
49
- shift 2
50
- ;;
51
- --sync-branch)
52
- SYNC_BRANCH="${2:-}"
53
- shift 2
54
- ;;
55
- -h|--help)
56
- usage
57
- exit 0
58
- ;;
59
- *)
60
- echo "Unknown option: $1" >&2
61
- usage
62
- exit 1
63
- ;;
64
- esac
65
- done
66
-
67
- for var_name in UPSTREAM_REMOTE UPSTREAM_BRANCH BASE_BRANCH TRACK_BRANCH; do
68
- if [[ -z "${!var_name}" ]]; then
69
- echo "Error: ${var_name} cannot be empty." >&2
70
- exit 1
71
- fi
72
- done
73
-
74
- if [[ -n "$(git status --porcelain)" ]]; then
75
- echo "Error: working tree is not clean. Commit or stash changes first." >&2
76
- exit 1
77
- fi
78
-
79
- if ! git remote get-url "$UPSTREAM_REMOTE" >/dev/null 2>&1; then
80
- echo "Error: remote '$UPSTREAM_REMOTE' does not exist." >&2
81
- exit 1
82
- fi
83
-
84
- echo "Fetching upstream branch: ${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}"
85
- git fetch "$UPSTREAM_REMOTE" "$UPSTREAM_BRANCH"
86
-
87
- if git show-ref --verify --quiet "refs/heads/$TRACK_BRANCH"; then
88
- echo "Updating local track branch: $TRACK_BRANCH"
89
- git switch "$TRACK_BRANCH" >/dev/null
90
- git merge --ff-only "${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}"
91
- else
92
- echo "Creating local track branch: $TRACK_BRANCH"
93
- git branch "$TRACK_BRANCH" "${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}"
94
- fi
95
-
96
- echo "Switching to base branch: $BASE_BRANCH"
97
- git switch "$BASE_BRANCH" >/dev/null
98
-
99
- if git show-ref --verify --quiet "refs/remotes/origin/$BASE_BRANCH"; then
100
- echo "Fast-forwarding ${BASE_BRANCH} from origin/${BASE_BRANCH}"
101
- git fetch origin "$BASE_BRANCH"
102
- git merge --ff-only "origin/${BASE_BRANCH}"
103
- fi
104
-
105
- if [[ -z "$SYNC_BRANCH" ]]; then
106
- SYNC_BRANCH="sync/$(date +%F)"
107
- fi
108
-
109
- if git show-ref --verify --quiet "refs/heads/$SYNC_BRANCH"; then
110
- suffix=1
111
- while git show-ref --verify --quiet "refs/heads/${SYNC_BRANCH}-${suffix}"; do
112
- suffix=$((suffix + 1))
113
- done
114
- SYNC_BRANCH="${SYNC_BRANCH}-${suffix}"
115
- fi
116
-
117
- echo "Creating sync branch: $SYNC_BRANCH"
118
- git switch -c "$SYNC_BRANCH" "$BASE_BRANCH" >/dev/null
119
-
120
- merge_message="chore(sync): merge ${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH} into ${BASE_BRANCH}"
121
- echo "Merging $TRACK_BRANCH into $SYNC_BRANCH"
122
- if ! git merge --no-ff "$TRACK_BRANCH" -m "$merge_message"; then
123
- echo ""
124
- echo "Merge conflict detected. Resolve conflicts, then run:"
125
- echo " git add <resolved-files>"
126
- echo " git commit"
127
- if [[ "$PUSH_BRANCH" == true ]]; then
128
- echo " git push -u origin $SYNC_BRANCH"
129
- fi
130
- exit 1
131
- fi
132
-
133
- echo "Upstream merge completed on branch: $SYNC_BRANCH"
134
-
135
- if [[ "$PUSH_BRANCH" == true ]]; then
136
- echo "Pushing branch to origin: $SYNC_BRANCH"
137
- git push -u origin "$SYNC_BRANCH"
138
- echo "Done. Open a PR: ${SYNC_BRANCH} -> ${BASE_BRANCH}"
139
- else
140
- echo "Branch is local only. Push when ready:"
141
- echo " git push -u origin $SYNC_BRANCH"
142
- fi
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Verifies that all bundled platform binaries are present and embed the
5
- * package.json version string. This catches stale binary bundles where the
6
- * package version is bumped but one or more binaries were not rebuilt.
7
- */
8
-
9
- import { existsSync, readFileSync, statSync } from "fs";
10
- import { dirname, join } from "path";
11
- import { fileURLToPath } from "url";
12
-
13
- const __dirname = dirname(fileURLToPath(import.meta.url));
14
- const rootDir = join(__dirname, "..");
15
-
16
- const pkg = JSON.parse(readFileSync(join(rootDir, "package.json"), "utf8"));
17
- const expectedVersion = String(pkg.version || "").trim();
18
-
19
- if (!expectedVersion) {
20
- console.error("Error: package.json version is empty");
21
- process.exit(1);
22
- }
23
-
24
- const expectedBinaries = [
25
- "agent-browser-linux-x64",
26
- "agent-browser-linux-arm64",
27
- "agent-browser-win32-x64.exe",
28
- "agent-browser-darwin-x64",
29
- "agent-browser-darwin-arm64",
30
- ];
31
-
32
- const minSizeBytes = 100_000;
33
- const versionBytes = Buffer.from(expectedVersion, "utf8");
34
-
35
- let errors = 0;
36
-
37
- for (const name of expectedBinaries) {
38
- const binaryPath = join(rootDir, "bin", name);
39
- if (!existsSync(binaryPath)) {
40
- console.error(`ERROR: missing binary: bin/${name}`);
41
- errors += 1;
42
- continue;
43
- }
44
-
45
- const size = statSync(binaryPath).size;
46
- if (size < minSizeBytes) {
47
- console.error(
48
- `ERROR: binary too small: bin/${name} (${size} bytes, expected >= ${minSizeBytes})`
49
- );
50
- errors += 1;
51
- continue;
52
- }
53
-
54
- const bytes = readFileSync(binaryPath);
55
- if (!bytes.includes(versionBytes)) {
56
- console.error(
57
- `ERROR: stale binary version: bin/${name} does not contain "${expectedVersion}"`
58
- );
59
- errors += 1;
60
- continue;
61
- }
62
-
63
- console.log(`OK: bin/${name} matches version ${expectedVersion}`);
64
- }
65
-
66
- if (errors > 0) {
67
- console.error(`\nFound ${errors} binary validation issue(s).`);
68
- process.exit(1);
69
- }
70
-
71
- console.log(`\nAll bundled binaries match package.json version ${expectedVersion}.`);
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Verifies that the bundled native binary version matches package.json version.
5
- * This prevents publishing npm tarballs where package version and native binary
6
- * version drift (e.g. package is fork.8 but binary still reports fork.7).
7
- */
8
-
9
- import { existsSync, readFileSync } from 'fs';
10
- import { dirname, join } from 'path';
11
- import { fileURLToPath } from 'url';
12
- import { arch, platform } from 'os';
13
- import { execFileSync } from 'child_process';
14
-
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const projectRoot = join(__dirname, '..');
17
-
18
- const pkg = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8'));
19
- const expectedVersion = pkg.version;
20
-
21
- const ext = platform() === 'win32' ? '.exe' : '';
22
- const platformBinary = join(projectRoot, 'bin', `agent-browser-${platform()}-${arch()}${ext}`);
23
-
24
- if (!existsSync(platformBinary)) {
25
- console.error(`Error: native binary not found for current platform: ${platformBinary}`);
26
- console.error('Run `pnpm run build:native` before publishing.');
27
- process.exit(1);
28
- }
29
-
30
- let versionOutput = '';
31
- try {
32
- versionOutput = execFileSync(platformBinary, ['--version'], {
33
- encoding: 'utf8',
34
- stdio: ['ignore', 'pipe', 'pipe'],
35
- }).trim();
36
- } catch (error) {
37
- const message = error instanceof Error ? error.message : String(error);
38
- console.error(`Error: failed to execute native binary --version: ${message}`);
39
- process.exit(1);
40
- }
41
-
42
- if (!versionOutput.includes(expectedVersion)) {
43
- console.error(`Version mismatch: package.json=${expectedVersion}, native='${versionOutput}'.`);
44
- console.error('Run `pnpm run build:native` and retry publishing.');
45
- process.exit(1);
46
- }
47
-
48
- console.log(`✓ Native binary version matches package.json (${expectedVersion})`);
@@ -1,88 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Build an npm tarball locally and verify that the bundled host-platform native
5
- * binary reports the same version as package.json.
6
- *
7
- * This catches publish drifts where package.json is bumped but the embedded
8
- * binary still points to an older fork version.
9
- */
10
-
11
- import { existsSync, mkdtempSync, readFileSync, rmSync, unlinkSync } from 'fs';
12
- import { tmpdir } from 'os';
13
- import { dirname, join } from 'path';
14
- import { fileURLToPath } from 'url';
15
- import { execFileSync } from 'child_process';
16
-
17
- const __dirname = dirname(fileURLToPath(import.meta.url));
18
- const rootDir = join(__dirname, '..');
19
-
20
- const pkg = JSON.parse(readFileSync(join(rootDir, 'package.json'), 'utf8'));
21
- const expectedVersion = String(pkg.version || '').trim();
22
-
23
- if (!expectedVersion) {
24
- console.error('Error: package.json version is empty');
25
- process.exit(1);
26
- }
27
-
28
- const ext = process.platform === 'win32' ? '.exe' : '';
29
- const hostBinaryName = `agent-browser-${process.platform}-${process.arch}${ext}`;
30
-
31
- let tempDir = '';
32
- let packedTarball = '';
33
-
34
- try {
35
- const packRaw = execFileSync('npm', ['pack', '--json'], {
36
- cwd: rootDir,
37
- encoding: 'utf8',
38
- stdio: ['ignore', 'pipe', 'pipe'],
39
- });
40
- const parsed = JSON.parse(packRaw);
41
- const filename = parsed?.[0]?.filename;
42
- if (!filename || typeof filename !== 'string') {
43
- throw new Error(`unexpected npm pack output: ${packRaw}`);
44
- }
45
-
46
- packedTarball = join(rootDir, filename);
47
- if (!existsSync(packedTarball)) {
48
- throw new Error(`tarball not found: ${packedTarball}`);
49
- }
50
-
51
- tempDir = mkdtempSync(join(tmpdir(), 'ab-pack-verify-'));
52
- execFileSync('tar', ['-xzf', packedTarball, '-C', tempDir], {
53
- stdio: ['ignore', 'pipe', 'pipe'],
54
- });
55
-
56
- const packedRoot = join(tempDir, 'package');
57
- const packedPkg = JSON.parse(readFileSync(join(packedRoot, 'package.json'), 'utf8'));
58
- if (String(packedPkg.version || '').trim() !== expectedVersion) {
59
- throw new Error(
60
- `packed package.json version mismatch: expected ${expectedVersion}, got ${packedPkg.version}`
61
- );
62
- }
63
-
64
- const packedBinary = join(packedRoot, 'bin', hostBinaryName);
65
- if (!existsSync(packedBinary)) {
66
- throw new Error(`host binary missing in tarball: bin/${hostBinaryName}`);
67
- }
68
-
69
- const binaryVersion = execFileSync(packedBinary, ['--version'], {
70
- encoding: 'utf8',
71
- stdio: ['ignore', 'pipe', 'pipe'],
72
- }).trim();
73
-
74
- if (!binaryVersion.includes(expectedVersion)) {
75
- throw new Error(
76
- `tarball host binary version mismatch: expected ${expectedVersion}, got "${binaryVersion}"`
77
- );
78
- }
79
-
80
- console.log(`✓ Packed tarball host binary matches package.json (${expectedVersion})`);
81
- } catch (error) {
82
- const message = error instanceof Error ? error.message : String(error);
83
- console.error(`Error: ${message}`);
84
- process.exitCode = 1;
85
- } finally {
86
- if (tempDir) rmSync(tempDir, { recursive: true, force: true });
87
- if (packedTarball && existsSync(packedTarball)) unlinkSync(packedTarball);
88
- }
@@ -1,120 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Download the published npm tarball and verify that the bundled host-platform
5
- * native binary reports the expected package version.
6
- */
7
-
8
- import { createWriteStream, existsSync, mkdtempSync, readFileSync, rmSync, unlinkSync } from 'fs';
9
- import { tmpdir } from 'os';
10
- import { dirname, join } from 'path';
11
- import { fileURLToPath } from 'url';
12
- import { execFileSync } from 'child_process';
13
- import { get } from 'https';
14
-
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const rootDir = join(__dirname, '..');
17
-
18
- const pkg = JSON.parse(readFileSync(join(rootDir, 'package.json'), 'utf8'));
19
- const packageName = process.env.PACKAGE_NAME || pkg.name || 'agent-browser-stealth';
20
- const expectedVersion = process.env.EXPECTED_VERSION || pkg.version;
21
-
22
- if (!expectedVersion) {
23
- console.error('Error: expected version is empty');
24
- process.exit(1);
25
- }
26
-
27
- const ext = process.platform === 'win32' ? '.exe' : '';
28
- const hostBinaryName = `agent-browser-${process.platform}-${process.arch}${ext}`;
29
-
30
- function downloadFile(url, dest) {
31
- return new Promise((resolve, reject) => {
32
- const file = createWriteStream(dest);
33
-
34
- const request = (currentUrl) => {
35
- get(currentUrl, (response) => {
36
- if (response.statusCode === 301 || response.statusCode === 302) {
37
- request(response.headers.location);
38
- return;
39
- }
40
-
41
- if (response.statusCode !== 200) {
42
- reject(new Error(`Failed to download tarball: HTTP ${response.statusCode}`));
43
- return;
44
- }
45
-
46
- response.pipe(file);
47
- file.on('finish', () => {
48
- file.close();
49
- resolve();
50
- });
51
- }).on('error', (err) => {
52
- reject(err);
53
- });
54
- };
55
-
56
- request(url);
57
- });
58
- }
59
-
60
- let tempDir = '';
61
- let tarballPath = '';
62
-
63
- try {
64
- const tarballUrl = execFileSync(
65
- 'npm',
66
- ['view', `${packageName}@${expectedVersion}`, 'dist.tarball'],
67
- {
68
- cwd: rootDir,
69
- encoding: 'utf8',
70
- stdio: ['ignore', 'pipe', 'pipe'],
71
- }
72
- ).trim();
73
-
74
- if (!tarballUrl) {
75
- throw new Error(`could not resolve dist.tarball for ${packageName}@${expectedVersion}`);
76
- }
77
-
78
- tempDir = mkdtempSync(join(tmpdir(), 'ab-registry-verify-'));
79
- tarballPath = join(tempDir, 'package.tgz');
80
- await downloadFile(tarballUrl, tarballPath);
81
-
82
- execFileSync('tar', ['-xzf', tarballPath, '-C', tempDir], {
83
- stdio: ['ignore', 'pipe', 'pipe'],
84
- });
85
-
86
- const packedRoot = join(tempDir, 'package');
87
- const packedPkg = JSON.parse(readFileSync(join(packedRoot, 'package.json'), 'utf8'));
88
- if (String(packedPkg.version || '').trim() !== expectedVersion) {
89
- throw new Error(
90
- `registry package.json version mismatch: expected ${expectedVersion}, got ${packedPkg.version}`
91
- );
92
- }
93
-
94
- const packedBinary = join(packedRoot, 'bin', hostBinaryName);
95
- if (!existsSync(packedBinary)) {
96
- throw new Error(`host binary missing in registry tarball: bin/${hostBinaryName}`);
97
- }
98
-
99
- const binaryVersion = execFileSync(packedBinary, ['--version'], {
100
- encoding: 'utf8',
101
- stdio: ['ignore', 'pipe', 'pipe'],
102
- }).trim();
103
-
104
- if (!binaryVersion.includes(expectedVersion)) {
105
- throw new Error(
106
- `registry host binary version mismatch: expected ${expectedVersion}, got "${binaryVersion}"`
107
- );
108
- }
109
-
110
- console.log(
111
- `✓ Registry tarball host binary matches package.json (${packageName}@${expectedVersion})`
112
- );
113
- } catch (error) {
114
- const message = error instanceof Error ? error.message : String(error);
115
- console.error(`Error: ${message}`);
116
- process.exitCode = 1;
117
- } finally {
118
- if (tarballPath && existsSync(tarballPath)) unlinkSync(tarballPath);
119
- if (tempDir) rmSync(tempDir, { recursive: true, force: true });
120
- }