Skip to content

feat(web): bring the task.nself.org app into this repo - #116

Merged
acamarata merged 3 commits into
mainfrom
feat/web-app-migration
Aug 19, 2026
Merged

feat(web): bring the task.nself.org app into this repo#116
acamarata merged 3 commits into
mainfrom
feat/web-app-migration

Conversation

@acamarata

Copy link
Copy Markdown
Collaborator

Moves the ntask web app (243 files) out of nself-org/web, so every ɳTask surface — mobile, desktop, TV, CLI, MCP, backend and now web — lives in one repo, and the repo stays forkable without access to a private monorepo.

Only possible now that nself-org/packages#7 landed: the app imports @nself-web/ui in sixteen files and could not resolve it anywhere else.

Five problems the monorepo was hiding

Undeclared dependencies @nself/i18n and @nself/observability were used but never declared — they resolved by hoisting from the monorepo root
Removed React 19 global Three components typed returns as the bare global JSX.Element. React 19 removed that namespace; the app only compiled because a stray @types/react@18 leaked in through hoisting
Monorepo-relative paths vite and vitest resolved shared packages through ../packages, which meant web/packages in the monorepo
Four Reacts, three versions Expo 53 / RN 0.79 pin react to exactly 19.0.0; the web app takes ^19.0.0. Under node-linker=hoisted that produced react 19.2.8 beside 19.0.0 and a transitive react-dom@18.3.1 — every hook call hit a null dispatcher
Cross-checkout resolution Aliasing @nself-web/ui to source makes its react/react-dom/next-themes resolve from the sibling checkout. resolve.dedupe does not reach outside the project root, so those three are aliased explicitly

The version gate read web/ntask/package.json — a path that cannot exist here. It now reads web/package.json and holds the web app to the same version as every other surface.

Verified in this repo

  • typecheck clean
  • build clean
  • 461/461 tests pass — the same count as in the monorepo, so nothing was dropped

Deliberately not in this PR

task.nself.org still deploys from nself-org/web. Switching the Vercel project and deleting the copy there are follow-ups, kept separate so the live site is never mid-migration. The web monorepo also has six open PRs from other work right now; removing ntask/ there would conflict with all of them.

Per the surface rule, a product's web app belongs in the product repo. This
moves the ntask app (243 files) out of nself-org/web so every ɳTask surface —
mobile, desktop, TV, CLI, MCP, backend and now web — lives in one place, and
so the repo stays forkable without access to a private monorepo.

Only possible now that nself-org/packages holds the shared web packages. The
app imports @nself-web/ui in sixteen files and could not resolve it anywhere
else.

Five real problems the monorepo had been hiding:

- @nself/i18n and @nself/observability were used but never declared; they
  resolved by hoisting from the monorepo root. Now dependencies.
- Three components typed returns as the bare global JSX.Element. React 19
  removed that namespace — the app only compiled because a stray
  @types/react@18 leaked in through hoisting. Now React.JSX.Element.
- vite and vitest resolved shared packages through ../packages, which pointed
  at web/packages in the monorepo. Repointed at the sibling checkout, matching
  what pnpm-workspace.yaml already uses.
- Expo 53 and RN 0.79 pin react to exactly 19.0.0 while the web app takes
  ^19.0.0. Under node-linker=hoisted that produced four copies across three
  versions, including a transitive react-dom@18.3.1, so every hook call hit a
  null dispatcher. Pinned react and react-dom for the workspace.
- Aliasing @nself-web/ui to its TypeScript source makes its own react,
  react-dom and next-themes imports resolve from the sibling checkout's
  node_modules — a second React instance again. resolve.dedupe does not reach
  outside the project root, so those three are aliased explicitly.

The version gate read web/ntask/package.json, a path that cannot exist here;
it now reads web/package.json and holds the web app to the same version as the
other surfaces.

Verified in this repo: typecheck clean, build clean, 461/461 tests pass — the
same count as in the monorepo, so nothing was dropped.

task.nself.org still deploys from nself-org/web. Switching the Vercel project
and removing the copy there are follow-ups, deliberately separate so the live
site is never mid-migration.
OSV flags ajv 8.6.3, minimatch 10.1.1, path-to-regexp 6.1.0 and smol-toml 1.5.2
through the web app's toolchain — four high, two medium. All have published
fixes, so override rather than allowlist.
minimatch@<10.2.3 also matches 3.x, so babel-plugin-istanbul's minimatch v3 was
force-upgraded to v10. v10 moved to named exports, so coverage instrumentation
died with 'minimatch is not a function' and every mobile suite failed to run.

Each override is now bounded on both sides, matching the form-data entries
already in this file. minimatch 3.1.5 survives for istanbul while the
vulnerable 10.1.1 is raised to 10.2.5.

Mobile: 365 tests pass. Web: 461 pass.
@acamarata
acamarata merged commit 2ee4428 into main Aug 19, 2026
11 checks passed
@acamarata
acamarata deleted the feat/web-app-migration branch August 19, 2026 16:47
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