Thanks for wanting to help. Oak is a personal fitness coach agent, and the goal of every change is to keep it generic, reliable, and useful to anyone who clones it.
- Open an issue first for anything bigger than a small fix, so we agree on direction before you write code.
- Keep it generic: nothing personal (Notion ids, chat ids, goals, tokens) belongs in the
repo.
PERSONAL.md,.env,config/notion-hub.json, anddata/stay gitignored.
- Node >= 22, TypeScript, ESM.
src/is organised by domain (agent/,media/,scheduler/,calendar/). Put new code in the domain it belongs to; do not growindex.ts. - Biome is the formatter and linter. Run
npm run lintbefore pushing; CI enforces it. - No em dashes anywhere (code, docs, prose). Use commas, parentheses, or full stops.
- Helpers that talk to external APIs live in
scripts/as dependency-free.mjsfiles (seenotion.mjs,calendar.mjs) so the agent can drive them via Bash.
- New agent capabilities ship as a skill under
coach-plugin/skills/<name>/SKILL.md, plus a row in the skills table inCLAUDE.md. Keep the two in sync. - If a skill references a script command, the command must exist. Docs never describe flags that are not implemented.
- Anything touching Notion goes through
scripts/notion.mjs; anything touching Google Calendar goes throughscripts/calendar.mjs. No new direct API clients.
- Pair changes with tests where the logic is testable (
npm test; node:test files live intests/andscripts/*.test.mjs). - Update the relevant doc in
docs/in the same PR:configuration.mdfor new env vars,deployment.mdfor infra changes. Mirror infra changes in bothinfra/gcp/andinfra/azure/where applicable.
- Small, focused PRs with imperative-mood commit subjects ("Add X", "Fix Y") and a body explaining why.
- PRs must pass CI (lint, build, tests).
- Persona tweaks and personal-workflow changes belong in your fork; PRs should keep the project useful to others.
Oak is a coach, not a doctor. PRs that add medical advice, extreme dieting, or push-through-pain behaviour will be declined. Nutrition guidance stays sensible and non-extreme.