endurance-coach 0.1.1 → 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.
Files changed (74) hide show
  1. package/README.md +3 -0
  2. package/dist/cli.js +318 -35
  3. package/dist/expander/expander.d.ts +20 -0
  4. package/dist/expander/expander.js +339 -0
  5. package/dist/expander/index.d.ts +8 -0
  6. package/dist/expander/index.js +9 -0
  7. package/dist/expander/types.d.ts +169 -0
  8. package/dist/expander/types.js +6 -0
  9. package/dist/expander/zones.d.ts +50 -0
  10. package/dist/expander/zones.js +159 -0
  11. package/dist/index.d.ts +4 -0
  12. package/dist/index.js +9 -1
  13. package/dist/schema/compact-plan.d.ts +175 -0
  14. package/dist/schema/compact-plan.js +64 -0
  15. package/dist/schema/compact-plan.schema.d.ts +277 -0
  16. package/dist/schema/compact-plan.schema.js +205 -0
  17. package/dist/templates/index.d.ts +10 -0
  18. package/dist/templates/index.js +13 -0
  19. package/dist/templates/interpolate.d.ts +51 -0
  20. package/dist/templates/interpolate.js +204 -0
  21. package/dist/templates/loader.d.ts +19 -0
  22. package/dist/templates/loader.js +129 -0
  23. package/dist/templates/template.schema.d.ts +401 -0
  24. package/dist/templates/template.schema.js +101 -0
  25. package/dist/templates/template.types.d.ts +155 -0
  26. package/dist/templates/template.types.js +7 -0
  27. package/dist/templates/yaml-parser.d.ts +15 -0
  28. package/dist/templates/yaml-parser.js +18 -0
  29. package/package.json +2 -1
  30. package/templates/bike/CLAUDE.md +7 -0
  31. package/templates/bike/easy.yaml +38 -0
  32. package/templates/bike/endurance.yaml +42 -0
  33. package/templates/bike/hills.yaml +80 -0
  34. package/templates/bike/overunders.yaml +81 -0
  35. package/templates/bike/rest.yaml +16 -0
  36. package/templates/bike/sweetspot.yaml +80 -0
  37. package/templates/bike/tempo.yaml +79 -0
  38. package/templates/bike/threshold.yaml +83 -0
  39. package/templates/bike/vo2max.yaml +84 -0
  40. package/templates/brick/CLAUDE.md +7 -0
  41. package/templates/brick/halfironman.yaml +72 -0
  42. package/templates/brick/ironman.yaml +72 -0
  43. package/templates/brick/olympic.yaml +70 -0
  44. package/templates/brick/sprint.yaml +70 -0
  45. package/templates/plan-viewer.html +22 -22
  46. package/templates/run/CLAUDE.md +7 -0
  47. package/templates/run/easy.yaml +36 -0
  48. package/templates/run/fartlek.yaml +40 -0
  49. package/templates/run/hills.yaml +36 -0
  50. package/templates/run/intervals.1k.yaml +63 -0
  51. package/templates/run/intervals.400.yaml +63 -0
  52. package/templates/run/intervals.800.yaml +63 -0
  53. package/templates/run/intervals.mile.yaml +64 -0
  54. package/templates/run/long.yaml +41 -0
  55. package/templates/run/progression.yaml +49 -0
  56. package/templates/run/race.5k.yaml +36 -0
  57. package/templates/run/recovery.yaml +36 -0
  58. package/templates/run/rest.yaml +16 -0
  59. package/templates/run/strides.yaml +49 -0
  60. package/templates/run/tempo.yaml +56 -0
  61. package/templates/run/threshold.yaml +56 -0
  62. package/templates/strength/CLAUDE.md +7 -0
  63. package/templates/strength/core.yaml +56 -0
  64. package/templates/strength/foundation.yaml +65 -0
  65. package/templates/strength/full.yaml +73 -0
  66. package/templates/strength/maintenance.yaml +62 -0
  67. package/templates/swim/CLAUDE.md +7 -0
  68. package/templates/swim/aerobic.yaml +67 -0
  69. package/templates/swim/easy.yaml +51 -0
  70. package/templates/swim/openwater.yaml +60 -0
  71. package/templates/swim/rest.yaml +16 -0
  72. package/templates/swim/technique.yaml +67 -0
  73. package/templates/swim/threshold.yaml +75 -0
  74. package/templates/swim/vo2max.yaml +88 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "endurance-coach",
3
- "version": "0.1.1",
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,7 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ _No recent activity_
7
+ </claude-mem-context>
@@ -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,7 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ _No recent activity_
7
+ </claude-mem-context>
@@ -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