Thank you for your interest in contributing! This guide covers the development workflow, branching strategy, and quality standards.
See README.md — Getting Started for setup instructions including Node.js, API key, LinkedIn data, and export dependencies.
| Environment | Branch | URL | Deploys on |
|---|---|---|---|
| Local dev | any | localhost:3000 |
npm run dev |
| Preview / Staging | manual on branch | <deployment>.vercel.app |
manual vercel deploy (or workflow extension) |
| Production | main |
paulprae.com | merge/push to main after CI + Deploy workflow |
Production deployment is managed by GitHub Actions (ci.yml then deploy.yml). PR preview deployment is not automatic in the current workflow set.
We use GitHub Flow — a single long-lived branch (main) with short-lived feature branches.
feature/<name> # New functionality (e.g., feature/dark-mode)
fix/<name> # Bug fixes (e.g., fix/pdf-export-margin)
docs/<name> # Documentation-only changes (e.g., docs/update-readme)
chore/<name> # Tooling, CI, dependency updates (e.g., chore/upgrade-next)
-
Create a branch from
main:git checkout main && git pull git checkout -b feature/my-feature -
Make changes and commit (see Commit Messages)
-
Push and open a PR against
main:git push -u origin feature/my-feature # Write PR body to a temp file (avoids shell escaping issues with backticks): cat > /tmp/pr-body.md << 'PREOF' ## Summary - Description of changes ## Test plan - [ ] `npm run check` passes PREOF gh pr create --title "feat: my feature" --body-file /tmp/pr-body.md
Tip: Always use
--body-filefor PR descriptions containing backticks or code blocks. Using<< 'PREOF'(quoted delimiter) prevents variable/command expansion. -
CI runs automatically — lint, format check, tests, and build must all pass
-
Vercel deploys a preview — check the preview URL in the PR checks
-
Merge — squash or merge commit, then delete the branch
- All changes to
maingo through pull requests - CI must pass before merge
- Keep branches short-lived (days, not weeks)
- Delete branches after merge
- Never use
git commit --amendon pushed commits — force pushes orphan SHAs that Vercel and CI depend on
For PR creation from the WSL terminal, authenticate gh with a personal access token:
- Create a fine-grained token at https://github.com/settings/tokens
- Scopes: Contents (read/write), Pull Requests (read/write)
- Add to
.env.local:GH_TOKEN=github_pat_... - Source it:
export GH_TOKEN=$(grep GH_TOKEN .env.local | cut -d= -f2) - Verify:
gh auth status
Note: Claude Code uses the Windows
gh.exe(already authenticated). This setup is only needed for manualghcommands in WSL.
Use Conventional Commits style:
<type>: <short description in imperative mood>
[optional body explaining why, not what]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> # if AI-assisted
Types: feat, fix, docs, chore, refactor, test, style, design
Examples:
feat: add dark mode togglefix: correct PDF margin on mobiledocs: update pipeline commands in README
The AI generation pipeline runs locally, not on Vercel. Before committing generated content:
npm run pipeline # Full: ingest → generate → export
# or
npm run pipeline:content # Just: ingest → generate
npm run pipeline:render # Just: exportGenerated files that should be committed: data/generated/career-data.json, data/generated/<Name>-Resume.md (filename derived from profile name), public/<Name>-Resume.*
A pre-commit hook runs automatically on every git commit. It formats staged files with Prettier via lint-staged before the commit is recorded, so formatting issues never reach CI.
The hook is installed by npm install via the prepare lifecycle hook — no extra setup needed. It works across all Git environments:
- WSL / Linux / macOS terminal: Uses
npxdirectly (sources nvm if present) - Windows Git clients (GitHub Desktop, VS Code, etc.): Automatically delegates to WSL via
wsl.exewhennpxisn't available in the Windows shell, converting UNC paths to WSL-native paths
Run the release checklist before pushing:
npm run check # Full checklist: data files → lint → format → test → build → validate
npm run check:quick # Data file validation only (instant)Or run individual checks:
npm run lint # ESLint
npm run format:check # Prettier
npm test # Vitest
npm run test:e2e # Playwright E2E smoke tests
npm run build # Next.js buildE2E options:
- Default: Chromium + mocked smoke tests.
- Full matrix:
PW_FULL_MATRIX=1 npm run test:e2e. - Optional live API check:
E2E_LIVE_CHAT=1 npx playwright test e2e/live-chat.spec.ts.
CI runs lint, format, test, build, and build output validation on every PR. All must pass to merge.
.env.local— API keysdata/sources/linkedin/*.csv— raw LinkedIn exportsdata/generated/*.pdf,data/generated/*.docx— regenerable binary artifactsdata/generated/*.staging.md— transient staging filesnode_modules/
The resume markdown is generated — don't edit the resume .md file directly. To change content:
- Edit
scripts/generate-resume.ts(prompt, formatting, data processing) - Run
npm run generate(writes to staging) - Run
npm run compareto review changes vs current approved version - Run
npm run approveto promote staging → live - Run
npm run exportto regenerate PDF/DOCX - Commit the updated files