@phnx-labs/browser-cli 0.1.0
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/CHANGELOG.md +21 -0
- package/LICENSE +105 -0
- package/README.md +144 -0
- package/bin/browser.cjs +35 -0
- package/package.json +48 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
First standalone release of `@phnx-labs/browser-cli`, extracted from the
|
|
6
|
+
`agents browser` subsystem of agents-cli.
|
|
7
|
+
|
|
8
|
+
- Drive Chromium-family browsers (Chrome, Brave, Edge, Chromium, Comet) over the
|
|
9
|
+
Chrome DevTools Protocol, Firefox over WebDriver BiDi, and Arc over Apple
|
|
10
|
+
Events on macOS.
|
|
11
|
+
- Manage browser processes, tasks, tabs and network capture through a local IPC
|
|
12
|
+
service; keep a local action ledger and `browser sessions` history.
|
|
13
|
+
- Machine-local profiles with `cdp://`, `bidi=firefox-bidi://` and `ssh://`
|
|
14
|
+
endpoints; bind a task to a remote device with `--device` on `start`.
|
|
15
|
+
- No runtime dependency on agents-cli. The inherited context descriptor, event
|
|
16
|
+
stream and shared on-disk paths are the only seams (see docs/integration.md).
|
|
17
|
+
- Ship per-platform binaries (macOS arm64/x64, Linux arm64/x64, Windows x64) as
|
|
18
|
+
optional dependencies behind a small Node launcher. The build minifies,
|
|
19
|
+
obfuscates and bytecode-compiles the bundle; the npm tarball carries no
|
|
20
|
+
TypeScript sources or source maps. `scripts/verify-compiled.mjs` gates each
|
|
21
|
+
binary in CI.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, Apache 2.0 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-Apache-2.0
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Phoenix Horizon, Inc.
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
+
will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# browser-cli
|
|
2
|
+
|
|
3
|
+
`browser` drives real browsers from the command line — the same Chrome, Brave,
|
|
4
|
+
Edge, Chromium, Comet, Firefox or Arc you use by hand, with their profiles and
|
|
5
|
+
cookies. It manages the browser process, tabs and network capture through a
|
|
6
|
+
local IPC service, so a sequence of commands (`start`, `navigate`, `screenshot`,
|
|
7
|
+
`done`) acts on one persistent session instead of a fresh headless launch each
|
|
8
|
+
time. It talks to Chromium-family browsers over the Chrome DevTools Protocol,
|
|
9
|
+
Firefox over WebDriver BiDi, and Arc over Apple Events, and it can drive a
|
|
10
|
+
browser on another machine over SSH.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install -g @phnx-labs/browser-cli
|
|
16
|
+
browser --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
npm installs a small Node launcher plus one compiled binary for your platform
|
|
20
|
+
(macOS arm64/x64, Linux arm64/x64, or Windows x64). No TypeScript sources or
|
|
21
|
+
source maps ship in the package.
|
|
22
|
+
|
|
23
|
+
## First run
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
browser profiles create work --browser chromium
|
|
27
|
+
browser start --profile work
|
|
28
|
+
browser navigate https://example.com --profile work
|
|
29
|
+
browser screenshot -o shot.png
|
|
30
|
+
browser done --profile work
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`start` launches (or attaches to) the browser for a profile and opens a **task** —
|
|
34
|
+
a named browsing context with its own tabs and capture ledger. Page verbs like
|
|
35
|
+
`navigate` and `screenshot` attach to that task: they resolve the caller's live
|
|
36
|
+
task, or take `--task <id>` to pick one explicitly. `done` closes the task's
|
|
37
|
+
tabs; `browser stop` stops the whole service.
|
|
38
|
+
|
|
39
|
+
Run `browser --help` for the full verb list and `browser <verb> --help` for its
|
|
40
|
+
options.
|
|
41
|
+
|
|
42
|
+
## Profiles and endpoints
|
|
43
|
+
|
|
44
|
+
A **profile** names a browser, where it runs, and how to reach it. Profiles are
|
|
45
|
+
machine-local and stored under `~/.agents/devices/<machine>/agents.yaml`.
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
browser profiles create work --browser chrome # local Chrome, auto-assigned CDP port
|
|
49
|
+
browser profiles create hl --browser chromium --headless # headless Chromium
|
|
50
|
+
browser profiles list
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Each profile resolves to an endpoint:
|
|
54
|
+
|
|
55
|
+
- `cdp://127.0.0.1:9222` — a Chromium-family browser over the DevTools Protocol.
|
|
56
|
+
- `bidi=firefox-bidi://127.0.0.1:9674` — Firefox over WebDriver BiDi.
|
|
57
|
+
- `ssh://user@box?port=9222` — a browser on a remote host reached over SSH.
|
|
58
|
+
|
|
59
|
+
## Remote browsers
|
|
60
|
+
|
|
61
|
+
Bind a task to a browser on another machine with `--device` on `start`:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
browser start --device box --profile work
|
|
65
|
+
browser navigate https://example.com
|
|
66
|
+
browser screenshot -o shot.png
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`--device <alias>` resolves against `~/.ssh/config`, and against an inherited
|
|
70
|
+
context descriptor when the CLI runs under agents-cli. browser-cli itself does
|
|
71
|
+
not read a fleet registry. Use `--device local` to force the task onto this
|
|
72
|
+
machine. The device is bound once at `start`; page verbs run against the task's
|
|
73
|
+
bound device, so `--device` is only valid there.
|
|
74
|
+
|
|
75
|
+
## Using it through agents-cli
|
|
76
|
+
|
|
77
|
+
Agents CLI ships `agents browser` as a thin consumer of this binary. It forwards
|
|
78
|
+
every verb unchanged and adds the concerns it owns: fleet device discovery
|
|
79
|
+
(`--device` becomes an SSH target), agent-session identity, remote-control
|
|
80
|
+
consent, and cross-machine session history. The seam between the two — the
|
|
81
|
+
inherited context descriptor, the event stream, and the shared on-disk paths —
|
|
82
|
+
is documented in [docs/integration.md](docs/integration.md). The command
|
|
83
|
+
reference is [docs/browser.md](docs/browser.md).
|
|
84
|
+
|
|
85
|
+
## Platform support
|
|
86
|
+
|
|
87
|
+
| Platform | Architectures |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| macOS | arm64, x64 |
|
|
90
|
+
| Linux | arm64, x64 |
|
|
91
|
+
| Windows | x64 |
|
|
92
|
+
|
|
93
|
+
Chromium CDP, Firefox BiDi and SSH endpoints work on all three. Native Arc
|
|
94
|
+
control is macOS-only. Safari is not supported.
|
|
95
|
+
|
|
96
|
+
## Troubleshooting
|
|
97
|
+
|
|
98
|
+
- **Headless on Linux.** A headless Chromium or Brave needs the usual shared
|
|
99
|
+
libraries (fonts, `libnss3`, `libatk`, `libgbm`, and friends). Install your
|
|
100
|
+
distribution's chromium package to pull them in; a missing library shows up as
|
|
101
|
+
the browser process exiting immediately after `start`.
|
|
102
|
+
- **Port already in use.** Each profile binds a debugging port. If `start`
|
|
103
|
+
reports a squatted port, another browser or a stale process holds it — stop it,
|
|
104
|
+
or create the profile with a different `--endpoint`.
|
|
105
|
+
- **Comet and Arc.** Comet is driven as a Chromium-family browser over CDP and
|
|
106
|
+
works best as an attach-only profile against a browser you already launched.
|
|
107
|
+
Arc is always attach-only and reuses an open tab or Space rather than creating
|
|
108
|
+
one; it is macOS-only.
|
|
109
|
+
- **Service state.** `browser status` shows whether the IPC service is running
|
|
110
|
+
and lists active tasks. `browser stop` shuts the service down.
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
bash scripts/install.sh # install dependencies
|
|
116
|
+
bash scripts/test.sh # typecheck + tests
|
|
117
|
+
bash scripts/build.sh # compile this platform's binary into dist/
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`scripts/build.sh` bundles and minifies `src/`, obfuscates the bundle, then
|
|
121
|
+
compiles a bytecode binary per target. `scripts/verify-compiled.mjs` asserts the
|
|
122
|
+
shipped artifact behaves correctly and that source string literals do not survive
|
|
123
|
+
in plaintext. Run `dist/<platform>-<arch>/browser` directly during development.
|
|
124
|
+
|
|
125
|
+
Release with the repository's own script:
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
bash scripts/release.sh # print the release plan (dry run)
|
|
129
|
+
secrets exec npmjs.com -- bash scripts/release.sh --confirm
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Release requires a clean linked worktree at the reviewed `origin/main` commit. It
|
|
133
|
+
builds every platform, verifies packed file lists and immutable package
|
|
134
|
+
integrity, publishes the launcher and per-platform packages, and checks a
|
|
135
|
+
registry install.
|
|
136
|
+
|
|
137
|
+
Minification, obfuscation and bytecode compilation raise the bar for casual
|
|
138
|
+
inspection; they are not a guarantee against reverse engineering. Keep
|
|
139
|
+
credentials out of the binary.
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
Functional Source License 1.1 with an Apache 2.0 future grant
|
|
144
|
+
([FSL-1.1-Apache-2.0](LICENSE)).
|
package/bin/browser.cjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
const { spawn } = require('node:child_process');
|
|
4
|
+
const name = '@phnx-labs/browser-cli-' + process.platform + '-' + process.arch;
|
|
5
|
+
let executable;
|
|
6
|
+
try {
|
|
7
|
+
executable = require.resolve(name + '/' + (process.platform === 'win32' ? 'browser.exe' : 'browser'));
|
|
8
|
+
} catch {
|
|
9
|
+
console.error('browser: missing ' + name + '. Reinstall @phnx-labs/browser-cli with optional dependencies enabled.');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
const stdio = ['inherit', 'inherit', 'inherit'];
|
|
13
|
+
for (const key of ['BROWSER_CONTEXT_FD', 'BROWSER_EVENTS_FD']) {
|
|
14
|
+
if (process.env[key] === undefined) continue;
|
|
15
|
+
const fd = Number(process.env[key]);
|
|
16
|
+
if (!Number.isInteger(fd) || fd < 3 || fd > 16) {
|
|
17
|
+
console.error('browser: invalid ' + key);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
while (stdio.length <= fd) stdio.push('ignore');
|
|
21
|
+
stdio[fd] = fd;
|
|
22
|
+
}
|
|
23
|
+
const child = spawn(executable, process.argv.slice(2), { stdio, windowsHide: true });
|
|
24
|
+
child.on('error', error => { console.error('browser: ' + error.message); process.exitCode = 1; });
|
|
25
|
+
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
|
26
|
+
process.on(signal, () => child.kill(signal));
|
|
27
|
+
}
|
|
28
|
+
child.on('exit', (code, signal) => {
|
|
29
|
+
if (signal && process.platform !== 'win32') {
|
|
30
|
+
process.removeAllListeners(signal);
|
|
31
|
+
process.kill(process.pid, signal);
|
|
32
|
+
} else {
|
|
33
|
+
process.exitCode = code === null ? 1 : code;
|
|
34
|
+
}
|
|
35
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@phnx-labs/browser-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Drive real browsers over CDP, WebDriver BiDi and native Arc",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"browser": "bin/browser.cjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/browser.cjs",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE",
|
|
13
|
+
"CHANGELOG.md"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=22.5.0"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/phnx-labs/browser-cli.git"
|
|
21
|
+
},
|
|
22
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "bash scripts/build.sh",
|
|
25
|
+
"test": "bash scripts/test.sh"
|
|
26
|
+
},
|
|
27
|
+
"optionalDependencies": {
|
|
28
|
+
"@phnx-labs/browser-cli-darwin-arm64": "0.1.0",
|
|
29
|
+
"@phnx-labs/browser-cli-darwin-x64": "0.1.0",
|
|
30
|
+
"@phnx-labs/browser-cli-linux-arm64": "0.1.0",
|
|
31
|
+
"@phnx-labs/browser-cli-linux-x64": "0.1.0",
|
|
32
|
+
"@phnx-labs/browser-cli-win32-x64": "0.1.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@inquirer/prompts": "8.5.2",
|
|
36
|
+
"@types/bun": "1.3.10",
|
|
37
|
+
"@types/node": "26.1.0",
|
|
38
|
+
"@types/ws": "8.18.1",
|
|
39
|
+
"bun": "1.4.1",
|
|
40
|
+
"chalk": "5.6.2",
|
|
41
|
+
"commander": "15.0.0",
|
|
42
|
+
"javascript-obfuscator": "5.7.0",
|
|
43
|
+
"proper-lockfile": "4.1.2",
|
|
44
|
+
"typescript": "6.0.3",
|
|
45
|
+
"ws": "8.21.0",
|
|
46
|
+
"yaml": "2.9.0"
|
|
47
|
+
}
|
|
48
|
+
}
|