c2 — Concept2 Logbook CLI
A CLI tool for syncing and analyzing rowing data from your Concept2 Logbook.
Install
go install github.com/richhaase/c2/cmd/c2@latest
Or pin a release:
go install github.com/richhaase/c2/cmd/c2@v0.5.0
Binaries for macOS and Linux are also attached to each
release.
To build from a checkout:
git clone https://github.com/richhaase/c2.git
cd c2
make install
Quick Start
# Configure token and goals
c2 setup
# Sync workouts
c2 sync
# Check your progress
c2 status
Usage
Setup
Configure your token and goal settings:
c2 setup
Get your personal access token from log.concept2.com under Settings → Developer. The setup wizard will prompt for your token, goal target, and date range.
Sync Workouts
Pull new workouts from the Concept2 API:
c2 sync
View Workouts
# Show last 10 workouts
c2 log
# Show last 25 workouts
c2 log -n 25
Interval workouts are tagged with [IVL rest M:SS.S] so they're visually
distinct from continuous pieces. The rest duration is surfaced because, for
interval workouts, the displayed time (time_formatted) is elapsed time
including rest, while the displayed pace is correctly computed from work
time only. For example:
04/11 5,000m 28:35.4 2:51.5/500m 24spm 112bpm 107df
04/11 3,000m 20:22.6 2:23.8/500m 30spm 152bpm 108df [IVL rest 6:00.0]
The second row is 6x500m with ~1 min rest between reps: 20:22.6 elapsed =
14:22.6 work + 6:00 rest. The 2:23.8/500m pace is the work pace.
Goal Progress
Track progress toward your distance goal:
c2 status
Training Trends
View weekly trends for pace, volume, stroke rate, and heart rate:
# Last 8 weeks (default)
c2 trend
# Last 12 weeks
c2 trend -w 12
HTML Report
Generate a self-contained HTML progress report. Coaching content from the
store renders automatically when present: the latest narrative (as "Coach's
Report"), notes from the last 14 days, and the training-plan excerpt.
c2 report --data emits the entire report as structured JSON
(c2.report.v1) — the machine-readable twin of the HTML, for agents and
custom rendering surfaces:
# Write to a temp file and open it in your browser
c2 report
# Custom output path
c2 report -o ~/Desktop/rowing.html
# Write the file but don't open it
c2 report --no-open
# Show more weeks of history
c2 report -w 16
Export Data
Export workouts to CSV, JSON, or JSONL:
# CSV to stdout
c2 export
# JSON format
c2 export -f json
# Filter by date range
c2 export --from 2026-01-01 --to 2026-03-01
# Pipe to file
c2 export -f jsonl > workouts.jsonl
The CSV export includes workout_type, rest_time_tenths, and
rest_distance columns so interval workouts are fully distinguishable from
continuous pieces without having to consult the full JSON export.
Workout Detail & Derived Stats
# Full detail for one workout: splits, stroke summary, comments
c2 show last
c2 show 118212501
# Derived analytics (the arithmetic, so coaches only interpret)
c2 stats weekly -w 12 # volume/pace/SPM/HR per week
c2 stats goal # trajectory + projection
c2 stats splits last # per-split pace/HR + shape (even/negative/positive)
c2 stats hr-pace -w 8 # avg HR by steady pace band, with early→late drift
All of these accept --json.
Coaching Data
The store holds coaching content alongside workout data, so any coach — human
or AI, on any machine — reads and writes the same facts:
# Subjective report after a row (athlete voice, linked to the workout)
c2 note add --type subjective --workout last "felt slow early, opened up late"
# Coach observations and durable lessons
c2 note add --type lesson --author coach "HR cap is the rule, not pace"
# Review
c2 note list --since 2026-06-01
c2 note list --workout 118212501 --json
c2 show last # linked notes appear in workout detail
# Training plan and coaching playbook (whole-document set/show)
c2 plan set plan.md
c2 playbook show
# Dated coaching report narratives
c2 narrative add 2026-07-05 report.md
c2 narrative show
Notes are stored one file each for the most recent 7 days (safe under iCloud/
Dropbox sync), then automatically compacted into one archive file per year
(c2 data compact runs after every sync). c2 data doctor validates the
whole store.
Machine-Readable Output
log, status, trend, show, stats, and data info accept --json and emit a stable
versioned envelope for scripts and AI agents:
{ "schema": "c2.status.v1", "generated_at": "2026-07-05T18:00:00.000Z", "data": { } }
export -f json emits the same envelope (c2.export.v1) with the full
workout records under data.workouts. export -f jsonl stays one raw
workout per line for streaming.
Data Store
Workout data and coaching data live in a single data directory,
chosen during c2 setup and stored as data_dir in config. Point it at a
synced folder (iCloud, Dropbox, a git repo) to share one store across
machines — the config file with your API token always stays machine-local
in ~/.config/c2/ (mode 600).
# Where is my data, and what's in it?
c2 data info
# Relocate the store (copies, verifies, updates config)
c2 data move ~/Documents/KnowledgeBase/c2-data
Setup validates the directory you pick: it creates it if missing (with
confirmation), checks writability, adopts an existing c2 store it finds
there, and refuses to save a path that fails validation.
Note: bare c2 prints help. Unknown commands error instead of falling
through to a default.
Configuration
Config lives at ~/.config/c2/config.json. Created automatically on c2 setup.
{
"data_dir": "~/.config/c2/data",
"api": {
"base_url": "https://log.concept2.com",
"token": "YOUR_TOKEN"
},
"goal": {
"target_meters": 1000000,
"start_date": "2026-01-01",
"end_date": "2026-12-31"
},
"display": {
"date_format": "%m/%d"
}
}
Development
make check # fmt-check + vet + lint + race tests
make test # tests only
make build # build ./bin/c2
make run ARGS="log -n 5"
License
MIT — see LICENSE