26 KiB
Codebase Structure
Analysis Date: 2026-05-11
Directory Layout
reactive-resume/
├── apps/
│ └── web/ # Sole deployable application (TanStack Start / Vite / Nitro)
│ ├── plugins/ # Nitro startup plugins (run on `pnpm dev` / `pnpm start`)
│ ├── public/ # Static assets (PWA, opengraph, templates, screenshots)
│ ├── locales/ # Lingui `.po` translation catalogs (~40 locales)
│ ├── src/
│ │ ├── components/ # Reusable web components grouped by feature
│ │ ├── dialogs/ # Global dialog system + dialog implementations
│ │ ├── hooks/ # App-level React hooks
│ │ ├── libs/ # Browser/server glue (auth, orpc, query, resume, theme, locale, pwa)
│ │ ├── routes/ # File-based TanStack Router routes (UI + `server.handlers`)
│ │ ├── router.tsx # Router factory (builds query client, context, SSR query integration)
│ │ ├── routeTree.gen.ts # GENERATED — do not hand-edit
│ │ ├── server.ts # Nitro fetch entry (wraps `react-start/server-entry`)
│ │ └── index.css # Tailwind v4 entry
│ ├── components.json # shadcn config
│ ├── lingui.config.ts # i18n extract config
│ ├── vite.config.ts # Vite + TanStack Start + Nitro + PWA + Lingui
│ └── vitest.config.ts
├── packages/
│ ├── ai/ # AI prompts, Zustand store, patch-resume tool
│ ├── api/ # oRPC routers, services, helpers, DTOs, rate-limit middleware
│ ├── auth/ # Better Auth config and helpers
│ ├── config/ # Shared tsconfig + vitest base configs
│ ├── db/ # Drizzle client + schema (Postgres)
│ ├── email/ # Nodemailer transport + react-email templates
│ ├── env/ # `@t3-oss/env-core` server env (auto-loads root `.env`)
│ ├── fonts/ # Google Fonts metadata
│ ├── import/ # JSON Resume / Reactive Resume v3/v4 importers
│ ├── pdf/ # React PDF document, fonts, 14 templates, shared primitives
│ ├── runtime-externals/ # Declares bcrypt, sharp, @aws-sdk/client-s3 as runtime-only
│ ├── schema/ # Zod schemas (resume data, templates, page, analysis, icons)
│ ├── scripts/ # Standalone tsx scripts (db reset, font generation)
│ ├── ui/ # Shared Base UI + shadcn-style components
│ └── utils/ # Small focused helpers (color, date, html, sanitize, etc.)
├── migrations/ # Drizzle-generated SQL + snapshots (one folder per migration)
├── docs/ # Project documentation
├── skills/ # Internal agent skill definitions
├── data/ # Local-FS storage root (when S3 is unset) — gitignored runtime data
├── .vite-hooks/ # Lefthook-managed git hooks (commit-msg, pre-commit)
├── .github/ # GitHub Actions / issue templates
├── .claude/ # Project-local Claude/Codex agent assets
├── .codex/
├── .planning/ # GSD planning + codebase maps (this directory)
├── .vscode/
├── compose.dev.yml # Postgres + SeaweedFS for local dev
├── compose.yml # Production-shaped compose
├── Dockerfile # Node 24 multi-stage build
├── AGENTS.md # Canonical agent guide (symlinked from CLAUDE.md)
├── README.md
├── SECURITY.md
├── LICENSE
├── package.json # Root scripts (turbo run …) + workspace devDeps
├── pnpm-workspace.yaml # `apps/*` + `packages/*`
├── pnpm-lock.yaml
├── turbo.json # Pipeline + globalEnv allowlist
├── biome.json # Biome (lint + format) config
├── knip.json # Dead-code/dep analysis config
├── lefthook.yml # Git hooks
├── commitlint.config.cjs
├── crowdin.yml # Translation sync config
├── tsconfig.json # Root TS solution config
├── vitest.shared.ts / vitest.setup.ts # Shared vitest config and global setup
├── .ncurc.cjs # npm-check-updates ignore list
├── .env.example # Documented env vars
└── .gitignore / .dockerignore
Directory Purposes
apps/web/:
- Purpose: The only deployed app — TanStack Start / React 19 / Vite / Nitro.
- Contains: Routes, components, dialogs, hooks, libs, server entry, build config.
- Key files:
apps/web/vite.config.ts,apps/web/src/router.tsx,apps/web/src/server.ts,apps/web/src/routes/__root.tsx,apps/web/plugins/1.migrate.ts,apps/web/plugins/2.storage.ts.
apps/web/src/routes/:
- Purpose: TanStack Router file-based route tree. Each file is either a UI route, a server-only endpoint (
server.handlers), or both. - Notable subtrees:
__root.tsx— global HTML shell, providers, head/meta, PWA scripts._home/— public marketing layout (route.tsx,index.tsx,-sections/{hero,features,faq,testimonials,...}.tsx).auth/— login/register/2FA/password flows and OAuth callback (oauth.ts).dashboard/— authenticated dashboard (route.tsx,index.tsx,resumes/,settings/{profile,preferences,api-keys,authentication,integrations,job-search,danger-zone}.tsx,-components/{header,sidebar,functions}.{ts,tsx}).builder/$resumeId/— resume builder (route.tsxshell,index.tsxbrowser-only preview,-components/,-sidebar/{left,right}/,-store/{section,sidebar}.ts).$username/$slug.tsx— public/shared resume route (ssr: "data-only").api/— server-only endpoints (rpc.$.ts,auth.$.ts,health.ts,openapi.$.ts,uploads/$userId.$.ts,-helpers/resume-pdf.ts).mcp/— Model Context Protocol server (index.ts,-helpers/{tools,resources,prompts,mcp-server-card,mcp-tool-names,tool-annotations}.ts).[.]well-known/— OAuth/OIDC/MCP discovery documents.uploads/$userId.$.tsx— etag/security-validated file serving.templates/$.tsx— template preview/download.schema[.]json.ts—/schema.jsonendpoint.
apps/web/src/components/:
- Purpose: Reusable, app-scoped components organized by domain.
- Subdirectories:
animation/— Motion-driven UI (comet-card,count-up,spotlight,text-mask).command-palette/— Cmd-K UI (index.tsx,store.ts,pages/).input/— Custom inputs (chip-input,color-picker,github-stars-button,icon-picker,rich-input,url-input).layout/— Error/loading/not-found screens, breakpoint indicator.level/,locale/,theme/,typography/— combobox/toggle utilities for those concerns.resume/— Builder preview surface (preview.tsx,preview.browser.tsx,preview.shared.tsx,pdf-canvas.tsx,builder-resume-draft.ts).ui/— App-level UI extensions (combobox.tsx,copyright.tsx).user/— User dropdown menu.
apps/web/src/libs/:
- Purpose: Glue between UI and external systems.
- Contents:
auth/{client.ts,session.ts}— Better Auth browser client + SSR session getter.orpc/client.ts— Isomorphic oRPC client (in-process server + RPCLink browser).query/client.ts— TanStack Query client factory.resume/— Section, PDF, and ordering helpers (make-section-item.ts,move-item.ts,section-actions.ts,section-title.ts,section-title-locale.ts,pdf-document.tsx,pdf-document.server.tsx,section.tsx).theme.ts,locale.ts,pwa.ts,error-message.ts,tanstack-form.tsx— direct app utilities.
apps/web/src/dialogs/:
- Purpose: Global imperative dialog system.
- Contents:
manager.tsx(renders open dialogs),store.ts(Zustand store), then domain dialogs underauth/,resume/{sections,template,index.tsx,import.tsx},api-key/.
apps/web/src/hooks/:
- Purpose: Web-app hooks. (Shared cross-package hooks live in
packages/ui/src/hooks/.) - Contents:
use-confirm.tsx,use-controlled-state.tsx,use-form-blocker.tsx,use-mobile.tsx,use-prompt.tsx,use-sync-form-values.ts.
apps/web/plugins/:
- Purpose: Nitro startup plugins.
- Contents:
1.migrate.ts(runs Drizzle migrations on boot),2.storage.ts(validates the local data dir when S3 isn't configured).
apps/web/public/:
- Purpose: Static assets served at the site root.
- Notable subdirs:
templates/{jpg,pdf}/(per-template previews),screenshots/(PWA + marketing),opengraph/,icon/,logo/,fonts/,photos/,sounds/,videos/. Top-level files includefavicon.{ico,svg},apple-touch-icon-180x180.png,manifest.webmanifest,pwa-{64,192,512}x.png,maskable-icon-512x512.png,robots.txt,sitemap.xml,funding.json.
apps/web/locales/:
- Purpose: Lingui
.potranslation catalogs (~40 languages,en-USis source). - Synced via
crowdin.ymlandpnpm lingui:extract.
packages/ai/:
- Purpose: AI prompt assets, patch-resume tool, sanitize/extraction helpers.
- Key paths:
packages/ai/src/prompts/{chat,analyze-resume,docx-parser,pdf-parser}-*.md,packages/ai/src/store.ts,packages/ai/src/tools/{patch-resume,patch-proposal}.ts,packages/ai/src/resume/{extraction-template,sanitize}.ts.
packages/api/:
- Purpose: Server-side business logic exposed over oRPC. The only place oRPC procedures live.
- Key paths:
packages/api/src/context.ts(auth context +publicProcedure/protectedProcedure),packages/api/src/routers/{ai,auth,flags,resume,statistics,storage,index}.ts,packages/api/src/services/{resume,resume-events,storage,ai,auth,flags,statistics}.ts,packages/api/src/dto/resume.ts,packages/api/src/helpers/{resume-access,resume-access-policy}.ts,packages/api/src/middleware/rate-limit/index.ts.
packages/auth/:
- Purpose: Better Auth instance and types reused by web routes and API context.
- Key paths:
packages/auth/src/config.ts(Drizzle adapter, OAuth/passkey/2FA/api-key/JWT/MCP OAuth provider),packages/auth/src/functions.ts,packages/auth/src/types.ts.
packages/config/:
- Purpose: Shared tsconfig and vitest base configs consumed via workspace devDep.
- Key paths:
packages/config/tsconfig.base.json,packages/config/vitest.config.ts.
packages/db/:
- Purpose: Drizzle client and schema. Migration tooling but migrations live in repo-root
migrations/(packages/db/drizzle.config.ts→out: "../../migrations"). - Key paths:
packages/db/src/client.ts(singletonpg.Pool+drizzle()onglobalThis),packages/db/src/schema/{auth,resume,index}.ts,packages/db/src/relations.ts.
packages/email/:
- Purpose: SMTP transport + react-email templates.
- Key paths:
packages/email/src/transport.ts,packages/email/src/templates/{auth,reset-password,verify-email,verify-email-change}.tsx.
packages/env/:
- Purpose: Type-safe server environment variables. Auto-loads the repo-root
.envfor app/server callers (drizzle-kit must exportDATABASE_URLmanually). - Key paths:
packages/env/src/server.ts.
packages/fonts/:
- Purpose: Generated Google Fonts metadata used by the typography combobox and React PDF font registration.
- Key paths:
packages/fonts/src/index.ts,packages/fonts/src/webfontlist.json(regenerated bypackages/scripts/fonts/generate.ts).
packages/import/:
- Purpose: Importers that convert external resume formats into the shared
ResumeDataschema. - Key paths:
packages/import/src/{json-resume,reactive-resume-json,reactive-resume-v4-json}.tsx.
packages/pdf/:
- Purpose: React PDF rendering — the same code paths used by the browser preview and the server-side PDF download.
- Key paths:
packages/pdf/src/document.tsx,packages/pdf/src/context.tsx,packages/pdf/src/section-title.ts,packages/pdf/src/hooks/use-register-fonts.ts,packages/pdf/src/templates/index.ts,packages/pdf/src/templates/<name>/<Name>Page.tsx(14 templates:azurill,bronzor,chikorita,ditgar,ditto,gengar,glalie,kakuna,lapras,leafish,meowth,onyx,pikachu,rhyhorn,scizor), shared primitives underpackages/pdf/src/templates/shared/(filtering.ts,rich-text.tsx,sections.tsx,primitives.tsx,picture.ts,page-size.ts,columns.ts,metrics.ts,meta-line.tsx,contact.ts,contact-item.tsx,level-display.tsx,section-links.ts,rich-text-html.ts,rich-text-spacing.ts,styles.ts,types.ts,context.tsx).
packages/runtime-externals/:
- Purpose: Vendors
bcrypt,sharp,@aws-sdk/client-s3so they stay runtime-only (Vite externalizes them inapps/web/vite.config.ts:55). - No
src/—package.jsonis the entire surface.
packages/schema/:
- Purpose: Source-of-truth Zod schemas for resume data, templates, page settings, AI analysis, and icon catalog.
- Key paths:
packages/schema/src/resume/{data,default,sample,analysis}.ts,packages/schema/src/templates.ts,packages/schema/src/page.ts,packages/schema/src/icons.ts.
packages/scripts/:
- Purpose: Standalone tsx scripts; no exports.
- Key paths:
packages/scripts/database/reset.ts(pnpm --filter @reactive-resume/scripts db:reset),packages/scripts/fonts/generate.ts(pnpm --filter @reactive-resume/scripts fonts:generate).
packages/ui/:
- Purpose: Shared component library (Base UI primitives + shadcn-style wrappers, Tailwind v4 styles).
- Key paths:
packages/ui/src/components/{dialog,dropdown-menu,command,resizable,form,tooltip,sonner,…}.tsx,packages/ui/src/hooks/{use-confirm,use-controlled-state,use-mobile,use-prompt}.tsx,packages/ui/src/styles/globals.css.
packages/utils/:
- Purpose: Pure utility functions used everywhere. Each helper has its own export path; do not import internal files.
- Key paths:
packages/utils/src/{color,date,field,file,html,level,locale,network-icons,rate-limit,sanitize,string,style,url}.ts, Node-onlypackages/utils/src/{monorepo.node,url-security.node}.ts, andpackages/utils/src/resume/{docx/index.ts,patch.ts}.
migrations/:
- Purpose: Drizzle-generated migration directories (one per migration), kept at the repo root.
- Layout: each
YYYYMMDDhhmmss_<adjective>_<noun>/containsmigration.sql(the SQL Drizzle will apply) andsnapshot.json(Drizzle's internal state). - Applied by
apps/web/plugins/1.migrate.tson every server boot, and manually bypnpm db:migrate. Generated bypnpm db:generate(which writes here because ofout: "../../migrations"inpackages/db/drizzle.config.ts). Do not hand-editmigration.sql/snapshot.json.
data/ (and apps/web/data/):
- Purpose: Default local-filesystem storage root when S3 vars are unset.
<workspace>/datais validated/created at boot byapps/web/plugins/2.storage.ts. Override withLOCAL_STORAGE_PATH(must be absolute). data/statistics/andapps/web/data/statistics/exist as runtime byproducts; treat as gitignored runtime state.
.vite-hooks/:
- Purpose: Lefthook-managed git hooks (
pre-commitrunsbiome check,commit-msgruns commitlint). Configured bylefthook.ymlandcommitlint.config.cjs.
.planning/:
- Purpose: GSD planning artifacts.
- Subdirectories:
.planning/codebase/(this directory — analysis docs).
Key File Locations
Entry Points:
apps/web/src/server.ts— Nitro fetch entry.apps/web/src/router.tsx— Router factory.apps/web/src/routes/__root.tsx— Root route + global providers.apps/web/plugins/1.migrate.ts— Migration on boot.apps/web/plugins/2.storage.ts— Local storage validation on boot.
Configuration:
apps/web/vite.config.ts— Vite + TanStack Start + Nitro + PWA + Lingui.turbo.json— Pipeline +globalEnvallowlist.pnpm-workspace.yaml— Workspaces (apps/*+packages/*).biome.json— Lint + format rules.knip.json— Dead-code analysis config.lefthook.yml— Git hooks.packages/db/drizzle.config.ts— Drizzle migration config (writes to../../migrations).packages/env/src/server.ts— Server env schema +.envloader.apps/web/lingui.config.ts— i18n extract config.compose.dev.yml/compose.yml— Postgres + SeaweedFS (dev) and prod-shaped compose.
Core API:
packages/api/src/routers/index.ts— Router root.packages/api/src/context.ts— Auth resolver + procedure factories.packages/api/src/services/resume.ts— Resume CRUD/patch/lock/password/duplication.packages/api/src/services/storage.ts— S3 + local FS storage abstraction.packages/api/src/helpers/resume-access-policy.ts— Visibility/redaction policy.
Core data:
packages/db/src/schema/resume.ts— Resume, statistics, analysis tables.packages/db/src/schema/auth.ts— Better Auth tables.packages/db/src/client.ts— Singletonpg.Pool+drizzle()client.packages/schema/src/resume/data.ts— Canonical Zod schema forResumeData.packages/schema/src/templates.ts— Enum of template names.
Core PDF:
packages/pdf/src/document.tsx—ResumeDocumentroot component.packages/pdf/src/templates/index.ts— Template registry.packages/pdf/src/hooks/use-register-fonts.ts— Font registration + CJK fallbacks.packages/pdf/src/templates/shared/filtering.ts— Shared section filtering.
Auth:
packages/auth/src/config.ts— Better Auth instance.apps/web/src/routes/api/auth.$.ts—/api/auth/*handler with OAuth sanitization.apps/web/src/libs/auth/{client.ts,session.ts}— Browser client + SSR session helper.
Testing:
vitest.shared.ts,vitest.setup.ts— Repo-wide setup (Testing Library, jest-dom, happy-dom env).packages/config/vitest.config.ts— Reusable Vitest base.apps/web/vitest.config.ts— Web app Vitest config.
Naming Conventions
Files:
- Source files:
kebab-case.ts/kebab-case.tsx(e.g.resume-access-policy.ts,command-palette.tsx). - Component PascalCase is reserved for component names inside files; filenames stay kebab-case (e.g.
Buttonexported frompackages/ui/src/components/button.tsx). - PDF template components are the one PascalCase exception:
packages/pdf/src/templates/azurill/AzurillPage.tsx(kept that way because the directory name doubles as the template enum value). - Tests sit next to their subject:
foo.ts↔foo.test.ts,foo.tsx↔foo.test.tsx. - Browser-only modules use a
.browser.tsxsuffix (e.g.apps/web/src/components/resume/preview.browser.tsx). - Server-only modules use a
.server.tsxsuffix when they live next to browser counterparts (e.g.apps/web/src/libs/resume/pdf-document.server.tsx). - Generated files use
.gen.ts(e.g.apps/web/src/routeTree.gen.ts). - Node-only utilities use a
.node.tssuffix (e.g.packages/utils/src/monorepo.node.ts,packages/utils/src/url-security.node.ts).
Routes (TanStack Router file conventions):
$param.tsx— dynamic path segment (e.g.apps/web/src/routes/$username/$slug.tsx).$.tsx— splat (matches the rest of the path; used forapi/rpc/$,api/auth/$,[.]well-known/$)._layout/(underscore prefix) — pathless layout group (e.g.apps/web/src/routes/_home/).-folder/(dash prefix) — colocated, non-route helpers (-components/,-sidebar/,-store/,-sections/,-helpers/). The router ignores these.[.]well-known— escaped folder name for paths starting with a dot.name[.]json.ts— escaped dot in a route filename (used for/schema.json).route.tsx— layout/wrapper route at a directory level;index.tsx— index route inside it.
Directories:
apps/<app>andpackages/<name>— kebab-case workspace members.packages/<name>/src/<subdomain>/<file>.ts— every public path inpackage.jsonexports points intosrc/.
Package names: All workspace packages are scoped under @reactive-resume/* (api, auth, db, ui, etc.). The web app is just web.
Where to Add New Code
New oRPC procedure:
- Define in
packages/api/src/routers/<domain>.ts, register it on the exported router map, and add corresponding business logic topackages/api/src/services/<domain>.ts. - If authenticated, prefer
protectedProcedurefrompackages/api/src/context.ts. - If it mutates resumes, attach
resumeMutationRateLimitfrompackages/api/src/middleware/rate-limit/index.ts. - Define input/output Zod schemas in
packages/api/src/dto/<domain>.tswhen reused.
New database table or column:
- Add the table/column to
packages/db/src/schema/<file>.ts, updatepackages/db/src/relations.tsif needed, re-export frompackages/db/src/schema/index.ts. - Run
DATABASE_URL=... pnpm db:generateto write a migration directory undermigrations/. - Apply with
DATABASE_URL=... pnpm db:migrate(or just start the app —apps/web/plugins/1.migrate.tsruns them on boot).
New resume field or section:
- Update Zod first in
packages/schema/src/resume/data.ts(anddefault.ts/sample.tsif applicable). - Adjust API DTOs (
packages/api/src/dto/resume.ts), importers (packages/import/src/*.tsx), PDF templates and shared primitives (packages/pdf/src/templates/...), and the builder forms underapps/web/src/routes/builder/$resumeId/-sidebar/.
New resume template:
- Add to the template enum in
packages/schema/src/templates.ts. - Implement the page component at
packages/pdf/src/templates/<name>/<Name>Page.tsxand register it inpackages/pdf/src/templates/index.ts. - Drop static previews into
apps/web/public/templates/jpg/<name>.jpgandapps/web/public/templates/pdf/<name>.pdf.
New web route:
- Add the file under
apps/web/src/routes/.... Use$param.tsxfor dynamic segments,_layout/for pathless groups, and-folder/for colocated helpers. - The route tree regenerates into
apps/web/src/routeTree.gen.ts— do not hand-edit. - For browser-only sub-routes, set
ssr: false(seeapps/web/src/routes/builder/$resumeId/index.tsx) orssr: "data-only"(seeapps/web/src/routes/$username/$slug.tsx).
New server-only HTTP endpoint:
- Add a route file (typically under
apps/web/src/routes/api/) and exportRoute = createFileRoute(...)({ server: { handlers: { GET/POST/ANY: handler } } }). - Import server-only deps (
@reactive-resume/db/client,@reactive-resume/api/services/*) only inside the handler module so they stay out of the client bundle.
New shared component:
- App-only:
apps/web/src/components/<group>/<name>.tsx(with colocated test if behaviour is non-trivial). - Reused across packages:
packages/ui/src/components/<name>.tsx(export via deep path@reactive-resume/ui/components/<name>).
New shared utility:
- Add to
packages/utils/src/<topic>.tsand an explicit"./<topic>": "./src/<topic>.ts"entry inpackages/utils/package.jsonexports. Never import private files across packages.
New dialog:
- Implement under
apps/web/src/dialogs/<group>/<name>.tsx. - Register with the dialog store and ensure
apps/web/src/dialogs/manager.tsxrenders it.
New AI prompt or tool:
- Prompts go in
packages/ai/src/prompts/<name>.md(re-exported viapackages/ai/src/prompts.ts). - Tools go in
packages/ai/src/tools/<name>.tsand are exposed through the AI router inpackages/api/src/routers/ai.ts.
New MCP tool/resource/prompt:
- Register in
apps/web/src/routes/mcp/-helpers/{tools,resources,prompts}.ts; reuse existing oRPC services for actual logic.
Special Directories
apps/web/src/routes/:
- Purpose: Source for the file-based route tree.
- Generated artifact:
apps/web/src/routeTree.gen.ts. - Committed: Yes (the tree file is committed; regenerated by TanStack Router tooling on dev/build).
migrations/:
- Purpose: Drizzle-generated SQL + snapshots.
- Generated: Yes (by
pnpm db:generate). - Committed: Yes — do not hand-edit, but always commit new migration folders.
apps/web/.output/:
- Purpose: Nitro/Vite production build output (server + client + PWA assets).
- Generated: Yes (by
pnpm build). - Committed: No (gitignored).
apps/web/locales/:
- Purpose: Lingui
.pocatalogs. - Generated:
en-US.pois the source; other locales are synced via Crowdin (crowdin.yml). - Committed: Yes.
data/ and apps/web/data/:
- Purpose: Default local storage root when S3 is unset (
<workspace>/data). - Generated: Yes (at runtime by
apps/web/plugins/2.storage.tsor service calls). - Committed: No (gitignored runtime state).
.turbo/, .pnpm-store/, node_modules/:
- Purpose: Tool caches and dependency stores.
- Committed: No.
.vite-hooks/:
- Purpose: Lefthook-installed git hooks (
commit-msg,pre-commit). - Committed: Yes (so contributors get hooks automatically), but the underlying behavior is defined by
lefthook.yml.
packages/runtime-externals/:
- Purpose: Marks
bcrypt,sharp,@aws-sdk/client-s3as runtime dependencies that Vite externalizes. - No source files — package.json is the entire contract.
Files / Locations to Avoid Hand-Editing
apps/web/src/routeTree.gen.ts— regenerated by TanStack Router tooling.migrations/<timestamp>_<name>/migration.sqlandsnapshot.json— generated bydrizzle-kit. Add a new migration viapnpm db:generateinstead of editing past ones.pnpm-lock.yaml— managed by pnpm. Update viapnpm install.apps/web/.output/,apps/web/coverage/,packages/*/coverage/,packages/*/reports/— build/test artifacts.apps/web/locales/*.po(excepten-US.po) — synced from Crowdin percrowdin.yml.apps/web/public/screenshots/,apps/web/public/opengraph/,apps/web/public/templates/{jpg,pdf}/— regenerated assets; replace files wholesale rather than diff-editing.
Structure analysis: 2026-05-11