No description
- TypeScript 96.4%
- CSS 3.3%
- JavaScript 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .agents/skills | ||
| .claude/skills | ||
| .forgejo/workflows | ||
| .github | ||
| .vscode | ||
| apps/web | ||
| packages | ||
| patches | ||
| .gitignore | ||
| .npmrc | ||
| .yarnrc | ||
| AGENTS.md | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| skills-lock.json | ||
| turbo.json | ||
Shipment
A Payload 4 + TanStack Start template on Cloudflare Workers (D1 + R2), and the in-house Payload plugins it uses, in one pnpm + Turborepo workspace.
| Path | Package | What it is |
|---|---|---|
apps/web |
@shipment/web |
The template app: Payload admin + TanStack Start frontend, deployed as one Worker. See its README. |
packages/payload-seo-analyzer |
@shipment/payload-seo-analyzer |
SEO analysis plugin (Payload 4 port of @consilioweb/payload-seo-analyzer). See its README. |
packages/payload-plugin-socials |
@shipment/payload-plugin-socials |
Social publishing to Pinterest, Instagram, Facebook Pages and Google Business Profile (Payload 4 port of payload-plugin-socials). Registered in the app, but off until SOCIALS_ENCRYPTION_KEY is set (the app composes Pinterest only). See its README. |
packages/payload-plugin-ab |
@shipment/payload-plugin-ab |
A/B testing: page variants with traffic shares in the admin, and a framework-agnostic request resolver (Payload 4 port of @focus-reactive/payload-plugin-ab). Registered on Pages; loadPage routes visitors. See its README. |
packages/payload-plugin-mcp |
@shipment/payload-plugin-mcp |
Our fork of @payloadcms/plugin-mcp (MCP server at POST /api/mcp) with an OAuth 2.1 server, so ChatGPT and claude.ai can connect. Pinned to one Payload version, not the catalog. It replaces upstream and keeps its plugin slug: never install both. Registered in the app (see the app's README). See the plugin's README. |
packages/payload-plugin-assistant |
@shipment/payload-plugin-assistant |
Admin assistant: chat with the content through the MCP tools (TanStack AI + OpenRouter, a Durable Object per conversation). Registered in the app at /admin/assistant (see the app's README). See its README. |
packages/onpage |
@shipment/onpage-* |
On-page editing ("Edit on page"): five packages (core, plugin, react, lexical, tanstack-start), our fork of payload-onpage. Registered in the app through onpage(). See its README. |
Quick start
echo "PAYLOAD_SECRET=$(openssl rand -hex 32)" > apps/web/.env.development.local
pnpm install
pnpm web migrate
pnpm dev
pnpm web migrate builds the local D1 database from the committed migrations; run it again after pulling new ones. pnpm dev builds the plugins once, keeps them rebuilding on change (tsup --watch; the onpage packages have no watch mode, so rebuild them with pnpm turbo run build --filter='./packages/onpage/*'), and starts the app at http://localhost:3000.
Commands
| Command | Runs |
|---|---|
pnpm dev |
Plugins in watch mode + the app's dev server |
pnpm build |
build in every package, plugins first |
pnpm typecheck / pnpm lint |
Across all packages |
pnpm test |
Package unit tests + the app's integration and e2e tests |
pnpm test:int |
The app's Local API integration tests |
pnpm web <script> |
Any app script, e.g. pnpm web migrate:create, pnpm web run deploy (run is needed: deploy is also a pnpm command), pnpm web generate:importmap |
pnpm --filter @shipment/payload-seo-analyzer <script> |
Any plugin script |
Turbo caches build, typecheck and lint; anything that depends on a plugin builds it first (dependsOn: ["^build"]).
Workspace conventions
- Shared versions live in the pnpm catalog (
pnpm-workspace.yaml):payload, every@payloadcms/*package, React and TypeScript. Packages reference them as"catalog:". Upgrade Payload by editing the catalog once. Keeping them shared also guarantees one copy ofpayloadand@payloadcms/uiat runtime; two copies break the admin's React contexts. - Plugins go in
packages/<name>, named@shipment/<name>,"private": true, built with tsup todist/, and consumed by the app as"workspace:*". Declarepayload/@payloadcms/ui/reactas peer dependencies and take the dev versions from the catalog. - onpage is the exception: its five packages live in
packages/onpage/*(named@shipment/onpage-*) and build withtsc -b, one output file per source, which keeps'use client'and the lazy editor chunk. Its tests, lint and typecheck run frompackages/onpage(@shipment/onpage). Read its README before changing it. - Plugin admin UI follows
packages/payload-seo-analyzer/src/ui/README.md:@payloadcms/uicomponents and Payload 4 tokens only. - Upstream code imported with
git subtreekeeps its history. Pull upstream fixes withgit subtree pull --prefix=packages/<name> <repo-url> <branch>.
CI and code review
- CI (
.github/workflows/ci.yml) runs on every PR and push tomaster.- The checks job runs lint, typecheck, the plugins' and onpage's unit tests, the app's integration tests and the production build. It also fails when the Payload schema changed without a migration, or when the import map or generated types are stale.
- The e2e job migrates a fresh local D1 and runs the Playwright suite (frontend, admin and SEO views), then the second-locale specs with
LOCALES=en,pt. - It needs no secrets.
- Reviews: Pullfrog reviews PRs with DeepSeek V4.1 Flash on OpenCode Go (
.github/workflows/pullfrog.yml). Its instructions and console setup are in.github/pullfrog/. - Workflow actions are pinned to commit SHAs, and Dependabot bumps them.