Skip to content

refactor(shell): extract @etherpad/shell + Platform injection seam (Phase 2a)#32

Merged
JohnMcLear merged 9 commits into
mainfrom
feat/mobile-phase2a-shell-extract
May 11, 2026
Merged

refactor(shell): extract @etherpad/shell + Platform injection seam (Phase 2a)#32
JohnMcLear merged 9 commits into
mainfrom
feat/mobile-phase2a-shell-extract

Conversation

@JohnMcLear

Copy link
Copy Markdown
Member

Summary

Phase 2a of the mobile rollout (spec §11.2, plan
docs/superpowers/plans/2026-05-11-etherpad-mobile-phase2a-shell-extract.md):

  • New workspace package @etherpad/shell containing the renderer code
    (App.tsx, components, dialogs, rail, sidebar, state, tabs, i18n, styles)
    and the previously-shared modules (ipc, types, validation, locales,
    url.ts).
  • New Platform interface and setPlatform() / getPlatform() /
    __resetPlatformForTests() seam in packages/shell/src/platform/ipc.ts.
    Shape mirrors today's preload API verbatim — abstract sub-interfaces
    (storage / padView / events) from spec §4 are intentionally deferred
    to Phase 2b once mobile is a real consumer driving the shape.
  • packages/desktop/src/renderer/index.tsx wires a thin
    createElectronPlatform() adapter at boot before mounting the shell <App />.
    E2E test seam moved out of App.tsx into a pure attachE2EHelpers() export
    that desktop invokes conditionally — shell src is now fully decoupled from
    runtime-specific globals.
  • Renderer tests moved into packages/shell/tests/ with their own vitest
    jsdom project and a buildMockPlatform() helper. Legacy
    window.etherpadDesktop = {...} test patterns still work via a
    compatibility shim that routes assignments through setPlatform().
    Fixed 4 pre-existing latent type errors that vitest was silently tolerating.
  • Root pnpm typecheck / test / lint now recurse across both packages
    via pnpm -r --workspace-concurrency=1 <script>.
  • Docs refreshed: root CLAUDE.md monorepo section, README.md package
    table, packages/desktop/AGENTS.md shell pointers, new
    packages/shell/AGENTS.md.

Zero behavioural change to the desktop app. Both packages typecheck, lint,
and test cleanly. The shell's stylesheet + entry point still mount inside
desktop's Vite renderer build exactly as before.

Stacked plan: this branch was cut off main after PR #30 (Phase 1 recovery)
merged. Phase 2b will introduce the abstract Platform sub-interfaces
once packages/mobile exists to drive their shape.

Test plan

  • CI green on pnpm typecheck (composite project refs across shell + desktop)
  • CI green on pnpm test (204 shell + 281 desktop = 485, same total as pre-refactor)
  • CI green on pnpm test:e2e (Playwright Electron, unchanged surface)
  • No window.etherpadDesktop reads inside packages/shell/src/ (only a doc comment)
  • No imports of electron / @capacitor/* inside packages/shell/src/

🤖 Generated with Claude Code

JohnMcLear and others added 9 commits May 11, 2026 17:11
Plan for Phase 2a of the mobile rollout: move renderer + shared code into
a new @etherpad/shell workspace package and introduce a Platform injection
seam (setPlatform/getPlatform). The abstract Platform sub-interfaces
(storage/padView/events) from spec §4 are intentionally deferred to
Phase 2b once mobile is a real consumer driving the shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move ipc/api.ts to platform/ipc.ts. Rename the internal RuntimeApi to the
public Platform interface and add setPlatform()/getPlatform()/
__resetPlatformForTests(). Desktop's renderer index.tsx now calls
setPlatform(createElectronPlatform()) before mounting App, decoupling
shell from window.etherpadDesktop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Set up shell's own jsdom vitest project with a buildMockPlatform() helper
in tests/setup.ts. Install a compatibility shim that routes legacy
`window.etherpadDesktop = {...}` mutations through setPlatform() so the
existing test code continues to work unchanged.

Drop the renderer project from desktop vitest config — desktop only runs
the main project now. tsconfig.tests.json widened to include the new
spec files. Fixed pre-existing latent type errors in 4 tests that vitest
was silently tolerating (JSX.Element → React.JSX.Element, Settings
literal missing fields).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
typecheck/test/lint now run across both @etherpad/shell and @etherpad/desktop
via `pnpm -r --workspace-concurrency=1 <script>`. Adds shell's eslint
config + devDeps so the new package participates in CI lint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Root CLAUDE.md monorepo section lists both packages now. Desktop's
AGENTS.md drops the dead `src/renderer/` / `src/shared/` paths and
points at packages/shell for shell-side code. New
packages/shell/AGENTS.md gives the package its own orientation doc.
Root README lists shell in the package table.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
App.tsx no longer reads window.etherpadDesktop.e2eFlags. Shell now exports
a pure attachE2EHelpers(target) function and desktop's renderer/index.tsx
invokes it conditionally when the preload reports e2eFlags.enabled. Shell
src/ is now fully decoupled from runtime-specific globals.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown
ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one.

@JohnMcLear
JohnMcLear merged commit f3e174c into main May 11, 2026
5 checks passed
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