Monorepo & dev workflow
The portal framework lives in a single pnpm workspace with two top-level groups:
packages/— the five published@drawnagency/*packagesapps/— the in-repo dev site (apps/dev), admin provisioner (apps/admin), and this docs site (apps/docs)
Getting started
Section titled “Getting started”Clone the monorepo and install:
git clone git@github.com:Drawn-Agency/portal.gitcd portalpnpm installpnpm links all workspace packages via workspace:* entries. No separate build step is needed before starting the dev server. The repo is pnpm-only — a preinstall hook runs npx only-allow pnpm, so npm install / yarn are rejected.
Running the dev server
Section titled “Running the dev server”pnpm devThis runs apps/dev on localhost. apps/dev depends on the packages via workspace:*, so Vite’s HMR picks up changes to package source files immediately — no rebuild needed for:
- Routes and middleware (
packages/core/src/pages/,packages/core/src/middleware.ts) - Components, hooks, and schemas (
packages/primitives/src/) - Auth adapters (
packages/auth-supabase/src/,packages/core/src/lib/password.ts) - GitHub client (
packages/github/src/)
When a rebuild is required
Section titled “When a rebuild is required”HMR only covers files that Vite can hot-reload. A full package rebuild is needed when you change compiled files — anything tsc processes into the dist/ output that other packages or consumers import from dist/:
packages/core/src/config.ts,index.ts,integration.ts,vite-plugin.tspackages/primitives/src/**/index.ts(barrel exports)- Type declarations
pnpm -r --filter './packages/*' buildThen restart the dev server. The build script in every package runs tsup && rm -f tsconfig.tsbuildinfo && tsc --emitDeclarationOnly — tsup produces the ESM bundle, tsc emits declaration files only.
Running tests
Section titled “Running tests”pnpm vitest run # run all tests oncepnpm vitest run --watch # watch modepnpm vitest run tests/lib/auth # specific directoryTests live in tests/ mirroring src/, and use Vitest + @testing-library/react.
Package dependency graph
Section titled “Package dependency graph”primitives (leaf — no internal deps)├── authoring (depends on primitives)├── github (depends on primitives)├── auth-supabase (depends on primitives)└── core (depends on primitives + github)Build order for the full workspace is: primitives → authoring → github → auth-supabase → core. scripts/publish.sh enforces this order automatically; when building manually use pnpm -r --filter './packages/*' build (pnpm respects the workspace dependency graph and builds in the correct order).
Running a client site against your local packages
Section titled “Running a client site against your local packages”pnpm dev runs the in-repo apps/dev site — the fastest loop for iterating on package code. To instead see your local changes in a real client portal (with its actual content and config), link your local packages into a client checkout. The dev-link script automates this; pack/link are the manual alternatives.
pnpm dev-link <client-site-path> (recommended)
Section titled “pnpm dev-link <client-site-path> (recommended)”scripts/dev-link.sh wires your local packages into an existing client repo, runs its dev server, and cleans up after itself on exit:
pnpm dev-link ~/flavcity-portal# equivalent: bash scripts/dev-link.sh ~/flavcity-portalThe client repo must already exist locally with a package.json (e.g. a checkout of a Drawn-Agency/*-portal repo). The script:
- Backs up the client’s
package.json(topackage.json.devlink-backup). - Adds pnpm
overridespointing@drawnagency/primitives,@drawnagency/core,@drawnagency/auth-supabase, and@drawnagency/githubat your localpackages/*vialink:. (@drawnagency/authoringis not linked.) - Adds missing transitive deps — scans those four packages’
dependenciesand adds any the client repo doesn’t already declare, so its Vite can resolve them. - Runs
pnpm installin the client repo. - Clears the client’s on-disk GitHub API cache (
.portal/api-cache) — it’s keyed only by branch, so a cache written by an older package build would otherwise be served stale. - Starts the client dev server with
PORTAL_DEV_CACHE=true pnpm dev --host. GitHub API responses are cached locally for speed; append?refresh=trueto a request to bust the cache. - On exit (Ctrl-C), a trap restores the original
package.jsonand reinstalls, leaving the client repo clean.
Edits to package source files reflect live (the packages are linked); changes to compiled files still need a package rebuild (see When a rebuild is required above), then restart.
Manual option A: pack (simulates a real publish)
Section titled “Manual option A: pack (simulates a real publish)”pnpm -r --filter './packages/*' buildcd packages/primitives && pnpm pack# repeat for other packages as needed
# In the client repo:pnpm install ~/portal/packages/primitives/drawnagency-primitives-X.Y.Z.tgzManual option B: link
Section titled “Manual option B: link”# In the client repo:pnpm link ~/portal/packages/primitivespnpm link ~/portal/packages/authoringpnpm link ~/portal/packages/githubpnpm link ~/portal/packages/auth-supabasepnpm link ~/portal/packages/core
# Unlink when done:pnpm unlink @drawnagency/primitives @drawnagency/authoring @drawnagency/github @drawnagency/auth-supabase @drawnagency/corepnpm install # restore published versions