CI and local validation
Clay does not run a hosted CI pipeline today. Validation happens through the local scripts inapps/specs/package.json and apps/backend/package.json, coordinated by turbo.json at the repo root. This page is the contract for what those scripts do and when to run them.
Treat every script on this page as a local gate. Before pushing, the same commands should pass on
a developer machine. When a hosted CI lands, these are the commands it should run.
Local scripts
The specs package (@clay/specs) owns site authoring, validation, and deploy. Run these from
apps/specs/ or via pnpm --filter @clay/specs <script>.
| Script | Command | Purpose |
|---|---|---|
dev | pnpm dev | Mintlify live preview at localhost:3000. Hot-reloads MDX changes while authoring. |
build | pnpm build | Export the static site to .mintlify-export/. Produces a deployable bundle. |
cf:deploy | pnpm cf:deploy | Publish .mintlify-export/ to the clay-specs Cloudflare Pages project. |
deploy | pnpm deploy | Alias for cf:deploy. |
validate | pnpm validate | Run Mintlify’s strict build validation. Frontmatter, navigation, and config are checked. |
lint | pnpm lint | Alias for validate. |
broken-links | pnpm broken-links | Scan internal Mintlify links for breakage. |
a11y | pnpm a11y | Run accessibility checks across the authored pages. |
format | pnpm format | Prettier write across MDX, JSON, and category folders. Uses --ignore-path ../../.prettierignore. |
format:check | pnpm format:check | Prettier check only. CI-friendly: same scope as format without writing. |
clean | pnpm clean | Remove .mintlify-export/ and the zip artifact. |
Backend scripts
The backend package (@clay/backend) owns OpenAPI generation, typechecking, and Worker deploy.
Run these from apps/backend/ or via pnpm --filter @clay/backend <script>.
| Script | Command | Purpose |
|---|---|---|
dev | pnpm dev | wrangler dev — start the Worker locally. |
generate | pnpm generate | Export the live Hono app’s OpenAPI document to openapi/openapi.yaml. The client and Redocly lint depend on this output. |
openapi:export | pnpm openapi:export | Run scripts/export-openapi.ts directly. generate is the public alias. |
build | pnpm build | Alias for typecheck. The Worker itself is built by Wrangler on deploy. |
deploy | pnpm deploy | wrangler deploy — publish the Worker. |
lint | pnpm lint | Alias for openapi:check. |
openapi:check | pnpm openapi:check | redocly lint openapi/openapi.yaml — lint the exported OpenAPI document. |
typecheck | pnpm typecheck | tsc --noEmit across apps/backend. |
types:wrangler | pnpm types:wrangler | Refresh worker-configuration.d.ts from wrangler.toml. |
format | pnpm format | Prettier write across src/, scripts/, and config files. |
format:check | pnpm format:check | Prettier check across apps/backend sources. |
clean | pnpm clean | Remove the generated openapi/ directory. |
Workspace turbo tasks
turbo.json orchestrates the scripts above across packages. The most useful entry points:
pnpm typecheck
Runs
typecheck everywhere. Backend and the generated client both depend on generate first,
so OpenAPI export runs automatically.pnpm lint
Runs
lint everywhere. For @clay/backend this means Redocly against the freshly exported
OpenAPI.pnpm build
Runs
build everywhere with ^build and ^generate as dependencies. The specs build exports
the static site; the backend build typechecks.pnpm generate
Runs the
generate task everywhere. Backend exports OpenAPI; the client regenerates from it.Workspace-wide commands
The rootpackage.json exposes a few commands that fan out across the workspace. They compose
the package scripts through Turbo and Prettier.
| Command | Purpose |
|---|---|
pnpm dev | turbo run dev — runs every package’s dev script in parallel and watches for changes. |
pnpm generate | turbo run generate — backend exports OpenAPI, client regenerates the SDK, etc. |
pnpm build | turbo run build — typecheck across packages plus the Next.js production build. |
pnpm lint | turbo run lint — Redocly on the backend OpenAPI document and Mintlify validate on the specs site. |
pnpm typecheck | turbo run typecheck — tsc --noEmit everywhere. |
pnpm md:frontmatter | node scripts/check-markdown-frontmatter.mjs — verify YAML frontmatter on every tracked *.md and *.mdx. |
pnpm format:all | Prettier write across the whole repo (every supported extension), respecting .prettierignore. |
pnpm format:check | Prettier check across the whole repo. CI-friendly. |
pnpm all | The full chain: generate && format && build && lint && typecheck. The “did everything pass?” command. |
pnpm deploy | pnpm run build && turbo run deploy — publishes every deployable surface. Ask before running. |
Deploy gate
A change is deployable when:pnpm typechecksucceeds across the workspace.pnpm lintsucceeds across the workspace (Redocly + Mintlify validate).pnpm --filter @clay/specs format:checksucceeds.pnpm --filter @clay/specs broken-linksreports no broken internal links.pnpm --filter @clay/specs buildproduces a clean static export.pnpm md:frontmatterreports no frontmatter failures on tracked Markdown.
When a script fails
Read the failure top-down
Mintlify, Redocly, and
tsc each report the first failure clearly. Fix the first error before
chasing later ones — many later failures cascade.Check input freshness
If
typecheck or lint fails after a schema change, make sure pnpm generate has been run so
openapi/openapi.yaml matches the live Hono app.Clear the cache when in doubt
For
turbo run issues, clear node_modules/.cache/turbo and rerun. For Mintlify preview
issues, delete .mintlify and restart pnpm dev.Related
Testing policy
What counts as verification in Clay, and why there are no automated tests.
Workspace
The pnpm + Turborepo contracts that wire these scripts together.
Architecture
The app surfaces these CI scripts protect.
Decisions
ADRs that justify the choices behind this validation layout.

