Repository navigation
fix(bwopencode2): persist TUI plugin state across sessions - #29
Merged
Dan Allan (danielballan) merged 1 commit intoOct 24, 2026
Merged
Dan Allan (danielballan) merged 1 commit into
Dan Allan (danielballan) merged 1 commit into
Conversation
The sandbox state directory is a tmpfs, so a dismissed Getting started box and the tab layout were lost on every launch. Bind only latest/tui from the host opencode2 state directory; locks and service files stay ephemeral. A directory is bound because OpenCode saves by rename, which fails on a bind-mounted file. Assisted-by: opencode:claude-sonnet-5-5
There was a problem hiding this comment.
🟡 Changes recommended
The new writable mount’s source validation can allow symlinks to expose protected host configuration.
No open issues 🎉
What changed in this PR
This PR updates bwopencode2 to preserve OpenCode 2’s TUI plugin state across sandbox sessions while keeping other state ephemeral.
Changes:
- Creates and binds the host
latest/tuidirectory to preserve dismissed onboarding boxes and tab layouts. - Documents the persistence boundary, leaving locks and background-service files ephemeral.
- Updates the AI disclosure metadata.
| File | Description |
|---|---|
| docs/bw-wrappers.md | Documents the persistent TUI mount and remaining ephemeral state. |
| bin/bwopencode2 | Adds TUI state path validation, directory creation, and a writable bind. |
| AI_DISCLOSURE.md | Updates the model list and disclosure date. |
Review effort: Balanced
Dan Allan (danielballan)
approved these changes
Oct 24, 2026
Stuart B. Wilkins (stuwilkins)
deleted the
fix/bwopencode2-persist-tui-state
branch
October 25, 2026 23:53
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.
What
Persist OpenCode 2's TUI plugin storage (
~/.local/state/opencode/latest/tui)across
bwopencode2launches by binding it from the host(
~/.local/state/opencode2/opencode/latest/tui, the location the ansibleopencode2wrapper uses). The rest of the state directory stays ephemeral.Why
$HOMEin the sandbox is a tmpfs, so everything under~/.local/state/opencodewas discarded on exit. That includes the TUI'splugin storage, so:
dismissed (users whose providers come from config rather than
/connectalways see it), and
tabs.json) is forgotten.How
resolve_opencode2_paths: addOC2_TUI_STATE_SRC/OC2_TUI_STATE_DIR,with a
_check_dir_safecheck on the host path.ensure_host_dirs: create the host directory (skipped on--dry-run).build_opencode2_state_dir: keep--dirfor the state dir, add--bindforlatest/tuionly.docs/bw-wrappers.md: mount table and text updated.Why only
latest/tuilocks/andlatest/locks/stay on tmpfs. This keeps the original reasonfor an ephemeral state dir: avoiding lock clashes on NFS homes.
host
opencode2.model.json,kv.json,prompt-history.jsonl) are notbound one by one. OpenCode saves by writing a temp file and renaming it over
the target, which fails (
EBUSY) on a bind-mounted single file. A directorybind does not have this problem.
latestis the release-channel directory name. Another channel would notbe persisted; this is noted in a code comment.
Testing
bash -n, and the repo's pre-commit hooks (shfmt, shellcheck,markdownlint, codespell, gitleaks) pass on the changed files.
bwopencode2 --dry-runshows--bind ~/.local/state/opencode2/opencode/latest/tui ~/.local/state/opencode/latest/tui.hidden and the tabs are restored.
AI disclosure
Written with OpenCode (claude-sonnet-5-5), reviewed by a human.
AI_DISCLOSURE.mdupdated.