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.
- package/README.md +1256 -240
- package/bin/agent-browser-darwin-arm64 +0 -0
- package/bin/agent-browser-darwin-x64 +0 -0
- package/bin/agent-browser-linux-arm64 +0 -0
- package/bin/agent-browser-linux-x64 +0 -0
- package/bin/agent-browser-win32-x64.exe +0 -0
- package/bin/agent-browser.js +13 -2
- package/extensions/tab-group-cdp/content-script.js +425 -0
- package/extensions/tab-group-cdp/icons/icon.svg +7 -0
- package/extensions/tab-group-cdp/manifest.json +34 -0
- package/extensions/tab-group-cdp/page-bridge.js +133 -0
- package/extensions/tab-group-cdp/service-worker.js +2249 -0
- package/extensions/tab-group-cdp/sidepanel.css +258 -0
- package/extensions/tab-group-cdp/sidepanel.html +28 -0
- package/extensions/tab-group-cdp/sidepanel.js +1225 -0
- package/package.json +17 -69
- package/scripts/build-all-platforms.sh +6 -0
- package/scripts/check-version-sync.js +14 -2
- package/scripts/copy-native.js +8 -50
- package/scripts/postinstall.js +149 -165
- package/scripts/windows-debug/provision.sh +220 -0
- package/scripts/windows-debug/run.sh +92 -0
- package/scripts/windows-debug/start.sh +43 -0
- package/scripts/windows-debug/stop.sh +28 -0
- package/scripts/windows-debug/sync.sh +27 -0
- package/skills/agent-browser/SKILL.md +256 -159
- package/skills/agent-browser/references/authentication.md +101 -0
- package/skills/agent-browser/references/commands.md +34 -2
- package/skills/agent-browser/references/snapshot-refs.md +25 -0
- package/skills/agentcore/SKILL.md +115 -0
- package/skills/dogfood/SKILL.md +4 -2
- package/skills/electron/SKILL.md +26 -2
- package/skills/slack/SKILL.md +0 -9
- package/skills/slack/references/slack-tasks.md +2 -8
- package/skills/vercel-sandbox/SKILL.md +280 -0
- package/bin/agent-browser-local +0 -0
- package/bin/agent-browser-stealth +0 -0
- package/bin/agent-browser-stealth.d +0 -1
- package/dist/action-policy.d.ts +0 -14
- package/dist/action-policy.d.ts.map +0 -1
- package/dist/action-policy.js +0 -253
- package/dist/action-policy.js.map +0 -1
- package/dist/actions.d.ts +0 -21
- package/dist/actions.d.ts.map +0 -1
- package/dist/actions.js +0 -2139
- package/dist/actions.js.map +0 -1
- package/dist/auth-cli.d.ts +0 -2
- package/dist/auth-cli.d.ts.map +0 -1
- package/dist/auth-cli.js +0 -97
- package/dist/auth-cli.js.map +0 -1
- package/dist/auth-vault.d.ts +0 -36
- package/dist/auth-vault.d.ts.map +0 -1
- package/dist/auth-vault.js +0 -125
- package/dist/auth-vault.js.map +0 -1
- package/dist/browser.d.ts +0 -665
- package/dist/browser.d.ts.map +0 -1
- package/dist/browser.js +0 -3210
- package/dist/browser.js.map +0 -1
- package/dist/confirmation.d.ts +0 -8
- package/dist/confirmation.d.ts.map +0 -1
- package/dist/confirmation.js +0 -30
- package/dist/confirmation.js.map +0 -1
- package/dist/daemon.d.ts +0 -78
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js +0 -744
- package/dist/daemon.js.map +0 -1
- package/dist/diff.d.ts +0 -18
- package/dist/diff.d.ts.map +0 -1
- package/dist/diff.js +0 -271
- package/dist/diff.js.map +0 -1
- package/dist/domain-filter.d.ts +0 -28
- package/dist/domain-filter.d.ts.map +0 -1
- package/dist/domain-filter.js +0 -149
- package/dist/domain-filter.js.map +0 -1
- package/dist/encryption.d.ts +0 -73
- package/dist/encryption.d.ts.map +0 -1
- package/dist/encryption.js +0 -171
- package/dist/encryption.js.map +0 -1
- package/dist/ios-actions.d.ts +0 -11
- package/dist/ios-actions.d.ts.map +0 -1
- package/dist/ios-actions.js +0 -228
- package/dist/ios-actions.js.map +0 -1
- package/dist/ios-manager.d.ts +0 -266
- package/dist/ios-manager.d.ts.map +0 -1
- package/dist/ios-manager.js +0 -1073
- package/dist/ios-manager.js.map +0 -1
- package/dist/protocol.d.ts +0 -26
- package/dist/protocol.d.ts.map +0 -1
- package/dist/protocol.js +0 -990
- package/dist/protocol.js.map +0 -1
- package/dist/snapshot.d.ts +0 -67
- package/dist/snapshot.d.ts.map +0 -1
- package/dist/snapshot.js +0 -514
- package/dist/snapshot.js.map +0 -1
- package/dist/state-utils.d.ts +0 -77
- package/dist/state-utils.d.ts.map +0 -1
- package/dist/state-utils.js +0 -178
- package/dist/state-utils.js.map +0 -1
- package/dist/stealth.d.ts +0 -41
- package/dist/stealth.d.ts.map +0 -1
- package/dist/stealth.js +0 -1743
- package/dist/stealth.js.map +0 -1
- package/dist/stream-server.d.ts +0 -117
- package/dist/stream-server.d.ts.map +0 -1
- package/dist/stream-server.js +0 -309
- package/dist/stream-server.js.map +0 -1
- package/dist/types.d.ts +0 -973
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/scripts/check-creepjs-headless.js +0 -137
- package/scripts/check-daemon-pid-recovery.js +0 -148
- package/scripts/check-sannysoft-webdriver.js +0 -112
- package/scripts/check-stealth-regression.js +0 -199
- package/scripts/check-turnstile-testkey.ts +0 -125
- package/scripts/clawhub-sync.sh +0 -27
- package/scripts/sync-upstream.sh +0 -142
- package/scripts/verify-bundled-binaries.js +0 -71
- package/scripts/verify-native-version.js +0 -48
- package/scripts/verify-packed-host-binary.js +0 -88
- package/scripts/verify-registry-host-binary.js +0 -120
- 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
|
-
});
|
package/scripts/clawhub-sync.sh
DELETED
|
@@ -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."
|
package/scripts/sync-upstream.sh
DELETED
|
@@ -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
|
-
}
|