harness: wally openwork with every RunAnywhere model
wally openwork -m <model> opens the OpenWork desktop app (different-ai/openwork) with every RunAnywhere model in its model picker.
How it works: wally builds an opencode config and hands it to the app in OPENCODE_CONFIG_CONTENT. OpenWork passes its environment to the opencode 1.18.33 engine it bundles, and that engine merges the variable last, after OpenWork's own config file. The hosted catalog goes under runanywhere. A local -m starts the kit server on loopback and adds runanywhere-local beside the hosted list. The launched model is selected.
The app runs as a second instance on a profile under the state dir (openwork/). Its Electron data, runtime DB, server settings, opencode history and workspace all live there, so the user's own OpenWork, opencode history and home folder are never written. The profile is kept between runs.
Two OpenWork defaults are switched off for that profile, both found by running it:
- A fresh profile sends chats to OpenWork's opencode 2 engine, which gets an allowlisted environment and never sees the provider.
OPENWORK_ENGINE_V2_PREVIEW=offandOPENWORK_ENGINE_AUTO_UPGRADE=0keep chats on the v1 engine. - With no workspace list, OpenWork creates
~/OpenWork Chatin the real home. wally writes a list naming its own folder first, using OpenWork's id scheme (ws_+ sha256(path)[:12]).
The provider declares X-RA-Harness: opencode, because the contract has no openwork value yet. On macOS a missing app gets a brew install --cask openwork offer (never npm i openwork, which is a different project). Quitting the app ends the run, and Ctrl-C quits the app. open_code_provider was split out of build_open_code_config so both providers share one builder.
Tested on macOS arm64 with OpenWork 0.18.63:
tests/test_wally_openwork.rs: 9 hermetic tests (config, profile env, workspace id, app detection, launch command).tests/local_harness: a stand-inopenworkapp, signed out and signed in, plus the missing-app path.scripts/test/e2e-openwork.sh(opt-in,WALLY_E2E_OPENWORK=1): real app. 10 hosted models plus 1 local listed and connected, the launched one selected,pongback onrunanywhere-local/qwen3-4b-instruct-2507andrunanywhere/glm-5.3-flash, then a clean quit.wally models list --cloudshows 11; the 11th iseve, a decision model kept out on purpose.- ctest (6/6), fmt, clippy
-D warnings, test ledger, agents sync, versions, sys bindings. - Goldens: the new command line shows up in the usual 31 root-list cases, plus
help__openworkandhelp__help__openwork.
Not done:
- GUI checks by a person (onboarding screen, picker, Ctrl-C, running beside an existing OpenWork).
- Windows: the install path
%LOCALAPPDATA%\Programs\OpenWork\OpenWork.exeis a guess, and nothing has run there. - Linux.
- The engine still writes its log to the real
~/.local/share/opencode/log, and the user's global~/.config/opencodeproviders show up next to ours.
Summary by cubic
Adds wally openwork -m <model>, which opens the OpenWork desktop app with every RunAnywhere model in its model picker. The app runs as a second instance on a private profile so the user's own OpenWork, opencode history, and home folder are never written.
Behavior
- The provider config goes in
OPENCODE_CONFIG_CONTENT: hosted models underrunanywhere, a local model starts the kit server and addsrunanywhere-local, with the launched model selected. An expired account token is refreshed first and the hosted endpoint passes the image gate. - The app is launched from its own executable rather than
open, so the profile environment (carrying the account token) reaches the child directly and the app stays wally's child: Ctrl-C reaches it and its exit ends the run. - Before the first launch the profile gets a workspace list that names its workspace exactly as OpenWork resolves it (canonicalized, native separators, Windows
\\?\prefix stripped), so no~/OpenWork Chatis created in the real home. - Two OpenWork defaults are switched off so chats stay on the opencode 1.x engine, which reads the variable before OpenWork's own config.
XDG_DATA_HOMEalso moves to the profile, so the engine's log and saved logins stay out of the real home. - The app is found by bundle ID on macOS,
WALLY_OPENWORK_APPpoints at any other install, and Linux looks only forOpenWork.AppImageon PATH (a bareopenworkis a different npm project). A missing app on macOS offersbrew install --cask openworkand nevernpm i openwork. - Quitting the app ends the run; Ctrl-C quits the app.
- Windows and Linux are not yet verified against a real install.
Summary by CodeRabbit
-
New Features
- Added
wally openworkto launch OpenWork with a local or hosted model, or without model configuration. OpenWork uses a separate persistent profile and workspace. - Added model selection and instructions for missing installations, including an optional Homebrew install on macOS.
- Updated command help and guides with usage examples.
- Added
-
Tests
- Added coverage for OpenWork launches, model configuration, app discovery, and missing-app handling, including an opt-in macOS end-to-end test.