Skip to content

a Bot can have its own screen, browser and profile on a computer several Bots share - #40

Merged
hexuria merged 1 commit into
mainfrom
gol/own-screen
Oct 10, 2026
Merged

hexuria merged 1 commit into
mainfrom
gol/own-screen

Conversation

@hexuria

@hexuria hexuria commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Box half of hexuria/opengrok-server#376. Stacked on #39: this branch includes its commit, so merge #39 first.

Why

Bots that share a computer share one screen, one Chromium, one profile and one keyboard. On 10 Oct, Bot A opened Facebook and Bot B showed Facebook too. The owner wants the shared screen to stay the default, with a Bot able to switch to its own screen, private sign-ins included, through a tool call or a switch in the app.

What

box-screen (new, /usr/local/bin/box-screen):

  • up <bot> is idempotent. It allocates slot N (from 2, kept in ~/.box-screens/ in the home volume) and starts the slot's pieces:
    • Xvfb :N;
    • xfwm4 --display=:N;
    • x11vnc on 127.0.0.1:590N, with the box's VNC password; its DISPLAY is :N, so box-release-keys releases keys on that screen.
  • It prints {"bot","slot","display","profile","running"}.
  • The Bot's Chromium is started by the server on that display, through box-chromium with BOX_DISPLAY=:N and BOX_CHROME_PROFILE=~/chrome-profile/bots/<bot>.
  • down <bot> stops the slot's Chromium, VNC, window manager and X server. It keeps the slot and the profile.
  • list shows every Bot's slot and whether its screen is running.
  • It allows at most BOX_MAX_OWN_SCREENS own screens (default 4), and answers why past that.
  • One box-screen runs at a time (flock). The processes it starts never inherit the lock.

Viewer: one websockify on 6080 for every screen (--token-plugin TokenFile, /tmp/box-vnc-tokens/).

  • Token sN reaches 590N.
  • A connection with no token is the shared screen, as before. The wrapper patches get_target, so a server that doesn't know about own screens keeps working.

CUA per screen:

  • Every /v1/cua/* route takes ?display=:N (CuaConfig::on, which takes only :N).
  • Without it, the routes act on the box's own display, unchanged.

Page-in-front per screen:

  • box-active-tab writes /tmp/box-active-tab.N.json for its Chromium's DISPLAY. The shared screen keeps /tmp/box-active-tab.json.
  • GET /v1/chrome/active-tab?display=:N reads it.
  • The shared screen is recognised by BOX_SHARED_DISPLAY, not BOX_DISPLAY, because a Bot's Chromium is started with its own BOX_DISPLAY. A live run caught that mistake.

Other changes:

Tests

New unit tests:

  • a_request_may_name_another_screen_of_the_box (only :N is taken; ; rm -rf / is refused);
  • each_screen_has_its_own_report;
  • a_client_on_another_screen_names_it_on_every_screen_call.

cargo test --workspace --no-fail-fast: everything passes except jail::tests::absolute_inside_ok, which fails only on macOS and predates this. Clippy -D warnings and fmt are clean.

Live check (throwaway container, this branch's image)

Step Result
box-screen up cw_bob, twice slot 2 (:2) both times, the second already running
shared page on :1, the Bot's page on :2 different screenshots (red "SHARED" vs blue "OWN")
Tab on :2 only shared report a.html, focus:"text" (untouched); own report b.html, focus:"password"
viewer no token → 101 + RFB (shared); s1 → shared; s2 → own; s9 → refused
down cw_bob the Bot's Chromium stopped, the shared Chromium still running, the slot kept

The server half (Screen on every screen call, the use_own_screen tool, PUT /coworkers/{id}/computer/screen) and the app's switch follow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant