Skip to content

Commit f3e174c

Browse files
JohnMcLearclaude
andauthored
refactor(shell): extract @etherpad/shell + Platform injection seam (Phase 2a) (#32)
* docs(plan): add phase-2a shell-extract implementation plan 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> * chore(shell): scaffold empty @etherpad/shell workspace package * refactor(shell): move src/shared into packages/shell/src * refactor(shell): move renderer code into packages/shell/src * feat(shell): introduce Platform seam + wire Electron adapter 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> * test(shell): move renderer tests into packages/shell/tests 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> * chore(workspace): make root pnpm scripts recurse across packages 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> * docs: refresh CLAUDE.md, AGENTS.md, README for @etherpad/shell 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> * refactor(shell): move E2E seam into desktop entry point 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> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3bd8aeb commit f3e174c

92 files changed

Lines changed: 1931 additions & 183 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ adds Claude-specific notes and project gotchas that other agents share too.
55

66
## Monorepo layout (read this first)
77

8-
This repo is a pnpm workspace as of 2026-05. The desktop app lives in `packages/desktop`. Run every `pnpm` command from the repo root — the root `package.json` proxies every script via `pnpm --filter @etherpad/desktop`. Don't `cd` into `packages/desktop` for normal dev — it works but breaks IDE assumptions about where the workspace is.
8+
This repo is a pnpm workspace. Source lives under `packages/`:
99

10-
Mobile (`packages/mobile`) and shell (`packages/shell`) are coming in subsequent phases; today there is only `packages/desktop`.
10+
- `packages/shell` (`@etherpad/shell`) — React renderer shell, Zustand state, i18n, types, validation, IPC channel names, the `Platform` injection seam (`setPlatform()` / `getPlatform()`). Consumed as source by `packages/desktop` and (soon) `packages/mobile`.
11+
- `packages/desktop` (`@etherpad/desktop`) — Electron main + preload + the renderer entry that injects `createElectronPlatform()` and mounts the shell.
12+
13+
Run every `pnpm` command from the repo root. `pnpm test`, `pnpm typecheck`, and `pnpm lint` recurse across both packages via `pnpm -r`. Don't `cd` into a package directory for normal dev — it works but breaks IDE assumptions about where the workspace is.
14+
15+
Mobile (`packages/mobile`) lands in a later phase.
1116

1217
## Read first
1318

@@ -49,20 +54,20 @@ These bite people who don't know them. Don't relearn the hard way.
4954
the gutter constant must agree — there's a regression test pinning
5055
this in `packages/desktop/tests/main/windows/app-window-layout.spec.ts`.
5156
- **All user-facing strings go through i18n.** `t.<section>.<key>` from
52-
`packages/desktop/src/renderer/i18n/`. No hardcoded English in JSX, aria-labels, or
57+
`packages/shell/src/i18n/`. No hardcoded English in JSX, aria-labels, or
5358
titles — use `fmt()` for placeholder substitution. The shape contract
54-
is pinned in `packages/desktop/tests/renderer/i18n/i18n.spec.ts`.
59+
is pinned in `packages/shell/tests/i18n/i18n.spec.ts`.
5560

5661
## Working style for this repo
5762

5863
- **Inline execution.** When given a plan or spec the user expects work
5964
to land directly — don't pause for review of committed plan files.
6065
- **Push on every fix.** This repo has a tracking remote on
6166
`feat/linux-mvp`; push to origin after each commit, not in batches.
62-
- **Always run backend tests.** `pnpm test` covers both main and
63-
renderer suites — running only the renderer half can miss real
64-
regressions. Backend tests caught dependency issues we didn't notice
65-
locally.
67+
- **Always run backend tests.** `pnpm test` recurses across `@etherpad/shell`
68+
and `@etherpad/desktop` (which itself runs the main vitest project).
69+
Running only the renderer half can miss real regressions. Backend tests
70+
caught dependency issues we didn't notice locally.
6671
- **Wait ~20s and check CI after every push.** Fix CI failures
6772
immediately before moving on. `gh run list --branch feat/linux-mvp
6873
--limit 3` is the quick check.

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ This is a pnpm monorepo.
77
| Package | Status | Source |
88
|---|---|---|
99
| `@etherpad/desktop` | Released | [`packages/desktop`](packages/desktop) |
10+
| `@etherpad/shell` | Source-consumed workspace dep | [`packages/shell`](packages/shell) |
1011
| `@etherpad/mobile` | In development (Android first, iOS-ready) | `packages/mobile` (added in phase 3) |
11-
| `@etherpad/shell` | Pending refactor (phase 2 of mobile rollout) | `packages/shell` |
1212

1313
## Quick start (desktop)
1414

@@ -22,6 +22,7 @@ See [`packages/desktop/README.md`](packages/desktop/README.md) for full develope
2222
## Layout
2323

2424
- `packages/desktop/` — Electron app (Linux AppImage, deb, snap; macOS DMG; Windows NSIS).
25+
- `packages/shell/` — React renderer shell shared between desktop and (soon) mobile. Owns dialogs, state, i18n, and the `Platform` injection seam.
2526
- `docs/` — specs, plans, and shared internal docs.
2627

2728
## License

0 commit comments

Comments
 (0)