@workingdevshero/olympia-ait-adapter 0.1.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -28
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/reader/cell-utils.d.ts +10 -0
- package/dist/reader/cell-utils.d.ts.map +1 -0
- package/dist/reader/cell-utils.js +40 -0
- package/dist/reader/cell-utils.js.map +1 -0
- package/dist/reader/parse-day-sheet.d.ts +0 -1
- package/dist/reader/parse-day-sheet.d.ts.map +1 -1
- package/dist/reader/parse-day-sheet.js +1 -50
- package/dist/reader/parse-day-sheet.js.map +1 -1
- package/dist/reader/parse-warmup-workbook.d.ts +13 -0
- package/dist/reader/parse-warmup-workbook.d.ts.map +1 -0
- package/dist/reader/parse-warmup-workbook.js +154 -0
- package/dist/reader/parse-warmup-workbook.js.map +1 -0
- package/dist/reader/parse-workbook.d.ts +2 -2
- package/dist/reader/parse-workbook.d.ts.map +1 -1
- package/dist/reader/parse-workbook.js +1 -6
- package/dist/reader/parse-workbook.js.map +1 -1
- package/dist/schema/program.d.ts +35 -48
- package/dist/schema/program.d.ts.map +1 -1
- package/dist/schema/program.js +26 -15
- package/dist/schema/program.js.map +1 -1
- package/dist/schema/warmup.d.ts +426 -0
- package/dist/schema/warmup.d.ts.map +1 -0
- package/dist/schema/warmup.js +100 -0
- package/dist/schema/warmup.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +51 -18
- package/dist/server.js.map +1 -1
- package/dist/tools/program-json-to-xlsx.d.ts +3 -0
- package/dist/tools/program-json-to-xlsx.d.ts.map +1 -0
- package/dist/tools/program-json-to-xlsx.js +5 -0
- package/dist/tools/program-json-to-xlsx.js.map +1 -0
- package/dist/tools/program-xlsx-to-json.d.ts +3 -0
- package/dist/tools/program-xlsx-to-json.d.ts.map +1 -0
- package/dist/tools/program-xlsx-to-json.js +5 -0
- package/dist/tools/program-xlsx-to-json.js.map +1 -0
- package/dist/tools/warmup-json-to-xlsx.d.ts +3 -0
- package/dist/tools/warmup-json-to-xlsx.d.ts.map +1 -0
- package/dist/tools/warmup-json-to-xlsx.js +5 -0
- package/dist/tools/warmup-json-to-xlsx.js.map +1 -0
- package/dist/tools/warmup-xlsx-to-json.d.ts +3 -0
- package/dist/tools/warmup-xlsx-to-json.d.ts.map +1 -0
- package/dist/tools/warmup-xlsx-to-json.js +5 -0
- package/dist/tools/warmup-xlsx-to-json.js.map +1 -0
- package/dist/writer/build-warmup-workbook.d.ts +3 -0
- package/dist/writer/build-warmup-workbook.d.ts.map +1 -0
- package/dist/writer/build-warmup-workbook.js +101 -0
- package/dist/writer/build-warmup-workbook.js.map +1 -0
- package/dist/writer/build-workbook.d.ts +2 -2
- package/dist/writer/build-workbook.d.ts.map +1 -1
- package/dist/writer/build-workbook.js +1 -11
- package/dist/writer/build-workbook.js.map +1 -1
- package/package.json +5 -4
- package/skills/olympia-authoring/SKILL.md +124 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program-xlsx-to-json.js","sourceRoot":"","sources":["../../src/tools/program-xlsx-to-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAMnE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAA6B;IAE7B,OAAO,oBAAoB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warmup-json-to-xlsx.d.ts","sourceRoot":"","sources":["../../src/tools/warmup-json-to-xlsx.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,sBAAsB,CAAC,CAEjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warmup-json-to-xlsx.js","sourceRoot":"","sources":["../../src/tools/warmup-json-to-xlsx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAMzE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAA4B;IAE5B,OAAO,mBAAmB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warmup-xlsx-to-json.d.ts","sourceRoot":"","sources":["../../src/tools/warmup-xlsx-to-json.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,sBAAsB,CAAC,CAEjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warmup-xlsx-to-json.js","sourceRoot":"","sources":["../../src/tools/warmup-xlsx-to-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAMzE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAA4B;IAE5B,OAAO,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-warmup-workbook.d.ts","sourceRoot":"","sources":["../../src/writer/build-warmup-workbook.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAyC7B,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,CAAC,CAwEjC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import ExcelJS from "exceljs";
|
|
3
|
+
// The warm-up format shares nothing with the program format (no borders,
|
|
4
|
+
// no fills, no logo, Calibri instead of Arial), so its four styles live
|
|
5
|
+
// here instead of in styles.ts.
|
|
6
|
+
const FONT_BASE = {
|
|
7
|
+
name: "Calibri",
|
|
8
|
+
family: 2,
|
|
9
|
+
size: 14,
|
|
10
|
+
};
|
|
11
|
+
const CENTER = { horizontal: "center" };
|
|
12
|
+
const WU_DAY_HEADER = {
|
|
13
|
+
font: { ...FONT_BASE, bold: true, underline: true },
|
|
14
|
+
alignment: CENTER,
|
|
15
|
+
};
|
|
16
|
+
const WU_SECTION_HEADER = {
|
|
17
|
+
font: { ...FONT_BASE, bold: true },
|
|
18
|
+
alignment: CENTER,
|
|
19
|
+
};
|
|
20
|
+
const WU_ITEM = {
|
|
21
|
+
font: { ...FONT_BASE },
|
|
22
|
+
alignment: { ...CENTER, wrapText: true },
|
|
23
|
+
};
|
|
24
|
+
// Italic — not the source files' plain-12pt convention — so that notes
|
|
25
|
+
// without surrounding parentheses still decode as notes (the reader treats
|
|
26
|
+
// italic as the primary note marker).
|
|
27
|
+
const WU_NOTE = {
|
|
28
|
+
font: { ...FONT_BASE, italic: true },
|
|
29
|
+
alignment: { ...CENTER, wrapText: true },
|
|
30
|
+
};
|
|
31
|
+
const DAY_COLUMN_WIDTH = 35.83203125;
|
|
32
|
+
const DAY_HEADER_ROW = 1;
|
|
33
|
+
const FIRST_SECTION_ROW = 3;
|
|
34
|
+
export async function buildWarmUpWorkbook(doc, outputPath) {
|
|
35
|
+
const workbook = new ExcelJS.Workbook();
|
|
36
|
+
workbook.creator = "olympia-ait-adapter";
|
|
37
|
+
workbook.created = new Date(0);
|
|
38
|
+
workbook.modified = new Date(0);
|
|
39
|
+
workbook.title = `${doc.client} Warm Up ${doc.warmUpDate}`;
|
|
40
|
+
workbook.subject = doc.client;
|
|
41
|
+
workbook.keywords = doc.warmUpDate;
|
|
42
|
+
const ws = workbook.addWorksheet("Sheet1");
|
|
43
|
+
ws.pageSetup.orientation = "landscape";
|
|
44
|
+
ws.views = [{ style: "pageLayout" }];
|
|
45
|
+
// Day i lives in column 1 + 2i (A, C, E, …) with empty gutter columns
|
|
46
|
+
// between; all columns through the last day column get the same width.
|
|
47
|
+
const colOf = (dayIdx) => 1 + 2 * dayIdx;
|
|
48
|
+
for (let c = 1; c <= colOf(doc.days.length - 1); c++) {
|
|
49
|
+
ws.getColumn(c).width = DAY_COLUMN_WIDTH;
|
|
50
|
+
}
|
|
51
|
+
for (const [dayIdx, day] of doc.days.entries()) {
|
|
52
|
+
const cell = ws.getRow(DAY_HEADER_ROW).getCell(colOf(dayIdx));
|
|
53
|
+
cell.value = day.name;
|
|
54
|
+
Object.assign(cell, WU_DAY_HEADER);
|
|
55
|
+
}
|
|
56
|
+
// Sections are row-aligned across days: section s starts on the same row
|
|
57
|
+
// in every day column, and the next section starts after the tallest
|
|
58
|
+
// day's block (items + notes) plus one blank spacer row.
|
|
59
|
+
const sectionCount = Math.max(...doc.days.map((d) => d.sections.length));
|
|
60
|
+
let row = FIRST_SECTION_ROW;
|
|
61
|
+
for (let s = 0; s < sectionCount; s++) {
|
|
62
|
+
let blockHeight = 0;
|
|
63
|
+
for (const [dayIdx, day] of doc.days.entries()) {
|
|
64
|
+
const section = day.sections[s];
|
|
65
|
+
if (!section)
|
|
66
|
+
continue;
|
|
67
|
+
if (section.title !== "") {
|
|
68
|
+
const cell = ws.getRow(row).getCell(colOf(dayIdx));
|
|
69
|
+
cell.value = section.title;
|
|
70
|
+
Object.assign(cell, WU_SECTION_HEADER);
|
|
71
|
+
}
|
|
72
|
+
let r = row + 1;
|
|
73
|
+
for (const item of section.items) {
|
|
74
|
+
const itemCell = ws.getRow(r).getCell(colOf(dayIdx));
|
|
75
|
+
itemCell.value = item.text;
|
|
76
|
+
Object.assign(itemCell, WU_ITEM);
|
|
77
|
+
r++;
|
|
78
|
+
if (item.note !== undefined) {
|
|
79
|
+
// The schema rejects blank note lines, but direct library callers
|
|
80
|
+
// bypass it — skip them so layout height matches what the reader
|
|
81
|
+
// can observe (blank cells are structural no-ops on decode).
|
|
82
|
+
const lines = item.note
|
|
83
|
+
.split("\n")
|
|
84
|
+
.filter((line) => line.trim() !== "");
|
|
85
|
+
for (const line of lines) {
|
|
86
|
+
const noteCell = ws.getRow(r).getCell(colOf(dayIdx));
|
|
87
|
+
noteCell.value = line;
|
|
88
|
+
Object.assign(noteCell, WU_NOTE);
|
|
89
|
+
r++;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
blockHeight = Math.max(blockHeight, r - (row + 1));
|
|
94
|
+
}
|
|
95
|
+
row += 1 + blockHeight + 1; // header + tallest block + blank spacer
|
|
96
|
+
}
|
|
97
|
+
await workbook.xlsx.writeFile(outputPath);
|
|
98
|
+
const stat = await fs.stat(outputPath);
|
|
99
|
+
return { outputPath, bytesWritten: stat.size };
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=build-warmup-workbook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-warmup-workbook.js","sourceRoot":"","sources":["../../src/writer/build-warmup-workbook.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function
|
|
1
|
+
import type { ProgramJsonToXlsxOutput, Program } from "../schema/program.js";
|
|
2
|
+
export declare function buildProgramWorkbook(program: Program, outputPath: string): Promise<ProgramJsonToXlsxOutput>;
|
|
3
3
|
//# sourceMappingURL=build-workbook.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-workbook.d.ts","sourceRoot":"","sources":["../../src/writer/build-workbook.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"build-workbook.d.ts","sourceRoot":"","sources":["../../src/writer/build-workbook.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,uBAAuB,EACvB,OAAO,EAER,MAAM,sBAAsB,CAAC;AAgC9B,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,CAAC,CAyJlC"}
|
|
@@ -8,7 +8,7 @@ import { groupNumberOf, stampExercise } from "./stamp-exercise.js";
|
|
|
8
8
|
import { stampSupplementalTemplate } from "./supplemental-template.js";
|
|
9
9
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
const LOGO_PATH = path.resolve(here, "../../src/assets/olympia-logo.png");
|
|
11
|
-
export async function
|
|
11
|
+
export async function buildProgramWorkbook(program, outputPath) {
|
|
12
12
|
const workbook = new ExcelJS.Workbook();
|
|
13
13
|
workbook.creator = "olympia-ait-adapter";
|
|
14
14
|
workbook.created = new Date(0);
|
|
@@ -107,16 +107,6 @@ export async function buildWorkbook(program, outputPath) {
|
|
|
107
107
|
Object.assign(ws.getCell(`${WEEK_WEIGHT_COLS[i]}6`), headerPadBelowStyle("weight"));
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
// Week dates (row 2) — override "Date:" labels if program has them.
|
|
111
|
-
if (program.weekDates) {
|
|
112
|
-
for (let i = 0; i < 6; i++) {
|
|
113
|
-
const v = program.weekDates[i];
|
|
114
|
-
if (v) {
|
|
115
|
-
const c = ws.getCell(`${WEEK_REPS_COLS[i]}${DATE_ROW}`);
|
|
116
|
-
c.value = v;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
110
|
// --- Body: walk sections, stamp exercises with neighbor-aware borders. ---
|
|
121
111
|
let row = FIRST_EXERCISE_ROW;
|
|
122
112
|
for (const section of day.sections) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-workbook.js","sourceRoot":"","sources":["../../src/writer/build-workbook.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,OAAO,EACL,aAAa,EACb,QAAQ,EACR,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,eAAe,EACf,SAAS,EACT,UAAU,EACV,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,UAAU,EACV,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,mCAAmC,CAAC,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"build-workbook.js","sourceRoot":"","sources":["../../src/writer/build-workbook.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workingdevshero/olympia-ait-adapter",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP adapter that converts between Olympia Fitness & Performance
|
|
3
|
+
"version": "1.0.0",
|
|
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": {
|
|
7
7
|
"olympia-ait-adapter": "./dist/bin.js"
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
13
|
-
"src/assets"
|
|
13
|
+
"src/assets",
|
|
14
|
+
"skills"
|
|
14
15
|
],
|
|
15
16
|
"scripts": {
|
|
16
17
|
"build": "tsc -p tsconfig.json && chmod +x dist/bin.js",
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
"dev": "tsx src/bin.ts",
|
|
19
20
|
"test": "vitest run",
|
|
20
21
|
"test:watch": "vitest",
|
|
21
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
22
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.scripts.json",
|
|
22
23
|
"prepublishOnly": "npm run build && npm test"
|
|
23
24
|
},
|
|
24
25
|
"publishConfig": {
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: olympia-authoring
|
|
3
|
+
description: Technical reference for decoding and authoring Olympia Fitness program and warm-up documents via the olympia-ait-adapter MCP tools — JSON schemas, prescription notation, layout conventions, and the decode → author → encode workflow.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Olympia document authoring
|
|
7
|
+
|
|
8
|
+
Technical specifics for working with Olympia Fitness & Performance client
|
|
9
|
+
paperwork through the `olympia-ait-adapter` MCP tools. Two document types
|
|
10
|
+
exist, with different formats and separate tool pairs.
|
|
11
|
+
|
|
12
|
+
## The document pair
|
|
13
|
+
|
|
14
|
+
A client's paperwork for one training cycle is **two workbooks**:
|
|
15
|
+
|
|
16
|
+
- `<Client> Programs <M.YY>.xlsx` — the training program
|
|
17
|
+
- `<Client> Warm Up <M.YY>.xlsx` — its companion warm-up document
|
|
18
|
+
|
|
19
|
+
Same client, same date identifier (`4.26` = April 2026). The pairing is
|
|
20
|
+
day-for-day: the warm-up's "Day 4" column is performed before the program's
|
|
21
|
+
"Day 4" sheet. Each program day sheet carries a "Warm Up #N" label that
|
|
22
|
+
refers to the matching day in the companion warm-up workbook. When
|
|
23
|
+
authoring, day names in the warm-up document must match the program's day
|
|
24
|
+
sheet names.
|
|
25
|
+
|
|
26
|
+
## Tools
|
|
27
|
+
|
|
28
|
+
| Tool | Input | Output |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `olympia_program_xlsx_to_json` | `{ xlsxPath }` | `{ program, warnings }` |
|
|
31
|
+
| `olympia_program_json_to_xlsx` | `{ program, outputPath }` | `{ outputPath, bytesWritten }` |
|
|
32
|
+
| `olympia_warmup_xlsx_to_json` | `{ xlsxPath }` | `{ warmUp, warnings }` |
|
|
33
|
+
| `olympia_warmup_json_to_xlsx` | `{ warmUp, outputPath }` | `{ outputPath, bytesWritten }` |
|
|
34
|
+
|
|
35
|
+
Paths are absolute; the output parent directory must exist. `warnings`
|
|
36
|
+
lists structural surprises found while parsing — treat any warning as a
|
|
37
|
+
signal the source file deviated from the expected layout.
|
|
38
|
+
|
|
39
|
+
All schemas are strict: unknown fields are rejected with an error, never
|
|
40
|
+
silently dropped (e.g. the removed `weekDates` field fails loudly).
|
|
41
|
+
|
|
42
|
+
## Program format
|
|
43
|
+
|
|
44
|
+
JSON shape (zod-validated; every tool call re-validates):
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
Program { client, programDate, days[] }
|
|
48
|
+
Day { name, sections[], supplementalNotes?[] }
|
|
49
|
+
Section { kind: "warmup"|"main"|"sportSpecific"|"supplemental"|"conditioning", exercises[] }
|
|
50
|
+
Exercise { name, groupLabel?, notes?, sets[][] } // sets[setIdx][weekIdx], inner length 6
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- One sheet per day; sheet name = day name (`"Day 1"`).
|
|
54
|
+
- Six-week grid: every set row has exactly 6 cells, one per week, in week
|
|
55
|
+
order. Set positions are coherent across weeks (`sets[0]` is set 1's
|
|
56
|
+
progression).
|
|
57
|
+
- `groupLabel` matches `/^\d+[A-Z]$/`. Same number = one superset/circuit
|
|
58
|
+
group (1A/1B run back-to-back).
|
|
59
|
+
- Cell notation: `"12"` (reps), `"10E"` (each side), `":20"` (20-sec hold),
|
|
60
|
+
`":20E"`, `":60"`, `"5 breaths"`, or freeform circuit strings like
|
|
61
|
+
`"x3 Rest :60"`. Weights are **never** prescribed; `null` = empty cell.
|
|
62
|
+
- The row-2 `Date:` cells are **intentionally blank** — clients hand-write
|
|
63
|
+
week dates. Never author values for them.
|
|
64
|
+
- `Section.kind: "warmup"` is the short warmup row *inside* a program day
|
|
65
|
+
sheet. It is unrelated to the companion warm-up workbook.
|
|
66
|
+
- `supplementalNotes` is the freeform trainer-managed area at the bottom of
|
|
67
|
+
a day sheet: sparse `{ row, col, value }` entries where `row` is the
|
|
68
|
+
offset from the area's first row and `col` is one of the week-column
|
|
69
|
+
masters `D/F/H/J/L/N`. One full phrase per row; to span the row visually,
|
|
70
|
+
repeat the same `value` in each of the six columns.
|
|
71
|
+
|
|
72
|
+
## Warm-up format
|
|
73
|
+
|
|
74
|
+
JSON shape:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
WarmUpDocument { client, warmUpDate, days[] }
|
|
78
|
+
WarmUpDay { name, sections[] }
|
|
79
|
+
WarmUpSection { title, items[] }
|
|
80
|
+
WarmUpItem { text, note? }
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- Single sheet; **days are columns** (A, C, E, … with empty gutter columns
|
|
84
|
+
between), not sheets. Day label at the top of each column.
|
|
85
|
+
- Sections are row-aligned across days: each section header sits on the
|
|
86
|
+
same row in every day column, padded with blank rows where days are
|
|
87
|
+
ragged.
|
|
88
|
+
- `title` is the bold header line and may embed a rounds count, e.g.
|
|
89
|
+
`"Prep \ Activation X2 Rounds"`.
|
|
90
|
+
- `text` is one freeform exercise line with the prescription embedded:
|
|
91
|
+
observed shorthand includes `:45E`, `:45EL`, `:30E`, `X8br`, `X8 Br E`,
|
|
92
|
+
`X10EL`, `X4ES`. These are trainer conventions — treat them as opaque,
|
|
93
|
+
copy the style of the client's past documents, never invent new notation
|
|
94
|
+
semantics.
|
|
95
|
+
- `note` is an annotation line rendered under its item (italic in encoded
|
|
96
|
+
output), stored verbatim including decoration, e.g.
|
|
97
|
+
`"(^R.F.E on SB, F-Roller for Balance^)"`. Multiple note lines join with
|
|
98
|
+
`"\n"`; every line must be non-empty (blank lines don't survive a
|
|
99
|
+
round-trip). Omit the field when there is no note — `note: ""` is
|
|
100
|
+
rejected.
|
|
101
|
+
- Never author an item whose **entire** text is wrapped in parentheses —
|
|
102
|
+
fully-parenthesized lines decode as notes attached to the previous item.
|
|
103
|
+
|
|
104
|
+
## Workflow
|
|
105
|
+
|
|
106
|
+
1. Decode the client's most recent program **and** companion warm-up
|
|
107
|
+
(`*_xlsx_to_json`) to learn their conventions: section titles, notation
|
|
108
|
+
style, day count, volume.
|
|
109
|
+
2. Author new JSON conforming to the schema. Keep warm-up day names
|
|
110
|
+
matched to the program's day sheets and both documents' date
|
|
111
|
+
identifiers equal.
|
|
112
|
+
3. Encode with `*_json_to_xlsx` to `<Client> Programs <M.YY>.xlsx` /
|
|
113
|
+
`<Client> Warm Up <M.YY>.xlsx`.
|
|
114
|
+
|
|
115
|
+
## Gotchas
|
|
116
|
+
|
|
117
|
+
- A `WarmUpSection` with `title: ""` is a decode artifact (items appeared
|
|
118
|
+
before any bold header in the source) — don't author empty titles.
|
|
119
|
+
- Round-trip fidelity is at the **JSON level**: decode → encode → decode
|
|
120
|
+
yields identical JSON, but the encoded file is a canonical layout, not a
|
|
121
|
+
byte-for-byte copy of a hand-made source.
|
|
122
|
+
- Client/date metadata: the encoders stamp them into workbook properties;
|
|
123
|
+
the decoders fall back to parsing the filename, so keep the filename
|
|
124
|
+
conventions exact.
|