# Plan: OpenCode Windows And WSL Support



* Status: Planned for a later cross-platform implementation pass
* Date: 2026-05-28
* Task: COL-133
* Related ADR: OpenCode Support Integration Contract

## Purpose

Define how Coldtea should support OpenCode on Windows before implementation
starts. This document is a planning contract, not an implementation change.

The goal is to preserve Coldtea's transparent terminal-host model while avoiding
silent assumptions that only work on macOS or Linux.

## Sources Checked

* OpenCode intro/install docs: [https://opencode.ai/docs/](https://opencode.ai/docs/)
* OpenCode Windows/WSL docs: [https://opencode.ai/docs/windows-wsl](https://opencode.ai/docs/windows-wsl)
* OpenCode config docs: [https://opencode.ai/docs/config/](https://opencode.ai/docs/config/)
* OpenCode CLI docs: [https://opencode.ai/docs/cli/](https://opencode.ai/docs/cli/)
* OpenCode troubleshooting docs: [https://opencode.ai/docs/troubleshooting/](https://opencode.ai/docs/troubleshooting/)
* Current Coldtea OpenCode ADR and QA runbook.
* Current Coldtea OpenCode code paths in `apps/desktop/src-tauri/src/agents/`,
  `apps/desktop/src-tauri/src/agent_enablement.rs`,
  `apps/desktop/src-tauri/src/agent_setup/`, and `terminal.rs`.

## Assumptions

* Coldtea remains PTY/TUI-first for OpenCode. Windows support must not replace
  the visible OpenCode TUI with SDK/server/ACP control.
* OpenCode's own docs recommend WSL for the best Windows experience, while
  native Windows installs are available through Chocolatey, Scoop, npm, Mise,
  Docker, or a release binary.
* Coldtea's first Windows implementation should optimize for one reliable path
  rather than trying PowerShell, cmd, Git Bash, native Node shims, and WSL at
  once.

## First-Pass Support Decision

First-pass Windows support for OpenCode should be **WSL-only**.

In scope:

* Detect WSL availability on native Windows.
* Detect `opencode` inside a selected WSL distro.
* Launch OpenCode inside that WSL distro in a real Coldtea PTY.
* Support projects stored in the WSL filesystem for the initial WSL release.
* Defer Windows drive projects mounted under `/mnt/<drive>/` until path
  conversion, read/write behavior, git behavior, and session metadata access are
  verified in a separate promotion step.
* Keep all OpenCode config, auth, plugins, sessions, and logs in the same WSL
  distro that runs `opencode`.
* Show clear UI/docs messaging when WSL or WSL OpenCode is missing.

Out of scope for the first pass:

* Native Windows OpenCode launch through PowerShell.
* Native Windows OpenCode launch through `cmd.exe`.
* Git Bash as a compatibility layer for native Windows OpenCode.
* Running or managing `opencode serve`, `opencode web`, SDK, or ACP as the
  default Windows path.
* Reading or mutating OpenCode provider credentials on any platform.

Native Windows OpenCode can be evaluated later, after the WSL path is stable and
manual QA proves OpenCode behaves consistently under ConPTY and Windows package
manager shims.

## User-Facing Behavior

On native Windows, the OpenCode launcher should report one of these states:

| State                                       | Expected message                                                                                                               |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| WSL unavailable                             | OpenCode support on Windows requires WSL in this version. Install WSL, install OpenCode in a WSL distro, then restart Coldtea. |
| WSL installed, no usable distro             | OpenCode support on Windows requires a configured WSL distro. Install or repair a WSL distro, then install OpenCode inside it. |
| WSL available, OpenCode missing in distro   | OpenCode was not found in the selected WSL distro. Open that distro and install OpenCode there.                                |
| Native OpenCode found, WSL OpenCode missing | Native Windows OpenCode is not supported by Coldtea yet. Install and run OpenCode from WSL for this version.                   |
| WSL OpenCode ready                          | OpenCode launches in WSL using the selected distro and project path.                                                           |

The UI must not silently offer a native Windows `opencode` binary as launchable
while the implementation only supports WSL. Native binaries should either be
ignored for OpenCode launch health or surfaced as an unsupported diagnostic.

## Platform-Specific OpenCode Paths

`opencode db path` is the source of truth for the database whenever possible.
The paths below are fallback locations and documentation references, not a reason
to bypass OpenCode's CLI when the CLI is available.

### macOS, Linux, And WSL

These paths apply inside the environment where `opencode` runs. For WSL, that
means inside the selected distro, not in the Windows user profile.

| Data           | Expected location                                                                 |
| -------------- | --------------------------------------------------------------------------------- |
| Global config  | `~/.config/opencode/opencode.json` or `opencode.jsonc`                            |
| TUI config     | `~/.config/opencode/tui.json`                                                     |
| Global plugins | `~/.config/opencode/plugins/`                                                     |
| Project config | `<project>/opencode.json`, `<project>/opencode.jsonc`, and `<project>/.opencode/` |
| Auth           | `~/.local/share/opencode/auth.json`                                               |
| DB fallback    | `~/.local/share/opencode/opencode.db`                                             |
| Logs           | `~/.local/share/opencode/log/`                                                    |
| Cache          | `~/.cache/opencode/`                                                              |
| Managed config | macOS: `/Library/Application Support/opencode/`; Linux: `/etc/opencode/`          |

Coldtea's WSL-managed wrapper/plugin files should also live inside the selected
WSL distro so OpenCode can read them without Windows path translation.

### Native Windows

Native Windows paths are documented here for future support and guardrails. They
are not first-pass launch targets.

| Data           | Expected location                                                                 |
| -------------- | --------------------------------------------------------------------------------- |
| Global config  | `%USERPROFILE%\.config\opencode\opencode.json` or `opencode.jsonc`                |
| TUI config     | `%USERPROFILE%\.config\opencode\tui.json`                                         |
| Global plugins | `%USERPROFILE%\.config\opencode\plugins\`                                         |
| Project config | `<project>\opencode.json`, `<project>\opencode.jsonc`, and `<project>\.opencode\` |
| Auth           | `%USERPROFILE%\.local\share\opencode\auth.json`                                   |
| DB fallback    | `%USERPROFILE%\.local\share\opencode\opencode.db`                                 |
| Logs           | `%USERPROFILE%\.local\share\opencode\log\`                                        |
| Cache          | `%USERPROFILE%\.cache\opencode\`                                                  |
| Managed config | `%ProgramData%\opencode`                                                          |

Coldtea must treat these as OpenCode-owned locations. It can resolve them for
health checks, docs, or read-only session metadata, but it must not write
provider credentials or broad user config there.

## Shell Behavior Contract

### Unix Shells

macOS/Linux behavior remains unchanged:

* Launch through the user's shell with Coldtea's existing shell integration.
* Prefer zsh/bash wrapper paths when available.
* Preserve user `OPENCODE_CONFIG`, `OPENCODE_TUI_CONFIG`,
  `OPENCODE_CONFIG_DIR`, and `OPENCODE_CONFIG_CONTENT` values.
* Use Coldtea-managed `OPENCODE_CONFIG_DIR` and session-scoped
  `OPENCODE_CONFIG_CONTENT` only when doing so does not clobber user values.

### WSL Shells

WSL launch should be an explicit runtime, not an accidental fallback through the
Windows process `PATH`.

Expected behavior:

* Detect distros with `wsl.exe --list --quiet` or equivalent Windows API.
* Resolve `opencode` by running a command inside the selected distro, for
  example a login-compatible `sh`/`bash` command that executes
  `command -v opencode`.
* Launch through `wsl.exe` into the selected distro and run OpenCode inside a
  Linux shell. Do not launch a Windows shim that happens to call WSL.
* Install or expose Coldtea's OpenCode plugin/wrapper files inside the WSL
  filesystem.
* Resolve `opencode db path` inside the same distro before reading session
  metadata.
* Translate paths only at process boundaries:
  * Windows host path to WSL path for `cwd` when launching.
  * WSL path to a Windows-readable UNC path only if the native Windows process
    must read a file directly.

If path translation fails, the launcher should fail actionably instead of
falling back to a different shell or project directory.

### Windows Drive Projects Under WSL

Projects mounted from Windows drives, such as `/mnt/c/...`, are deferred for the
initial WSL release. The first supported WSL milestone should require projects
to live in the WSL filesystem, for example under `~/code/`.

Promote `/mnt/<drive>/` projects only after QA verifies all of the following in
the same WSL distro:

* Windows host path to WSL `cwd` conversion.
* File read/write behavior through OpenCode tools.
* Git status, branch, and worktree behavior.
* Coldtea file watching and editor path handling.
* `opencode db path`, session list, resume, fork, and delete behavior.
* Failure copy when a Windows path cannot be converted or accessed from WSL.

### PowerShell

PowerShell is out of scope for first-pass OpenCode launch.

Future native support must not reuse POSIX wrapper scripts. It should use either
PowerShell-native wrapper logic or direct process launch with explicit environment
variables. Quoting, `.ps1` execution policy, `opencode.cmd` shims, and provider
environment inheritance need separate tests.

### cmd.exe

`cmd.exe` is out of scope for first-pass OpenCode launch.

Future native support needs dedicated handling for `.cmd`/`.bat` shims,
`PATHEXT`, percent-style environment expansion, and argument quoting. It should
not inherit Unix shell assumptions like `exec`, `command -v`, `$HOME`, or
single-quote shell escaping.

### Git Bash

Git Bash is out of scope for first-pass OpenCode launch.

OpenCode exposes `OPENCODE_GIT_BASH_PATH` for Windows shell configuration, but
Coldtea should not treat Git Bash as equivalent to WSL. If Git Bash support is
added later, it should be a native Windows mode with its own QA matrix and clear
copy.

## Implementation Guardrails

Before Windows/WSL implementation starts, introduce a runtime boundary so agent
code does not scatter platform checks across unrelated modules.

Recommended shape:

* Add an `AgentRuntime` or equivalent abstraction for:
  * detection command execution;
  * launch command construction;
  * shell integration paths;
  * OpenCode DB path resolution;
  * host/distro path translation;
  * delete/session commands.
* Model at least these runtimes:
  * `UnixHost` for current macOS/Linux behavior;
  * `WindowsWsl` for first-pass Windows support;
  * `WindowsNativeUnsupported` for clear messaging;
  * a future `WindowsNative` only after native support is approved.
* Keep OpenCode-specific path fallbacks behind platform-aware helpers.
* Do not call `/bin/zsh`, `/bin/bash`, `/bin/sh`, `command -v`, or POSIX shell
  quoting helpers from native Windows code paths.
* Do not call Windows `where`, PowerShell, or `cmd.exe` from WSL runtime logic.
* Do not assume `HOME`, `XDG_CONFIG_HOME`, or `.local/share` identify the
  correct OpenCode profile when a native Windows process is managing a WSL
  OpenCode process.
* Do not read a WSL SQLite database through a Windows path until path conversion
  and file-locking behavior have been manually verified. If unsafe, return an
  empty session list with an actionable diagnostic rather than blocking launch.
* Keep native Windows OpenCode detection separate from launch availability so
  unsupported binaries do not appear as ready.

## QA Requirements

Add Windows/WSL scenarios to the OpenCode QA runbook before implementation is
accepted:

1. Native Windows with no WSL installed shows WSL-required messaging.
2. WSL installed but no distro configured shows setup-required messaging.
3. WSL distro installed but `opencode` missing shows install-in-WSL messaging.
4. Native Windows `opencode` installed, WSL `opencode` missing, stays
   unsupported for launch.
5. WSL `opencode` installed in a distro launches the native TUI in a Coldtea PTY.
6. A project under the WSL home filesystem launches with the correct Linux `cwd`.
7. A project under `/mnt/c/...` remains unsupported until the Windows-drive
   promotion checks above pass.
8. Coldtea MCP/startup prompt and OpenCode plugin events work from WSL without
   writing tokens into durable OpenCode config.
9. `opencode db path`, session listing, resume, fork, and delete operate inside
   the same WSL distro or fail safely with clear messaging.
10. macOS/Linux OpenCode behavior remains unchanged.

Native PowerShell, cmd, and Git Bash tests belong to a later native-Windows
support task, not the WSL first pass.

## Open Questions For Implementation

* How will users choose or remember a WSL distro when more than one is
  installed?
* Which release should promote Windows drive workspaces after the `/mnt/<drive>/`
  path-conversion, file, git, watcher, and session-metadata checks pass?
* Should session metadata read the WSL SQLite DB through `\\wsl$\...`, or should
  Coldtea use a WSL-side helper/CLI command to avoid host file-locking issues?
* Where should WSL-specific shell integration files be installed and versioned
  when the native Windows app manages multiple distros?
* What is the smallest supported Windows version/build for ConPTY + WSL launch?

## Acceptance Checklist

A future implementation can claim COL-133's plan is satisfied when:

* First-pass Windows support is explicitly WSL-only.
* The initial WSL project scope is explicitly WSL-filesystem-only, with
  `/mnt/<drive>/` projects deferred until promotion checks pass.
* Native Windows OpenCode is documented as unsupported for the first pass.
* Platform-specific OpenCode config/auth/plugin/DB paths are documented.
* Shell behavior for Unix, WSL, PowerShell, cmd, and Git Bash is explicit.
* Unsupported states have clear product copy.
* Follow-up implementation work has concrete platform guards and QA scenarios.
