Contributing to todos.md (v0.1.0)
Thank you for helping build todos.md! This guide covers local setup, coding standards, tests, and releases.
Prerequisites
- Node 20+ (suggest nvm), pnpm 9+
- Python 3.11+
- Postgres 14+ and Redis (Docker recommended)
Setup
- Install JS deps:
pnpm install - Create and activate Python venv; install API deps:
pip install -r apps/web/requirements.txt - Start infra (example):
docker compose up -d db redis - Run DB migrations:
alembic upgrade head - Dev servers:
- API:
uvicorn apps.web.main:app --reload - CLI:
pnpm --filter @todosmd/cli dev - MCP:
pnpm --filter @todosmd/mcp dev
- API:
Code Style
- TypeScript: ESLint + Prettier; strict mode.
- Python: Ruff + Black; type hints encouraged (pyright/mypy TBD).
- Commit messages: Conventional Commits (feat:, fix:, docs:, chore:, refactor:, test:, ci:)
Tests
- Unit tests for parser/normalizer/mint flows.
- Golden diff tests for CLI writes and alias→id rewrites.
- API tests for ETag/Idempotency and error codes.
Branches & PRs
- Fork/branch off
main. Small, focused PRs. - Include before/after examples and diffs when changing parsing/formatting.
- PR checklist: tests pass, lint clean, updated docs if behavior changes.
Versioning & Releases — from day zero
- Semantic versioning
- Start at v0.1.0 (already in .github/release-please-manifest.json).
- Pre-1.0 semantics: feats bump minor, fixes bump patch. Major bumps happen after 1.0.0; before that, breaking changes should be rare and can still be represented with feat! but we keep bump-minor-pre-major true for smoother iteration.
- Conventional Commits
- feat(scope): ... → minor bump
- fix(scope): ... → patch bump
- chore/docs/test: ... → no version bump (unless configured otherwise)
- feat!(scope): ... or footer with BREAKING CHANGE: ... → pre-1.0 still treated as minor (due to config); post-1.0 bumps major
- First release steps
- Push the current branch to main (with the .github files).
- Trigger the release workflow:
- Option A: Create a PR with at least one feat or fix commit title; merge to main. The workflow will open a “chore: release v0.1.0” PR. Merge it to create tag v0.1.0 and CHANGELOG.md.
- Option B: Manually run the workflow (Actions → release-please → Run workflow). It will open the same release PR; merge it to tag v0.1.0.
- Ongoing releases
- Every merged PR with feat/fix updates the pending release PR. Merging that PR creates a new GitHub release and tag (v0.1.1, v0.2.0, etc.).
- Monorepo expansion later
- When we add packages (packages/cli, packages/mcp, packages/schema), we keep manifest mode and map each package path to its own version in .github/release-please-manifest.json. Release-please will then open one release PR that can version multiple components together.
Quick commands to bootstrap locally (once this repo is a git repo)
- Set up git if new:
- git init && git add . && git commit -m "feat: initial scaffolding"
- git branch -M main
- git remote add origin
- git push -u origin main
- Trigger first release:
- Create an empty change with a feat or fix commit or manually run the workflow in GitHub Actions.
- Merge the auto-opened “chore: release v0.1.0” PR → tag v0.1.0 and release appear.
Issue Labels (suggested)
area:cli,area:mcp,area:api,area:web,area:templates,bug,enhancement,docs,security.
Community
- Be respectful. Assume positive intent. Prefer async reviews with crisp diffs.