feat(web): bring the task.nself.org app into this repo - #116
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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/uiin sixteen files and could not resolve it anywhere else.Five problems the monorepo was hiding
@nself/i18nand@nself/observabilitywere used but never declared — they resolved by hoisting from the monorepo rootJSX.Element. React 19 removed that namespace; the app only compiled because a stray@types/react@18leaked in through hoisting../packages, which meantweb/packagesin the monorepo19.0.0; the web app takes^19.0.0. Undernode-linker=hoistedthat produced react 19.2.8 beside 19.0.0 and a transitive react-dom@18.3.1 — every hook call hit a null dispatcher@nself-web/uito source makes its react/react-dom/next-themes resolve from the sibling checkout.resolve.dedupedoes not reach outside the project root, so those three are aliased explicitlyThe version gate read
web/ntask/package.json— a path that cannot exist here. It now readsweb/package.jsonand holds the web app to the same version as every other surface.Verified in this repo
Deliberately not in this PR
task.nself.orgstill deploys fromnself-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; removingntask/there would conflict with all of them.