endurance-coach 0.1.0 → 1.0.0
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.
- package/README.md +3 -0
- package/dist/cli.js +318 -35
- package/dist/expander/expander.d.ts +20 -0
- package/dist/expander/expander.js +339 -0
- package/dist/expander/index.d.ts +8 -0
- package/dist/expander/index.js +9 -0
- package/dist/expander/types.d.ts +169 -0
- package/dist/expander/types.js +6 -0
- package/dist/expander/zones.d.ts +50 -0
- package/dist/expander/zones.js +159 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -1
- package/dist/schema/compact-plan.d.ts +175 -0
- package/dist/schema/compact-plan.js +64 -0
- package/dist/schema/compact-plan.schema.d.ts +277 -0
- package/dist/schema/compact-plan.schema.js +205 -0
- package/dist/templates/index.d.ts +10 -0
- package/dist/templates/index.js +13 -0
- package/dist/templates/interpolate.d.ts +51 -0
- package/dist/templates/interpolate.js +204 -0
- package/dist/templates/loader.d.ts +19 -0
- package/dist/templates/loader.js +129 -0
- package/dist/templates/template.schema.d.ts +401 -0
- package/dist/templates/template.schema.js +101 -0
- package/dist/templates/template.types.d.ts +155 -0
- package/dist/templates/template.types.js +7 -0
- package/dist/templates/yaml-parser.d.ts +15 -0
- package/dist/templates/yaml-parser.js +18 -0
- package/package.json +2 -1
- package/templates/bike/CLAUDE.md +7 -0
- package/templates/bike/easy.yaml +38 -0
- package/templates/bike/endurance.yaml +42 -0
- package/templates/bike/hills.yaml +80 -0
- package/templates/bike/overunders.yaml +81 -0
- package/templates/bike/rest.yaml +16 -0
- package/templates/bike/sweetspot.yaml +80 -0
- package/templates/bike/tempo.yaml +79 -0
- package/templates/bike/threshold.yaml +83 -0
- package/templates/bike/vo2max.yaml +84 -0
- package/templates/brick/CLAUDE.md +7 -0
- package/templates/brick/halfironman.yaml +72 -0
- package/templates/brick/ironman.yaml +72 -0
- package/templates/brick/olympic.yaml +70 -0
- package/templates/brick/sprint.yaml +70 -0
- package/templates/plan-viewer.html +22 -22
- package/templates/run/CLAUDE.md +7 -0
- package/templates/run/easy.yaml +36 -0
- package/templates/run/fartlek.yaml +40 -0
- package/templates/run/hills.yaml +36 -0
- package/templates/run/intervals.1k.yaml +63 -0
- package/templates/run/intervals.400.yaml +63 -0
- package/templates/run/intervals.800.yaml +63 -0
- package/templates/run/intervals.mile.yaml +64 -0
- package/templates/run/long.yaml +41 -0
- package/templates/run/progression.yaml +49 -0
- package/templates/run/race.5k.yaml +36 -0
- package/templates/run/recovery.yaml +36 -0
- package/templates/run/rest.yaml +16 -0
- package/templates/run/strides.yaml +49 -0
- package/templates/run/tempo.yaml +56 -0
- package/templates/run/threshold.yaml +56 -0
- package/templates/strength/CLAUDE.md +7 -0
- package/templates/strength/core.yaml +56 -0
- package/templates/strength/foundation.yaml +65 -0
- package/templates/strength/full.yaml +73 -0
- package/templates/strength/maintenance.yaml +62 -0
- package/templates/swim/CLAUDE.md +7 -0
- package/templates/swim/aerobic.yaml +67 -0
- package/templates/swim/easy.yaml +51 -0
- package/templates/swim/openwater.yaml +60 -0
- package/templates/swim/rest.yaml +16 -0
- package/templates/swim/technique.yaml +67 -0
- package/templates/swim/threshold.yaml +75 -0
- package/templates/swim/vo2max.yaml +88 -0
- /package/bin/{claude-coach.js → endurance-coach.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "endurance-coach",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"author": "Felix Rieseberg",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Shiva Prasad <sp@shiv19.com> (https://shiv19.com)"
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"jszip": "^3.10.1",
|
|
56
56
|
"open": "^10.1.0",
|
|
57
57
|
"undici": "^7.16.0",
|
|
58
|
+
"yaml": "^2.8.2",
|
|
58
59
|
"zod": "^4.3.5"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
id: bike.easy
|
|
2
|
+
name: Easy Ride
|
|
3
|
+
sport: bike
|
|
4
|
+
type: endurance
|
|
5
|
+
category: endurance
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
duration:
|
|
9
|
+
type: int
|
|
10
|
+
required: true
|
|
11
|
+
default: 60
|
|
12
|
+
min: 30
|
|
13
|
+
max: 120
|
|
14
|
+
description: Duration in minutes
|
|
15
|
+
|
|
16
|
+
structure:
|
|
17
|
+
main:
|
|
18
|
+
- type: work
|
|
19
|
+
name: Easy Ride
|
|
20
|
+
duration: "${duration}min"
|
|
21
|
+
power: "< 55% FTP"
|
|
22
|
+
intensity: Zone 1-2
|
|
23
|
+
|
|
24
|
+
humanReadable: |
|
|
25
|
+
EASY RIDE - ${duration} minutes
|
|
26
|
+
|
|
27
|
+
Ride at a comfortable pace throughout.
|
|
28
|
+
Power: Under 55% FTP (Recovery/Zone 1-2)
|
|
29
|
+
Heart Rate: Zone 1-2
|
|
30
|
+
|
|
31
|
+
Keep effort very light. This is active recovery.
|
|
32
|
+
Spin easy, keep cadence comfortable (85-95 rpm).
|
|
33
|
+
Stay in the small ring if needed.
|
|
34
|
+
|
|
35
|
+
estimatedDuration: "${duration}"
|
|
36
|
+
targetZone: Z1-Z2
|
|
37
|
+
rpe: "2-3"
|
|
38
|
+
notes: Active recovery, easy spinning
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
id: bike.endurance
|
|
2
|
+
name: Endurance Ride
|
|
3
|
+
sport: bike
|
|
4
|
+
type: endurance
|
|
5
|
+
category: endurance
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
duration:
|
|
9
|
+
type: int
|
|
10
|
+
required: true
|
|
11
|
+
default: 120
|
|
12
|
+
min: 60
|
|
13
|
+
max: 360
|
|
14
|
+
description: Duration in minutes
|
|
15
|
+
|
|
16
|
+
structure:
|
|
17
|
+
main:
|
|
18
|
+
- type: work
|
|
19
|
+
name: Endurance Ride
|
|
20
|
+
duration: "${duration}min"
|
|
21
|
+
power: "56-75% FTP"
|
|
22
|
+
intensity: Zone 2
|
|
23
|
+
|
|
24
|
+
humanReadable: |
|
|
25
|
+
ENDURANCE RIDE - ${duration} minutes
|
|
26
|
+
|
|
27
|
+
Steady aerobic riding at Zone 2.
|
|
28
|
+
Power: 56-75% FTP
|
|
29
|
+
Heart Rate: Zone 2
|
|
30
|
+
|
|
31
|
+
Maintain a consistent, sustainable effort.
|
|
32
|
+
Cadence: 80-95 rpm
|
|
33
|
+
You should be able to hold a conversation.
|
|
34
|
+
|
|
35
|
+
For rides over 2 hours:
|
|
36
|
+
- Fuel with 30-60g carbs/hour
|
|
37
|
+
- Stay hydrated (500-750ml/hour)
|
|
38
|
+
|
|
39
|
+
estimatedDuration: "${duration}"
|
|
40
|
+
targetZone: Z2
|
|
41
|
+
rpe: "4-5"
|
|
42
|
+
notes: Aerobic base building, long steady state
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
id: bike.hills
|
|
2
|
+
name: Hill Repeats
|
|
3
|
+
sport: bike
|
|
4
|
+
type: hills
|
|
5
|
+
category: strength
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
reps:
|
|
9
|
+
type: int
|
|
10
|
+
required: true
|
|
11
|
+
default: 5
|
|
12
|
+
min: 3
|
|
13
|
+
max: 8
|
|
14
|
+
description: Number of hill repeats
|
|
15
|
+
climb_mins:
|
|
16
|
+
type: int
|
|
17
|
+
default: 6
|
|
18
|
+
min: 4
|
|
19
|
+
max: 10
|
|
20
|
+
description: Duration of each climb in minutes
|
|
21
|
+
warmup_mins:
|
|
22
|
+
type: int
|
|
23
|
+
default: 20
|
|
24
|
+
description: Warmup duration in minutes
|
|
25
|
+
cooldown_mins:
|
|
26
|
+
type: int
|
|
27
|
+
default: 15
|
|
28
|
+
description: Cooldown duration in minutes
|
|
29
|
+
|
|
30
|
+
structure:
|
|
31
|
+
warmup:
|
|
32
|
+
- type: warmup
|
|
33
|
+
name: Easy spin to climb
|
|
34
|
+
duration: "${warmup_mins}min"
|
|
35
|
+
power: "< 65% FTP"
|
|
36
|
+
intensity: Zone 1-2
|
|
37
|
+
main:
|
|
38
|
+
- type: intervals
|
|
39
|
+
repeats: "${reps}"
|
|
40
|
+
work:
|
|
41
|
+
type: work
|
|
42
|
+
name: Hill climb
|
|
43
|
+
duration: "${climb_mins}min"
|
|
44
|
+
power: "100-110% FTP"
|
|
45
|
+
intensity: Zone 4-5
|
|
46
|
+
description: "4-8% grade, seated or standing"
|
|
47
|
+
recovery:
|
|
48
|
+
type: recovery
|
|
49
|
+
name: Descent recovery
|
|
50
|
+
duration: "Descent"
|
|
51
|
+
intensity: Zone 1
|
|
52
|
+
description: "Easy spin down"
|
|
53
|
+
cooldown:
|
|
54
|
+
- type: cooldown
|
|
55
|
+
name: Easy spin home
|
|
56
|
+
duration: "${cooldown_mins}min"
|
|
57
|
+
power: "< 55% FTP"
|
|
58
|
+
intensity: Zone 1
|
|
59
|
+
|
|
60
|
+
humanReadable: |
|
|
61
|
+
HILL REPEATS
|
|
62
|
+
|
|
63
|
+
WARM-UP: ${warmup_mins} min easy spin to the climb
|
|
64
|
+
|
|
65
|
+
MAIN SET:
|
|
66
|
+
${reps} x ${climb_mins} min climbs @ 100-110% FTP
|
|
67
|
+
Recover on the descent
|
|
68
|
+
|
|
69
|
+
Find a 4-8% grade climb that takes ~${climb_mins} min.
|
|
70
|
+
Alternate seated/standing as needed.
|
|
71
|
+
Focus on steady power output, not speed.
|
|
72
|
+
|
|
73
|
+
COOL-DOWN: ${cooldown_mins} min easy spin home
|
|
74
|
+
|
|
75
|
+
Total: ~${warmup_mins + (reps * climb_mins * 2) + cooldown_mins} min
|
|
76
|
+
|
|
77
|
+
estimatedDuration: "${warmup_mins + (reps * climb_mins * 2) + cooldown_mins}"
|
|
78
|
+
targetZone: Z4-Z5
|
|
79
|
+
rpe: "7-8"
|
|
80
|
+
notes: Climbing strength and power development
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
id: bike.overunders
|
|
2
|
+
name: Over-Under Intervals
|
|
3
|
+
sport: bike
|
|
4
|
+
type: threshold
|
|
5
|
+
category: threshold
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
sets:
|
|
9
|
+
type: int
|
|
10
|
+
required: true
|
|
11
|
+
default: 3
|
|
12
|
+
min: 2
|
|
13
|
+
max: 5
|
|
14
|
+
description: Number of over-under sets
|
|
15
|
+
cycles_per_set:
|
|
16
|
+
type: int
|
|
17
|
+
default: 3
|
|
18
|
+
description: Number of over-under cycles per set
|
|
19
|
+
warmup_mins:
|
|
20
|
+
type: int
|
|
21
|
+
default: 20
|
|
22
|
+
description: Warmup duration in minutes
|
|
23
|
+
cooldown_mins:
|
|
24
|
+
type: int
|
|
25
|
+
default: 15
|
|
26
|
+
description: Cooldown duration in minutes
|
|
27
|
+
|
|
28
|
+
structure:
|
|
29
|
+
warmup:
|
|
30
|
+
- type: warmup
|
|
31
|
+
name: Progressive with accelerations
|
|
32
|
+
description: "20min with 3x30s accelerations"
|
|
33
|
+
duration: "${warmup_mins}min"
|
|
34
|
+
intensity: Zone 1-3
|
|
35
|
+
main:
|
|
36
|
+
- type: intervals
|
|
37
|
+
repeats: "${sets}"
|
|
38
|
+
work:
|
|
39
|
+
type: work
|
|
40
|
+
name: Over-under set
|
|
41
|
+
description: "(2min @ 95% FTP + 1min @ 108% FTP) x ${cycles_per_set}"
|
|
42
|
+
duration: "${cycles_per_set * 3}min"
|
|
43
|
+
intensity: Zone 4-5a
|
|
44
|
+
recovery:
|
|
45
|
+
type: recovery
|
|
46
|
+
name: Easy spin
|
|
47
|
+
duration: 5min
|
|
48
|
+
power: "< 55% FTP"
|
|
49
|
+
intensity: Zone 1
|
|
50
|
+
cooldown:
|
|
51
|
+
- type: cooldown
|
|
52
|
+
name: Easy spin
|
|
53
|
+
duration: "${cooldown_mins}min"
|
|
54
|
+
power: "< 55% FTP"
|
|
55
|
+
intensity: Zone 1
|
|
56
|
+
|
|
57
|
+
humanReadable: |
|
|
58
|
+
OVER-UNDER INTERVALS
|
|
59
|
+
|
|
60
|
+
WARM-UP: ${warmup_mins} min with 3x30s accelerations
|
|
61
|
+
|
|
62
|
+
MAIN SET:
|
|
63
|
+
${sets} sets of:
|
|
64
|
+
(2 min @ 95% FTP + 1 min @ 108% FTP) x ${cycles_per_set}
|
|
65
|
+
5 min easy recovery between sets
|
|
66
|
+
|
|
67
|
+
Each ${cycles_per_set * 3} min set alternates:
|
|
68
|
+
- "Under": 2 min just below threshold (95% FTP)
|
|
69
|
+
- "Over": 1 min above threshold (108% FTP)
|
|
70
|
+
|
|
71
|
+
This teaches your body to clear lactate while riding.
|
|
72
|
+
|
|
73
|
+
COOL-DOWN: ${cooldown_mins} min Zone 1
|
|
74
|
+
|
|
75
|
+
Total: ~${warmup_mins + (sets * cycles_per_set * 3) + ((sets - 1) * 5) + cooldown_mins} min
|
|
76
|
+
TSS: ~85
|
|
77
|
+
|
|
78
|
+
estimatedDuration: "${warmup_mins + (sets * cycles_per_set * 3) + ((sets - 1) * 5) + cooldown_mins}"
|
|
79
|
+
targetZone: Z4-Z5a
|
|
80
|
+
rpe: "7-8"
|
|
81
|
+
notes: Threshold extension - lactate clearance training
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
id: bike.rest
|
|
2
|
+
name: Rest Day
|
|
3
|
+
sport: bike
|
|
4
|
+
type: rest
|
|
5
|
+
category: rest
|
|
6
|
+
|
|
7
|
+
humanReadable: |
|
|
8
|
+
REST DAY
|
|
9
|
+
|
|
10
|
+
Take the day off from cycling. Focus on recovery, sleep, and nutrition.
|
|
11
|
+
Light stretching or foam rolling optional.
|
|
12
|
+
|
|
13
|
+
estimatedDuration: 0
|
|
14
|
+
targetZone: "-"
|
|
15
|
+
rpe: "1"
|
|
16
|
+
notes: Complete rest from structured training
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
id: bike.sweetspot
|
|
2
|
+
name: Sweet Spot Ride
|
|
3
|
+
sport: bike
|
|
4
|
+
type: threshold
|
|
5
|
+
category: threshold
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
ss_mins:
|
|
9
|
+
type: int
|
|
10
|
+
required: true
|
|
11
|
+
default: 60
|
|
12
|
+
min: 20
|
|
13
|
+
max: 90
|
|
14
|
+
description: Total sweet spot duration in minutes
|
|
15
|
+
sets:
|
|
16
|
+
type: int
|
|
17
|
+
default: 3
|
|
18
|
+
min: 2
|
|
19
|
+
max: 4
|
|
20
|
+
description: Number of sweet spot intervals
|
|
21
|
+
warmup_mins:
|
|
22
|
+
type: int
|
|
23
|
+
default: 20
|
|
24
|
+
description: Warmup duration in minutes
|
|
25
|
+
cooldown_mins:
|
|
26
|
+
type: int
|
|
27
|
+
default: 15
|
|
28
|
+
description: Cooldown duration in minutes
|
|
29
|
+
|
|
30
|
+
structure:
|
|
31
|
+
warmup:
|
|
32
|
+
- type: warmup
|
|
33
|
+
name: Easy with openers
|
|
34
|
+
description: "Zone 2 with 2x1min high-cadence"
|
|
35
|
+
duration: "${warmup_mins}min"
|
|
36
|
+
intensity: Zone 2
|
|
37
|
+
main:
|
|
38
|
+
- type: intervals
|
|
39
|
+
repeats: "${sets}"
|
|
40
|
+
work:
|
|
41
|
+
type: work
|
|
42
|
+
name: Sweet spot interval
|
|
43
|
+
duration: "${ss_mins / sets}min"
|
|
44
|
+
power: "88-93% FTP"
|
|
45
|
+
intensity: Zone 3-4
|
|
46
|
+
recovery:
|
|
47
|
+
type: recovery
|
|
48
|
+
name: Easy spin
|
|
49
|
+
duration: 5min
|
|
50
|
+
power: "< 55% FTP"
|
|
51
|
+
intensity: Zone 1
|
|
52
|
+
cooldown:
|
|
53
|
+
- type: cooldown
|
|
54
|
+
name: Easy spin
|
|
55
|
+
duration: "${cooldown_mins}min"
|
|
56
|
+
power: "< 55% FTP"
|
|
57
|
+
intensity: Zone 1
|
|
58
|
+
|
|
59
|
+
humanReadable: |
|
|
60
|
+
SWEET SPOT RIDE
|
|
61
|
+
|
|
62
|
+
WARM-UP: ${warmup_mins} min Zone 2, include 2x1min high-cadence
|
|
63
|
+
|
|
64
|
+
MAIN SET:
|
|
65
|
+
${sets} x ${ss_mins / sets} min @ Sweet Spot (88-93% FTP)
|
|
66
|
+
5 min easy spin between intervals
|
|
67
|
+
|
|
68
|
+
Power: 88-93% FTP
|
|
69
|
+
This is the "sweet spot" - high training benefit, manageable fatigue.
|
|
70
|
+
Challenging but sustainable for the full interval.
|
|
71
|
+
|
|
72
|
+
COOL-DOWN: ${cooldown_mins} min Zone 1
|
|
73
|
+
|
|
74
|
+
Total: ~${warmup_mins + ss_mins + (sets * 5) + cooldown_mins} min
|
|
75
|
+
TSS: ~80
|
|
76
|
+
|
|
77
|
+
estimatedDuration: "${warmup_mins + ss_mins + (sets * 5) + cooldown_mins}"
|
|
78
|
+
targetZone: Z3-Z4
|
|
79
|
+
rpe: "6-7"
|
|
80
|
+
notes: Build phase staple - high benefit, moderate cost
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
id: bike.tempo
|
|
2
|
+
name: Tempo Ride
|
|
3
|
+
sport: bike
|
|
4
|
+
type: tempo
|
|
5
|
+
category: tempo
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
tempo_mins:
|
|
9
|
+
type: int
|
|
10
|
+
required: true
|
|
11
|
+
default: 40
|
|
12
|
+
min: 15
|
|
13
|
+
max: 90
|
|
14
|
+
description: Total tempo duration in minutes
|
|
15
|
+
sets:
|
|
16
|
+
type: int
|
|
17
|
+
default: 2
|
|
18
|
+
min: 1
|
|
19
|
+
max: 4
|
|
20
|
+
description: Number of tempo intervals
|
|
21
|
+
warmup_mins:
|
|
22
|
+
type: int
|
|
23
|
+
default: 15
|
|
24
|
+
description: Warmup duration in minutes
|
|
25
|
+
cooldown_mins:
|
|
26
|
+
type: int
|
|
27
|
+
default: 10
|
|
28
|
+
description: Cooldown duration in minutes
|
|
29
|
+
|
|
30
|
+
structure:
|
|
31
|
+
warmup:
|
|
32
|
+
- type: warmup
|
|
33
|
+
name: Easy spin
|
|
34
|
+
duration: "${warmup_mins}min"
|
|
35
|
+
power: "< 55% FTP"
|
|
36
|
+
intensity: Zone 1-2
|
|
37
|
+
main:
|
|
38
|
+
- type: intervals
|
|
39
|
+
repeats: "${sets}"
|
|
40
|
+
work:
|
|
41
|
+
type: work
|
|
42
|
+
name: Tempo interval
|
|
43
|
+
duration: "${tempo_mins / sets}min"
|
|
44
|
+
power: "76-90% FTP"
|
|
45
|
+
intensity: Zone 3
|
|
46
|
+
recovery:
|
|
47
|
+
type: recovery
|
|
48
|
+
name: Easy spin
|
|
49
|
+
duration: 5min
|
|
50
|
+
power: "< 55% FTP"
|
|
51
|
+
intensity: Zone 1
|
|
52
|
+
cooldown:
|
|
53
|
+
- type: cooldown
|
|
54
|
+
name: Easy spin
|
|
55
|
+
duration: "${cooldown_mins}min"
|
|
56
|
+
power: "< 55% FTP"
|
|
57
|
+
intensity: Zone 1
|
|
58
|
+
|
|
59
|
+
humanReadable: |
|
|
60
|
+
TEMPO RIDE
|
|
61
|
+
|
|
62
|
+
WARM-UP: ${warmup_mins} min easy Zone 1-2
|
|
63
|
+
|
|
64
|
+
MAIN SET:
|
|
65
|
+
${sets} x ${tempo_mins / sets} min @ Tempo (76-90% FTP)
|
|
66
|
+
5 min easy spin between intervals
|
|
67
|
+
|
|
68
|
+
Power: 76-90% FTP
|
|
69
|
+
Cadence: 85-95 rpm
|
|
70
|
+
This is "comfortably hard" - sustainable but focused.
|
|
71
|
+
|
|
72
|
+
COOL-DOWN: ${cooldown_mins} min easy
|
|
73
|
+
|
|
74
|
+
Total: ~${warmup_mins + tempo_mins + (sets * 5) + cooldown_mins} min
|
|
75
|
+
|
|
76
|
+
estimatedDuration: "${warmup_mins + tempo_mins + (sets * 5) + cooldown_mins}"
|
|
77
|
+
targetZone: Z3
|
|
78
|
+
rpe: "6"
|
|
79
|
+
notes: Muscular endurance development
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
id: bike.threshold
|
|
2
|
+
name: Threshold Intervals
|
|
3
|
+
sport: bike
|
|
4
|
+
type: threshold
|
|
5
|
+
category: threshold
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
reps:
|
|
9
|
+
type: int
|
|
10
|
+
required: true
|
|
11
|
+
default: 3
|
|
12
|
+
min: 2
|
|
13
|
+
max: 5
|
|
14
|
+
description: Number of threshold intervals
|
|
15
|
+
interval_mins:
|
|
16
|
+
type: int
|
|
17
|
+
default: 10
|
|
18
|
+
min: 8
|
|
19
|
+
max: 20
|
|
20
|
+
description: Duration of each threshold interval
|
|
21
|
+
rest_mins:
|
|
22
|
+
type: int
|
|
23
|
+
default: 5
|
|
24
|
+
description: Recovery between intervals in minutes
|
|
25
|
+
warmup_mins:
|
|
26
|
+
type: int
|
|
27
|
+
default: 20
|
|
28
|
+
description: Warmup duration in minutes
|
|
29
|
+
cooldown_mins:
|
|
30
|
+
type: int
|
|
31
|
+
default: 15
|
|
32
|
+
description: Cooldown duration in minutes
|
|
33
|
+
|
|
34
|
+
structure:
|
|
35
|
+
warmup:
|
|
36
|
+
- type: warmup
|
|
37
|
+
name: Progressive warmup
|
|
38
|
+
description: "Zone 1 to Zone 3"
|
|
39
|
+
duration: "${warmup_mins}min"
|
|
40
|
+
intensity: Zone 1-3
|
|
41
|
+
main:
|
|
42
|
+
- type: intervals
|
|
43
|
+
repeats: "${reps}"
|
|
44
|
+
work:
|
|
45
|
+
type: work
|
|
46
|
+
name: Threshold interval
|
|
47
|
+
duration: "${interval_mins}min"
|
|
48
|
+
power: "95-105% FTP"
|
|
49
|
+
intensity: Zone 4
|
|
50
|
+
recovery:
|
|
51
|
+
type: recovery
|
|
52
|
+
name: Easy spin
|
|
53
|
+
duration: "${rest_mins}min"
|
|
54
|
+
power: "< 55% FTP"
|
|
55
|
+
intensity: Zone 1
|
|
56
|
+
cooldown:
|
|
57
|
+
- type: cooldown
|
|
58
|
+
name: Easy spin
|
|
59
|
+
duration: "${cooldown_mins}min"
|
|
60
|
+
power: "< 55% FTP"
|
|
61
|
+
intensity: Zone 1
|
|
62
|
+
|
|
63
|
+
humanReadable: |
|
|
64
|
+
THRESHOLD INTERVALS
|
|
65
|
+
|
|
66
|
+
WARM-UP: ${warmup_mins} min progressive (Zone 1 → Zone 3)
|
|
67
|
+
|
|
68
|
+
MAIN SET:
|
|
69
|
+
${reps} x ${interval_mins} min @ 95-105% FTP
|
|
70
|
+
${rest_mins} min easy spin recovery between each
|
|
71
|
+
|
|
72
|
+
Power: 95-105% FTP
|
|
73
|
+
This is hard, sustained effort at lactate threshold.
|
|
74
|
+
You should be able to complete all reps at target power.
|
|
75
|
+
|
|
76
|
+
COOL-DOWN: ${cooldown_mins} min Zone 1
|
|
77
|
+
|
|
78
|
+
Total: ~${warmup_mins + (reps * interval_mins) + ((reps - 1) * rest_mins) + cooldown_mins} min
|
|
79
|
+
|
|
80
|
+
estimatedDuration: "${warmup_mins + (reps * interval_mins) + ((reps - 1) * rest_mins) + cooldown_mins}"
|
|
81
|
+
targetZone: Z4
|
|
82
|
+
rpe: "7-8"
|
|
83
|
+
notes: Lactate threshold development
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
id: bike.vo2max
|
|
2
|
+
name: VO2max Intervals
|
|
3
|
+
sport: bike
|
|
4
|
+
type: vo2max
|
|
5
|
+
category: speed
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
reps:
|
|
9
|
+
type: int
|
|
10
|
+
required: true
|
|
11
|
+
default: 5
|
|
12
|
+
min: 3
|
|
13
|
+
max: 8
|
|
14
|
+
description: Number of VO2max intervals
|
|
15
|
+
interval_mins:
|
|
16
|
+
type: int
|
|
17
|
+
default: 5
|
|
18
|
+
min: 3
|
|
19
|
+
max: 6
|
|
20
|
+
description: Duration of each VO2max interval
|
|
21
|
+
rest_mins:
|
|
22
|
+
type: int
|
|
23
|
+
default: 5
|
|
24
|
+
description: Recovery between intervals in minutes
|
|
25
|
+
warmup_mins:
|
|
26
|
+
type: int
|
|
27
|
+
default: 20
|
|
28
|
+
description: Warmup duration in minutes
|
|
29
|
+
cooldown_mins:
|
|
30
|
+
type: int
|
|
31
|
+
default: 15
|
|
32
|
+
description: Cooldown duration in minutes
|
|
33
|
+
|
|
34
|
+
structure:
|
|
35
|
+
warmup:
|
|
36
|
+
- type: warmup
|
|
37
|
+
name: Progressive warmup
|
|
38
|
+
description: "Progressive to Zone 3"
|
|
39
|
+
duration: "${warmup_mins}min"
|
|
40
|
+
intensity: Zone 1-3
|
|
41
|
+
main:
|
|
42
|
+
- type: intervals
|
|
43
|
+
repeats: "${reps}"
|
|
44
|
+
work:
|
|
45
|
+
type: work
|
|
46
|
+
name: VO2max interval
|
|
47
|
+
duration: "${interval_mins}min"
|
|
48
|
+
power: "106-120% FTP"
|
|
49
|
+
intensity: Zone 5
|
|
50
|
+
recovery:
|
|
51
|
+
type: recovery
|
|
52
|
+
name: Easy spin
|
|
53
|
+
duration: "${rest_mins}min"
|
|
54
|
+
power: "50% FTP"
|
|
55
|
+
intensity: Zone 1
|
|
56
|
+
cooldown:
|
|
57
|
+
- type: cooldown
|
|
58
|
+
name: Easy spin
|
|
59
|
+
duration: "${cooldown_mins}min"
|
|
60
|
+
power: "< 55% FTP"
|
|
61
|
+
intensity: Zone 1
|
|
62
|
+
|
|
63
|
+
humanReadable: |
|
|
64
|
+
VO2MAX INTERVALS
|
|
65
|
+
|
|
66
|
+
WARM-UP: ${warmup_mins} min progressive to Zone 3
|
|
67
|
+
|
|
68
|
+
MAIN SET:
|
|
69
|
+
${reps} x ${interval_mins} min @ 106-120% FTP
|
|
70
|
+
${rest_mins} min @ 50% FTP recovery between each
|
|
71
|
+
|
|
72
|
+
Power: 106-120% FTP
|
|
73
|
+
This is HARD. Breathing will be labored.
|
|
74
|
+
Maintain consistent power across all intervals.
|
|
75
|
+
|
|
76
|
+
COOL-DOWN: ${cooldown_mins} min easy spin
|
|
77
|
+
|
|
78
|
+
Total: ~${warmup_mins + (reps * interval_mins) + ((reps - 1) * rest_mins) + cooldown_mins} min
|
|
79
|
+
TSS: ~90
|
|
80
|
+
|
|
81
|
+
estimatedDuration: "${warmup_mins + (reps * interval_mins) + ((reps - 1) * rest_mins) + cooldown_mins}"
|
|
82
|
+
targetZone: Z5
|
|
83
|
+
rpe: "8-9"
|
|
84
|
+
notes: Peak phase - VO2max development
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
id: brick.halfironman
|
|
2
|
+
name: Half Ironman Brick
|
|
3
|
+
sport: brick
|
|
4
|
+
type: brick
|
|
5
|
+
category: race
|
|
6
|
+
|
|
7
|
+
params:
|
|
8
|
+
bike_hrs:
|
|
9
|
+
type: number
|
|
10
|
+
required: true
|
|
11
|
+
default: 3
|
|
12
|
+
min: 2
|
|
13
|
+
max: 4
|
|
14
|
+
description: Bike duration in hours
|
|
15
|
+
run_mins:
|
|
16
|
+
type: int
|
|
17
|
+
required: true
|
|
18
|
+
default: 45
|
|
19
|
+
min: 30
|
|
20
|
+
max: 60
|
|
21
|
+
description: Run duration in minutes
|
|
22
|
+
|
|
23
|
+
structure:
|
|
24
|
+
main:
|
|
25
|
+
- type: work
|
|
26
|
+
name: Bike - Endurance
|
|
27
|
+
duration: "${(bike_hrs - 1) * 60}min"
|
|
28
|
+
power: "56-75% FTP"
|
|
29
|
+
intensity: Zone 2
|
|
30
|
+
- type: work
|
|
31
|
+
name: Bike - Race simulation
|
|
32
|
+
duration: 60min
|
|
33
|
+
power: "68-76% FTP"
|
|
34
|
+
intensity: Zone 2-3
|
|
35
|
+
description: "Final hour at race effort"
|
|
36
|
+
- type: rest
|
|
37
|
+
name: T2
|
|
38
|
+
duration: 3min
|
|
39
|
+
description: "Transition practice"
|
|
40
|
+
- type: work
|
|
41
|
+
name: Run - Easy/Moderate
|
|
42
|
+
duration: "${run_mins}min"
|
|
43
|
+
pace: "${paces.easy}"
|
|
44
|
+
intensity: Zone 2
|
|
45
|
+
|
|
46
|
+
humanReadable: |
|
|
47
|
+
HALF IRONMAN BRICK
|
|
48
|
+
|
|
49
|
+
BIKE: ${bike_hrs} hours total
|
|
50
|
+
- ${bike_hrs - 1} hr Zone 2 endurance
|
|
51
|
+
- 1 hr @ race effort (68-76% FTP, Zone 2-3)
|
|
52
|
+
|
|
53
|
+
T2: Transition practice
|
|
54
|
+
|
|
55
|
+
RUN: ${run_mins} min easy
|
|
56
|
+
Pace: ${paces.easy}
|
|
57
|
+
|
|
58
|
+
Purpose: Fatigue adaptation for 70.3 racing.
|
|
59
|
+
The goal is to finish the bike on tired legs,
|
|
60
|
+
then practice running smoothly.
|
|
61
|
+
|
|
62
|
+
Nutrition practice:
|
|
63
|
+
- 60-80g carbs/hour on bike
|
|
64
|
+
- Start fueling early
|
|
65
|
+
- Practice race-day nutrition plan
|
|
66
|
+
|
|
67
|
+
Total: ~${bike_hrs * 60 + run_mins + 3} min
|
|
68
|
+
|
|
69
|
+
estimatedDuration: "${bike_hrs * 60 + run_mins + 3}"
|
|
70
|
+
targetZone: Z2-Z3
|
|
71
|
+
rpe: "5-6"
|
|
72
|
+
notes: 70.3 race preparation - fatigue adaptation
|