browser-agent-server 1.0.3__tar.gz → 1.0.4__tar.gz
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.
- browser_agent_server-1.0.4/.github/workflows/deploy-ssh.yml +47 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/.github/workflows/release.yml +5 -20
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/CHANGELOG.md +15 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/PKG-INFO +1 -1
- browser_agent_server-1.0.4/docs/multi-project-cd.md +99 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/docs/publishing.md +3 -2
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/pyproject.toml +1 -1
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/uv.lock +1 -1
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/.github/workflows/ci.yml +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/.gitignore +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/AGENTS.md +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/LICENSE +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/README.md +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/docs/api.md +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/docs/architecture.md +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/docs/deployment.md +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/docs/security.md +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/docs/troubleshooting.md +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/src/browser_agent/__init__.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/src/browser_agent/chrome.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/src/browser_agent/cli.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/src/browser_agent/data/browser-agent.service +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/src/browser_agent/server.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/src/browser_agent/vision_agent.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/src/browser_agent/x11_input.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/tests/test_bezier.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/tests/test_chrome_state_dir.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/tests/test_cli.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/tests/test_client.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/tests/test_cloudflare.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/tests/test_http_api.py +0 -0
- {browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/tests/test_ws_frames.py +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: deploy-ssh (reusable)
|
|
2
|
+
|
|
3
|
+
# Push-style continuous deployment to self-hosted servers.
|
|
4
|
+
# Caller passes the app name; the server-side dispatcher /usr/local/bin/deploy-tools
|
|
5
|
+
# resolves it via /etc/deploy-tools.d/<app>.conf (install exact version → restart →
|
|
6
|
+
# healthcheck → auto-rollback). See docs/multi-project-cd.md.
|
|
7
|
+
#
|
|
8
|
+
# Caller:
|
|
9
|
+
# deploy:
|
|
10
|
+
# needs: pypi # or your publish job — deploy only what is published
|
|
11
|
+
# uses: vernikr/browser-agent/.github/workflows/deploy-ssh.yml@main
|
|
12
|
+
# with: { app: my-app, tag: ${{ github.ref_name }} }
|
|
13
|
+
# secrets: inherit # DEPLOY_SSH_KEY / DEPLOY_HOST / DEPLOY_USER
|
|
14
|
+
|
|
15
|
+
on:
|
|
16
|
+
workflow_call:
|
|
17
|
+
inputs:
|
|
18
|
+
app:
|
|
19
|
+
required: true
|
|
20
|
+
type: string
|
|
21
|
+
description: App name — must match /etc/deploy-tools.d/<app>.conf on the host
|
|
22
|
+
tag:
|
|
23
|
+
required: true
|
|
24
|
+
type: string
|
|
25
|
+
description: Git tag that triggered the release, e.g. v1.2.3
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
deploy:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
environment:
|
|
31
|
+
name: prod
|
|
32
|
+
steps:
|
|
33
|
+
# Plain ssh (no third-party action): this key is trusted to drive the prod host.
|
|
34
|
+
# Server side it is pinned to the dispatcher via authorized_keys forced command:
|
|
35
|
+
# command="/usr/local/bin/deploy-tools",no-pty,no-port-forwarding,no-agent-forwarding,no-X11-forwarding
|
|
36
|
+
- name: Deploy exact version to production
|
|
37
|
+
env:
|
|
38
|
+
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
39
|
+
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
|
40
|
+
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
|
41
|
+
run: |
|
|
42
|
+
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
|
43
|
+
printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/ci_deploy_key
|
|
44
|
+
chmod 600 ~/.ssh/ci_deploy_key
|
|
45
|
+
ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts 2>/dev/null
|
|
46
|
+
VER="${{ inputs.tag }}"; VER="${VER#v}"
|
|
47
|
+
ssh -i ~/.ssh/ci_deploy_key "$DEPLOY_USER@$DEPLOY_HOST" "deploy ${{ inputs.app }} $VER"
|
|
@@ -52,26 +52,11 @@ jobs:
|
|
|
52
52
|
|
|
53
53
|
deploy:
|
|
54
54
|
needs: pypi
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
# Plain ssh (no third-party action): this key is trusted to drive the prod host.
|
|
61
|
-
# Server side it is pinned to the single command via authorized_keys forced command:
|
|
62
|
-
# command="/usr/local/bin/deploy-browser-agent",no-pty,no-port-forwarding,...
|
|
63
|
-
- name: Deploy exact version to production
|
|
64
|
-
env:
|
|
65
|
-
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
66
|
-
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
|
67
|
-
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
|
68
|
-
run: |
|
|
69
|
-
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
|
70
|
-
printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/ci_deploy_key
|
|
71
|
-
chmod 600 ~/.ssh/ci_deploy_key
|
|
72
|
-
ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts 2>/dev/null
|
|
73
|
-
VER="${GITHUB_REF_NAME#v}"
|
|
74
|
-
ssh -i ~/.ssh/ci_deploy_key "$DEPLOY_USER@$DEPLOY_HOST" "deploy $VER"
|
|
55
|
+
uses: ./.github/workflows/deploy-ssh.yml
|
|
56
|
+
with:
|
|
57
|
+
app: browser-agent
|
|
58
|
+
tag: ${{ github.ref_name }}
|
|
59
|
+
secrets: inherit
|
|
75
60
|
|
|
76
61
|
github-release:
|
|
77
62
|
needs: build
|
|
@@ -5,6 +5,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [1.0.4] - 2026-10-10
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- CD generalized for multi-project use: the deploy job now calls the reusable
|
|
13
|
+
workflow `.github/workflows/deploy-ssh.yml`, and the server-side forced
|
|
14
|
+
command became a dispatcher (`deploy <app> <semver>`) driven by
|
|
15
|
+
`/etc/deploy-tools.d/*.conf` — playbook in docs/multi-project-cd.md.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- docs/multi-project-cd.md — how to wire any project on the same server for
|
|
20
|
+
push-style CD in ~20 minutes (checklist + agent prompt).
|
|
21
|
+
|
|
22
|
+
|
|
8
23
|
## [1.0.3] - 2026-10-10
|
|
9
24
|
|
|
10
25
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: browser-agent-server
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Real headful Chrome on Xvfb with a hardware-level X11 mouse, Cloudflare Turnstile auto-solve and zero-leak CDP. Localhost HTTP API + CLI + Python SDK.
|
|
5
5
|
Project-URL: Homepage, https://github.com/vernikr/browser-agent
|
|
6
6
|
Project-URL: Repository, https://github.com/vernikr/browser-agent
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Multi-project CD: push every release to production from CI
|
|
2
|
+
|
|
3
|
+
The deploy used for `browser-agent` generalizes to any number of projects on the same
|
|
4
|
+
server. This page is the one-stop playbook — give it (or the prompt at the bottom) to any
|
|
5
|
+
agent to wire up a new project in ~20 minutes.
|
|
6
|
+
|
|
7
|
+
## Architecture (once per server)
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
GitHub release.yml (tag push)
|
|
11
|
+
build → publish (OIDC, no tokens)
|
|
12
|
+
→ deploy job → reusable workflow deploy-ssh.yml
|
|
13
|
+
└─ ssh <ci-key>@host "deploy <app> <ver>"
|
|
14
|
+
└─ authorized_keys forced command → /usr/local/bin/deploy-tools
|
|
15
|
+
└─ /etc/deploy-tools.d/<app>.conf
|
|
16
|
+
└─ install exact version → restart unit → healthcheck → rollback
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- **One CI key serves all projects.** The key is pinned by a forced command to the
|
|
20
|
+
dispatcher; it cannot open a shell, forward ports, or run anything else.
|
|
21
|
+
- **The whitelist of deployable apps is the server itself**: an app exists iff a
|
|
22
|
+
root-owned `/etc/deploy-tools.d/<app>.conf` exists. Unknown names are rejected.
|
|
23
|
+
- **No public endpoint, no firewall changes** — push arrives over the SSH port that is
|
|
24
|
+
already open for admin access.
|
|
25
|
+
|
|
26
|
+
Server-side artifacts (already installed on 38.244.152.2; copy to a new host as-is):
|
|
27
|
+
|
|
28
|
+
- `/usr/local/bin/deploy-tools` — the generic dispatcher (protocol: `deploy <app> <semver>`;
|
|
29
|
+
legacy `deploy <semver>` works while exactly one app is configured).
|
|
30
|
+
- `/etc/deploy-tools.d/browser-agent.conf` — the reference app config.
|
|
31
|
+
- backups under `/root/bak/`.
|
|
32
|
+
|
|
33
|
+
## Per-project checklist (~20 min)
|
|
34
|
+
|
|
35
|
+
Prerequisites: the project is a package published from CI to a registry with OIDC
|
|
36
|
+
trusted publishing (same one-time registry setup as in `docs/publishing.md`), and it runs
|
|
37
|
+
on the server as a systemd unit with some health signal.
|
|
38
|
+
|
|
39
|
+
1. **Systemd unit** — the service must come up healthy after `systemctl restart`. Health
|
|
40
|
+
signal: either a JSON endpoint answering `"version": "X.Y.Z"` or a CLI
|
|
41
|
+
`myapp --version`. No JSON endpoint? Put `HEALTH_CMD=...` in the config.
|
|
42
|
+
2. **Server config** — create `/etc/deploy-tools.d/<app>.conf` (app name: `[a-z0-9-]+`):
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
INSTALLER=uv # uv (Python) | npm-global (Node)
|
|
46
|
+
PKG=<registry package name> # e.g. my-tool-server / @scope/my-tool
|
|
47
|
+
BIN=<executable name> # for uv tools (for --version); optional otherwise
|
|
48
|
+
UNIT=<systemd unit name>
|
|
49
|
+
STATUS_URL=http://127.0.0.1:PORT/status # OR: HEALTH_CMD='...'
|
|
50
|
+
HEALTH_FIELD=version
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Test on the host:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
SSH_ORIGINAL_COMMAND="deploy <app> <current-version>" /usr/local/bin/deploy-tools
|
|
57
|
+
# expect: "already on <ver> and healthy — nothing to do"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
3. **Registry/CI side already solved**: publish from `release.yml` exactly like this repo
|
|
61
|
+
(`pypi`/`npm` job first, so deploy only installs what already exists in the registry).
|
|
62
|
+
4. **Deploy job** in the project's `release.yml`:
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
deploy:
|
|
66
|
+
needs: <publish-job>
|
|
67
|
+
uses: vernikr/browser-agent/.github/workflows/deploy-ssh.yml@main
|
|
68
|
+
with:
|
|
69
|
+
app: <app>
|
|
70
|
+
tag: ${{ github.ref_name }}
|
|
71
|
+
secrets: inherit
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
5. **Repo secrets** (Settings → Secrets and variables → Actions): `DEPLOY_SSH_KEY`,
|
|
75
|
+
`DEPLOY_HOST`, `DEPLOY_USER` — the same values as in this repo (reusing the same
|
|
76
|
+
single-purpose key across repos is fine and simplifies rotation; rotate by replacing
|
|
77
|
+
the one `authorized_keys` line + the secret values).
|
|
78
|
+
6. **Smoke-release**: tag `vX.Y.Z+1`, watch the Actions tab — deploy should be green and
|
|
79
|
+
the unit should report the new version on its health endpoint.
|
|
80
|
+
|
|
81
|
+
Failure semantics: unreadable registry → retries; bad health → automatic reinstall of the
|
|
82
|
+
previous version, restart, re-check, and the CI job turns red. Everything is logged in the
|
|
83
|
+
GitHub job — no `journalctl` digging needed for routine failures.
|
|
84
|
+
|
|
85
|
+
## Agent prompt (copy-paste to configure a new project)
|
|
86
|
+
|
|
87
|
+
> Wire the `<PROJECT>` repo for push-style CD to our production server, following
|
|
88
|
+
> `vernikr/browser-agent/docs/multi-project-cd.md`: (1) on the server create
|
|
89
|
+
> `/etc/deploy-tools.d/<app>.conf` for unit `<UNIT>`, package `<PKG>` (`INSTALLER=uv|npm-global`),
|
|
90
|
+
> health via `STATUS_URL=<...>` or `HEALTH_CMD`, then smoke-test with
|
|
91
|
+
> `SSH_ORIGINAL_COMMAND="deploy <app> <current-version>" /usr/local/bin/deploy-tools`;
|
|
92
|
+
> (2) add a `deploy` job to `<PROJECT>`'s `release.yml` that `needs:` the publish job and
|
|
93
|
+
> calls `vernikr/browser-agent/.github/workflows/deploy-ssh.yml@main` with
|
|
94
|
+
> `with: { app: <app>, tag: github.ref_name }` and `secrets: inherit`;
|
|
95
|
+
> (3) add the repo secrets `DEPLOY_SSH_KEY` / `DEPLOY_HOST` / `DEPLOY_USER` (same values as
|
|
96
|
+
> in `vernikr/browser-agent`); (4) ship a patch release and confirm the deploy job is green
|
|
97
|
+
> and the unit reports the new version. Do not touch other services, firewall, or VPN units
|
|
98
|
+
> on the server; before modifying `authorized_keys` or the dispatcher, back the file up to
|
|
99
|
+
> `/root/bak/`.
|
|
@@ -47,5 +47,6 @@ tag version to the production host — no human SSH needed. Design:
|
|
|
47
47
|
target version. On healthcheck failure it reinstalls the previous version and restarts again.
|
|
48
48
|
- Idempotent: redeploying the version already running is a no-op success.
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
Scaling to more projects on the same server: the forced command now points at a generic
|
|
51
|
+
dispatcher — the full playbook (per-project checklist + an agent prompt) is
|
|
52
|
+
[docs/multi-project-cd.md](multi-project-cd.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "browser-agent-server"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.4"
|
|
4
4
|
description = "Real headful Chrome on Xvfb with a hardware-level X11 mouse, Cloudflare Turnstile auto-solve and zero-leak CDP. Localhost HTTP API + CLI + Python SDK."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
{browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/.github/ISSUE_TEMPLATE/bug_report.yml
RENAMED
|
File without changes
|
|
File without changes
|
{browser_agent_server-1.0.3 → browser_agent_server-1.0.4}/.github/ISSUE_TEMPLATE/feature_request.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|