Skip to content

refactor(web): migrate loft → @e2a/ui + wire build (CI/Docker/jest)#334

Open
jiashuoz wants to merge 3 commits into
mainfrom
web-migrate-loft-to-e2a-ui
Open

refactor(web): migrate loft → @e2a/ui + wire build (CI/Docker/jest)#334
jiashuoz wants to merge 3 commits into
mainfrom
web-migrate-loft-to-e2a-ui

Conversation

@jiashuoz

Copy link
Copy Markdown
Member

What

Follow-up to #333. Migrates web/ to consume the @e2a/ui package for the extracted leaf components, and does the build-wiring that #333 deliberately deferred (an adversarial review had flagged it NO-GO). The deferred migration commit came from branch web-migration-deferred.

Commits

  1. refactor(web) — 15 files move from local loft/* imports to @e2a/ui (Chip, Dot, Eyebrow, InkConsole), consolidated to one import each; adds the @e2a/ui dep + loads its stylesheet. PageShell/Topbar/Sidebar stay on loft/ (not extracted yet).
  2. build(design-system) — commit @e2a/ui's dist/ (web consumes it via file: and the Docker image copies it) + a CI freshness gate that rebuilds it and fails on drift (same idiom as the OpenAPI/SDK freshness checks).
  3. build(web) — make web build @e2a/ui in CI and Docker.

The build-wiring fixes (the review's blockers)

  • B1dist/ is committed + freshness-gated, so clean checkouts (CI, jest) resolve @e2a/ui.
  • B2 — the web Docker image builds from the repo root (so the sibling @e2a/ui workspace is in context), with a web/Dockerfile.dockerignore to trim it. Turbopack's root is pinned to web/'s parent so it resolves @e2a/ui (which lives outside web/).
  • H1 — jest resolves the ESM-only @e2a/ui to its TS source, with react pinned to web's single copy (this caught a real duplicate-React null-hook crash).
  • M1--success-strong added to globals.css (:root + .dark) so globals stays the token authority.
  • L1 — the success Chip text color now uses --success-strong (was --success). Intentional: it's the consistent choice — every other tone already uses its -strong pair.

Verification (clean-environment, not just local smoke)

  • docker build -f web/Dockerfile . succeeds and the container serves the migrated UI (loft-eyebrow present in the served HTML; Caddy returns 200).
  • 259/259 web jest tests pass; npm run lint clean (1 pre-existing warning); local next build compiles.
  • @e2a/ui dist/ rebuilds byte-for-byte (freshness gate green).

Scope

loft/ is not removed yet — PageShell/Topbar/Sidebar need extraction first (the Tailwind/layout work), which is a later PR.

🤖 Generated with Claude Code

jiashuoz and others added 3 commits June 27, 2026 14:15
Migrate the dashboard and marketing pages off local loft/ imports onto the
@e2a/ui package for the four extracted leaf components (Chip, Dot, Eyebrow,
InkConsole) — 15 files, consolidated to one @e2a/ui import each. Add @e2a/ui
as a dependency and load its stylesheet in the root layout (before
globals.css, which stays authoritative for tokens).

PageShell, Topbar, and Sidebar remain on loft/ until they're extracted, so
loft/ is not removed in this pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
web consumes @e2a/ui via a file: dep and its Docker image copies the built
output, so dist/ must exist on a clean checkout — un-gitignore and commit it
(sourcemaps dropped to keep the tracked artifact small). A new CI job rebuilds
dist/ and fails on drift, same idiom as the OpenAPI/SDK freshness gates.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Docker: build the web image from the repo root so the sibling @e2a/ui
  workspace (file:../design-system) is in context; add web/Dockerfile.dockerignore
  to trim it. Pin Turbopack's root to web/'s parent so it resolves @e2a/ui,
  which lives outside web/ (next.config.ts) — verified by a local image build
  that serves the migrated UI.
- jest: resolve the ESM-only @e2a/ui to its TS source and pin react to web's
  single copy (avoids a duplicate-React null-hook crash).
- tokens: define --success-strong in globals.css (:root + .dark) so globals
  stays authoritative; @e2a/ui's success Chip uses it.
- build-image: rebuild the web image when design-system/ changes too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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