Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e8df141
fix: block field handling with custom blockKey and component references
kadenbking Jan 22, 2026
d1f08df
Merge pull request #1 from cornerstone-web/fix/block-field-discrimina…
kadenbking Jan 22, 2026
fa36978
feat: add live block preview system to entry editor
kadenbking Jan 26, 2026
3045241
fix: read previewUrl from config.object (parsed YAML)
kadenbking Jan 26, 2026
f7c790f
fix: preview and block discriminator keys for live preview
kadenbking Jan 26, 2026
7add13a
fix: live block preview!!!
kadenbking Jan 27, 2026
5b0545d
feat: UI improvements for block preview
kadenbking Jan 27, 2026
b2b9722
feat: added full page preview
kadenbking Jan 27, 2026
6d565ba
Merge pull request #2 from cornerstone-web/feat/full-page-preview
kadenbking Jan 27, 2026
8c0670f
chore: added help docs
kadenbking Jan 27, 2026
3f946b2
feat: support ref: block references and list.template
kadenbking Jan 29, 2026
84d001a
feat: added working template dropdown, confirmation modal
kadenbking Jan 30, 2026
6c0c2c4
Merge pull request #3 from cornerstone-web/feature/preview
kadenbking Jan 31, 2026
9661b9e
Merge pull request #4 from cornerstone-web/feat/template-refs
kadenbking Jan 31, 2026
70e3730
fix: build warnings
kadenbking Jan 31, 2026
af07757
Merge pull request #5 from cornerstone-web/fix/build-warnings
kadenbking Jan 31, 2026
01cb02c
fix: added right sidebar scroll
kadenbking Jan 31, 2026
9982f82
fix: consolidate preview frames
kadenbking Jan 31, 2026
4362b5e
feat: added mobile page preview
kadenbking Jan 31, 2026
9488a6f
feat: add link field type with internal page picker
kadenbking Feb 1, 2026
e69398d
feat: integrate link picker into rich-text editor
kadenbking Feb 1, 2026
cf79a97
Merge pull request #6 from cornerstone-web/feat/link-selector-component
kadenbking Feb 1, 2026
d7ea001
feat: preview collapsed state
kadenbking Feb 1, 2026
ccc524a
Merge pull request #7 from cornerstone-web/feat/ui-improvements
kadenbking Feb 1, 2026
bbceb11
feat: fetch collections for previews without placeholder data
kadenbking Feb 3, 2026
49b97c9
restore blockDataKey
kadenbking Feb 3, 2026
80a29c9
feat: template editing
kadenbking Feb 3, 2026
7284fe0
feat: block field toggles
kadenbking Feb 5, 2026
ba911b0
feat: added slider component
kadenbking Feb 5, 2026
a49b253
fix: handle null block key
kadenbking Feb 5, 2026
900c32b
fix: show configuration label in block editor
kadenbking Feb 5, 2026
09cf3bf
feat: initial block collapsed state
kadenbking Feb 5, 2026
b7bf528
feat: inverse controlled by field
kadenbking Feb 5, 2026
496d7a5
fix: transformed image paths in block preview
kadenbking Feb 5, 2026
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Pages CMS is an open-source Content Management System for GitHub, designed for static site generators (Jekyll, Next.js, Hugo, Astro, etc.). It provides a user-friendly web interface to edit content directly on GitHub repositories.

**Tech Stack:** Next.js 14 (App Router), TypeScript, Tailwind CSS, shadcn/ui, Drizzle ORM with PostgreSQL, Lucia for authentication, Octokit for GitHub API.

## Commands

```bash
npm run dev # Start development server
npm run build # Build for production (auto-runs db:migrate)
npm run lint # Run ESLint
npm run db:generate # Generate Drizzle migrations after schema changes
npm run db:migrate # Apply pending migrations
npm run db:clear-cache # Clear file/permission cache from database
```

For development, you need a GitHub App configured and a tunnel (e.g., ngrok) for webhooks.

## Architecture

### Directory Structure

- **`/app`** - Next.js App Router
- `/(auth)/` - Authentication pages (sign-in flows)
- `/(main)/` - Main application UI
- `/api/` - REST API routes
- `/api/auth/` - OAuth and email auth
- `/api/webhook/github/` - GitHub webhook handler
- `/api/[owner]/[repo]/[branch]/` - Content management endpoints (entries, files, collections, media)

- **`/lib`** - Core business logic
- `auth.ts` - Lucia authentication setup
- `githubApp.ts` - GitHub App configuration
- `githubCache.ts` - GitHub API caching layer
- `config.ts` - CMS configuration parsing
- `configSchema.ts` - Zod schema for config validation
- `crypto.ts` - Token encryption (AES)

- **`/db`** - Database layer (Drizzle ORM)
- `schema.ts` - Table definitions (users, sessions, tokens, collaborators, config, cache)
- `/migrations/` - SQL migrations

- **`/fields`** - Extensible field type system
- `/core/` - Built-in types (string, text, date, image, rich-text, code, select, etc.)
- `/custom/` - User-defined field types
- `registry.ts` - Dynamic field component loading via webpack require.context

- **`/components`** - React components
- `/ui/` - shadcn/ui components
- `/collection/`, `/entry/`, `/file/`, `/media/`, `/repo/` - Feature components

### Field Type System

Fields are dynamically registered from `/fields/core` and `/fields/custom`. Each field can export:

- `schema` - Zod validation schema
- `read`/`write` - Format conversion functions
- `EditComponent`/`ViewComponent` - React components
- `defaultValue` - Default value for new entries

To create a custom field, add a folder in `/fields/custom/` with an `index.ts` exporting these.

### Configuration-Driven CMS

Repositories define their CMS structure via `.pages.yml` (or YAML/TOML variants). The schema in `lib/configSchema.ts` validates:

- `media` - Media folder configuration
- `content` - Collections and file definitions with fields
- `components` - Reusable field groups

### Authentication Flow

- GitHub OAuth via Arctic library
- Email magic links via Resend
- Sessions managed by Lucia with Drizzle adapter
- GitHub tokens encrypted at rest using AES

### Caching Strategy

- File contents cached in `cache_file` table with configurable TTL
- Permissions cached in `cache_permission` table
- Cron endpoint (`/api/cron`) clears expired cache entries

## Contributing

- Submit PRs against `development` branch, not `main`
- `main` is production (app.pagescms.org)
- `development` is staging (dev.pagescms.org)
- Use `feature/name` or `issue/123-description` branch naming
47 changes: 47 additions & 0 deletions START_HERE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Local Help Guide for Getting Started

What the README doesn't say.

In the root dir `/pages-cms`

1. Install dependencies

```
npm i
```

2. Copy .env file

```
cp .env.local.example .env
```

3. Create Github App

- Follow README instructions
- Use `openssl rand -base64 32` to generate random 32-character strings
- Use `ngrok` to establish tunnel:

```
ngrok http 3000
```

- Copy local redirect URL to Github App Webhook URL (you will have to update and save this in GH App each time you run locally)

4. Run PostgreSQL Locally

```
docker run --name pages-cms-db -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:15
```

5. Update .env with GH App secrets and DB url

```
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres"
```

6. Run

```
npm run dev
```
3 changes: 2 additions & 1 deletion app/api/[owner]/[repo]/[branch]/files/[path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ export async function POST(
}

// Use mapBlocks to convert config blocks array to a map
const zodSchema = generateZodSchema(contentFields);
// In template mode, only validate templateEditable fields
const zodSchema = generateZodSchema(contentFields, false, data.isTemplateMode === true);
const zodValidation = zodSchema.safeParse(contentObject);

if (zodValidation.success === false ) {
Expand Down
Loading