Skip to content

feat(workbench): extract the host-agnostic core into packages/workbench (0406) - #644

Merged
crs48 merged 3 commits into
mainfrom
claude/0406-workbench-package
Jul 28, 2026
Merged

feat(workbench): extract the host-agnostic core into packages/workbench (0406)#644
crs48 merged 3 commits into
mainfrom
claude/0406-workbench-package

Conversation

@crs48

@crs48 crs48 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Continues exploration 0406 (12/33 after this). Follows #641 (the seam) and #642 (the migration onto it); this PR makes the core physically shareable.

Why the core first, not the whole directory

The workbench's chrome references 52 distinct app-local modules (views, comms, hooks, search). A whole-directory move would churn web's highest-traffic area for days and conflate relocation with API design. The host-agnostic core, by contrast, has exactly four dependencies — react, zustand, lucide-react, @xnetjs/plugins — so it moves cleanly and delivers the thing desktop actually needs first: the state layer.

@xnetjs/workbench now contains: the PlatformPort, the workbench store, tab/preview grammar, navigation intent, surfaces, command wiring, focus, route titles, sidebar sections, explorer sort, new-doc identity, and the test port. Private and source-consumed (main → src/index.ts, the canvas-core pattern) — no build ordering, no vite aliases.

Old paths keep one-line shims (the 0280 layout-tree.ts pattern, this repo's own precedent). Both roads resolve to one module instance; consumers migrate opportunistically.

What the move itself surfaced

  • state.ts declared its own ChromePosture, a twin of the canonical type in @xnetjs/plugins — 0277's copied-type drift in miniature, invisible until a barrel saw both declarations. Fixed at the source rather than papered over in the barrel.
  • newDocId/CreatableDocType graduate into the package; lib/doc-creation keeps routes + menu chrome and re-exports identity.

Why this matters for the desktop

The parity test's founding condition — "the moment desktop adopts them it consumes the SAME module as web" — now covers the entire state layer, not just layout-tree. Phase 3 (mounting the shell in Electron) can begin with desktop importing useWorkbench and the port directly.

Verification

  • Live app: boot, working-set open, and New → Page (URL change + editor mount) all flow through the package modules, zero console errors.
  • 992 web + 89 package + 149 electron tests green (parity test included); repo-wide typecheck clean; lint 0 errors.
  • The router ban now also covers packages/workbench/src.

skip-changelog: internal restructuring, no user-visible change. Private package → no changeset.

🤖 Generated with Claude Code

The workbench's chrome references 52 distinct app-local modules, so moving the
whole directory in one PR would churn web's highest-traffic area for days.
This lands the increment with the best value-to-risk: the host-agnostic CORE
— platform port, workbench store, tab/preview grammar, navigation intent,
surfaces, commands, focus, route titles, sidebar sections, explorer sort, and
the new-doc identity — whose only dependencies are react, zustand,
lucide-react, and @xnetjs/plugins.

The package is private and source-consumed (main -> src/index.ts, the
canvas-core pattern), so no build ordering or vite aliases are needed. Old
paths under apps/web/src/workbench/ keep one-line shims (the 0280 layout-tree
pattern); both roads resolve to one module instance, and consumers migrate
opportunistically.

Two things surfaced by the move, fixed rather than carried:
- state.ts declared its own ChromePosture, twin to the canonical one in
  @xnetjs/plugins — 0277's copied-type drift in miniature, exposed the moment
  a barrel saw both. The canonical type wins.
- newDocId/CreatableDocType graduate from lib/doc-creation into the package;
  the app file keeps routes and menu chrome and re-exports identity.

The ESLint router ban now covers packages/workbench/src, and the package's 89
tests run under the dom project.

With the core packaged, the desktop renderer can adopt useWorkbench, the
LayoutTree, and the port TODAY — the parity test's "the moment desktop adopts
them it consumes the SAME module as web" now covers the whole state layer,
not just layout-tree.

Verified live: boot, working-set open, and New->Page (URL + editor) all flow
through the package modules with zero console errors. 992 web + 89 package +
149 electron tests green; repo-wide typecheck clean.

Signed-off-by: xNet Test <test@xnet.dev>
@crs48 crs48 added the skip-changelog Exclude this PR from the changelog label Jul 28, 2026
@crs48
crs48 temporarily deployed to pr-644 July 28, 2026 18:11 — with GitHub Actions Inactive
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

🖼️ UI changes in this PR

No visual differences detected in the changed UI.

CI run

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
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Preview removed for PR #644.

@crs48
crs48 temporarily deployed to pr-644 July 28, 2026 18:21 — 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
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
@crs48
crs48 temporarily deployed to pr-644 July 28, 2026 18:38 — 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
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
@crs48
crs48 merged commit 5549118 into main Jul 28, 2026
22 checks passed
@crs48
crs48 deleted the claude/0406-workbench-package branch July 28, 2026 18:53
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
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