From c28ebe5be8b92d78c6922318264205956408571b Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:08:51 -0400
Subject: [PATCH 01/17] feat: add pnpm verify and verify:full scripts
---
.git-hooks/pre-push | 3 +--
package.json | 3 ++-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.git-hooks/pre-push b/.git-hooks/pre-push
index bc97dfe8..60bf9ba5 100755
--- a/.git-hooks/pre-push
+++ b/.git-hooks/pre-push
@@ -1,3 +1,2 @@
#!/usr/bin/env sh
-
-pnpm run pre-push
+exec pnpm run verify
diff --git a/package.json b/package.json
index 65020157..736a1b33 100644
--- a/package.json
+++ b/package.json
@@ -15,12 +15,13 @@
"lint:fix": "oxlint --fix",
"postbuild": "next-sitemap --config next-sitemap.config.cjs",
"postinstall": "prisma generate",
- "pre-push": "pnpm run lint && pnpm run format:check && pnpm run typecheck && pnpm run test:ci",
"prepare": "git config core.hooksPath .git-hooks",
"start": "next start",
"test": "jest",
"test:ci": "jest --ci",
"test:coverage": "jest --coverage",
+ "verify": "pnpm run lint && pnpm run format:check && pnpm run typecheck && pnpm run test:ci",
+ "verify:full": "pnpm run verify && pnpm run build",
"typecheck": "tsc --noEmit"
},
"dependencies": {
From 9ab31d7eac9c4416d8ec425ab31a2d3fa614ccc0 Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:12:48 -0400
Subject: [PATCH 02/17] fix: ignore next-env.d.ts in oxfmt
---
.oxfmtrc.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.oxfmtrc.json b/.oxfmtrc.json
index 74643716..90218442 100644
--- a/.oxfmtrc.json
+++ b/.oxfmtrc.json
@@ -12,6 +12,7 @@
"build/**",
"coverage/**",
"prisma/migrations/**",
- "public/**"
+ "public/**",
+ "next-env.d.ts"
]
}
From 384f1610bf4692f280241bcf4904ce9f2b75e9af Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:14:15 -0400
Subject: [PATCH 03/17] docs: add AGENTS.md
---
AGENTS.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 AGENTS.md
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 00000000..7f310d85
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,97 @@
+# AGENTS.md
+
+Brief for AI coding agents (Claude Code, Codex, Cursor, Copilot, Factory). Humans should read [README.md](README.md) first.
+
+## Project at a glance
+
+`shramko.dev` is a personal portfolio + blog + digital garden. Single deployment target: Vercel.
+
+| Layer | Tools |
+|---|---|
+| Framework | Next.js 16 (Pages Router), React 19 |
+| Language | TypeScript (strict) |
+| Styling | Tailwind CSS v4 |
+| Content | MDX via `next-mdx-remote`, Shiki for syntax highlighting |
+| Data | Prisma 7, Postgres (Neon in prod) |
+| Fetch | SWR |
+| Monitoring | Sentry, Vercel Analytics, Speed Insights, Checkly, UptimeRobot |
+| Testing | Jest + Testing Library |
+| Tooling | oxlint, oxfmt, commitlint, pnpm |
+
+## Setup
+
+Prereqs: Node 24.x (see `.nvmrc`), pnpm 10.x, Postgres database for any DB-touching feature.
+
+```bash
+pnpm install # also runs prisma generate via postinstall
+cp .env.example .env # fill in values; see "Env vars" below
+pnpm dev # http://localhost:3000
+```
+
+## The verify loop
+
+**Two commands. Use the right one.**
+
+- `pnpm verify` — fast (~1 s). Runs `lint`, `format:check`, `typecheck`, `test:ci`. The pre-push hook calls this. Use during tight iteration.
+- `pnpm verify:full` — slower (~30–60 s). Adds `next build` on top. Matches what CI runs. **Run this before opening a PR.**
+
+**Success criterion:** before claiming work is done, `pnpm verify:full` exits 0.
+
+## Common tasks
+
+| Goal | Command |
+|---|---|
+| Start dev server | `pnpm dev` |
+| Run a single test file | `pnpm exec jest path/to/file.test.ts` |
+| Run a single test by name | `pnpm exec jest -t "test name"` |
+| Production build | `pnpm build` |
+| Format only (write) | `pnpm format` |
+| Lint only (auto-fix) | `pnpm lint:fix` |
+| Type check only | `pnpm typecheck` |
+| Scaffold a blog post | `pnpm article` |
+| Regenerate Prisma client | `pnpm exec prisma generate` |
+
+## Repo layout
+
+| Path | Purpose |
+|---|---|
+| `pages/` | Next.js Pages Router routes + API endpoints (`pages/api/`) |
+| `components/` | Shared React components |
+| `lib/` | Utilities, schema, GitHub/Sentry helpers, scripts |
+| `_posts/` | Blog post MDX sources |
+| `_snippets/` | Code-snippet MDX sources |
+| `prisma/` | Prisma schema + migrations |
+| `public/` | Static assets |
+| `styles/` | Global CSS + Tailwind directives |
+| `__tests__/` | Page-level and API-route tests |
+| `__mocks__/` | Manual Jest mocks |
+| `docs/superpowers/` | Local-only specs and plans (gitignored) |
+
+## Conventions
+
+- **Commits:** [Conventional Commits](https://www.conventionalcommits.org/) Angular convention. Enforced by `commitlint.config.ts`. Lowercase subject, ≤ 50 chars, no period. Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.
+- **Branches:** `feat/`, `fix/`, `chore/`, `ci/`, `docs/`, `refactor/`, `test/`, `perf/`.
+- **Formatting:** `oxfmt`. Pre-commit hook auto-formats staged JS/TS. Don't fight it.
+- **Before pushing:** the `pnpm pre-push` hook runs `pnpm verify`. Don't bypass with `--no-verify`.
+- **Before opening a PR:** run `pnpm verify:full` (adds `build`). PR template has a checkbox for this.
+
+## Where things live
+
+- **Env vars** are documented in `.env.example` with descriptions and where to obtain each value.
+- **Secrets** live in Vercel project settings (`Sentry*`, `DATABASE_URL`, `GITHUB_TOKEN`). Read-only for agents — don't try to set them.
+- **The Sentry public DSN** (`NEXT_PUBLIC_SENTRY_DSN`) is intentionally exposed to the client; this is by Sentry design, not a leak.
+- **Specs and plans** for non-trivial work are in `docs/superpowers/specs/` and `docs/superpowers/plans/`. Both are gitignored — they live locally per-developer.
+
+## Don't do
+
+- Don't bypass git hooks with `--no-verify`.
+- Don't commit `.env` (only `.env.example`).
+- Don't hand-edit `pnpm-lock.yaml` — let `pnpm install` regenerate it.
+- Don't push directly to `main`. PRs only.
+- Don't add a dependency without a clear justification — this repo deliberately stays lean.
+- Don't write `*.md` files outside what an issue requires; this project does not use docs-as-features.
+
+## Notes for specific tools
+
+- **Claude Code:** `CLAUDE.md` at the repo root is a symlink to this file. Edit `AGENTS.md`, not `CLAUDE.md`.
+- **Pages Router note:** if you touch `pages/`, remember Sentry SSR-error capture currently lacks a `pages/_error.tsx` with `Sentry.captureUnderscoreErrorException`. There's a separate spec planned for this — don't fix it inline unless that's the task.
From bfaaf7858ca94b195df3e89a7a03f578469dbee2 Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:14:34 -0400
Subject: [PATCH 04/17] docs: symlink CLAUDE.md to AGENTS.md
---
CLAUDE.md | 1 +
1 file changed, 1 insertion(+)
create mode 120000 CLAUDE.md
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 120000
index 00000000..47dc3e3d
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1 @@
+AGENTS.md
\ No newline at end of file
From 0b5ef6cd369159e3ac1104ee00a3ed9d0f37d845 Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:15:10 -0400
Subject: [PATCH 05/17] chore: add CODEOWNERS
---
.github/CODEOWNERS | 1 +
1 file changed, 1 insertion(+)
create mode 100644 .github/CODEOWNERS
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000..579b67c9
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+* @Shramkoweb
From 321a035700eb479a18b1ae6974ebcd169460ae0e Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:15:47 -0400
Subject: [PATCH 06/17] docs: add contributing guide
---
CONTRIBUTING.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 CONTRIBUTING.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..4050ae76
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,46 @@
+# Contributing
+
+This is a personal, opinionated portfolio. Contributions are welcome but not the primary mode of development. If you're considering a non-trivial change, open an issue first to align on scope.
+
+## Setup
+
+See [README.md](README.md) for prerequisites and bootstrap steps.
+
+## Branch naming
+
+Use one of these prefixes (matches existing git history):
+
+- `feat/` — new feature
+- `fix/` — bug fix
+- `chore/` — maintenance / non-functional
+- `ci/` — CI configuration
+- `docs/` — documentation only
+- `refactor/` — internal restructuring
+- `test/` — tests only
+- `perf/` — performance work
+
+## Commits
+
+Conventional Commits (Angular convention) is enforced by `commitlint.config.ts`. Rules:
+
+- Lowercase subject, ≤ 50 characters, no trailing period.
+- Type required (one of: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`).
+- Imperative mood: `add`, not `added`.
+
+Examples: `feat: add OG image generator`, `fix(api): correct slug normalization`.
+
+## Pre-PR checks
+
+Run `pnpm verify:full` locally and confirm it exits 0. This runs:
+
+```
+oxlint → oxfmt --check → tsc --noEmit → jest --ci → next build
+```
+
+The PR template has a checkbox for this. Without it, CI will fail.
+
+## Pull request description
+
+- Explain the **why**, not just the what.
+- Flag breaking changes explicitly.
+- If the change has a spec under `docs/superpowers/specs/`, link it. Specs are local-only (gitignored), so paste the relevant excerpt rather than a path-only link.
From ae282b66e2862eb6dee999a1e23cfffe3cbf8c02 Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:15:47 -0400
Subject: [PATCH 07/17] docs: add security policy
---
SECURITY.md | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 SECURITY.md
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..e51e4d80
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,33 @@
+# Security Policy
+
+## Supported versions
+
+Only the version currently deployed at is supported. There is no LTS branch.
+
+## Reporting a vulnerability
+
+Please **do not open a public GitHub issue** for security problems.
+
+Two reporting channels, in order of preference:
+
+1. **GitHub private vulnerability advisory** — preferred. Use the "Report a vulnerability" button on the [Security tab](https://github.com/Shramkoweb/Portfolio/security).
+2. **Email:** `shramko.dev@gmail.com` with subject `Security: `.
+
+## What to expect
+
+- Acknowledgement within 7 days (best-effort, solo maintainer).
+- Investigation timeline depends on severity. Critical issues that affect deployed code take priority.
+- Credit in the fix commit / release notes if you'd like (mention in your report).
+
+## Out of scope
+
+- Content under `_posts/` and `_snippets/` (not executable code).
+- Missing security headers on demo or staging subdomains.
+- Reports from automated scanners with no proof-of-concept.
+- Issues in third-party services I integrate with (Vercel, Sentry, GitHub) — please report to the upstream vendor.
+
+## Existing controls
+
+- GitHub native secret scanning is enabled (public repo, automatic).
+- CodeQL workflow runs on every push and PR (`.github/workflows/codeql.yml`).
+- Dependencies are updated weekly via Renovate; `pnpm audit` runs in CI.
From 44c0fbe1f204c3eedfbd6d86fca5cf1be0ecccfc Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:16:29 -0400
Subject: [PATCH 08/17] chore: add pull request template
---
.github/PULL_REQUEST_TEMPLATE.md | 33 ++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 .github/PULL_REQUEST_TEMPLATE.md
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..b7cff9d6
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,33 @@
+## Summary
+
+
+
+-
+
+## Type
+
+
+
+- [ ] feat — new feature
+- [ ] fix — bug fix
+- [ ] docs — docs only
+- [ ] style — formatting / whitespace
+- [ ] refactor — internal restructuring
+- [ ] perf — performance
+- [ ] test — tests only
+- [ ] build — build system / deps
+- [ ] ci — CI config
+- [ ] chore — maintenance
+
+## Linked spec or plan
+
+
+
+## Test plan
+
+- [ ] `pnpm verify:full` exits 0 locally
+- [ ]
+
+## Breaking changes
+
+
From dc7d45a71e49e721de65cbac6f8a331cd751c0aa Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:16:29 -0400
Subject: [PATCH 09/17] chore: add issue templates
---
.github/ISSUE_TEMPLATE/bug_report.yml | 66 ++++++++++++++++++++++
.github/ISSUE_TEMPLATE/config.yml | 1 +
.github/ISSUE_TEMPLATE/feature_request.yml | 26 +++++++++
3 files changed, 93 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml
create mode 100644 .github/ISSUE_TEMPLATE/config.yml
create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 00000000..a8386cac
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,66 @@
+name: Bug report
+description: Something on shramko.dev is broken or behaves unexpectedly
+labels: ['bug']
+body:
+ - type: textarea
+ id: summary
+ attributes:
+ label: Summary
+ description: What went wrong, in one or two sentences.
+ validations:
+ required: true
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Steps to reproduce
+ description: Numbered steps that someone else can follow to see the bug.
+ placeholder: |
+ 1. Go to https://shramko.dev/...
+ 2. Click ...
+ 3. See error
+ validations:
+ required: true
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected behavior
+ validations:
+ required: true
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual behavior
+ validations:
+ required: true
+ - type: input
+ id: browser
+ attributes:
+ label: Browser and version
+ placeholder: 'Chrome 130 / Safari 18 / Firefox 130'
+ validations:
+ required: true
+ - type: dropdown
+ id: viewport
+ attributes:
+ label: Viewport
+ options:
+ - Desktop
+ - Tablet
+ - Mobile
+ validations:
+ required: true
+ - type: dropdown
+ id: theme
+ attributes:
+ label: Theme
+ options:
+ - Light
+ - Dark
+ - System
+ validations:
+ required: true
+ - type: textarea
+ id: extra
+ attributes:
+ label: Anything else
+ description: Console errors, screenshots, related links.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..3ba13e0c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 00000000..7b83f024
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,26 @@
+name: Feature request
+description: Suggest an addition or change
+labels: ['enhancement']
+body:
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem
+ description: What user need or pain point does this address?
+ validations:
+ required: true
+ - type: textarea
+ id: proposal
+ attributes:
+ label: Proposed solution
+ validations:
+ required: true
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives considered
+ description: Other approaches you thought about and why you chose the one above.
+ - type: textarea
+ id: extra
+ attributes:
+ label: Anything else
From aceff49136a5365ea98ff70920f961e2f1e1f154 Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:17:15 -0400
Subject: [PATCH 10/17] docs: document env vars in .env.example
---
.env.example | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/.env.example b/.env.example
index 962755bb..235a58a3 100644
--- a/.env.example
+++ b/.env.example
@@ -1,7 +1,22 @@
+# Sentry server-side DSN. Required for production builds, optional for local dev.
+# Obtain: Sentry project → Settings → Client Keys (DSN).
SENTRY_DSN=
+
+# Sentry browser DSN. Same value as SENTRY_DSN — Next.js exposes this to the client.
NEXT_PUBLIC_SENTRY_DSN=
+
+# Sentry CLI auth token. Required for source-map upload during `pnpm build`.
+# Obtain: Sentry → User Settings → Auth Tokens, scope `project:releases`.
SENTRY_AUTH_TOKEN=
+
+# Sentry environment label. Defaults to `development` locally; Vercel sets `production`.
SENTRY_ENVIRONMENT=development
NEXT_PUBLIC_SENTRY_ENVIRONMENT=development
+
+# Postgres connection string. Required for any feature that hits the DB
+# (view counters, reactions, dashboard). Use Neon or local Postgres for dev.
DATABASE_URL=
+
+# GitHub personal access token (read-only). Required by /api/github
+# (powers the GitHub stats card on the homepage). `public_repo` scope is sufficient.
GITHUB_TOKEN=
From f6cd814f5ecce07fc4dca8d0cda49b91f3ce05d1 Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:17:16 -0400
Subject: [PATCH 11/17] ci: add codeql workflow
---
.github/workflows/codeql.yml | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 .github/workflows/codeql.yml
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 00000000..1445613f
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,26 @@
+name: CodeQL
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+ schedule:
+ - cron: '0 6 * * 1'
+permissions:
+ actions: read
+ contents: read
+ security-events: write
+concurrency:
+ group: codeql-${{ github.ref }}
+ cancel-in-progress: true
+jobs:
+ analyze:
+ name: analyze
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ steps:
+ - uses: actions/checkout@v6
+ - uses: github/codeql-action/init@v3
+ with:
+ languages: javascript-typescript
+ - uses: github/codeql-action/analyze@v3
From 7d78966538c1c25aaadddc4057e7bd01e83afd7e Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:17:51 -0400
Subject: [PATCH 12/17] style: pad AGENTS.md tables
---
AGENTS.md | 68 +++++++++++++++++++++++++++----------------------------
1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index 7f310d85..f7bc48fa 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -6,17 +6,17 @@ Brief for AI coding agents (Claude Code, Codex, Cursor, Copilot, Factory). Human
`shramko.dev` is a personal portfolio + blog + digital garden. Single deployment target: Vercel.
-| Layer | Tools |
-|---|---|
-| Framework | Next.js 16 (Pages Router), React 19 |
-| Language | TypeScript (strict) |
-| Styling | Tailwind CSS v4 |
-| Content | MDX via `next-mdx-remote`, Shiki for syntax highlighting |
-| Data | Prisma 7, Postgres (Neon in prod) |
-| Fetch | SWR |
+| Layer | Tools |
+| ---------- | -------------------------------------------------------------- |
+| Framework | Next.js 16 (Pages Router), React 19 |
+| Language | TypeScript (strict) |
+| Styling | Tailwind CSS v4 |
+| Content | MDX via `next-mdx-remote`, Shiki for syntax highlighting |
+| Data | Prisma 7, Postgres (Neon in prod) |
+| Fetch | SWR |
| Monitoring | Sentry, Vercel Analytics, Speed Insights, Checkly, UptimeRobot |
-| Testing | Jest + Testing Library |
-| Tooling | oxlint, oxfmt, commitlint, pnpm |
+| Testing | Jest + Testing Library |
+| Tooling | oxlint, oxfmt, commitlint, pnpm |
## Setup
@@ -39,33 +39,33 @@ pnpm dev # http://localhost:3000
## Common tasks
-| Goal | Command |
-|---|---|
-| Start dev server | `pnpm dev` |
-| Run a single test file | `pnpm exec jest path/to/file.test.ts` |
-| Run a single test by name | `pnpm exec jest -t "test name"` |
-| Production build | `pnpm build` |
-| Format only (write) | `pnpm format` |
-| Lint only (auto-fix) | `pnpm lint:fix` |
-| Type check only | `pnpm typecheck` |
-| Scaffold a blog post | `pnpm article` |
-| Regenerate Prisma client | `pnpm exec prisma generate` |
+| Goal | Command |
+| ------------------------- | ------------------------------------- |
+| Start dev server | `pnpm dev` |
+| Run a single test file | `pnpm exec jest path/to/file.test.ts` |
+| Run a single test by name | `pnpm exec jest -t "test name"` |
+| Production build | `pnpm build` |
+| Format only (write) | `pnpm format` |
+| Lint only (auto-fix) | `pnpm lint:fix` |
+| Type check only | `pnpm typecheck` |
+| Scaffold a blog post | `pnpm article` |
+| Regenerate Prisma client | `pnpm exec prisma generate` |
## Repo layout
-| Path | Purpose |
-|---|---|
-| `pages/` | Next.js Pages Router routes + API endpoints (`pages/api/`) |
-| `components/` | Shared React components |
-| `lib/` | Utilities, schema, GitHub/Sentry helpers, scripts |
-| `_posts/` | Blog post MDX sources |
-| `_snippets/` | Code-snippet MDX sources |
-| `prisma/` | Prisma schema + migrations |
-| `public/` | Static assets |
-| `styles/` | Global CSS + Tailwind directives |
-| `__tests__/` | Page-level and API-route tests |
-| `__mocks__/` | Manual Jest mocks |
-| `docs/superpowers/` | Local-only specs and plans (gitignored) |
+| Path | Purpose |
+| ------------------- | ---------------------------------------------------------- |
+| `pages/` | Next.js Pages Router routes + API endpoints (`pages/api/`) |
+| `components/` | Shared React components |
+| `lib/` | Utilities, schema, GitHub/Sentry helpers, scripts |
+| `_posts/` | Blog post MDX sources |
+| `_snippets/` | Code-snippet MDX sources |
+| `prisma/` | Prisma schema + migrations |
+| `public/` | Static assets |
+| `styles/` | Global CSS + Tailwind directives |
+| `__tests__/` | Page-level and API-route tests |
+| `__mocks__/` | Manual Jest mocks |
+| `docs/superpowers/` | Local-only specs and plans (gitignored) |
## Conventions
From b83da65ea11428f1f6afc2bfe527dca23a3dd66d Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:22:58 -0400
Subject: [PATCH 13/17] ci: drop codeql workflow; default setup covers it
---
.github/workflows/codeql.yml | 26 --------------------------
1 file changed, 26 deletions(-)
delete mode 100644 .github/workflows/codeql.yml
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
deleted file mode 100644
index 1445613f..00000000
--- a/.github/workflows/codeql.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: CodeQL
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
- schedule:
- - cron: '0 6 * * 1'
-permissions:
- actions: read
- contents: read
- security-events: write
-concurrency:
- group: codeql-${{ github.ref }}
- cancel-in-progress: true
-jobs:
- analyze:
- name: analyze
- runs-on: ubuntu-latest
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@v6
- - uses: github/codeql-action/init@v3
- with:
- languages: javascript-typescript
- - uses: github/codeql-action/analyze@v3
From ae541f0d19779dd12e920f39b1827ed7cd620b7a Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:23:27 -0400
Subject: [PATCH 14/17] docs: correct codeql reference in security.md
---
SECURITY.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SECURITY.md b/SECURITY.md
index e51e4d80..27f83f63 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -29,5 +29,5 @@ Two reporting channels, in order of preference:
## Existing controls
- GitHub native secret scanning is enabled (public repo, automatic).
-- CodeQL workflow runs on every push and PR (`.github/workflows/codeql.yml`).
+- CodeQL default setup is enabled (repo Security tab) — runs on every push and PR.
- Dependencies are updated weekly via Renovate; `pnpm audit` runs in CI.
From 1881d112f20e23b6235bb17efdf5a02710e5acc4 Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:30:12 -0400
Subject: [PATCH 15/17] docs: refresh stale pre-push references
---
AGENTS.md | 2 +-
README.md | 23 +++++++++++++----------
README.ua.md | 23 +++++++++++++----------
3 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index f7bc48fa..178b20f5 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -72,7 +72,7 @@ pnpm dev # http://localhost:3000
- **Commits:** [Conventional Commits](https://www.conventionalcommits.org/) Angular convention. Enforced by `commitlint.config.ts`. Lowercase subject, ≤ 50 chars, no period. Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.
- **Branches:** `feat/`, `fix/`, `chore/`, `ci/`, `docs/`, `refactor/`, `test/`, `perf/`.
- **Formatting:** `oxfmt`. Pre-commit hook auto-formats staged JS/TS. Don't fight it.
-- **Before pushing:** the `pnpm pre-push` hook runs `pnpm verify`. Don't bypass with `--no-verify`.
+- **Before pushing:** the git pre-push hook (`.git-hooks/pre-push`) runs `pnpm verify` automatically. Don't bypass with `--no-verify`.
- **Before opening a PR:** run `pnpm verify:full` (adds `build`). PR template has a checkbox for this.
## Where things live
diff --git a/README.md b/README.md
index 0853a328..bebb34f6 100755
--- a/README.md
+++ b/README.md
@@ -61,15 +61,17 @@ App runs at http://localhost:3000.
## Scripts
-| Command | Purpose |
-| ----------------------------------- | -------------------------- |
-| `pnpm dev` | start dev server |
-| `pnpm build` | production build + sitemap |
-| `pnpm start` | start production server |
-| `pnpm lint` / `pnpm lint:fix` | oxlint |
-| `pnpm format` / `pnpm format:check` | oxfmt |
-| `pnpm test` / `pnpm test:coverage` | Jest |
-| `pnpm article` | scaffold a new blog post |
+| Command | Purpose |
+| ----------------------------------- | ------------------------------------------- |
+| `pnpm dev` | start dev server |
+| `pnpm build` | production build + sitemap |
+| `pnpm start` | start production server |
+| `pnpm lint` / `pnpm lint:fix` | oxlint |
+| `pnpm format` / `pnpm format:check` | oxfmt |
+| `pnpm test` / `pnpm test:coverage` | Jest |
+| `pnpm verify` | lint + format:check + typecheck + test (CI) |
+| `pnpm verify:full` | `verify` + production build |
+| `pnpm article` | scaffold a new blog post |
## Testing
@@ -93,7 +95,8 @@ Deploys automatically to [Vercel](https://vercel.com) on push to `main`. The `po
- Commits follow [Conventional Commits](https://www.conventionalcommits.org) (Angular convention). Enforced by `commitlint.config.ts`.
- A pre-commit hook auto-formats staged JS/TS via `oxfmt` (installed by `pnpm install` through the `prepare` script).
-- Run `pnpm pre-push` before pushing — it runs lint and format checks.
+- A pre-push hook (`.git-hooks/pre-push`) runs `pnpm verify` automatically before each push. Run `pnpm verify:full` (adds `next build`) before opening a PR.
+- See [AGENTS.md](AGENTS.md) if you're using an AI coding agent. Full policy in [CONTRIBUTING.md](CONTRIBUTING.md).
## License
diff --git a/README.ua.md b/README.ua.md
index 022aa500..e44a64ca 100644
--- a/README.ua.md
+++ b/README.ua.md
@@ -61,15 +61,17 @@ pnpm dev
## Команди
-| Команда | Опис |
-| ----------------------------------- | ------------------------------- |
-| `pnpm dev` | запуск dev-сервера |
-| `pnpm build` | продакшн-збірка + sitemap |
-| `pnpm start` | запуск продакшн-сервера |
-| `pnpm lint` / `pnpm lint:fix` | oxlint |
-| `pnpm format` / `pnpm format:check` | oxfmt |
-| `pnpm test` / `pnpm test:coverage` | Jest |
-| `pnpm article` | створення шаблону нового допису |
+| Команда | Опис |
+| ----------------------------------- | ------------------------------------------- |
+| `pnpm dev` | запуск dev-сервера |
+| `pnpm build` | продакшн-збірка + sitemap |
+| `pnpm start` | запуск продакшн-сервера |
+| `pnpm lint` / `pnpm lint:fix` | oxlint |
+| `pnpm format` / `pnpm format:check` | oxfmt |
+| `pnpm test` / `pnpm test:coverage` | Jest |
+| `pnpm verify` | lint + format:check + typecheck + test (CI) |
+| `pnpm verify:full` | `verify` + продакшн-збірка |
+| `pnpm article` | створення шаблону нового допису |
## Тестування
@@ -93,7 +95,8 @@ pnpm dev
- Коміти йдуть у форматі [Conventional Commits](https://www.conventionalcommits.org) (Angular convention). Перевіряється через `commitlint.config.ts`.
- Pre-commit хук автоматично форматує JS/TS через `oxfmt` (встановлюється `pnpm install` через скрипт `prepare`).
-- Запустіть `pnpm pre-push` перед пушем — він запускає lint і перевірку форматування.
+- Pre-push хук (`.git-hooks/pre-push`) автоматично запускає `pnpm verify` перед кожним пушем. Перед відкриттям PR запустіть `pnpm verify:full` (додає `next build`).
+- Якщо ви використовуєте AI-агента, дивіться [AGENTS.md](AGENTS.md). Повна політика — у [CONTRIBUTING.md](CONTRIBUTING.md).
## Ліцензія
From b28bc08c1b023631410b2d392a6c91a4456401b4 Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:30:44 -0400
Subject: [PATCH 16/17] docs: remove ukrainian readme
---
README.md | 2 -
README.ua.md | 103 ---------------------------------------------------
2 files changed, 105 deletions(-)
delete mode 100644 README.ua.md
diff --git a/README.md b/README.md
index bebb34f6..c93ba9ee 100755
--- a/README.md
+++ b/README.md
@@ -10,8 +10,6 @@
-🇺🇦 Українською
-
## Contents
- [Tech Stack](#tech-stack)
diff --git a/README.ua.md b/README.ua.md
deleted file mode 100644
index e44a64ca..00000000
--- a/README.ua.md
+++ /dev/null
@@ -1,103 +0,0 @@
-shramko.dev
-Портфоліо · блог · цифровий сад
-Дивитись сайт →
-
-
-
-
-
-
-
-
-
-English
-
-## Зміст
-
-- [Технології](#технології)
-- [Швидкий старт](#швидкий-старт)
-- [Команди](#команди)
-- [Тестування](#тестування)
-- [Деплой](#деплой)
-- [Моніторинг](#моніторинг)
-- [Внесок у проєкт](#внесок-у-проєкт)
-- [Ліцензія](#ліцензія)
-
-## Технології
-
-| Шар | Інструменти |
-| ------------- | -------------------------------------------------------------- |
-| Фреймворк | Next.js 16, React 19 |
-| Мова | TypeScript |
-| Стилі | Tailwind CSS v4 |
-| Контент | MDX, `next-mdx-remote`, Shiki |
-| Дані | Prisma 7, Postgres |
-| Стан / Запити | SWR |
-| Моніторинг | Sentry, Checkly, UptimeRobot, Vercel Analytics, Speed Insights |
-| Тести | Jest, Testing Library |
-| Інструменти | oxlint, oxfmt, commitlint, pnpm |
-| Хостинг | Vercel |
-
-## Швидкий старт
-
-### Передумови
-
-- Node 24.x
-- pnpm 10.x
-- База даних Postgres (локальна або хмарна, наприклад [Neon](https://neon.tech))
-
-### Установка
-
-```bash
-git clone https://github.com/Shramkoweb/Portfolio.git
-cd Portfolio
-pnpm install
-cp .env.example .env
-# заповніть DATABASE_URL, SENTRY_*, GITHUB_TOKEN
-pnpm dev
-```
-
-Застосунок запускається на http://localhost:3000.
-
-## Команди
-
-| Команда | Опис |
-| ----------------------------------- | ------------------------------------------- |
-| `pnpm dev` | запуск dev-сервера |
-| `pnpm build` | продакшн-збірка + sitemap |
-| `pnpm start` | запуск продакшн-сервера |
-| `pnpm lint` / `pnpm lint:fix` | oxlint |
-| `pnpm format` / `pnpm format:check` | oxfmt |
-| `pnpm test` / `pnpm test:coverage` | Jest |
-| `pnpm verify` | lint + format:check + typecheck + test (CI) |
-| `pnpm verify:full` | `verify` + продакшн-збірка |
-| `pnpm article` | створення шаблону нового допису |
-
-## Тестування
-
-Тести працюють на Jest з Testing Library. Запустіть `pnpm test` для повного набору або `pnpm test:coverage` для звіту покриття. Тести розташовані в `__tests__/`. CI завантажує покриття у Code Climate.
-
-## Деплой
-
-Автоматичний деплой на [Vercel](https://vercel.com) при пуші до `main`. Скрипт `postbuild` регенерує sitemap через `next-sitemap`. Pull request-и проходять перевірку Lighthouse budget, описану в `.github/workflows/lighthouse.yml`.
-
-## Моніторинг
-
-- [UptimeRobot status page](https://stats.uptimerobot.com/8lYYzuXNM9/792406216) — публічний моніторинг доступності сайту.
-
- 
-
-- [Checkly dashboard](https://portfolio-shramko.checkly-dashboards.com/?duration=30d) — E2E тести та статус збірки.
-
- 
-
-## Внесок у проєкт
-
-- Коміти йдуть у форматі [Conventional Commits](https://www.conventionalcommits.org) (Angular convention). Перевіряється через `commitlint.config.ts`.
-- Pre-commit хук автоматично форматує JS/TS через `oxfmt` (встановлюється `pnpm install` через скрипт `prepare`).
-- Pre-push хук (`.git-hooks/pre-push`) автоматично запускає `pnpm verify` перед кожним пушем. Перед відкриттям PR запустіть `pnpm verify:full` (додає `next build`).
-- Якщо ви використовуєте AI-агента, дивіться [AGENTS.md](AGENTS.md). Повна політика — у [CONTRIBUTING.md](CONTRIBUTING.md).
-
-## Ліцензія
-
-MIT — дивіться [LICENSE](LICENSE).
From fee70f4db6b28ffd85d42e8e3f4f853f8ba3e79b Mon Sep 17 00:00:00 2001
From: shramko
Date: Mon, 4 May 2026 14:37:45 -0400
Subject: [PATCH 17/17] docs: fix stale references in agents.md
---
AGENTS.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index 178b20f5..640e16a8 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -24,7 +24,7 @@ Prereqs: Node 24.x (see `.nvmrc`), pnpm 10.x, Postgres database for any DB-touch
```bash
pnpm install # also runs prisma generate via postinstall
-cp .env.example .env # fill in values; see "Env vars" below
+cp .env.example .env # each var is documented inline in .env.example
pnpm dev # http://localhost:3000
```
@@ -94,4 +94,4 @@ pnpm dev # http://localhost:3000
## Notes for specific tools
- **Claude Code:** `CLAUDE.md` at the repo root is a symlink to this file. Edit `AGENTS.md`, not `CLAUDE.md`.
-- **Pages Router note:** if you touch `pages/`, remember Sentry SSR-error capture currently lacks a `pages/_error.tsx` with `Sentry.captureUnderscoreErrorException`. There's a separate spec planned for this — don't fix it inline unless that's the task.
+- **Pages Router / Sentry gap:** there is no `pages/_error.tsx` with `Sentry.captureUnderscoreErrorException`, so SSR errors from the Pages Router don't reach Sentry. Don't fix this inline as a side effect of unrelated work — open a focused PR for it.