Package reference
The framework is distributed as six packages under the @drawnagency npm scope. All are published as ESM with declaration files. The build toolchain (tsup and typescript) is declared only in the root devDependencies — by design, so packages can build via pnpm’s workspace hoisting without each declaring the toolchain separately.
Each package’s build script runs:
tsup && rm -f tsconfig.tsbuildinfo && tsc --emitDeclarationOnlytsup produces the Node-compatible ESM bundle with correct .js extensions; tsc --emitDeclarationOnly writes .d.ts files alongside it.
@drawnagency/primitives
Section titled “@drawnagency/primitives”Purpose: The shared foundation. Contains the section registry, defineSection helper, all Zod schemas, shared React components (editor UI, viewer section shells), auth types, media types, and utility libraries. Every other package depends on this one.
Internal deps: None.
Key exports:
| Entry path | Contents |
|---|---|
. (root) | defineSection, registerSection, registerSchema, getAllSections, getAllSchemas, SectionDefinition, auth types, AuthProvider, Session, Audience, media types |
./lib/registry | Full registry API: createRegistry, registerSection, registerSchema, registerRichText, getSection, getSchema, getAllSections, getAllSchemas, clearRegistry |
./schemas | Barrel for all Zod schemas |
./schemas/auth | Audience, Session, auth Zod schemas |
./schemas/block | Block/content Zod schemas |
./schemas/link | LinkValue and link Zod schema |
./lib/dexie | Dexie-based in-memory edit store |
./lib/env | env() helper (with guarded process.env fallback) |
./lib/platform-broker | Platform API client |
./lib/registry | Registry module (see above) |
./components/sections/register-schemas | ensureSchemasRegistered() — registers all built-in schemas |
./components/sections/brand-guide | brandGuideSectionDefs array + color schema exports |
./components/editor | Editor React components |
./components/primitives | Shared primitive React components |
./auth | Auth helper exports |
./media | Media helper exports |
The package ships both dist/ (compiled) and src/ (source). The Astro integration aliases all primitives import paths to src/ during dev and SSR builds — see SSR / Netlify gotchas.
@drawnagency/assets-r2
Section titled “@drawnagency/assets-r2”Purpose: The Cloudflare R2 storage adapter — the optional bucket half of the storage model (videos, large documents). Ships a dependency-free SigV4 signer, so it pulls in no AWS SDK. Imported by the template’s default portal.config.mjs.
Internal deps: @drawnagency/primitives (workspace:^) — for the AssetStore / DocumentStore interfaces.
Key exports:
| Entry path | Contents |
|---|---|
. (root) | r2Assets() → AssetStore, r2Documents() → DocumentStore |
Standalone (“.env”) mode reads R2_ACCOUNT_ID, R2_BUCKET, the access key pair and PORTAL_SITE_ID; platform mode goes through the broker instead. A portal may have no bucket at all — GitHub-backed media works without one, so never assume these are configured. See the storage-model notes in the SSR / Netlify rules.
@drawnagency/authoring
Section titled “@drawnagency/authoring”Purpose: CLI tooling and Claude skills for populating client sites. Provides the authoring binary (used via pnpm exec authoring) with subcommands validate, process-images and upload-video. Also ships the /populate-site skill into client repos via postinstall.
Internal deps: @drawnagency/primitives (workspace:^), @drawnagency/assets-r2 (workspace:^ — the R2 signer behind upload-video).
Key exports:
| Entry path | Contents |
|---|---|
. (root) | Public API for authoring utilities |
bin/authoring | CLI binary: validate --project <path>, process-images --project <path>, upload-video <file> --project <path> --width <n> --height <n> |
files in package.json includes dist/, skills/, and scripts/. The skills/ directory contains the /populate-site skill; scripts/link-skills.mjs is run by client repos’ postinstall to symlink it into .claude/skills/.
@drawnagency/github
Section titled “@drawnagency/github”Purpose: GitHub storage adapter. Handles reading and writing content files and media to a GitHub repository via the GitHub REST API (@octokit/rest). Exports githubStorage(), the StorageProvider implementation used in portal.config.mjs.
Internal deps: @drawnagency/primitives (workspace:^).
Key exports:
| Entry path | Contents |
|---|---|
. (root) | githubStorage() — returns a StorageProvider |
@drawnagency/auth-supabase
Section titled “@drawnagency/auth-supabase”Purpose: Supabase auth adapter. Wraps @supabase/supabase-js and @supabase/ssr to implement the AuthProvider interface from @drawnagency/primitives. Handles OAuth sign-in, session cookies, audience management, and invite flows.
Internal deps: @drawnagency/primitives (workspace:^).
Key exports:
| Entry path | Contents |
|---|---|
. (root) | supabaseAuth() — returns an AuthProvider; createSupabaseAuth() for advanced use |
@drawnagency/core
Section titled “@drawnagency/core”Purpose: The Astro integration and all server-side page/API routes. Injects viewer and editor routes, middleware, API endpoints, and the Vite plugin configuration into the client Astro project. Also exports the defineConfig helper and the password-only auth adapter.
Internal deps: @drawnagency/primitives (workspace:^), @drawnagency/github (workspace:^).
Key exports:
| Entry path | Contents |
|---|---|
. (root) | The Astro integration (default export); do not import this in browser code — it pulls in node:url, node:fs, etc. |
./config | defineConfig() helper — import this in portal.config.mjs |
./password | createPasswordAuth() — the password-only auth adapter |
./styles/base.css | Base Tailwind CSS; client repos @import this from their own src/styles/base.css |
The ./config and ./password entry points resolve to src/ files directly (not dist/) so they can be used in contexts where dist/ may not have been built (e.g. apps/admin uses only import type from core; portal.config.mjs must import defineConfig from ./config specifically).
@drawnagency/platform (private — not published)
Section titled “@drawnagency/platform (private — not published)”Purpose: The platform-side provisioning and access core shared by apps/admin and apps/mcp. Contains provisionSite/teardownSite, the GitHub App/Netlify/Cloudflare provider clients, the service-role Supabase admin client, and checkPlatformAccess (the platform_users/allowed_signups gate).
Internal deps: @drawnagency/primitives — import type only (no runtime import, so no primitives dist/ is required by consumers).
Key difference from the published six: every export points at ./src/*.ts — there is no build step and no dist/. apps/admin bundles it from source via vite.ssr.noExternal (its Netlify build runs without build:packages); apps/mcp bundles it with esbuild. CI’s check-admin-isolation gate fails the build if this package ever grows a dist-pointing export. It is excluded from scripts/publish.sh and has no build script, so “build all six packages” remains literally six.