@workingdevshero/olympia-ait-adapter 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/reader/parse-day-sheet.d.ts.map +1 -1
- package/dist/reader/parse-day-sheet.js +98 -29
- package/dist/reader/parse-day-sheet.js.map +1 -1
- package/dist/schema/program.d.ts +363 -19
- package/dist/schema/program.d.ts.map +1 -1
- package/dist/schema/program.js +110 -14
- package/dist/schema/program.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/writer/build-workbook.d.ts +1 -1
- package/dist/writer/build-workbook.d.ts.map +1 -1
- package/dist/writer/build-workbook.js +18 -12
- package/dist/writer/build-workbook.js.map +1 -1
- package/dist/writer/layout.d.ts +19 -7
- package/dist/writer/layout.d.ts.map +1 -1
- package/dist/writer/layout.js +40 -21
- package/dist/writer/layout.js.map +1 -1
- package/dist/writer/stamp-exercise.d.ts +13 -5
- package/dist/writer/stamp-exercise.d.ts.map +1 -1
- package/dist/writer/stamp-exercise.js +25 -18
- package/dist/writer/stamp-exercise.js.map +1 -1
- package/dist/writer/supplemental-template.d.ts +3 -2
- package/dist/writer/supplemental-template.d.ts.map +1 -1
- package/dist/writer/supplemental-template.js +15 -15
- package/dist/writer/supplemental-template.js.map +1 -1
- package/package.json +1 -1
- package/skills/olympia-authoring/SKILL.md +25 -9
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { EXERCISE_NAME_COL
|
|
1
|
+
import { EXERCISE_NAME_COL } from "./layout.js";
|
|
2
2
|
import { exerciseNameStyle, groupLabelStyle, NOTES_CELL, weekRepsCellStyle, weekWeightCellStyle, } from "./styles.js";
|
|
3
3
|
/**
|
|
4
4
|
* Stamps one exercise block onto the worksheet starting at `startRow`.
|
|
5
5
|
*
|
|
6
6
|
* Layout rules (N = exercise.sets.length):
|
|
7
|
-
* - With
|
|
8
|
-
* when N > 2);
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
7
|
+
* - With a label: name occupies the first N−1 rows of col C (merged
|
|
8
|
+
* when N > 2); the label sits in col C of the last row.
|
|
9
|
+
* - With a label and a single set: the set sits on the name row and the
|
|
10
|
+
* label gets a row of its own below it, with empty prescription cells.
|
|
11
|
+
* - Without a label: name occupies all N rows of col C (merged when
|
|
12
|
+
* N > 1); no label row.
|
|
11
13
|
*
|
|
12
14
|
* Borders on column C (the gray bar) are driven by `topBorder` and
|
|
13
15
|
* `bottomBorder` so the caller can express "this block is the first/last
|
|
@@ -15,21 +17,25 @@ import { exerciseNameStyle, groupLabelStyle, NOTES_CELL, weekRepsCellStyle, week
|
|
|
15
17
|
*
|
|
16
18
|
* @returns the next free row after the block.
|
|
17
19
|
*/
|
|
18
|
-
export function stampExercise(ws, startRow, exercise, opts) {
|
|
20
|
+
export function stampExercise(ws, startRow, exercise, layout, opts) {
|
|
21
|
+
const { repsCols: WEEK_REPS_COLS, weightCols: WEEK_WEIGHT_COLS, notesCol: NOTES_COL } = layout;
|
|
19
22
|
const setCount = exercise.sets.length;
|
|
20
|
-
const hasGroupLabel =
|
|
21
|
-
|
|
23
|
+
const hasGroupLabel = opts.label !== undefined;
|
|
24
|
+
// The label shares the last set's row; a one-set block gets an extra row
|
|
25
|
+
// for it, left empty of prescriptions.
|
|
26
|
+
const rowCount = hasGroupLabel && setCount === 1 ? 2 : setCount;
|
|
27
|
+
const lastBlockRow = startRow + rowCount - 1;
|
|
22
28
|
// Where the exercise-name region ends.
|
|
23
|
-
const nameLastRow = hasGroupLabel
|
|
29
|
+
const nameLastRow = hasGroupLabel ? lastBlockRow - 1 : lastBlockRow;
|
|
24
30
|
if (nameLastRow > startRow) {
|
|
25
31
|
ws.mergeCells(`${EXERCISE_NAME_COL}${startRow}:${EXERCISE_NAME_COL}${nameLastRow}`);
|
|
26
32
|
}
|
|
27
33
|
const nameCell = ws.getCell(`${EXERCISE_NAME_COL}${startRow}`);
|
|
28
34
|
nameCell.value = exercise.name;
|
|
29
35
|
Object.assign(nameCell, exerciseNameStyle(opts.topBorder));
|
|
30
|
-
if (hasGroupLabel
|
|
36
|
+
if (hasGroupLabel) {
|
|
31
37
|
const groupCell = ws.getCell(`${EXERCISE_NAME_COL}${lastBlockRow}`);
|
|
32
|
-
groupCell.value =
|
|
38
|
+
groupCell.value = opts.label;
|
|
33
39
|
Object.assign(groupCell, groupLabelStyle(opts.bottomBorder));
|
|
34
40
|
}
|
|
35
41
|
else if (!hasGroupLabel && opts.bottomBorder === "medium") {
|
|
@@ -44,27 +50,28 @@ export function stampExercise(ws, startRow, exercise, opts) {
|
|
|
44
50
|
};
|
|
45
51
|
Object.assign(nameCell, composed);
|
|
46
52
|
}
|
|
47
|
-
// Notes column
|
|
48
|
-
if (
|
|
53
|
+
// Notes column: merge across the whole block when there's more than one row.
|
|
54
|
+
if (rowCount > 1) {
|
|
49
55
|
ws.mergeCells(`${NOTES_COL}${startRow}:${NOTES_COL}${lastBlockRow}`);
|
|
50
56
|
}
|
|
51
57
|
const noteCell = ws.getCell(`${NOTES_COL}${startRow}`);
|
|
52
58
|
noteCell.value = exercise.notes ?? "";
|
|
53
59
|
Object.assign(noteCell, NOTES_CELL);
|
|
54
60
|
// Per-set per-week cells
|
|
55
|
-
for (let setIdx = 0; setIdx <
|
|
61
|
+
for (let setIdx = 0; setIdx < rowCount; setIdx++) {
|
|
56
62
|
const r = startRow + setIdx;
|
|
57
63
|
const isTop = setIdx === 0;
|
|
58
|
-
const isBottom = setIdx ===
|
|
59
|
-
const setRow = exercise.sets[setIdx];
|
|
60
|
-
|
|
64
|
+
const isBottom = setIdx === rowCount - 1;
|
|
65
|
+
const setRow = exercise.sets[setIdx] ?? [];
|
|
66
|
+
const weightRow = exercise.weights?.[setIdx];
|
|
67
|
+
for (let weekIdx = 0; weekIdx < layout.weekCount; weekIdx++) {
|
|
61
68
|
const repsCol = WEEK_REPS_COLS[weekIdx];
|
|
62
69
|
const weightCol = WEEK_WEIGHT_COLS[weekIdx];
|
|
63
70
|
const repsCell = ws.getCell(`${repsCol}${r}`);
|
|
64
71
|
repsCell.value = setRow[weekIdx] ?? null;
|
|
65
72
|
Object.assign(repsCell, weekRepsCellStyle({ isTop, isBottom }));
|
|
66
73
|
const weightCell = ws.getCell(`${weightCol}${r}`);
|
|
67
|
-
weightCell.value = null;
|
|
74
|
+
weightCell.value = weightRow?.[weekIdx] ?? null;
|
|
68
75
|
Object.assign(weightCell, weekWeightCellStyle({ isTop, isBottom }));
|
|
69
76
|
}
|
|
70
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stamp-exercise.js","sourceRoot":"","sources":["../../src/writer/stamp-exercise.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"stamp-exercise.js","sourceRoot":"","sources":["../../src/writer/stamp-exercise.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type ExcelJS from "exceljs";
|
|
2
2
|
import type { SupplementalNote } from "../schema/program.js";
|
|
3
|
+
import { type WeekLayout } from "./layout.js";
|
|
3
4
|
/**
|
|
4
5
|
* Stamps the fixed "Sport Specific / Supplemental" template area at the
|
|
5
6
|
* bottom of a day sheet, then layers in any supplementalNotes the program
|
|
6
7
|
* JSON supplied. The template is 10 rows tall and uses single-row merges
|
|
7
|
-
* in each week-column pair (D-E, F-G,
|
|
8
|
+
* in each week-column pair (D-E, F-G, … one pair per week) so the LLM can
|
|
8
9
|
* put a value into any cell by its master address.
|
|
9
10
|
*
|
|
10
11
|
* Layout:
|
|
@@ -19,5 +20,5 @@ import type { SupplementalNote } from "../schema/program.js";
|
|
|
19
20
|
*
|
|
20
21
|
* @returns the next free row after the template (startRow + 10).
|
|
21
22
|
*/
|
|
22
|
-
export declare function stampSupplementalTemplate(ws: ExcelJS.Worksheet, startRow: number, supplementalNotes?: SupplementalNote[]): number;
|
|
23
|
+
export declare function stampSupplementalTemplate(ws: ExcelJS.Worksheet, startRow: number, layout: WeekLayout, supplementalNotes?: SupplementalNote[]): number;
|
|
23
24
|
//# sourceMappingURL=supplemental-template.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supplemental-template.d.ts","sourceRoot":"","sources":["../../src/writer/supplemental-template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"supplemental-template.d.ts","sourceRoot":"","sources":["../../src/writer/supplemental-template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAYjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,OAAO,CAAC,SAAS,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,GACrC,MAAM,CAkER"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EXERCISE_NAME_COL
|
|
1
|
+
import { EXERCISE_NAME_COL } from "./layout.js";
|
|
2
2
|
import { TPL_C_GRAY, TPL_C_GRAY_BOTTOM, TPL_NOTES_LEFT, TPL_NOTES_LEFT_BOTTOM, } from "./styles.js";
|
|
3
3
|
const TEMPLATE_ROWS = 10;
|
|
4
4
|
const LABEL_SPORT_SPECIFIC_ROW = 0;
|
|
@@ -7,7 +7,7 @@ const LABEL_SUPPLEMENTAL_ROW = 1;
|
|
|
7
7
|
* Stamps the fixed "Sport Specific / Supplemental" template area at the
|
|
8
8
|
* bottom of a day sheet, then layers in any supplementalNotes the program
|
|
9
9
|
* JSON supplied. The template is 10 rows tall and uses single-row merges
|
|
10
|
-
* in each week-column pair (D-E, F-G,
|
|
10
|
+
* in each week-column pair (D-E, F-G, … one pair per week) so the LLM can
|
|
11
11
|
* put a value into any cell by its master address.
|
|
12
12
|
*
|
|
13
13
|
* Layout:
|
|
@@ -22,7 +22,8 @@ const LABEL_SUPPLEMENTAL_ROW = 1;
|
|
|
22
22
|
*
|
|
23
23
|
* @returns the next free row after the template (startRow + 10).
|
|
24
24
|
*/
|
|
25
|
-
export function stampSupplementalTemplate(ws, startRow, supplementalNotes) {
|
|
25
|
+
export function stampSupplementalTemplate(ws, startRow, layout, supplementalNotes) {
|
|
26
|
+
const { weekCount, repsCols: WEEK_REPS_COLS, weightCols: WEEK_WEIGHT_COLS, notesCol: NOTES_COL } = layout;
|
|
26
27
|
const lastTemplateRow = startRow + TEMPLATE_ROWS - 1;
|
|
27
28
|
// --- Column C: gray bar with labels at the top two rows. ---
|
|
28
29
|
for (let i = 0; i < TEMPLATE_ROWS; i++) {
|
|
@@ -36,37 +37,37 @@ export function stampSupplementalTemplate(ws, startRow, supplementalNotes) {
|
|
|
36
37
|
c.value = null;
|
|
37
38
|
Object.assign(c, i === TEMPLATE_ROWS - 1 ? TPL_C_GRAY_BOTTOM : TPL_C_GRAY);
|
|
38
39
|
}
|
|
39
|
-
// --- Week-column content cells: each week pair (D-E, F-G,
|
|
40
|
+
// --- Week-column content cells: each week pair (D-E, F-G, …) is
|
|
40
41
|
// merged into a single master cell per row, matching the source files.
|
|
41
42
|
// Merging (plus wrapText on the style) lets a long phrase wrap inside
|
|
42
43
|
// the cell instead of clipping at the D/E boundary. Each cell is
|
|
43
44
|
// plain-white-filled. Borders are only on the "reps" columns
|
|
44
|
-
//
|
|
45
|
+
// and on the last weight column so the rendered area has:
|
|
45
46
|
// - a left edge on D
|
|
46
|
-
// -
|
|
47
|
-
// - a right edge on
|
|
47
|
+
// - a vertical divider between adjacent week pairs (E|F, G|H, …)
|
|
48
|
+
// - a right edge on the last weight column
|
|
48
49
|
// - top edge on row 0, bottom edge on row 9
|
|
49
50
|
// No horizontal lines between content rows.
|
|
50
51
|
for (let i = 0; i < TEMPLATE_ROWS; i++) {
|
|
51
52
|
const r = startRow + i;
|
|
52
53
|
const isTop = i === 0;
|
|
53
54
|
const isBottom = i === TEMPLATE_ROWS - 1;
|
|
54
|
-
for (let w = 0; w <
|
|
55
|
+
for (let w = 0; w < weekCount; w++) {
|
|
55
56
|
const left = WEEK_REPS_COLS[w];
|
|
56
57
|
const right = WEEK_WEIGHT_COLS[w];
|
|
57
|
-
const isLastPair = w ===
|
|
58
|
+
const isLastPair = w === weekCount - 1;
|
|
58
59
|
ws.mergeCells(`${left}${r}:${right}${r}`);
|
|
59
60
|
Object.assign(ws.getCell(`${left}${r}`), contentCellStyle({ side: "left", isTop, isBottom, isLastPair: false }));
|
|
60
61
|
Object.assign(ws.getCell(`${right}${r}`), contentCellStyle({ side: "right", isTop, isBottom, isLastPair }));
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
|
-
// --- Notes column
|
|
64
|
+
// --- Notes column: open above, closed at the bottom. ---
|
|
64
65
|
for (let i = 0; i < TEMPLATE_ROWS; i++) {
|
|
65
66
|
const r = startRow + i;
|
|
66
67
|
Object.assign(ws.getCell(`${NOTES_COL}${r}`), i === TEMPLATE_ROWS - 1 ? TPL_NOTES_LEFT_BOTTOM : TPL_NOTES_LEFT);
|
|
67
68
|
}
|
|
68
69
|
// --- Apply supplementalNotes on top of the template. Each note's col is a
|
|
69
|
-
// week-pair master (D, F, H,
|
|
70
|
+
// week-pair master (D, F, H, …), so writing to it fills the
|
|
70
71
|
// merged cell. ---
|
|
71
72
|
if (supplementalNotes) {
|
|
72
73
|
for (const note of supplementalNotes) {
|
|
@@ -95,10 +96,9 @@ function contentCellStyle(opts) {
|
|
|
95
96
|
// the outer left edge of the whole area.
|
|
96
97
|
if (opts.side === "left")
|
|
97
98
|
border.left = MEDIUM;
|
|
98
|
-
// The "right" cell of the LAST week pair
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
// cell (F, H, J, L, N).
|
|
99
|
+
// The "right" cell of the LAST week pair carries the right edge of the
|
|
100
|
+
// whole area. Other "right" cells carry no right border — the divider to
|
|
101
|
+
// the next pair is provided by THAT pair's left cell.
|
|
102
102
|
if (opts.side === "right" && opts.isLastPair)
|
|
103
103
|
border.right = MEDIUM;
|
|
104
104
|
if (opts.isTop)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supplemental-template.js","sourceRoot":"","sources":["../../src/writer/supplemental-template.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"supplemental-template.js","sourceRoot":"","sources":["../../src/writer/supplemental-template.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workingdevshero/olympia-ait-adapter",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "MCP adapter that converts between Olympia Fitness & Performance XLSX workbooks (programs and companion warm-ups) and strict JSON schemas.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,27 +47,43 @@ JSON shape (zod-validated; every tool call re-validates):
|
|
|
47
47
|
Program { client, programDate, days[] }
|
|
48
48
|
Day { name, sections[], supplementalNotes?[] }
|
|
49
49
|
Section { kind: "warmup"|"main"|"sportSpecific"|"supplemental"|"conditioning", exercises[] }
|
|
50
|
-
Exercise { name, groupLabel?, notes?, sets[][] } //
|
|
50
|
+
Exercise { name, groupLabel?, notes?, sets[][], weights?[][] } // [setIdx][weekIdx], one entry per week
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
- One sheet per day; sheet name = day name (`"Day 1"`).
|
|
54
|
-
-
|
|
55
|
-
|
|
54
|
+
- Week grid: a program runs a fixed number of weeks, 4 or 6 at Olympia
|
|
55
|
+
(1-6 accepted). Every set row has one cell per week, in week order, and
|
|
56
|
+
every set row in the program must be the same length. Decoding a client's
|
|
57
|
+
past program tells you their week count — author the new program with the
|
|
58
|
+
same count; the sheet is laid out with exactly that many week columns.
|
|
59
|
+
Set positions are coherent across weeks (`sets[0]` is set 1's
|
|
56
60
|
progression).
|
|
57
61
|
- `groupLabel` matches `/^\d+[A-Z]$/`. Same number = one superset/circuit
|
|
58
62
|
group (1A/1B run back-to-back).
|
|
59
63
|
- Cell notation: `"12"` (reps), `"10E"` (each side), `":20"` (20-sec hold),
|
|
60
64
|
`":20E"`, `":60"`, `"5 breaths"`, or freeform circuit strings like
|
|
61
|
-
`"x3 Rest :60"`.
|
|
65
|
+
`"x3 Rest :60"`. `null` = empty cell.
|
|
66
|
+
- `weights` is the Weight column beside each reps cell, same shape as
|
|
67
|
+
`sets` (`weights[setIdx][weekIdx]`). Cells are free text and most are
|
|
68
|
+
empty, because the client writes in what they lifted. Coaches type a
|
|
69
|
+
starting load (`"25"`) or an equipment setting — band colour (`"Yel"`),
|
|
70
|
+
box height (`'12" + 2 Pads'`), rack position (`"#10"`) — usually in
|
|
71
|
+
week 1 only. A bodyweight exercise may have empty reps and a setting in
|
|
72
|
+
every Weight cell. Omit `weights` when every cell is empty.
|
|
62
73
|
- The row-2 `Date:` cells are **intentionally blank** — clients hand-write
|
|
63
74
|
week dates. Never author values for them.
|
|
64
|
-
- `Section.kind: "warmup"`
|
|
65
|
-
sheet
|
|
75
|
+
- `Section.kind: "warmup"` holds warm-up exercises listed *inside* a
|
|
76
|
+
program day sheet, above the main exercises. On the sheet each one is
|
|
77
|
+
closed by a "Warmup N" label row where a main exercise has its group
|
|
78
|
+
label, so give them no `groupLabel`. One set is fine. It is
|
|
79
|
+
unrelated to the companion warm-up workbook.
|
|
66
80
|
- `supplementalNotes` is the freeform trainer-managed area at the bottom of
|
|
67
81
|
a day sheet: sparse `{ row, col, value }` entries where `row` is the
|
|
68
|
-
offset from the area's first row and `col` is
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
offset from the area's first row and `col` is a week-column master:
|
|
83
|
+
`D/F/H/J` for a 4-week program, plus `L/N` for a 6-week one. Any other
|
|
84
|
+
column is rejected. One full
|
|
85
|
+
phrase per row; to span the row visually,
|
|
86
|
+
repeat the same `value` in each week column.
|
|
71
87
|
|
|
72
88
|
## Warm-up format
|
|
73
89
|
|