Skip to content

feat(workbench): move the shell chrome into @xnetjs/workbench (0406) - #650

Merged
crs48 merged 7 commits into
mainfrom
claude/0406-chrome-move
Jul 28, 2026
Merged

feat(workbench): move the shell chrome into @xnetjs/workbench (0406)#650
crs48 merged 7 commits into
mainfrom
claude/0406-chrome-move

Conversation

@crs48

@crs48 crs48 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

The chrome phase of exploration 0406 (one shell, two surfaces): the entire workbench shell chrome — frames, islands, menus, mobile shell, sidebar, explorer views, time machine, drafts, calm surface — moves from `apps/web/src/workbench` into `@xnetjs/workbench`, behind two injection points the host app fills at boot:

  • View registry (`registerHostedViews`): the shell renders tab content through `hostedView()`; web registers its complete view table in `platform/hosted-views.tsx` (a full `Record<TabNodeType, …>`, so exhaustiveness stays a compile error). ViewHost drops all 18 view imports.
  • WorkbenchHost contract (`setWorkbenchHost`): the app services the chrome consumes but cannot define — workspace data hooks (spaces, tags, storage, requests, node actions), comms presence, the Today-panel experiments API, and host-owned components (ShareDialog, GlobalSearch, WorkspaceCommands, SelfAvatar, coachmarks, error fallback…). Members are narrowed to what the chrome actually reads, so the desktop host will implement the minimum. Web binds its existing modules onto the contract in `platform/workbench-host.tsx` — no new behaviour, one file that knows both names.

Pure modules moved outright (with shims at the old paths, 0280 pattern): format-bytes, settings-sections, saved-view-registry, tag-view-data, data-runtime, explorer-items, the source-stamp browser half, `DOC_TYPE_META` (the label/icon half of `DOC_TYPE_ROUTES`), and `AGENT_LAYOUT_EVENT`.

What deliberately did not move: `inspect/` (dev-only point-and-change overlay, coupled to devkit), and every app component that binds the router or app data — those stay host-side behind the contract.

Boot-order rule enforced throughout: no `workbenchHost()` call at module scope — the barrel evaluates before the app's boot registration runs, so module-scope registration (Workbench's builtin views, WorkspaceSwitcher's coachtips) became lazy-once on first render, and reading before registration throws loudly instead of rendering an empty shell.

Verification

  • `turbo run typecheck` green across web, desktop, workbench (44 tasks)
  • 992 dom tests + 155 electron tests green; `pnpm lint` clean
  • Live-driven on the dev server: shell boots with zero console errors; New menu renders all DOC_TYPE_META entries; New → Page navigates (the feat(workbench): route the shell through the PlatformPort, not the router (0406) #642 regression path); ShareDialog opens on a doc; Chats surface renders through the host wrapper; status bar (sync chips, storage bytes, What's New) all live
  • editor-ux spec set run locally: 7 passed; the one mobile failure reproduces identically against a baseline `main` server — pre-existing local-env issue, not this change

Part of exploration 0406 (now 15/23 implementation). Next: mount `` in Electron behind `XNET_UNIFIED_SHELL`.

🤖 Generated with Claude Code

xNet Test added 4 commits July 28, 2026 14:24
The shell renders tab content through a view registry the app fills at
boot (registerHostedViews takes the complete Record so exhaustiveness
stays a compile error, now in apps/web/src/platform/hosted-views.tsx).
ViewHost drops all 18 view imports.

Pure modules move into the package with shims at the old paths:
format-bytes, settings-sections, saved-view-registry (+@xnetjs/social
dep), tag-view-data, and the source-stamp browser half (the inspect
overlay follows with the chrome).

Signed-off-by: xNet Test <test@xnet.dev>
Signed-off-by: xNet Test <test@xnet.dev>
@crs48
crs48 temporarily deployed to pr-650 July 28, 2026 22:09 — with GitHub Actions Inactive
@crs48 crs48 added the skip-changelog Exclude this PR from the changelog label Jul 28, 2026
@crs48
crs48 temporarily deployed to pr-650 July 28, 2026 22:16 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Preview removed for PR #650.

github-actions Bot added a commit that referenced this pull request Jul 28, 2026
… build (0406)

builtin-slot-views now lazy-loads AiChatPanel (restoring the isolation
the /ai subpath exists for), the storybook plugins shim gains the AI
surface/connector exports the chrome resolves, and the storybook build
externalizes usearch exactly like apps/web does.

Signed-off-by: xNet Test <test@xnet.dev>
@crs48
crs48 temporarily deployed to pr-650 July 28, 2026 22:37 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
The moved chrome's arbitrary-value classes (e.g. the mobile shell's
h-[calc(100dvh-…)]) stopped being generated when the files left
apps/web — the web and storybook Tailwind configs never scanned
packages/workbench. The mobile shell collapsed to half height and the
bottom cluster intercepted editor clicks (the editor-ux CI failure).
Electron's config already wildcards packages/*/src.

Signed-off-by: xNet Test <test@xnet.dev>
@crs48
crs48 temporarily deployed to pr-650 July 28, 2026 22:57 — with GitHub Actions Inactive
@github-actions

Copy link
Copy Markdown
Contributor

🖼️ UI changes in this PR

Components

✏️ Web/PresenceAvatars — Docs _(SSIM 0.989)_
before after diff
before after diff

Screens

✏️ CRM _(SSIM 0.980)_
before after diff
before after diff
✏️ Home _(SSIM 0.982)_
before after diff
before after diff

Interactions

🎬 Open a channel and post a message

Open a channel and post a message

▶ Watch MP4

🎬 Build a CRM quote (product + line item)

Build a CRM quote (product + line item)

▶ Watch MP4

Auto-captured by CI · run. Informational — not a blocking check.

github-actions Bot added a commit that referenced this pull request Jul 28, 2026
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
@crs48
crs48 merged commit af6fc9a into main Jul 28, 2026
22 checks passed
@crs48
crs48 deleted the claude/0406-chrome-move branch July 28, 2026 23:06
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
crs48 added a commit that referenced this pull request Jul 28, 2026
#651)

## Summary

The desktop half of exploration 0406's mount phase, stacked on #650:

- **Palette cluster + data hooks move into the package.** GlobalSearch,
WorkspaceCommands, UndoToast, \`lib/desk\`, \`usePageSearchSurface\`,
\`useSpaces\`, \`useRequestCount\`, and \`useNodeActions\` are
package-clean (pure @xnetjs/* data hooks and port-abstracted
components), so they move into \`@xnetjs/workbench\` outright and the
\`WorkbenchHost\` contract shrinks by seven members — the minimum a
second host must implement got smaller.
- **Desktop implements WorkbenchHost** (\`shell/workbench-host.tsx\`):
real workspace tags and Space-aware doc creation through the
PlatformPort; explicit "not on desktop yet" panels for comms, habits,
and share links — visible absences, never silent stubs.
- **Desktop registers its hosted-view table**
(\`shell/hosted-views.tsx\`): real PageView/DatabaseView; every other
TabNodeType gets a labeled placeholder. The Record stays complete, so
exhaustiveness is still a compile error.
- **\`<Workbench/>\` mounts in Electron** behind
\`localStorage.setItem('xnet:unified-shell', '1')\` — the bespoke shell
remains the default.
- \`sidebar/sources\` channel rows degrade via \`useCommsMaybe\` instead
of throwing on hosts without a comms provider (found live: the first
desktop mount crashed exactly there, loudly).
- New \`[boot] renderer loaded\` trace marker used for the cold-open
measurement.

## Verified live in Electron over real SQLite

Sidebar islands, lens chips, and the explorer listing the desktop
store's real pages; clicking a row navigates through the port into the
real desktop PageView; the ⌘K palette (the moved GlobalSearch) searches
native data ("Electron Smoke Page") — zero console errors.

## Measurements (checklist item)

- Renderer dist: 26.1 MB → 35.4 MB (+9.3 MB — the chrome and its graph,
parsed alongside the bespoke shell while the flag exists)
- Cold-open (\`electron-vite preview\`, \`main module loaded\` →
\`renderer loaded\`): 0.52 s → 0.78 s. The 10% validation budget applies
to the end state where the chrome replaces the bespoke shell.

Exploration 0406 is now 18/23 implementation. Remaining: register canvas
home/meetings/social-import as workbench views, capability gating, flag
removal + bespoke-shell deletion, and the 0394-gated panel-write item.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
crs48 added a commit that referenced this pull request Jul 29, 2026
Every box in exploration 0406 is checked — 23/23 implementation, 10/10
validation — so the filename flips to `[x]`.

The arc, for the record: #641/#642/#644 (port + core extraction), #648
(AI panel on desktop), #650/#651 (chrome behind injection points, first
Electron mount), #652 (desktop surfaces in the shell), #653 (flag
removed, bespoke shell deleted), #655 (cold-open back under the 0.52s
baseline), #656 (approval-gated writes — the last blocked item). The
desktop and web apps now render one shell from one module, verified live
at every step.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Exclude this PR from the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant