@@ -10,116 +10,53 @@ const primeText = `liftoff-export — primer for LLM agents
1010======================================
1111
1212WHAT IT IS
13- A CLI that reads your personal Liftoff (gymbros.com) data — gym workouts
14- with sets/ reps/weights, recorded bodyweights — and prints it on stdout .
13+ CLI for personal Liftoff (gymbros.com) data: gym workouts with sets/
14+ reps/weights and recorded bodyweights .
1515
16- OUTPUT FORMATS
17- Default: narrow, fitdown-style markdown — date-grouped headings, one
18- exercise per block with set lines and Nx... compression for repeated
19- sets, easy to skim and easy for an LLM to consume inline.
16+ I/O
17+ stdout: data in --format markdown (default; fitdown set notation) or json.
18+ stderr: errors. Exit 0 on success including empty results.
2019
21- --format json Pretty-printed JSON ARRAY of full posts/exercises.
22- Use this when you want the complete row, when piping
23- to jq, or when round-tripping into other tools.
24-
25- Errors go to stderr. You do NOT need '2>&1'. Exit code is 0 on
26- success and non-zero on auth or network failure. An empty result is
27- success — markdown prints "No workouts found.", JSON prints '[]'.
28-
29- AUTH
30- 'liftoff-export auth login' opens an interactive prompt for email/
31- password and writes ~/.config/liftoff-export/auth.json (access token,
32- refresh token, expiry). Subsequent calls auto-refresh when the access
33- token is within 5 minutes of expiry.
34-
35- 'liftoff-export auth status' is a fast local check that exits 0 when a
36- saved token is present and not yet expired, 1 with a clear "not logged
37- in" or "token expired" message otherwise. No network call.
38-
39- 'liftoff-export auth refresh' forces a refresh now.
40- 'liftoff-export auth logout' deletes the stored tokens.
41-
42- Liftoff retires version-pinned API hosts periodically. If a refresh
43- starts failing with "server is deprecated", set LIFTOFF_API_BASE=
44- https://vX-Y-Z.api.getgymbros.com to point at a current version
45- without waiting for a new release.
46-
47- DATE FLAGS (every export subcommand accepts these)
48- --since VALUE inclusive lower bound
49- --until VALUE inclusive upper bound; defaults to now
20+ DATE FLAGS (every subcommand)
21+ --since VALUE / --until VALUE
5022 VALUE: today | yesterday | YYYY-MM-DD | Nd/Nw/Nm/Ny
51-
5223 See https://github.com/quantcli/common/blob/main/CONTRACT.md#3-date-flags
53- for the cross-CLI specification.
5424
5525SUBCOMMANDS
26+ workouts list Every workout in the window
27+ workouts show DATE Workouts on one specific day
28+ workouts stats Per-exercise PR/recent + monthly bar charts
29+ Filters: --exercise NAME, --detail
30+ bodyweights list Recorded bodyweights, one per line
31+ bodyweights stats Current/high/low + monthly trend + plateau
5632
57- workouts list — every workout you've logged.
58- Markdown: 'Workout MONTH D, YYYY' headings; one exercise block per
59- movement with set lines. Bodyweight-relative sets render as
60- 'reps@-assist' (assisted) or 'reps@+added' (banded).
61- JSON: full Post array. Keys (subset):
62- id, startedAt, postedAt, sessionDuration, sessionNotes,
63- bodyweight, caloriesBurned, prCount,
64- exerciseData: [{ exerciseName, exerciseTypes, setsData: [...] }]
65-
66- Filters: --exercise NAME (word-prefix match: 'bench' → 'Bench Press').
67-
68- workouts show DATE
69- Same shape as 'list' but only workouts on DATE. DATE is the same
70- vocabulary as --since (today, yesterday, YYYY-MM-DD). Useful for
71- 'what did I do today' agent prompts.
72-
73- workouts stats — per-exercise summaries across the window.
74- Markdown: one section per exercise with PR/recent and a per-month
75- bar chart of best weight (or duration for cardio).
76- JSON: array of ExerciseSummary { name, type, sessions: [SessionStats] }.
77- Filters: --exercise, --detail (per-session breakdown).
78-
79- bodyweights list — recorded bodyweights.
80- Output: one line per entry, '2026-04-15 187.6 lbs'.
81-
82- bodyweights stats — current/high/low, monthly trend chart, plateau
83- detection on the trailing 6 months.
33+ Inspect any subcommand's row schema with: <subcommand> --since 1d --format json
8434
8535EXAMPLES
86-
87- # Today's workout, scannable
8836 liftoff-export workouts show today
89-
90- # 30-day exercise volume, parsed
91- liftoff-export workouts stats --since 30d --format json | jq '
92- .[] | select(.type == "WR")
93- | { name, total_volume: ([.sessions[].volume] | add) }'
94-
95- # PR over time for one exercise
96- liftoff-export workouts stats --exercise bench --since 1y --format json |
97- jq '.[].sessions | map({ date, weight: .bestWeight, reps: .bestReps })'
98-
99- # Bodyweight delta vs 90 days ago
37+ liftoff-export workouts stats --since 30d --format json |
38+ jq '.[] | select(.type == "WR") | {name, vol: ([.sessions[].volume] | add)}'
10039 liftoff-export bodyweights list --since 90d --format json |
10140 jq '[.[]] | (.[-1].weight - .[0].weight)'
10241
10342GOTCHAS
104- - Workout dates are LOCAL. A 11pm workout buckets on the date you
105- logged it, not the UTC date.
106- - Liftoff retires API hosts periodically — see LIFTOFF_API_BASE above.
107- 'liftoff-export auth status' won't catch this; the failure is a
108- deprecation message on the next subcommand call.
109- - Bodyweight is read off Post.bodyweight, which is the value you
110- entered for that workout — not a separate weigh-in feed. No workout
111- that day means no bodyweight that day.
112- - 'workouts stats' silently bins exercises by name. Renaming an
113- exercise in Liftoff splits it into two summaries.
43+ - Workout dates are LOCAL — 11pm workouts bucket on the day you logged them.
44+ - API hosts rotate; set LIFTOFF_API_BASE=https://vX-Y-Z.api.getgymbros.com
45+ if data calls fail with "server is deprecated".
46+ - Bodyweight is read off Post.bodyweight (the value you entered for that
47+ workout). No workout that day means no bodyweight that day.
48+ - 'workouts stats' bins exercises by name. Renaming an exercise in
49+ Liftoff splits it into two summaries.
11450`
11551
11652var primeCmd = & cobra.Command {
11753 Use : "prime" ,
118- Short : "Print an LLM-targeted primer (output formats, subcommands, jq recipes )" ,
54+ Short : "Print an LLM-targeted primer (one screen )" ,
11955 Long : `Print a one-screen primer aimed at LLM agents calling this CLI as a tool.
120- Covers the output formats (markdown by default, --format json for structured),
121- auth subcommands and env vars, the subcommands and what their rows look like,
122- the shared date flags, and a few jq recipes for common questions.` ,
56+ Covers I/O, the shared date flags, the subcommand menu, and a few jq
57+ recipes. Per the quantcli contract, prime is short — anything that wants
58+ to grow into a man page belongs in --help on the relevant subcommand or
59+ in https://github.com/quantcli/common/blob/main/CONTRACT.md.` ,
12360 RunE : func (cmd * cobra.Command , _ []string ) error {
12461 _ , err := fmt .Fprint (cmd .OutOrStdout (), primeText )
12562 return err
0 commit comments