fitdocs 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fitdocs-0.1.0/.gitignore +44 -0
- fitdocs-0.1.0/CHANGELOG.md +54 -0
- fitdocs-0.1.0/LICENSE +21 -0
- fitdocs-0.1.0/PKG-INFO +249 -0
- fitdocs-0.1.0/README.md +212 -0
- fitdocs-0.1.0/pyproject.toml +168 -0
- fitdocs-0.1.0/src/fitdocs/__init__.py +125 -0
- fitdocs-0.1.0/src/fitdocs/agentskill.py +105 -0
- fitdocs-0.1.0/src/fitdocs/athlete.py +183 -0
- fitdocs-0.1.0/src/fitdocs/audit.py +491 -0
- fitdocs-0.1.0/src/fitdocs/benchmarks.py +692 -0
- fitdocs-0.1.0/src/fitdocs/citation.py +199 -0
- fitdocs-0.1.0/src/fitdocs/cli.py +1627 -0
- fitdocs-0.1.0/src/fitdocs/config.py +146 -0
- fitdocs-0.1.0/src/fitdocs/contract.py +1155 -0
- fitdocs-0.1.0/src/fitdocs/declaration.py +593 -0
- fitdocs-0.1.0/src/fitdocs/docio.py +95 -0
- fitdocs-0.1.0/src/fitdocs/docmerge.py +220 -0
- fitdocs-0.1.0/src/fitdocs/history/__init__.py +68 -0
- fitdocs-0.1.0/src/fitdocs/history/documents.py +223 -0
- fitdocs-0.1.0/src/fitdocs/history/engine.py +462 -0
- fitdocs-0.1.0/src/fitdocs/history/model.py +135 -0
- fitdocs-0.1.0/src/fitdocs/history/page.py +669 -0
- fitdocs-0.1.0/src/fitdocs/history/series.py +738 -0
- fitdocs-0.1.0/src/fitdocs/history/settings.py +268 -0
- fitdocs-0.1.0/src/fitdocs/history/sources.py +463 -0
- fitdocs-0.1.0/src/fitdocs/inbox.py +845 -0
- fitdocs-0.1.0/src/fitdocs/ingest/__init__.py +133 -0
- fitdocs-0.1.0/src/fitdocs/ingest/_fields.py +89 -0
- fitdocs-0.1.0/src/fitdocs/ingest/decode.py +105 -0
- fitdocs-0.1.0/src/fitdocs/ingest/errors.py +29 -0
- fitdocs-0.1.0/src/fitdocs/ingest/laps.py +171 -0
- fitdocs-0.1.0/src/fitdocs/ingest/records.py +164 -0
- fitdocs-0.1.0/src/fitdocs/ingest/sets.py +183 -0
- fitdocs-0.1.0/src/fitdocs/ingest/sport.py +115 -0
- fitdocs-0.1.0/src/fitdocs/ingest/summary.py +418 -0
- fitdocs-0.1.0/src/fitdocs/layout.py +453 -0
- fitdocs-0.1.0/src/fitdocs/load/__init__.py +108 -0
- fitdocs-0.1.0/src/fitdocs/load/arbitrate.py +187 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/__init__.py +113 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/grade.py +267 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/heart_rate.py +292 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/pace.py +277 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/power.py +169 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/sources.py +436 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/sufficiency.py +150 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/types.py +214 -0
- fitdocs-0.1.0/src/fitdocs/load/channels/weighting.py +165 -0
- fitdocs-0.1.0/src/fitdocs/load/docedit.py +407 -0
- fitdocs-0.1.0/src/fitdocs/load/engine.py +677 -0
- fitdocs-0.1.0/src/fitdocs/load/priority.py +66 -0
- fitdocs-0.1.0/src/fitdocs/load/profile.py +1008 -0
- fitdocs-0.1.0/src/fitdocs/load/prompts.py +460 -0
- fitdocs-0.1.0/src/fitdocs/load/qa/__init__.py +57 -0
- fitdocs-0.1.0/src/fitdocs/load/qa/cadence.py +348 -0
- fitdocs-0.1.0/src/fitdocs/load/qa/divergence.py +187 -0
- fitdocs-0.1.0/src/fitdocs/load/qa/drift.py +113 -0
- fitdocs-0.1.0/src/fitdocs/load/qa/flags.py +281 -0
- fitdocs-0.1.0/src/fitdocs/load/qa/sources.py +324 -0
- fitdocs-0.1.0/src/fitdocs/load/qa/staleness.py +147 -0
- fitdocs-0.1.0/src/fitdocs/load/qa/types.py +141 -0
- fitdocs-0.1.0/src/fitdocs/load/registry.py +196 -0
- fitdocs-0.1.0/src/fitdocs/load/render.py +468 -0
- fitdocs-0.1.0/src/fitdocs/load/settings.py +546 -0
- fitdocs-0.1.0/src/fitdocs/load/threshold/__init__.py +23 -0
- fitdocs-0.1.0/src/fitdocs/load/threshold/anchors.py +168 -0
- fitdocs-0.1.0/src/fitdocs/load/threshold/calculator.py +768 -0
- fitdocs-0.1.0/src/fitdocs/load/threshold/discipline.py +117 -0
- fitdocs-0.1.0/src/fitdocs/load/threshold/selection.py +140 -0
- fitdocs-0.1.0/src/fitdocs/load/types.py +451 -0
- fitdocs-0.1.0/src/fitdocs/metrics/__init__.py +160 -0
- fitdocs-0.1.0/src/fitdocs/metrics/aggregates.py +393 -0
- fitdocs-0.1.0/src/fitdocs/metrics/power.py +364 -0
- fitdocs-0.1.0/src/fitdocs/metrics/sources.py +745 -0
- fitdocs-0.1.0/src/fitdocs/metrics/stress.py +203 -0
- fitdocs-0.1.0/src/fitdocs/metrics/types.py +164 -0
- fitdocs-0.1.0/src/fitdocs/metrics/zones.py +75 -0
- fitdocs-0.1.0/src/fitdocs/model.py +241 -0
- fitdocs-0.1.0/src/fitdocs/performance/__init__.py +26 -0
- fitdocs-0.1.0/src/fitdocs/performance/derive.py +787 -0
- fitdocs-0.1.0/src/fitdocs/performance/engine.py +556 -0
- fitdocs-0.1.0/src/fitdocs/performance/models.py +159 -0
- fitdocs-0.1.0/src/fitdocs/performance/sources.py +665 -0
- fitdocs-0.1.0/src/fitdocs/performance/types.py +108 -0
- fitdocs-0.1.0/src/fitdocs/plans/__init__.py +221 -0
- fitdocs-0.1.0/src/fitdocs/plans/aggregate.py +163 -0
- fitdocs-0.1.0/src/fitdocs/plans/block_page.py +351 -0
- fitdocs-0.1.0/src/fitdocs/plans/corpus.py +206 -0
- fitdocs-0.1.0/src/fitdocs/plans/engine.py +577 -0
- fitdocs-0.1.0/src/fitdocs/plans/matching.py +395 -0
- fitdocs-0.1.0/src/fitdocs/plans/model.py +750 -0
- fitdocs-0.1.0/src/fitdocs/plans/page.py +324 -0
- fitdocs-0.1.0/src/fitdocs/plans/placement.py +521 -0
- fitdocs-0.1.0/src/fitdocs/plans/planned_page.py +113 -0
- fitdocs-0.1.0/src/fitdocs/plans/reconcile.py +228 -0
- fitdocs-0.1.0/src/fitdocs/plans/resolution.py +94 -0
- fitdocs-0.1.0/src/fitdocs/plans/settings.py +175 -0
- fitdocs-0.1.0/src/fitdocs/plans/source.py +1130 -0
- fitdocs-0.1.0/src/fitdocs/plugins.py +657 -0
- fitdocs-0.1.0/src/fitdocs/py.typed +0 -0
- fitdocs-0.1.0/src/fitdocs/quarantine.py +245 -0
- fitdocs-0.1.0/src/fitdocs/render/__init__.py +153 -0
- fitdocs-0.1.0/src/fitdocs/render/charts/__init__.py +9 -0
- fitdocs-0.1.0/src/fitdocs/render/charts/calendar.py +482 -0
- fitdocs-0.1.0/src/fitdocs/render/charts/hero.py +421 -0
- fitdocs-0.1.0/src/fitdocs/render/charts/map.py +462 -0
- fitdocs-0.1.0/src/fitdocs/render/charts/palette.py +190 -0
- fitdocs-0.1.0/src/fitdocs/render/charts/series.py +155 -0
- fitdocs-0.1.0/src/fitdocs/render/charts/svg.py +130 -0
- fitdocs-0.1.0/src/fitdocs/render/charts/zones.py +201 -0
- fitdocs-0.1.0/src/fitdocs/render/format.py +106 -0
- fitdocs-0.1.0/src/fitdocs/render/frontmatter.py +159 -0
- fitdocs-0.1.0/src/fitdocs/render/sections.py +618 -0
- fitdocs-0.1.0/src/fitdocs/render/splits.py +340 -0
- fitdocs-0.1.0/src/fitdocs/render/strength.py +180 -0
- fitdocs-0.1.0/src/fitdocs/render/views.py +245 -0
- fitdocs-0.1.0/src/fitdocs/settings.py +71 -0
- fitdocs-0.1.0/src/fitdocs/skills/build-training-block/SKILL.md +249 -0
- fitdocs-0.1.0/src/fitdocs/skills/build-training-block/example-block.toml +105 -0
- fitdocs-0.1.0/src/fitdocs/skills/fitdocs-workouts/SKILL.md +89 -0
- fitdocs-0.1.0/src/fitdocs/sync.py +1515 -0
- fitdocs-0.1.0/src/fitdocs/tiles.py +438 -0
- fitdocs-0.1.0/src/fitdocs/version.py +64 -0
fitdocs-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
venv/
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
*.egg-info/
|
|
9
|
+
.pytest_cache/
|
|
10
|
+
.ruff_cache/
|
|
11
|
+
.mypy_cache/
|
|
12
|
+
|
|
13
|
+
# OS / IDE
|
|
14
|
+
.DS_Store
|
|
15
|
+
.idea/
|
|
16
|
+
|
|
17
|
+
# Machine-local config (mirrors pkm's data-root contract)
|
|
18
|
+
.fitdocs/data-root
|
|
19
|
+
|
|
20
|
+
# Personal fitness data never lives in the repo (hard rule; see CLAUDE.md /
|
|
21
|
+
# tech.md data-root contract). Local .fit/.gpx exports kept for real-data
|
|
22
|
+
# verification stay on disk but are never committed.
|
|
23
|
+
data/
|
|
24
|
+
*.fit
|
|
25
|
+
*.gpx
|
|
26
|
+
|
|
27
|
+
# Source spreadsheets for the withdrawn methodology, kept out of the repo
|
|
28
|
+
# pending redistribution permission from the third party.
|
|
29
|
+
*.xlsx
|
|
30
|
+
|
|
31
|
+
# Copyrighted third-party reference texts, read to source the training-load
|
|
32
|
+
# formulas and never redistributable: page scans of Banister (1991), "Modeling
|
|
33
|
+
# Elite Athletic Performance", ch. 9 of Physiological Testing of the
|
|
34
|
+
# High-Performance Athlete, and the publisher PDF of Morton, Fitz-Clarke &
|
|
35
|
+
# Banister (1990), J Appl Physiol 69(3):1171-1177 (© American Physiological
|
|
36
|
+
# Society). They stay on disk for verification, like the source workbooks above,
|
|
37
|
+
# but are committed nowhere — and these rules are also what keeps them out of
|
|
38
|
+
# the sdist, which ships untracked files that git does not ignore. What was
|
|
39
|
+
# extracted from them: docs/reference/banister-trimp-primary-sources.md.
|
|
40
|
+
bannister_physiological_testing_of_the_high_performance_athlete/
|
|
41
|
+
Morton*Modeling*human*performance*in*running*.pdf
|
|
42
|
+
|
|
43
|
+
# local secrets (Final Surge creds etc.) -- never committed
|
|
44
|
+
.env
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
**Convention:** an entry that touches a governed contract -- the generated
|
|
9
|
+
document and ownership contract, the inbox interface, the plugin API, or the
|
|
10
|
+
`fitdocs.toml` settings schema -- names the contract and the action a user or
|
|
11
|
+
plugin author must take, inline in the entry that changes it. Entries
|
|
12
|
+
describe user-observable behavior, not commit subjects; removing or adding
|
|
13
|
+
the built-in `threshold` calculator is itself a contract change and is
|
|
14
|
+
recorded as one.
|
|
15
|
+
|
|
16
|
+
## [Unreleased]
|
|
17
|
+
|
|
18
|
+
## [0.1.0] - 2026-09-19
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- `fitdocs` is installable as a Python package with a single console
|
|
23
|
+
command.
|
|
24
|
+
- `fitdocs sync` ingests `.fit` files from the configured inbox, archives
|
|
25
|
+
each source, and writes one markdown document per workout under the data
|
|
26
|
+
root's `workouts/` directory, with charts and computed training load;
|
|
27
|
+
`fitdocs regen` rebuilds every workout document from the data root alone
|
|
28
|
+
(the archive, the athlete profile, and settings) -- the original files
|
|
29
|
+
and the inbox are not needed.
|
|
30
|
+
- The data root's owned paths, the overwrite rules, and the user-owned
|
|
31
|
+
regions of every generated document are published as the ownership
|
|
32
|
+
contract; the four owned directories a human or agent browses
|
|
33
|
+
(`workouts/`, `fit-archive/`, `history/`, `blocks/`) each carry a generated
|
|
34
|
+
`AGENTS.md` restating it, and every generated document carries a matching
|
|
35
|
+
provenance banner.
|
|
36
|
+
- The inbox is configured through the `[inbox]` table in
|
|
37
|
+
`<data-root>/fitdocs.toml`: a location fitdocs drains on `sync`, with a
|
|
38
|
+
disposition policy that never deletes a source file.
|
|
39
|
+
- Training-load calculation is pluggable through the `LoadCalculator`
|
|
40
|
+
interface: a calculator is discovered as an installed distribution
|
|
41
|
+
advertising the `fitdocs.load_calculators` entry point, or as a local
|
|
42
|
+
plugin file/directory named in `[plugins]`. fitdocs ships one built-in
|
|
43
|
+
calculator, `threshold`.
|
|
44
|
+
- `fitdocs plugins` lists every registered calculator (built-in, packaged,
|
|
45
|
+
and local) with its id, display name, version, origin, and supported
|
|
46
|
+
modalities, and every plugin load error; it works with or without a
|
|
47
|
+
configured data root.
|
|
48
|
+
- `fitdocs check` reports every place a data root diverges from the
|
|
49
|
+
installed ownership contract.
|
|
50
|
+
- Every packaged agent skill ships inside the distribution and is
|
|
51
|
+
discoverable through `fitdocs skill`, which prints a packaged skill's
|
|
52
|
+
directory and a one-line copy recipe without resolving a data root or
|
|
53
|
+
writing anything.
|
|
54
|
+
- `fitdocs --version` reports the installed package version.
|
fitdocs-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Josh Stauffer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
fitdocs-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: fitdocs
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Turn .fit files into rich per-workout markdown documents, with pluggable training-load calculation.
|
|
5
|
+
Project-URL: Source, https://github.com/joshua-stauffer/fitdocs
|
|
6
|
+
Project-URL: Documentation, https://github.com/joshua-stauffer/fitdocs/blob/main/docs/index.md
|
|
7
|
+
Project-URL: Changelog, https://github.com/joshua-stauffer/fitdocs/blob/main/CHANGELOG.md
|
|
8
|
+
Project-URL: Issues, https://github.com/joshua-stauffer/fitdocs/issues
|
|
9
|
+
Project-URL: Ownership Contract, https://github.com/joshua-stauffer/fitdocs/blob/main/docs/ownership-contract.md
|
|
10
|
+
Project-URL: Plugin Platform, https://github.com/joshua-stauffer/fitdocs/blob/main/docs/plugins.md
|
|
11
|
+
Project-URL: Inbox, https://github.com/joshua-stauffer/fitdocs/blob/main/docs/inbox.md
|
|
12
|
+
Project-URL: Configuration, https://github.com/joshua-stauffer/fitdocs/blob/main/docs/configuration.md
|
|
13
|
+
Project-URL: Install, https://github.com/joshua-stauffer/fitdocs/blob/main/docs/install.md
|
|
14
|
+
Project-URL: Compatibility, https://github.com/joshua-stauffer/fitdocs/blob/main/docs/compatibility.md
|
|
15
|
+
Project-URL: Wiki Integration, https://github.com/joshua-stauffer/fitdocs/blob/main/docs/wiki-integration.md
|
|
16
|
+
Author-email: Josh Stauffer <66793731+joshua-stauffer@users.noreply.github.com>
|
|
17
|
+
License-Expression: MIT
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Keywords: cycling,fit-file,fitness,garmin,markdown,running,training-load
|
|
20
|
+
Classifier: Development Status :: 3 - Alpha
|
|
21
|
+
Classifier: Environment :: Console
|
|
22
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
23
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
24
|
+
Classifier: Programming Language :: Python :: 3
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
28
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
29
|
+
Classifier: Typing :: Typed
|
|
30
|
+
Requires-Python: >=3.11
|
|
31
|
+
Requires-Dist: garmin-fit-sdk>=21.208.0
|
|
32
|
+
Requires-Dist: pyyaml>=6.0
|
|
33
|
+
Requires-Dist: rich>=13
|
|
34
|
+
Requires-Dist: tomli-w>=1.0
|
|
35
|
+
Requires-Dist: typer>=0.12
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# fitdocs
|
|
39
|
+
|
|
40
|
+
An installable personal knowledge manager for fitness. Consumes `.fit` files and
|
|
41
|
+
writes one markdown document per workout — rich, readable activity pages for
|
|
42
|
+
running, cycling, and weight training, with charts and computed training load.
|
|
43
|
+
|
|
44
|
+
Built to plug into a larger markdown PKM (wiki-style, Obsidian-compatible) as a
|
|
45
|
+
first-class path, while remaining feature-complete standalone.
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
fitdocs installs as a single console entry point with either standard
|
|
50
|
+
isolated-application installer:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
uv tool install fitdocs
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
pipx install fitdocs
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
See [Install](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/install.md)
|
|
61
|
+
for the full first-run path — installing from a checkout before the package
|
|
62
|
+
is published, choosing a data root, getting `.fit` files where fitdocs finds
|
|
63
|
+
them, the first run, and what differs between a standalone data root and one
|
|
64
|
+
inside an existing markdown wiki.
|
|
65
|
+
|
|
66
|
+
## What it does
|
|
67
|
+
|
|
68
|
+
1. **Ingest** `.fit` files from a target directory or the standing inbox (user drops files in; fitdocs never watches for them).
|
|
69
|
+
2. **Render** one markdown doc per activity — summary metrics, laps/splits or
|
|
70
|
+
sets/reps, and embedded charts (e.g. the power-vs-heart-rate hero graph) —
|
|
71
|
+
modeled on [fitdocs.ai](https://github.com/joshua-stauffer/fitdocs.ai)'s
|
|
72
|
+
activity views.
|
|
73
|
+
3. **Compute training load** through a pluggable `LoadCalculator` interface.
|
|
74
|
+
fitdocs ships one built-in methodology, `threshold`, and is otherwise the
|
|
75
|
+
carrier: any other calculator is a plugin, installed or dropped in
|
|
76
|
+
locally, and contributions are welcome. If an activity is missing data a
|
|
77
|
+
calculator needs (e.g. max heart rate, a threshold pace), fitdocs prompts
|
|
78
|
+
for it and completes the calculation; when the activity predates the
|
|
79
|
+
prompt, fitdocs also asks whether the answer covers earlier activities
|
|
80
|
+
too.
|
|
81
|
+
4. **Show training history.** `fitdocs history` renders one longitudinal
|
|
82
|
+
page — a fitness/fatigue/form model and chart built from the training
|
|
83
|
+
load already recorded on your workout documents — with no new data to
|
|
84
|
+
enter and no `.fit` file read.
|
|
85
|
+
5. **Render training blocks.** `fitdocs plan` renders one block page per
|
|
86
|
+
source in your plan directory, with one planned-workout page per row
|
|
87
|
+
underneath it — rebuilt from your plan sources and reconciled against
|
|
88
|
+
your logged workout pages; the same pass also runs at the end of
|
|
89
|
+
`fitdocs sync` and `fitdocs regen` (see [Training blocks](#training-blocks)).
|
|
90
|
+
|
|
91
|
+
Organizing workouts into cycles/training blocks was deliberately deferred
|
|
92
|
+
through the first releases; Phase 7 of the roadmap (2026-09-15) adds training
|
|
93
|
+
blocks — a plan document rendered from an athlete-owned source and reconciled
|
|
94
|
+
against logged workouts — as the `training-blocks` (shipped: the plan
|
|
95
|
+
source, the two page types and `fitdocs plan`) and `plan-resolution`
|
|
96
|
+
(shipped: the reconciling pass chained after `fitdocs sync`/`fitdocs regen`
|
|
97
|
+
and run standalone through `fitdocs plan`) specs; only `build-training-block`
|
|
98
|
+
is not yet shipped.
|
|
99
|
+
|
|
100
|
+
## Route maps
|
|
101
|
+
|
|
102
|
+
Outdoor activities get a **Map** section drawn over real basemap tiles —
|
|
103
|
+
the only time fitdocs touches the network. What leaves your machine and
|
|
104
|
+
when, the persistent opt-out, choosing a provider, attribution, and the tile
|
|
105
|
+
cache all now live in
|
|
106
|
+
[Configuration](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/configuration.md#tiles-the-map-tile-provider-and-the-offline-opt-out).
|
|
107
|
+
|
|
108
|
+
## Plugins
|
|
109
|
+
|
|
110
|
+
fitdocs ships one built-in training-load methodology, `threshold`, and
|
|
111
|
+
discovers any other calculator as a plugin, from two channels: an installed
|
|
112
|
+
Python distribution advertising the `fitdocs.load_calculators` entry point
|
|
113
|
+
(`pip install fitdocs-mycalc` is the whole install), or a local plugin
|
|
114
|
+
file/directory named by `[plugins].path` in `<data-root>/fitdocs.toml`. Run
|
|
115
|
+
`fitdocs plugins` at any time to see every registered calculator (id, version,
|
|
116
|
+
origin, modalities) and any plugin load errors — a plugin failure is always a
|
|
117
|
+
warning, never a run failure.
|
|
118
|
+
|
|
119
|
+
**Local plugin files are executed as ordinary code with your own user
|
|
120
|
+
privileges — fitdocs applies no sandboxing.** Only point `[plugins].path` at
|
|
121
|
+
code you trust.
|
|
122
|
+
|
|
123
|
+
See [`docs/plugins.md`](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/plugins.md)
|
|
124
|
+
for the full guide — the worked packaged example, the local-file alternative,
|
|
125
|
+
the public API surface, the compatibility policy, diagnosis of every
|
|
126
|
+
rejection reason, and (linked from there) how to write the calculator itself.
|
|
127
|
+
|
|
128
|
+
## Agent skills
|
|
129
|
+
|
|
130
|
+
fitdocs packages agent skills inside the wheel. Run `fitdocs skill` to list
|
|
131
|
+
the packaged skills and their installed directories, and
|
|
132
|
+
`fitdocs skill <name>` to print one skill's installed directory and a
|
|
133
|
+
recipe for putting it where your agent can use it.
|
|
134
|
+
|
|
135
|
+
**Install** a packaged skill by copying its directory into your agent's
|
|
136
|
+
skills directory — the open SKILL.md standard fixes no location, so your
|
|
137
|
+
agent's own documentation is where you find it.
|
|
138
|
+
|
|
139
|
+
**Verify** a packaged skill is active by asking the agent to list its
|
|
140
|
+
skills; the packaged skill appears under its frontmatter `name`.
|
|
141
|
+
|
|
142
|
+
**Update** a packaged skill once you have upgraded fitdocs: run
|
|
143
|
+
`fitdocs skill <name>` again and replace the old directory with the new
|
|
144
|
+
one; the copied `SKILL.md`'s `metadata.version` says which fitdocs release
|
|
145
|
+
it came from.
|
|
146
|
+
|
|
147
|
+
Two packaged skills ship today: `build-training-block` walks an agent
|
|
148
|
+
through building a training block from the athlete's answers as a plan
|
|
149
|
+
source, rendering it with `fitdocs plan`, amending it, and settling
|
|
150
|
+
ambiguous matches; `fitdocs-workouts` drains the inbox into workout
|
|
151
|
+
documents and reads the drain report. See
|
|
152
|
+
[Wiki Integration](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/wiki-integration.md)
|
|
153
|
+
for where each skill lands, how to confirm it is active, how to update it,
|
|
154
|
+
and an end-to-end recipe for adopting fitdocs into an existing wiki.
|
|
155
|
+
|
|
156
|
+
## Inbox
|
|
157
|
+
|
|
158
|
+
fitdocs defines a standing inbox: get `.fit` files there however you like,
|
|
159
|
+
and `fitdocs sync`, run with no arguments, drains it — performing no
|
|
160
|
+
watching and no scheduling of any kind. See
|
|
161
|
+
[Inbox](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/inbox.md)
|
|
162
|
+
for the full interface: every settings key and its default, drain semantics,
|
|
163
|
+
the safeguards, and the disposition policy's never-delete guarantee.
|
|
164
|
+
|
|
165
|
+
## Training blocks
|
|
166
|
+
|
|
167
|
+
`fitdocs plan` renders every plan source in your plan directory into a block
|
|
168
|
+
page under `blocks/`, plus one planned-workout page per row in a subdirectory
|
|
169
|
+
per block. The plan directory itself is **user-owned and read-only to
|
|
170
|
+
fitdocs**: fitdocs never creates, writes, renames, or deletes anything
|
|
171
|
+
there. It is configured in the `[plans]` table of
|
|
172
|
+
`<data-root>/fitdocs.toml`, the same settings file `[tiles]`, `[inbox]`, and
|
|
173
|
+
`[plugins]` share, which is itself read-only to fitdocs.
|
|
174
|
+
|
|
175
|
+
| Key | Meaning | Default |
|
|
176
|
+
|-----|---------|---------|
|
|
177
|
+
| `path` | The plan-source location. An absolute path is used as given; a relative path resolves against the data root. **Never created** by fitdocs. Must lie outside the owned paths — configuring it inside `blocks/` or another owned path is a configuration error. | `"plans"` (i.e. `<data-root>/plans/`) |
|
|
178
|
+
|
|
179
|
+
`fitdocs plan`, and the same pass chained at the end of `fitdocs sync` and
|
|
180
|
+
`fitdocs regen`, also reconciles each row against the logged workout pages,
|
|
181
|
+
resolving it to one of five states — `matched`, `overridden`, `skipped`,
|
|
182
|
+
`not logged`, or `upcoming` — a `matched` row further labeled `exact` (one
|
|
183
|
+
candidate), `absorbed` (several candidates, all taken by that one row — a
|
|
184
|
+
split session), or `ambiguous` when two or more planned workouts on the
|
|
185
|
+
same day compete for the same candidates, in which case the proposed
|
|
186
|
+
pairing is never presented as settled. An `[[override]]` entry in a plan
|
|
187
|
+
source pins a row to named logged workouts, or marks it skipped, ahead of
|
|
188
|
+
that automatic matching. Standalone or chained, the resolution shown is
|
|
189
|
+
re-derived from whatever the logged workout pages currently record —
|
|
190
|
+
nothing about the match is stored, and nothing is written back into a
|
|
191
|
+
workout page or a plan source.
|
|
192
|
+
|
|
193
|
+
## Benchmarks
|
|
194
|
+
|
|
195
|
+
`fitdocs derive-benchmarks [--out PATH] [--dry-run]` turns your tagged
|
|
196
|
+
efforts (races, tests, and hard efforts you marked with the `effort`
|
|
197
|
+
frontmatter key) into dated benchmarks — threshold pace, lactate-threshold
|
|
198
|
+
heart rate, and functional threshold power — written to `athlete.toml`
|
|
199
|
+
alongside anything you typed in by hand. It never touches a benchmark you
|
|
200
|
+
recorded yourself, reports exactly why any tagged page was declined or
|
|
201
|
+
failed, and `--dry-run` prints the identical report without writing
|
|
202
|
+
anything.
|
|
203
|
+
|
|
204
|
+
## Ownership
|
|
205
|
+
|
|
206
|
+
fitdocs writes into a wiki it does not control, so what it owns and what
|
|
207
|
+
you own is a published, versioned contract, not an implicit arrangement:
|
|
208
|
+
see the
|
|
209
|
+
[fitdocs Ownership Contract](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/ownership-contract.md).
|
|
210
|
+
|
|
211
|
+
In short: fitdocs owns `workouts/`, `workouts/assets/`, `history/`,
|
|
212
|
+
`history/assets/`, `blocks/`, `fit-archive/`, `.cache/`, and `.fitdocs/`
|
|
213
|
+
under your data root (plus any location your `fitdocs.toml` settings
|
|
214
|
+
configure it to write into — the [Inbox](#inbox)'s `path` and
|
|
215
|
+
`processed_dir` are the first example), and writes nowhere else. `history/`
|
|
216
|
+
and `history/assets/` hold a second, generated document type — the
|
|
217
|
+
training-history page `fitdocs history` writes, alongside the per-workout
|
|
218
|
+
documents under `workouts/` — and carry no user-owned content of their own.
|
|
219
|
+
`blocks/` holds two further generated document types — one block page per
|
|
220
|
+
plan source and one planned-workout page per row, written by `fitdocs plan`
|
|
221
|
+
— of which the block page carries one user-owned region, `notes`, preserved
|
|
222
|
+
the same way a workout document's `notes` region is; the planned-workout
|
|
223
|
+
page carries no user-owned content. You own every workout document's
|
|
224
|
+
`notes` and `workout` regions, and its effort-tag frontmatter keys (`effort`,
|
|
225
|
+
`effort_distance_m`, `effort_time_s`, `effort_event`) — see the published
|
|
226
|
+
contract for the full detail. And `athlete.toml`'s hand-added keys survive
|
|
227
|
+
every fitdocs write. Every generated document carries a provenance stamp,
|
|
228
|
+
and the four owned directories a human or agent browses — `workouts/`,
|
|
229
|
+
`history/`, `blocks/`, and `fit-archive/` — each carry an `AGENTS.md`
|
|
230
|
+
restating the same contract for LLM agents maintaining the wiki.
|
|
231
|
+
|
|
232
|
+
## Development workflow
|
|
233
|
+
|
|
234
|
+
All feature work follows Kiro-style Spec-Driven Development via
|
|
235
|
+
[cc-sdd](https://github.com/gotalab/cc-sdd) (`/kiro-*` skills in Claude Code).
|
|
236
|
+
Start with `.kiro/steering/roadmap.md` for the current plan; `.kiro/specs/`
|
|
237
|
+
holds every feature spec (requirements → design → tasks → implementation),
|
|
238
|
+
and `docs/reference/` holds the research and methodology references backing
|
|
239
|
+
them.
|
|
240
|
+
|
|
241
|
+
## Learn more
|
|
242
|
+
|
|
243
|
+
- [Documentation index](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/index.md) — the single entry point into every page below.
|
|
244
|
+
- [Install](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/install.md) — the full first-run path, standalone or wiki-hosted.
|
|
245
|
+
- [Configuration](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/configuration.md) — the data-root contract, the settings file, and the network/offline behavior.
|
|
246
|
+
- [Inbox](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/inbox.md) — the full inbox interface.
|
|
247
|
+
- [Compatibility policy](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/compatibility.md) — what a version number promises.
|
|
248
|
+
- [Plugin platform](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/plugins.md) — the calculator plugin API.
|
|
249
|
+
- [Ownership contract](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/ownership-contract.md) — what fitdocs owns in your data root and what you own.
|
fitdocs-0.1.0/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# fitdocs
|
|
2
|
+
|
|
3
|
+
An installable personal knowledge manager for fitness. Consumes `.fit` files and
|
|
4
|
+
writes one markdown document per workout — rich, readable activity pages for
|
|
5
|
+
running, cycling, and weight training, with charts and computed training load.
|
|
6
|
+
|
|
7
|
+
Built to plug into a larger markdown PKM (wiki-style, Obsidian-compatible) as a
|
|
8
|
+
first-class path, while remaining feature-complete standalone.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
fitdocs installs as a single console entry point with either standard
|
|
13
|
+
isolated-application installer:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
uv tool install fitdocs
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
pipx install fitdocs
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
See [Install](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/install.md)
|
|
24
|
+
for the full first-run path — installing from a checkout before the package
|
|
25
|
+
is published, choosing a data root, getting `.fit` files where fitdocs finds
|
|
26
|
+
them, the first run, and what differs between a standalone data root and one
|
|
27
|
+
inside an existing markdown wiki.
|
|
28
|
+
|
|
29
|
+
## What it does
|
|
30
|
+
|
|
31
|
+
1. **Ingest** `.fit` files from a target directory or the standing inbox (user drops files in; fitdocs never watches for them).
|
|
32
|
+
2. **Render** one markdown doc per activity — summary metrics, laps/splits or
|
|
33
|
+
sets/reps, and embedded charts (e.g. the power-vs-heart-rate hero graph) —
|
|
34
|
+
modeled on [fitdocs.ai](https://github.com/joshua-stauffer/fitdocs.ai)'s
|
|
35
|
+
activity views.
|
|
36
|
+
3. **Compute training load** through a pluggable `LoadCalculator` interface.
|
|
37
|
+
fitdocs ships one built-in methodology, `threshold`, and is otherwise the
|
|
38
|
+
carrier: any other calculator is a plugin, installed or dropped in
|
|
39
|
+
locally, and contributions are welcome. If an activity is missing data a
|
|
40
|
+
calculator needs (e.g. max heart rate, a threshold pace), fitdocs prompts
|
|
41
|
+
for it and completes the calculation; when the activity predates the
|
|
42
|
+
prompt, fitdocs also asks whether the answer covers earlier activities
|
|
43
|
+
too.
|
|
44
|
+
4. **Show training history.** `fitdocs history` renders one longitudinal
|
|
45
|
+
page — a fitness/fatigue/form model and chart built from the training
|
|
46
|
+
load already recorded on your workout documents — with no new data to
|
|
47
|
+
enter and no `.fit` file read.
|
|
48
|
+
5. **Render training blocks.** `fitdocs plan` renders one block page per
|
|
49
|
+
source in your plan directory, with one planned-workout page per row
|
|
50
|
+
underneath it — rebuilt from your plan sources and reconciled against
|
|
51
|
+
your logged workout pages; the same pass also runs at the end of
|
|
52
|
+
`fitdocs sync` and `fitdocs regen` (see [Training blocks](#training-blocks)).
|
|
53
|
+
|
|
54
|
+
Organizing workouts into cycles/training blocks was deliberately deferred
|
|
55
|
+
through the first releases; Phase 7 of the roadmap (2026-09-15) adds training
|
|
56
|
+
blocks — a plan document rendered from an athlete-owned source and reconciled
|
|
57
|
+
against logged workouts — as the `training-blocks` (shipped: the plan
|
|
58
|
+
source, the two page types and `fitdocs plan`) and `plan-resolution`
|
|
59
|
+
(shipped: the reconciling pass chained after `fitdocs sync`/`fitdocs regen`
|
|
60
|
+
and run standalone through `fitdocs plan`) specs; only `build-training-block`
|
|
61
|
+
is not yet shipped.
|
|
62
|
+
|
|
63
|
+
## Route maps
|
|
64
|
+
|
|
65
|
+
Outdoor activities get a **Map** section drawn over real basemap tiles —
|
|
66
|
+
the only time fitdocs touches the network. What leaves your machine and
|
|
67
|
+
when, the persistent opt-out, choosing a provider, attribution, and the tile
|
|
68
|
+
cache all now live in
|
|
69
|
+
[Configuration](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/configuration.md#tiles-the-map-tile-provider-and-the-offline-opt-out).
|
|
70
|
+
|
|
71
|
+
## Plugins
|
|
72
|
+
|
|
73
|
+
fitdocs ships one built-in training-load methodology, `threshold`, and
|
|
74
|
+
discovers any other calculator as a plugin, from two channels: an installed
|
|
75
|
+
Python distribution advertising the `fitdocs.load_calculators` entry point
|
|
76
|
+
(`pip install fitdocs-mycalc` is the whole install), or a local plugin
|
|
77
|
+
file/directory named by `[plugins].path` in `<data-root>/fitdocs.toml`. Run
|
|
78
|
+
`fitdocs plugins` at any time to see every registered calculator (id, version,
|
|
79
|
+
origin, modalities) and any plugin load errors — a plugin failure is always a
|
|
80
|
+
warning, never a run failure.
|
|
81
|
+
|
|
82
|
+
**Local plugin files are executed as ordinary code with your own user
|
|
83
|
+
privileges — fitdocs applies no sandboxing.** Only point `[plugins].path` at
|
|
84
|
+
code you trust.
|
|
85
|
+
|
|
86
|
+
See [`docs/plugins.md`](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/plugins.md)
|
|
87
|
+
for the full guide — the worked packaged example, the local-file alternative,
|
|
88
|
+
the public API surface, the compatibility policy, diagnosis of every
|
|
89
|
+
rejection reason, and (linked from there) how to write the calculator itself.
|
|
90
|
+
|
|
91
|
+
## Agent skills
|
|
92
|
+
|
|
93
|
+
fitdocs packages agent skills inside the wheel. Run `fitdocs skill` to list
|
|
94
|
+
the packaged skills and their installed directories, and
|
|
95
|
+
`fitdocs skill <name>` to print one skill's installed directory and a
|
|
96
|
+
recipe for putting it where your agent can use it.
|
|
97
|
+
|
|
98
|
+
**Install** a packaged skill by copying its directory into your agent's
|
|
99
|
+
skills directory — the open SKILL.md standard fixes no location, so your
|
|
100
|
+
agent's own documentation is where you find it.
|
|
101
|
+
|
|
102
|
+
**Verify** a packaged skill is active by asking the agent to list its
|
|
103
|
+
skills; the packaged skill appears under its frontmatter `name`.
|
|
104
|
+
|
|
105
|
+
**Update** a packaged skill once you have upgraded fitdocs: run
|
|
106
|
+
`fitdocs skill <name>` again and replace the old directory with the new
|
|
107
|
+
one; the copied `SKILL.md`'s `metadata.version` says which fitdocs release
|
|
108
|
+
it came from.
|
|
109
|
+
|
|
110
|
+
Two packaged skills ship today: `build-training-block` walks an agent
|
|
111
|
+
through building a training block from the athlete's answers as a plan
|
|
112
|
+
source, rendering it with `fitdocs plan`, amending it, and settling
|
|
113
|
+
ambiguous matches; `fitdocs-workouts` drains the inbox into workout
|
|
114
|
+
documents and reads the drain report. See
|
|
115
|
+
[Wiki Integration](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/wiki-integration.md)
|
|
116
|
+
for where each skill lands, how to confirm it is active, how to update it,
|
|
117
|
+
and an end-to-end recipe for adopting fitdocs into an existing wiki.
|
|
118
|
+
|
|
119
|
+
## Inbox
|
|
120
|
+
|
|
121
|
+
fitdocs defines a standing inbox: get `.fit` files there however you like,
|
|
122
|
+
and `fitdocs sync`, run with no arguments, drains it — performing no
|
|
123
|
+
watching and no scheduling of any kind. See
|
|
124
|
+
[Inbox](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/inbox.md)
|
|
125
|
+
for the full interface: every settings key and its default, drain semantics,
|
|
126
|
+
the safeguards, and the disposition policy's never-delete guarantee.
|
|
127
|
+
|
|
128
|
+
## Training blocks
|
|
129
|
+
|
|
130
|
+
`fitdocs plan` renders every plan source in your plan directory into a block
|
|
131
|
+
page under `blocks/`, plus one planned-workout page per row in a subdirectory
|
|
132
|
+
per block. The plan directory itself is **user-owned and read-only to
|
|
133
|
+
fitdocs**: fitdocs never creates, writes, renames, or deletes anything
|
|
134
|
+
there. It is configured in the `[plans]` table of
|
|
135
|
+
`<data-root>/fitdocs.toml`, the same settings file `[tiles]`, `[inbox]`, and
|
|
136
|
+
`[plugins]` share, which is itself read-only to fitdocs.
|
|
137
|
+
|
|
138
|
+
| Key | Meaning | Default |
|
|
139
|
+
|-----|---------|---------|
|
|
140
|
+
| `path` | The plan-source location. An absolute path is used as given; a relative path resolves against the data root. **Never created** by fitdocs. Must lie outside the owned paths — configuring it inside `blocks/` or another owned path is a configuration error. | `"plans"` (i.e. `<data-root>/plans/`) |
|
|
141
|
+
|
|
142
|
+
`fitdocs plan`, and the same pass chained at the end of `fitdocs sync` and
|
|
143
|
+
`fitdocs regen`, also reconciles each row against the logged workout pages,
|
|
144
|
+
resolving it to one of five states — `matched`, `overridden`, `skipped`,
|
|
145
|
+
`not logged`, or `upcoming` — a `matched` row further labeled `exact` (one
|
|
146
|
+
candidate), `absorbed` (several candidates, all taken by that one row — a
|
|
147
|
+
split session), or `ambiguous` when two or more planned workouts on the
|
|
148
|
+
same day compete for the same candidates, in which case the proposed
|
|
149
|
+
pairing is never presented as settled. An `[[override]]` entry in a plan
|
|
150
|
+
source pins a row to named logged workouts, or marks it skipped, ahead of
|
|
151
|
+
that automatic matching. Standalone or chained, the resolution shown is
|
|
152
|
+
re-derived from whatever the logged workout pages currently record —
|
|
153
|
+
nothing about the match is stored, and nothing is written back into a
|
|
154
|
+
workout page or a plan source.
|
|
155
|
+
|
|
156
|
+
## Benchmarks
|
|
157
|
+
|
|
158
|
+
`fitdocs derive-benchmarks [--out PATH] [--dry-run]` turns your tagged
|
|
159
|
+
efforts (races, tests, and hard efforts you marked with the `effort`
|
|
160
|
+
frontmatter key) into dated benchmarks — threshold pace, lactate-threshold
|
|
161
|
+
heart rate, and functional threshold power — written to `athlete.toml`
|
|
162
|
+
alongside anything you typed in by hand. It never touches a benchmark you
|
|
163
|
+
recorded yourself, reports exactly why any tagged page was declined or
|
|
164
|
+
failed, and `--dry-run` prints the identical report without writing
|
|
165
|
+
anything.
|
|
166
|
+
|
|
167
|
+
## Ownership
|
|
168
|
+
|
|
169
|
+
fitdocs writes into a wiki it does not control, so what it owns and what
|
|
170
|
+
you own is a published, versioned contract, not an implicit arrangement:
|
|
171
|
+
see the
|
|
172
|
+
[fitdocs Ownership Contract](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/ownership-contract.md).
|
|
173
|
+
|
|
174
|
+
In short: fitdocs owns `workouts/`, `workouts/assets/`, `history/`,
|
|
175
|
+
`history/assets/`, `blocks/`, `fit-archive/`, `.cache/`, and `.fitdocs/`
|
|
176
|
+
under your data root (plus any location your `fitdocs.toml` settings
|
|
177
|
+
configure it to write into — the [Inbox](#inbox)'s `path` and
|
|
178
|
+
`processed_dir` are the first example), and writes nowhere else. `history/`
|
|
179
|
+
and `history/assets/` hold a second, generated document type — the
|
|
180
|
+
training-history page `fitdocs history` writes, alongside the per-workout
|
|
181
|
+
documents under `workouts/` — and carry no user-owned content of their own.
|
|
182
|
+
`blocks/` holds two further generated document types — one block page per
|
|
183
|
+
plan source and one planned-workout page per row, written by `fitdocs plan`
|
|
184
|
+
— of which the block page carries one user-owned region, `notes`, preserved
|
|
185
|
+
the same way a workout document's `notes` region is; the planned-workout
|
|
186
|
+
page carries no user-owned content. You own every workout document's
|
|
187
|
+
`notes` and `workout` regions, and its effort-tag frontmatter keys (`effort`,
|
|
188
|
+
`effort_distance_m`, `effort_time_s`, `effort_event`) — see the published
|
|
189
|
+
contract for the full detail. And `athlete.toml`'s hand-added keys survive
|
|
190
|
+
every fitdocs write. Every generated document carries a provenance stamp,
|
|
191
|
+
and the four owned directories a human or agent browses — `workouts/`,
|
|
192
|
+
`history/`, `blocks/`, and `fit-archive/` — each carry an `AGENTS.md`
|
|
193
|
+
restating the same contract for LLM agents maintaining the wiki.
|
|
194
|
+
|
|
195
|
+
## Development workflow
|
|
196
|
+
|
|
197
|
+
All feature work follows Kiro-style Spec-Driven Development via
|
|
198
|
+
[cc-sdd](https://github.com/gotalab/cc-sdd) (`/kiro-*` skills in Claude Code).
|
|
199
|
+
Start with `.kiro/steering/roadmap.md` for the current plan; `.kiro/specs/`
|
|
200
|
+
holds every feature spec (requirements → design → tasks → implementation),
|
|
201
|
+
and `docs/reference/` holds the research and methodology references backing
|
|
202
|
+
them.
|
|
203
|
+
|
|
204
|
+
## Learn more
|
|
205
|
+
|
|
206
|
+
- [Documentation index](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/index.md) — the single entry point into every page below.
|
|
207
|
+
- [Install](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/install.md) — the full first-run path, standalone or wiki-hosted.
|
|
208
|
+
- [Configuration](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/configuration.md) — the data-root contract, the settings file, and the network/offline behavior.
|
|
209
|
+
- [Inbox](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/inbox.md) — the full inbox interface.
|
|
210
|
+
- [Compatibility policy](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/compatibility.md) — what a version number promises.
|
|
211
|
+
- [Plugin platform](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/plugins.md) — the calculator plugin API.
|
|
212
|
+
- [Ownership contract](https://github.com/joshua-stauffer/fitdocs/blob/main/docs/ownership-contract.md) — what fitdocs owns in your data root and what you own.
|