Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Shows a "Sponsor" button on the repo. Fill in the handles you actually use;
# delete the lines you don't. GitHub validates these, so a wrong handle just
# hides that entry rather than breaking the page.
github: [Alvaro5] # requires GitHub Sponsors enabled on your account
# ko_fi: your-handle
# buy_me_a_coffee: your-handle
# custom: ["https://gradepace.vercel.app"]
42 changes: 42 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Bug report
description: Something in the pacing plan or UI is wrong or broken.
labels: [bug]
body:
- type: markdown
attributes:
value: |
Thanks for the report. GradePace runs entirely in your browser, so the
more you can tell me about the GPX and your setup, the faster this gets fixed.
- type: textarea
id: what-happened
attributes:
label: What happened?
description: What did you see, and what did you expect instead?
placeholder: "The projected finish was 3:12 but the course is 70 km, so that can't be right..."
validations:
required: true
- type: textarea
id: gpx
attributes:
label: The GPX file
description: >
If you can share the course (a link, or drag the file into the comment
box after creating the issue), that makes it reproducible. Note if it's a
recorded track (with times) or a route export.
validations:
required: false
- type: input
id: settings
attributes:
label: Settings
description: Flat pace, VAM, hike gate, terrain factor, units, language, if relevant.
placeholder: "6:00/km, VAM 750, gate 18%, terrain x1.04, metric, EN"
validations:
required: false
- type: input
id: env
attributes:
label: Browser / device
placeholder: "Chrome 141 on macOS, or Safari on iPhone"
validations:
required: false
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Try GradePace
url: https://gradepace.vercel.app
about: The live app. Load an example course to see the full output before filing.
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Feature request
description: Suggest something that would make the pacing plan more honest or the app more useful.
labels: [enhancement]
body:
- type: textarea
id: problem
attributes:
label: What are you trying to do?
description: Describe the racing/planning problem, not just the feature. What can't you do today?
validations:
required: true
- type: textarea
id: idea
attributes:
label: Your idea
description: How would you like it to work? Rough is fine.
validations:
required: false
- type: checkboxes
id: thesis
attributes:
label: Fit check
description: GradePace is deliberately about honest self-calibration, not false precision. (Optional.)
options:
- label: This is about a more honest or personal prediction, not just more knobs to tune.
12 changes: 12 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!-- Keep PRs small and focused: one idea each. -->

## What and why

<!-- What does this change, and what problem does it solve? -->

## Checklist

- [ ] `npm run lint && npm test && npm run build` all pass
- [ ] Added or updated tests for any engine/behavior change
- [ ] If this moves the projected finish time, I've called that out explicitly
- [ ] STATUS.md / README updated if the change affects them
42 changes: 42 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

# Cancel superseded runs on the same ref (e.g. rapid pushes to a PR).
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-test:
name: Lint, test, build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm

# `npm install`, not `npm ci`: sharp and the tailwind-oxide / rolldown
# wasm fallbacks pull nested, platform-specific optional deps that a
# macOS-generated lockfile can't fully describe for a Linux runner, so
# `npm ci`'s strict lockfile check fails. `npm install` reconciles the
# tree for whatever platform the runner is.
- name: Install dependencies
run: npm install --no-audit --no-fund

- name: Lint
run: npm run lint

- name: Test (Vitest)
run: npm test

- name: Build
run: npm run build
46 changes: 46 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Contributing to GradePace

Thanks for taking a look. GradePace is a small, opinionated project with a real
race behind it, so contributions are welcome but the bar is "does this make the
pacing plan more honest or the app more useful," not "more features."

## Ground rules

- **The engine is the asset.** `src/lib/pacing.ts` is pure TypeScript: no React,
no DOM, fully unit-tested. Domain logic lives there and stays testable. UI
glue lives in `src/App.tsx` and the component files.
- **Verify against reality, not vibes.** Distances should match known race
lengths, D+ should match published figures, and the Minetti cost model must
match the 2002 paper's measured anchors. There are tests that lock these.
- **Keep the tests green.** `npm test` must pass. A coefficient typo should fail
loudly, so please add a test when you add behavior.
- **Honest uncertainty over false precision.** The product presents a finish
*range* on purpose. Changes that pretend to more accuracy than a GPX-only
prediction can deliver will be pushed back on.

## Getting set up

```sh
npm install
npm run dev # local dev server
npm run test # engine + app tests (Vitest)
npm run lint
npm run build # production build (also what CI runs)
```

## Proposing a change

1. Open an issue first for anything non-trivial, so we can agree on the shape
before you write code. Bug reports with the GPX file (or a link) and what you
expected vs. saw are the most useful.
2. Keep pull requests small and focused. One idea per PR.
3. Don't bundle a model/behavior change (anything that moves the projected
finish time) into an unrelated PR. Call it out so it can be reviewed on its
own merits.
4. Run `npm run lint && npm test && npm run build` before pushing.

## Where things are

The current technical state, decisions, and roadmap live in
[STATUS.md](./STATUS.md). Read it first. The high-level architecture is in the
[README](./README.md#project-structure).
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Alvaro Serero

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading
Loading