@bitcobblers/wod-wiki-tools 0.51.2196 → 0.52.2198
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/dist/bin/wod.cjs +979 -888
- package/dist/bin/wod.cjs.map +1 -1
- package/dist/bin/wod.mjs +4 -4
- package/dist/{chunk-V23POHG2.mjs → chunk-2EWCEE6N.mjs} +86 -7
- package/dist/chunk-2EWCEE6N.mjs.map +1 -0
- package/dist/{chunk-TDYC2FCK.mjs → chunk-FJSPH4EA.mjs} +69 -148
- package/dist/chunk-FJSPH4EA.mjs.map +1 -0
- package/dist/{chunk-ZUZMRH3G.mjs → chunk-FUISPA7A.mjs} +55 -3
- package/dist/chunk-FUISPA7A.mjs.map +1 -0
- package/dist/chunk-KGP6STLY.mjs +69 -0
- package/dist/chunk-KGP6STLY.mjs.map +1 -0
- package/dist/{chunk-Z2IQPTDI.mjs → chunk-LNBKPHEP.mjs} +6 -5
- package/dist/chunk-LNBKPHEP.mjs.map +1 -0
- package/dist/{chunk-QE5CK3QT.mjs → chunk-V77RQF5T.mjs} +3 -3
- package/dist/chunk-V77RQF5T.mjs.map +1 -0
- package/dist/{chunk-L5S7PXAB.mjs → compiler-KOSG7QUK.mjs} +50 -70
- package/dist/compiler-KOSG7QUK.mjs.map +1 -0
- package/dist/index.cjs +979 -888
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +6 -6
- package/dist/{scaffoldFeed-MROAPAAP.mjs → scaffoldFeed-Y57UWPGG.mjs} +3 -3
- package/dist/{scaffoldFeed-MROAPAAP.mjs.map → scaffoldFeed-Y57UWPGG.mjs.map} +1 -1
- package/dist/server/app.cjs +155 -5
- package/dist/server/app.cjs.map +1 -1
- package/dist/server/app.d.cts +3 -0
- package/dist/server/app.d.ts +3 -0
- package/dist/server/app.mjs +2 -1
- package/dist/server-SHNWCIIM.mjs +11 -0
- package/dist/{server-QK2CXCDJ.mjs.map → server-SHNWCIIM.mjs.map} +1 -1
- package/dist/skills/wod-extraction/SKILL.md +40 -0
- package/dist/web/playground/ai-skills/parse.md +40 -0
- package/dist/web/playground/assets/{feedSync.worker-ftP9nOAl.js → feedSync.worker-O4TGLEj3.js} +7 -7
- package/dist/web/playground/assets/main-CnfiwGSd.js +1149 -0
- package/dist/web/playground/assets/main-Vksl1E71.css +2 -0
- package/dist/web/playground/assets/{statementBuilderFlow-CNz2Wkh9.js → statementBuilderFlow-Ba3zNEUH.js} +2 -2
- package/dist/web/playground/assets/{vendor-BiwvmytJ.js → vendor-Dz-Azkoq.js} +69 -69
- package/dist/web/{server/assets/vendor-codemirror-B461LMkB.js → playground/assets/vendor-codemirror-B4BeZarI.js} +11 -11
- package/dist/web/playground/index.html +4 -4
- package/dist/web/playground/seed/core/chunks/canvas.6ac57ab1.json +1 -0
- package/dist/web/playground/seed/core/chunks/dashboards.96c1474b.json +1 -0
- package/dist/web/playground/seed/core/chunks/{efforts.f2875ac9.json → efforts.b724fc2b.json} +1 -1
- package/dist/web/playground/seed/core/chunks/{equipment.a56f9b72.json → equipment.2743295a.json} +1 -1
- package/dist/web/playground/seed/core/indexes/notebooks/canvas.json +181 -181
- package/dist/web/playground/seed/core/indexes/notebooks/dashboards.json +17 -17
- package/dist/web/playground/seed/core/indexes/notebooks/efforts.json +326 -326
- package/dist/web/playground/seed/core/indexes/notebooks/equipment.json +50 -50
- package/dist/web/playground/seed/core/manifest.json +31 -31
- package/dist/web/playground/seed/core/markdown/canvas/ai-first/README.json +1 -1
- package/dist/web/playground/seed/core/markdown/canvas/guide/README.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/guide/clock.json +1 -1
- package/dist/web/playground/seed/core/markdown/canvas/guide/dashboards.json +4 -32
- package/dist/web/playground/seed/core/markdown/canvas/guide/metrics-summaries.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/guide/metrics.json +16 -16
- package/dist/web/playground/seed/core/markdown/canvas/guide/protocols.json +20 -20
- package/dist/web/playground/seed/core/markdown/canvas/guide/sessions.json +33 -33
- package/dist/web/playground/seed/core/markdown/canvas/guide/start.json +11 -11
- package/dist/web/playground/seed/core/markdown/canvas/guide/structure.json +25 -25
- package/dist/web/playground/seed/core/markdown/canvas/guide/wql.json +22 -22
- package/dist/web/playground/seed/core/markdown/canvas/home/sample-script.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/home/welcome-1.json +2 -2
- package/dist/web/playground/seed/core/markdown/canvas/syntax/actions-comments.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/alternating-emom.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/basic-emom.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/calculated-metrics.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/classic-amrap.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-barbell-cycling.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-full-session.json +10 -10
- package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-nested-protocols.json +7 -7
- package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-partner-workout.json +7 -7
- package/dist/web/playground/seed/core/markdown/canvas/syntax/complex-swimming.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/core-rules.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-and-calculated-metrics.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-intervals.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-1.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-2.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-3.json +3 -3
- package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-4.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/custom-metrics-5.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-climb-bouldering.json +2 -2
- package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-climb-hangboard.json +2 -2
- package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-climb-sport.json +2 -2
- package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-log.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-plan.json +8 -8
- package/dist/web/playground/seed/core/markdown/canvas/syntax/dialect-wod.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/distance-intervals.json +3 -3
- package/dist/web/playground/seed/core/markdown/canvas/syntax/document-1.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/document-2.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/document-3.json +10 -10
- package/dist/web/playground/seed/core/markdown/canvas/syntax/document-4.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/effort-notes.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/frontmatter-summaries.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/groups-1.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/groups-2.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/groups-3.json +3 -3
- package/dist/web/playground/seed/core/markdown/canvas/syntax/groups-4.json +3 -3
- package/dist/web/playground/seed/core/markdown/canvas/syntax/longer-duration.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/longer-intervals.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/measurements.json +7 -7
- package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-1.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-2.json +7 -7
- package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-3.json +8 -8
- package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-4.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/metrics-5.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/mixed-sections.json +10 -10
- package/dist/web/playground/seed/core/markdown/canvas/syntax/mixed-timers.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/multiple-amrap-windows.json +7 -7
- package/dist/web/playground/seed/core/markdown/canvas/syntax/multiple-sets.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/named-groups.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-1.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-2.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-3.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-4.json +3 -3
- package/dist/web/playground/seed/core/markdown/canvas/syntax/protocols-5.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/single-movement.json +3 -3
- package/dist/web/playground/seed/core/markdown/canvas/syntax/supplemental-1.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/supplemental-2.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/supplemental-3.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/supplemental-4.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/time-cap.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/timer-modifiers.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-1.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-2.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-3.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-4.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-5.json +5 -5
- package/dist/web/playground/seed/core/markdown/canvas/syntax/timers-rest.json +4 -4
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/aggregate-by-effort.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/aggregate-by-week.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/content-fran.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/filter-combos.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/pipes-limit.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/session-rpe.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/source-journal.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/tis-trend.json +6 -6
- package/dist/web/playground/seed/core/markdown/canvas/wql-presets/where-join.json +6 -6
- package/dist/web/playground/seed/core/markdown/dashboards/benchmark-pr-board.json +32 -32
- package/dist/web/playground/seed/core/markdown/dashboards/finger-strength-v8.json +26 -26
- package/dist/web/playground/seed/core/markdown/dashboards/polarized-base-marathon.json +50 -50
- package/dist/web/playground/seed/core/markdown/dashboards/recovery-readiness.json +38 -38
- package/dist/web/playground/seed/core/markdown/dashboards/road-to-560-total.json +50 -50
- package/dist/web/playground/seed/core/markdown/dashboards/training-block-review.json +62 -62
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/air-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/box-jump.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/broad-jump.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/burpee-box-jump-over.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/burpee-over-dumbbell.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/burpee.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/dumbbell-squat-clean.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/ghd-sit-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/ground-kong.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/jumping-jack.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/kong-walk.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/lunge.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/overhead-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/parkour-roll.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/parkour-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/pistol-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/plank.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/precision-burpee.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/precision-jump.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/quadrupedal-movement.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/russian-twist.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/sit-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/squat-clean.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/squat-hold.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/squat-snatch.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/tuck-jump.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/wall-ball.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/bodyweight/wall-burpee.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/cycling/assault-bike.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/cycling/cycling-moderate.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/cycling/cycling-vigorous.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/assisted-pull-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/burpee-pull-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/chest-to-bar-pull-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/dip.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/double-under.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/handstand-hold.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/handstand-push-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/handstand-walk.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/jump-rope.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/jumping-pull-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/jumping-push-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/l-sit-pull-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/muscle-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/pull-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/push-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/reverse-wall-dip.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/rope-climb.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/gymnastics/toes-to-bar.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-arm-bar.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-around-the-world.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-bent-over-row.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-clean-and-jerk.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-clean-and-press.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-clean.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-deadlift.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-floor-press.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-front-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-goblet-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-gorilla-row.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-halo.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-jerk.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-overhead-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-press.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-snatch.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-swing.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/kettlebell-windmill.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/kettlebell/turkish-get-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/recovery/rest.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/recovery/stretching.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/rowing/rowing-sprint.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/rowing/rowing.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/rowing/ski-erg.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/running/backward-running.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/running/running-6-mph.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/running/running-8-mph.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/running/running-sprint.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/snatch.json +2 -2
- package/dist/web/playground/seed/core/markdown/efforts/strength/back-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/bench-press.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/box-step-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/carioca.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/clean-and-jerk.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/cluster.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/dead-hang.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/deadlift.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/devils-press.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-box-step-up.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-clean.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-fly.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-row.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-snatch.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/dumbbell-thruster.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/elbows-to-knees.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/farmer-carry.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/frog-stand.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/front-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/good-morning.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/hanging-leg-raise.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/hollow-rock.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/knees-to-elbows.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/l-sit.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/man-maker.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/medicine-ball-clean.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/overhead-press.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/parkour-vault.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/pig-flip.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/power-clean.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/power-snatch.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/push-jerk.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/push-press.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/romanian-deadlift.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/single-leg-deadlift.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/skull-crusher.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/slam-ball.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/sled-pull.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/sled-push.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/sumo-deadlift.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/thruster.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/triceps-extension.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/v-sit-hold.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/wall-walk.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/strength/yoga-sun-salutation.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-assisted-sprint.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-backstroke.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-breaststroke-kick.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-breaststroke.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-butterfly.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-catch-up-drill.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-choice-stroke.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-dive-start.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-dolphin-kick.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-drafting.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-fingertip-drag.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-freestyle.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-individual-medley.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-kick.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-pull.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-resisted-sprint.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-rotation-drill.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-sighting.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-single-arm-drill.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-stroke-transition.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-two-kick-one-pull.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming-vigorous.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/swimming/swimming.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-arm-cast.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-circles.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-mill.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-reverse-mill.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/clubbell-shield-cast.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-10-to-2-swing.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-360-swing.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-barbarian-squat.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-flow.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-gravedigger.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/macebell-touchdown.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/sandbag-bear-hug-carry.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/sandbag-bear-hug-extension.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/unconventional/sandbag-over-shoulder.json +1 -1
- package/dist/web/playground/seed/core/markdown/efforts/walking/walking-3-mph.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/air-bike.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/barbell.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/bench.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/bike-erg.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/climbing-rope.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/clubs.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/dumbbell.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/ghd.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/gymnastic-rings.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/jump-rope.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/kettlebell.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/macebell.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/medicine-ball.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/parallettes.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/plyo-box.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/pull-up-bar.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/rower.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/sandbag.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/ski-erg.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/slam-ball.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/sled.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/sledgehammer.json +1 -1
- package/dist/web/playground/seed/core/markdown/equipment/weight-vest.json +1 -1
- package/dist/web/playground/seed/core/report.html +14 -14
- package/dist/web/server/ai-skills/parse.md +40 -0
- package/dist/web/server/assets/{feedSync.worker-ftP9nOAl.js → feedSync.worker-O4TGLEj3.js} +7 -7
- package/dist/web/server/assets/main-CnNELDQ_.js +1149 -0
- package/dist/web/server/assets/main-Vksl1E71.css +2 -0
- package/dist/web/server/assets/{statementBuilderFlow-BgrBt6FL.js → statementBuilderFlow-D5uFXVe0.js} +2 -2
- package/dist/web/server/assets/{vendor-BiwvmytJ.js → vendor-Dz-Azkoq.js} +69 -69
- package/dist/web/{playground/assets/vendor-codemirror-B461LMkB.js → server/assets/vendor-codemirror-B4BeZarI.js} +11 -11
- package/dist/web/server/index.html +4 -4
- package/dist/web/server/seed/core/chunks/canvas.6ac57ab1.json +1 -0
- package/dist/web/server/seed/core/chunks/dashboards.96c1474b.json +1 -0
- package/dist/web/server/seed/core/chunks/{efforts.f2875ac9.json → efforts.b724fc2b.json} +1 -1
- package/dist/web/server/seed/core/chunks/{equipment.a56f9b72.json → equipment.2743295a.json} +1 -1
- package/dist/web/server/seed/core/indexes/notebooks/canvas.json +181 -181
- package/dist/web/server/seed/core/indexes/notebooks/dashboards.json +17 -17
- package/dist/web/server/seed/core/indexes/notebooks/efforts.json +326 -326
- package/dist/web/server/seed/core/indexes/notebooks/equipment.json +50 -50
- package/dist/web/server/seed/core/manifest.json +31 -31
- package/dist/web/server/seed/core/markdown/canvas/ai-first/README.json +1 -1
- package/dist/web/server/seed/core/markdown/canvas/guide/README.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/guide/clock.json +1 -1
- package/dist/web/server/seed/core/markdown/canvas/guide/dashboards.json +4 -32
- package/dist/web/server/seed/core/markdown/canvas/guide/metrics-summaries.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/guide/metrics.json +16 -16
- package/dist/web/server/seed/core/markdown/canvas/guide/protocols.json +20 -20
- package/dist/web/server/seed/core/markdown/canvas/guide/sessions.json +33 -33
- package/dist/web/server/seed/core/markdown/canvas/guide/start.json +11 -11
- package/dist/web/server/seed/core/markdown/canvas/guide/structure.json +25 -25
- package/dist/web/server/seed/core/markdown/canvas/guide/wql.json +22 -22
- package/dist/web/server/seed/core/markdown/canvas/home/sample-script.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/home/welcome-1.json +2 -2
- package/dist/web/server/seed/core/markdown/canvas/syntax/actions-comments.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/alternating-emom.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/basic-emom.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/calculated-metrics.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/classic-amrap.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/complex-barbell-cycling.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/complex-full-session.json +10 -10
- package/dist/web/server/seed/core/markdown/canvas/syntax/complex-nested-protocols.json +7 -7
- package/dist/web/server/seed/core/markdown/canvas/syntax/complex-partner-workout.json +7 -7
- package/dist/web/server/seed/core/markdown/canvas/syntax/complex-swimming.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/core-rules.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/custom-and-calculated-metrics.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/custom-intervals.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-1.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-2.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-3.json +3 -3
- package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-4.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/custom-metrics-5.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-climb-bouldering.json +2 -2
- package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-climb-hangboard.json +2 -2
- package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-climb-sport.json +2 -2
- package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-log.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-plan.json +8 -8
- package/dist/web/server/seed/core/markdown/canvas/syntax/dialect-wod.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/distance-intervals.json +3 -3
- package/dist/web/server/seed/core/markdown/canvas/syntax/document-1.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/document-2.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/document-3.json +10 -10
- package/dist/web/server/seed/core/markdown/canvas/syntax/document-4.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/effort-notes.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/frontmatter-summaries.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/groups-1.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/groups-2.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/groups-3.json +3 -3
- package/dist/web/server/seed/core/markdown/canvas/syntax/groups-4.json +3 -3
- package/dist/web/server/seed/core/markdown/canvas/syntax/longer-duration.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/longer-intervals.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/measurements.json +7 -7
- package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-1.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-2.json +7 -7
- package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-3.json +8 -8
- package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-4.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/metrics-5.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/mixed-sections.json +10 -10
- package/dist/web/server/seed/core/markdown/canvas/syntax/mixed-timers.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/multiple-amrap-windows.json +7 -7
- package/dist/web/server/seed/core/markdown/canvas/syntax/multiple-sets.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/named-groups.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-1.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-2.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-3.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-4.json +3 -3
- package/dist/web/server/seed/core/markdown/canvas/syntax/protocols-5.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/single-movement.json +3 -3
- package/dist/web/server/seed/core/markdown/canvas/syntax/supplemental-1.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/supplemental-2.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/supplemental-3.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/supplemental-4.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/time-cap.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/timer-modifiers.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/timers-1.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/syntax/timers-2.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/timers-3.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/timers-4.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/syntax/timers-5.json +5 -5
- package/dist/web/server/seed/core/markdown/canvas/syntax/timers-rest.json +4 -4
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/aggregate-by-effort.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/aggregate-by-week.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/content-fran.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/filter-combos.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/pipes-limit.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/session-rpe.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/source-journal.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/tis-trend.json +6 -6
- package/dist/web/server/seed/core/markdown/canvas/wql-presets/where-join.json +6 -6
- package/dist/web/server/seed/core/markdown/dashboards/benchmark-pr-board.json +32 -32
- package/dist/web/server/seed/core/markdown/dashboards/finger-strength-v8.json +26 -26
- package/dist/web/server/seed/core/markdown/dashboards/polarized-base-marathon.json +50 -50
- package/dist/web/server/seed/core/markdown/dashboards/recovery-readiness.json +38 -38
- package/dist/web/server/seed/core/markdown/dashboards/road-to-560-total.json +50 -50
- package/dist/web/server/seed/core/markdown/dashboards/training-block-review.json +62 -62
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/air-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/box-jump.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/broad-jump.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/burpee-box-jump-over.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/burpee-over-dumbbell.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/burpee.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/dumbbell-squat-clean.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/ghd-sit-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/ground-kong.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/jumping-jack.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/kong-walk.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/lunge.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/overhead-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/parkour-roll.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/parkour-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/pistol-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/plank.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/precision-burpee.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/precision-jump.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/quadrupedal-movement.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/russian-twist.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/sit-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/squat-clean.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/squat-hold.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/squat-snatch.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/tuck-jump.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/wall-ball.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/bodyweight/wall-burpee.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/cycling/assault-bike.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/cycling/cycling-moderate.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/cycling/cycling-vigorous.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/assisted-pull-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/burpee-pull-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/chest-to-bar-pull-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/dip.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/double-under.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/handstand-hold.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/handstand-push-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/handstand-walk.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/jump-rope.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/jumping-pull-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/jumping-push-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/l-sit-pull-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/muscle-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/pull-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/push-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/reverse-wall-dip.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/rope-climb.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/gymnastics/toes-to-bar.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-arm-bar.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-around-the-world.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-bent-over-row.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-clean-and-jerk.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-clean-and-press.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-clean.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-deadlift.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-floor-press.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-front-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-goblet-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-gorilla-row.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-halo.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-jerk.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-overhead-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-press.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-snatch.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-swing.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/kettlebell-windmill.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/kettlebell/turkish-get-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/recovery/rest.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/recovery/stretching.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/rowing/rowing-sprint.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/rowing/rowing.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/rowing/ski-erg.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/running/backward-running.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/running/running-6-mph.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/running/running-8-mph.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/running/running-sprint.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/snatch.json +2 -2
- package/dist/web/server/seed/core/markdown/efforts/strength/back-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/bench-press.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/box-step-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/carioca.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/clean-and-jerk.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/cluster.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/dead-hang.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/deadlift.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/devils-press.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-box-step-up.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-clean.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-fly.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-row.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-snatch.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/dumbbell-thruster.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/elbows-to-knees.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/farmer-carry.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/frog-stand.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/front-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/good-morning.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/hanging-leg-raise.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/hollow-rock.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/knees-to-elbows.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/l-sit.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/man-maker.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/medicine-ball-clean.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/overhead-press.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/parkour-vault.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/pig-flip.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/power-clean.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/power-snatch.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/push-jerk.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/push-press.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/romanian-deadlift.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/single-leg-deadlift.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/skull-crusher.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/slam-ball.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/sled-pull.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/sled-push.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/sumo-deadlift.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/thruster.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/triceps-extension.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/v-sit-hold.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/wall-walk.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/strength/yoga-sun-salutation.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-assisted-sprint.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-backstroke.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-breaststroke-kick.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-breaststroke.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-butterfly.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-catch-up-drill.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-choice-stroke.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-dive-start.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-dolphin-kick.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-drafting.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-fingertip-drag.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-freestyle.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-individual-medley.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-kick.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-pull.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-resisted-sprint.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-rotation-drill.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-sighting.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-single-arm-drill.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-stroke-transition.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-two-kick-one-pull.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming-vigorous.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/swimming/swimming.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-arm-cast.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-circles.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-mill.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-reverse-mill.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/clubbell-shield-cast.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-10-to-2-swing.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-360-swing.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-barbarian-squat.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-flow.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-gravedigger.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/macebell-touchdown.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/sandbag-bear-hug-carry.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/sandbag-bear-hug-extension.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/unconventional/sandbag-over-shoulder.json +1 -1
- package/dist/web/server/seed/core/markdown/efforts/walking/walking-3-mph.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/air-bike.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/barbell.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/bench.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/bike-erg.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/climbing-rope.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/clubs.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/dumbbell.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/ghd.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/gymnastic-rings.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/jump-rope.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/kettlebell.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/macebell.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/medicine-ball.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/parallettes.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/plyo-box.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/pull-up-bar.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/rower.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/sandbag.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/ski-erg.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/slam-ball.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/sled.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/sledgehammer.json +1 -1
- package/dist/web/server/seed/core/markdown/equipment/weight-vest.json +1 -1
- package/dist/web/server/seed/core/report.html +14 -14
- package/package.json +6 -6
- package/dist/chunk-L5S7PXAB.mjs.map +0 -1
- package/dist/chunk-QE5CK3QT.mjs.map +0 -1
- package/dist/chunk-TDYC2FCK.mjs.map +0 -1
- package/dist/chunk-V23POHG2.mjs.map +0 -1
- package/dist/chunk-Z2IQPTDI.mjs.map +0 -1
- package/dist/chunk-ZUZMRH3G.mjs.map +0 -1
- package/dist/compiler-TOM2S2RL.mjs +0 -9
- package/dist/compiler-TOM2S2RL.mjs.map +0 -1
- package/dist/server-QK2CXCDJ.mjs +0 -11
- package/dist/web/playground/assets/main-Dq1wHl4y.css +0 -2
- package/dist/web/playground/assets/main-lF0MJ7yl.js +0 -499
- package/dist/web/playground/seed/core/chunks/canvas.499930d3.json +0 -1
- package/dist/web/playground/seed/core/chunks/dashboards.91cae756.json +0 -1
- package/dist/web/server/assets/main-4y8Q5pTh.js +0 -499
- package/dist/web/server/assets/main-Dq1wHl4y.css +0 -2
- package/dist/web/server/seed/core/chunks/canvas.499930d3.json +0 -1
- package/dist/web/server/seed/core/chunks/dashboards.91cae756.json +0 -1
package/dist/bin/wod.cjs
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
var wodWikiLang = require('@bitcobblers/wod-wiki-lang');
|
|
5
5
|
var wod_wiki_engine_star = require('@bitcobblers/wod-wiki-engine');
|
|
6
|
-
var child_process = require('child_process');
|
|
7
6
|
var fs = require('fs');
|
|
8
7
|
var path = require('path');
|
|
8
|
+
var child_process = require('child_process');
|
|
9
9
|
var wodWikiCore = require('@bitcobblers/wod-wiki-core');
|
|
10
10
|
var wodWikiWql = require('@bitcobblers/wod-wiki-wql');
|
|
11
11
|
var crypto = require('crypto');
|
|
@@ -316,82 +316,60 @@ var init_db = __esm({
|
|
|
316
316
|
CLI_UUID_NAMESPACE = "c0ffee00-8b1a-4e2c-9d3f-5a6b7c8d9e0f";
|
|
317
317
|
}
|
|
318
318
|
});
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
function resolveGitVersion(repoRoot) {
|
|
374
|
-
try {
|
|
375
|
-
const run = (args) => child_process.execSync(`git ${args}`, { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
376
|
-
const count = Number(run("rev-list --count HEAD"));
|
|
377
|
-
return {
|
|
378
|
-
version: Number.isFinite(count) && count > 0 ? count : 0,
|
|
379
|
-
versionLabel: run("describe --tags --long --always --dirty"),
|
|
380
|
-
commit: run("rev-parse HEAD"),
|
|
381
|
-
dirty: run("status --porcelain") !== ""
|
|
382
|
-
};
|
|
383
|
-
} catch {
|
|
384
|
-
return UNKNOWN_GIT_VERSION;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
var UNKNOWN_GIT_VERSION;
|
|
388
|
-
var init_git_version = __esm({
|
|
389
|
-
"src/seedbuild/git-version.ts"() {
|
|
390
|
-
UNKNOWN_GIT_VERSION = {
|
|
391
|
-
version: 0,
|
|
392
|
-
versionLabel: "unknown",
|
|
393
|
-
commit: "",
|
|
394
|
-
dirty: false
|
|
319
|
+
var NodeFsFeedTree;
|
|
320
|
+
var init_nodeFeedTree = __esm({
|
|
321
|
+
"src/cli/nodeFeedTree.ts"() {
|
|
322
|
+
init_db();
|
|
323
|
+
NodeFsFeedTree = class {
|
|
324
|
+
rootDir;
|
|
325
|
+
constructor(rootDir) {
|
|
326
|
+
this.rootDir = nodePath().resolve(rootDir);
|
|
327
|
+
}
|
|
328
|
+
get root() {
|
|
329
|
+
return this.rootDir;
|
|
330
|
+
}
|
|
331
|
+
absPath(relPath) {
|
|
332
|
+
const clean = wod_wiki_engine_star.normalizeFeedTreePath(relPath);
|
|
333
|
+
const resolved = nodePath().resolve(this.rootDir, clean);
|
|
334
|
+
if (resolved !== this.rootDir && !resolved.startsWith(this.rootDir + "/") && !resolved.startsWith(this.rootDir + "\\")) {
|
|
335
|
+
throw new wod_wiki_engine_star.FeedTreeError("layout", `Path '${relPath}' escapes root '${this.rootDir}'`);
|
|
336
|
+
}
|
|
337
|
+
return resolved;
|
|
338
|
+
}
|
|
339
|
+
async read(path) {
|
|
340
|
+
const abs = this.absPath(path);
|
|
341
|
+
const fs = nodeFs();
|
|
342
|
+
if (!fs.existsSync(abs)) {
|
|
343
|
+
throw new wod_wiki_engine_star.FeedTreeError("not-found", `File not found: ${path}`);
|
|
344
|
+
}
|
|
345
|
+
return new Uint8Array(fs.readFileSync(abs));
|
|
346
|
+
}
|
|
347
|
+
async stat(path) {
|
|
348
|
+
try {
|
|
349
|
+
const bytes = await this.read(path);
|
|
350
|
+
return {
|
|
351
|
+
bytes: bytes.byteLength,
|
|
352
|
+
sha256: await wod_wiki_engine_star.sha256HexAsync(bytes)
|
|
353
|
+
};
|
|
354
|
+
} catch (err) {
|
|
355
|
+
if (err instanceof wod_wiki_engine_star.FeedTreeError && err.code === "not-found") return void 0;
|
|
356
|
+
throw err;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
async write(path, bytes) {
|
|
360
|
+
const abs = this.absPath(path);
|
|
361
|
+
const p = nodePath();
|
|
362
|
+
const fs = nodeFs();
|
|
363
|
+
fs.mkdirSync(p.dirname(abs), { recursive: true });
|
|
364
|
+
fs.writeFileSync(abs, bytes);
|
|
365
|
+
}
|
|
366
|
+
async delete(path) {
|
|
367
|
+
const abs = this.absPath(path);
|
|
368
|
+
const fs = nodeFs();
|
|
369
|
+
if (fs.existsSync(abs)) {
|
|
370
|
+
fs.unlinkSync(abs);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
395
373
|
};
|
|
396
374
|
}
|
|
397
375
|
});
|
|
@@ -457,283 +435,663 @@ var init_report = __esm({
|
|
|
457
435
|
"src/seedbuild/report.ts"() {
|
|
458
436
|
}
|
|
459
437
|
});
|
|
460
|
-
var init_frontmatter = __esm({
|
|
461
|
-
"src/seedbuild/frontmatter.ts"() {
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
438
|
|
|
465
|
-
// src/
|
|
466
|
-
var
|
|
467
|
-
var
|
|
468
|
-
"src/
|
|
469
|
-
|
|
439
|
+
// src/version.ts
|
|
440
|
+
var VERSION;
|
|
441
|
+
var init_version = __esm({
|
|
442
|
+
"src/version.ts"() {
|
|
443
|
+
VERSION = "0.52.2198";
|
|
470
444
|
}
|
|
471
445
|
});
|
|
472
446
|
|
|
473
|
-
// src/
|
|
474
|
-
var
|
|
475
|
-
__export(
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
buildBlockIndexRows: () => buildBlockIndexRows,
|
|
479
|
-
chunkIdFor: () => chunkIdFor,
|
|
480
|
-
collectCorpusMarkdown: () => collectCorpusMarkdown,
|
|
481
|
-
compileSeedRow: () => compileSeedRow,
|
|
482
|
-
dateKeyToCreatedAt: () => dateKeyToCreatedAt,
|
|
483
|
-
discoverUncatalogedEfforts: () => discoverUncatalogedEfforts,
|
|
484
|
-
frontmatterDateToCreatedAt: () => frontmatterDateToCreatedAt,
|
|
485
|
-
generateSeed: () => generateSeed,
|
|
486
|
-
getFileCommit: () => getFileCommit,
|
|
487
|
-
getFileVersion: () => getFileVersion,
|
|
488
|
-
getPathCommit: () => getPathCommit,
|
|
489
|
-
getPathUpdatedAt: () => getPathUpdatedAt,
|
|
490
|
-
getPathVersion: () => getPathVersion,
|
|
491
|
-
groupCorpusPath: () => groupCorpusPath,
|
|
492
|
-
loadCorpusReferenceCatalog: () => loadCorpusReferenceCatalog,
|
|
493
|
-
partitionIntoChunks: () => partitionIntoChunks,
|
|
494
|
-
scaffoldDiscoveredEfforts: () => scaffoldDiscoveredEfforts,
|
|
495
|
-
seedNoteIdSync: () => seedNoteIdSync,
|
|
496
|
-
validateDashboardNote: () => validateDashboardNote,
|
|
497
|
-
validateWodBlockSyntax: () => validateWodBlockSyntax
|
|
447
|
+
// src/cli/scaffoldFeed.ts
|
|
448
|
+
var scaffoldFeed_exports = {};
|
|
449
|
+
__export(scaffoldFeed_exports, {
|
|
450
|
+
scaffoldFeed: () => scaffoldFeed,
|
|
451
|
+
validateFeedName: () => validateFeedName
|
|
498
452
|
});
|
|
499
|
-
function
|
|
500
|
-
if (
|
|
501
|
-
|
|
502
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
503
|
-
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
504
|
-
if (entry.isDirectory()) out.push(...listMarkdownFiles(path.join(dir, entry.name), rel));
|
|
505
|
-
else if (entry.isFile() && entry.name.endsWith(".md")) out.push(rel);
|
|
453
|
+
function validateFeedName(name) {
|
|
454
|
+
if (name.length === 0 || name === "." || name === "..") {
|
|
455
|
+
throw new Error("Feed name must be a single non-empty directory name");
|
|
506
456
|
}
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
function chunkIdFor(relPath) {
|
|
510
|
-
const parts = relPath.split("/");
|
|
511
|
-
if (parts[0] !== "markdown" || parts.length < 2) return null;
|
|
512
|
-
const corpus = parts[1];
|
|
513
|
-
if (parts.length === 2) return null;
|
|
514
|
-
const slug = parts[2]?.replace(/\.md$/, "");
|
|
515
|
-
switch (corpus) {
|
|
516
|
-
case "canvas":
|
|
517
|
-
case "dashboards":
|
|
518
|
-
case "efforts":
|
|
519
|
-
case "equipment":
|
|
520
|
-
return corpus;
|
|
521
|
-
case "notebooks":
|
|
522
|
-
return parts.length === 3 ? `notebook._root` : `notebook.${slug}`;
|
|
523
|
-
default:
|
|
524
|
-
return null;
|
|
457
|
+
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
|
458
|
+
throw new Error(`Invalid feed name '${name}': must be a single directory name (no path separators or traversal)`);
|
|
525
459
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
const excluded = new Set(excludePaths);
|
|
529
|
-
return listMarkdownFiles(markdownDir).map((p) => `markdown/${p}`).filter((path) => !excluded.has(path));
|
|
530
|
-
}
|
|
531
|
-
function partitionIntoChunks(paths) {
|
|
532
|
-
const byId = /* @__PURE__ */ new Map();
|
|
533
|
-
for (const p of paths) {
|
|
534
|
-
const id = chunkIdFor(p);
|
|
535
|
-
if (id === null) {
|
|
536
|
-
throw new Error(
|
|
537
|
-
`[generate-seed] Parity failure: '${p}' is not part of any known corpus (canvas | dashboards | efforts | equipment | notebooks). Extend chunkIdFor() if this is a new corpus.`
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
const list = byId.get(id);
|
|
541
|
-
if (list) list.push(p);
|
|
542
|
-
else byId.set(id, [p]);
|
|
460
|
+
if (/^(?:[A-Za-z]:)?[/\\]/.test(name)) {
|
|
461
|
+
throw new Error(`Invalid feed name '${name}': absolute paths are not allowed`);
|
|
543
462
|
}
|
|
544
|
-
|
|
463
|
+
if (name.length > 214 || !/^[a-z0-9][a-z0-9._-]*$/.test(name)) {
|
|
464
|
+
throw new Error(
|
|
465
|
+
`Invalid feed name '${name}': must be a valid npm package name (lowercase letters, digits, dots, hyphens, underscores; no leading dot/hyphen)`
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
return name;
|
|
545
469
|
}
|
|
546
|
-
function
|
|
547
|
-
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
const declared = new Set(doc.tokens.map((t) => t.name));
|
|
555
|
-
for (const widget of doc.widgets) {
|
|
556
|
-
const where = `widget '${widget.title ?? widget.body.slice(0, 40)}'`;
|
|
557
|
-
if (widget.title === void 0) problems.push(`${where}: missing title`);
|
|
558
|
-
if (!wodWikiWql.isDashboardWidgetType(wodWikiWql.resolveWidgetType(widget.type))) {
|
|
559
|
-
problems.push(`${where}: unknown widget type '${widget.type}'`);
|
|
470
|
+
function scaffoldFeed(name, opts = {}) {
|
|
471
|
+
validateFeedName(name);
|
|
472
|
+
const dir = path.resolve(opts.cwd ?? process.cwd(), name);
|
|
473
|
+
try {
|
|
474
|
+
fs.mkdirSync(dir);
|
|
475
|
+
} catch (error) {
|
|
476
|
+
if (error.code === "EEXIST") {
|
|
477
|
+
throw new Error(`Refusing to overwrite '${dir}': destination already exists`, { cause: error });
|
|
560
478
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
479
|
+
throw error;
|
|
480
|
+
}
|
|
481
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
482
|
+
const files = [
|
|
483
|
+
["package.json", `${JSON.stringify(
|
|
484
|
+
{
|
|
485
|
+
name,
|
|
486
|
+
version: "0.1.0",
|
|
487
|
+
private: true,
|
|
488
|
+
type: "module",
|
|
489
|
+
description: `WOD Wiki workout feed: ${name}`,
|
|
490
|
+
scripts: {
|
|
491
|
+
build: "wod build . --output dist"
|
|
492
|
+
},
|
|
493
|
+
devDependencies: {
|
|
494
|
+
"@bitcobblers/wod-wiki-tools": `^${VERSION}`
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
null,
|
|
498
|
+
2
|
|
499
|
+
)}
|
|
500
|
+
`],
|
|
501
|
+
[".gitignore", "node_modules/\ndist/\n"],
|
|
502
|
+
[".github/workflows/publish-feed.yml", publishWorkflow()],
|
|
503
|
+
["markdown/notebooks/example/README.md", feedReadme(name)],
|
|
504
|
+
[`markdown/notebooks/example/morning-session.md`, exampleWorkout(date)],
|
|
505
|
+
["README.md", repoReadme(name)]
|
|
506
|
+
];
|
|
507
|
+
try {
|
|
508
|
+
for (const [rel, content] of files) {
|
|
509
|
+
const target = path.join(dir, rel);
|
|
510
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
511
|
+
fs.writeFileSync(target, content, "utf-8");
|
|
568
512
|
}
|
|
513
|
+
} catch (error) {
|
|
514
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
515
|
+
throw error;
|
|
569
516
|
}
|
|
570
|
-
return
|
|
517
|
+
return { dir, files: files.map(([rel]) => rel) };
|
|
571
518
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
519
|
+
var publishWorkflow, feedReadme, exampleWorkout, repoReadme;
|
|
520
|
+
var init_scaffoldFeed = __esm({
|
|
521
|
+
"src/cli/scaffoldFeed.ts"() {
|
|
522
|
+
init_version();
|
|
523
|
+
publishWorkflow = () => `name: Publish feed
|
|
524
|
+
|
|
525
|
+
# Compile the feed with the wod CLI and deploy dist/ to GitHub Pages.
|
|
526
|
+
# Requires Pages enabled: repo Settings \u2192 Pages \u2192 Source: "GitHub Actions".
|
|
527
|
+
|
|
528
|
+
on:
|
|
529
|
+
push:
|
|
530
|
+
branches: [main]
|
|
531
|
+
workflow_dispatch:
|
|
532
|
+
|
|
533
|
+
permissions:
|
|
534
|
+
contents: read
|
|
535
|
+
pages: write
|
|
536
|
+
id-token: write
|
|
537
|
+
|
|
538
|
+
concurrency:
|
|
539
|
+
group: pages
|
|
540
|
+
cancel-in-progress: true
|
|
541
|
+
|
|
542
|
+
jobs:
|
|
543
|
+
publish:
|
|
544
|
+
runs-on: ubuntu-latest
|
|
545
|
+
environment:
|
|
546
|
+
name: github-pages
|
|
547
|
+
url: \${{ steps.deployment.outputs.page_url }}
|
|
548
|
+
steps:
|
|
549
|
+
- uses: actions/checkout@v4
|
|
550
|
+
with:
|
|
551
|
+
# Full history: seed manifest version stamps derive from git commit count.
|
|
552
|
+
fetch-depth: 0
|
|
553
|
+
|
|
554
|
+
- name: Set up Bun
|
|
555
|
+
uses: oven-sh/setup-bun@v2
|
|
556
|
+
with:
|
|
557
|
+
bun-version: 1.4.x
|
|
558
|
+
|
|
559
|
+
- name: Install dependencies
|
|
560
|
+
run: bun install
|
|
561
|
+
|
|
562
|
+
- name: Build seed
|
|
563
|
+
run: bunx wod build . --output dist
|
|
564
|
+
|
|
565
|
+
- uses: actions/configure-pages@v5
|
|
566
|
+
|
|
567
|
+
- name: Upload dist
|
|
568
|
+
uses: actions/upload-pages-artifact@v3
|
|
569
|
+
with:
|
|
570
|
+
path: dist
|
|
571
|
+
|
|
572
|
+
- id: deployment
|
|
573
|
+
uses: actions/deploy-pages@v4
|
|
574
|
+
`;
|
|
575
|
+
feedReadme = (name) => `# ${name}
|
|
576
|
+
|
|
577
|
+
Example benchmark notebook. Each \`.md\` file in this directory becomes part of
|
|
578
|
+
the \`example\` notebook chunk; \`README.md\` is the notebook's landing page.
|
|
579
|
+
|
|
580
|
+
Add one file per workout:
|
|
581
|
+
|
|
582
|
+
\`\`\`\`markdown
|
|
583
|
+
---
|
|
584
|
+
title: My workout
|
|
585
|
+
date: 2026-01-01
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
# My workout
|
|
589
|
+
|
|
590
|
+
\`\`\`time
|
|
591
|
+
(21-15-9)
|
|
592
|
+
Thrusters @95lb
|
|
593
|
+
Pull-ups
|
|
594
|
+
\`\`\`
|
|
595
|
+
\`\`\`\`
|
|
596
|
+
|
|
597
|
+
The \`date:\` frontmatter field sets the workout's chronological placement
|
|
598
|
+
(regardless of filename or directory).
|
|
599
|
+
`;
|
|
600
|
+
exampleWorkout = (date) => `---
|
|
601
|
+
title: Morning session
|
|
602
|
+
date: ${date}
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
# Morning session
|
|
606
|
+
|
|
607
|
+
\`\`\`time
|
|
608
|
+
(21-15-9)
|
|
609
|
+
Thrusters @95lb
|
|
610
|
+
Pull-ups
|
|
611
|
+
\`\`\`
|
|
612
|
+
`;
|
|
613
|
+
repoReadme = (name) => `# ${name}
|
|
614
|
+
|
|
615
|
+
A [WOD Wiki](https://github.com/bitcobblers/wod-wiki) workout feed: plain
|
|
616
|
+
Markdown workouts compiled to static, version-stamped seed chunks and published
|
|
617
|
+
via GitHub Pages.
|
|
618
|
+
|
|
619
|
+
## Develop
|
|
620
|
+
|
|
621
|
+
\`\`\`sh
|
|
622
|
+
bun install
|
|
623
|
+
bunx wod build . --output dist
|
|
624
|
+
\`\`\`
|
|
625
|
+
|
|
626
|
+
Workouts live under \`markdown/\` \u2014 this scaffold starts with one example
|
|
627
|
+
feed. Validate everything with \`bunx wod build\`: it gates every file on
|
|
628
|
+
the Whiteboard grammar and corpus layout before writing \`dist/\`.
|
|
629
|
+
|
|
630
|
+
## Publish
|
|
631
|
+
|
|
632
|
+
Push to GitHub and enable Pages (**Settings \u2192 Pages \u2192 Source: GitHub
|
|
633
|
+
Actions**). The bundled workflow (\`.github/workflows/publish-feed.yml\`)
|
|
634
|
+
builds the feed on every push to \`main\` and deploys \`dist/\`.
|
|
635
|
+
|
|
636
|
+
## Share
|
|
637
|
+
|
|
638
|
+
Once published, anyone can subscribe to this feed from a WOD Wiki instance
|
|
639
|
+
at:
|
|
640
|
+
|
|
641
|
+
\`\`\`
|
|
642
|
+
<app-url>/subscribe?source=<url-encoded published feed URL>
|
|
643
|
+
\`\`\`
|
|
644
|
+
|
|
645
|
+
For \`owner\`/\`repo\` on GitHub Pages the feed URL is the deployed
|
|
646
|
+
directory, \`https://owner.github.io/repo/\`, e.g.
|
|
647
|
+
\`/subscribe?source=https%3A%2F%2Fowner.github.io%2Frepo%2F\`.
|
|
648
|
+
`;
|
|
591
649
|
}
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
// src/cli/skills.ts
|
|
653
|
+
var skills_exports = {};
|
|
654
|
+
__export(skills_exports, {
|
|
655
|
+
bundledSkillsRoot: () => bundledSkillsRoot,
|
|
656
|
+
installSkills: () => installSkills,
|
|
657
|
+
listBundledSkills: () => listBundledSkills
|
|
658
|
+
});
|
|
659
|
+
function frontmatterField(source, key) {
|
|
660
|
+
const match = source.match(new RegExp(`^${key}:[ ]*(.*)$`, "m"));
|
|
661
|
+
return match?.[1].trim().replace(/^(['"])(.*)\1$/, "$2") || void 0;
|
|
592
662
|
}
|
|
593
|
-
function
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
} catch {
|
|
604
|
-
return "";
|
|
605
|
-
}
|
|
663
|
+
function listBundledSkills(root) {
|
|
664
|
+
if (!fs.existsSync(root)) return [];
|
|
665
|
+
return fs.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory() && fs.existsSync(path.join(root, entry.name, "SKILL.md"))).sort((a, b) => a.name.localeCompare(b.name)).map((entry) => {
|
|
666
|
+
const source = fs.readFileSync(path.join(root, entry.name, "SKILL.md"), "utf-8");
|
|
667
|
+
return {
|
|
668
|
+
name: entry.name,
|
|
669
|
+
description: frontmatterField(source, "description") ?? "",
|
|
670
|
+
path: path.join(root, entry.name)
|
|
671
|
+
};
|
|
672
|
+
});
|
|
606
673
|
}
|
|
607
|
-
function
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
return 1;
|
|
614
|
-
}
|
|
674
|
+
function bundledSkillsRoot() {
|
|
675
|
+
const scriptDir = path.dirname(fs.realpathSync(process.argv[1] ?? process.cwd()));
|
|
676
|
+
const candidates = ["skills", "../skills", "../../skills", "../../../skills", "../../../../skills"].map(
|
|
677
|
+
(rel) => path.resolve(scriptDir, rel)
|
|
678
|
+
);
|
|
679
|
+
return candidates.find((candidate) => listBundledSkills(candidate).length > 0);
|
|
615
680
|
}
|
|
616
|
-
function
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
return Number.isFinite(count) && count > 0 ? count : 1;
|
|
621
|
-
} catch {
|
|
622
|
-
return 1;
|
|
681
|
+
function installSkills(options = {}) {
|
|
682
|
+
const root = options.root ?? bundledSkillsRoot();
|
|
683
|
+
if (!root) {
|
|
684
|
+
throw new Error("no bundled skills found next to this CLI \u2014 reinstall the package or run from the wod-wiki checkout");
|
|
623
685
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
686
|
+
const skills = listBundledSkills(root);
|
|
687
|
+
if (skills.length === 0) throw new Error(`no skills under ${root}`);
|
|
688
|
+
const target = path.join(path.resolve(options.dir ?? process.cwd()), ".agents", "skills");
|
|
689
|
+
const installed = [];
|
|
690
|
+
const skipped = [];
|
|
691
|
+
for (const skill of skills) {
|
|
692
|
+
const destination = path.join(target, skill.name);
|
|
693
|
+
if (fs.existsSync(destination) && options.force !== true) {
|
|
694
|
+
skipped.push(skill.name);
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
fs.rmSync(destination, { recursive: true, force: true });
|
|
698
|
+
fs.mkdirSync(target, { recursive: true });
|
|
699
|
+
fs.cpSync(skill.path, destination, { recursive: true });
|
|
700
|
+
installed.push(skill.name);
|
|
630
701
|
}
|
|
702
|
+
return { root, target, installed, skipped };
|
|
631
703
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
const out = child_process.execFileSync("git", ["log", "-1", "--format=%cI", "--", targetPath], { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
635
|
-
return out || void 0;
|
|
636
|
-
} catch {
|
|
637
|
-
return void 0;
|
|
704
|
+
var init_skills = __esm({
|
|
705
|
+
"src/cli/skills.ts"() {
|
|
638
706
|
}
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// src/seedbuild/contract.ts
|
|
710
|
+
var contract_exports = {};
|
|
711
|
+
var init_contract = __esm({
|
|
712
|
+
"src/seedbuild/contract.ts"() {
|
|
713
|
+
__reExport(contract_exports, wod_wiki_engine_star__namespace);
|
|
644
714
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
const
|
|
652
|
-
const
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
// src/seedbuild/filename.ts
|
|
718
|
+
function fileToDisplayName(filename) {
|
|
719
|
+
const base = filename.replace(/\.md$/, "");
|
|
720
|
+
if (base.toUpperCase() === "README") return "Overview";
|
|
721
|
+
const cleaned = base.replace(/^day-\d+-/, "");
|
|
722
|
+
const tokens = cleaned.split(/[-_]/);
|
|
723
|
+
const titled = [];
|
|
724
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
725
|
+
const token = tokens[i];
|
|
726
|
+
const next = tokens[i + 1];
|
|
727
|
+
const after = tokens[i + 2];
|
|
728
|
+
const prev = tokens[i - 1];
|
|
729
|
+
if (/^\d{1,2}$/.test(token) && /^\d{1,2}$/.test(next ?? "") && !/^\d+$/.test(prev ?? "") && !/^\d+$/.test(after ?? "")) {
|
|
730
|
+
titled.push(`${token}.${next}`);
|
|
731
|
+
i++;
|
|
732
|
+
continue;
|
|
733
|
+
}
|
|
734
|
+
if (titled.length > 0 && FILE_TITLE_STOP_WORDS[token.toLowerCase()]) {
|
|
735
|
+
titled.push(token.toLowerCase());
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
titled.push(token.charAt(0).toUpperCase() + token.slice(1));
|
|
656
739
|
}
|
|
657
|
-
return
|
|
740
|
+
return titled.join(" ");
|
|
658
741
|
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
742
|
+
var FILE_TITLE_STOP_WORDS;
|
|
743
|
+
var init_filename = __esm({
|
|
744
|
+
"src/seedbuild/filename.ts"() {
|
|
745
|
+
FILE_TITLE_STOP_WORDS = {
|
|
746
|
+
and: true,
|
|
747
|
+
or: true,
|
|
748
|
+
of: true,
|
|
749
|
+
for: true,
|
|
750
|
+
to: true,
|
|
751
|
+
in: true,
|
|
752
|
+
on: true,
|
|
753
|
+
at: true,
|
|
754
|
+
by: true,
|
|
755
|
+
with: true,
|
|
756
|
+
the: true,
|
|
757
|
+
a: true,
|
|
758
|
+
an: true
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
function resolveGitVersion(repoRoot) {
|
|
763
|
+
try {
|
|
764
|
+
const run = (args) => child_process.execSync(`git ${args}`, { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
765
|
+
const count = Number(run("rev-list --count HEAD"));
|
|
766
|
+
return {
|
|
767
|
+
version: Number.isFinite(count) && count > 0 ? count : 0,
|
|
768
|
+
versionLabel: run("describe --tags --long --always --dirty"),
|
|
769
|
+
commit: run("rev-parse HEAD"),
|
|
770
|
+
dirty: run("status --porcelain") !== ""
|
|
771
|
+
};
|
|
772
|
+
} catch {
|
|
773
|
+
return UNKNOWN_GIT_VERSION;
|
|
774
|
+
}
|
|
663
775
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
776
|
+
var UNKNOWN_GIT_VERSION;
|
|
777
|
+
var init_git_version = __esm({
|
|
778
|
+
"src/seedbuild/git-version.ts"() {
|
|
779
|
+
UNKNOWN_GIT_VERSION = {
|
|
780
|
+
version: 0,
|
|
781
|
+
versionLabel: "unknown",
|
|
782
|
+
commit: "",
|
|
783
|
+
dirty: false
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
var init_frontmatter = __esm({
|
|
788
|
+
"src/seedbuild/frontmatter.ts"() {
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
// src/seedbuild/validation.ts
|
|
793
|
+
var validation_exports = {};
|
|
794
|
+
var init_validation = __esm({
|
|
795
|
+
"src/seedbuild/validation.ts"() {
|
|
796
|
+
__reExport(validation_exports, wod_wiki_engine_star__namespace);
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
// src/seedbuild/compiler.ts
|
|
801
|
+
var compiler_exports = {};
|
|
802
|
+
__export(compiler_exports, {
|
|
803
|
+
buildBlockEffortRows: () => buildBlockEffortRows,
|
|
804
|
+
buildBlockEquipmentRows: () => buildBlockEquipmentRows,
|
|
805
|
+
buildBlockIndexRows: () => buildBlockIndexRows,
|
|
806
|
+
chunkIdFor: () => chunkIdFor,
|
|
807
|
+
collectCorpusMarkdown: () => collectCorpusMarkdown,
|
|
808
|
+
compileSeedRow: () => compileSeedRow,
|
|
809
|
+
dateKeyToCreatedAt: () => dateKeyToCreatedAt,
|
|
810
|
+
discoverUncatalogedEfforts: () => discoverUncatalogedEfforts,
|
|
811
|
+
frontmatterDateToCreatedAt: () => frontmatterDateToCreatedAt,
|
|
812
|
+
generateSeed: () => generateSeed,
|
|
813
|
+
getFileCommit: () => getFileCommit,
|
|
814
|
+
getFileVersion: () => getFileVersion,
|
|
815
|
+
getPathCommit: () => getPathCommit,
|
|
816
|
+
getPathUpdatedAt: () => getPathUpdatedAt,
|
|
817
|
+
getPathVersion: () => getPathVersion,
|
|
818
|
+
groupCorpusPath: () => groupCorpusPath,
|
|
819
|
+
loadCorpusReferenceCatalog: () => loadCorpusReferenceCatalog,
|
|
820
|
+
partitionIntoChunks: () => partitionIntoChunks,
|
|
821
|
+
scaffoldDiscoveredEfforts: () => scaffoldDiscoveredEfforts,
|
|
822
|
+
seedNoteIdSync: () => seedNoteIdSync,
|
|
823
|
+
validateDashboardNote: () => validateDashboardNote,
|
|
824
|
+
validateWodBlockSyntax: () => validateWodBlockSyntax
|
|
825
|
+
});
|
|
826
|
+
function listMarkdownFiles(dir, prefix = "") {
|
|
827
|
+
if (!fs.existsSync(dir)) return [];
|
|
828
|
+
const out = [];
|
|
829
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
830
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
831
|
+
if (entry.isDirectory()) out.push(...listMarkdownFiles(path.join(dir, entry.name), rel));
|
|
832
|
+
else if (entry.isFile() && entry.name.endsWith(".md")) out.push(rel);
|
|
833
|
+
}
|
|
834
|
+
return out.sort();
|
|
674
835
|
}
|
|
675
|
-
function
|
|
676
|
-
const
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
836
|
+
function chunkIdFor(relPath) {
|
|
837
|
+
const parts = relPath.split("/");
|
|
838
|
+
if (parts[0] !== "markdown" || parts.length < 2) return null;
|
|
839
|
+
const corpus = parts[1];
|
|
840
|
+
if (parts.length === 2) return null;
|
|
841
|
+
const slug = parts[2]?.replace(/\.md$/, "");
|
|
842
|
+
switch (corpus) {
|
|
843
|
+
case "canvas":
|
|
844
|
+
case "dashboards":
|
|
845
|
+
case "efforts":
|
|
846
|
+
case "equipment":
|
|
847
|
+
return corpus;
|
|
848
|
+
case "notebooks":
|
|
849
|
+
return parts.length === 3 ? `notebook._root` : `notebook.${slug}`;
|
|
850
|
+
default:
|
|
851
|
+
return null;
|
|
688
852
|
}
|
|
689
|
-
return rows;
|
|
690
853
|
}
|
|
691
|
-
function
|
|
854
|
+
function collectCorpusMarkdown(markdownDir, excludePaths = []) {
|
|
855
|
+
const excluded = new Set(excludePaths);
|
|
856
|
+
return listMarkdownFiles(markdownDir).map((p) => `markdown/${p}`).filter((path) => !excluded.has(path));
|
|
857
|
+
}
|
|
858
|
+
function partitionIntoChunks(paths) {
|
|
859
|
+
const byId = /* @__PURE__ */ new Map();
|
|
860
|
+
for (const p of paths) {
|
|
861
|
+
const id = chunkIdFor(p);
|
|
862
|
+
if (id === null) {
|
|
863
|
+
throw new Error(
|
|
864
|
+
`[generate-seed] Parity failure: '${p}' is not part of any known corpus (canvas | dashboards | efforts | equipment | notebooks). Extend chunkIdFor() if this is a new corpus.`
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
const list = byId.get(id);
|
|
868
|
+
if (list) list.push(p);
|
|
869
|
+
else byId.set(id, [p]);
|
|
870
|
+
}
|
|
871
|
+
return [...byId.entries()].sort(([a], [b]) => a < b ? -1 : 1).map(([id, files]) => ({ id, files }));
|
|
872
|
+
}
|
|
873
|
+
function validateDashboardNote(raw) {
|
|
692
874
|
const problems = [];
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
875
|
+
const { meta } = wodWikiCore.parseFrontmatter(raw);
|
|
876
|
+
const { sections } = wodWikiWql.parseDashboardNote(raw);
|
|
877
|
+
const doc = wodWikiWql.buildDashboardDocument(sections, meta);
|
|
878
|
+
if (!doc.isDashboard) return ["file is not a dashboard note (missing dashboard frontmatter)"];
|
|
879
|
+
if (doc.title === void 0) problems.push("dashboard has no title");
|
|
880
|
+
if (doc.widgets.length < 3) problems.push(`dashboard has only ${doc.widgets.length} widgets (the locked format has \u2265 3)`);
|
|
881
|
+
const declared = new Set(doc.tokens.map((t) => t.name));
|
|
882
|
+
for (const widget of doc.widgets) {
|
|
883
|
+
const where = `widget '${widget.title ?? widget.body.slice(0, 40)}'`;
|
|
884
|
+
if (widget.title === void 0) problems.push(`${where}: missing title`);
|
|
885
|
+
if (!wodWikiWql.isDashboardWidgetType(wodWikiWql.resolveWidgetType(widget.type))) {
|
|
886
|
+
problems.push(`${where}: unknown widget type '${widget.type}'`);
|
|
705
887
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
if (!node.type.isError) return;
|
|
711
|
-
const line = doc.slice(0, node.from).split("\n").length;
|
|
712
|
-
const snippet = source.slice(node.from, Math.min(node.to, node.from + 60)).split("\n")[0];
|
|
713
|
-
problems.push(`${where}:${line} \`${snippet}\``);
|
|
888
|
+
if (widget.body.includes("\n")) {
|
|
889
|
+
const docParsed = wodWikiWql.parseDocument(widget.body);
|
|
890
|
+
if (docParsed.diagnostics.length > 0) {
|
|
891
|
+
problems.push(`${where}: QueryDocument error: ${docParsed.diagnostics[0]}`);
|
|
714
892
|
}
|
|
715
|
-
}
|
|
893
|
+
} else {
|
|
894
|
+
const parsed = wodWikiWql.parseQuery(widget.body);
|
|
895
|
+
if (parsed.error !== void 0) problems.push(`${where}: WQL parse error: ${parsed.error}`);
|
|
896
|
+
}
|
|
897
|
+
for (const ref of [
|
|
898
|
+
...widget.body.matchAll(/\$([A-Za-z][\w-]*)/g),
|
|
899
|
+
...Object.values(widget.attributes).flatMap((v) => [...String(v).matchAll(/\$([A-Za-z][\w-]*)/g)])
|
|
900
|
+
]) {
|
|
901
|
+
if (!declared.has(ref[1])) problems.push(`${where}: undeclared token $${ref[1]}`);
|
|
902
|
+
}
|
|
716
903
|
}
|
|
717
904
|
return problems;
|
|
718
905
|
}
|
|
719
|
-
function
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
if (parsed) efforts.push(parsed);
|
|
730
|
-
}
|
|
731
|
-
const equipmentDir = path.join(markdownDir, "equipment");
|
|
732
|
-
for (const file of listMarkdownFiles(equipmentDir)) {
|
|
733
|
-
const parsed = wodWikiLang.parseEquipmentFile(fs.readFileSync(path.join(equipmentDir, file), "utf8"));
|
|
734
|
-
if (parsed) equipment.push(parsed);
|
|
906
|
+
function gateDashboards(groups, corpusRoot) {
|
|
907
|
+
for (const group of groups) {
|
|
908
|
+
if (group.id !== contract_exports.DASHBOARDS_CHUNK_ID) continue;
|
|
909
|
+
for (const p of group.files) {
|
|
910
|
+
const problems = validateDashboardNote(fs.readFileSync(path.join(corpusRoot, p), "utf8"));
|
|
911
|
+
if (problems.length > 0) {
|
|
912
|
+
throw new Error(`[generate-seed] Dashboard validation failed for '${p}':
|
|
913
|
+
- ${problems.join("\n - ")}`);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
735
916
|
}
|
|
736
|
-
|
|
917
|
+
}
|
|
918
|
+
function getFileCreatedAt(file, repoRoot) {
|
|
919
|
+
try {
|
|
920
|
+
const out = child_process.execSync(`git log -1 --format=%ct -- '${file}'`, { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
921
|
+
const ts = Number(out) * 1e3;
|
|
922
|
+
return Number.isFinite(ts) && ts > 0 ? ts : 0;
|
|
923
|
+
} catch {
|
|
924
|
+
return 0;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
function seedNoteIdSync(path) {
|
|
928
|
+
const hash = crypto.createHash("sha1").update(`${contract_exports.SEED_NAMESPACE}:${path}`).digest();
|
|
929
|
+
const bytes = new Uint8Array(hash.subarray(0, 16));
|
|
930
|
+
bytes[6] = bytes[6] & 15 | 80;
|
|
931
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
932
|
+
return [...bytes].map((b, i) => [4, 6, 8, 10].includes(i) ? `-${b.toString(16).padStart(2, "0")}` : b.toString(16).padStart(2, "0")).join("");
|
|
933
|
+
}
|
|
934
|
+
function getFileCommit(file, repoRoot) {
|
|
935
|
+
try {
|
|
936
|
+
return child_process.execFileSync("git", ["log", "-1", "--format=%H", "--", file], { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
937
|
+
} catch {
|
|
938
|
+
return "";
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
function getFileVersion(file, repoRoot) {
|
|
942
|
+
try {
|
|
943
|
+
const out = child_process.execFileSync("git", ["rev-list", "--count", "HEAD", "--", file], { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
944
|
+
const count = Number(out);
|
|
945
|
+
return Number.isFinite(count) && count > 0 ? count : 1;
|
|
946
|
+
} catch {
|
|
947
|
+
return 1;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
function getPathVersion(targetPath, repoRoot) {
|
|
951
|
+
try {
|
|
952
|
+
const out = child_process.execFileSync("git", ["rev-list", "--count", "HEAD", "--", targetPath], { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
953
|
+
const count = Number(out);
|
|
954
|
+
return Number.isFinite(count) && count > 0 ? count : 1;
|
|
955
|
+
} catch {
|
|
956
|
+
return 1;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
function getPathCommit(targetPath, repoRoot) {
|
|
960
|
+
try {
|
|
961
|
+
return child_process.execFileSync("git", ["log", "-1", "--format=%H", "--", targetPath], { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
962
|
+
} catch {
|
|
963
|
+
return "";
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
function getPathUpdatedAt(targetPath, repoRoot) {
|
|
967
|
+
try {
|
|
968
|
+
const out = child_process.execFileSync("git", ["log", "-1", "--format=%cI", "--", targetPath], { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
969
|
+
return out || void 0;
|
|
970
|
+
} catch {
|
|
971
|
+
return void 0;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
function groupCorpusPath(id) {
|
|
975
|
+
if (id.startsWith("notebook.")) {
|
|
976
|
+
const slug = id.slice("notebook.".length);
|
|
977
|
+
return slug === "_root" ? "markdown/notebooks" : `markdown/notebooks/${slug}`;
|
|
978
|
+
}
|
|
979
|
+
return `markdown/${id}`;
|
|
980
|
+
}
|
|
981
|
+
function frontmatterDateToCreatedAt(raw, path) {
|
|
982
|
+
const value = wodWikiCore.getScalar(wodWikiCore.parseFrontmatter(raw).meta, "date");
|
|
983
|
+
if (value === void 0 || value === "") return void 0;
|
|
984
|
+
const text = String(value);
|
|
985
|
+
const parts = text.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
986
|
+
const ts = parts ? Date.parse(`${text}T12:00:00Z`) : NaN;
|
|
987
|
+
const valid = !!parts && Number.isFinite(ts) && new Date(ts).getUTCMonth() === Number(parts[2]) - 1 && new Date(ts).getUTCDate() === Number(parts[3]);
|
|
988
|
+
if (!valid) {
|
|
989
|
+
throw new Error(`[wod build] invalid frontmatter date '${text}' in '${path}' \u2014 expected a real calendar day (YYYY-MM-DD)`);
|
|
990
|
+
}
|
|
991
|
+
return ts;
|
|
992
|
+
}
|
|
993
|
+
function dateKeyToCreatedAt(dateKey) {
|
|
994
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(dateKey)) return 0;
|
|
995
|
+
const ts = Date.parse(`${dateKey}T00:00:00Z`);
|
|
996
|
+
return Number.isNaN(ts) ? 0 : ts;
|
|
997
|
+
}
|
|
998
|
+
function compileCompanionTelemetry(path, jsonl, blockIndex) {
|
|
999
|
+
const firstWod = blockIndex.find((block) => block.dataType === "wod");
|
|
1000
|
+
const noteId = seedNoteIdSync(path);
|
|
1001
|
+
const normalized = jsonl.split(/\r?\n/).map((line) => {
|
|
1002
|
+
if (!line.trim()) return line;
|
|
1003
|
+
const parsed2 = JSON.parse(line);
|
|
1004
|
+
if (typeof parsed2 !== "object" || parsed2 === null || Array.isArray(parsed2)) return line;
|
|
1005
|
+
const record = { ...parsed2, noteId };
|
|
1006
|
+
if (record.kind === "session" || record.kind === "event") {
|
|
1007
|
+
if (!firstWod) throw new Error(`Telemetry for '${path}' requires a wod block`);
|
|
1008
|
+
if (record.blockId === void 0 || record.blockId === "@first-wod") record.blockId = firstWod.blockId;
|
|
1009
|
+
if (record.blockVersion === void 0 || record.blockVersion === "@first-wod") record.blockVersion = firstWod.blockVersion;
|
|
1010
|
+
if (record.blockContentId === void 0 || record.blockContentId === "@first-wod") record.blockContentId = firstWod.blockContentId;
|
|
1011
|
+
}
|
|
1012
|
+
return JSON.stringify(record);
|
|
1013
|
+
}).join("\n");
|
|
1014
|
+
const parsed = wodWikiCore.parseNoteBundleFromJsonl(normalized);
|
|
1015
|
+
if (parsed.errors.length > 0) throw new Error(`Invalid telemetry companion '${path}': ${parsed.errors.join("; ")}`);
|
|
1016
|
+
return {
|
|
1017
|
+
sessions: parsed.bundles.flatMap((bundle) => bundle.sessions),
|
|
1018
|
+
events: parsed.bundles.flatMap((bundle) => bundle.events)
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
function compileSeedRow(path, content, metadata = {}) {
|
|
1022
|
+
let ordinal = 0;
|
|
1023
|
+
const blocks = wodWikiCore.reconcileNoteBlocks(content, { sourceRevision: 1, registeredWidgets: contract_exports.SEED_REGISTERED_WIDGETS, createId: () => `seed:${path}:${ordinal++}` });
|
|
1024
|
+
const noteId = metadata.routeId ?? path;
|
|
1025
|
+
const sections = wodWikiCore.parseDocumentSections(content);
|
|
1026
|
+
const blockIndex = Object.values(blocks).map((block, position) => {
|
|
1027
|
+
const section = sections.find((section2) => section2.from === block.from && section2.to === block.to);
|
|
1028
|
+
return { id: `${noteId}:${block.id}`, noteId, blockId: block.id, blockVersion: 1, sourceRevision: 1, from: block.from, to: block.to, position, dataType: block.kind, ...block.kind === "wod" ? { blockContentId: wodWikiCore.blockContentId(section?.scriptBlock?.content ?? content.slice(block.from, block.to)) } : {}, rawContent: content.slice(block.from, block.to), noteTitle: metadata.noteTitle ?? fileToDisplayName(path.split("/").at(-1) ?? path), createdAt: metadata.createdAt ?? 0, isStatic: true, sourceId: metadata.sourceId, sourcePath: path, routeId: metadata.routeId };
|
|
1029
|
+
});
|
|
1030
|
+
const telemetry = metadata.telemetryJsonl === void 0 ? void 0 : compileCompanionTelemetry(path, metadata.telemetryJsonl, blockIndex);
|
|
1031
|
+
return { path, content, blocks, blockIndex, blockEfforts: [], blockEquipment: [], ...telemetry ? { telemetry } : {} };
|
|
1032
|
+
}
|
|
1033
|
+
function buildBlockIndexRows(markdownDir, corpusRoot, excludePaths = []) {
|
|
1034
|
+
const rows = [];
|
|
1035
|
+
for (const path$1 of collectCorpusMarkdown(markdownDir, excludePaths)) {
|
|
1036
|
+
const chunkId = chunkIdFor(path$1);
|
|
1037
|
+
if (!chunkId) continue;
|
|
1038
|
+
const content = fs.readFileSync(path.join(corpusRoot, path$1), "utf8");
|
|
1039
|
+
const parts = path$1.split("/");
|
|
1040
|
+
const stem = (parts.at(-1) ?? "").replace(/\.md$/, "");
|
|
1041
|
+
const slug = parts[2];
|
|
1042
|
+
const routeId = chunkId === "canvas" ? (0, contract_exports.canvasRouteSlug)(content) ?? void 0 : chunkId.startsWith("notebook.") ? stem.toLowerCase() === "readme" ? slug : parts.slice(2).join("/").replace(/\.md$/, "") : void 0;
|
|
1043
|
+
const sourceId = (0, contract_exports.seedNoteSourceId)(path$1, content, chunkId);
|
|
1044
|
+
const createdAt = frontmatterDateToCreatedAt(content, path$1) ?? (chunkId.startsWith("notebook.") && /^\d{4}-\d{2}-\d{2}$/.test(parts.at(-2) ?? "") ? dateKeyToCreatedAt(parts.at(-2) ?? "") : getFileCreatedAt(path$1, corpusRoot));
|
|
1045
|
+
rows.push(...compileSeedRow(path$1, content, { routeId, sourceId, createdAt }).blockIndex);
|
|
1046
|
+
}
|
|
1047
|
+
return rows;
|
|
1048
|
+
}
|
|
1049
|
+
function validateWodBlockSyntax(blocks) {
|
|
1050
|
+
const problems = [];
|
|
1051
|
+
for (const block of blocks) {
|
|
1052
|
+
if (block.dataType !== "wod" || !block.rawContent?.trim()) continue;
|
|
1053
|
+
const section = wodWikiCore.parseDocumentSections(block.rawContent, { registeredWidgets: contract_exports.SEED_REGISTERED_WIDGETS }).find((s) => s.scriptBlock);
|
|
1054
|
+
const source = section?.scriptBlock?.content ?? block.rawContent;
|
|
1055
|
+
if (!source.trim()) continue;
|
|
1056
|
+
const where = block.sourcePath ?? block.noteId;
|
|
1057
|
+
if (section?.sport) {
|
|
1058
|
+
const parsed = wodWikiLang.parseScript(source, { sport: section.sport });
|
|
1059
|
+
for (const error of parsed.errors ?? []) {
|
|
1060
|
+
problems.push(`${where}: ${error.message}`);
|
|
1061
|
+
}
|
|
1062
|
+
continue;
|
|
1063
|
+
}
|
|
1064
|
+
const doc = source.endsWith("\n") ? source : source + "\n";
|
|
1065
|
+
const tree = wodWikiLang.whiteboardParser.parse(doc);
|
|
1066
|
+
tree.iterate({
|
|
1067
|
+
enter: (node) => {
|
|
1068
|
+
if (!node.type.isError) return;
|
|
1069
|
+
const line = doc.slice(0, node.from).split("\n").length;
|
|
1070
|
+
const snippet = source.slice(node.from, Math.min(node.to, node.from + 60)).split("\n")[0];
|
|
1071
|
+
problems.push(`${where}:${line} \`${snippet}\``);
|
|
1072
|
+
}
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
return problems;
|
|
1076
|
+
}
|
|
1077
|
+
function formatDiscoveredLabel(raw) {
|
|
1078
|
+
const clean = raw.replace(/[-_]+/g, " ").trim();
|
|
1079
|
+
return clean.split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ");
|
|
1080
|
+
}
|
|
1081
|
+
function loadCorpusReferenceCatalog(markdownDir) {
|
|
1082
|
+
const efforts = [];
|
|
1083
|
+
const equipment = [];
|
|
1084
|
+
const effortsDir = path.join(markdownDir, "efforts");
|
|
1085
|
+
for (const file of listMarkdownFiles(effortsDir)) {
|
|
1086
|
+
const parsed = wodWikiLang.parseEffortFile(fs.readFileSync(path.join(effortsDir, file), "utf8"));
|
|
1087
|
+
if (parsed) efforts.push(parsed);
|
|
1088
|
+
}
|
|
1089
|
+
const equipmentDir = path.join(markdownDir, "equipment");
|
|
1090
|
+
for (const file of listMarkdownFiles(equipmentDir)) {
|
|
1091
|
+
const parsed = wodWikiLang.parseEquipmentFile(fs.readFileSync(path.join(equipmentDir, file), "utf8"));
|
|
1092
|
+
if (parsed) equipment.push(parsed);
|
|
1093
|
+
}
|
|
1094
|
+
return { efforts, equipment };
|
|
737
1095
|
}
|
|
738
1096
|
function discoverUncatalogedEfforts(markdownDir, corpusRoot, excludePaths = []) {
|
|
739
1097
|
const catalog = loadCorpusReferenceCatalog(markdownDir);
|
|
@@ -913,434 +1271,168 @@ ${shown}${more}`);
|
|
|
913
1271
|
}
|
|
914
1272
|
for (const row of effortRows) {
|
|
915
1273
|
const rows = effortsByPath.get(row.sourcePath) ?? [];
|
|
916
|
-
rows.push(row);
|
|
917
|
-
effortsByPath.set(row.sourcePath, rows);
|
|
918
|
-
}
|
|
919
|
-
for (const row of equipmentRows) {
|
|
920
|
-
const rows = equipmentByPath.get(row.sourcePath) ?? [];
|
|
921
|
-
rows.push(row);
|
|
922
|
-
equipmentByPath.set(row.sourcePath, rows);
|
|
923
|
-
}
|
|
924
|
-
let totalFiles = 0;
|
|
925
|
-
const manifestNotebooks = [];
|
|
926
|
-
const manifestBuiltAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
927
|
-
const tWrite = Date.now();
|
|
928
|
-
for (const { id, files } of groups) {
|
|
929
|
-
const records = [];
|
|
930
|
-
const rows = files.map((p) => {
|
|
931
|
-
const raw = fs.readFileSync(path.join(corpusRoot, p), "utf8");
|
|
932
|
-
const content = raw;
|
|
933
|
-
const compiled = compileSeedRow(p, content);
|
|
934
|
-
compiled.blockIndex = blocksByPath.get(p) ?? compiled.blockIndex;
|
|
935
|
-
compiled.blockEfforts = effortsByPath.get(p) ?? [];
|
|
936
|
-
compiled.blockEquipment = equipmentByPath.get(p) ?? [];
|
|
937
|
-
const fileCommit = getFileCommit(p, corpusRoot) || gitVersion.commit || "";
|
|
938
|
-
const fileVer = getFileVersion(p, corpusRoot);
|
|
939
|
-
const uuid = seedNoteIdSync(p);
|
|
940
|
-
compiled.commit = fileCommit;
|
|
941
|
-
compiled.uuid = uuid;
|
|
942
|
-
compiled.version = fileVer;
|
|
943
|
-
const recordRelPath = p.replace(/\.md$/, ".json");
|
|
944
|
-
const recordOutFile = path.join(outDir, recordRelPath);
|
|
945
|
-
fs.mkdirSync(path.dirname(recordOutFile), { recursive: true });
|
|
946
|
-
const recordBytes = Buffer.from(JSON.stringify(compiled, null, 2), "utf8");
|
|
947
|
-
fs.writeFileSync(recordOutFile, recordBytes);
|
|
948
|
-
const title = compiled.blockIndex[0]?.noteTitle ?? fileToDisplayName(p.split("/").at(-1) ?? p);
|
|
949
|
-
records.push({
|
|
950
|
-
uuid,
|
|
951
|
-
path: p,
|
|
952
|
-
recordPath: recordRelPath,
|
|
953
|
-
commit: fileCommit,
|
|
954
|
-
version: fileVer,
|
|
955
|
-
sha256: sha256Hex(recordBytes),
|
|
956
|
-
title,
|
|
957
|
-
date: frontmatterDateToCreatedAt(content, p)
|
|
958
|
-
});
|
|
959
|
-
return compiled;
|
|
960
|
-
});
|
|
961
|
-
(0, validation_exports.assertSeedRows)(rows);
|
|
962
|
-
const bytes = Buffer.from(JSON.stringify(rows), "utf8");
|
|
963
|
-
const sha = sha256Hex(bytes);
|
|
964
|
-
const file = `chunks/${id}.${sha.slice(0, 8)}.json`;
|
|
965
|
-
fs.writeFileSync(path.join(outDir, file), bytes);
|
|
966
|
-
manifestChunks.push({ id, path: file, sha256: sha, bytes: bytes.length, count: rows.length });
|
|
967
|
-
totalFiles += rows.length;
|
|
968
|
-
const groupPath = groupCorpusPath(id);
|
|
969
|
-
const groupVersion = getPathVersion(groupPath, corpusRoot);
|
|
970
|
-
const groupCommit = getPathCommit(groupPath, corpusRoot) || gitVersion.commit || "";
|
|
971
|
-
const groupUpdatedAt = getPathUpdatedAt(groupPath, corpusRoot);
|
|
972
|
-
const notebookIndexPath = `indexes/notebooks/${id}.json`;
|
|
973
|
-
const summary = {
|
|
974
|
-
notebookId: id,
|
|
975
|
-
label: fileToDisplayName(id.split(".").at(-1) ?? id),
|
|
976
|
-
category: (0, contract_exports.notebookSlugForChunkId)(id),
|
|
977
|
-
indexPath: notebookIndexPath,
|
|
978
|
-
version: groupVersion,
|
|
979
|
-
commit: groupCommit,
|
|
980
|
-
updatedAt: groupUpdatedAt,
|
|
981
|
-
builtAt: manifestBuiltAt,
|
|
982
|
-
sha256: sha,
|
|
983
|
-
bytes: bytes.length,
|
|
984
|
-
count: rows.length
|
|
985
|
-
};
|
|
986
|
-
const notebookIndex = {
|
|
987
|
-
...summary,
|
|
988
|
-
records
|
|
989
|
-
};
|
|
990
|
-
(0, validation_exports.assertNotebookIndex)(notebookIndex);
|
|
991
|
-
const indexOutFile = path.join(outDir, notebookIndexPath);
|
|
992
|
-
fs.mkdirSync(path.dirname(indexOutFile), { recursive: true });
|
|
993
|
-
fs.writeFileSync(indexOutFile, JSON.stringify(notebookIndex, null, 2) + "\n");
|
|
994
|
-
manifestNotebooks.push(summary);
|
|
995
|
-
}
|
|
996
|
-
passMs.write = Date.now() - tWrite;
|
|
997
|
-
const manifest = {
|
|
998
|
-
name: "name" in metadata && typeof metadata.name === "string" ? metadata.name : void 0,
|
|
999
|
-
description: "description" in metadata && typeof metadata.description === "string" ? metadata.description : void 0,
|
|
1000
|
-
repositoryUrl: repositoryLink?.protocol === "https:" && !repositoryLink.username && !repositoryLink.password ? repositoryLink.href : void 0,
|
|
1001
|
-
schema: contract_exports.SEED_SCHEMA,
|
|
1002
|
-
version: gitVersion.version,
|
|
1003
|
-
versionLabel: gitVersion.versionLabel,
|
|
1004
|
-
commit: gitVersion.commit,
|
|
1005
|
-
dirty: gitVersion.dirty,
|
|
1006
|
-
builtAt: manifestBuiltAt,
|
|
1007
|
-
chunks: manifestChunks,
|
|
1008
|
-
notebooks: manifestNotebooks
|
|
1009
|
-
};
|
|
1010
|
-
(0, validation_exports.assertSeedManifest)(manifest);
|
|
1011
|
-
fs.writeFileSync(path.join(outDir, "manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
1012
|
-
const reportPath = writeBuildReport(outDir, {
|
|
1013
|
-
manifest,
|
|
1014
|
-
totalMs: Date.now() - t0,
|
|
1015
|
-
passMs,
|
|
1016
|
-
fileCount: paths.length});
|
|
1017
|
-
return { manifest, outDir, totalFiles, reportPath, passMs };
|
|
1018
|
-
}
|
|
1019
|
-
var NON_EFFORT_SLUGS;
|
|
1020
|
-
var init_compiler = __esm({
|
|
1021
|
-
"src/seedbuild/compiler.ts"() {
|
|
1022
|
-
init_contract();
|
|
1023
|
-
init_filename();
|
|
1024
|
-
init_git_version();
|
|
1025
|
-
init_report();
|
|
1026
|
-
init_frontmatter();
|
|
1027
|
-
init_validation();
|
|
1028
|
-
NON_EFFORT_SLUGS = {
|
|
1029
|
-
"amrap": true,
|
|
1030
|
-
"emom": true,
|
|
1031
|
-
"tabata": true,
|
|
1032
|
-
"for-time": true,
|
|
1033
|
-
"rounds": true,
|
|
1034
|
-
"sets": true,
|
|
1035
|
-
"repetitions": true,
|
|
1036
|
-
"count-down": true,
|
|
1037
|
-
"total-reps": true,
|
|
1038
|
-
"warmup": true,
|
|
1039
|
-
"cooldown": true,
|
|
1040
|
-
"cool-down": true,
|
|
1041
|
-
"transition": true,
|
|
1042
|
-
"rest": true,
|
|
1043
|
-
"break": true,
|
|
1044
|
-
"work": true,
|
|
1045
|
-
"i-suck-at-this": true,
|
|
1046
|
-
"isuckatthis": true,
|
|
1047
|
-
"movement": true,
|
|
1048
|
-
"movement-you": true,
|
|
1049
|
-
"selected-exercise": true,
|
|
1050
|
-
"training-setup": true,
|
|
1051
|
-
"grade-system": true,
|
|
1052
|
-
"hangs": true,
|
|
1053
|
-
"warm-light-wind": true,
|
|
1054
|
-
"basin": true,
|
|
1055
|
-
"rock-canyon": true,
|
|
1056
|
-
"b-onsight": true,
|
|
1057
|
-
"a-redpoint": true,
|
|
1058
|
-
"d-redpoint": true,
|
|
1059
|
-
"v0-flash": true,
|
|
1060
|
-
"v2-flash": true,
|
|
1061
|
-
"v7-redpoint": true,
|
|
1062
|
-
"avgrpe-mean": true,
|
|
1063
|
-
"calculate": true,
|
|
1064
|
-
"totalload-sum": true,
|
|
1065
|
-
"query": true,
|
|
1066
|
-
"by": true,
|
|
1067
|
-
"": true,
|
|
1068
|
-
"-": true,
|
|
1069
|
-
"...": true,
|
|
1070
|
-
"x": true,
|
|
1071
|
-
"s": true,
|
|
1072
|
-
"bw": true
|
|
1073
|
-
};
|
|
1074
|
-
}
|
|
1075
|
-
});
|
|
1076
|
-
|
|
1077
|
-
// src/version.ts
|
|
1078
|
-
var VERSION;
|
|
1079
|
-
var init_version = __esm({
|
|
1080
|
-
"src/version.ts"() {
|
|
1081
|
-
VERSION = "0.51.2196";
|
|
1082
|
-
}
|
|
1083
|
-
});
|
|
1084
|
-
|
|
1085
|
-
// src/cli/scaffoldFeed.ts
|
|
1086
|
-
var scaffoldFeed_exports = {};
|
|
1087
|
-
__export(scaffoldFeed_exports, {
|
|
1088
|
-
scaffoldFeed: () => scaffoldFeed,
|
|
1089
|
-
validateFeedName: () => validateFeedName
|
|
1090
|
-
});
|
|
1091
|
-
function validateFeedName(name) {
|
|
1092
|
-
if (name.length === 0 || name === "." || name === "..") {
|
|
1093
|
-
throw new Error("Feed name must be a single non-empty directory name");
|
|
1094
|
-
}
|
|
1095
|
-
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
|
1096
|
-
throw new Error(`Invalid feed name '${name}': must be a single directory name (no path separators or traversal)`);
|
|
1097
|
-
}
|
|
1098
|
-
if (/^(?:[A-Za-z]:)?[/\\]/.test(name)) {
|
|
1099
|
-
throw new Error(`Invalid feed name '${name}': absolute paths are not allowed`);
|
|
1100
|
-
}
|
|
1101
|
-
if (name.length > 214 || !/^[a-z0-9][a-z0-9._-]*$/.test(name)) {
|
|
1102
|
-
throw new Error(
|
|
1103
|
-
`Invalid feed name '${name}': must be a valid npm package name (lowercase letters, digits, dots, hyphens, underscores; no leading dot/hyphen)`
|
|
1104
|
-
);
|
|
1105
|
-
}
|
|
1106
|
-
return name;
|
|
1107
|
-
}
|
|
1108
|
-
function scaffoldFeed(name, opts = {}) {
|
|
1109
|
-
validateFeedName(name);
|
|
1110
|
-
const dir = path.resolve(opts.cwd ?? process.cwd(), name);
|
|
1111
|
-
try {
|
|
1112
|
-
fs.mkdirSync(dir);
|
|
1113
|
-
} catch (error) {
|
|
1114
|
-
if (error.code === "EEXIST") {
|
|
1115
|
-
throw new Error(`Refusing to overwrite '${dir}': destination already exists`, { cause: error });
|
|
1116
|
-
}
|
|
1117
|
-
throw error;
|
|
1118
|
-
}
|
|
1119
|
-
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1120
|
-
const files = [
|
|
1121
|
-
["package.json", `${JSON.stringify(
|
|
1122
|
-
{
|
|
1123
|
-
name,
|
|
1124
|
-
version: "0.1.0",
|
|
1125
|
-
private: true,
|
|
1126
|
-
type: "module",
|
|
1127
|
-
description: `WOD Wiki workout feed: ${name}`,
|
|
1128
|
-
scripts: {
|
|
1129
|
-
build: "wod build . --output dist"
|
|
1130
|
-
},
|
|
1131
|
-
devDependencies: {
|
|
1132
|
-
"@bitcobblers/wod-wiki-tools": `^${VERSION}`
|
|
1133
|
-
}
|
|
1134
|
-
},
|
|
1135
|
-
null,
|
|
1136
|
-
2
|
|
1137
|
-
)}
|
|
1138
|
-
`],
|
|
1139
|
-
[".gitignore", "node_modules/\ndist/\n"],
|
|
1140
|
-
[".github/workflows/publish-feed.yml", publishWorkflow()],
|
|
1141
|
-
["markdown/notebooks/example/README.md", feedReadme(name)],
|
|
1142
|
-
[`markdown/notebooks/example/morning-session.md`, exampleWorkout(date)],
|
|
1143
|
-
["README.md", repoReadme(name)]
|
|
1144
|
-
];
|
|
1145
|
-
try {
|
|
1146
|
-
for (const [rel, content] of files) {
|
|
1147
|
-
const target = path.join(dir, rel);
|
|
1148
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
1149
|
-
fs.writeFileSync(target, content, "utf-8");
|
|
1150
|
-
}
|
|
1151
|
-
} catch (error) {
|
|
1152
|
-
fs.rmSync(dir, { recursive: true, force: true });
|
|
1153
|
-
throw error;
|
|
1154
|
-
}
|
|
1155
|
-
return { dir, files: files.map(([rel]) => rel) };
|
|
1156
|
-
}
|
|
1157
|
-
var publishWorkflow, feedReadme, exampleWorkout, repoReadme;
|
|
1158
|
-
var init_scaffoldFeed = __esm({
|
|
1159
|
-
"src/cli/scaffoldFeed.ts"() {
|
|
1160
|
-
init_version();
|
|
1161
|
-
publishWorkflow = () => `name: Publish feed
|
|
1162
|
-
|
|
1163
|
-
# Compile the feed with the wod CLI and deploy dist/ to GitHub Pages.
|
|
1164
|
-
# Requires Pages enabled: repo Settings \u2192 Pages \u2192 Source: "GitHub Actions".
|
|
1165
|
-
|
|
1166
|
-
on:
|
|
1167
|
-
push:
|
|
1168
|
-
branches: [main]
|
|
1169
|
-
workflow_dispatch:
|
|
1170
|
-
|
|
1171
|
-
permissions:
|
|
1172
|
-
contents: read
|
|
1173
|
-
pages: write
|
|
1174
|
-
id-token: write
|
|
1175
|
-
|
|
1176
|
-
concurrency:
|
|
1177
|
-
group: pages
|
|
1178
|
-
cancel-in-progress: true
|
|
1179
|
-
|
|
1180
|
-
jobs:
|
|
1181
|
-
publish:
|
|
1182
|
-
runs-on: ubuntu-latest
|
|
1183
|
-
environment:
|
|
1184
|
-
name: github-pages
|
|
1185
|
-
url: \${{ steps.deployment.outputs.page_url }}
|
|
1186
|
-
steps:
|
|
1187
|
-
- uses: actions/checkout@v4
|
|
1188
|
-
with:
|
|
1189
|
-
# Full history: seed manifest version stamps derive from git commit count.
|
|
1190
|
-
fetch-depth: 0
|
|
1191
|
-
|
|
1192
|
-
- name: Set up Bun
|
|
1193
|
-
uses: oven-sh/setup-bun@v2
|
|
1194
|
-
with:
|
|
1195
|
-
bun-version: 1.4.x
|
|
1196
|
-
|
|
1197
|
-
- name: Install dependencies
|
|
1198
|
-
run: bun install
|
|
1199
|
-
|
|
1200
|
-
- name: Build seed
|
|
1201
|
-
run: bunx wod build . --output dist
|
|
1202
|
-
|
|
1203
|
-
- uses: actions/configure-pages@v5
|
|
1204
|
-
|
|
1205
|
-
- name: Upload dist
|
|
1206
|
-
uses: actions/upload-pages-artifact@v3
|
|
1207
|
-
with:
|
|
1208
|
-
path: dist
|
|
1209
|
-
|
|
1210
|
-
- id: deployment
|
|
1211
|
-
uses: actions/deploy-pages@v4
|
|
1212
|
-
`;
|
|
1213
|
-
feedReadme = (name) => `# ${name}
|
|
1214
|
-
|
|
1215
|
-
Example benchmark notebook. Each \`.md\` file in this directory becomes part of
|
|
1216
|
-
the \`example\` notebook chunk; \`README.md\` is the notebook's landing page.
|
|
1217
|
-
|
|
1218
|
-
Add one file per workout:
|
|
1219
|
-
|
|
1220
|
-
\`\`\`\`markdown
|
|
1221
|
-
---
|
|
1222
|
-
title: My workout
|
|
1223
|
-
date: 2026-01-01
|
|
1224
|
-
---
|
|
1225
|
-
|
|
1226
|
-
# My workout
|
|
1227
|
-
|
|
1228
|
-
\`\`\`time
|
|
1229
|
-
(21-15-9)
|
|
1230
|
-
Thrusters @95lb
|
|
1231
|
-
Pull-ups
|
|
1232
|
-
\`\`\`
|
|
1233
|
-
\`\`\`\`
|
|
1234
|
-
|
|
1235
|
-
The \`date:\` frontmatter field sets the workout's chronological placement
|
|
1236
|
-
(regardless of filename or directory).
|
|
1237
|
-
`;
|
|
1238
|
-
exampleWorkout = (date) => `---
|
|
1239
|
-
title: Morning session
|
|
1240
|
-
date: ${date}
|
|
1241
|
-
---
|
|
1242
|
-
|
|
1243
|
-
# Morning session
|
|
1244
|
-
|
|
1245
|
-
\`\`\`time
|
|
1246
|
-
(21-15-9)
|
|
1247
|
-
Thrusters @95lb
|
|
1248
|
-
Pull-ups
|
|
1249
|
-
\`\`\`
|
|
1250
|
-
`;
|
|
1251
|
-
repoReadme = (name) => `# ${name}
|
|
1252
|
-
|
|
1253
|
-
A [WOD Wiki](https://github.com/bitcobblers/wod-wiki) workout feed: plain
|
|
1254
|
-
Markdown workouts compiled to static, version-stamped seed chunks and published
|
|
1255
|
-
via GitHub Pages.
|
|
1256
|
-
|
|
1257
|
-
## Develop
|
|
1258
|
-
|
|
1259
|
-
\`\`\`sh
|
|
1260
|
-
bun install
|
|
1261
|
-
bunx wod build . --output dist
|
|
1262
|
-
\`\`\`
|
|
1263
|
-
|
|
1264
|
-
Workouts live under \`markdown/\` \u2014 this scaffold starts with one example
|
|
1265
|
-
feed. Validate everything with \`bunx wod build\`: it gates every file on
|
|
1266
|
-
the Whiteboard grammar and corpus layout before writing \`dist/\`.
|
|
1267
|
-
|
|
1268
|
-
## Publish
|
|
1269
|
-
|
|
1270
|
-
Push to GitHub and enable Pages (**Settings \u2192 Pages \u2192 Source: GitHub
|
|
1271
|
-
Actions**). The bundled workflow (\`.github/workflows/publish-feed.yml\`)
|
|
1272
|
-
builds the feed on every push to \`main\` and deploys \`dist/\`.
|
|
1273
|
-
|
|
1274
|
-
## Share
|
|
1275
|
-
|
|
1276
|
-
Once published, anyone can subscribe to this feed from a WOD Wiki instance
|
|
1277
|
-
at:
|
|
1278
|
-
|
|
1279
|
-
\`\`\`
|
|
1280
|
-
<app-url>/subscribe?source=<url-encoded published feed URL>
|
|
1281
|
-
\`\`\`
|
|
1282
|
-
|
|
1283
|
-
For \`owner\`/\`repo\` on GitHub Pages the feed URL is the deployed
|
|
1284
|
-
directory, \`https://owner.github.io/repo/\`, e.g.
|
|
1285
|
-
\`/subscribe?source=https%3A%2F%2Fowner.github.io%2Frepo%2F\`.
|
|
1286
|
-
`;
|
|
1274
|
+
rows.push(row);
|
|
1275
|
+
effortsByPath.set(row.sourcePath, rows);
|
|
1287
1276
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
__export(skills_exports, {
|
|
1293
|
-
bundledSkillsRoot: () => bundledSkillsRoot,
|
|
1294
|
-
installSkills: () => installSkills,
|
|
1295
|
-
listBundledSkills: () => listBundledSkills
|
|
1296
|
-
});
|
|
1297
|
-
function frontmatterField(source, key) {
|
|
1298
|
-
const match = source.match(new RegExp(`^${key}:[ ]*(.*)$`, "m"));
|
|
1299
|
-
return match?.[1].trim().replace(/^(['"])(.*)\1$/, "$2") || void 0;
|
|
1300
|
-
}
|
|
1301
|
-
function listBundledSkills(root) {
|
|
1302
|
-
if (!fs.existsSync(root)) return [];
|
|
1303
|
-
return fs.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory() && fs.existsSync(path.join(root, entry.name, "SKILL.md"))).sort((a, b) => a.name.localeCompare(b.name)).map((entry) => {
|
|
1304
|
-
const source = fs.readFileSync(path.join(root, entry.name, "SKILL.md"), "utf-8");
|
|
1305
|
-
return {
|
|
1306
|
-
name: entry.name,
|
|
1307
|
-
description: frontmatterField(source, "description") ?? "",
|
|
1308
|
-
path: path.join(root, entry.name)
|
|
1309
|
-
};
|
|
1310
|
-
});
|
|
1311
|
-
}
|
|
1312
|
-
function bundledSkillsRoot() {
|
|
1313
|
-
const scriptDir = path.dirname(fs.realpathSync(process.argv[1] ?? process.cwd()));
|
|
1314
|
-
const candidates = ["skills", "../skills", "../../skills", "../../../skills", "../../../../skills"].map(
|
|
1315
|
-
(rel) => path.resolve(scriptDir, rel)
|
|
1316
|
-
);
|
|
1317
|
-
return candidates.find((candidate) => listBundledSkills(candidate).length > 0);
|
|
1318
|
-
}
|
|
1319
|
-
function installSkills(options = {}) {
|
|
1320
|
-
const root = options.root ?? bundledSkillsRoot();
|
|
1321
|
-
if (!root) {
|
|
1322
|
-
throw new Error("no bundled skills found next to this CLI \u2014 reinstall the package or run from the wod-wiki checkout");
|
|
1277
|
+
for (const row of equipmentRows) {
|
|
1278
|
+
const rows = equipmentByPath.get(row.sourcePath) ?? [];
|
|
1279
|
+
rows.push(row);
|
|
1280
|
+
equipmentByPath.set(row.sourcePath, rows);
|
|
1323
1281
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
const
|
|
1327
|
-
const
|
|
1328
|
-
const
|
|
1329
|
-
|
|
1330
|
-
const
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1282
|
+
let totalFiles = 0;
|
|
1283
|
+
const manifestNotebooks = [];
|
|
1284
|
+
const manifestBuiltAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1285
|
+
const tWrite = Date.now();
|
|
1286
|
+
for (const { id, files } of groups) {
|
|
1287
|
+
const records = [];
|
|
1288
|
+
const rows = files.map((p) => {
|
|
1289
|
+
const raw = fs.readFileSync(path.join(corpusRoot, p), "utf8");
|
|
1290
|
+
const content = raw;
|
|
1291
|
+
const companionPath = path.join(corpusRoot, p.replace(/\.md$/, ".jsonl"));
|
|
1292
|
+
const compiled = compileSeedRow(p, content, { telemetryJsonl: fs.existsSync(companionPath) ? fs.readFileSync(companionPath, "utf8") : void 0 });
|
|
1293
|
+
compiled.blockIndex = blocksByPath.get(p) ?? compiled.blockIndex;
|
|
1294
|
+
compiled.blockEfforts = effortsByPath.get(p) ?? [];
|
|
1295
|
+
compiled.blockEquipment = equipmentByPath.get(p) ?? [];
|
|
1296
|
+
const fileCommit = getFileCommit(p, corpusRoot) || gitVersion.commit || "";
|
|
1297
|
+
const fileVer = getFileVersion(p, corpusRoot);
|
|
1298
|
+
const uuid = seedNoteIdSync(p);
|
|
1299
|
+
compiled.commit = fileCommit;
|
|
1300
|
+
compiled.uuid = uuid;
|
|
1301
|
+
compiled.version = fileVer;
|
|
1302
|
+
const recordRelPath = p.replace(/\.md$/, ".json");
|
|
1303
|
+
const recordOutFile = path.join(outDir, recordRelPath);
|
|
1304
|
+
fs.mkdirSync(path.dirname(recordOutFile), { recursive: true });
|
|
1305
|
+
const recordBytes = Buffer.from(JSON.stringify(compiled, null, 2), "utf8");
|
|
1306
|
+
fs.writeFileSync(recordOutFile, recordBytes);
|
|
1307
|
+
if (compiled.telemetry) {
|
|
1308
|
+
fs.writeFileSync(path.join(outDir, p.replace(/\.md$/, ".jsonl")), wodWikiCore.serializeNoteBundleToJsonl(compiled.telemetry) + "\n");
|
|
1309
|
+
}
|
|
1310
|
+
const title = compiled.blockIndex[0]?.noteTitle ?? fileToDisplayName(p.split("/").at(-1) ?? p);
|
|
1311
|
+
records.push({
|
|
1312
|
+
uuid,
|
|
1313
|
+
path: p,
|
|
1314
|
+
recordPath: recordRelPath,
|
|
1315
|
+
commit: fileCommit,
|
|
1316
|
+
version: fileVer,
|
|
1317
|
+
sha256: sha256Hex(recordBytes),
|
|
1318
|
+
title,
|
|
1319
|
+
date: frontmatterDateToCreatedAt(content, p)
|
|
1320
|
+
});
|
|
1321
|
+
return compiled;
|
|
1322
|
+
});
|
|
1323
|
+
(0, validation_exports.assertSeedRows)(rows);
|
|
1324
|
+
const bytes = Buffer.from(JSON.stringify(rows), "utf8");
|
|
1325
|
+
const sha = sha256Hex(bytes);
|
|
1326
|
+
const file = `chunks/${id}.${sha.slice(0, 8)}.json`;
|
|
1327
|
+
fs.writeFileSync(path.join(outDir, file), bytes);
|
|
1328
|
+
manifestChunks.push({ id, path: file, sha256: sha, bytes: bytes.length, count: rows.length });
|
|
1329
|
+
totalFiles += rows.length;
|
|
1330
|
+
const groupPath = groupCorpusPath(id);
|
|
1331
|
+
const groupVersion = getPathVersion(groupPath, corpusRoot);
|
|
1332
|
+
const groupCommit = getPathCommit(groupPath, corpusRoot) || gitVersion.commit || "";
|
|
1333
|
+
const groupUpdatedAt = getPathUpdatedAt(groupPath, corpusRoot);
|
|
1334
|
+
const notebookIndexPath = `indexes/notebooks/${id}.json`;
|
|
1335
|
+
const summary = {
|
|
1336
|
+
notebookId: id,
|
|
1337
|
+
label: fileToDisplayName(id.split(".").at(-1) ?? id),
|
|
1338
|
+
category: (0, contract_exports.notebookSlugForChunkId)(id),
|
|
1339
|
+
indexPath: notebookIndexPath,
|
|
1340
|
+
version: groupVersion,
|
|
1341
|
+
commit: groupCommit,
|
|
1342
|
+
updatedAt: groupUpdatedAt,
|
|
1343
|
+
builtAt: manifestBuiltAt,
|
|
1344
|
+
sha256: sha,
|
|
1345
|
+
bytes: bytes.length,
|
|
1346
|
+
count: rows.length
|
|
1347
|
+
};
|
|
1348
|
+
const notebookIndex = {
|
|
1349
|
+
...summary,
|
|
1350
|
+
records
|
|
1351
|
+
};
|
|
1352
|
+
(0, validation_exports.assertNotebookIndex)(notebookIndex);
|
|
1353
|
+
const indexOutFile = path.join(outDir, notebookIndexPath);
|
|
1354
|
+
fs.mkdirSync(path.dirname(indexOutFile), { recursive: true });
|
|
1355
|
+
fs.writeFileSync(indexOutFile, JSON.stringify(notebookIndex, null, 2) + "\n");
|
|
1356
|
+
manifestNotebooks.push(summary);
|
|
1339
1357
|
}
|
|
1340
|
-
|
|
1358
|
+
passMs.write = Date.now() - tWrite;
|
|
1359
|
+
const manifest = {
|
|
1360
|
+
name: "name" in metadata && typeof metadata.name === "string" ? metadata.name : void 0,
|
|
1361
|
+
description: "description" in metadata && typeof metadata.description === "string" ? metadata.description : void 0,
|
|
1362
|
+
repositoryUrl: repositoryLink?.protocol === "https:" && !repositoryLink.username && !repositoryLink.password ? repositoryLink.href : void 0,
|
|
1363
|
+
schema: contract_exports.SEED_SCHEMA,
|
|
1364
|
+
version: gitVersion.version,
|
|
1365
|
+
versionLabel: gitVersion.versionLabel,
|
|
1366
|
+
commit: gitVersion.commit,
|
|
1367
|
+
dirty: gitVersion.dirty,
|
|
1368
|
+
builtAt: manifestBuiltAt,
|
|
1369
|
+
chunks: manifestChunks,
|
|
1370
|
+
notebooks: manifestNotebooks
|
|
1371
|
+
};
|
|
1372
|
+
(0, validation_exports.assertSeedManifest)(manifest);
|
|
1373
|
+
fs.writeFileSync(path.join(outDir, "manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
1374
|
+
const reportPath = writeBuildReport(outDir, {
|
|
1375
|
+
manifest,
|
|
1376
|
+
totalMs: Date.now() - t0,
|
|
1377
|
+
passMs,
|
|
1378
|
+
fileCount: paths.length});
|
|
1379
|
+
return { manifest, outDir, totalFiles, reportPath, passMs };
|
|
1341
1380
|
}
|
|
1342
|
-
var
|
|
1343
|
-
|
|
1381
|
+
var NON_EFFORT_SLUGS;
|
|
1382
|
+
var init_compiler = __esm({
|
|
1383
|
+
"src/seedbuild/compiler.ts"() {
|
|
1384
|
+
init_contract();
|
|
1385
|
+
init_filename();
|
|
1386
|
+
init_git_version();
|
|
1387
|
+
init_report();
|
|
1388
|
+
init_frontmatter();
|
|
1389
|
+
init_validation();
|
|
1390
|
+
NON_EFFORT_SLUGS = {
|
|
1391
|
+
"amrap": true,
|
|
1392
|
+
"emom": true,
|
|
1393
|
+
"tabata": true,
|
|
1394
|
+
"for-time": true,
|
|
1395
|
+
"rounds": true,
|
|
1396
|
+
"sets": true,
|
|
1397
|
+
"repetitions": true,
|
|
1398
|
+
"count-down": true,
|
|
1399
|
+
"total-reps": true,
|
|
1400
|
+
"warmup": true,
|
|
1401
|
+
"cooldown": true,
|
|
1402
|
+
"cool-down": true,
|
|
1403
|
+
"transition": true,
|
|
1404
|
+
"rest": true,
|
|
1405
|
+
"break": true,
|
|
1406
|
+
"work": true,
|
|
1407
|
+
"i-suck-at-this": true,
|
|
1408
|
+
"isuckatthis": true,
|
|
1409
|
+
"movement": true,
|
|
1410
|
+
"movement-you": true,
|
|
1411
|
+
"selected-exercise": true,
|
|
1412
|
+
"training-setup": true,
|
|
1413
|
+
"grade-system": true,
|
|
1414
|
+
"hangs": true,
|
|
1415
|
+
"warm-light-wind": true,
|
|
1416
|
+
"basin": true,
|
|
1417
|
+
"rock-canyon": true,
|
|
1418
|
+
"b-onsight": true,
|
|
1419
|
+
"a-redpoint": true,
|
|
1420
|
+
"d-redpoint": true,
|
|
1421
|
+
"v0-flash": true,
|
|
1422
|
+
"v2-flash": true,
|
|
1423
|
+
"v7-redpoint": true,
|
|
1424
|
+
"avgrpe-mean": true,
|
|
1425
|
+
"calculate": true,
|
|
1426
|
+
"totalload-sum": true,
|
|
1427
|
+
"query": true,
|
|
1428
|
+
"by": true,
|
|
1429
|
+
"": true,
|
|
1430
|
+
"-": true,
|
|
1431
|
+
"...": true,
|
|
1432
|
+
"x": true,
|
|
1433
|
+
"s": true,
|
|
1434
|
+
"bw": true
|
|
1435
|
+
};
|
|
1344
1436
|
}
|
|
1345
1437
|
});
|
|
1346
1438
|
|
|
@@ -1550,10 +1642,75 @@ async function storeRoutes(db, method, sub, url, req) {
|
|
|
1550
1642
|
}
|
|
1551
1643
|
return methodNotAllowed();
|
|
1552
1644
|
}
|
|
1553
|
-
|
|
1645
|
+
function isPublishedFeedAssetPath(pathname) {
|
|
1646
|
+
if (pathname === "/feed" || pathname === "/feed/") return "index.html";
|
|
1647
|
+
if (!pathname.startsWith("/feed/")) return null;
|
|
1648
|
+
const sub = pathname.slice("/feed/".length);
|
|
1649
|
+
if (sub === "index.html" || sub === "manifest.json" || sub === "report.html" || sub.startsWith("chunks/") || sub.startsWith("indexes/") || sub.startsWith("markdown/")) {
|
|
1650
|
+
return sub;
|
|
1651
|
+
}
|
|
1652
|
+
return null;
|
|
1653
|
+
}
|
|
1654
|
+
async function servePublishedFeed(feedTree, method, relPath) {
|
|
1655
|
+
if (method === "OPTIONS") {
|
|
1656
|
+
return new Response(null, {
|
|
1657
|
+
status: 204,
|
|
1658
|
+
headers: {
|
|
1659
|
+
"access-control-allow-origin": "*",
|
|
1660
|
+
"access-control-allow-methods": "GET, HEAD, OPTIONS"
|
|
1661
|
+
}
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
if (method !== "GET") return methodNotAllowed();
|
|
1665
|
+
try {
|
|
1666
|
+
const decoded = decodeURIComponent(relPath);
|
|
1667
|
+
const bytes = await feedTree.read(decoded);
|
|
1668
|
+
const ext = decoded.includes(".") ? decoded.slice(decoded.lastIndexOf(".") + 1).toLowerCase() : "html";
|
|
1669
|
+
const cache = decoded.startsWith("chunks/") ? "public, max-age=31536000, immutable" : "no-cache";
|
|
1670
|
+
const copy = new Uint8Array(bytes.byteLength);
|
|
1671
|
+
copy.set(bytes);
|
|
1672
|
+
return new Response(copy.buffer, {
|
|
1673
|
+
status: 200,
|
|
1674
|
+
headers: {
|
|
1675
|
+
"content-type": MIME[ext] ?? "application/octet-stream",
|
|
1676
|
+
"cache-control": cache,
|
|
1677
|
+
"access-control-allow-origin": "*"
|
|
1678
|
+
}
|
|
1679
|
+
});
|
|
1680
|
+
} catch (err) {
|
|
1681
|
+
if (err instanceof wod_wiki_engine_star.FeedTreeError && err.code === "not-found") return notFound();
|
|
1682
|
+
if (err instanceof wod_wiki_engine_star.FeedTreeError && err.code === "layout") return plain("forbidden", 403);
|
|
1683
|
+
throw err;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
async function apiRoutes(db, feedTree, req, method, sub, url) {
|
|
1554
1687
|
if (sub === "/health") {
|
|
1555
1688
|
return json({ ok: true, driver: db.dialect }, 200);
|
|
1556
1689
|
}
|
|
1690
|
+
if (sub === "/v1/feed/status" && method === "GET") {
|
|
1691
|
+
const storage = new sql.SqlStorage(db);
|
|
1692
|
+
const status = await wod_wiki_engine_star.checkUnpublishedFeedChanges(storage, feedTree);
|
|
1693
|
+
return json({ ...status, feedUrl: `${url.origin}/feed/` }, 200);
|
|
1694
|
+
}
|
|
1695
|
+
if (sub === "/v1/feed/publish" && method === "POST") {
|
|
1696
|
+
const body = req.headers.get("content-length") === "0" ? {} : await readJsonBody(req).catch(() => ({}));
|
|
1697
|
+
const opts = typeof body === "object" && body !== null ? body : {};
|
|
1698
|
+
const storage = new sql.SqlStorage(db);
|
|
1699
|
+
const report = await wod_wiki_engine_star.publishFeedFromStorage(storage, feedTree, {
|
|
1700
|
+
layout: "feed",
|
|
1701
|
+
...typeof opts.name === "string" ? { name: opts.name } : {},
|
|
1702
|
+
...typeof opts.description === "string" ? { description: opts.description } : {},
|
|
1703
|
+
...typeof opts.repositoryUrl === "string" ? { repositoryUrl: opts.repositoryUrl } : {},
|
|
1704
|
+
...typeof opts.notebookSlug === "string" ? { notebookSlug: opts.notebookSlug } : {}
|
|
1705
|
+
});
|
|
1706
|
+
return json({
|
|
1707
|
+
manifest: report.manifest,
|
|
1708
|
+
notebooks: report.notebooks,
|
|
1709
|
+
totalNotes: report.totalNotes,
|
|
1710
|
+
totalPublicSessions: report.totalPublicSessions,
|
|
1711
|
+
feedUrl: `${url.origin}/feed/`
|
|
1712
|
+
}, 200);
|
|
1713
|
+
}
|
|
1557
1714
|
if (sub === "/v1/wipe" && method === "POST") {
|
|
1558
1715
|
await db.transaction(async (tx) => {
|
|
1559
1716
|
await sql.wipeRows(tx);
|
|
@@ -1586,13 +1743,22 @@ function distRootOf(playgroundDist) {
|
|
|
1586
1743
|
}
|
|
1587
1744
|
function createHandler(db, options) {
|
|
1588
1745
|
const distRoot = distRootOf(options.playgroundDist);
|
|
1746
|
+
const feedTree = options.feedTree ?? (options.feedDir ? new NodeFsFeedTree(options.feedDir) : new wod_wiki_engine_star.MemoryFeedTree());
|
|
1589
1747
|
return async (request) => {
|
|
1590
1748
|
try {
|
|
1591
1749
|
const url = new URL(request.url);
|
|
1592
1750
|
const method = request.method === "HEAD" ? "GET" : request.method;
|
|
1593
1751
|
const path = url.pathname;
|
|
1594
|
-
|
|
1595
|
-
|
|
1752
|
+
if (path === "/api" || path.startsWith("/api/")) {
|
|
1753
|
+
return db ? await apiRoutes(db, feedTree, request, method, path.slice("/api".length) || "/", url) : notFound();
|
|
1754
|
+
}
|
|
1755
|
+
if (db) {
|
|
1756
|
+
const feedAsset = isPublishedFeedAssetPath(path);
|
|
1757
|
+
if (feedAsset !== null) {
|
|
1758
|
+
return await servePublishedFeed(feedTree, request.method === "OPTIONS" ? "OPTIONS" : method, feedAsset);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
return await staticResponse(distRoot, method, path);
|
|
1596
1762
|
} catch (e) {
|
|
1597
1763
|
if (e instanceof HttpError || e instanceof sql.StorageError) {
|
|
1598
1764
|
const status = e.status;
|
|
@@ -1610,6 +1776,7 @@ var json, plain, notFound, methodNotAllowed, noContent, qget, MIME;
|
|
|
1610
1776
|
var init_app = __esm({
|
|
1611
1777
|
"src/server/app.ts"() {
|
|
1612
1778
|
init_errors();
|
|
1779
|
+
init_nodeFeedTree();
|
|
1613
1780
|
json = (value, status) => new Response(JSON.stringify(value), { status, headers: { "content-type": "application/json" } });
|
|
1614
1781
|
plain = (body, status) => new Response(body, { status, headers: { "content-type": "text/plain; charset=utf-8" } });
|
|
1615
1782
|
notFound = () => json({ error: "not found" }, 404);
|
|
@@ -1636,7 +1803,10 @@ var init_app = __esm({
|
|
|
1636
1803
|
wav: "audio/wav",
|
|
1637
1804
|
webmanifest: "application/manifest+json",
|
|
1638
1805
|
xml: "application/xml",
|
|
1639
|
-
txt: "text/plain; charset=utf-8"
|
|
1806
|
+
txt: "text/plain; charset=utf-8",
|
|
1807
|
+
md: "text/markdown; charset=utf-8",
|
|
1808
|
+
jsonl: "application/x-ndjson; charset=utf-8",
|
|
1809
|
+
csv: "text/csv; charset=utf-8"
|
|
1640
1810
|
};
|
|
1641
1811
|
}
|
|
1642
1812
|
});
|
|
@@ -1767,7 +1937,8 @@ async function runCliServer(mode, options, writeOut) {
|
|
|
1767
1937
|
let server;
|
|
1768
1938
|
try {
|
|
1769
1939
|
const dist = resolveDist(mode, options);
|
|
1770
|
-
const
|
|
1940
|
+
const feedDir = mode === "server" && options.database?.kind === "sqlite" ? `${options.database.path}.feed` : void 0;
|
|
1941
|
+
const handler = createHandler(db?.db ?? null, { playgroundDist: dist, feedDir });
|
|
1771
1942
|
server = await startHttpServer(handler, host, port);
|
|
1772
1943
|
if (mode === "server") {
|
|
1773
1944
|
writeOut(`wod server: http://${host}:${port} \u2014 ${dbLabel} \xB7 dist ${dist}`);
|
|
@@ -3475,145 +3646,37 @@ function defaultSeedDirs(cwd) {
|
|
|
3475
3646
|
|
|
3476
3647
|
// src/cli/publish.ts
|
|
3477
3648
|
init_db();
|
|
3478
|
-
|
|
3479
|
-
init_compiler();
|
|
3649
|
+
init_nodeFeedTree();
|
|
3480
3650
|
init_report();
|
|
3481
3651
|
async function publishNotebookSeed(db, options) {
|
|
3482
3652
|
const t0 = Date.now();
|
|
3483
|
-
const fs = nodeFs();
|
|
3484
|
-
const path = nodePath();
|
|
3485
3653
|
const allNotes = await db.storage.readonly("notes").getAll();
|
|
3486
3654
|
if (allNotes.length === 0) {
|
|
3487
3655
|
throw new Error(`[wod publish] No notes found in database ${db.path}`);
|
|
3488
3656
|
}
|
|
3489
|
-
const
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
targetNotebooks.set(options.notebook, matching);
|
|
3502
|
-
} else if (notesByNotebook.has("__unassigned__") && notesByNotebook.size === 1) {
|
|
3503
|
-
targetNotebooks.set(options.notebook, notesByNotebook.get("__unassigned__"));
|
|
3504
|
-
} else {
|
|
3505
|
-
const available = [...notesByNotebook.keys()].filter((k) => k !== "__unassigned__");
|
|
3506
|
-
throw new Error(
|
|
3507
|
-
`[wod publish] Notebook "${options.notebook}" not found in ${db.path}.` + (available.length > 0 ? ` Available notebooks: ${available.join(", ")}` : "")
|
|
3508
|
-
);
|
|
3509
|
-
}
|
|
3510
|
-
} else {
|
|
3511
|
-
for (const [slug, notes] of notesByNotebook.entries()) {
|
|
3512
|
-
targetNotebooks.set(slug === "__unassigned__" ? "default" : slug, notes);
|
|
3513
|
-
}
|
|
3514
|
-
}
|
|
3515
|
-
const allIndexRows = await db.storage.readonly("block_index").getAll();
|
|
3516
|
-
const allEffortRows = await db.storage.readonly("block_efforts").getAll();
|
|
3517
|
-
const allEquipmentRows = await db.storage.readonly("block_equipment").getAll();
|
|
3518
|
-
const indexByNote = /* @__PURE__ */ new Map();
|
|
3519
|
-
for (const row of allIndexRows) {
|
|
3520
|
-
const list = indexByNote.get(row.noteId) ?? [];
|
|
3521
|
-
list.push(row);
|
|
3522
|
-
indexByNote.set(row.noteId, list);
|
|
3523
|
-
}
|
|
3524
|
-
const effortsByNote = /* @__PURE__ */ new Map();
|
|
3525
|
-
for (const row of allEffortRows) {
|
|
3526
|
-
const list = effortsByNote.get(row.noteId) ?? [];
|
|
3527
|
-
list.push(row);
|
|
3528
|
-
effortsByNote.set(row.noteId, list);
|
|
3529
|
-
}
|
|
3530
|
-
const equipmentByNote = /* @__PURE__ */ new Map();
|
|
3531
|
-
for (const row of allEquipmentRows) {
|
|
3532
|
-
const list = equipmentByNote.get(row.noteId) ?? [];
|
|
3533
|
-
list.push(row);
|
|
3534
|
-
equipmentByNote.set(row.noteId, list);
|
|
3535
|
-
}
|
|
3536
|
-
const outDir = path.resolve(process.cwd(), options.outDir);
|
|
3537
|
-
const chunksDir = path.join(outDir, "chunks");
|
|
3538
|
-
fs.mkdirSync(chunksDir, { recursive: true });
|
|
3539
|
-
const manifestChunks = [];
|
|
3540
|
-
let totalNotes = 0;
|
|
3541
|
-
const publishedNotebooks = [];
|
|
3542
|
-
for (const [notebookSlug, notes] of targetNotebooks.entries()) {
|
|
3543
|
-
publishedNotebooks.push(notebookSlug);
|
|
3544
|
-
const chunkRows = [];
|
|
3545
|
-
for (const note of notes) {
|
|
3546
|
-
const stem = (note.title || note.id).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") || "note";
|
|
3547
|
-
const notePath = note.sourcePath ?? `markdown/notebooks/${notebookSlug}/${stem}.md`;
|
|
3548
|
-
const noteBlockIndex = indexByNote.get(note.id) ?? [];
|
|
3549
|
-
const noteBlockEfforts = effortsByNote.get(note.id) ?? [];
|
|
3550
|
-
const noteBlockEquipment = equipmentByNote.get(note.id) ?? [];
|
|
3551
|
-
const blockIndex = noteBlockIndex.length > 0 ? noteBlockIndex.map((b) => ({
|
|
3552
|
-
...b,
|
|
3553
|
-
isStatic: true,
|
|
3554
|
-
sourceId: b.sourceId ?? `notebook:${notebookSlug}/${stem}`,
|
|
3555
|
-
sourcePath: b.sourcePath ?? notePath
|
|
3556
|
-
})) : compileSeedRow(notePath, note.rawContent, {
|
|
3557
|
-
routeId: `${notebookSlug}/${stem}`,
|
|
3558
|
-
sourceId: `notebook:${notebookSlug}/${stem}`,
|
|
3559
|
-
// Authored frontmatter date first — exports keep the post's own
|
|
3560
|
-
// day, never the import/publish time.
|
|
3561
|
-
createdAt: note.date ?? note.createdAt,
|
|
3562
|
-
noteTitle: note.title
|
|
3563
|
-
}).blockIndex;
|
|
3564
|
-
const blockEfforts = noteBlockEfforts.map((e) => ({
|
|
3565
|
-
...e,
|
|
3566
|
-
isStatic: true,
|
|
3567
|
-
sourcePath: e.sourcePath ?? notePath
|
|
3568
|
-
}));
|
|
3569
|
-
const blockEquipment = noteBlockEquipment.map((e) => ({
|
|
3570
|
-
...e,
|
|
3571
|
-
isStatic: true,
|
|
3572
|
-
sourcePath: e.sourcePath ?? notePath
|
|
3573
|
-
}));
|
|
3574
|
-
chunkRows.push({
|
|
3575
|
-
path: notePath,
|
|
3576
|
-
content: note.rawContent,
|
|
3577
|
-
blocks: note.blocks,
|
|
3578
|
-
blockIndex,
|
|
3579
|
-
blockEfforts,
|
|
3580
|
-
blockEquipment
|
|
3581
|
-
});
|
|
3582
|
-
}
|
|
3583
|
-
const chunkId = `notebook.${notebookSlug}`;
|
|
3584
|
-
const json2 = JSON.stringify(chunkRows);
|
|
3585
|
-
const digest = nodeCrypto().createHash("sha256").update(json2).digest();
|
|
3586
|
-
const sha = [...digest].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3587
|
-
const chunkFile = `chunks/${chunkId}.${sha.slice(0, 8)}.json`;
|
|
3588
|
-
fs.writeFileSync(path.join(outDir, chunkFile), json2, "utf-8");
|
|
3589
|
-
manifestChunks.push({
|
|
3590
|
-
id: chunkId,
|
|
3591
|
-
path: chunkFile,
|
|
3592
|
-
sha256: sha,
|
|
3593
|
-
bytes: Buffer.byteLength(json2, "utf8"),
|
|
3594
|
-
count: chunkRows.length,
|
|
3595
|
-
kind: "notes"
|
|
3596
|
-
});
|
|
3597
|
-
totalNotes += chunkRows.length;
|
|
3598
|
-
}
|
|
3599
|
-
const manifest = {
|
|
3600
|
-
schema: contract_exports.SEED_SCHEMA,
|
|
3601
|
-
version: options.version ?? 1,
|
|
3602
|
-
versionLabel: `v${options.version ?? 1}`,
|
|
3603
|
-
builtAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3604
|
-
chunks: manifestChunks
|
|
3605
|
-
};
|
|
3606
|
-
fs.writeFileSync(path.join(outDir, "manifest.json"), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
|
3657
|
+
const outDir = nodePath().resolve(process.cwd(), options.outDir);
|
|
3658
|
+
const tree = new NodeFsFeedTree(outDir);
|
|
3659
|
+
const report = await wod_wiki_engine_star.publishFeedFromStorage(db.storage, tree, {
|
|
3660
|
+
layout: "feed",
|
|
3661
|
+
notebookSlug: options.notebook,
|
|
3662
|
+
version: options.version,
|
|
3663
|
+
name: options.name,
|
|
3664
|
+
description: options.description,
|
|
3665
|
+
repositoryUrl: options.repositoryUrl,
|
|
3666
|
+
includePrivateWhenFiltered: true
|
|
3667
|
+
});
|
|
3668
|
+
const elapsed = Math.max(1, Date.now() - t0);
|
|
3607
3669
|
writeBuildReport(outDir, {
|
|
3608
|
-
manifest,
|
|
3609
|
-
totalMs:
|
|
3610
|
-
passMs: { scan: 0, blockIndex: 0, parseGate: 0, blockEfforts: 0, write:
|
|
3611
|
-
fileCount: totalNotes});
|
|
3670
|
+
manifest: report.manifest,
|
|
3671
|
+
totalMs: elapsed,
|
|
3672
|
+
passMs: { scan: 0, blockIndex: 0, parseGate: 0, blockEfforts: 0, write: elapsed },
|
|
3673
|
+
fileCount: report.totalNotes});
|
|
3612
3674
|
return {
|
|
3613
|
-
manifest,
|
|
3675
|
+
manifest: report.manifest,
|
|
3614
3676
|
outDir,
|
|
3615
|
-
notebooks:
|
|
3616
|
-
totalNotes
|
|
3677
|
+
notebooks: report.notebooks,
|
|
3678
|
+
totalNotes: report.totalNotes,
|
|
3679
|
+
totalPublicSessions: report.totalPublicSessions
|
|
3617
3680
|
};
|
|
3618
3681
|
}
|
|
3619
3682
|
|
|
@@ -3991,13 +4054,13 @@ function parseCliArgs(args) {
|
|
|
3991
4054
|
i++;
|
|
3992
4055
|
} else if (arg === "--format") {
|
|
3993
4056
|
const fmt = args[++i];
|
|
3994
|
-
if (fmt === "json" || fmt === "table" || fmt === "csv") {
|
|
4057
|
+
if (fmt === "json" || fmt === "table" || fmt === "csv" || fmt === "jsonl") {
|
|
3995
4058
|
result.format = fmt;
|
|
3996
4059
|
}
|
|
3997
4060
|
i++;
|
|
3998
4061
|
} else if (arg.startsWith("--format=")) {
|
|
3999
4062
|
const fmt = arg.slice("--format=".length);
|
|
4000
|
-
if (fmt === "json" || fmt === "table" || fmt === "csv") {
|
|
4063
|
+
if (fmt === "json" || fmt === "table" || fmt === "csv" || fmt === "jsonl") {
|
|
4001
4064
|
result.format = fmt;
|
|
4002
4065
|
}
|
|
4003
4066
|
i++;
|
|
@@ -4624,12 +4687,28 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
4624
4687
|
writeErr(`[wod ${verb}] Session not found in ${db.path}: ${id}`);
|
|
4625
4688
|
return 1;
|
|
4626
4689
|
}
|
|
4627
|
-
const
|
|
4628
|
-
const
|
|
4690
|
+
const wantsJsonl = parsed.format === "jsonl" || parsed.output !== void 0 && /\.jsonl$/i.test(parsed.output);
|
|
4691
|
+
const defaultExt = wantsJsonl ? "jsonl" : "csv";
|
|
4692
|
+
const target = parsed.output && parsed.output !== "-" ? parsed.output : `${id}.${defaultExt}`;
|
|
4693
|
+
let payload;
|
|
4694
|
+
if (wantsJsonl) {
|
|
4695
|
+
const rev = await db.storage.readonly("block_revisions").get([
|
|
4696
|
+
bundle.session.noteId,
|
|
4697
|
+
bundle.session.blockId,
|
|
4698
|
+
bundle.session.blockVersion
|
|
4699
|
+
]);
|
|
4700
|
+
payload = wod_wiki_engine_star.serializeNoteBundleToJsonl({
|
|
4701
|
+
...rev ? { revisions: [rev] } : {},
|
|
4702
|
+
sessions: [bundle.session],
|
|
4703
|
+
events: bundle.events
|
|
4704
|
+
}) + "\n";
|
|
4705
|
+
} else {
|
|
4706
|
+
payload = wod_wiki_engine_star.sessionToCsv(bundle.session, bundle.events);
|
|
4707
|
+
}
|
|
4629
4708
|
if (parsed.output === "-") {
|
|
4630
|
-
writeOut(
|
|
4709
|
+
writeOut(payload.trimEnd());
|
|
4631
4710
|
} else {
|
|
4632
|
-
nodeFs().writeFileSync(target,
|
|
4711
|
+
nodeFs().writeFileSync(target, payload, "utf-8");
|
|
4633
4712
|
}
|
|
4634
4713
|
if (parsed.output !== "-") writeOut(`[wod ${verb}] session ${id} \u2192 ${target} (${bundle.events.length} events)`);
|
|
4635
4714
|
} else if (kind === "effort") {
|
|
@@ -4749,13 +4828,25 @@ async function cliMain(argv = process.argv.slice(2), io = {}) {
|
|
|
4749
4828
|
}
|
|
4750
4829
|
return 0;
|
|
4751
4830
|
}
|
|
4752
|
-
const
|
|
4831
|
+
const rawSessionText = fs.readFileSync(file, "utf-8");
|
|
4753
4832
|
const db = await openCliDb(cliDb());
|
|
4754
4833
|
try {
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4834
|
+
if (/\.jsonl$/i.test(file)) {
|
|
4835
|
+
const report = await wod_wiki_engine_star.ingestPortableFilesIntoStorage(db.storage, [{ path: file, content: rawSessionText }]);
|
|
4836
|
+
if (report.errors.length > 0 && report.sessionsImported === 0) {
|
|
4837
|
+
writeErr(`[wod import] ${report.errors.join("; ")}`);
|
|
4838
|
+
return 1;
|
|
4839
|
+
}
|
|
4840
|
+
writeOut(
|
|
4841
|
+
`[wod import] session jsonl \u2014 ${report.sessionsImported} session(s), ${report.eventsImported} events \u2192 ${db.path}`
|
|
4842
|
+
);
|
|
4843
|
+
} else {
|
|
4844
|
+
const { session, events } = wod_wiki_engine_star.csvToSessionRows(rawSessionText);
|
|
4845
|
+
const result = await persistSessionBundle(db, session, events);
|
|
4846
|
+
writeOut(
|
|
4847
|
+
`[wod import] session ${session.id} \u2014 ${result.events} events \u2192 ${db.path}`
|
|
4848
|
+
);
|
|
4849
|
+
}
|
|
4759
4850
|
} finally {
|
|
4760
4851
|
await db.close();
|
|
4761
4852
|
}
|