@madarco/agentbox 0.5.0 → 0.7.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.
Files changed (62) hide show
  1. package/dist/_cloud-attach-DMVH6GWO.js +12 -0
  2. package/dist/chunk-7KOEFGN2.js +1162 -0
  3. package/dist/chunk-7KOEFGN2.js.map +1 -0
  4. package/dist/chunk-I24B6AXR.js +600 -0
  5. package/dist/chunk-I24B6AXR.js.map +1 -0
  6. package/dist/chunk-NAVL4R34.js +7546 -0
  7. package/dist/chunk-NAVL4R34.js.map +1 -0
  8. package/dist/chunk-NW5NYTQM.js +1366 -0
  9. package/dist/chunk-NW5NYTQM.js.map +1 -0
  10. package/dist/chunk-UK72UQ5U.js +237 -0
  11. package/dist/chunk-UK72UQ5U.js.map +1 -0
  12. package/dist/chunk-V5KZGB5V.js +722 -0
  13. package/dist/chunk-V5KZGB5V.js.map +1 -0
  14. package/dist/cloud-poller-ZIWSADJB-JXFRJUEM.js +10 -0
  15. package/dist/dist-ETCFRVPA.js +423 -0
  16. package/dist/dist-QZGJIBT5.js +1339 -0
  17. package/dist/dist-QZGJIBT5.js.map +1 -0
  18. package/dist/dist-R67WMLCF.js +183 -0
  19. package/dist/dist-R67WMLCF.js.map +1 -0
  20. package/dist/index.js +4088 -1451
  21. package/dist/index.js.map +1 -1
  22. package/package.json +9 -4
  23. package/runtime/docker/Dockerfile.box +115 -19
  24. package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +34 -19
  25. package/runtime/docker/packages/ctl/dist/bin.cjs +10246 -758
  26. package/runtime/docker/packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup +13 -3
  27. package/runtime/docker/packages/sandbox-docker/scripts/agentbox-codex-hooks.json +37 -0
  28. package/runtime/docker/packages/sandbox-docker/scripts/agentbox-dockerd-start +87 -7
  29. package/runtime/docker/packages/sandbox-docker/scripts/agentbox-open +28 -0
  30. package/runtime/docker/packages/sandbox-docker/scripts/custom-system-CLAUDE.md +4 -9
  31. package/runtime/hetzner/agentbox-checkpoint-cleanup +52 -0
  32. package/runtime/hetzner/agentbox-codex-hooks.json +37 -0
  33. package/runtime/hetzner/agentbox-dockerd-start +132 -0
  34. package/runtime/hetzner/agentbox-open +28 -0
  35. package/runtime/hetzner/agentbox-setup-skill.md +196 -0
  36. package/runtime/hetzner/agentbox-vnc-start +77 -0
  37. package/runtime/hetzner/claude-managed-settings.json +54 -0
  38. package/runtime/hetzner/ctl.cjs +22350 -0
  39. package/runtime/hetzner/custom-system-CLAUDE.md +27 -0
  40. package/runtime/hetzner/scripts/install-box.sh +365 -0
  41. package/runtime/relay/bin.cjs +9182 -754
  42. package/share/agentbox-setup/SKILL.md +34 -19
  43. package/dist/chunk-6VTAPD4H.js +0 -507
  44. package/dist/chunk-6VTAPD4H.js.map +0 -1
  45. package/dist/chunk-7J5AJLWG.js +0 -238
  46. package/dist/chunk-7J5AJLWG.js.map +0 -1
  47. package/dist/chunk-FJNIFTWK.js +0 -523
  48. package/dist/chunk-FJNIFTWK.js.map +0 -1
  49. package/dist/chunk-HPZMD5DE.js +0 -106
  50. package/dist/chunk-HPZMD5DE.js.map +0 -1
  51. package/dist/chunk-PXUBE5KS.js +0 -2346
  52. package/dist/chunk-PXUBE5KS.js.map +0 -1
  53. package/dist/chunk-RFC5F5HR.js +0 -1709
  54. package/dist/chunk-RFC5F5HR.js.map +0 -1
  55. package/dist/create-AHZ3GVEZ-TGEDL7UX.js +0 -15
  56. package/dist/lifecycle-LFOL6YFM-TCHDX3J5.js +0 -38
  57. package/dist/state-KD7M46ZP-KHFTHFUS.js +0 -26
  58. package/dist/stats-Z4BVJODD-HEC4TMUZ.js +0 -19
  59. package/dist/stats-Z4BVJODD-HEC4TMUZ.js.map +0 -1
  60. /package/dist/{create-AHZ3GVEZ-TGEDL7UX.js.map → _cloud-attach-DMVH6GWO.js.map} +0 -0
  61. /package/dist/{lifecycle-LFOL6YFM-TCHDX3J5.js.map → cloud-poller-ZIWSADJB-JXFRJUEM.js.map} +0 -0
  62. /package/dist/{state-KD7M46ZP-KHFTHFUS.js.map → dist-ETCFRVPA.js.map} +0 -0
@@ -0,0 +1,27 @@
1
+ # AgentBox sandbox
2
+
3
+ You are running inside an AgentBox sandbox: a Linux Docker container with
4
+ docker-in-docker (run `docker` directly, no sudo).
5
+ Your user is `vscode` and you can use passwordless **sudo** to run commands as root.
6
+ `/workspace` is your own per-box git worktree on branch `agentbox/<box-name>`:
7
+ writes there stay in the container's writable layer and don't touch the host's working
8
+ tree.
9
+
10
+ You can save the current filesystem state to be reused by future boxes by
11
+ running `agentbox-ctl checkpoint --set-default`. This doesn't need to be confirmed by the user.
12
+
13
+ The main `.git/` is bind-mounted at the same absolute path as on
14
+ the host, so local commits show up in the host's `git log` immediately.
15
+ No SSH creds, no host gitconfig identity. For ops that need the user
16
+ (push, fetch from private remotes), use `agentbox-ctl git push|fetch|pull
17
+ -- <args>` — it RPCs to the host, which runs git with the real SSH agent.
18
+
19
+ For ad-hoc file transfers between this box and the host, use
20
+ `agentbox-ctl cp toHost <boxPath> <hostPath>` and
21
+ `agentbox-ctl cp fromHost <hostPath> <boxPath>` or `agentbox-ctl download claude` / `download env` /
22
+ `download config`. They RPC to the host and
23
+ ask the user for confirmation on the wrapper that runs `agentbox claude`;
24
+ deny returns exit 10 (`denied by user`).
25
+ Don't put any timeout on the command, it will run forever and the user will be notified through multiple channels.
26
+
27
+ Box identity: /etc/agentbox/box.env and the AGENTBOX_* env vars.
@@ -0,0 +1,365 @@
1
+ #!/usr/bin/env bash
2
+ # AgentBox Hetzner base-image installer.
3
+ #
4
+ # Idempotent shell-script mirror of `packages/sandbox-docker/Dockerfile.box`,
5
+ # run once on a freshly-booted Ubuntu 24.04 VPS during
6
+ # `agentbox prepare --provider hetzner`. After this script completes we
7
+ # `create_image` the VPS — that snapshot is what every per-box create boots
8
+ # from.
9
+ #
10
+ # Required inputs (already in place when this script runs):
11
+ # /tmp/agentbox-ctl -- prebuilt @agentbox/ctl bundle (cjs)
12
+ # /tmp/agentbox-vnc-start -- VNC startup helper
13
+ # /tmp/agentbox-dockerd-start -- DinD startup helper
14
+ # /tmp/agentbox-checkpoint-cleanup -- pre-snapshot cleanup helper
15
+ # /tmp/agentbox-open -- in-box xdg-open shim
16
+ # /tmp/agentbox-custom-CLAUDE.md -- /etc/claude-code/CLAUDE.md content
17
+ # /tmp/agentbox-managed-settings.json -- /etc/claude-code/managed-settings.json
18
+ # /tmp/agentbox-codex-hooks.json -- /usr/local/share/agentbox/codex-hooks.json
19
+ # /tmp/agentbox-setup-skill.md -- /usr/local/share/agentbox/setup-guide.md
20
+ #
21
+ # Output: noisy progress to stdout (the host streams it into
22
+ # ~/.agentbox/logs/prepare.log via the ssh exec). Each major step prints
23
+ # `>>> BEGIN <step>` and `<<< END <step>` so a tail-watcher can spot a hang.
24
+
25
+ set -euo pipefail
26
+
27
+ step() { printf '\n>>> BEGIN %s\n' "$1"; }
28
+ done_() { printf '<<< END %s\n' "$1"; }
29
+
30
+ if [ "$(id -u)" -ne 0 ]; then
31
+ echo "install-box.sh: must run as root (got uid $(id -u))" >&2
32
+ exit 64
33
+ fi
34
+
35
+ export DEBIAN_FRONTEND=noninteractive
36
+
37
+ step "wait for cloud-init"
38
+ # sshd is up via cloud-init's `users:` module before all of cloud-init's
39
+ # modules finish. Without this wait, our own `apt-get update` can race
40
+ # against cloud-init's apt operations (unattended-upgrades, etc.) and fail
41
+ # with "Could not get lock /var/lib/dpkg/lock-frontend".
42
+ cloud-init status --wait || true
43
+ done_ "wait for cloud-init"
44
+
45
+ step "apt update + base packages"
46
+ apt-get update
47
+ apt-get install -y --no-install-recommends \
48
+ curl ca-certificates gnupg
49
+ done_ "apt update + base packages"
50
+
51
+ step "Node 24 via NodeSource"
52
+ if ! command -v node >/dev/null 2>&1 || ! node --version | grep -qE '^v24\.'; then
53
+ curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
54
+ fi
55
+ done_ "Node 24 via NodeSource"
56
+
57
+ step "core runtime + tooling"
58
+ apt-get install -y --no-install-recommends \
59
+ fuse3 \
60
+ fuse-overlayfs \
61
+ rsync \
62
+ nodejs \
63
+ python3 \
64
+ python3-pip \
65
+ python3-venv \
66
+ build-essential \
67
+ git \
68
+ tmux \
69
+ vim \
70
+ libcap2-bin \
71
+ sudo \
72
+ locales \
73
+ bash-completion
74
+ # devcontainers/base bakes en_US.UTF-8; on plain Ubuntu we have to generate it
75
+ # ourselves so /etc/profile.d/agentbox.sh's LANG export doesn't surface a
76
+ # locale warning.
77
+ locale-gen en_US.UTF-8 >/dev/null 2>&1 || true
78
+ update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 >/dev/null 2>&1 || true
79
+ done_ "core runtime + tooling"
80
+
81
+ step "vscode user (UID 1000) + sudoers"
82
+ # The devcontainers base image creates `vscode` for us; on plain Ubuntu we
83
+ # do it ourselves. UID 1000 matches the docker provider so any path that
84
+ # bakes in /home/vscode (agentbox-ctl, /etc/profile.d/agentbox.sh, the
85
+ # credential symlinks, the in-box configs) Just Works regardless of provider.
86
+ if ! id vscode >/dev/null 2>&1; then
87
+ # Hetzner's stock images already create a sequenced UID 1000 user named
88
+ # `debian` / `ubuntu` depending on the distro stage. If something owns UID
89
+ # 1000 already, rename that account to `vscode` instead of failing — keeps
90
+ # any cloud-init-deposited files (authorized_keys) discoverable under the
91
+ # new home.
92
+ if existing="$(getent passwd 1000 | cut -d: -f1)"; then
93
+ if [ -n "$existing" ] && [ "$existing" != "vscode" ]; then
94
+ usermod -l vscode "$existing"
95
+ usermod -d /home/vscode -m vscode || true
96
+ groupmod -n vscode "$existing" 2>/dev/null || true
97
+ fi
98
+ fi
99
+ if ! id vscode >/dev/null 2>&1; then
100
+ useradd -m -u 1000 -s /bin/bash vscode
101
+ fi
102
+ fi
103
+ install -d -m 0755 -o vscode -g vscode /home/vscode
104
+ echo 'vscode ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/90-agentbox-vscode
105
+ chmod 0440 /etc/sudoers.d/90-agentbox-vscode
106
+ done_ "vscode user (UID 1000) + sudoers"
107
+
108
+ step "agentbox base dirs + /workspace ownership"
109
+ mkdir -p /workspace /run/agentbox /var/log/agentbox /etc/agentbox /etc/claude-code \
110
+ /usr/local/share/agentbox
111
+ chmod 755 /workspace
112
+ chown vscode:vscode /workspace /run/agentbox /var/log/agentbox
113
+ done_ "agentbox base dirs + /workspace ownership"
114
+
115
+ step "node setcap (port <1024 bind without root)"
116
+ NODE_BIN="$(readlink -f "$(command -v node)")"
117
+ setcap cap_net_bind_service=+ep "$NODE_BIN"
118
+ done_ "node setcap (port <1024 bind without root)"
119
+
120
+ step "corepack (pnpm + yarn shims)"
121
+ npm install -g corepack@latest
122
+ corepack enable pnpm yarn
123
+ done_ "corepack (pnpm + yarn shims)"
124
+
125
+ step "corepack cache dir (vscode-owned, prevents first-use ENOENT)"
126
+ sudo -u vscode -H mkdir -p /home/vscode/.cache/node/corepack
127
+ done_ "corepack cache dir (vscode-owned, prevents first-use ENOENT)"
128
+
129
+ step "git system-wide safe.directory"
130
+ git config --system --add safe.directory '*'
131
+ done_ "git system-wide safe.directory"
132
+
133
+ step "docker + iptables for in-VPS DinD"
134
+ apt-get install -y --no-install-recommends \
135
+ docker.io \
136
+ iptables
137
+ mkdir -p /etc/docker
138
+ printf '%s\n' '{ "iptables": true }' > /etc/docker/daemon.json
139
+ usermod -aG docker vscode
140
+ # In-VPS dockerd is launched by the cloud-provider scaffolding via
141
+ # `agentbox-dockerd-start` (the same script the docker provider uses), so the
142
+ # systemd `docker.service` shouldn't auto-start — we want the agentbox
143
+ # helper's storage-driver-probe + flag composition, not Ubuntu's defaults.
144
+ systemctl disable --now docker.service 2>/dev/null || true
145
+ systemctl disable --now docker.socket 2>/dev/null || true
146
+ done_ "docker + iptables for in-VPS DinD"
147
+
148
+ step "agentbox-ctl install"
149
+ install -m 0755 /tmp/agentbox-ctl /usr/local/bin/agentbox-ctl
150
+ done_ "agentbox-ctl install"
151
+
152
+ # === EARLY BAKE: helper scripts, baked configs, profile/sshd shims ===
153
+ # Originally these steps lived after Chromium download (which takes ~5min).
154
+ # We moved them up because — for reasons that didn't fully resolve in
155
+ # diagnostic runs — bash's set -x trace, the pipe-tee log capture, and any
156
+ # subsequent file system writes from this script silently stop emitting
157
+ # output after the long-running `playwright install chromium` exec, leaving
158
+ # the snapshot missing every file these steps would install. Running them
159
+ # *before* Chromium sidesteps the issue and keeps the snapshot complete.
160
+ # Tracked as Phase-7 follow-up in docs/hertzner_backlog.md.
161
+
162
+ step "baked helper scripts (vnc / dockerd / cleanup / xdg-open shim)"
163
+ install -m 0755 /tmp/agentbox-vnc-start /usr/local/bin/agentbox-vnc-start
164
+ install -m 0755 /tmp/agentbox-dockerd-start /usr/local/bin/agentbox-dockerd-start
165
+ install -m 0755 /tmp/agentbox-checkpoint-cleanup /usr/local/bin/agentbox-checkpoint-cleanup
166
+ install -m 0755 /tmp/agentbox-open /usr/local/bin/agentbox-open
167
+ ln -sf /usr/local/bin/agentbox-open /usr/local/bin/xdg-open
168
+ done_ "baked helper scripts (vnc / dockerd / cleanup / xdg-open shim)"
169
+
170
+ step "baked config files (claude / codex / setup guide / tmux.conf)"
171
+ install -m 0644 /tmp/agentbox-custom-CLAUDE.md /etc/claude-code/CLAUDE.md
172
+ install -m 0644 /tmp/agentbox-managed-settings.json /etc/claude-code/managed-settings.json
173
+ install -m 0644 /tmp/agentbox-codex-hooks.json /usr/local/share/agentbox/codex-hooks.json
174
+ install -m 0644 /tmp/agentbox-setup-skill.md /usr/local/share/agentbox/setup-guide.md
175
+
176
+ # tmux.conf — verbatim from Dockerfile.box.
177
+ cat > /etc/tmux.conf <<'TMUX'
178
+ set -g default-terminal "tmux-256color"
179
+ set -as terminal-overrides ",*:Tc"
180
+ set -as terminal-overrides ",*:RGB"
181
+ set -as terminal-features ",*:hyperlinks"
182
+ set -as terminal-features ",*:RGB"
183
+ set -g allow-passthrough on
184
+ set -g set-clipboard on
185
+ set -g extended-keys on
186
+ set -as terminal-features ",*:extkeys"
187
+ set -g mouse on
188
+ bind -T copy-mode WheelUpPane send -N2 -X scroll-up
189
+ bind -T copy-mode WheelDownPane send -N2 -X scroll-down
190
+ bind -T copy-mode-vi WheelUpPane send -N2 -X scroll-up
191
+ bind -T copy-mode-vi WheelDownPane send -N2 -X scroll-down
192
+ set -g history-limit 50000
193
+ set -g escape-time 0
194
+ TMUX
195
+ done_ "baked config files (claude / codex / setup guide / tmux.conf)"
196
+
197
+ step "credential pivot symlinks (vscode home)"
198
+ sudo -u vscode -H mkdir -p \
199
+ /home/vscode/.claude \
200
+ /home/vscode/.claude/skills/agentbox-setup \
201
+ /home/vscode/.codex \
202
+ /home/vscode/.local/share/opencode \
203
+ /home/vscode/.agentbox-creds/claude \
204
+ /home/vscode/.agentbox-creds/codex \
205
+ /home/vscode/.agentbox-creds/opencode
206
+ sudo -u vscode -H ln -sf /home/vscode/.agentbox-creds/claude/.credentials.json \
207
+ /home/vscode/.claude/.credentials.json
208
+ sudo -u vscode -H ln -sf /home/vscode/.agentbox-creds/codex/auth.json \
209
+ /home/vscode/.codex/auth.json
210
+ sudo -u vscode -H ln -sf /home/vscode/.agentbox-creds/opencode/auth.json \
211
+ /home/vscode/.local/share/opencode/auth.json
212
+ sudo -u vscode -H ln -sf /home/vscode/.claude/_claude.json /home/vscode/.claude.json
213
+
214
+ # `/agentbox-setup` skill — the in-box-only first-run wizard the setup
215
+ # prompt references. Docker's seedSetupSkillIntoVolume() (sandbox-docker/
216
+ # src/claude.ts) does this at create time via a helper container with the
217
+ # claude-config volume mounted. Hetzner doesn't have a shared volume — we
218
+ # bake it directly into the snapshot here so every box has it. The same
219
+ # content is also reachable as a static file at /usr/local/share/agentbox/
220
+ # setup-guide.md (referenced as fallback in the wizard initial prompt).
221
+ # `tar -xzf` of the host's ~/.claude in prepareHetzner extracts WITHOUT
222
+ # removing pre-existing files in the dest, so this skill survives the
223
+ # subsequent static-config bake.
224
+ sudo -u vscode -H cp /usr/local/share/agentbox/setup-guide.md \
225
+ /home/vscode/.claude/skills/agentbox-setup/SKILL.md
226
+ done_ "credential pivot symlinks (vscode home)"
227
+
228
+ step "login-shell shim (/etc/profile.d/agentbox.sh)"
229
+ cat > /etc/profile.d/agentbox.sh <<'PROFILE'
230
+ # Auto-loaded by login shells; box.env is written at create time.
231
+ if [ -r /etc/agentbox/box.env ]; then
232
+ set -a
233
+ . /etc/agentbox/box.env
234
+ set +a
235
+ fi
236
+ case ":$PATH:" in
237
+ *:/home/vscode/.local/bin:*) : ;;
238
+ *) PATH=/home/vscode/.local/bin:$PATH ;;
239
+ esac
240
+ export PATH
241
+ export COLORTERM=${COLORTERM:-truecolor}
242
+ export DISABLE_AUTOUPDATER=${DISABLE_AUTOUPDATER:-1}
243
+ export LANG=${LANG:-en_US.UTF-8}
244
+ export LC_ALL=${LC_ALL:-en_US.UTF-8}
245
+ export DISPLAY=${DISPLAY:-:1}
246
+ export AGENT_BROWSER_EXECUTABLE_PATH=${AGENT_BROWSER_EXECUTABLE_PATH:-/usr/local/bin/chromium}
247
+ export BROWSER=${BROWSER:-/usr/local/bin/agentbox-open}
248
+ PROFILE
249
+ chmod 0644 /etc/profile.d/agentbox.sh
250
+ done_ "login-shell shim (/etc/profile.d/agentbox.sh)"
251
+
252
+ step "sshd hardening drop-in"
253
+ cat > /etc/ssh/sshd_config.d/agentbox.conf <<'SSHD'
254
+ # Written by AgentBox install-box.sh — see plan §"safety model".
255
+ PasswordAuthentication no
256
+ PermitRootLogin no
257
+ PubkeyAuthentication yes
258
+ AllowUsers vscode
259
+ AllowTcpForwarding yes
260
+ GatewayPorts no
261
+ PermitTunnel no
262
+ X11Forwarding no
263
+ ChallengeResponseAuthentication no
264
+ KbdInteractiveAuthentication no
265
+ SSHD
266
+ # Don't reload sshd here — we still need root SSH for the rest of the
267
+ # install. The drop-in takes effect on next sshd restart (the snapshot will
268
+ # include it; the next boot reads it).
269
+ done_ "sshd hardening drop-in"
270
+
271
+ step "allow unprivileged user namespaces (sysctl drop-in)"
272
+ # Ubuntu 23.10+ / 24.04 enables an AppArmor knob that blocks unprivileged
273
+ # user namespaces, which Chromium's sandbox needs. Without this, every
274
+ # in-box `chromium` / `agent-browser` invocation dies with
275
+ # "FATAL: zygote_host_impl_linux.cc: No usable sandbox!". Docker boxes
276
+ # don't hit it because the host kernel running their containers is older
277
+ # (or they get the relaxed sysctl from the docker host). On a bare Ubuntu
278
+ # 24.04 Hetzner VPS we have to flip it ourselves.
279
+ #
280
+ # We flip both the modern knob (`apparmor_restrict_unprivileged_userns`)
281
+ # and the legacy `unprivileged_userns_clone` — the legacy one is already
282
+ # 1 on 24.04 but writing it costs nothing and keeps the drop-in valid if
283
+ # a future kernel hardens the default back to 0.
284
+ cat > /etc/sysctl.d/99-agentbox-userns.conf <<'SYSCTL'
285
+ # Written by AgentBox install-box.sh — Chromium needs unprivileged user
286
+ # namespaces for its sandbox; the VPS itself is the isolation boundary.
287
+ kernel.apparmor_restrict_unprivileged_userns = 0
288
+ kernel.unprivileged_userns_clone = 1
289
+ SYSCTL
290
+ chmod 0644 /etc/sysctl.d/99-agentbox-userns.conf
291
+ # Apply now too so the rest of this install (in particular `playwright
292
+ # install chromium`'s post-install probe) works without needing a reboot
293
+ # of the prepare VPS. The drop-in then re-applies on every boot of the
294
+ # baked snapshot.
295
+ sysctl -p /etc/sysctl.d/99-agentbox-userns.conf >/dev/null
296
+ done_ "allow unprivileged user namespaces (sysctl drop-in)"
297
+
298
+ # === END EARLY BAKE ===
299
+
300
+ step "VNC stack (TigerVNC + noVNC + websockify + autocutsel)"
301
+ apt-get install -y --no-install-recommends \
302
+ tigervnc-standalone-server tigervnc-common tigervnc-tools \
303
+ novnc websockify \
304
+ autocutsel xclip
305
+ mkdir -p /home/vscode/.vnc
306
+ chown -R vscode:vscode /home/vscode/.vnc
307
+ done_ "VNC stack (TigerVNC + noVNC + websockify + autocutsel)"
308
+
309
+ step "Chrome runtime libs"
310
+ apt-get install -y --no-install-recommends \
311
+ libnss3 libnspr4 libatk1.0-0t64 libatk-bridge2.0-0t64 libcups2t64 \
312
+ libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
313
+ libgbm1 libdrm2 libpango-1.0-0 libcairo2 libasound2t64 \
314
+ fonts-liberation xdg-utils
315
+ done_ "Chrome runtime libs"
316
+
317
+ step "agent-browser + playwright + portless (global npm)"
318
+ npm install -g agent-browser playwright portless
319
+ done_ "agent-browser + playwright + portless (global npm)"
320
+
321
+ step "Codex CLI prereqs (bubblewrap) + agent installs"
322
+ apt-get install -y --no-install-recommends bubblewrap
323
+ npm install -g @openai/codex opencode-ai
324
+ done_ "Codex CLI prereqs (bubblewrap) + agent installs"
325
+
326
+ step "Claude Code (native installer, run as vscode)"
327
+ # Anthropic's native installer drops `claude` at /home/vscode/.local/bin/.
328
+ # Run as vscode so the binary lands in the right home and is owned by the
329
+ # user that'll execute it. DISABLE_AUTOUPDATER is set globally via
330
+ # /etc/profile.d/agentbox.sh below.
331
+ sudo -u vscode -H bash -lc 'curl -fsSL https://claude.ai/install.sh | bash -s stable'
332
+ done_ "Claude Code (native installer, run as vscode)"
333
+
334
+ step "Chromium download via Playwright (as vscode)"
335
+ # Run the download as vscode so the cache lands under
336
+ # /home/vscode/.cache/ms-playwright. Resolve a stable symlink at
337
+ # /usr/local/bin/chromium so AGENT_BROWSER_EXECUTABLE_PATH stays predictable
338
+ # across Chromium revision bumps.
339
+ sudo -u vscode -H bash -lc 'playwright install chromium'
340
+ CHROME_BIN="$(sudo -u vscode -H bash -lc 'ls /home/vscode/.cache/ms-playwright/chromium-*/chrome-linux*/chrome 2>/dev/null | sort | tail -1')"
341
+ if [ -z "$CHROME_BIN" ] || [ ! -x "$CHROME_BIN" ]; then
342
+ echo "install-box.sh: could not resolve Playwright Chromium binary" >&2
343
+ exit 70
344
+ fi
345
+ ln -sf "$CHROME_BIN" /usr/local/bin/chromium
346
+ done_ "Chromium download via Playwright (as vscode)"
347
+
348
+ step "apt cleanup"
349
+ apt-get clean
350
+ rm -rf /var/lib/apt/lists/*
351
+ done_ "apt cleanup"
352
+
353
+ step "trim /tmp/agentbox-*"
354
+ # Keep the install script itself out of the trim list — it's referenced by
355
+ # the install log saved into the snapshot so a Phase-7-style diagnostic can
356
+ # re-read which lines actually executed against which source.
357
+ rm -f /tmp/agentbox-ctl /tmp/agentbox-vnc-start /tmp/agentbox-dockerd-start \
358
+ /tmp/agentbox-checkpoint-cleanup /tmp/agentbox-open \
359
+ /tmp/agentbox-custom-CLAUDE.md /tmp/agentbox-managed-settings.json \
360
+ /tmp/agentbox-codex-hooks.json /tmp/agentbox-setup-skill.md
361
+ # Move install-box.sh into the persistent location for diagnostics.
362
+ mv /tmp/agentbox-install.sh /var/log/agentbox/install-box.sh 2>/dev/null || true
363
+ done_ "trim /tmp/agentbox-*"
364
+
365
+ printf '\n*** install-box.sh: complete — VPS ready for create_image snapshot.\n'