Repository navigation
feat(bwopencode2): add --serve to run the web UI server in the sandbox - #41
Closed
Stuart B. Wilkins (stuwilkins) wants to merge 2 commits into
Closed
Stuart B. Wilkins (stuwilkins) wants to merge 2 commits into
Stuart B. Wilkins (stuwilkins) wants to merge 2 commits into
Conversation
Runs opencode2 serve inside the sandbox on 127.0.0.1, so tools stay sandboxed, with one server per invocation on the first free port of a fixed range (24700-24709 by default) so one ssh_config block covers every session. The password is random for each session unless BWOPENCODE2_SERVE_PASSWORD is set, and reaches the server only as OPENCODE_PASSWORD. Ports are claimed with a host-side file so two launchers cannot pick the same one. --serve-ssh-config prints the matching ssh_config block. Assisted-by: opencode:claude-sonnet-5-5
There was a problem hiding this comment.
🔵 Needs a closer look
Port-claim races can allow concurrent launchers to select the same port, while host-agnostic claims on shared NFS homes can incorrectly delete remote claims or reserve free local ports.
No open issues 🎉
What changed in this PR
Adds bwopencode2 --serve to run the OpenCode web UI inside the existing sandbox, while preserving restrictions on shared, unsandboxed server access.
Changes:
- Adds loopback-only server startup with configurable port selection and host-side port claims.
- Adds per-session passwords, optional fixed passwords, and SSH forwarding instructions.
- Documents server usage, authentication trade-offs, limitations, and verification performed.
| File | Description |
|---|---|
docs/bw-wrappers.md |
Documents sandboxed web UI usage, port claims, passwords, and SSH tunnels. |
bin/bwopencode2 |
Implements serve options, port allocation, password handling, and sandbox launch integration. |
Review effort: Balanced
The web UI opens on a page that asks for a pairing link or the password, and opencode pair points at the shared service, which the wrapper refuses. Inside the sandbox a small wrapper now starts the server, waits for it, asks it for a pairing code and prints the link, so the browser can sign in without typing the password. The password reaches curl on stdin, never on a command line. Use password still works after the link expires. Assisted-by: opencode:claude-sonnet-5-5
Contributor
Author
|
Closing as now included in #37 with work by Thomas A Caswell (@tacaswell) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add
bwopencode2 --serve, which runs the OpenCode 2 web UI server inside thesandbox so it can be opened from a browser over an ssh tunnel.
Description
serve,--serverandpairstay refused: they reach a shared service thatruns tools outside any sandbox.
--serveis the one supported way to run aserver, and it runs
opencode2 serveinside the same sandbox, so tools staysandboxed.
127.0.0.1only.24700-24709by default(
BWOPENCODE2_SERVE_PORTS=LO-HIchanges it;--serve-port Npicks one). Therange is below the kernel's ephemeral range and clear of 49374, the shared
service.
--serve-ssh-configprints anssh_configblock with oneLocalForwardperport, so a single alias covers every session. The start-up message prints the
matching
ssh -Lcommand with the host fromhostname -f.BWOPENCODE2_SERVE_PASSWORDis set (at least 12 characters). It reaches the server only as
OPENCODE_PASSWORD, is never written to a file, and the host's ownOPENCODE_PASSWORDis still dropped.~/.local/state/bwopencode2/serve/(not mounted in the sandbox, no secret),so two launchers cannot pick the same port. Claims of dead processes are
removed.
--servetakes no opencode2 arguments and cannot be combined with--exec.Open questions for reviewers:
password. A random password limits that to its own session; a fixed
BWOPENCODE2_SERVE_PASSWORDis shared by every session that uses it. Is thefixed-password option worth keeping?
exec, so it cannot retry if another program takes theport just before the server binds it.
Documented in
docs/bw-wrappers.md.Testing
On
babelfish, with OpenCode 2.2.6:bash -n, shfmt, shellcheck and the other pre-commit hooks pass on thechanged files.
--serve-ssh-configoutput, and--serve --dry-run(port choice, redactedpassword, the
serve --hostname 127.0.0.1 --port Pcommand).skipping a claimed port, a busy port skipped, a stale claim reused, a busy
requested port failing, an exhausted range failing, short passwords and bad
ranges rejected.
opencode servewith isolated directories, queried with curl: 401without the password and 200 with it, the web page served without a
password, and
POST /api/pairgiving a one-time link that sets the cookieopencode_session_<port>.Not tested, because it needs a browser or a full launch: a real
bwopencode2 --serverun, the password prompt in the web UI, two sessions openin one browser, and whether the agent can see
OPENCODE_PASSWORDin itsenvironment.
Checklist
pixi run -e dev lintlocally (or wait for CI) — see.github/workflows/lint.ymlrunansibledeployment)