@rasmusjosefsson/agent-qa 0.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/bin/agent-qa.js +121 -0
- package/bin/postinstall.js +39 -0
- package/package.json +35 -0
package/bin/agent-qa.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
// agent-qa Node launcher.
|
|
4
|
+
//
|
|
5
|
+
// Does TWO things, then execs the Rust binary:
|
|
6
|
+
//
|
|
7
|
+
// 1. Resolves the platform-specific agent-qa binary out of the matching
|
|
8
|
+
// optionalDependency (agent-qa-<os>-<arch>). Mirrors the esbuild /
|
|
9
|
+
// Biome / Turborepo pattern.
|
|
10
|
+
//
|
|
11
|
+
// 2. Resolves the sibling `agent-browser` npm dep via require.resolve
|
|
12
|
+
// and passes its absolute path to the Rust binary via the
|
|
13
|
+
// AGENT_BROWSER_BIN env var. The Rust process never walks
|
|
14
|
+
// node_modules — that breaks on pnpm symlinks and Yarn PnP.
|
|
15
|
+
//
|
|
16
|
+
// Env-var overrides (for local dev / CI):
|
|
17
|
+
// AGENT_QA_BINARY_PATH - bypass platform resolution, use this binary
|
|
18
|
+
// AGENT_BROWSER_BIN - bypass agent-browser resolution, use this binary
|
|
19
|
+
|
|
20
|
+
'use strict';
|
|
21
|
+
|
|
22
|
+
const { execFileSync } = require('node:child_process');
|
|
23
|
+
const { existsSync, chmodSync, accessSync, constants } = require('node:fs');
|
|
24
|
+
const { join, dirname } = require('node:path');
|
|
25
|
+
const { platform, arch } = require('node:os');
|
|
26
|
+
|
|
27
|
+
function detectMusl() {
|
|
28
|
+
if (platform() !== 'linux') return false;
|
|
29
|
+
try {
|
|
30
|
+
const { execSync } = require('node:child_process');
|
|
31
|
+
const out = execSync('ldd --version 2>&1 || true', { encoding: 'utf8' });
|
|
32
|
+
return out.toLowerCase().includes('musl');
|
|
33
|
+
} catch {
|
|
34
|
+
return existsSync('/lib/ld-musl-x86_64.so.1') || existsSync('/lib/ld-musl-aarch64.so.1');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function platformPackageName() {
|
|
39
|
+
const p = platform();
|
|
40
|
+
const a = arch();
|
|
41
|
+
const libc = detectMusl() ? '-musl' : '';
|
|
42
|
+
const osKey =
|
|
43
|
+
p === 'darwin' ? 'darwin' :
|
|
44
|
+
p === 'linux' ? `linux${libc}` :
|
|
45
|
+
p === 'win32' ? 'win32' :
|
|
46
|
+
null;
|
|
47
|
+
const archKey = a === 'x64' ? 'x64' : a === 'arm64' ? 'arm64' : null;
|
|
48
|
+
if (!osKey || !archKey) return null;
|
|
49
|
+
return { pkg: `@rasmusjosefsson/agent-qa-${osKey}-${archKey}`, exe: p === 'win32' ? '.exe' : '' };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function resolveAgentQaBinary() {
|
|
53
|
+
const override = process.env.AGENT_QA_BINARY_PATH;
|
|
54
|
+
if (override) return override;
|
|
55
|
+
|
|
56
|
+
const desc = platformPackageName();
|
|
57
|
+
if (!desc) {
|
|
58
|
+
throw new Error(`agent-qa: unsupported platform ${platform()}-${arch()}`);
|
|
59
|
+
}
|
|
60
|
+
let pkgJson;
|
|
61
|
+
try {
|
|
62
|
+
pkgJson = require.resolve(`${desc.pkg}/package.json`);
|
|
63
|
+
} catch {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`agent-qa: platform package "${desc.pkg}" not installed.\n` +
|
|
66
|
+
`It should have been pulled in as an optionalDependency.\n` +
|
|
67
|
+
`Try: npm install --force @rasmusjosefsson/agent-qa`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const bin = join(dirname(pkgJson), 'bin', `agent-qa-${desc.pkg.replace(/^@rasmusjosefsson\/agent-qa-/, '')}${desc.exe}`);
|
|
71
|
+
if (!existsSync(bin)) {
|
|
72
|
+
throw new Error(`agent-qa: binary missing at ${bin}`);
|
|
73
|
+
}
|
|
74
|
+
if (platform() !== 'win32') {
|
|
75
|
+
try { accessSync(bin, constants.X_OK); }
|
|
76
|
+
catch { try { chmodSync(bin, 0o755); } catch (e) {
|
|
77
|
+
throw new Error(`agent-qa: cannot make ${bin} executable: ${e.message}`);
|
|
78
|
+
} }
|
|
79
|
+
}
|
|
80
|
+
return bin;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function resolveAgentBrowserBin() {
|
|
84
|
+
const override = process.env.AGENT_BROWSER_BIN;
|
|
85
|
+
if (override) return override;
|
|
86
|
+
try {
|
|
87
|
+
const pkgJson = require.resolve('agent-browser/package.json');
|
|
88
|
+
// agent-browser's own bin-resolution logic decides the platform binary;
|
|
89
|
+
// we just hand it the parent dir as a hint via the env var. agent-browser
|
|
90
|
+
// ships its own launcher at <pkgdir>/bin/agent-browser.js which knows
|
|
91
|
+
// the per-platform name — but the Rust binary needs the *native* binary
|
|
92
|
+
// path. Re-derive it here using the same naming convention.
|
|
93
|
+
const p = platform();
|
|
94
|
+
const a = arch();
|
|
95
|
+
const libc = detectMusl() ? '-musl' : '';
|
|
96
|
+
const osKey =
|
|
97
|
+
p === 'darwin' ? 'darwin' :
|
|
98
|
+
p === 'linux' ? `linux${libc}` :
|
|
99
|
+
p === 'win32' ? 'win32' :
|
|
100
|
+
null;
|
|
101
|
+
const archKey = a === 'x64' ? 'x64' : a === 'arm64' ? 'arm64' : null;
|
|
102
|
+
const ext = p === 'win32' ? '.exe' : '';
|
|
103
|
+
if (!osKey || !archKey) return null;
|
|
104
|
+
const candidate = join(dirname(pkgJson), 'bin', `agent-browser-${osKey}-${archKey}${ext}`);
|
|
105
|
+
return existsSync(candidate) ? candidate : null;
|
|
106
|
+
} catch {
|
|
107
|
+
return null; // Rust binary will error on first use with a clear message.
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const binary = resolveAgentQaBinary();
|
|
113
|
+
const env = { ...process.env };
|
|
114
|
+
const ab = resolveAgentBrowserBin();
|
|
115
|
+
if (ab) env.AGENT_BROWSER_BIN = ab;
|
|
116
|
+
execFileSync(binary, process.argv.slice(2), { stdio: 'inherit', env });
|
|
117
|
+
} catch (err) {
|
|
118
|
+
if (err && err.status != null) process.exit(err.status);
|
|
119
|
+
console.error(err.message || err);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
// Best-effort postinstall: ensure the resolved platform binary is executable.
|
|
4
|
+
//
|
|
5
|
+
// Some package managers (notably bun, certain sandboxed installs) strip the
|
|
6
|
+
// exec bit on extracted files. The launcher will also chmod on first run,
|
|
7
|
+
// but doing it at install time gives a cleaner first-run experience.
|
|
8
|
+
//
|
|
9
|
+
// Failure is non-fatal — we never want a postinstall to break `npm i`.
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const { existsSync, chmodSync } = require('node:fs');
|
|
15
|
+
const { join, dirname } = require('node:path');
|
|
16
|
+
const { platform, arch } = require('node:os');
|
|
17
|
+
|
|
18
|
+
const p = platform();
|
|
19
|
+
if (p === 'win32') return;
|
|
20
|
+
|
|
21
|
+
const a = arch();
|
|
22
|
+
|
|
23
|
+
const osKey =
|
|
24
|
+
p === 'darwin' ? 'darwin' :
|
|
25
|
+
p === 'linux' ? 'linux' :
|
|
26
|
+
null;
|
|
27
|
+
const archKey = a === 'x64' ? 'x64' : a === 'arm64' ? 'arm64' : null;
|
|
28
|
+
if (!osKey || !archKey) return;
|
|
29
|
+
|
|
30
|
+
const pkgName = `@rasmusjosefsson/agent-qa-${osKey}-${archKey}`;
|
|
31
|
+
let pkgJson;
|
|
32
|
+
try { pkgJson = require.resolve(`${pkgName}/package.json`); } catch { return; }
|
|
33
|
+
const bin = join(dirname(pkgJson), 'bin', `agent-qa-${osKey}-${archKey}`);
|
|
34
|
+
if (existsSync(bin)) {
|
|
35
|
+
try { chmodSync(bin, 0o755); } catch { /* ignore */ }
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
// never throw from postinstall
|
|
39
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rasmusjosefsson/agent-qa",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.0.1",
|
|
7
|
+
"description": "Record and replay user journeys against any web app via CDP. Generic, plugin-based, vendor-neutral.",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/rasmusjosefsson/agent-qa.git"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"agent-qa": "bin/agent-qa.js"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"postinstall": "node bin/postinstall.js"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"bin/",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"agent-browser": "0.27.0"
|
|
25
|
+
},
|
|
26
|
+
"optionalDependencies": {
|
|
27
|
+
"@rasmusjosefsson/agent-qa-darwin-arm64": "0.0.1",
|
|
28
|
+
"@rasmusjosefsson/agent-qa-darwin-x64": "0.0.1",
|
|
29
|
+
"@rasmusjosefsson/agent-qa-linux-x64": "0.0.1",
|
|
30
|
+
"@rasmusjosefsson/agent-qa-win32-x64": "0.0.1"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
}
|
|
35
|
+
}
|