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
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

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

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.13"]
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: requirements*.txt
- run: pip install -r requirements.txt -r requirements-dev.txt
- run: ruff check .
- run: python -m pytest --cov=. --cov-report=term-missing
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ config.json
*.db
*.db-wal
*.db-shm
.coverage
htmlcov/
coverage.xml

data/
25 changes: 25 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH

test:
image: python:3.12
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
cache:
key:
files: [requirements.txt, requirements-dev.txt]
paths: [.cache/pip]
script:
- pip install -r requirements.txt -r requirements-dev.txt
- ruff check .
- python -m pytest --cov=. --cov-report=term-missing --cov-report=xml
coverage: '/^TOTAL.+?(\d+(?:\.\d+)?%)$/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
16 changes: 16 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# AGENTS.md

## Docs
Keep all docs (ROADMAP.md, CHANGELOG.md `[Unreleased]`, README.md, docs/) in sync with the code and with any plans discussed, in the same change. Released CHANGELOG sections are immutable.

## Git
- Never commit. The maintainer signs commits, and agent commits come out unsigned. Hand over the commit message and list the files to add. Messages follow [Conventional Commits](https://www.conventionalcommits.org/): `type(scope): summary`, e.g. `fix(ui): show transition hint only during belt sequences (ROADMAP 3.18)`, ending with a `Co-Authored-By:` trailer naming the agent.
- Don't stage unless asked in that turn, and then `git add` specific paths only (never `docs/` plan files). The maintainer reviews `git diff` first.
- Run `git status`/`git log` before any claim about commit state; the maintainer commits between turns, so earlier snapshots go stale.
- Feature branches merge into `development`, not `main`. Open PRs with `--base development` and scope diffs/logs against `origin/development`.

## Platforms
The maintainer runs macOS (primary) and Fedora Linux, never Windows. Suggest manual checks on macOS first, Fedora when Linux behavior differs. Windows-only code (`start_app.bat`, `WSAE*` errnos, Windows socket semantics) can't be verified by the maintainer; flag it rather than asking for a test.

## Design target
The primary client is a laptop browser at a desk above the treadmill. Design for desktop width and mouse/keyboard first; keep the phone layout working, but it doesn't drive layout or feature decisions.
38 changes: 38 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,44 @@

All notable changes to WalkingDad will be documented in this file.

## [1.9.0] (2026-10-08)

### Added

- **Add to Home Screen opens WalkingDad full-screen** (ROADMAP 3.19), like an app, without the browser's address and tool bars.
- **Log to Apple Health from the iPhone or iPad running WalkingDad.** A phone can't scan its own screen, so on iPhone/iPad the per-session QR code is now a **Log to Apple Health** button, and the setup QR on the Settings page is an **Install Shortcut** button. Computers still show the QR codes, since a Mac can't write to Apple Health.
- **The Log to Apple Health prompt clears itself once the workout is logged**, on every open WalkingDad page. After the Shortcut finishes, the phone opens WalkingDad in Safari, which marks that session as logged. Dismissing the prompt is now recorded separately from logging. The installed Shortcut doesn't need to change.
- **See which sessions were logged to Apple Health, and log missed ones later.** With Apple Health export on, each session in Recent Sessions shows a filled heart once logged and an outline heart if not. **Edit** adds a **Log** button to each unlogged session.
- **Apple Health export logs steps.** WalkingDad now sends the session's step count to the Shortcut, which logs it as a Steps sample alongside the workout. Reinstall the Shortcut from Settings to pick this up; the old one keeps working without steps.
- **Delete individual sessions.** **Edit** also adds a delete button to each session in Recent Sessions, handy for removing test walks without clearing everything.
- **The screen stays on during an active session** (ROADMAP 3.12), and returns to normal on Pause or End. Browsers only allow this on `localhost` or HTTPS, so it works on the computer running WalkingDad but not on a phone connecting over your network.

### Changed

- **WalkingDad now has a real phone layout** (ROADMAP 3.19). Phones previously showed a shrunken desktop page. Now the speed reading fills the screen, the preset and Pause/End buttons sit full-width at the bottom within thumb reach, every button is large enough to tap while walking, the header controls fold into one menu button, and Recent Sessions shows as cards instead of a wide table. The desktop layout is unchanged.
- **Buttons show a pressed state when clicked or tapped**, instead of fading to transparent while held.
- **Everything WalkingDad writes now lives in a `data/` folder** instead of next to the code: settings (`data/config.json`), the session database, crash-recovery state, and the old JSON-migration backups (`data/backups/`). Existing files move there automatically the first time you start this version; nothing is overwritten. To edit settings by hand, use `data/config.json`.
- **`/reconnect` is now POST-only**, like the belt-control routes. The Connect and Try Again buttons on the connecting screen look and work the same.

### Fixed

- **Other websites can no longer control the treadmill** (ROADMAP 2.2). A page open in your browser could previously submit Start, speed, Clear History, Bluetooth reconnect, or Shutdown requests to WalkingDad behind your back. Requests that come from another website are now refused. Using WalkingDad from any device on your network works exactly as before.
- **Pause and speed buttons no longer error out when Bluetooth isn't running.** If the Bluetooth connection had already gone away, pressing Pause or a speed button showed a server error page. Pause now still pauses the session, and the speed buttons do nothing.
- **A corrupted crash-recovery file no longer stops the app from starting.** If `session_state.json` contained unreadable (non-UTF-8) bytes, startup crashed. Startup now ignores the file, the same as an unparseable one.
- **Speed buttons no longer flash a "Getting the belt moving…" message** (ROADMAP 3.18). Presets and the +/- buttons briefly showed it and pushed the buttons down, and Start, Pause, Resume and End flashed the wrong message ("Stopping belt…", "Pausing belt…"). The message now appears only while the belt is actually starting, pausing or stopping.
- **A quick double-tap can no longer send a button press twice.** Buttons could re-enable mid-request on a live stats update; they now stay disabled from the moment you press one until the next screen loads.

### Internal

- **Tests now cover nearly all of the Python code** (ROADMAP 2.5): routes, Bluetooth sequences against a fake treadmill, status-packet math, persistence, and `run.py`'s launcher. The suite runs in about a second.
- **Continuous integration** (ROADMAP 2.7): `ruff` lint and the test suite run on pull/merge requests and on pushes to `main`/`development` via GitHub Actions (Python 3.10 and 3.13) and GitLab CI (Python 3.12, with coverage shown in merge requests). `ruff` is pinned in `requirements-dev.txt`, and lint fixes in `app.py` (imports sorted, unused `global` declarations removed) have no behavior change.
- **Importing `app.py` with `WALKINGDAD_NO_STARTUP=1` no longer installs the Ctrl+C/SIGTERM handlers or the `atexit` hook**, so pressing Ctrl+C during a test run interrupts pytest instead of killing the process two seconds later. Running the app normally is unchanged.
- **pytest, ruff, and coverage settings merged into `pyproject.toml`**, replacing `pytest.ini`, `ruff.toml`, and `.coveragerc`. `requirements-dev.txt` adds `coverage[toml]` so coverage reads it on Python 3.10.
- **`run.py`'s launcher logic moved into a `main()` function** so it can be tested. `python run.py` behaves the same.
- **`AGENTS.md` added for AI coding agents** (`CLAUDE.md` is a symlink to it): keep docs in sync with code, the git workflow (PRs target `development`, the maintainer commits), the desktop-first design target, and the supported platforms.

---

## [1.8.0] (2026-10-05)

### Added
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Loading
Loading