# AGENTS.md This file provides guidance to AI Agents when working with code in this repository. ## Package Manager **Always use `pnpm` for all commands.** This repository uses pnpm workspaces, not npm. ## Monorepo Structure Ghost is a pnpm + Nx monorepo with three workspace groups: ### ghost/* - Core Ghost packages - **ghost/core** - Main Ghost application (Node.js/Express backend) - Core server: `ghost/core/core/server/` - Frontend rendering: `ghost/core/core/frontend/` - **ghost/admin** - Ember.js admin client (legacy, being migrated to React) - **ghost/i18n** - Centralized internationalization for all apps ### apps/* - React-based UI applications Two categories of apps: **Admin Apps** (embedded in Ghost Admin): - `admin-x-settings`, `admin-x-activitypub` - Settings and integrations - `posts`, `stats` - Post analytics and site-wide analytics - Built with Vite + React + `@tanstack/react-query` **Public Apps** (served to site visitors): - `portal`, `comments-ui`, `signup-form`, `sodo-search`, `announcement-bar` - Built as UMD bundles, loaded via CDN in site themes **Foundation Libraries**: - `admin-x-framework` - Shared API hooks, routing, utilities - `admin-x-design-system` - Legacy design system (being phased out) - `shade` - New design system (shadcn/ui + Radix UI + react-hook-form + zod) ### e2e/ - End-to-end tests - Playwright-based E2E tests with Docker container isolation - See `e2e/CLAUDE.md` for detailed testing guidance ## Common Commands ### Development ```bash corepack enable pnpm # Enable corepack to use the correct pnpm version pnpm run setup # First-time setup (installs deps + submodules) pnpm dev # Start development (Docker backend + host frontend dev servers) ``` ### Building ```bash pnpm build # Build all packages (Nx handles dependencies) pnpm build:clean # Clean build artifacts and rebuild ``` ### Testing ```bash # Unit tests (from root) pnpm test:unit # Run all unit tests in all packages # Ghost core tests (from ghost/core/) cd ghost/core pnpm test:unit # Unit tests only pnpm test:integration # Integration tests pnpm test:e2e # E2E API tests (not browser) pnpm test:all # All test types # E2E browser tests (from root) pnpm test:e2e # Run e2e/ Playwright tests # Running a single test cd ghost/core pnpm test:single test/unit/path/to/test.test.js ``` ### Linting ```bash pnpm lint # Lint all packages cd ghost/core && pnpm lint # Lint Ghost core (server, shared, frontend, tests) cd ghost/admin && pnpm lint # Lint Ember admin ``` ### Database ```bash pnpm knex-migrator migrate # Run database migrations pnpm reset:data # Reset database with test data (1000 members, 100 posts) (requires pnpm dev running) pnpm reset:data:empty # Reset database with no data (requires pnpm dev running) ``` ### Docker ```bash pnpm docker:build # Build Docker images pnpm docker:clean # Stop containers, remove volumes and local images pnpm docker:down # Stop containers ``` ### How `pnpm dev` works The `pnpm dev` command uses a **hybrid Docker + host development** setup: **What runs in Docker:** - Ghost Core backend (with hot-reload via mounted source) - MySQL, Redis, Mailpit - Caddy gateway/reverse proxy **What runs on host:** - Frontend dev servers (Admin, Portal, Comments UI, etc.) in watch mode with HMR - Foundation libraries (shade, admin-x-framework, etc.) **Setup:** ```bash # Start everything (Docker + frontend dev servers) pnpm dev # With optional services (uses Docker Compose file composition) pnpm dev:analytics # Include Tinybird analytics pnpm dev:storage # Include MinIO S3-compatible object storage pnpm dev:all # Include all optional services ``` **Accessing Services:** - Ghost: `http://localhost:2368` (database: `ghost_dev`) - Mailpit UI: `http://localhost:8025` (email testing) - MySQL: `localhost:3306` - Redis: `localhost:6379` - Tinybird: `http://localhost:7181` (when analytics enabled) - MinIO Console: `http://localhost:9001` (when storage enabled) - MinIO S3 API: `http://localhost:9000` (when storage enabled) ## Architecture Patterns ### Admin Apps Integration (Micro-Frontend) **Build Process:** 1. Admin-x React apps build to `apps/*/dist` using Vite 2. `ghost/admin/lib/asset-delivery` copies them to `ghost/core/core/built/admin/assets/*` 3. Ghost admin serves from `/ghost/assets/{app-name}/{app-name}.js` **Runtime Loading:** - Ember admin uses `AdminXComponent` to dynamically import React apps - React components wrapped in Suspense with error boundaries - Apps receive config via `additionalProps()` method ### Public Apps Integration - Built as UMD bundles to `apps/*/umd/*.min.js` - Loaded via `