Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
4836725
docs/claude: add project overview, integrations, and dev commands
ooloth May 20, 2026
2e80e7b
fix(claude): format table in CLAUDE.md to pass Prettier check
ooloth May 20, 2026
dba6721
fix(claude): address Copilot review comments in CLAUDE.md
ooloth May 21, 2026
ba9edc1
ci: trigger fresh check after transient Prettier failure
ooloth May 21, 2026
f359993
chore: upgrade Prettier from 3.6.2 to 3.8.3
ooloth May 21, 2026
3d733b9
fix(ci): use npm run format:check instead of npx prettier
ooloth May 21, 2026
0e636d0
fix(prettier): exclude package-lock.json from format check
ooloth May 21, 2026
73bcaec
chore: update package-lock.json for npm 11 compatibility
ooloth May 21, 2026
4f528ce
debug(ci): print failing files when format check fails
ooloth May 21, 2026
4da1fe9
debug(ci): write failing files to step summary on format failure
ooloth May 21, 2026
3071117
debug(ci): post PR comment with failing files on format failure
ooloth May 21, 2026
fcd5d88
debug(ci): use prettier --write + git diff to identify failing files
ooloth May 21, 2026
283c385
debug(ci): capture prettier exit code + always post diagnostic comment
ooloth May 21, 2026
09238c7
debug(ci): fix env var passing to node — export SUMMARY before node call
ooloth May 21, 2026
94c8b22
debug(ci): add permissions, reset lockfile, use curl+jq for comment
ooloth May 21, 2026
a101a9e
fix(ci): add settings.json and restore clean format check
ooloth May 22, 2026
427ee02
Merge branch 'main' into claude/issue-32
ooloth Jun 15, 2026
856d582
Potential fix for pull request finding
ooloth Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
# michaeluloth.com - Claude Code Rules

## What this project is

A personal blog and portfolio site built with Next.js, deployed to Cloudflare Pages (not Vercel). Content is authored in Notion and pulled at build time via the Notion API. The architecture treats the data pipeline like a production system: Zod validates every external API response at the boundary, errors are values (Rust-style `Result<T, E>`), and all external calls use exponential backoff retry.

## External integrations

| Integration | Role |
| ----------- | ----------------------------------------------------------- |
| Notion | CMS — albums, books, podcasts, writing |
| Cloudinary | Image CDN — responsive srcsets, format/quality optimization |
| TMDB | Film metadata (movie and TV list data) |
| iTunes | Podcast metadata |

## Local development

```bash
npm run dev # starts dev server at http://localhost:3000
```

On first run, each page fetch hits the real external APIs and caches the results under `.local-cache/` by namespace. Subsequent requests are served from that persistent on-disk cache until `.local-cache/` is manually cleared. The directory is created automatically on first write — no manual setup needed.

Required env vars (copy `.env.example` to `.env.local` and fill in):

- `NOTION_ACCESS_TOKEN`, `NOTION_DATA_SOURCE_ID_*` (albums, books, podcasts, writing)
- `CLOUDINARY_CLOUD_NAME`, `CLOUDINARY_API_KEY`, `CLOUDINARY_API_SECRET`
- `TMDB_READ_ACCESS_TOKEN`, `TMDB_MOVIE_LIST_ID`, `TMDB_TV_LIST_ID`
- `PUSHOVER_API_TOKEN`, `PUSHOVER_USER_KEY`

CI/deploy only (not needed for local dev):

- `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_API_TOKEN`

Comment on lines +24 to +34
## Check commands

```bash
npm run lint # ESLint
npm run typecheck # TypeScript
npm run test:ci # Vitest (all tests, no watch)
Comment on lines +38 to +40
Comment on lines +38 to +40
```

Run these before committing. To run a single test file: `npm run test:ci -- path/to/file.test.ts`.

Comment on lines +35 to +44
## Post-build metadata validation

```bash
npm run build && npm run test:metadata
```

`test:metadata` reads the static HTML from the `out/` build directory and validates OpenGraph tags, image dimensions, alt text, and SEO fields. It must run **after** `npm run build` — running it against a stale or missing build will produce false results.

## Deployment

The site deploys to **Cloudflare Pages** via GitHub Actions. Do not add Vercel config or assume Vercel-specific behaviour (e.g. `vercel.json`, edge runtime defaults).

---

## TypeScript Type Safety

### Never use `any`
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm ci
- run: npx prettier --check .
- run: npm run format:check

lint:
name: Linting
Expand Down
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Ignore Claude Code Review workflow to prevent breaking security validation
.github/workflows/claude-code-review.yml

# Generated by npm; npm 11 modifies this during `npm ci` before the format check runs
package-lock.json
68 changes: 64 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"deploy:production": "bash io/cloudflare/deploy-production-check.sh && npm run build && npx wrangler pages deploy out --project-name=michaeluloth --branch=main",
"dev": "next dev",
"format": "prettier --write .",
"format:check": "prettier --check .",
"generate:og-image": "tsx seo/generate-og-image.tsx",
Comment on lines 16 to 19
Comment on lines 16 to 19
"lighthouse": "lhci autorun || (tsx ci/lighthouse/parse-errors.ts && exit 1)",
Comment on lines 16 to 20
"prelighthouse": "tsx ci/lighthouse/generate-urls.ts",
Expand Down Expand Up @@ -56,7 +57,7 @@
"eslint-config-next": "16.0.1",
"eslint-config-prettier": "^10.1.8",
"happy-dom": "^20.0.11",
"prettier": "^3.6.2",
"prettier": "^3.8.3",
"satori": "^0.18.3",
Comment on lines 58 to 61
"sharp": "^0.34.5",
"shiki": "^3.15.0",
Expand Down
Loading