Skip to content

feat(app): hide the Work side until a sandbox exists - #292

Merged
quickbeard merged 1 commit into
mainfrom
feat/work-side-opt-in
Aug 22, 2026
Merged

quickbeard merged 1 commit into
mainfrom
feat/work-side-opt-in

Conversation

@quickbeard

Copy link
Copy Markdown
Owner

What

Every desktop install showed the Code / Work switch above the projects list, even for profiles that had never made a sandbox — Work was an empty side that only offered to build one. Both the Work side and the strip are now gated on a new pure predicate, workSideAvailable() (fork-only workspace/side.ts):

sandbox-capable platform AND (a sandbox exists OR the `showWork` preference is on)

Per the decisions on this:

  • Opt-in via a setting. Settings → General → Advanced gains a Show Work switch, default off, wrapped in <Show when={platform.sandboxes}> so non-sandbox builds never offer it. Owning a sandbox shows Work regardless of the switch — hiding the side its servers live on would strand them.
  • Creating a first sandbox stays where it already is: Settings → Servers → + → Add sandbox. Creating one reveals Work immediately. No new UI.
  • Deleting the last sandbox hides Work again (unless the switch is on). The existing removedServer already steps back to Code; now the strip goes with it.

Wiring (fork-only workspace/tabs.tsx): a useWorkAvailable() hook feeds both useWorkspaceSide()'s effectiveSide call and WorkspaceTabs's <Show> — which previously gated on platform.sandboxes. Gating both together is deliberate: a hidden strip with Work still selected would leave the user on sandbox servers with no way back to Code.

One race preserved from the original split: an undefined sandbox list means "not loaded", not "none", and keeps Work. Collapsing on unknown is what previously bounced the sidebar to Code on every launch and in the beat after the first sandbox was created. The main process answers sandbox-get-state synchronously, so that window is sub-frame.

DIVERGENCES: new row for the opt-in gate (settings.tsx, settings-v2/general.tsx, i18n are upstream files); the existing Code/Work split row's now-stale effectiveSide clause updated to point at it. CHANGELOG entry under Desktop / Web UI.

Verification

  • bun typecheck clean in packages/app; full bun turbo typecheck green via the pre-push hook.
  • bun run test:unit: 690 pass. bun run test:browser: 115 pass, including four new workSideAvailable cases (no sandbox + opted out → hidden; sandbox exists → shown either way; unsupported platform → never; unloaded list → kept).
  • Provider nesting checked statically: SettingsProvider (app.tsx:620) is a strict ancestor of LayoutProvider (via NewAppLayout → ServerScopedProviders), so the new useSettings() dependency resolves at every site where useWorkspaceSide() already called useLayout().
  • Not verified in the running GUI — see the note below.

🤖 Generated with Claude Code

The Code/Work strip showed on every desktop install, but Work was empty
for anyone who had never made a sandbox. Gate both the side and the
strip on workSideAvailable(): sandbox-capable platform and either an
existing sandbox or the new general.showWork preference.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@quickbeard
quickbeard merged commit 54645a8 into main Aug 22, 2026
0 of 5 checks passed
@quickbeard
quickbeard deleted the feat/work-side-opt-in branch August 22, 2026 08:05
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