Skip to content

fix(app): keep the new-session screen on its own side in Work - #263

Merged
quickbeard merged 3 commits into
mainfrom
fix/work-project-picker
Aug 18, 2026
Merged

quickbeard merged 3 commits into
mainfrom
fix/work-project-picker

Conversation

@quickbeard

@quickbeard quickbeard commented Aug 18, 2026 •

Copy link
Copy Markdown
Owner

Three fixes to the new-session screen when it is reached through the Work
tab. All of them are the same underlying miss: that screen did not know which
side it was on.

1. The project picker offered every server's projects

Opened from Work it listed the local machine's projects under a "Local Server"
heading beside the sandbox's own — and picking one started the session on the
local machine, outside any sandbox, with nothing on screen to say so.

createPromptProjectControls indexed server.list in four places (the grouped
project list, the two server lookups behind select/add, and the server field
the controls hand back). All four now read one memo:

serversForSide(server.list, sideForServer(projectServer()))

The side comes from the draft's own server (serverSDK().server) rather
than useWorkspaceSide(), because a draft route mounts its own server
(ResolvedDraftRoute in app.tsx) and the sidebar's side is not guaranteed to
agree with it.

With one server on the side the picker takes the same single-server branch Code
has always taken — no group headings, no server submenu — which is the correct
shape for a machine with one sandbox.

2. "Add project" browsed the inside of the sandbox

Adding a project to a sandbox means giving it a folder from this computer.
The menu entry ran upstream's directory picker against the server it is pointed
at, which for a sandbox is the guest's own filesystem — nothing the user has
ever put a project in.

On Work it now opens the mounts dialog the Work sidebar's add button already
opens, labelled Mount project like every other route to it
(sandbox.server.mounts). PromptProjectControls gains an optional mount
flag for the label; the three call sites (sidebar button, sidebar empty-state
prompt, this picker) share one useSandboxMountDialog() hook instead of
repeating the lazy import.

3. The "Local" workspace chip is now Code-only

That chip creates a git worktree on the server the session runs on —
Global.Path.data/worktree/<projectID> in
packages/opencode/src/worktree/index.ts. In a sandbox that is the guest's own
data dir, which is not one of the host folders the sandbox mounts
(packages/codev-sandbox/src/mounts.ts): the work happens where your editor
cannot see it, and a reset re-clones the guest disk and takes it along. The
chip meanwhile read "Local" / "Local repository" under a monitor icon.

showWorkspaceBar gains sideForServer(serverSDK().server) === "code". Work
falls through to the plain branch chip, the same branch a non-git project
already takes. newSessionWorktree() already returned "main" whenever the bar
is hidden, and "main" in submit.ts means "leave sessionDirectory alone" —
it does not redirect a session to the project root.

Worth recording for whoever reopens this: a guest worktree cannot be made
usable from the host by moving the checkout, because a worktree's .git file
holds an absolute path back to <repo>/.git/worktrees/<name> and that path is
/mnt/<name> in the guest and the real path on the host. And git worktree add
runs with cwd = the mounted host repo either way, so it registers the worktree
in the user's real .git no matter where the checkout goes. The DIVERGENCES row
carries the full reasoning and the three storage designs that were costed.

Notes

DIVERGENCES.md gains two rows (all four touched app files are upstream's);
CHANGELOG.md gains three Unreleased entries under Sandbox. Fork-only new file:
packages/app/src/sandbox/mount-dialog.tsx.

Testing

  • bun typecheck in packages/app
  • bun run test:unit (702 pass) and bun run test:browser (101 pass) in packages/app

Not driven in the desktop app: the Work side cannot be exercised from the web
e2e harness (that build has no sandbox platform, so effectiveSide collapses it
to Code).

🤖 Generated with Claude Code

quickbeard and others added 3 commits August 18, 2026 12:23
The composer's project picker read the full server list, so a draft opened
from the Work tab listed the local machine's projects under a "Local Server"
heading beside the sandbox's own — and picking one started the session on the
local machine, outside any sandbox, with nothing on screen to say so.

It now reads the servers on the same side as the draft's own server, so Work
offers only the sandboxes' projects and Code only everything else. The side
comes from the draft's server rather than the sidebar's selected side, because
a draft route mounts its own server and the two are not guaranteed to agree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adding a project to a sandbox means giving it a folder from this computer.
The picker's Add project ran upstream's directory picker against the server it
is pointed at, which for a sandbox is the guest's own filesystem — nothing the
user has ever put a project in.

On Work it now opens the mounts dialog the sidebar's add button already opens,
labelled "Mount project" like every other route to it. Both call sites, plus
the Work empty-state prompt, share one hook rather than repeating the lazy
import.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A workspace is a git worktree the session's server checks out, rooted at the
server's own data dir. Inside a sandbox that is the guest's disk: not one of
the host folders the sandbox mounts, so the work happens where the user's
editor cannot see it, and a reset takes it along. The chip meanwhile said
"Local" under a monitor icon.

Work now falls through to the plain branch chip, the same branch a project
that is not in git already takes. Code is untouched, and the bar stays gated
on the non-prod channel as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@quickbeard quickbeard changed the title fix(app): keep the new-session project picker on its own side fix(app): keep the new-session screen on its own side in Work Aug 18, 2026
@quickbeard
quickbeard merged commit 141ee6d into main Aug 18, 2026
0 of 5 checks passed
@quickbeard
quickbeard deleted the fix/work-project-picker branch August 18, 2026 06:36
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