Skip to Content
⚠️Active Development Notice: TimeTiles is under active development. Information may be placeholder content or not up-to-date.
DevelopmentContributingGit & Commit Guidelines

Git & Commit Guidelines

TimeTiles uses conventional commits. The executable rules live in commitlint.config.mjs; .husky/commit-msg runs them for each commit. Check that configuration when a rule changes instead of copying an older example.

Setup

Run make setup from the repository root to configure the development environment, Git hooks, and commit template.

Message Format

<type>(<scope>): <subject> <optional body>
  • Use a lowercase type and scope.
  • Keep the complete first line within 72 characters.
  • Give the subject at least 10 characters, use the imperative, and omit the final period.
  • Describe the concrete change. The validator rejects subjects containing stuff, things, updates, changes, or fixes.
  • Separate the optional body and footers with blank lines; wrap body lines at 100 characters.
  • Explain why the change is needed when the title does not make that clear.

The type describes what changed; the scope describes where.

Types

TypeUse
featNew user functionality
fixBug fix
refactorRestructuring without changing behavior
perfPerformance improvement
testTests and test corrections
docsDocumentation
format / styleFormatting and code style
buildBuild system or dependencies
ciCI workflows
choreOther maintenance
securitySecurity fix or improvement
revertRevert an earlier commit

Scopes

Use ingest for the import pipeline. import is not an accepted commit scope; “import” remains the user-facing term.

AreaAccepted scopes
Apps and packagesweb, docs, ui, assets, config, scraper
Featuresexplore, ingest, geocoding, events, schema, deploy, quota, access, cache, webhooks, admin, auth, media, charts, map
Technical areasdb, api, jobs, deps, seed, test, e2e
Infrastructureci, build, infra

The scraper scope covers TimeScrape and the scraper SDKs; the runner directory is apps/timescrape/. Use deps for dependency updates and ci or build for workflow/build configuration, rather than config.

The SCOPES array in commitlint.config.mjs is authoritative. A scope is optional, but usually helpful for fix, feat, and refactor. Omit redundant combinations such as ci(ci), build(build), and test(test), which the validator rejects. docs(docs) is accepted.

Examples

feat(ingest): add support for JSON API sources fix(geocoding): handle addresses with special characters refactor(events): centralize clustering query defaults test(ingest): cover empty CSV uploads docs: clarify database setup commands ci: cache browser downloads build(deps): upgrade PostgreSQL client

For a change that needs context:

refactor(ingest): remove obsolete interpretation helpers - Remove the unused legacy wrapper and identity conversion. - Assert expected rows directly so shared selection code cannot mask a regression.

Use a BREAKING CHANGE: footer when compatibility changes, and reference relevant issues when useful. Do not add generated-with-Claude text or Claude co-author trailers; the repository validator rejects them.

Commit Workflow

  1. Inspect git status and git diff. Stage only files belonging to the change.
  2. Keep unrelated changes in separate commits.
  3. Run the relevant checks and tests. See Development Setup and Testing Guidelines.
  4. Review git diff --cached before committing.
  5. Read hook failures, correct the cause, and retry normally.

The pre-commit hook checks whole-tree formatting and runs lint/typecheck for staged web, docs, and UI changes. It does not replace relevant tests. Repair reported formatting with pnpm exec oxfmt <file> to avoid unrelated changes. pnpm format and make format run only the formatter. Avoid broad eslint --fix runs: they can remove suppressions for oxlint-owned rules.

To check a proposed message with the same validator as the hook, from the repository root:

echo 'refactor(ingest): remove obsolete interpretation helpers' | pnpm exec commitlint

Validation includes staged-file context. If no files are staged, the configuration falls back to the latest commit’s changed files.

Last updated on