训记训练数据 Open API
Use the official v2 API for training records only. Read references/api.md before the first API operation in a task.
Mandatory safeguards
- Call the API only when the user explicitly asks to read, export, organize, analyze, sync, import, or write training data.
- Read authentication only from
XUNJI_API_KEY. Never print, log, cache, embed, or pass it in a body/query string.
- Cache by
datestr. Reuse cached results and do not issue duplicate reads for the same date. Choose light or full mode before the first call.
- Enforce the 90-second per-training-day read interval. On
too frequent, report the server retry time and wait; do not loop.
- Remove any returned field named
key before displaying or caching data.
- Use Chinese movement names only for writes. Never send an internal movement key.
- If a movement name is uncertain, consult
https://github.com/Foveluy/Xunji-movements and select an exact Chinese name. Do not invent one; ask the user when ambiguity remains.
- Never perform a real write in the same turn that first proposes the change. Show a concise change summary and wait for explicit user confirmation.
Read workflow
- Decide whether light data is sufficient. Use full data when the request needs unchecked sets, RPE, notes, completion feelings, left/right weights, actual duration, or detailed composite sets.
- Run:
python scripts/xunji_open_api.py read --date 2026-04-02
python scripts/xunji_open_api.py read --date 2026-04-02 --full
- Treat
res.trains as the training list. Preserve localid, start, and end when preparing updates.
- Parse record-style metrics from
sets[].metrics. Composite sets may contain child movements in sets[].items[].
- Use the cached response for all subsequent work on that date.
The default cache directory is ~/.codex/cache/xunji-training-open-api/. Override it with --cache-dir only when task isolation requires it.
Write workflow
- For an existing training, read full data first and preserve unchecked sets plus
localid, start, and end unless the user explicitly changes time.
- Build a JSON payload containing only the training records being created or updated. Omission never means deletion.
- Validate and summarize offline:
python scripts/xunji_open_api.py summarize --file proposed-trains.json
- Show the user the date, title, created/updated records, movement changes, set changes, and any time changes. Wait for explicit confirmation.
- After confirmation, run the server dry run first:
python scripts/xunji_open_api.py upsert --file proposed-trains.json
- If the dry run succeeds and still matches the approved summary, apply exactly that payload:
python scripts/xunji_open_api.py upsert --file proposed-trains.json --apply --confirmed
- Use the normalized response returned by the server as the new cache state.
Write constraints
- Send at most 4 trainings, all for the same
datestr.
- Send at most 15 movements per training and 20 sets per movement.
- Include
localid to update; omit it to create. Do not delete old trainings merely because they are absent from the payload.
- When
localid is present, retain start and end unless the user approved a time change.
- Each simple set must include at least one of
weight, weight_kg, reps, time, duration_s, or selfWeight.
- Preserve incomplete sets with
done: false.
- Never include secrets or authorization fields in a payload file.
Errors
apikey missing or apikey invalid: ask the user to copy or regenerate the key in 训记, then configure XUNJI_API_KEY locally.
仅VIP可用: explain that the account requires the relevant membership permission.
- Unknown movement: stop and ask for confirmation after checking the standard Chinese movement list.
- Validation failure: do not call the API; correct the draft first.
1---2name: xunji-training-open-api3description: Securely read, export, normalize, summarize, cache, and write back Xunji (训记) training records through the official LLM Open API v2. Use when the user asks to import, export, inspect, organize, analyze, sync, or modify 训记 training data.4---56# 训记训练数据 Open API78Use the official v2 API for training records only. Read `references/api.md` before the first API operation in a task.910## Mandatory safeguards1112- Call the API only when the user explicitly asks to read, export, organize, analyze, sync, import, or write training data.13- Read authentication only from `XUNJI_API_KEY`. Never print, log, cache, embed, or pass it in a body/query string.14- Cache by `datestr`. Reuse cached results and do not issue duplicate reads for the same date. Choose light or full mode before the first call.15- Enforce the 90-second per-training-day read interval. On `too frequent`, report the server retry time and wait; do not loop.16- Remove any returned field named `key` before displaying or caching data.17- Use Chinese movement names only for writes. Never send an internal movement key.18- If a movement name is uncertain, consult `https://github.com/Foveluy/Xunji-movements` and select an exact Chinese name. Do not invent one; ask the user when ambiguity remains.19- Never perform a real write in the same turn that first proposes the change. Show a concise change summary and wait for explicit user confirmation.2021## Read workflow22231. Decide whether light data is sufficient. Use full data when the request needs unchecked sets, RPE, notes, completion feelings, left/right weights, actual duration, or detailed composite sets.242. Run:2526```powershell27python scripts/xunji_open_api.py read --date 2026-04-0228python scripts/xunji_open_api.py read --date 2026-04-02 --full29```30313. Treat `res.trains` as the training list. Preserve `localid`, `start`, and `end` when preparing updates.324. Parse record-style metrics from `sets[].metrics`. Composite sets may contain child movements in `sets[].items[]`.335. Use the cached response for all subsequent work on that date.3435The default cache directory is `~/.codex/cache/xunji-training-open-api/`. Override it with `--cache-dir` only when task isolation requires it.3637## Write workflow38391. For an existing training, read full data first and preserve unchecked sets plus `localid`, `start`, and `end` unless the user explicitly changes time.402. Build a JSON payload containing only the training records being created or updated. Omission never means deletion.413. Validate and summarize offline:4243```powershell44python scripts/xunji_open_api.py summarize --file proposed-trains.json45```46474. Show the user the date, title, created/updated records, movement changes, set changes, and any time changes. Wait for explicit confirmation.485. After confirmation, run the server dry run first:4950```powershell51python scripts/xunji_open_api.py upsert --file proposed-trains.json52```53546. If the dry run succeeds and still matches the approved summary, apply exactly that payload:5556```powershell57python scripts/xunji_open_api.py upsert --file proposed-trains.json --apply --confirmed58```59607. Use the normalized response returned by the server as the new cache state.6162## Write constraints6364- Send at most 4 trainings, all for the same `datestr`.65- Send at most 15 movements per training and 20 sets per movement.66- Include `localid` to update; omit it to create. Do not delete old trainings merely because they are absent from the payload.67- When `localid` is present, retain `start` and `end` unless the user approved a time change.68- Each simple set must include at least one of `weight`, `weight_kg`, `reps`, `time`, `duration_s`, or `selfWeight`.69- Preserve incomplete sets with `done: false`.70- Never include secrets or authorization fields in a payload file.7172## Errors7374- `apikey missing` or `apikey invalid`: ask the user to copy or regenerate the key in 训记, then configure `XUNJI_API_KEY` locally.75- `仅VIP可用`: explain that the account requires the relevant membership permission.76- Unknown movement: stop and ask for confirmation after checking the standard Chinese movement list.77- Validation failure: do not call the API; correct the draft first.78