--- url: /docs/guide/quick-start.md description: >- Convert a Garmin FIT file to TCX in 4 lines of TypeScript using Kaiord. Install, convert, done in under 5 minutes. --- # Quick Start By the end of this guide, you'll convert a Garmin FIT file to TCX in 4 lines of TypeScript. ## Prerequisites * Node.js 20+ (24 recommended) * pnpm 9.15+ ## 1. Install packages ```bash pnpm add @kaiord/core @kaiord/fit @kaiord/tcx ``` ## 2. Create `convert.ts` ```ts twoslash import { fromBinary, toBinary, toText } from "@kaiord/core"; import { fitReader } from "@kaiord/fit"; import { tcxWriter } from "@kaiord/tcx"; import { readFile, writeFile } from "node:fs/promises"; // Read a FIT file const buffer = await readFile("workout.fit"); // Convert FIT -> KRD (canonical format) -> TCX const krd = await fromBinary(new Uint8Array(buffer), fitReader); const tcx = await toText(krd, tcxWriter); // Write the result await writeFile("workout.tcx", tcx); ``` ## 3. Run it ```bash npx tsx convert.ts ``` Your `workout.tcx` file is ready. ## What just happened? 1. `fromBinary` parsed the FIT file into **KRD**, Kaiord's canonical JSON format. 2. `toText` serialized the KRD data into TCX XML. 3. All type information was preserved through the conversion. KRD acts as the universal intermediate format. Every conversion goes through it: ``` FIT ──> KRD ──> TCX FIT ──> KRD ──> ZWO TCX ──> KRD ──> FIT ``` ## 4. Inspect the KRD data ```ts twoslash import { fromBinary } from "@kaiord/core"; import { fitReader } from "@kaiord/fit"; import { readFile } from "node:fs/promises"; const buffer = await readFile("workout.fit"); const krd = await fromBinary(new Uint8Array(buffer), fitReader); // KRD is a typed object you can inspect console.log(krd.metadata.sport); console.log(krd.version); ``` ## 5. Try the CLI instead No code needed -- install the CLI and convert from your terminal: ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.fit -o workout.tcx ``` ## Next steps * [Why Kaiord?](/guide/why-kaiord) -- understand the problem Kaiord solves * [Formats](/formats/krd) -- learn about KRD and supported formats * [Architecture](/guide/architecture) -- how the hexagonal architecture works * [CLI Reference](/cli/commands) -- all CLI commands and options --- --- url: /docs/guide/why-kaiord.md description: >- Kaiord is a unified TypeScript SDK to convert FIT, TCX, ZWO, and Garmin Connect workout files. Stop juggling parsers -- one SDK, every format. --- # Why Kaiord? ## The problem Fitness data is fragmented. Garmin uses FIT (binary), TrainingPeaks uses TCX (XML), Zwift uses ZWO (XML), and Garmin Connect has its own JSON API. If you need to convert a FIT file to TCX in TypeScript, you are on your own -- there is no unified SDK. Developers end up: * Installing separate parsing libraries for each format * Writing custom glue code to convert between them * Losing data during conversions because formats have different capabilities * Maintaining fragile pipelines that break when SDKs update ## Kaiord's approach Kaiord defines **KRD** (Kaiord Representation Definition), a canonical JSON format that captures the superset of all supported formats. Every conversion goes through KRD: ``` FIT ──> KRD ──> TCX ZWO ──> KRD ──> FIT GCN ──> KRD ──> ZWO ``` This means: * **One SDK** for reading and writing all formats * **Round-trip safe** conversions with defined tolerances * **Type-safe** -- every field is validated with Zod schemas * **Extensible** -- add new formats without changing existing code ## How Kaiord compares | Capability | Individual parsers | Kaiord | | ------------------------- | ------------------------------- | --------------------------- | | Read FIT files | `@garmin/fitsdk` | `@kaiord/fit` | | Read TCX files | `fast-xml-parser` + custom code | `@kaiord/tcx` | | Read ZWO files | Manual XML parsing | `@kaiord/zwo` | | Garmin Connect API format | Custom JSON mapping | `@kaiord/garmin` | | Convert between formats | DIY glue code | `fromBinary` / `toText` | | Round-trip validation | Not available | Built-in `validate` command | | TypeScript types | Partial or none | Full Zod schemas | | CLI tool | Build your own | `@kaiord/cli` | | AI/LLM integration | Not available | `@kaiord/mcp` | ## Who is Kaiord for? * **Developers** building fitness apps that need to import/export workout files * **Data engineers** processing Garmin, Zwift, or TrainingPeaks data pipelines * **Coaches** who want to convert workout plans between platforms programmatically * **AI builders** integrating fitness data into LLM workflows via MCP ## Search-friendly terms If you searched for any of these, Kaiord is what you need: * Convert FIT file to TCX in TypeScript * Parse Garmin FIT files in Node.js * Zwift workout file converter * Garmin Connect workout API TypeScript * FIT to JSON converter * Fitness file format SDK ## Get started ```bash pnpm add @kaiord/core @kaiord/fit @kaiord/tcx ``` Ready to convert? Follow the [Quick Start](/guide/quick-start). --- --- url: /docs/guide/getting-started.md description: >- Install Kaiord, convert your first workout file, and learn the basics of the library and CLI tool. --- # Getting Started with Kaiord Kaiord is an open-source framework for health and fitness data. It helps you: * Convert files between formats (FIT, TCX, ZWO, GCN, KRD) * Read and write health and fitness data in your programs * Validate and compare files across formats ## Prerequisites * **Node.js** 20+ (24 recommended) -- [download](https://nodejs.org/) * **pnpm** package manager -- [install guide](https://pnpm.io/installation) ```bash node --version # v20.0.0 or higher pnpm --version # 9.15.0 or higher ``` ## Installation ### Library ```bash pnpm add @kaiord/core ``` Add format adapters as needed: ```bash pnpm add @kaiord/fit @kaiord/tcx @kaiord/zwo @kaiord/garmin ``` ### CLI ```bash pnpm add -g @kaiord/cli ``` Or use without installing: ```bash pnpx @kaiord/cli --help ``` ## Library usage ### Convert FIT to KRD ```ts twoslash import { fromBinary } from "@kaiord/core"; import { fitReader } from "@kaiord/fit"; import { readFile } from "node:fs/promises"; const buffer = await readFile("workout.fit"); const krd = await fromBinary(new Uint8Array(buffer), fitReader); console.log(krd.metadata.sport); ``` ### Convert KRD to TCX ```ts twoslash import type { KRD } from "@kaiord/core"; import { toText } from "@kaiord/core"; import { tcxWriter } from "@kaiord/tcx"; import { writeFile } from "node:fs/promises"; declare const krd: KRD; const tcxString = await toText(krd, tcxWriter); await writeFile("workout.tcx", tcxString); ``` ### Read a Zwift workout ```ts twoslash import { fromText } from "@kaiord/core"; import { zwiftReader } from "@kaiord/zwo"; import { readFile } from "node:fs/promises"; const zwoContent = await readFile("workout.zwo", "utf-8"); const krd = await fromText(zwoContent, zwiftReader); ``` ## CLI usage ```bash # Convert FIT to KRD kaiord convert -i workout.fit -o workout.krd # Convert KRD to TCX kaiord convert -i workout.krd -o workout.tcx # Validate round-trip integrity kaiord validate -i workout.fit # Inspect a file kaiord inspect -i workout.fit ``` ## Error handling ```ts twoslash import { fromBinary } from "@kaiord/core"; import { fitReader } from "@kaiord/fit"; declare const buffer: Uint8Array; try { const krd = await fromBinary(buffer, fitReader); console.log("Success!"); } catch (error) { console.error("Conversion failed:", (error as Error).message); } ``` ## Next steps * [Architecture Guide](/guide/architecture) -- how Kaiord is built * [KRD Format](/formats/krd) -- the canonical format specification * [Testing Guide](/guide/testing) -- testing practices * [CLI Reference](/cli/commands) -- all commands and options --- --- url: /docs/guide/architecture.md description: >- Kaiord uses hexagonal architecture with ports and adapters. Learn about layer structure, use case patterns, and schema-first development. --- # Architecture Kaiord uses **Hexagonal Architecture** (Ports and Adapters) to keep business logic separate from technical details. ## Layer structure ``` packages/core/src/ ├── domain/ # Business rules and data types │ ├── schemas/ # Zod schemas for KRD format │ ├── validation/ # Business validators │ └── types/ # Error types ├── application/ # Use cases (business operations) ├── ports/ # Contracts for external services └── adapters/ # Logger implementation only ``` Format adapters live in their own packages: ``` packages/fit/src/ # FIT reader/writer (Garmin FIT SDK) packages/tcx/src/ # TCX reader/writer (fast-xml-parser) packages/zwo/src/ # ZWO reader/writer (fast-xml-parser) packages/garmin/src/ # GCN reader/writer (Garmin Connect JSON) ``` ## Dependency rules * **domain** depends on nothing (pure business logic) * **application** depends only on domain and ports * **adapters** implement ports and can use external libraries * **CLI/MCP** depend on application (not adapters directly) You can change how files are read or written without touching business logic. ## Hexagonal architecture explained The architecture separates code into layers: 1. **Domain Layer** -- business rules (what makes the app unique) 2. **Application Layer** -- use cases (what the app does) 3. **Ports** -- contracts for external services (what you need from outside) 4. **Adapters** -- implementations of ports (how you connect to outside) **Benefits**: testable, flexible, clear separation, maintainable. ### Example: reading a FIT file **Port (contract)**: ```typescript // ports/binary-reader.ts import type { KRD } from "../domain/schemas/krd"; export type BinaryReader = (buffer: Uint8Array) => Promise; ``` **Adapter (implementation)**: ```typescript // packages/fit/src/adapters/garmin-fitsdk.ts import type { BinaryReader } from "@kaiord/core"; export const createGarminFitSdkReader = (logger: Logger): BinaryReader => async (buffer: Uint8Array): Promise => { const stream = Stream.fromByteArray(Array.from(buffer)); const decoder = new Decoder(stream); const { messages } = decoder.read(); return convertMessagesToKRD(messages); }; ``` **Use case**: ```typescript // application/from-format.ts export const fromBinary = async ( buffer: Uint8Array, reader: BinaryReader, logger?: Logger ): Promise => { return reader(buffer); }; ``` ## Use case pattern Kaiord uses **strategy injection** -- readers and writers are passed as arguments to generic core functions: ```ts twoslash import { fromBinary, toText } from "@kaiord/core"; import { fitReader } from "@kaiord/fit"; import { tcxWriter } from "@kaiord/tcx"; declare const buffer: Uint8Array; // The core function is format-agnostic const krd = await fromBinary(buffer, fitReader); const tcx = await toText(krd, tcxWriter); ``` No dependency injection framework needed. Functions are composed at entry points (CLI, MCP). ### Curried use cases For more complex use cases, Kaiord uses currying for dependency injection. The use case receives adapters (ports) as dependencies and delegates work to them -- validation stays at adapter boundaries, not inside use cases: ```typescript // First function receives dependencies (adapters) // Second function receives operation parameters export const convertFitToKrd = (fitReader: FitReader) => async (params: { fitBuffer: Uint8Array }): Promise => { // The adapter validates internally at the boundary return fitReader(params.fitBuffer); }; ``` Composition happens at entry points: ```typescript const fitReader = createFitReader(logger); const convertFitToKrdUseCase = convertFitToKrd(fitReader); const krd = await convertFitToKrdUseCase({ fitBuffer }); ``` ## Schema-first development Kaiord uses **Zod as the single source of truth**: 1. Define Zod schemas first, infer types after 2. Validate at boundaries (CLI input, adapter output) 3. Use cases receive already-validated types ```typescript // domain/schemas/sport.ts export const sportSchema = z.enum([ "cycling", "running", "swimming", "generic", ]); export type Sport = z.infer; ``` ### Schema conventions * **Domain schemas** use `snake_case`: `indoor_cycling`, `lap_swimming` * **Adapter schemas** use `camelCase`: `indoorCycling`, `lapSwimming` * Access enum values via `.enum`: `sportSchema.enum.cycling` ### Enum schemas Use `z.enum()` for enumeration types, never TypeScript `enum` or constant objects: ```typescript export const subSportSchema = z.enum([ "generic", "indoor_cycling", // snake_case in domain "lap_swimming", ]); export type SubSport = z.infer; // Access values at runtime subSportSchema.enum.indoor_cycling; // "indoor_cycling" ``` ### Validation at boundaries Validate at entry points (CLI, adapters), not in use cases: ```typescript // Adapter validates its output before returning export const createFitReader = (logger: Logger): FitReader => async (buffer: Uint8Array): Promise => { const rawData = decoder.read(buffer); const krd = convertFitMessagesToKRD(rawData.messages); return krdSchema.parse(krd); // Validate at boundary }; ``` ## Error handling Errors follow Clean Architecture principles: 1. **Define** in domain layer (custom Error classes) 2. **Transform** at boundaries (adapters catch external errors, wrap in domain errors) 3. **Propagate** upward (use cases do not catch errors) 4. **Log** at entry points only (CLI, MCP) ``` Domain Layer → Define custom Error classes Application Layer → Propagate errors (add context if needed) Adapters Layer → Catch external errors, transform to domain errors Entry Points → Catch all errors, log, format response ``` ### Domain error classes All domain errors extend `Error` with descriptive names: * **FitParsingError** -- FIT file parsing failures * **KrdValidationError** -- KRD schema validation failures (includes field-level errors) * **ToleranceExceededError** -- round-trip tolerance violations (includes per-field deviations) ### Error transformation in adapters Adapters catch external library errors and wrap them: ```typescript export const createFitReader = (logger: Logger): FitReader => async (buffer: Uint8Array): Promise => { try { const { messages } = decoder.read(buffer); return convertMessagesToKRD(messages); } catch (error) { throw new FitParsingError("Failed to parse FIT file", error); } }; ``` ## Next steps * [KRD Format](/formats/krd) -- the canonical data format * [Testing Guide](/guide/testing) -- testing practices and TDD * [Quick Start](/guide/quick-start) -- build something in 5 minutes --- --- url: /docs/guide/testing.md description: >- Testing practices for Kaiord: TDD workflow, AAA pattern, round-trip tests, fixture management, and coverage requirements. --- # Testing Guide Kaiord uses a comprehensive testing strategy with multiple test types. ## Test types * **Unit tests** -- individual functions and components * **Integration tests** -- how components work together * **Round-trip tests** -- data integrity through format conversions * **E2E tests** -- complete user workflows * **Property-based tests** -- universal properties across many inputs ## Test stack | Package | Runner | Coverage target | | -------------- | -------------- | --------------------------- | | `@kaiord/core` | Vitest | 80% overall, 90% converters | | `@kaiord/fit` | Vitest | 80% | | `@kaiord/tcx` | Vitest | 80% | | `@kaiord/zwo` | Vitest | 80% | | Frontend SPA | Vitest + jsdom | 70% | ## TDD workflow Every task follows Test-Driven Development: 1. **Write the test first** -- before implementing 2. **Run the test** -- verify it fails (red) 3. **Write minimal code** -- make the test pass (green) 4. **Refactor** -- improve code while keeping tests green 5. **Commit** -- each task is a functional commit ## AAA pattern All tests use Arrange-Act-Assert with clear sections: ```typescript it("should convert FIT buffer to KRD", async () => { // Arrange const fitBuffer = new Uint8Array([1, 2, 3, 4]); const mockReader = vi.fn().mockResolvedValue(buildKRD.build()); // Act const result = await fromBinary(fitBuffer, mockReader); // Assert expect(result).toStrictEqual(mockReader.mock.results[0].value); }); ``` ## Test organization Tests are co-located with source code: ``` src/ ├── domain/ │ └── validation/ │ ├── schema-validator.ts │ └── schema-validator.test.ts ├── adapters/ │ └── fit/ │ ├── garmin-fitsdk.ts │ └── garmin-fitsdk.test.ts └── application/ └── use-cases/ ├── convert-fit-to-krd.ts └── convert-fit-to-krd.test.ts ``` ## Mappers vs converters **Mappers** (`*.mapper.ts`) -- simple data transformation, no logic. Do **not** test directly. **Converters** (`*.converter.ts`) -- business logic, calculations. **Must** test with 90%+ coverage. ## Round-trip tests Validate data integrity through conversions (FIT to KRD to FIT): **Tolerances**: * Time: +/- 1 second * Power: +/- 1 watt or +/- 1% FTP * Heart rate: +/- 1 bpm * Cadence: +/- 1 rpm ```typescript it("should preserve data in FIT round-trip", async () => { // Arrange const originalKrd = buildKRD.build(); // Act const fitBuffer = await convertKrdToFit(originalKrd); const roundTripKrd = await convertFitToKrd(fitBuffer); // Assert expect(roundTripKrd).toMatchKrdWithTolerance(originalKrd, { time: 1, power: 1, heartRate: 1, cadence: 1, }); }); ``` ## Fixture management Use Faker for realistic data, Rosie for factories: ```typescript import { faker } from "@faker-js/faker"; import { Factory } from "rosie"; export const buildEntity = new Factory() .attr("id", () => faker.string.uuid()) .attr("name", () => faker.lorem.word()); ``` Rules: * Fixtures generate data, tests validate * Do not call `.parse()` in fixtures * Keep fixtures simple ## What to test and what not to test **Test**: converters, validators, use cases, error handling, edge cases, round-trips. **Do not test**: types, mappers, fixtures, type definitions, third-party libraries. ## Test assertions * Use `toStrictEqual()` for objects -- validates complete structure * Use fixtures with `.build()` -- generate realistic data * Include all fields in assertions * One `expect` per object, not per property ```typescript // Good -- complete object validation expect(metadata).toStrictEqual({ created: "2025-01-15T10:30:00Z", manufacturer: metadata.manufacturer, sport: "running", subSport: metadata.subSport, }); // Avoid -- multiple expects for same object expect(metadata.created).toBe("2025-01-15T10:30:00Z"); expect(metadata.sport).toBe("running"); ``` ## Coverage strategy Mappers get coverage indirectly through: 1. **Integration tests** -- testing adapters that use mappers 2. **Round-trip tests** -- FIT to KRD to FIT conversions 3. **Converter tests** -- converters that call mappers 4. **Use case tests** -- end-to-end flows If a mapper has low coverage, it means the mapper is unused, has logic that should be in a converter, or is missing integration test scenarios. ## Frontend testing ### Component tests (React Testing Library) ```typescript describe("Button", () => { it("should call onClick when clicked", async () => { // Arrange const handleClick = vi.fn(); const user = userEvent.setup(); renderWithProviders(); // Act await user.click(screen.getByRole("button")); // Assert expect(handleClick).toHaveBeenCalledOnce(); }); }); ``` Use semantic queries in this order: `getByRole` > `getByLabelText` > `getByPlaceholderText` > `getByText` > `getByTestId` (last resort). ### Store tests (Zustand) Reset state before each test: ```typescript beforeEach(() => { useWorkoutStore.setState({ currentWorkout: null, workoutHistory: [], historyIndex: -1, }); }); ``` ### E2E tests (Playwright) ```typescript test("should load and edit workout", async ({ page }) => { await page.goto("/"); await page.getByRole("button", { name: /load workout/i }).click(); await page.getByRole("textbox", { name: /workout name/i }).fill("New Name"); await page.getByRole("button", { name: /save/i }).click(); await expect(page.getByText("Workout saved")).toBeVisible(); }); ``` ## Running tests ```bash # All tests pnpm -r test # Single package cd packages/core && pnpm test # Watch mode pnpm -r test:watch # With coverage pnpm test -- --coverage # E2E tests (frontend) cd packages/workout-spa-editor && pnpm test:e2e ``` ## Best practices **Do**: test user behavior, use semantic queries, test accessibility, test error states, follow AAA pattern, use fixtures. **Don't**: test implementation details, test types (TypeScript handles this), test mappers directly, test third-party libraries, use `getByTestId` as first choice. ## Next steps * [Architecture](/guide/architecture) -- how layers are tested in isolation * [Quick Start](/guide/quick-start) -- build something to test --- --- url: /docs/guide/contributing.md description: >- How to contribute to Kaiord: development setup, coding standards, PR workflow, and commit conventions. --- # Contributing Kaiord welcomes contributions. This guide covers the development workflow. ## Setup ```bash git clone https://github.com/pablo-albaladejo/kaiord.git cd kaiord pnpm install pnpm -r build pnpm -r test ``` ## Branch naming * `feature/my-feature` -- new features * `fix/my-fix` -- bug fixes * `docs/my-docs` -- documentation changes ## Commit messages Follow [Conventional Commits](https://www.conventionalcommits.org/): ``` feat(core): add ZWO round-trip validation fix(fit): handle empty lap arrays docs: update architecture guide ``` ## PR workflow 1. Create a feature branch from `main` 2. Implement changes following hexagonal architecture 3. Add tests (TDD -- failing test first) 4. Run `pnpm -r test && pnpm -r build && pnpm lint:fix` 5. Add changeset: `pnpm exec changeset` 6. Open a PR against `main` ## Code style * TypeScript strict mode * Max 100 lines per file (tests exempt) * Max 40 lines per function * Use `type` not `interface` * Separate type imports: `import type { X } from "..."` * Functions over classes ## Next steps * [Architecture](/guide/architecture) -- understand the codebase structure * [Testing](/guide/testing) -- testing practices * [Quick Start](/guide/quick-start) -- try Kaiord before contributing --- --- url: /docs/convert.md description: >- Free, in-browser converter for FIT, TCX, ZWO, and Garmin Connect workout files. No account, no upload. Plus a CLI and TypeScript SDK for developers. --- # Workout file converter — FIT, TCX, ZWO & Garmin Convert workout files between **FIT**, **TCX**, **ZWO** (Zwift), and **Garmin Connect** formats — free, in your browser, with no account and no file upload. Drop a file into the [Kaiord Editor](https://kaiord.com/editor/) and download the result. Developers can script the same conversions with the [CLI](/cli/commands) or the [TypeScript SDK](/guide/quick-start). Every conversion goes through **KRD**, Kaiord's canonical format, so round-trips stay within tight tolerances (time ±1 s, power ±1 W or ±1 % FTP, heart rate ±1 bpm, cadence ±1 rpm). See the [KRD format](/formats/krd) for the details. ## Pick a conversion | From ↓ / To → | FIT | TCX | ZWO (Zwift) | Garmin | | ------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | | **FIT** | — | [FIT → TCX](/convert/fit-to-tcx) | [FIT → ZWO](/convert/fit-to-zwo) | [FIT → Garmin](/convert/fit-to-garmin) | | **TCX** | [TCX → FIT](/convert/tcx-to-fit) | — | [TCX → ZWO](/convert/tcx-to-zwo) | [TCX → Garmin](/convert/tcx-to-garmin) | | **ZWO** | [ZWO → FIT](/convert/zwo-to-fit) | [ZWO → TCX](/convert/zwo-to-tcx) | — | [ZWO → Garmin](/convert/zwo-to-garmin) | | **Garmin** | [Garmin → FIT](/convert/garmin-to-fit) | [Garmin → TCX](/convert/garmin-to-tcx) | [Garmin → ZWO](/convert/garmin-to-zwo) | — | All twelve directed pairs have a guided walkthrough. Every conversion uses the same [`kaiord convert`](/cli/commands#convert) command and SDK calls — the format is detected from the file extension. ## Three ways to convert 1. **Editor** — [kaiord.com/editor](https://kaiord.com/editor/). Drag & drop a file, pick the target format, download. Nothing leaves your browser. 2. **CLI** — `kaiord convert -i workout.fit -o workout.zwo`. Formats are detected from the extensions. See the [CLI reference](/cli/commands#convert). 3. **SDK** — `@kaiord/core` plus the reader/writer for each format. See the [Quick Start](/guide/quick-start). ## What is lossless? KRD is designed to be round-trip safe, but the source and target formats are not identical — each pair page has a **"What survives the conversion"** table and the gotchas that matter for that direction. In short: * **FIT** is the richest workout format (power, heart rate, cadence, speed, and distance/time durations). * **TCX** workout targets are heart rate, speed, and cadence — **not power**. * **ZWO** is power-based (% of FTP); heart-rate and cadence targets have no native equivalent. * **Garmin Connect (GCN)** covers power, heart rate, speed, and cadence in watts/bpm/rpm, plus calorie durations. Format-specific data that has no target-side equivalent is preserved under the KRD `extensions` object so it can survive a later round-trip. ## Formats * [FIT](/formats/fit) — Garmin's binary protocol * [TCX](/formats/tcx) — Training Center XML * [ZWO](/formats/zwo) — Zwift workout XML * [GCN](/formats/gcn) — Garmin Connect JSON * [KRD](/formats/krd) — Kaiord's canonical format --- --- url: /docs/convert/fit-to-zwo.md description: >- Convert a Garmin FIT workout to a Zwift ZWO file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. See exactly what survives the conversion. --- # Convert FIT to ZWO Turn a **Garmin FIT** workout into a **Zwift ZWO** file so a structured session from your head unit or coach can run in Zwift. The fastest way is the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) — no account and no file upload. Developers can use the [CLI](/cli/commands#convert) or the [TypeScript SDK](/guide/quick-start). Every conversion goes through Kaiord's canonical [KRD format](/formats/krd), so values stay within round-trip tolerances (time ±1 s, power ±1 W or ±1 % FTP). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.fit` file, choose **ZWO** as the export format, and download `workout.zwo`. Everything runs locally in your browser. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.fit -o workout.zwo ``` The format is detected from the file extensions. Add `--input-format fit` if your file has a non-standard extension. ### 3. SDK ```ts import { fromBinary, toText } from "@kaiord/core"; import { fitReader } from "@kaiord/fit"; import { zwiftWriter } from "@kaiord/zwo"; import { readFile, writeFile } from "node:fs/promises"; const buffer = await readFile("workout.fit"); const krd = await fromBinary(new Uint8Array(buffer), fitReader); const zwo = await toText(krd, zwiftWriter); await writeFile("workout.zwo", zwo); ``` ## What survives the conversion | Data | FIT | ZWO (Zwift) | Result | | ------------------- | -------------------- | ------------------------------------- | -------------------------------------------------------------------------- | | Step order & names | workout steps | `SteadyState` / `Warmup` / `Cooldown` | Preserved (names kept as `kaiord:` attributes) | | Time durations | seconds | `Duration` seconds | Preserved (±1 s) | | Distance durations | meters | time-based `Duration` | Converted to time; original meters kept in `kaiord:originalDurationMeters` | | Power targets | watts / % FTP / zone | `Power` (fraction of FTP) | Normalized to % FTP (see FTP note below) | | Heart-rate targets | bpm / zone | — | Dropped (Zwift is power-based); kept under `extensions.zwift` | | Cadence targets | rpm | limited | Preserved under `extensions.zwift` | | Repeats / intervals | repeat steps | `IntervalsT` | Preserved | The Kaiord CLI logs a warning for every lossy step (for example `Lossy conversion: heart rate target not supported by Zwift`) so you can see exactly what changed. ## Gotchas **Do I need my FTP?** ZWO expresses power as a fraction of FTP. If your FIT targets are absolute watts, the conversion maps them to % FTP using a default FTP assumption — rescale in Zwift (or the Editor) if the exact watts matter. Zone- and %FTP-based FIT targets map across directly. **My heart-rate targets are gone.** Zwift workouts are power-based and ZWO has no native heart-rate target, so HR targets are dropped from the visible workout. Kaiord preserves them under `extensions.zwift` so a later ZWO → FIT round-trip can restore them. **My distance intervals became time intervals.** ZWO durations are time-based. Distance durations are converted to time and the original distance is preserved in `kaiord:originalDurationMeters`. ## Related * [Convert ZWO to FIT](/convert/zwo-to-fit) — the reverse direction * [Convert FIT to TCX](/convert/fit-to-tcx) — a sibling FIT export * [FIT format](/formats/fit) · [ZWO format](/formats/zwo) * [All converters](/convert/) --- --- url: /docs/convert/zwo-to-fit.md description: >- Convert a Zwift ZWO workout to a Garmin FIT file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. Push the result to your Garmin head unit. --- # Convert ZWO to FIT Turn a **Zwift ZWO** workout into a **Garmin FIT** file so a session built in Zwift can run on your Garmin head unit or watch. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) — no account, no upload — or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start) if you prefer to script it. Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, power ±1 W or ±1 % FTP). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.zwo` file, choose **FIT** as the export format, and download `workout.fit`. It runs entirely in your browser. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.zwo -o workout.fit ``` ### 3. SDK ```ts import { fromText, toBinary } from "@kaiord/core"; import { zwiftReader } from "@kaiord/zwo"; import { fitWriter } from "@kaiord/fit"; import { readFile, writeFile } from "node:fs/promises"; const zwo = await readFile("workout.zwo", "utf-8"); const krd = await fromText(zwo, zwiftReader); const fit = await toBinary(krd, fitWriter); await writeFile("workout.fit", fit); ``` ## What survives the conversion | Data | ZWO (Zwift) | FIT | Result | | ------------------ | ------------------------------ | ------------------- | -------------------------------------- | | Step order & names | blocks | workout steps | Preserved | | Time durations | `Duration` seconds | seconds | Preserved (±1 s) | | Power targets | % FTP (`Power` fraction) | power target | Preserved (±1 % FTP) | | Ramps | `Warmup` / `Cooldown` / `Ramp` | ranged power target | Preserved as a power range | | Free-ride segments | `FreeRide` | open step | Preserved as an untargeted step | | Cadence targets | limited | rpm | Preserved when present | | Text events | in-ride messages | — | Not part of the FIT workout definition | ## Gotchas **Will it load on my Garmin?** FIT is Garmin's native workout format, so the output is directly loadable. To send it to your device, push it with the CLI — `kaiord garmin push -i workout.fit --input-format fit` — or use the Editor's Garmin integration. See the [garmin command](/cli/commands#garmin). **Sport type.** ZWO uses `bike` or `run`; these map to the FIT `cycling` / `running` sports. Zwift workouts are overwhelmingly cycling, so most files land as indoor cycling on your device. **In-ride text messages don't transfer.** ZWO text events are Zwift-specific overlays and are not part of the FIT workout target model, so they are not emitted into the FIT file. ## Related * [Convert FIT to ZWO](/convert/fit-to-zwo) — the reverse direction * [Convert Garmin to ZWO](/convert/garmin-to-zwo) — sibling Zwift export * [ZWO format](/formats/zwo) · [FIT format](/formats/fit) * [All converters](/convert/) --- --- url: /docs/convert/fit-to-tcx.md description: >- Convert a Garmin FIT workout to a TCX (Training Center XML) file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. See what survives the conversion. --- # Convert FIT to TCX Turn a **Garmin FIT** workout into a **TCX** (Training Center XML) file — the format most training platforms accept for import. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, heart rate ±1 bpm, cadence ±1 rpm). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.fit` file, choose **TCX** as the export format, and download `workout.tcx`. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.fit -o workout.tcx ``` ### 3. SDK ```ts import { fromBinary, toText } from "@kaiord/core"; import { fitReader } from "@kaiord/fit"; import { tcxWriter } from "@kaiord/tcx"; import { readFile, writeFile } from "node:fs/promises"; const buffer = await readFile("workout.fit"); const krd = await fromBinary(new Uint8Array(buffer), fitReader); const tcx = await toText(krd, tcxWriter); await writeFile("workout.tcx", tcx); ``` ## What survives the conversion | Data | FIT | TCX | Result | | ------------------- | ------------- | --------------------------- | ----------------------------------------------- | | Step order & names | workout steps | `` / `` | Preserved | | Time durations | seconds | `Time_t` seconds | Preserved (±1 s) | | Distance durations | meters | `Distance_t` meters | Preserved | | Heart-rate targets | bpm / zone | `HeartRate_t` (zone or bpm) | Preserved (±1 bpm) | | Speed targets | m/s | `Speed_t` | Preserved | | Cadence targets | rpm | `Cadence_t` | Preserved (±1 rpm) | | Power targets | watts / % FTP | — | **Dropped** — TCX workouts have no power target | | Repeats / intervals | repeat steps | `Repeat_t` | Preserved | | Developer fields | custom fields | — | Preserved under `extensions.fit` | ## Gotchas **My power targets disappeared.** The TCX workout schema (Garmin Training Center) only defines heart-rate, speed, and cadence targets — there is no power target. If your FIT workout is power-based, convert it to [ZWO](/convert/fit-to-zwo) or Garmin Connect instead, which keep power. **Workouts vs. activities.** This page is about structured *workouts* (the target plan). TCX can also hold recorded *activity* data; Kaiord reads and writes both, but the field mapping above is for the workout definition. **Which apps accept TCX?** TrainingPeaks, Strava, and Garmin Connect all import TCX, which makes it a good interchange format when a platform can't read FIT directly. ## Related * [Convert TCX to FIT](/convert/tcx-to-fit) — the reverse direction * [Convert FIT to ZWO](/convert/fit-to-zwo) — keep power targets * [FIT format](/formats/fit) · [TCX format](/formats/tcx) * [All converters](/convert/) --- --- url: /docs/convert/tcx-to-fit.md description: >- Convert a TCX (Training Center XML) workout to a Garmin FIT file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. Push the result to your Garmin. --- # Convert TCX to FIT Turn a **TCX** (Training Center XML) workout into a **Garmin FIT** file so a plan exported from another platform can run on your Garmin device. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, heart rate ±1 bpm, cadence ±1 rpm). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.tcx` file, choose **FIT** as the export format, and download `workout.fit`. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.tcx -o workout.fit ``` ### 3. SDK ```ts import { fromText, toBinary } from "@kaiord/core"; import { tcxReader } from "@kaiord/tcx"; import { fitWriter } from "@kaiord/fit"; import { readFile, writeFile } from "node:fs/promises"; const tcx = await readFile("workout.tcx", "utf-8"); const krd = await fromText(tcx, tcxReader); const fit = await toBinary(krd, fitWriter); await writeFile("workout.fit", fit); ``` ## What survives the conversion | Data | TCX | FIT | Result | | ------------------- | --------------------------- | ------------- | ------------------ | | Step order & names | `` / `` | workout steps | Preserved | | Time durations | `Time_t` seconds | seconds | Preserved (±1 s) | | Distance durations | `Distance_t` meters | meters | Preserved | | Heart-rate targets | `HeartRate_t` (zone or bpm) | bpm / zone | Preserved (±1 bpm) | | Speed targets | `Speed_t` | m/s | Preserved | | Cadence targets | `Cadence_t` | rpm | Preserved (±1 rpm) | | Repeats / intervals | `Repeat_t` | repeat steps | Preserved | ## Gotchas **No power targets appear.** TCX workouts have no power target (the schema covers heart rate, speed, and cadence only), so a TCX-sourced FIT file won't gain power targets. If you need power, start from a [ZWO](/convert/zwo-to-fit) or Garmin Connect workout instead. **Getting it onto your Garmin.** Push the FIT file with the CLI — `kaiord garmin push -i workout.fit --input-format fit` — or use the Editor's Garmin integration. See the [garmin command](/cli/commands#garmin). **Sport mapping.** TCX `Sport` values (`Running`, `Biking`, `Other`) map to the corresponding FIT sports; anything unrecognized falls back to `Other`. ## Related * [Convert FIT to TCX](/convert/fit-to-tcx) — the reverse direction * [Convert ZWO to FIT](/convert/zwo-to-fit) — a power-based FIT source * [TCX format](/formats/tcx) · [FIT format](/formats/fit) * [All converters](/convert/) --- --- url: /docs/convert/zwo-to-garmin.md description: >- Convert a Zwift ZWO workout to Garmin Connect format and push it to your watch — free and in-browser, or via the Kaiord CLI and TypeScript SDK. --- # Convert ZWO to Garmin Take a **Zwift ZWO** workout into **Garmin Connect** so you can run a session you built in Zwift on your Garmin watch or head unit. Kaiord converts ZWO to the Garmin Connect workout format (GCN JSON) — free and in-browser in the [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or via the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, power ±1 W or ±1 % FTP). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.zwo` file, choose **Garmin (GCN)** as the export format, and download the result. To send it straight to your watch, use the Editor's Garmin sync (backed by the `garmin-bridge` extension). ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.zwo -o workout.gcn ``` To push directly to Garmin Connect (after `kaiord garmin login`): ```bash kaiord garmin push -i workout.zwo --input-format zwo ``` ### 3. SDK ```ts import { fromText, toText } from "@kaiord/core"; import { zwiftReader } from "@kaiord/zwo"; import { garminWriter } from "@kaiord/garmin"; import { readFile, writeFile } from "node:fs/promises"; const zwo = await readFile("workout.zwo", "utf-8"); const krd = await fromText(zwo, zwiftReader); const gcn = await toText(krd, garminWriter); await writeFile("workout.gcn", gcn); ``` ## What survives the conversion | Data | ZWO (Zwift) | Garmin Connect (GCN) | Result | | ------------------- | ------------------------------ | -------------------- | ------------------------------------------ | | Step order & names | blocks | workout steps | Preserved | | Time durations | `Duration` seconds | time durations | Preserved (±1 s) | | Power targets | % FTP (`Power` fraction) | watts | Converted using an assumed FTP (see below) | | Ramps | `Warmup` / `Cooldown` / `Ramp` | ranged target | Preserved as a power range | | Repeats / intervals | `IntervalsT` | repeat blocks | Preserved | | Free-ride segments | `FreeRide` | open step | Preserved as an untargeted step | ## Gotchas **Watts vs. % FTP.** Zwift stores power as % FTP; Garmin Connect stores watts. The conversion applies an assumed FTP (the output records it as `kaiord:assumedFtp`, e.g. 250 W) to turn percentages into watts. If exact watts matter, set your real FTP in Garmin Connect or rescale afterwards. **How does it get on my watch?** A `.gcn` file is Garmin Connect's JSON, not a device file. Push it to your account with `kaiord garmin push` (via [`@kaiord/garmin-connect`](/formats/gcn#garmin-connect-api)) or use the Editor's Garmin sync; Garmin Connect then syncs it to your device. **Heart-rate and cadence.** Zwift workouts are power-based, so ZWO rarely carries heart-rate or cadence targets to bring across. Any that exist are mapped where Garmin Connect supports them. ## Related * [Convert Garmin to ZWO](/convert/garmin-to-zwo) — the reverse direction * [Convert ZWO to FIT](/convert/zwo-to-fit) — a device-file alternative * [ZWO format](/formats/zwo) · [GCN format](/formats/gcn) * [All converters](/convert/) --- --- url: /docs/convert/garmin-to-zwo.md description: >- Convert a Garmin Connect workout to a Zwift ZWO file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. See exactly what survives the conversion. --- # Convert Garmin to ZWO Take a **Garmin Connect** workout (GCN JSON) into a **Zwift ZWO** file so a plan from Garmin can run in Zwift. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, power ±1 W or ±1 % FTP). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your Garmin Connect workout file, choose **ZWO** as the export format, and download `workout.zwo`. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.gcn -o workout.zwo ``` ### 3. SDK ```ts import { fromText, toText } from "@kaiord/core"; import { garminReader } from "@kaiord/garmin"; import { zwiftWriter } from "@kaiord/zwo"; import { readFile, writeFile } from "node:fs/promises"; const gcn = await readFile("workout.gcn", "utf-8"); const krd = await fromText(gcn, garminReader); const zwo = await toText(krd, zwiftWriter); await writeFile("workout.zwo", zwo); ``` ## What survives the conversion | Data | Garmin Connect (GCN) | ZWO (Zwift) | Result | | ------------------- | ----------------------- | ------------------------------- | ------------------------------------------------------------- | | Step order & names | workout steps | blocks (names as `kaiord:name`) | Preserved | | Time durations | time durations | `Duration` seconds | Preserved (±1 s) | | Distance durations | distance durations | time-based `Duration` | Converted to time; original kept under `extensions.zwift` | | Power targets | watts | % FTP (`Power` fraction) | Converted using an assumed FTP (see below) | | Repeats / intervals | repeat blocks | `IntervalsT` | Preserved | | Steps without power | open / non-power target | `FreeRide` | Rendered as a free-ride segment | | Heart-rate targets | bpm | — | Dropped (Zwift is power-based); kept under `extensions.zwift` | ## Gotchas **Watts vs. % FTP.** Garmin Connect stores power as watts; Zwift needs % FTP. The conversion divides watts by an assumed FTP (recorded as `kaiord:assumedFtp`, e.g. 250 W). If the percentages look off, rescale to your own FTP. **Non-power steps become free rides.** ZWO is power-centric. Garmin steps that target heart rate or have no power target become `FreeRide` segments, since Zwift has no equivalent structured target for them. **Where do I get the `.gcn` file?** GCN is Garmin Connect's workout JSON. Fetch it through the Garmin Connect API with [`@kaiord/garmin-connect`](/formats/gcn#garmin-connect-api) (e.g. `kaiord garmin list`) or the Editor's Garmin integration. ## Related * [Convert ZWO to Garmin](/convert/zwo-to-garmin) — the reverse direction * [Convert FIT to ZWO](/convert/fit-to-zwo) — a device-file source * [GCN format](/formats/gcn) · [ZWO format](/formats/zwo) * [All converters](/convert/) --- --- url: /docs/convert/fit-to-garmin.md description: >- Convert a Garmin FIT workout to Garmin Connect format (GCN JSON) and push it to your account — free and in-browser, or via the Kaiord CLI and TypeScript SDK. --- # Convert FIT to Garmin Turn a **Garmin FIT** workout into the **Garmin Connect** workout format (GCN JSON) so a session from a FIT file can live in your Garmin Connect account and sync to your watch or head unit. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, power ±1 W, heart rate ±1 bpm, cadence ±1 rpm). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.fit` file, choose **Garmin (GCN)** as the export format, and download the result. To send it straight to your account, use the Editor's Garmin sync (backed by the `garmin-bridge` extension). ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.fit -o workout.gcn ``` To push directly to Garmin Connect (after `kaiord garmin login`): ```bash kaiord garmin push -i workout.fit --input-format fit ``` ### 3. SDK ```ts import { fromBinary, toText } from "@kaiord/core"; import { fitReader } from "@kaiord/fit"; import { garminWriter } from "@kaiord/garmin"; import { readFile, writeFile } from "node:fs/promises"; const buffer = await readFile("workout.fit"); const krd = await fromBinary(new Uint8Array(buffer), fitReader); const gcn = await toText(krd, garminWriter); await writeFile("workout.gcn", gcn); ``` ## What survives the conversion | Data | FIT | Garmin Connect (GCN) | Result | | -------------------- | ------------- | --------------------- | ---------------------------------- | | Step order & names | workout steps | workout steps | Preserved | | Time durations | seconds | time durations | Preserved (±1 s) | | Distance durations | meters | distance durations | Preserved | | Power targets | watts / zone | watts / power zone | Preserved (±1 W; zones map across) | | Heart-rate targets | bpm / zone | bpm / heart-rate zone | Preserved (±1 bpm) | | Cadence targets | rpm | rpm | Preserved (±1 rpm) | | Speed / pace targets | m/s | m/s | Preserved | | Repeats / intervals | repeat steps | repeat blocks | Preserved | | Developer fields | custom fields | — | Preserved under `extensions.fit` | FIT and Garmin Connect are both Garmin-native, watt-based formats, so this is one of the highest-fidelity conversions Kaiord does — no assumed FTP is needed. ## Gotchas **FIT file vs. Garmin Connect JSON.** A `.fit` file is Garmin's on-device binary format; a `.gcn` file is Garmin Connect's workout JSON. They are not the same thing, which is why the conversion matters — the GCN output is what the Garmin Connect API accepts. **How does it get on my watch?** Push the `.gcn` to your account with `kaiord garmin push` (via [`@kaiord/garmin-connect`](/formats/gcn#garmin-connect-api)) or use the Editor's Garmin sync; Garmin Connect then syncs it to your device. **Developer and unknown fields.** FIT developer fields and unknown messages have no Garmin Connect equivalent, so they are kept under `extensions.fit` and survive a later `garmin-to-fit` round-trip rather than being emitted into the GCN workout. ## Related * [Convert Garmin to FIT](/convert/garmin-to-fit) — the reverse direction * [Convert FIT to TCX](/convert/fit-to-tcx) — a cross-platform FIT export * [FIT format](/formats/fit) · [GCN format](/formats/gcn) * [All converters](/convert/) --- --- url: /docs/convert/garmin-to-fit.md description: >- Convert a Garmin Connect workout (GCN JSON) to a Garmin FIT file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. Push the result to your device. --- # Convert Garmin to FIT Take a **Garmin Connect** workout (GCN JSON) into a **Garmin FIT** file — the on-device binary format — so a plan from your Garmin Connect account can be loaded as a native FIT workout. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, power ±1 W, heart rate ±1 bpm, cadence ±1 rpm). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your Garmin Connect workout file, choose **FIT** as the export format, and download `workout.fit`. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.gcn -o workout.fit ``` ### 3. SDK ```ts import { fromText, toBinary } from "@kaiord/core"; import { garminReader } from "@kaiord/garmin"; import { fitWriter } from "@kaiord/fit"; import { readFile, writeFile } from "node:fs/promises"; const gcn = await readFile("workout.gcn", "utf-8"); const krd = await fromText(gcn, garminReader); const fit = await toBinary(krd, fitWriter); await writeFile("workout.fit", fit); ``` ## What survives the conversion | Data | Garmin Connect (GCN) | FIT | Result | | -------------------- | -------------------- | ------------------ | ---------------------------------- | | Step order & names | workout steps | workout steps | Preserved | | Time durations | time durations | seconds | Preserved (±1 s) | | Distance durations | distance durations | meters | Preserved | | Power targets | watts / power zone | watts / zone | Preserved (±1 W; zones map across) | | Heart-rate targets | bpm | bpm / zone | Preserved (±1 bpm) | | Cadence targets | rpm | rpm | Preserved (±1 rpm) | | Speed / pace targets | m/s | m/s | Preserved | | Repeats / intervals | repeat blocks | repeat steps | Preserved | | Step notes | `description` | workout step notes | Preserved (truncated to 256 chars) | Both formats are Garmin-native and watt-based, so this is a high-fidelity conversion — no assumed FTP is needed. ## Gotchas **Where do I get the `.gcn` file?** GCN is Garmin Connect's workout JSON. Fetch it through the Garmin Connect API with [`@kaiord/garmin-connect`](/formats/gcn#garmin-connect-api) (e.g. `kaiord garmin list`) or the Editor's Garmin integration. **Will it load on my Garmin?** FIT is Garmin's native workout format, so the output is directly loadable. To send it to your device, push it with the CLI — `kaiord garmin push -i workout.fit --input-format fit` — or use the Editor's Garmin integration. **Calorie-based durations.** Garmin Connect can express a step duration in calories. KRD models calorie durations natively, so they carry through to FIT (which also supports calorie durations); a target format without them, such as [TCX](/convert/garmin-to-tcx), would not. ## Related * [Convert FIT to Garmin](/convert/fit-to-garmin) — the reverse direction * [Convert Garmin to ZWO](/convert/garmin-to-zwo) — a Zwift export * [GCN format](/formats/gcn) · [FIT format](/formats/fit) * [All converters](/convert/) --- --- url: /docs/convert/tcx-to-zwo.md description: >- Convert a TCX (Training Center XML) workout to a Zwift ZWO file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. See what survives the conversion. --- # Convert TCX to ZWO Turn a **TCX** (Training Center XML) workout into a **Zwift ZWO** file so a plan exported from a training platform can run in Zwift. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.tcx` file, choose **ZWO** as the export format, and download `workout.zwo`. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.tcx -o workout.zwo ``` ### 3. SDK ```ts import { fromText, toText } from "@kaiord/core"; import { tcxReader } from "@kaiord/tcx"; import { zwiftWriter } from "@kaiord/zwo"; import { readFile, writeFile } from "node:fs/promises"; const tcx = await readFile("workout.tcx", "utf-8"); const krd = await fromText(tcx, tcxReader); const zwo = await toText(krd, zwiftWriter); await writeFile("workout.zwo", zwo); ``` ## What survives the conversion | Data | TCX | ZWO (Zwift) | Result | | ------------------- | --------------------------- | --------------------- | ------------------------------------------------------------- | | Step order & names | `` / `` | blocks | Preserved (names kept as `kaiord:` attributes) | | Time durations | `Time_t` seconds | `Duration` seconds | Preserved (±1 s) | | Distance durations | `Distance_t` meters | time-based `Duration` | Converted to time; original kept under `extensions.zwift` | | Power targets | — (TCX has none) | `Power` (% FTP) | No power to carry — steps become `FreeRide` (see below) | | Heart-rate targets | `HeartRate_t` (zone or bpm) | — | Dropped (Zwift is power-based); kept under `extensions.zwift` | | Speed targets | `Speed_t` | — | Dropped (no Zwift equivalent); kept under `extensions.zwift` | | Cadence targets | `Cadence_t` | limited | Preserved under `extensions.zwift` | | Repeats / intervals | `Repeat_t` | `IntervalsT` | Preserved | ## Gotchas **My steps became free rides.** TCX workouts have no power target (the schema covers heart rate, speed, and cadence only), and Zwift workouts are power-based. With no power to map, the structured steps become `FreeRide` segments that keep their duration but have no power target. For a power-based Zwift workout, start from a source that carries power, such as [FIT](/convert/fit-to-zwo) or [Garmin Connect](/convert/garmin-to-zwo). **My heart-rate targets are gone.** ZWO has no native heart-rate target, so HR targets are dropped from the visible workout. Kaiord preserves them under `extensions.zwift` so a later ZWO → TCX round-trip can restore them. **Distance intervals became time intervals.** ZWO durations are time-based. Distance durations are converted to time, and the original distance is preserved under `extensions.zwift`. ## Related * [Convert ZWO to TCX](/convert/zwo-to-tcx) — the reverse direction * [Convert TCX to FIT](/convert/tcx-to-fit) — a device-file export * [TCX format](/formats/tcx) · [ZWO format](/formats/zwo) * [All converters](/convert/) --- --- url: /docs/convert/zwo-to-tcx.md description: >- Convert a Zwift ZWO workout to a TCX (Training Center XML) file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. See what survives the conversion. --- # Convert ZWO to TCX Turn a **Zwift ZWO** workout into a **TCX** (Training Center XML) file — the format most training platforms accept for import. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, cadence ±1 rpm). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.zwo` file, choose **TCX** as the export format, and download `workout.tcx`. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.zwo -o workout.tcx ``` ### 3. SDK ```ts import { fromText, toText } from "@kaiord/core"; import { zwiftReader } from "@kaiord/zwo"; import { tcxWriter } from "@kaiord/tcx"; import { readFile, writeFile } from "node:fs/promises"; const zwo = await readFile("workout.zwo", "utf-8"); const krd = await fromText(zwo, zwiftReader); const tcx = await toText(krd, tcxWriter); await writeFile("workout.tcx", tcx); ``` ## What survives the conversion | Data | ZWO (Zwift) | TCX | Result | | ------------------- | ------------------------------ | ------------------- | ----------------------------------------------- | | Step order & names | blocks | `` / `` | Preserved | | Time durations | `Duration` seconds | `Time_t` seconds | Preserved (±1 s) | | Power targets | % FTP (`Power` fraction) | — | **Dropped** — TCX workouts have no power target | | Ramps | `Warmup` / `Cooldown` / `Ramp` | untargeted steps | Duration preserved; the power ramp is dropped | | Cadence targets | limited | `Cadence_t` | Preserved when present (±1 rpm) | | Free-ride segments | `FreeRide` | untargeted step | Preserved as a step without a target | | Repeats / intervals | `IntervalsT` | `Repeat_t` | Preserved | ## Gotchas **My power targets disappeared.** The TCX workout schema (Garmin Training Center) defines heart-rate, speed, and cadence targets only — there is no power target. Zwift workouts are power-based (% FTP), so the power targets have nowhere to land and are dropped; the step structure and durations remain. To keep power, convert to [FIT](/convert/zwo-to-fit) or [Garmin Connect](/convert/zwo-to-garmin) instead. **So why convert to TCX at all?** TCX is a widely accepted interchange format — TrainingPeaks, Strava, and Garmin Connect all import it — so it is useful when you want the workout's structure (steps, durations, intervals) on a platform that reads TCX but cannot read ZWO. Just expect the power targets not to come along. **Cadence.** If your ZWO carries cadence targets, they map to TCX `Cadence_t` targets. Most Zwift workouts are pure power, so this is often empty. ## Related * [Convert TCX to ZWO](/convert/tcx-to-zwo) — the reverse direction * [Convert ZWO to FIT](/convert/zwo-to-fit) — keep power targets * [ZWO format](/formats/zwo) · [TCX format](/formats/tcx) * [All converters](/convert/) --- --- url: /docs/convert/tcx-to-garmin.md description: >- Convert a TCX (Training Center XML) workout to Garmin Connect format and push it to your watch — free and in-browser, or via the Kaiord CLI and TypeScript SDK. --- # Convert TCX to Garmin Take a **TCX** (Training Center XML) workout into the **Garmin Connect** workout format (GCN JSON) so a plan exported from another platform can run on your Garmin watch or head unit. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, heart rate ±1 bpm, cadence ±1 rpm). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your `.tcx` file, choose **Garmin (GCN)** as the export format, and download the result. To send it straight to your watch, use the Editor's Garmin sync (backed by the `garmin-bridge` extension). ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.tcx -o workout.gcn ``` To push directly to Garmin Connect (after `kaiord garmin login`): ```bash kaiord garmin push -i workout.tcx --input-format tcx ``` ### 3. SDK ```ts import { fromText, toText } from "@kaiord/core"; import { tcxReader } from "@kaiord/tcx"; import { garminWriter } from "@kaiord/garmin"; import { readFile, writeFile } from "node:fs/promises"; const tcx = await readFile("workout.tcx", "utf-8"); const krd = await fromText(tcx, tcxReader); const gcn = await toText(krd, garminWriter); await writeFile("workout.gcn", gcn); ``` ## What survives the conversion | Data | TCX | Garmin Connect (GCN) | Result | | -------------------- | --------------------------- | -------------------- | ------------------------- | | Step order & names | `` / `` | workout steps | Preserved | | Time durations | `Time_t` seconds | time durations | Preserved (±1 s) | | Distance durations | `Distance_t` meters | distance durations | Preserved | | Heart-rate targets | `HeartRate_t` (zone or bpm) | bpm | Preserved (±1 bpm) | | Speed / pace targets | `Speed_t` | m/s | Preserved | | Cadence targets | `Cadence_t` | rpm | Preserved (±1 rpm) | | Power targets | — (TCX has none) | watts | Not present in the source | | Repeats / intervals | `Repeat_t` | repeat blocks | Preserved | Heart-rate-based workouts convert cleanly: TCX carries heart-rate, speed, and cadence targets, all of which Garmin Connect supports. ## Gotchas **No power targets.** TCX workouts have no power target (the schema covers heart rate, speed, and cadence only), so a TCX-sourced Garmin Connect workout won't gain power targets. If you need power, start from a [FIT](/convert/fit-to-garmin) or [ZWO](/convert/zwo-to-garmin) workout instead. **How does it get on my watch?** A `.gcn` file is Garmin Connect's JSON, not a device file. Push it to your account with `kaiord garmin push` (via [`@kaiord/garmin-connect`](/formats/gcn#garmin-connect-api)) or use the Editor's Garmin sync; Garmin Connect then syncs it to your device. **Sport mapping.** TCX `Sport` values (`Running`, `Biking`, `Other`) map to the corresponding Garmin sports; anything unrecognized falls back to `Other`. ## Related * [Convert Garmin to TCX](/convert/garmin-to-tcx) — the reverse direction * [Convert TCX to FIT](/convert/tcx-to-fit) — a device-file export * [TCX format](/formats/tcx) · [GCN format](/formats/gcn) * [All converters](/convert/) --- --- url: /docs/convert/garmin-to-tcx.md description: >- Convert a Garmin Connect workout (GCN JSON) to a TCX (Training Center XML) file — free and in-browser, or via the Kaiord CLI and TypeScript SDK. --- # Convert Garmin to TCX Take a **Garmin Connect** workout (GCN JSON) into a **TCX** (Training Center XML) file so a plan from Garmin can import into another training platform. Use the free, in-browser [Kaiord Editor](https://kaiord.com/editor/) (no account, no upload), or the [CLI](/cli/commands#convert) and [TypeScript SDK](/guide/quick-start). Conversions go through Kaiord's canonical [KRD format](/formats/krd) and stay within round-trip tolerances (time ±1 s, heart rate ±1 bpm, cadence ±1 rpm). ## Three ways to convert ### 1. Editor (drag & drop) Open [kaiord.com/editor](https://kaiord.com/editor/), drop your Garmin Connect workout file, choose **TCX** as the export format, and download `workout.tcx`. ### 2. CLI ```bash pnpm add -g @kaiord/cli kaiord convert -i workout.gcn -o workout.tcx ``` ### 3. SDK ```ts import { fromText, toText } from "@kaiord/core"; import { garminReader } from "@kaiord/garmin"; import { tcxWriter } from "@kaiord/tcx"; import { readFile, writeFile } from "node:fs/promises"; const gcn = await readFile("workout.gcn", "utf-8"); const krd = await fromText(gcn, garminReader); const tcx = await toText(krd, tcxWriter); await writeFile("workout.tcx", tcx); ``` ## What survives the conversion | Data | Garmin Connect (GCN) | TCX | Result | | -------------------- | -------------------- | ------------------- | ----------------------------------------------- | | Step order & names | workout steps | `` / `` | Preserved | | Time durations | time durations | `Time_t` seconds | Preserved (±1 s) | | Distance durations | distance durations | `Distance_t` meters | Preserved | | Heart-rate targets | bpm | `HeartRate_t` | Preserved (±1 bpm) | | Speed / pace targets | m/s | `Speed_t` | Preserved | | Cadence targets | rpm | `Cadence_t` | Preserved (±1 rpm) | | Power targets | watts | — | **Dropped** — TCX workouts have no power target | | Repeats / intervals | repeat blocks | `Repeat_t` | Preserved | ## Gotchas **My power targets disappeared.** The TCX workout schema covers heart rate, speed, and cadence — there is no power target. Garmin Connect stores power in watts, so any power targets are dropped in the TCX output. To keep power, convert to [FIT](/convert/garmin-to-fit) instead, which keeps watt targets. **Where do I get the `.gcn` file?** GCN is Garmin Connect's workout JSON. Fetch it through the Garmin Connect API with [`@kaiord/garmin-connect`](/formats/gcn#garmin-connect-api) (e.g. `kaiord garmin list`) or the Editor's Garmin integration. **Calorie-based durations.** Garmin Connect can express a step duration in calories, but TCX supports only time- and distance-based durations. A calorie-duration step therefore has no direct TCX equivalent — prefer [FIT](/convert/garmin-to-fit) if your workout relies on calorie goals. ## Related * [Convert TCX to Garmin](/convert/tcx-to-garmin) — the reverse direction * [Convert Garmin to ZWO](/convert/garmin-to-zwo) — a Zwift export * [GCN format](/formats/gcn) · [TCX format](/formats/tcx) * [All converters](/convert/) --- --- url: /docs/formats/krd.md description: >- KRD (Kaiord Representation Definition) is a JSON-based canonical format for workout data. Round-trip safe, schema-validated, and extensible. --- # KRD Format Specification **KRD** (Kaiord Representation Definition) is a JSON-based canonical format for workout data, inspired by the Garmin FIT protocol but designed for human readability. **MIME type**: `application/vnd.kaiord+json` ## Design principles * **Round-trip safe** -- convert FIT/TCX/ZWO to KRD and back without data loss * **Schema-validated** -- all KRD files validate against Zod schemas * **Normalized** -- consistent units and naming across all source formats * **Extensible** -- custom fields via `extensions` object ## Core structure ```json { "version": "1.0", "type": "workout", "metadata": {}, "sessions": [], "laps": [], "records": [] } ``` ### Required fields * **version** (string): KRD schema version, e.g. `"1.0"` * **type** (string): `"workout"`, `"activity"`, or `"course"` * **metadata** (object): file-level metadata ### Optional fields * **sessions** (array): training sessions * **laps** (array): lap/interval data * **records** (array): time-series data points * **events** (array): workout events (start, stop, pause) * **extensions** (object): format-specific extensions ## Metadata ```json { "metadata": { "created": "2025-01-15T10:30:00Z", "manufacturer": "garmin", "product": "fenix7", "sport": "running", "subSport": "trail" } } ``` ## Workout steps Workouts are stored in `extensions.workout.steps`: ```json { "stepIndex": 0, "durationType": "time", "duration": { "type": "time", "seconds": 600 }, "targetType": "heart_rate", "target": { "type": "heart_rate", "value": { "unit": "zone", "value": 2 } }, "intensity": "warmup", "notes": "Easy warmup" } ``` ## Duration types | Type | Example | | ----------------------------- | ------------------------------------------------------------------------------ | | `time` | `{ "type": "time", "seconds": 600 }` | | `distance` | `{ "type": "distance", "meters": 5000 }` | | `open` | `{ "type": "open" }` | | `calories` | `{ "type": "calories", "calories": 200 }` | | `power_less_than` | `{ "type": "power_less_than", "watts": 150 }` | | `power_greater_than` | `{ "type": "power_greater_than", "watts": 300 }` | | `heart_rate_less_than` | `{ "type": "heart_rate_less_than", "bpm": 120 }` | | `repeat_until_steps_complete` | `{ "type": "repeat_until_steps_complete", "repeatCount": 5, "repeatFrom": 0 }` | Additional repeat types: `repeat_until_time`, `repeat_until_distance`, `repeat_until_calories`, `repeat_until_power_less_than`, `repeat_until_power_greater_than`, `repeat_until_heart_rate_less_than`, `repeat_until_heart_rate_greater_than`. ## Target types | Type | Units | | ------------ | --------------------------------------- | | `power` | `watts`, `percent_ftp`, `zone`, `range` | | `heart_rate` | `bpm`, `percent_max`, `zone`, `range` | | `pace` | `meters_per_second`, `zone`, `range` | | `cadence` | `rpm`, `zone`, `range` | | `open` | No target | ## Sessions Sessions capture training session summaries: ```json { "sessions": [ { "startTime": "2025-01-15T10:30:00Z", "totalElapsedTime": 3600, "totalTimerTime": 3540, "totalDistance": 10000, "sport": "running", "avgHeartRate": 145, "maxHeartRate": 178, "avgCadence": 85, "avgPower": 250, "totalCalories": 650 } ] } ``` Key fields: `startTime` (ISO 8601), `totalElapsedTime` (seconds), `totalTimerTime` (active time, excludes pauses), `totalDistance` (meters), `sport`. ## Laps Laps represent intervals within a session: ```json { "laps": [ { "startTime": "2025-01-15T10:30:00Z", "totalElapsedTime": 600, "totalDistance": 1000, "avgHeartRate": 142, "maxHeartRate": 155, "avgCadence": 84, "avgPower": 245 } ] } ``` ## Records Time-series data points (typically 1 Hz): ```json { "records": [ { "timestamp": "2025-01-15T10:30:00Z", "position": { "lat": 41.3851, "lon": 2.1734 }, "altitude": 12.5, "heartRate": 145, "cadence": 85, "power": 250, "speed": 2.78, "distance": 100 } ] } ``` Fields: `timestamp` (ISO 8601), `position` (lat/lon in degrees), `altitude` (meters), `heartRate` (bpm), `cadence` (rpm), `power` (watts), `speed` (m/s), `distance` (cumulative meters). All fields except `timestamp` are optional. ## Units and conventions | Measurement | Unit | | ----------- | -------------------- | | Time | seconds | | Distance | meters | | Speed | meters per second | | Altitude | meters | | Heart rate | bpm | | Cadence | rpm (running: spm/2) | | Power | watts | | Timestamps | ISO 8601 UTC | Field naming uses **camelCase** with prefixes: `total*`, `avg*`, `max*`, `min*`. ## Extensions Format-specific data lives in `extensions`: ```json { "extensions": { "fit": { "developerFields": [], "unknownMessages": {} }, "tcx": { "extensions": {} }, "zwift": { "originalDurationType": "distance" } } } ``` FIT developer fields and unknown messages are preserved during round-trip conversions: ```json { "extensions": { "fit": { "developerFields": [ { "fieldDefinitionNumber": 0, "fieldName": "custom_field", "value": 42 } ] } } } ``` ## Validation rules 1. All KRD files MUST validate against the Zod schema 2. Timestamps MUST be in ISO 8601 format with UTC timezone 3. Numeric values MUST be finite (no NaN or Infinity) 4. Arrays MUST be sorted by timestamp where applicable 5. Required fields MUST be present; optional fields may be omitted (not null) ## Round-trip tolerances * Time: +/- 1 second * Power: +/- 1 watt or +/- 1% FTP * Heart rate: +/- 1 bpm * Cadence: +/- 1 rpm * Distance: +/- 1 meter ## Example: minimal valid KRD ```json { "version": "1.0", "type": "workout", "metadata": { "created": "2025-01-15T10:30:00Z", "sport": "running" } } ``` ## Example: complete workout ```json { "version": "1.0", "type": "workout", "metadata": { "created": "2025-01-15T10:30:00Z", "manufacturer": "garmin", "product": "fenix7", "sport": "cycling", "subSport": "indoor_cycling" }, "extensions": { "workout": { "name": "FTP Intervals", "sport": "cycling", "steps": [ { "stepIndex": 0, "durationType": "time", "duration": { "type": "time", "seconds": 600 }, "targetType": "power", "target": { "type": "power", "value": { "unit": "percent_ftp", "value": 60 } }, "intensity": "warmup", "notes": "Easy warmup" }, { "stepIndex": 1, "durationType": "time", "duration": { "type": "time", "seconds": 300 }, "targetType": "power", "target": { "type": "power", "value": { "unit": "percent_ftp", "value": 105 } }, "intensity": "active", "notes": "Hard effort" }, { "stepIndex": 2, "durationType": "time", "duration": { "type": "time", "seconds": 180 }, "targetType": "power", "target": { "type": "power", "value": { "unit": "percent_ftp", "value": 50 } }, "intensity": "rest", "notes": "Recovery" }, { "stepIndex": 3, "durationType": "time", "duration": { "type": "time", "seconds": 300 }, "targetType": "power", "target": { "type": "power", "value": { "unit": "percent_ftp", "value": 50 } }, "intensity": "cooldown", "notes": "Easy cooldown" } ] } } } ``` Ready to convert? Follow the [Quick Start](/guide/quick-start). --- --- url: /docs/formats/fit.md description: >- Read and write Garmin FIT workout files using @kaiord/fit. Supports workouts, activities, courses, laps, records, and events. --- # FIT Format The `@kaiord/fit` package provides reading and writing of Garmin FIT workout files using the official Garmin FIT SDK. ## Installation ```bash pnpm add @kaiord/core @kaiord/fit ``` ## Usage ### Pre-built adapters ```ts twoslash import { fromBinary, toBinary } from "@kaiord/core"; import { fitReader, fitWriter } from "@kaiord/fit"; import { readFile, writeFile } from "node:fs/promises"; // FIT to KRD const buffer = await readFile("workout.fit"); const krd = await fromBinary(new Uint8Array(buffer), fitReader); // KRD to FIT const fitBuffer = await toBinary(krd, fitWriter); await writeFile("output.fit", fitBuffer); ``` ### Factory with custom logger ```ts twoslash import { createConsoleLogger } from "@kaiord/core"; import { createFitReader, createFitWriter } from "@kaiord/fit"; const logger = createConsoleLogger(); const reader = createFitReader(logger); const writer = createFitWriter(logger); ``` ## API | Function | Description | | -------------------------- | ------------------------------------------- | | `fitReader` | Pre-built FIT binary reader | | `fitWriter` | Pre-built FIT binary writer | | `createFitReader(logger?)` | Factory for FIT reader with optional logger | | `createFitWriter(logger?)` | Factory for FIT writer with optional logger | ## Supported features * Workout files (structured workout steps) * Activity files (recorded activity data) * Course files (GPS routes) * Lap messages * Record messages (time-series data) * Event messages * Session and activity metadata * Developer fields (preserved in `extensions.fit`) * Unknown messages (preserved in `extensions.fit`) ## FIT-specific notes FIT is Garmin's binary protocol. When converting FIT to KRD: * Duration values are converted from milliseconds to seconds * Power targets with Garmin's +1000 offset are normalized * Sub-sport values are mapped from camelCase to snake\_case * Developer fields and unknown messages are preserved in `extensions.fit` Ready to convert? Follow the [Quick Start](/guide/quick-start). --- --- url: /docs/formats/tcx.md description: >- Read, write, and validate Garmin Training Center XML files using @kaiord/tcx. Includes XSD schema validation. --- # TCX Format The `@kaiord/tcx` package provides reading, writing, and XSD validation of Garmin Training Center XML files. ## Installation ```bash pnpm add @kaiord/core @kaiord/tcx ``` ## Usage ### Pre-built adapters ```ts twoslash import { fromText, toText } from "@kaiord/core"; import { tcxReader, tcxWriter } from "@kaiord/tcx"; import { readFile, writeFile } from "node:fs/promises"; // TCX to KRD const tcxContent = await readFile("workout.tcx", "utf-8"); const krd = await fromText(tcxContent, tcxReader); // KRD to TCX const tcxString = await toText(krd, tcxWriter); await writeFile("output.tcx", tcxString); ``` ### Factory with custom logger ```ts twoslash import { createConsoleLogger } from "@kaiord/core"; import { createTcxReader, createTcxWriter } from "@kaiord/tcx"; const logger = createConsoleLogger(); const reader = createTcxReader(logger); const writer = createTcxWriter(logger); ``` ### XSD validation ```ts twoslash import { createConsoleLogger } from "@kaiord/core"; import { createXsdTcxValidator } from "@kaiord/tcx"; const logger = createConsoleLogger(); const validator = createXsdTcxValidator(logger); ``` ## API | Function | Description | | ------------------------------- | ------------------------------------------- | | `tcxReader` | Pre-built TCX text reader | | `tcxWriter` | Pre-built TCX text writer | | `createTcxReader(logger?)` | Factory for TCX reader with optional logger | | `createTcxWriter(logger?)` | Factory for TCX writer with optional logger | | `createXsdTcxValidator(logger)` | XSD schema validator for TCX files | ## Supported features * Workout definitions with structured steps * Heart rate, speed, and cadence targets * Time-based and distance-based durations * Repeat blocks (intervals) * Multiple sport types Ready to convert? Follow the [Quick Start](/guide/quick-start). --- --- url: /docs/formats/zwo.md description: >- Read, write, and validate Zwift workout XML files using @kaiord/zwo. Supports all ZWO interval types and power targets. --- # ZWO Format The `@kaiord/zwo` package provides reading, writing, and validation of Zwift workout XML files. ## Installation ```bash pnpm add @kaiord/core @kaiord/zwo ``` ## Usage ### Pre-built adapters ```ts twoslash import { fromText, toText } from "@kaiord/core"; import { zwiftReader, zwiftWriter } from "@kaiord/zwo"; import { readFile, writeFile } from "node:fs/promises"; // ZWO to KRD const zwoContent = await readFile("workout.zwo", "utf-8"); const krd = await fromText(zwoContent, zwiftReader); // KRD to ZWO const zwoString = await toText(krd, zwiftWriter); await writeFile("output.zwo", zwoString); ``` ### Factory with custom logger ```ts twoslash import { createConsoleLogger } from "@kaiord/core"; import { createZwiftReader, createZwiftWriter } from "@kaiord/zwo"; const logger = createConsoleLogger(); const reader = createZwiftReader(logger); const writer = createZwiftWriter(logger); ``` ## API | Function | Description | | ------------------------------ | ------------------------------------------------------------ | | `zwiftReader` | Pre-built ZWO text reader | | `zwiftWriter` | Pre-built ZWO text writer | | `createZwiftReader(logger?)` | Factory for ZWO reader with optional logger | | `createZwiftWriter(logger?)` | Factory for ZWO writer with optional logger | | `createZwiftValidator(logger)` | XSD validator (Node.js) or well-formedness checker (browser) | ## Supported features * SteadyState intervals * Warmup and Cooldown ramps * IntervalsT (structured intervals) * FreeRide segments * Power targets (FTP percentage) * Heart rate and cadence targets * Text events ## ZWO-specific notes When converting ZWO to KRD: * Power targets are expressed as FTP percentage (Zwift's native unit) * Heart rate targets have limited support in ZWO format * Distance-based durations may be converted to time-based * Original ZWO-specific data is preserved in `extensions.zwift` Ready to convert? Follow the [Quick Start](/guide/quick-start). --- --- url: /docs/formats/gcn.md description: >- Convert between Garmin Connect workout JSON and KRD using @kaiord/garmin. Bidirectional conversion for the Garmin Connect API. --- # GCN Format (Garmin Connect) The `@kaiord/garmin` package provides bidirectional conversion between Garmin Connect workout JSON format and KRD. ## Installation ```bash pnpm add @kaiord/core @kaiord/garmin ``` ## Usage ### Pre-built adapters ```ts twoslash import { fromText, toText } from "@kaiord/core"; import { garminReader, garminWriter } from "@kaiord/garmin"; import { readFile, writeFile } from "node:fs/promises"; // GCN to KRD const gcnContent = await readFile("workout.gcn", "utf-8"); const krd = await fromText(gcnContent, garminReader); // KRD to GCN const gcnString = await toText(krd, garminWriter); await writeFile("output.gcn", gcnString); ``` ### Factory with custom logger ```ts twoslash import { createConsoleLogger } from "@kaiord/core"; import { createGarminReader, createGarminWriter } from "@kaiord/garmin"; const logger = createConsoleLogger(); const reader = createGarminReader(logger); const writer = createGarminWriter(logger); ``` ## API | Function | Description | | ----------------------------- | ------------------------------------------- | | `garminReader` | Pre-built GCN text reader | | `garminWriter` | Pre-built GCN text writer | | `createGarminReader(logger?)` | Factory for GCN reader with optional logger | | `createGarminWriter(logger?)` | Factory for GCN writer with optional logger | ## Supported features * Workout definitions with structured steps * Power, heart rate, speed, and cadence targets * Time-based, distance-based, and calorie-based durations * Repeat blocks (intervals) * Multiple sport types * Custom step names and notes ## GCN-specific notes GCN is Garmin Connect's JSON format for workouts. When working with GCN: * Target values use explicit `targetValueOne`/`targetValueTwo` (not `zoneNumber`) * Pace targets use meters per second * Heart rate targets use bpm values * Power targets use watts ## Garmin Connect API To push workouts to Garmin Connect, use `@kaiord/garmin-connect` which handles SSO authentication and the workout API. See the [CLI garmin command](/cli/commands#garmin) for command-line usage. Ready to convert? Follow the [Quick Start](/guide/quick-start). --- --- url: /docs/cli/commands.md description: >- Complete reference for the Kaiord CLI: convert, validate, inspect, diff, extract-workout, and garmin commands with all options. --- # CLI Commands The `@kaiord/cli` package provides a command-line interface for converting, validating, and inspecting fitness files. ## Installation ```bash pnpm add -g @kaiord/cli ``` Or use without installing: ```bash pnpx @kaiord/cli --help ``` ## convert Convert workout files between formats. Detects formats from file extensions. ```bash kaiord convert -i workout.fit -o workout.krd kaiord convert -i workout.krd -o workout.tcx kaiord convert -i "workouts/*.fit" --output-dir converted/ kaiord convert -i data.bin --input-format fit -o workout.krd ``` | Option | Alias | Description | | ----------------- | ----- | --------------------------------------------------------- | | `--input` | `-i` | Input file path or glob pattern (required) | | `--output` | `-o` | Output file path | | `--output-dir` | | Output directory for batch conversion | | `--input-format` | | Override input format: `fit`, `gcn`, `krd`, `tcx`, `zwo` | | `--output-format` | | Override output format: `fit`, `gcn`, `krd`, `tcx`, `zwo` | ## validate Validate round-trip conversion integrity of FIT files (FIT to KRD to FIT). ```bash kaiord validate -i workout.fit kaiord validate -i workout.fit --tolerance-config custom.json ``` | Option | Alias | Description | | -------------------- | ----- | ------------------------------------------- | | `--input` | `-i` | Input file path (required) | | `--tolerance-config` | | Path to custom tolerance configuration JSON | Tolerance config example: ```json { "time": { "absolute": 1, "unit": "seconds" }, "power": { "absolute": 1, "percentage": 1, "unit": "watts" }, "heartRate": { "absolute": 1, "unit": "bpm" }, "cadence": { "absolute": 1, "unit": "rpm" } } ``` ## inspect Parse a fitness file and display a summary or full KRD JSON. ```bash kaiord inspect -i workout.fit kaiord inspect -i workout.fit --json kaiord inspect -i workout.fit --input-format fit ``` | Option | Alias | Description | | ---------------- | ----- | ------------------------------------------------------------ | | `--input` | `-i` | Input file path (required) | | `--input-format` | | Override format detection: `fit`, `tcx`, `zwo`, `gcn`, `krd` | ## diff Compare two workout files and show differences. Supports cross-format comparison. ```bash kaiord diff --file1 workout1.fit --file2 workout2.fit kaiord diff --file1 workout.fit --file2 workout.krd kaiord diff --file1 a.krd --file2 b.krd --json ``` | Option | Alias | Description | | ----------- | ----- | ----------------------------------------- | | `--file1` | `-1` | First file to compare (required) | | `--file2` | `-2` | Second file to compare (required) | | `--format1` | | Override format detection for first file | | `--format2` | | Override format detection for second file | ## extract-workout Extract the structured workout definition from a fitness file as JSON. ```bash kaiord extract-workout -i workout.fit kaiord extract-workout -i workout.krd ``` | Option | Alias | Description | | ---------------- | ----- | -------------------------- | | `--input` | `-i` | Input file path (required) | | `--input-format` | | Override format detection | ## garmin Garmin Connect operations. Requires authentication via `garmin login`. ### garmin login ```bash kaiord garmin login -e user@example.com -p password ``` | Option | Alias | Description | | ------------ | ----- | ---------------------------------- | | `--email` | `-e` | Garmin Connect email (required) | | `--password` | `-p` | Garmin Connect password (required) | ### garmin logout ```bash kaiord garmin logout ``` ### garmin list ```bash kaiord garmin list kaiord garmin list --limit 50 --offset 20 ``` | Option | Alias | Description | | ---------- | ----- | --------------------------------------- | | `--limit` | `-l` | Maximum workouts to list (default: 20) | | `--offset` | | Number of workouts to skip (default: 0) | ### garmin push ```bash kaiord garmin push -i workout.krd kaiord garmin push -i workout.fit --input-format fit ``` | Option | Alias | Description | | ---------------- | ----- | ---------------------------------- | | `--input` | `-i` | Input workout file path (required) | | `--input-format` | | Override format detection | ## Global options | Option | Description | | -------------- | ------------------------------ | | `--verbose` | Enable verbose logging | | `--quiet` | Quiet mode (errors only) | | `--json` | JSON output (machine-readable) | | `--log-format` | Log format: `pretty` or `json` | | `--help` | Show help | | `--version` | Show version | ## Configuration file Create `.kaiordrc.json` in your project or home directory for defaults: ```json { "defaultInputFormat": "fit", "defaultOutputFormat": "krd", "defaultOutputDir": "./converted", "verbose": false, "quiet": false, "json": false, "logFormat": "pretty" } ``` CLI options always override config file defaults. ## Supported formats | Format | Extension | Type | Description | | ------ | --------- | ------ | --------------------- | | FIT | `.fit` | Binary | Garmin FIT protocol | | KRD | `.krd` | Text | Kaiord canonical JSON | | TCX | `.tcx` | Text | Training Center XML | | ZWO | `.zwo` | Text | Zwift workout XML | | GCN | `.gcn` | Text | Garmin Connect JSON | ## Exit codes * **0**: Success * **1**: Error (invalid arguments, file not found, parsing error) --- --- url: /docs/mcp/tools.md description: >- Kaiord MCP server reference: tools, resources, and prompts for AI/LLM integration via the Model Context Protocol. --- # MCP Tools The `@kaiord/mcp` package provides a Model Context Protocol (MCP) server that exposes fitness file conversion, validation, and inspection tools to AI agents. ## Installation ```bash npm install -g @kaiord/mcp ``` ## Configuration ### Claude Desktop / Claude Code Add to your MCP configuration: ```json { "kaiord": { "type": "stdio", "command": "npx", "args": ["-y", "@kaiord/mcp"] } } ``` ### Local development ```json { "kaiord": { "type": "stdio", "command": "node", "args": ["./packages/mcp/dist/bin/kaiord-mcp.js"] } } ``` ## Tools ### kaiord\_convert Convert between FIT, TCX, ZWO, GCN, and KRD formats. * **Input**: source format, target format, file content (base64 for binary) * **Output**: converted file content ### kaiord\_validate Validate KRD JSON against the schema. * **Input**: KRD JSON content * **Output**: validation result with errors if any ### kaiord\_inspect Parse and summarize any fitness file. * **Input**: file content and format * **Output**: structured metadata, sport, steps summary ### kaiord\_diff Compare two fitness files and show differences. * **Input**: two files with their formats * **Output**: field-by-field differences with tolerances applied ### kaiord\_extract\_workout Extract structured workout definition from a fitness file. * **Input**: file content and format * **Output**: workout JSON with steps, targets, and durations ### kaiord\_list\_formats List all supported formats and their capabilities. * **Input**: none * **Output**: format registry with read/write/validate support per format ## Resources | URI | Description | | -------------------------- | ----------------------------------- | | `kaiord://schema/krd` | KRD JSON Schema | | `kaiord://formats` | Supported formats with capabilities | | `kaiord://docs/krd-format` | KRD format specification | ## Prompts | Name | Description | | ----------------- | ----------------------------------------- | | `convert_file` | Guided file conversion workflow | | `analyze_workout` | Inspect, extract, and summarize a workout | ## Supported formats | Format | Extension | Type | Description | | ------ | --------- | ------ | ---------------------------- | | FIT | `.fit` | Binary | Garmin FIT protocol | | TCX | `.tcx` | Text | Training Center XML | | ZWO | `.zwo` | Text | Zwift workout XML | | GCN | `.gcn` | Text | Garmin Connect workout JSON | | KRD | `.krd` | Text | Kaiord canonical JSON format | ## Next steps * [Quick Start](/guide/quick-start) -- get started with Kaiord * [CLI Commands](/cli/commands) -- command-line alternative --- --- url: /docs/api.md description: Auto-generated TypeScript API documentation for all Kaiord packages. --- # API Reference Auto-generated from TSDoc comments using TypeDoc. | Package | Description | | --- | --- | | [@kaiord/core](./core/README.md) | Domain types, schemas, ports, and use cases | | [@kaiord/fit](./fit/README.md) | FIT format adapter (Garmin FIT SDK) | | [@kaiord/tcx](./tcx/README.md) | TCX format adapter | | [@kaiord/zwo](./zwo/README.md) | ZWO format adapter | | [@kaiord/garmin](./garmin/README.md) | Garmin Connect (GCN) format adapter | | [@kaiord/garmin-connect](./garmin-connect/README.md) | Garmin Connect API client | | [@kaiord/cli](./cli/index.md) | Command-line interface | | [@kaiord/mcp](./mcp/README.md) | Model Context Protocol server | --- --- url: /docs/legal/privacy-policy.md description: >- Kaiord privacy policy covering the website, documentation, Chrome extensions, and optional AI integrations. --- # Privacy Policy **Last updated:** 2026-07-22 This privacy policy describes how the Kaiord project ("we", "us") handles data across all its products: the website (kaiord.com), documentation (kaiord.com/docs), the Kaiord workout editor, the Kaiord Garmin Bridge Chrome extension, the Kaiord Train2Go Bridge Chrome extension, the Kaiord Tanita Bridge Chrome extension, and the Kaiord TrainingPeaks Bridge Chrome extension. ## Data Controller Kaiord operates no backend that receives, stores, or processes your data. All processing is entirely client-side — on your device, inside your browser. For GDPR purposes there is therefore no Kaiord-operated data controller. The maintainer (Pablo Albaladejo) is the point of contact for privacy inquiries; see the [Contact](#contact) section. ## Data Collection Kaiord does **not** collect any personal data, analytics, or telemetry. We do not use cookies for tracking. We do not use any third-party analytics services. All workout-editor state (workouts, templates, sport-zone profiles, AI provider keys, sync state, chat transcripts) is stored locally in your browser via IndexedDB (Dexie). Nothing is sent to a Kaiord-operated server, ever. This local data remains on your device until you remove it: clear AI provider keys via Settings → Privacy → Clear All API Keys, delete individual workouts via the per-workout delete action, clear a conversation via the assistant's Clear conversation action, or clear site data in your browser to remove everything at once. If you configure the optional AI features inside the workout editor, your prompts and workout content are sent directly from your browser to the LLM provider you chose (Anthropic, OpenAI, or Google) and are subject to that provider's privacy policy and terms of service. Kaiord does not receive or relay this data; your API key is stored locally and transmitted only to the provider you configured. When you use the in-app chat assistant, summaries of your locally stored history — including workout, coaching, and health data such as sleep — are sent to the LLM provider you configured, and only while you are actively conversing with the assistant (never in the background). Your chat transcripts are stored locally in your browser like the rest of your editor state and, if you enable cross-device sync, are included in the encrypted snapshot saved to your own cloud storage; they are never sent to a Kaiord-operated server. ## Kaiord Garmin Bridge Extension The Kaiord Garmin Bridge Chrome extension connects the Kaiord workout editor to Garmin Connect via your browser session. Here is how it handles data: * **OAuth Token**: The extension mints an OAuth token by reusing your existing Garmin single-sign-on session — it exchanges that session for a short-lived service ticket, then for an OAuth token — and stores the token in `chrome.storage.local` so it can call Garmin's API on your behalf across service-worker restarts. The token is sent only to Garmin (as a Bearer credential) and never leaves your device otherwise. * **No Password**: The extension never reads, stores, or transmits your Garmin Connect password, and never sees it. Authentication reuses the session you already established by signing in to Garmin Connect in your browser. * **Body-Composition Upload**: When you choose to sync a measurement, the extension uploads a body-composition record (your weight plus derived metrics such as body-fat percentage) to Garmin Connect as a FIT file, using the `write:body` capability. It only ever sends the data you supply from the editor; it never reads your Garmin body-composition history. * **No Third-Party Sharing**: No data is shared with any third party. The extension only communicates with Garmin (`sso.garmin.com`, `connectapi.garmin.com`, `connect.garmin.com`) and allowed Kaiord origins (to exchange workout and body-composition data with the editor). * **No Telemetry**: The extension does not include any analytics, error reporting, or telemetry of any kind. ## Kaiord Train2Go Bridge Extension The Kaiord Train2Go Bridge Chrome extension imports coaching plans from Train2Go pages you are already viewing into the Kaiord workout editor. Here is how it handles data: * **No Data Persistence**: The extension stores no data locally. Training plan data is read on-demand from the Train2Go page DOM and delivered directly to the Kaiord workout editor (running in your browser). Nothing is transmitted to a Kaiord server; nothing is written to `chrome.storage`, cookies, or disk. * **No Credentials**: The extension never reads, stores, or transmits your Train2Go password or authentication tokens. It does not declare the `cookies` permission and cannot access your session cookie directly. It only reads the training plan rendered on the page. * **Read-Only DOM Access**: The content script only reads the coaching plan from pages on `app.train2go.com`. It does not modify the page, submit forms, or make authenticated API calls on your behalf. * **No Third-Party Sharing**: No data is shared with any third party. The extension only communicates with `app.train2go.com` (via its content script) and allowed Kaiord origins (to deliver imported workouts to the editor). * **No Telemetry**: The extension does not include any analytics, error reporting, or telemetry of any kind. ## Kaiord Tanita Bridge Extension The Kaiord Tanita Bridge Chrome extension reads your MyTANITA body-composition CSV export and hands it to the Kaiord workout editor. Here is how it handles data: * **No Data Persistence**: The extension stores no measurement data locally. Its service worker fetches your own CSV export from `mytanita.eu` on demand and passes the raw text directly to the Kaiord workout editor (running in your browser). Nothing is transmitted to a Kaiord server; nothing is written to `chrome.storage`, cookies, or disk. Only the `read:body` capability is declared — the extension reads your body-composition export and nothing else. * **No Credentials, No Password**: The extension never asks for, reads, stores, or transmits your MyTANITA password or any authentication token. It rides your existing logged-in browser session: the request is sent with `credentials:"include"` so your own HttpOnly `TANITASESS` session cookie is attached by the browser. The extension cannot read that cookie's value (it does not declare the `cookies` permission), and it reports session presence to the editor only as a boolean. If the session has expired, the extension surfaces a re-authentication prompt rather than any credential. * **No mytanita.eu DOM Access**: The extension injects no content script on `mytanita.eu`. It only performs a single, fixed, read-only `GET` of your CSV export; it does not modify the page, submit forms, or call any other endpoint. * **No Third-Party Sharing**: No data is shared with any third party. The extension only communicates with `mytanita.eu` (to fetch your export) and allowed Kaiord origins (to deliver the export to the editor). The raw CSV is parsed in the editor, not by the extension. * **No Telemetry**: The extension does not include any analytics, error reporting, or telemetry of any kind. ## Kaiord TrainingPeaks Bridge Extension The Kaiord TrainingPeaks Bridge Chrome extension reads your TrainingPeaks body metrics and hands them to the Kaiord workout editor. Here is how it handles data: * **No Credentials, No Password**: The extension never asks for, reads, stores, or transmits your TrainingPeaks password. It rides your existing logged-in browser session: it exchanges your session cookie for a short-lived access token by issuing a single cookie-only `GET https://tpapi.trainingpeaks.com/users/v3/token` request (`credentials:"include"`, no `Authorization` header). The `Production_tpAuth` session cookie is a domain-wide `.trainingpeaks.com` cookie, so it reaches `tpapi.trainingpeaks.com` automatically; the extension cannot read that cookie's value (it does not declare the `cookies` permission). Only the minted access token is stored — locally, in `chrome.storage.local` — and it is sent only to TrainingPeaks as a Bearer credential. * **Body-Metric Read/Write**: Using the access token, the extension reads your consolidated timed metrics (weight and related body-composition channels) from `https://tpapi.trainingpeaks.com/metrics/v3/...` and, only when you choose to sync, writes a single weight measurement back (the `read:body` and `write:body` capabilities). The raw metric JSON is parsed in the editor, not by the extension. Session presence is reported to the editor only as a boolean. * **No TrainingPeaks DOM Access**: The extension injects no content script on TrainingPeaks. All requests are made from its background service worker against a fixed, disclosed set of `tpapi.trainingpeaks.com` endpoints; it does not modify any page or submit forms. * **No Third-Party Sharing**: No data is shared with any third party. The extension only communicates with `tpapi.trainingpeaks.com` (to exchange the token and read/write metrics) and allowed Kaiord origins (to deliver the metrics to the editor). * **No Telemetry**: The extension does not include any analytics, error reporting, or telemetry of any kind. ## Communication Scope The extensions only communicate with the following domains: * `https://sso.garmin.com/*` — Garmin Bridge exchanges your existing Garmin sign-in session for a short-lived service ticket (no password is entered or seen) * `https://connectapi.garmin.com/*` — Garmin Bridge exchanges the ticket for an OAuth token and makes the workout/activity API calls with it * `https://connect.garmin.com/*` — where you sign in to Garmin Connect; the Garmin Bridge `open-garmin` action opens this page * `https://app.train2go.com/*` — Train2Go Bridge content script (runs on that domain) reads the coaching plan from the page * `https://mytanita.eu/*` — Tanita Bridge service worker fetches your body-composition CSV export using your existing session cookie * `https://tpapi.trainingpeaks.com/*` — TrainingPeaks Bridge service worker exchanges your existing session cookie for a short-lived access token and reads/writes your body metrics with it * `https://*.kaiord.com/*` — the Kaiord editor (running on kaiord.com) sends messages **to** each extension via Chrome's `externally_connectable` channel. This is a one-way inbound channel: the extensions do not read the editor's DOM or cookies. Each extension also injects a minimal **announce-only** content script (`kaiord-announce.js`) into `https://*.kaiord.com/*` so the editor can discover which extension IDs are installed at runtime. This content script only calls `window.postMessage` to publish a fixed announcement object (bridge id, extension id, version, declared capabilities) and re-announces on request. It does **not** read the editor's DOM, cookies, storage, or network traffic, does **not** modify the page, and does **not** enable any inbound data path from kaiord.com into the extension beyond what `externally_connectable` already allows. Each extension declares `host_permissions` limited to the hosts listed above — no wildcard or `` access. No other domains are contacted in production builds. During local development, the extensions additionally accept messages from `http://localhost:5173` and `http://localhost:5174` (Vite dev server), and the announce-only content script is also injected on `http://localhost/*` so locally-served editor builds can discover the extensions. These development-only matches are stripped from the production manifests (`manifest.prod.json`) before publishing to the Chrome Web Store. ## Regulatory Compliance Because Kaiord operates no backend and collects no personal data server-side, there is no personal data held by us to protect, share, or delete. This applies as long as Kaiord operates no backend and collects no personal data server-side (the state of the system today and at every release), under all applicable data protection regulations, including the EU General Data Protection Regulation (GDPR) and the California Consumer Privacy Act (CCPA). You retain all data-subject rights under GDPR and CCPA (access, rectification, erasure, portability). Because Kaiord holds no records about you, a request would return nothing to act upon; if you believe data has been collected or processed in error, please contact us and we will investigate immediately. ## Children's Privacy The Kaiord products are not directed at children under 13 (or under 16 in jurisdictions where that age applies), and we do not knowingly collect personal information from children. Because we do not collect personal data from anyone, this is trivially true, but we state it explicitly for clarity. ## Changes to this Policy Material changes to this policy are announced through the project's GitHub release notes and reflected in the "Last updated" date above. This file lives under version control at [`packages/docs/legal/privacy-policy.md`](https://github.com/pablo-albaladejo/kaiord/blob/main/packages/docs/legal/privacy-policy.md); every change is visible via `git log`. ## Open Source Kaiord is fully open source. You can inspect the complete source code, including both extensions, at [github.com/pablo-albaladejo/kaiord](https://github.com/pablo-albaladejo/kaiord). ## Contact For privacy inquiries, please open an issue on the [GitHub repository](https://github.com/pablo-albaladejo/kaiord/issues) or contact the project maintainer, Pablo Albaladejo. --- --- url: /docs/api/cli.md description: API reference for @kaiord/cli --- # @kaiord/cli See the [CLI Commands Reference](/cli/commands) for documentation. --- --- url: /docs/api/core/README.md --- **@kaiord/core** *** # @kaiord/core ## Classes * [FitParsingError](classes/FitParsingError.md) * [GarminParsingError](classes/GarminParsingError.md) * [KrdValidationError](classes/KrdValidationError.md) * [ServiceApiError](classes/ServiceApiError.md) * [ServiceAuthError](classes/ServiceAuthError.md) * [TcxParsingError](classes/TcxParsingError.md) * [TcxValidationError](classes/TcxValidationError.md) * [ToleranceExceededError](classes/ToleranceExceededError.md) * [UnsupportedKrdTypeError](classes/UnsupportedKrdTypeError.md) * [ZwiftParsingError](classes/ZwiftParsingError.md) * [ZwiftValidationError](classes/ZwiftValidationError.md) ## Type Aliases * [Activity](type-aliases/Activity.md) * [ActivityLevel](type-aliases/ActivityLevel.md) * [ActivitySummary](type-aliases/ActivitySummary.md) * [AdaptiveTdeeResult](type-aliases/AdaptiveTdeeResult.md) * [AffineUnit](type-aliases/AffineUnit.md) * [Analytics](type-aliases/Analytics.md) * [AnalyticsEvent](type-aliases/AnalyticsEvent.md) * [AssembleDayEnergyBalanceInput](type-aliases/AssembleDayEnergyBalanceInput.md) * [AuthProvider](type-aliases/AuthProvider.md) * [BinaryReader](type-aliases/BinaryReader.md) * [BinaryWriter](type-aliases/BinaryWriter.md) * [BiologicalSex](type-aliases/BiologicalSex.md) * [BmrFormula](type-aliases/BmrFormula.md) * [BmrInput](type-aliases/BmrInput.md) * [BmrResult](type-aliases/BmrResult.md) * [BodyComposition](type-aliases/BodyComposition.md) * [BridgeId](type-aliases/BridgeId.md) * [CadenceValue](type-aliases/CadenceValue.md) * [CanonicalMeasurement](type-aliases/CanonicalMeasurement.md) * [CatalogFallback](type-aliases/CatalogFallback.md) * [ComputeAdaptiveTdeeInput](type-aliases/ComputeAdaptiveTdeeInput.md) * [ComputeDailyDeltaInput](type-aliases/ComputeDailyDeltaInput.md) * [ComputeDailyDeltaResult](type-aliases/ComputeDailyDeltaResult.md) * [ComputeFlagInput](type-aliases/ComputeFlagInput.md) * [ComputeMacroTargetsInput](type-aliases/ComputeMacroTargetsInput.md) * [ComputePeriodizedTargetInput](type-aliases/ComputePeriodizedTargetInput.md) * [DailyWellness](type-aliases/DailyWellness.md) * [DayEnergyBalance](type-aliases/DayEnergyBalance.md) * [DayExpenditureInput](type-aliases/DayExpenditureInput.md) * [DayExpenditureResult](type-aliases/DayExpenditureResult.md) * [Duration](type-aliases/Duration.md) * [DurationType](type-aliases/DurationType.md) * [EmaOptions](type-aliases/EmaOptions.md) * [EmaPoint](type-aliases/EmaPoint.md) * [EmaResult](type-aliases/EmaResult.md) * [EnergyBalanceRollup](type-aliases/EnergyBalanceRollup.md) * [EnergyGoal](type-aliases/EnergyGoal.md) * [Equipment](type-aliases/Equipment.md) * [ExpectedActivityKcalInput](type-aliases/ExpectedActivityKcalInput.md) * [ExpenditureSource](type-aliases/ExpenditureSource.md) * [FileType](type-aliases/FileType.md) * [GoalType](type-aliases/GoalType.md) * [HashProjection](type-aliases/HashProjection.md) * [HealthExtensionPayload](type-aliases/HealthExtensionPayload.md) * [HealthFileType](type-aliases/HealthFileType.md) * [HeartRateSeries](type-aliases/HeartRateSeries.md) * [HeartRateValue](type-aliases/HeartRateValue.md) * [HrvSummary](type-aliases/HrvSummary.md) * [Intensity](type-aliases/Intensity.md) * [KnownUnit](type-aliases/KnownUnit.md) * [KRD](type-aliases/KRD.md) * [KRDEvent](type-aliases/KRDEvent.md) * [KRDExtensions](type-aliases/KRDExtensions.md) * [KRDLap](type-aliases/KRDLap.md) * [KRDLapTrigger](type-aliases/KRDLapTrigger.md) * [KRDMetadata](type-aliases/KRDMetadata.md) * [KRDRecord](type-aliases/KRDRecord.md) * [KRDSession](type-aliases/KRDSession.md) * [LabFlag](type-aliases/LabFlag.md) * [LabPanel](type-aliases/LabPanel.md) * [LabParameter](type-aliases/LabParameter.md) * [LabProvenance](type-aliases/LabProvenance.md) * [LabRefRange](type-aliases/LabRefRange.md) * [LabRefSource](type-aliases/LabRefSource.md) * [LabReport](type-aliases/LabReport.md) * [LabValue](type-aliases/LabValue.md) * [LengthUnit](type-aliases/LengthUnit.md) * [ListOptions](type-aliases/ListOptions.md) * [Logger](type-aliases/Logger.md) * [LogLevel](type-aliases/LogLevel.md) * [MacroNutrients](type-aliases/MacroNutrients.md) * [ManagedDataRegistryEntry](type-aliases/ManagedDataRegistryEntry.md) * [ManagedDataType](type-aliases/ManagedDataType.md) * [MealSlot](type-aliases/MealSlot.md) * [MeasuredWellness](type-aliases/MeasuredWellness.md) * [PaceValue](type-aliases/PaceValue.md) * [PlannedSession](type-aliases/PlannedSession.md) * [PlannedSessionStatus](type-aliases/PlannedSessionStatus.md) * [PowerValue](type-aliases/PowerValue.md) * [PowerZone](type-aliases/PowerZone.md) * [ProfileSnapshot](type-aliases/ProfileSnapshot.md) * [PushResult](type-aliases/PushResult.md) * [RepetitionBlock](type-aliases/RepetitionBlock.md) * [ResolvedExpenditure](type-aliases/ResolvedExpenditure.md) * [SchemaValidator](type-aliases/SchemaValidator.md) * [Sex](type-aliases/Sex.md) * [SleepRecord](type-aliases/SleepRecord.md) * [SleepStage](type-aliases/SleepStage.md) * [Sport](type-aliases/Sport.md) * [SportCategory](type-aliases/SportCategory.md) * [StrainSummary](type-aliases/StrainSummary.md) * [StressEpisode](type-aliases/StressEpisode.md) * [StrokeTypeValue](type-aliases/StrokeTypeValue.md) * [SubSport](type-aliases/SubSport.md) * [SwimStroke](type-aliases/SwimStroke.md) * [Target](type-aliases/Target.md) * [TargetType](type-aliases/TargetType.md) * [TargetUnit](type-aliases/TargetUnit.md) * [TextReader](type-aliases/TextReader.md) * [TextWriter](type-aliases/TextWriter.md) * [TokenData](type-aliases/TokenData.md) * [TokenStore](type-aliases/TokenStore.md) * [ToleranceChecker](type-aliases/ToleranceChecker.md) * [ToleranceConfig](type-aliases/ToleranceConfig.md) * [ToleranceViolation](type-aliases/ToleranceViolation.md) * [TrainingZoneBand](type-aliases/TrainingZoneBand.md) * [TrainingZones](type-aliases/TrainingZones.md) * [TrainingZoneSet](type-aliases/TrainingZoneSet.md) * [ValidateRoundTrip](type-aliases/ValidateRoundTrip.md) * [ValidationError](type-aliases/ValidationError.md) * [VitalsSummary](type-aliases/VitalsSummary.md) * [WeightMeasurement](type-aliases/WeightMeasurement.md) * [Workout](type-aliases/Workout.md) * [WorkoutService](type-aliases/WorkoutService.md) * [WorkoutStep](type-aliases/WorkoutStep.md) * [WorkoutSummary](type-aliases/WorkoutSummary.md) ## Variables * [activitySchema](variables/activitySchema.md) * [activitySummarySchema](variables/activitySummarySchema.md) * [BODY\_FAT\_TOLERANCE\_PERCENT](variables/BODY_FAT_TOLERANCE_PERCENT.md) * [bodyCompositionSchema](variables/bodyCompositionSchema.md) * [CUSTOM\_PARAMETER\_PREFIX](variables/CUSTOM_PARAMETER_PREFIX.md) * [DAILY\_KCAL\_TOLERANCE](variables/DAILY_KCAL_TOLERANCE.md) * [DAILY\_STEPS\_TOLERANCE](variables/DAILY_STEPS_TOLERANCE.md) * [dailyWellnessSchema](variables/dailyWellnessSchema.md) * [dayEnergyBalanceSchema](variables/dayEnergyBalanceSchema.md) * [DEFAULT\_MET](variables/DEFAULT_MET.md) * [DEFAULT\_NEAT\_FACTOR](variables/DEFAULT_NEAT_FACTOR.md) * [DEFAULT\_TOLERANCES](variables/DEFAULT_TOLERANCES.md) * [durationSchema](variables/durationSchema.md) * [durationTypeSchema](variables/durationTypeSchema.md) * [energyGoalSchema](variables/energyGoalSchema.md) * [equipmentSchema](variables/equipmentSchema.md) * [expenditureSourceSchema](variables/expenditureSourceSchema.md) * [fileTypeSchema](variables/fileTypeSchema.md) * [FIT\_TO\_SWIM\_STROKE](variables/FIT_TO_SWIM_STROKE.md) * [FLOOR\_KCAL](variables/FLOOR_KCAL.md) * [goalTypeSchema](variables/goalTypeSchema.md) * [healthExtensionPayloadSchema](variables/healthExtensionPayloadSchema.md) * [healthFileTypes](variables/healthFileTypes.md) * [HEART\_RATE\_SERIES\_BPM\_TOLERANCE](variables/HEART_RATE_SERIES_BPM_TOLERANCE.md) * [heartRateSeriesSchema](variables/heartRateSeriesSchema.md) * [HRV\_TOLERANCE\_MS](variables/HRV_TOLERANCE_MS.md) * [hrvSummarySchema](variables/hrvSummarySchema.md) * [intensitySchema](variables/intensitySchema.md) * [KCAL\_PER\_KG\_FAT](variables/KCAL_PER_KG_FAT.md) * [knownUnitSchema](variables/knownUnitSchema.md) * [krdEventSchema](variables/krdEventSchema.md) * [krdExtensionsSchema](variables/krdExtensionsSchema.md) * [krdLapSchema](variables/krdLapSchema.md) * [krdLapTriggerSchema](variables/krdLapTriggerSchema.md) * [krdMetadataSchema](variables/krdMetadataSchema.md) * [krdRecordSchema](variables/krdRecordSchema.md) * [krdSchema](variables/krdSchema.md) * [krdSessionSchema](variables/krdSessionSchema.md) * [LAB\_PARAMETER\_CATALOG](variables/LAB_PARAMETER_CATALOG.md) * [labFlagSchema](variables/labFlagSchema.md) * [labPanelSchema](variables/labPanelSchema.md) * [labParameterSchema](variables/labParameterSchema.md) * [labProvenanceSchema](variables/labProvenanceSchema.md) * [labRefRangeSchema](variables/labRefRangeSchema.md) * [labRefSourceSchema](variables/labRefSourceSchema.md) * [labReportSchema](variables/labReportSchema.md) * [labValueSchema](variables/labValueSchema.md) * [lengthUnitSchema](variables/lengthUnitSchema.md) * [macroNutrientsSchema](variables/macroNutrientsSchema.md) * [MANAGED\_DATA\_REGISTRY](variables/MANAGED_DATA_REGISTRY.md) * [managedDataTypes](variables/managedDataTypes.md) * [mealSlotSchema](variables/mealSlotSchema.md) * [MET\_TABLE](variables/MET_TABLE.md) * [MIN\_ADAPTIVE\_DAYS](variables/MIN_ADAPTIVE_DAYS.md) * [MUSCLE\_SURPLUS\_CAP](variables/MUSCLE_SURPLUS_CAP.md) * [NEAT\_FACTOR](variables/NEAT_FACTOR.md) * [plannedSessionSchema](variables/plannedSessionSchema.md) * [plannedSessionStatusSchema](variables/plannedSessionStatusSchema.md) * [POWER\_ZONE\_PERCENT\_FTP](variables/POWER_ZONE_PERCENT_FTP.md) * [POWER\_ZONES](variables/POWER_ZONES.md) * [profileSnapshotSchema](variables/profileSnapshotSchema.md) * [repetitionBlockSchema](variables/repetitionBlockSchema.md) * [SLEEP\_STAGE\_TOLERANCE\_SECONDS](variables/SLEEP_STAGE_TOLERANCE_SECONDS.md) * [SLEEP\_TOTAL\_DURATION\_TOLERANCE\_SECONDS](variables/SLEEP_TOTAL_DURATION_TOLERANCE_SECONDS.md) * [sleepRecordSchema](variables/sleepRecordSchema.md) * [sleepStageSchema](variables/sleepStageSchema.md) * [sportSchema](variables/sportSchema.md) * [STALE\_SNAPSHOT\_THRESHOLD\_DAYS](variables/STALE_SNAPSHOT_THRESHOLD_DAYS.md) * [STRAIN\_SCORE\_TOLERANCE](variables/STRAIN_SCORE_TOLERANCE.md) * [strainSummarySchema](variables/strainSummarySchema.md) * [STRESS\_TOLERANCE](variables/STRESS_TOLERANCE.md) * [stressEpisodeSchema](variables/stressEpisodeSchema.md) * [subSportSchema](variables/subSportSchema.md) * [SWIM\_STROKE\_TO\_FIT](variables/SWIM_STROKE_TO_FIT.md) * [swimStrokeSchema](variables/swimStrokeSchema.md) * [targetSchema](variables/targetSchema.md) * [targetTypeSchema](variables/targetTypeSchema.md) * [targetUnitSchema](variables/targetUnitSchema.md) * [toleranceConfigSchema](variables/toleranceConfigSchema.md) * [toleranceViolationSchema](variables/toleranceViolationSchema.md) * [trainingZoneBandSchema](variables/trainingZoneBandSchema.md) * [trainingZoneSetSchema](variables/trainingZoneSetSchema.md) * [trainingZonesSchema](variables/trainingZonesSchema.md) * [VITALS\_RESPIRATORY\_RATE\_TOLERANCE](variables/VITALS_RESPIRATORY_RATE_TOLERANCE.md) * [VITALS\_RESTING\_HEART\_RATE\_TOLERANCE](variables/VITALS_RESTING_HEART_RATE_TOLERANCE.md) * [VITALS\_SPO2\_TOLERANCE](variables/VITALS_SPO2_TOLERANCE.md) * [vitalsSummarySchema](variables/vitalsSummarySchema.md) * [WEIGHT\_TOLERANCE\_KG](variables/WEIGHT_TOLERANCE_KG.md) * [weightMeasurementSchema](variables/weightMeasurementSchema.md) * [workoutLikeFileTypes](variables/workoutLikeFileTypes.md) * [workoutSchema](variables/workoutSchema.md) * [workoutStepSchema](variables/workoutStepSchema.md) ## Functions * [aggregateEnergyBalance](functions/aggregateEnergyBalance.md) * [assembleDayEnergyBalance](functions/assembleDayEnergyBalance.md) * [canonicalHash](functions/canonicalHash.md) * [computeAdaptiveTdee](functions/computeAdaptiveTdee.md) * [computeBmr](functions/computeBmr.md) * [computeDailyDelta](functions/computeDailyDelta.md) * [computeFlag](functions/computeFlag.md) * [computeMacroTargets](functions/computeMacroTargets.md) * [computePeriodizedTarget](functions/computePeriodizedTarget.md) * [convertBound](functions/convertBound.md) * [convertLengthToMeters](functions/convertLengthToMeters.md) * [convertMeasurement](functions/convertMeasurement.md) * [createConsoleLogger](functions/createConsoleLogger.md) * [createFitParsingError](functions/createFitParsingError.md) * [createGarminParsingError](functions/createGarminParsingError.md) * [createKrdValidationError](functions/createKrdValidationError.md) * [createNoopAnalytics](functions/createNoopAnalytics.md) * [createSchemaValidator](functions/createSchemaValidator.md) * [createServiceApiError](functions/createServiceApiError.md) * [createServiceAuthError](functions/createServiceAuthError.md) * [createTcxParsingError](functions/createTcxParsingError.md) * [createTcxValidationError](functions/createTcxValidationError.md) * [createToleranceChecker](functions/createToleranceChecker.md) * [createUnsupportedKrdTypeError](functions/createUnsupportedKrdTypeError.md) * [createWorkoutKRD](functions/createWorkoutKRD.md) * [createZwiftParsingError](functions/createZwiftParsingError.md) * [createZwiftValidationError](functions/createZwiftValidationError.md) * [customParameterKey](functions/customParameterKey.md) * [deriveExternalId](functions/deriveExternalId.md) * [estimateExpectedActivityKcal](functions/estimateExpectedActivityKcal.md) * [exponentialMovingAverage](functions/exponentialMovingAverage.md) * [extractWorkout](functions/extractWorkout.md) * [fingerprintSnapshot](functions/fingerprintSnapshot.md) * [fromBinary](functions/fromBinary.md) * [fromCanonicalValue](functions/fromCanonicalValue.md) * [fromText](functions/fromText.md) * [getLabParameter](functions/getLabParameter.md) * [isCustomParameterKey](functions/isCustomParameterKey.md) * [isHealthFileType](functions/isHealthFileType.md) * [isPowerZone](functions/isPowerZone.md) * [isRepetitionBlock](functions/isRepetitionBlock.md) * [metForSport](functions/metForSport.md) * [neatFactorForActivityLevel](functions/neatFactorForActivityLevel.md) * [parseRefTextBounds](functions/parseRefTextBounds.md) * [percentFtpToZone](functions/percentFtpToZone.md) * [resolveAffineUnit](functions/resolveAffineUnit.md) * [resolveDayExpenditure](functions/resolveDayExpenditure.md) * [sportCategory](functions/sportCategory.md) * [toBinary](functions/toBinary.md) * [toCanonicalValue](functions/toCanonicalValue.md) * [toText](functions/toText.md) * [validateKrd](functions/validateKrd.md) * [validateRoundTrip](functions/validateRoundTrip.md) * [zoneToPercentFtp](functions/zoneToPercentFtp.md) --- --- url: /docs/CHANGELOG.md --- # @kaiord/docs ## 0.0.2 ### Patch Changes * 36efe53: Enable VitePress `cleanUrls` so canonical docs URLs are extensionless (better for search-engine and AI-agent citations; the `.html` files are still emitted, so existing links keep working), and fix the docs sitemap to include the `/docs/` base — VitePress does not prepend `base` to sitemap entries, so every URL pointed at the site root (`kaiord.com/CHANGELOG` instead of `kaiord.com/docs/CHANGELOG`). * 7764f5d: Refresh the docs and editor OG images to match the platform brand: add the ambient radial glow and a sky-accented subtitle. The editor now ships its own OG card (og-image-editor.png, subtitle "Editor") instead of reusing the landing image, with its meta tags repointed accordingly. Both are reproducible via each package's generate-og-image.mjs script. ## 0.0.1 ### Patch Changes * a2888cf: Close eight spec-vs-code drift gaps identified by the 2026-04-20 `/opsx-sync` audit. No public API breaks; the SPA changes are internal to `@kaiord/workout-spa-editor` and ship behind a Dexie v2+v3 schema bump with additive, backwards-compatible migrations. **`@kaiord/workout-spa-editor` (minor — new UI affordances, new Dexie stores, additive schema):** * Surface a storage-unavailable banner when `probeStorage()` reports failure ("Storage unavailable — changes in this session won't be saved"). Wired through a new `storage-store` + single-mount invariant in `MainLayout`. * Introduce `BridgeStatus = "verified" | "unavailable" | "removed"`. Pruning now transitions `unavailable → removed` after 24h (with a user notification) and deletes the row 24h after that. Registry persists to a new `bridges` Dexie store so the lifecycle timers survive browser restarts. * Pin the Train2Go 30s detection cache behavior (never-detected, cached-and-stale, cached-not-installed, no-rolling-window). * Advance `modifiedAt` on every KRD edit via a new `onWorkoutMutation` helper wired into the editor save path — edits in STRUCTURED/READY now bump the timestamp, not only the legacy PUSHED→MODIFIED transition. * Enrich `BatchProgress` with `counts` and per-workout `byId` so the calendar batch-progress panel can render per-workout status. * Split `UsageRecord.totalTokens` into `inputTokens` / `outputTokens` (derived `totalTokens` retained for legacy readers, Zod `.refine` pins the invariant). Dexie v3 migration backfills legacy rows (`inputTokens = totalTokens`, `outputTokens = 0`, `legacy: true`); the usage-panel renderer shows `—` for `outputTokens` on legacy rows. **`@kaiord/docs` (patch — head meta tag + token-parsing helper):** * Add `` to the VitePress docs head. Value is parsed at config-load time from `--brand-bg-primary` in `styles/brand-tokens.css`; CI invariant blocks re-introducing a hex literal under `packages/docs/`. **Repo-level** (not a publishable-package bump, called out here for the release log): * `.changeset/config.json` adds `@kaiord/garmin-bridge` and `@kaiord/train2go-bridge` to `linked[0]` so bridge extensions version in lockstep; guarded by `scripts/check-changeset-config.test.mjs`. --- --- url: /docs/README.md --- # @kaiord/docs VitePress documentation site for Kaiord. Hosts the public docs published at — guide, format references, CLI commands, MCP tools, legal pages, and the auto-generated TypeScript API reference. This package is `private: true` and is not published to npm. It is built and deployed as a static site by the `release.yml` / `pages.yml` workflows. ## Purpose * Render the long-form Kaiord documentation as a static VitePress site. * Keep guide content (`guide/`), format specs (`formats/`), CLI reference (`cli/`), MCP tools (`mcp/`), and legal pages (`legal/`) in one tree. * Generate the TypeScript API reference into `api/` from the public packages (`@kaiord/core`, `@kaiord/cli`, `@kaiord/fit`, `@kaiord/tcx`, `@kaiord/zwo`, `@kaiord/garmin`, `@kaiord/garmin-connect`, `@kaiord/mcp`) via TypeDoc with the `typedoc-plugin-markdown` plugin. * Enforce hygiene rules on docs content: spell-check (cspell) and a privacy-policy invariant (`scripts/check-privacy-policy.mjs`). The home page is `index.md`. Sidebar / navigation are configured in `.vitepress/config.ts`. ## Build entrypoint This package is a VitePress site, not a library — it has no `main` / `exports`. The build target is the static site under `.vitepress/dist/`. ```bash # Develop locally with hot reload pnpm --filter @kaiord/docs dev # Generate the API reference and build the static site pnpm --filter @kaiord/docs build # Preview the built site locally pnpm --filter @kaiord/docs preview ``` The `build` script first runs `node scripts/generate-api-docs.mjs` to refresh `api/` from the source packages, then runs `vitepress build`. Output is the static site that the deployment workflow uploads. ## How to test ```bash # Run the package's node:test suite (script invariants + content guards) pnpm --filter @kaiord/docs test # Spell-check Markdown content only pnpm --filter @kaiord/docs spellcheck # Verify the site builds end-to-end (catches broken VitePress links and # missing API references) pnpm --filter @kaiord/docs build ``` The `test` script runs `node --test scripts/*.test.mjs`, which covers the brand-token guard, build-output metadata check, head-config invariants, no-hex-literals rule, and the privacy-policy check. The whole suite is also executed in CI as part of `pnpm test:scripts`. ## License MIT — see the `LICENSE` file at the repository root. --- --- url: /docs/api/fit/README.md --- **@kaiord/fit** *** # @kaiord/fit ## Variables * [fitReader](variables/fitReader.md) * [fitWriter](variables/fitWriter.md) ## Functions * [createFitReader](functions/createFitReader.md) * [createFitWriter](functions/createFitWriter.md) * [createGarminFitSdkReader](functions/createGarminFitSdkReader.md) * [createGarminFitSdkWriter](functions/createGarminFitSdkWriter.md) * [encodeBodyCompositionFit](functions/encodeBodyCompositionFit.md) * [encodeFitMessages](functions/encodeFitMessages.md) --- --- url: /docs/api/garmin/README.md --- **@kaiord/garmin** *** # @kaiord/garmin ## Type Aliases * [GarminWriterOptions](type-aliases/GarminWriterOptions.md) * [PaceZoneEntry](type-aliases/PaceZoneEntry.md) * [PaceZoneTable](type-aliases/PaceZoneTable.md) ## Variables * [garminReader](variables/garminReader.md) * [garminWriter](variables/garminWriter.md) ## Functions * [createGarminReader](functions/createGarminReader.md) * [createGarminWriter](functions/createGarminWriter.md) * [mapGarminSportToKrd](functions/mapGarminSportToKrd.md) --- --- url: /docs/api/garmin-connect/README.md --- **@kaiord/garmin-connect** *** # @kaiord/garmin-connect ## Type Aliases * [GarminConnectClient](type-aliases/GarminConnectClient.md) * [GarminConnectClientOptions](type-aliases/GarminConnectClientOptions.md) * [GarminWorkoutClient](type-aliases/GarminWorkoutClient.md) * [InitResult](type-aliases/InitResult.md) * [ListOptions](type-aliases/ListOptions.md) * [PushResult](type-aliases/PushResult.md) * [RetryOptions](type-aliases/RetryOptions.md) * [TokenData](type-aliases/TokenData.md) * [TokenReader](type-aliases/TokenReader.md) * [TokenStore](type-aliases/TokenStore.md) * [WorkoutSummary](type-aliases/WorkoutSummary.md) ## Functions * [createCookieFetch](functions/createCookieFetch.md) * [createFileTokenStore](functions/createFileTokenStore.md) * [createGarminAuthProvider](functions/createGarminAuthProvider.md) * [createGarminConnectClient](functions/createGarminConnectClient.md) * [createMemoryTokenStore](functions/createMemoryTokenStore.md) * [createTokenManager](functions/createTokenManager.md) --- --- url: /docs/api/mcp/README.md --- **@kaiord/mcp** *** # @kaiord/mcp ## Type Aliases * [FileFormat](type-aliases/FileFormat.md) * [ToolResult](type-aliases/ToolResult.md) ## Variables * [FORMAT\_REGISTRY](variables/FORMAT_REGISTRY.md) * [formatSchema](variables/formatSchema.md) ## Functions * [createServer](functions/createServer.md) * [createStderrLogger](functions/createStderrLogger.md) * [detectFormatFromPath](functions/detectFormatFromPath.md) * [formatError](functions/formatError.md) * [formatSuccess](functions/formatSuccess.md) --- --- url: /docs/api/tcx/README.md --- **@kaiord/tcx** *** # @kaiord/tcx ## Type Aliases * [TcxValidationResult](type-aliases/TcxValidationResult.md) * [TcxValidator](type-aliases/TcxValidator.md) ## Variables * [tcxReader](variables/tcxReader.md) * [tcxWriter](variables/tcxWriter.md) ## Functions * [createFastXmlTcxReader](functions/createFastXmlTcxReader.md) * [createFastXmlTcxWriter](functions/createFastXmlTcxWriter.md) * [createTcxReader](functions/createTcxReader.md) * [createTcxWriter](functions/createTcxWriter.md) * [createXsdTcxValidator](functions/createXsdTcxValidator.md) --- --- url: /docs/api/zwo/README.md --- **@kaiord/zwo** *** # @kaiord/zwo ## Type Aliases * [ZwiftValidationError](type-aliases/ZwiftValidationError.md) * [ZwiftValidationResult](type-aliases/ZwiftValidationResult.md) * [ZwiftValidator](type-aliases/ZwiftValidator.md) ## Variables * [zwiftReader](variables/zwiftReader.md) * [zwiftWriter](variables/zwiftWriter.md) ## Functions * [createFastXmlZwiftReader](functions/createFastXmlZwiftReader.md) * [createFastXmlZwiftWriter](functions/createFastXmlZwiftWriter.md) * [createXsdZwiftValidator](functions/createXsdZwiftValidator.md) * [createZwiftReader](functions/createZwiftReader.md) * [createZwiftValidator](functions/createZwiftValidator.md) * [createZwiftWriter](functions/createZwiftWriter.md) --- --- url: /docs/api/core/classes/FitParsingError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / FitParsingError # Class: FitParsingError Defined in: [packages/core/src/domain/types/fit-errors.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/fit-errors.ts#L25) Error thrown when FIT file parsing fails. This error is thrown by FIT readers when they encounter corrupted files, invalid FIT data, or unsupported FIT features. ## Example ```typescript import { FitParsingError, convertFitToKrd } from '@kaiord/core'; try { const krd = await convertFitToKrd(fitReader, validator, logger)({ fitBuffer: corruptedBuffer }); } catch (error) { if (error instanceof FitParsingError) { console.error('FIT parsing failed:', error.message); console.error('Cause:', error.cause); } } ``` ## Extends * `FormatParsingError` ## Constructors ### Constructor > **new FitParsingError**(`message`, `cause?`): `FitParsingError` Defined in: [packages/core/src/domain/types/shared-errors.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L11) #### Parameters ##### message `string` ##### cause? `unknown` #### Returns `FitParsingError` #### Inherited from `FormatParsingError.constructor` ## Properties ### cause? > `readonly` `optional` **cause?**: `unknown` Defined in: [packages/core/src/domain/types/shared-errors.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L13) #### Inherited from `FormatParsingError.cause` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `FormatParsingError.message` *** ### name > `readonly` **name**: `"FitParsingError"` = `"FitParsingError"` Defined in: [packages/core/src/domain/types/fit-errors.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/fit-errors.ts#L26) #### Overrides `FormatParsingError.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `FormatParsingError.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `FormatParsingError.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `FormatParsingError.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `FormatParsingError.prepareStackTrace` --- --- url: /docs/api/core/classes/GarminParsingError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / GarminParsingError # Class: GarminParsingError Defined in: [packages/core/src/domain/types/garmin-errors.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/garmin-errors.ts#L6) Error thrown when Garmin Connect JSON parsing fails. ## Extends * `FormatParsingError` ## Constructors ### Constructor > **new GarminParsingError**(`message`, `cause?`): `GarminParsingError` Defined in: [packages/core/src/domain/types/shared-errors.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L11) #### Parameters ##### message `string` ##### cause? `unknown` #### Returns `GarminParsingError` #### Inherited from `FormatParsingError.constructor` ## Properties ### cause? > `readonly` `optional` **cause?**: `unknown` Defined in: [packages/core/src/domain/types/shared-errors.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L13) #### Inherited from `FormatParsingError.cause` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `FormatParsingError.message` *** ### name > `readonly` **name**: `"GarminParsingError"` = `"GarminParsingError"` Defined in: [packages/core/src/domain/types/garmin-errors.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/garmin-errors.ts#L7) #### Overrides `FormatParsingError.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `FormatParsingError.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `FormatParsingError.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `FormatParsingError.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `FormatParsingError.prepareStackTrace` --- --- url: /docs/api/core/classes/KrdValidationError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KrdValidationError # Class: KrdValidationError Defined in: [packages/core/src/domain/types/krd-errors.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/krd-errors.ts#L26) Error thrown when KRD schema validation fails. This error is thrown when KRD data doesn't conform to the expected schema, containing detailed validation errors for each field that failed validation. ## Example ```typescript import { KrdValidationError, krdSchema } from '@kaiord/core'; try { const krd = krdSchema.parse(invalidData); } catch (error) { if (error instanceof KrdValidationError) { console.error('KRD validation failed:', error.message); error.errors.forEach(err => { console.error(` ${err.field}: ${err.message}`); }); } } ``` ## Extends * `SchemaValidationError` ## Constructors ### Constructor > **new KrdValidationError**(`message`, `errors`): `KrdValidationError` Defined in: [packages/core/src/domain/types/shared-errors.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L27) #### Parameters ##### message `string` ##### errors [`ValidationError`](../type-aliases/ValidationError.md)\[] #### Returns `KrdValidationError` #### Inherited from `SchemaValidationError.constructor` ## Properties ### cause? > `optional` **cause?**: `unknown` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es2022.error.d.ts:24 #### Inherited from `SchemaValidationError.cause` *** ### errors > `readonly` **errors**: [`ValidationError`](../type-aliases/ValidationError.md)\[] Defined in: [packages/core/src/domain/types/shared-errors.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L29) #### Inherited from `SchemaValidationError.errors` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `SchemaValidationError.message` *** ### name > `readonly` **name**: `"KrdValidationError"` = `"KrdValidationError"` Defined in: [packages/core/src/domain/types/krd-errors.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/krd-errors.ts#L27) #### Overrides `SchemaValidationError.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `SchemaValidationError.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `SchemaValidationError.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `SchemaValidationError.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `SchemaValidationError.prepareStackTrace` --- --- url: /docs/api/core/classes/ServiceApiError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ServiceApiError # Class: ServiceApiError Defined in: [packages/core/src/domain/types/service-errors.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L26) Error thrown when a remote service API request fails. ## Extends * `Error` ## Constructors ### Constructor > **new ServiceApiError**(`message`, `statusCode?`, `cause?`): `ServiceApiError` Defined in: [packages/core/src/domain/types/service-errors.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L29) #### Parameters ##### message `string` ##### statusCode? `number` ##### cause? `unknown` #### Returns `ServiceApiError` #### Overrides `Error.constructor` ## Properties ### cause? > `readonly` `optional` **cause?**: `unknown` Defined in: [packages/core/src/domain/types/service-errors.ts:32](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L32) #### Inherited from `Error.cause` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `Error.message` *** ### name > `readonly` **name**: `"ServiceApiError"` = `"ServiceApiError"` Defined in: [packages/core/src/domain/types/service-errors.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L27) #### Overrides `Error.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `Error.stack` *** ### statusCode? > `readonly` `optional` **statusCode?**: `number` Defined in: [packages/core/src/domain/types/service-errors.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L31) *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `Error.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `Error.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `Error.prepareStackTrace` --- --- url: /docs/api/core/classes/ServiceAuthError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ServiceAuthError # Class: ServiceAuthError Defined in: [packages/core/src/domain/types/service-errors.ts:4](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L4) Error thrown when authentication against a remote service fails. ## Extends * `Error` ## Constructors ### Constructor > **new ServiceAuthError**(`message`, `cause?`): `ServiceAuthError` Defined in: [packages/core/src/domain/types/service-errors.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L7) #### Parameters ##### message `string` ##### cause? `unknown` #### Returns `ServiceAuthError` #### Overrides `Error.constructor` ## Properties ### cause? > `readonly` `optional` **cause?**: `unknown` Defined in: [packages/core/src/domain/types/service-errors.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L9) #### Inherited from `Error.cause` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `Error.message` *** ### name > `readonly` **name**: `"ServiceAuthError"` = `"ServiceAuthError"` Defined in: [packages/core/src/domain/types/service-errors.ts:5](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L5) #### Overrides `Error.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `Error.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `Error.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `Error.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `Error.prepareStackTrace` --- --- url: /docs/api/core/classes/TcxParsingError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TcxParsingError # Class: TcxParsingError Defined in: [packages/core/src/domain/types/tcx-errors.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tcx-errors.ts#L25) Error thrown when TCX file parsing fails. This error is thrown by TCX readers when they encounter invalid XML, malformed TCX data, or unsupported TCX features. ## Example ```typescript import { TcxParsingError, convertTcxToKrd } from '@kaiord/core'; try { const krd = await convertTcxToKrd(tcxReader, validator, logger)({ tcxString: invalidXml }); } catch (error) { if (error instanceof TcxParsingError) { console.error('TCX parsing failed:', error.message); } } ``` ## Extends * `FormatParsingError` ## Constructors ### Constructor > **new TcxParsingError**(`message`, `cause?`): `TcxParsingError` Defined in: [packages/core/src/domain/types/shared-errors.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L11) #### Parameters ##### message `string` ##### cause? `unknown` #### Returns `TcxParsingError` #### Inherited from `FormatParsingError.constructor` ## Properties ### cause? > `readonly` `optional` **cause?**: `unknown` Defined in: [packages/core/src/domain/types/shared-errors.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L13) #### Inherited from `FormatParsingError.cause` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `FormatParsingError.message` *** ### name > `readonly` **name**: `"TcxParsingError"` = `"TcxParsingError"` Defined in: [packages/core/src/domain/types/tcx-errors.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tcx-errors.ts#L26) #### Overrides `FormatParsingError.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `FormatParsingError.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `FormatParsingError.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `FormatParsingError.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `FormatParsingError.prepareStackTrace` --- --- url: /docs/api/core/classes/TcxValidationError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TcxValidationError # Class: TcxValidationError Defined in: [packages/core/src/domain/types/tcx-errors.ts:61](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tcx-errors.ts#L61) Error thrown when TCX schema validation fails. This error is thrown when TCX data doesn't conform to the expected schema. ## Example ```typescript import { TcxValidationError } from '@kaiord/core'; try { // validation code } catch (error) { if (error instanceof TcxValidationError) { error.errors.forEach(err => { console.error(`${err.field}: ${err.message}`); }); } } ``` ## Extends * `SchemaValidationError` ## Constructors ### Constructor > **new TcxValidationError**(`message`, `errors`): `TcxValidationError` Defined in: [packages/core/src/domain/types/shared-errors.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L27) #### Parameters ##### message `string` ##### errors [`ValidationError`](../type-aliases/ValidationError.md)\[] #### Returns `TcxValidationError` #### Inherited from `SchemaValidationError.constructor` ## Properties ### cause? > `optional` **cause?**: `unknown` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es2022.error.d.ts:24 #### Inherited from `SchemaValidationError.cause` *** ### errors > `readonly` **errors**: [`ValidationError`](../type-aliases/ValidationError.md)\[] Defined in: [packages/core/src/domain/types/shared-errors.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L29) #### Inherited from `SchemaValidationError.errors` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `SchemaValidationError.message` *** ### name > `readonly` **name**: `"TcxValidationError"` = `"TcxValidationError"` Defined in: [packages/core/src/domain/types/tcx-errors.ts:62](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tcx-errors.ts#L62) #### Overrides `SchemaValidationError.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `SchemaValidationError.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `SchemaValidationError.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `SchemaValidationError.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `SchemaValidationError.prepareStackTrace` --- --- url: /docs/api/core/classes/ToleranceExceededError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ToleranceExceededError # Class: ToleranceExceededError Defined in: [packages/core/src/domain/types/tolerance-errors.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tolerance-errors.ts#L28) Error thrown when round-trip conversion exceeds tolerance thresholds. This error is thrown by the tolerance checker when converting between formats results in data loss or precision errors beyond acceptable tolerances. ## Example ```typescript import { ToleranceExceededError, validateRoundTrip } from '@kaiord/core'; try { await validateRoundTrip(checker, fitReader, fitWriter, logger)({ krd: originalKrd }); } catch (error) { if (error instanceof ToleranceExceededError) { console.error('Round-trip tolerance exceeded:', error.message); error.violations.forEach(v => { console.error(` ${v.field}: expected ${v.expected}, got ${v.actual}`); console.error(` deviation: ${v.deviation}, tolerance: ${v.tolerance}`); }); } } ``` ## Extends * `Error` ## Constructors ### Constructor > **new ToleranceExceededError**(`message`, `violations`): `ToleranceExceededError` Defined in: [packages/core/src/domain/types/tolerance-errors.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tolerance-errors.ts#L31) #### Parameters ##### message `string` ##### violations [`ToleranceViolation`](../type-aliases/ToleranceViolation.md)\[] #### Returns `ToleranceExceededError` #### Overrides `Error.constructor` ## Properties ### cause? > `optional` **cause?**: `unknown` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es2022.error.d.ts:24 #### Inherited from `Error.cause` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `Error.message` *** ### name > `readonly` **name**: `"ToleranceExceededError"` = `"ToleranceExceededError"` Defined in: [packages/core/src/domain/types/tolerance-errors.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tolerance-errors.ts#L29) #### Overrides `Error.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `Error.stack` *** ### violations > `readonly` **violations**: [`ToleranceViolation`](../type-aliases/ToleranceViolation.md)\[] Defined in: [packages/core/src/domain/types/tolerance-errors.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tolerance-errors.ts#L33) *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `Error.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `Error.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `Error.prepareStackTrace` --- --- url: /docs/api/core/classes/UnsupportedKrdTypeError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / UnsupportedKrdTypeError # Class: UnsupportedKrdTypeError Defined in: [packages/core/src/domain/types/unsupported-krd-type-error.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/unsupported-krd-type-error.ts#L27) Error thrown by a workout-only format adapter (TCX, ZWO, GCN) when asked to write a KRD whose `type` is one of the health variants introduced in KRD v2.0 (`sleep_record`, `weight_measurement`, `hrv_summary`, `daily_wellness`, `body_composition`, `stress_episode`). This typed error replaces the generic `throw new Error(...)` previously used for unsupported types and lets callers (e.g., the SPA import flow) `instanceof`-check it to route the offending KRD to the FIT pipeline instead. ## Example ```typescript import { UnsupportedKrdTypeError } from '@kaiord/core'; try { await tcxWriter(sleepKrd); } catch (error) { if (error instanceof UnsupportedKrdTypeError) { console.log(`${error.adapterName} cannot write ${error.krdType}`); } } ``` ## Extends * `Error` ## Constructors ### Constructor > **new UnsupportedKrdTypeError**(`krdType`, `adapterName`): `UnsupportedKrdTypeError` Defined in: [packages/core/src/domain/types/unsupported-krd-type-error.ts:30](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/unsupported-krd-type-error.ts#L30) #### Parameters ##### krdType `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` ##### adapterName `string` #### Returns `UnsupportedKrdTypeError` #### Overrides `Error.constructor` ## Properties ### adapterName > `readonly` **adapterName**: `string` Defined in: [packages/core/src/domain/types/unsupported-krd-type-error.ts:32](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/unsupported-krd-type-error.ts#L32) *** ### cause? > `optional` **cause?**: `unknown` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es2022.error.d.ts:24 #### Inherited from `Error.cause` *** ### krdType > `readonly` **krdType**: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` Defined in: [packages/core/src/domain/types/unsupported-krd-type-error.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/unsupported-krd-type-error.ts#L31) *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `Error.message` *** ### name > `readonly` **name**: `"UnsupportedKrdTypeError"` = `"UnsupportedKrdTypeError"` Defined in: [packages/core/src/domain/types/unsupported-krd-type-error.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/unsupported-krd-type-error.ts#L28) #### Overrides `Error.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `Error.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `Error.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `Error.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `Error.prepareStackTrace` --- --- url: /docs/api/core/classes/ZwiftParsingError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ZwiftParsingError # Class: ZwiftParsingError Defined in: [packages/core/src/domain/types/zwift-errors.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/zwift-errors.ts#L25) Error thrown when Zwift workout file parsing fails. This error is thrown by Zwift readers when they encounter invalid XML, malformed ZWO data, or unsupported Zwift features. ## Example ```typescript import { ZwiftParsingError, convertZwiftToKrd } from '@kaiord/core'; try { const krd = await convertZwiftToKrd(zwiftReader, validator, logger)({ zwiftString: invalidXml }); } catch (error) { if (error instanceof ZwiftParsingError) { console.error('Zwift parsing failed:', error.message); } } ``` ## Extends * `FormatParsingError` ## Constructors ### Constructor > **new ZwiftParsingError**(`message`, `cause?`): `ZwiftParsingError` Defined in: [packages/core/src/domain/types/shared-errors.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L11) #### Parameters ##### message `string` ##### cause? `unknown` #### Returns `ZwiftParsingError` #### Inherited from `FormatParsingError.constructor` ## Properties ### cause? > `readonly` `optional` **cause?**: `unknown` Defined in: [packages/core/src/domain/types/shared-errors.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L13) #### Inherited from `FormatParsingError.cause` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `FormatParsingError.message` *** ### name > `readonly` **name**: `"ZwiftParsingError"` = `"ZwiftParsingError"` Defined in: [packages/core/src/domain/types/zwift-errors.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/zwift-errors.ts#L26) #### Overrides `FormatParsingError.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `FormatParsingError.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `FormatParsingError.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `FormatParsingError.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `FormatParsingError.prepareStackTrace` --- --- url: /docs/api/core/classes/ZwiftValidationError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ZwiftValidationError # Class: ZwiftValidationError Defined in: [packages/core/src/domain/types/zwift-errors.ts:61](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/zwift-errors.ts#L61) Error thrown when Zwift schema validation fails. This error is thrown when Zwift data doesn't conform to the expected schema. ## Example ```typescript import { ZwiftValidationError } from '@kaiord/core'; try { // validation code } catch (error) { if (error instanceof ZwiftValidationError) { error.errors.forEach(err => { console.error(`${err.field}: ${err.message}`); }); } } ``` ## Extends * `SchemaValidationError` ## Constructors ### Constructor > **new ZwiftValidationError**(`message`, `errors`): `ZwiftValidationError` Defined in: [packages/core/src/domain/types/shared-errors.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L27) #### Parameters ##### message `string` ##### errors [`ValidationError`](../type-aliases/ValidationError.md)\[] #### Returns `ZwiftValidationError` #### Inherited from `SchemaValidationError.constructor` ## Properties ### cause? > `optional` **cause?**: `unknown` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es2022.error.d.ts:24 #### Inherited from `SchemaValidationError.cause` *** ### errors > `readonly` **errors**: [`ValidationError`](../type-aliases/ValidationError.md)\[] Defined in: [packages/core/src/domain/types/shared-errors.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/shared-errors.ts#L29) #### Inherited from `SchemaValidationError.errors` *** ### message > **message**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 #### Inherited from `SchemaValidationError.message` *** ### name > `readonly` **name**: `"ZwiftValidationError"` = `"ZwiftValidationError"` Defined in: [packages/core/src/domain/types/zwift-errors.ts:62](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/zwift-errors.ts#L62) #### Overrides `SchemaValidationError.name` *** ### stack? > `optional` **stack?**: `string` Defined in: node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 #### Inherited from `SchemaValidationError.stack` *** ### stackTraceLimit > `static` **stackTraceLimit**: `number` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:67 The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### Inherited from `SchemaValidationError.stackTraceLimit` ## Methods ### captureStackTrace() > `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:51 Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. ```js const myObject = {}; Error.captureStackTrace(myObject); myObject.stack; // Similar to `new Error().stack` ``` The first line of the trace will be prefixed with `${myObject.name}: ${myObject.message}`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from the user. For instance: ```js function a() { b(); } function b() { c(); } function c() { // Create an error without stack trace to avoid calculating the stack trace twice. const { stackTraceLimit } = Error; Error.stackTraceLimit = 0; const error = new Error(); Error.stackTraceLimit = stackTraceLimit; // Capture the stack trace above function b Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace throw error; } a(); ``` #### Parameters ##### targetObject `object` ##### constructorOpt? `Function` #### Returns `void` #### Inherited from `SchemaValidationError.captureStackTrace` *** ### prepareStackTrace() > `static` **prepareStackTrace**(`err`, `stackTraces`): `any` Defined in: node\_modules/.pnpm/@types+node@26.1.2/node\_modules/@types/node/globals.d.ts:55 #### Parameters ##### err `Error` ##### stackTraces `CallSite`\[] #### Returns `any` #### See https://v8.dev/docs/stack-trace-api#customizing-stack-traces #### Inherited from `SchemaValidationError.prepareStackTrace` --- --- url: /docs/api/core/functions/aggregateEnergyBalance.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / aggregateEnergyBalance # Function: aggregateEnergyBalance() > **aggregateEnergyBalance**(`days`): [`EnergyBalanceRollup`](../type-aliases/EnergyBalanceRollup.md) Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:64](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L64) Roll up a range of `DayEnergyBalance` days into totals and averages. An empty range yields zeroed totals with `avgIntakeKcal` of `null`. ## Parameters ### days readonly `object`\[] ## Returns [`EnergyBalanceRollup`](../type-aliases/EnergyBalanceRollup.md) --- --- url: /docs/api/core/functions/assembleDayEnergyBalance.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / assembleDayEnergyBalance # Function: assembleDayEnergyBalance() > **assembleDayEnergyBalance**(`input`): `object` Defined in: [packages/core/src/application/energy/day-balance.ts:55](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L55) Assemble a validated `DayEnergyBalance` from a resolved expenditure plus the day's intake, target, and optional macro breakdowns. ## Parameters ### input [`AssembleDayEnergyBalanceInput`](../type-aliases/AssembleDayEnergyBalanceInput.md) ## Returns `object` ### activity\_kcal > **activity\_kcal**: `number` ### basal\_kcal > **basal\_kcal**: `number` ### date > **date**: `string` ### expenditure\_kcal > **expenditure\_kcal**: `number` ### intake\_kcal > **intake\_kcal**: `number` | `null` ### macro\_actuals? > `optional` **macro\_actuals?**: `object` #### macro\_actuals.carb\_g > **carb\_g**: `number` #### macro\_actuals.fat\_g > **fat\_g**: `number` #### macro\_actuals.kcal > **kcal**: `number` #### macro\_actuals.protein\_g > **protein\_g**: `number` ### macro\_targets? > `optional` **macro\_targets?**: `object` #### macro\_targets.carb\_g > **carb\_g**: `number` #### macro\_targets.fat\_g > **fat\_g**: `number` #### macro\_targets.kcal > **kcal**: `number` #### macro\_targets.protein\_g > **protein\_g**: `number` ### net\_kcal > **net\_kcal**: `number` | `null` ### source > **source**: `"measured"` | `"predicted"` | `"mixed"` = `expenditureSourceSchema` ### target\_kcal > **target\_kcal**: `number` | `null` ## Throws ZodError when the assembled view-model fails schema validation. --- --- url: /docs/api/core/functions/canonicalHash.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / canonicalHash # Function: canonicalHash() > **canonicalHash**(`value`): `string` Defined in: [packages/core/src/domain/hash/canonical-hash.ts:32](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/hash/canonical-hash.ts#L32) ## Parameters ### value `Record`<`string`, `unknown`> ## Returns `string` --- --- url: /docs/api/core/functions/computeAdaptiveTdee.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / computeAdaptiveTdee # Function: computeAdaptiveTdee() > **computeAdaptiveTdee**(`input`): [`AdaptiveTdeeResult`](../type-aliases/AdaptiveTdeeResult.md) Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:70](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L70) Back-calculate adaptive maintenance from average intake versus the smoothed weight change over a window. ## Parameters ### input [`ComputeAdaptiveTdeeInput`](../type-aliases/ComputeAdaptiveTdeeInput.md) ## Returns [`AdaptiveTdeeResult`](../type-aliases/AdaptiveTdeeResult.md) ## Throws RangeError when intake/weight are non-finite or `windowDays` <= 0. --- --- url: /docs/api/core/functions/computeBmr.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / computeBmr # Function: computeBmr() > **computeBmr**(`input`): [`BmrResult`](../type-aliases/BmrResult.md) Defined in: [packages/core/src/application/energy/bmr.ts:72](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L72) Estimate BMR (kcal/day). Uses Katch-McArdle when `bodyFatFraction` is a valid \[0, 1) fraction, otherwise Mifflin-St Jeor. ## Parameters ### input [`BmrInput`](../type-aliases/BmrInput.md) ## Returns [`BmrResult`](../type-aliases/BmrResult.md) ## Throws RangeError when weight, height, or age is not positive and finite. --- --- url: /docs/api/core/functions/computeDailyDelta.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / computeDailyDelta # Function: computeDailyDelta() > **computeDailyDelta**(`input`): [`ComputeDailyDeltaResult`](../type-aliases/ComputeDailyDeltaResult.md) Defined in: [packages/core/src/application/energy/goal-delta.ts:119](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L119) Compute the daily calorie delta (signed) for a goal, applying safety caps. ## Parameters ### input [`ComputeDailyDeltaInput`](../type-aliases/ComputeDailyDeltaInput.md) ## Returns [`ComputeDailyDeltaResult`](../type-aliases/ComputeDailyDeltaResult.md) ## Throws RangeError when weights/maintenance are not positive and finite or a date is not parseable. --- --- url: /docs/api/core/functions/computeFlag.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / computeFlag # Function: computeFlag() > **computeFlag**(`input`): `"unknown"` | `"in"` | `"low"` | `"high"` Defined in: [packages/core/src/domain/lab/lab-flag.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L33) Classify a canonical value against the effective reference range. Priority: report canonical bounds > report `refText` > catalog fallback (sex-aware when `refBySex` and `sex` are present) > `"unknown"`. A `refText` that does not parse to numeric bounds yields `"unknown"` (not highlighted). ## Parameters ### input [`ComputeFlagInput`](../type-aliases/ComputeFlagInput.md) ## Returns `"unknown"` | `"in"` | `"low"` | `"high"` --- --- url: /docs/api/core/functions/computeMacroTargets.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / computeMacroTargets # Function: computeMacroTargets() > **computeMacroTargets**(`input`): `object` Defined in: [packages/core/src/application/energy/macro-targets.ts:56](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/macro-targets.ts#L56) Derive protein/carb/fat gram targets from a calorie target and bodyweight. ## Parameters ### input [`ComputeMacroTargetsInput`](../type-aliases/ComputeMacroTargetsInput.md) ## Returns `object` ### carb\_g > **carb\_g**: `number` ### fat\_g > **fat\_g**: `number` ### kcal > **kcal**: `number` ### protein\_g > **protein\_g**: `number` ## Throws RangeError when `targetKcal` or `weightKg` is not positive and finite. --- --- url: /docs/api/core/functions/computePeriodizedTarget.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / computePeriodizedTarget # Function: computePeriodizedTarget() > **computePeriodizedTarget**(`input`): `number` Defined in: [packages/core/src/application/energy/periodized-target.ts:46](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/periodized-target.ts#L46) Resolve the floored per-day calorie target from modeled expenditure plus the goal's signed daily delta. ## Parameters ### input [`ComputePeriodizedTargetInput`](../type-aliases/ComputePeriodizedTargetInput.md) ## Returns `number` ## Throws RangeError when any kcal input is not finite. --- --- url: /docs/api/core/functions/convertBound.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / convertBound # Function: convertBound() > **convertBound**(`param`, `bound`, `unitRaw`): `number` | `undefined` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:66](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L66) Convert an optional reference bound with the same affine transform. ## Parameters ### param { `canonicalRefHigh?`: `number`; `canonicalRefLow?`: `number`; `canonicalUnit`: `string`; `key`: `string`; `knownUnits?`: `object`\[]; `loinc?`: `string`; `panel`: `"hemogram"` | `"biochemistry"` | `"lipids"` | `"hepatic"` | `"ions"` | `"iron"` | `"thyroid"` | `"vitamins"` | `"hormones"` | `"sports"`; `refBySex?`: { `female`: { `high?`: `number`; `low?`: `number`; }; `male`: { `high?`: `number`; `low?`: `number`; }; }; } | `undefined` ### bound `number` | `undefined` ### unitRaw `string` ## Returns `number` | `undefined` --- --- url: /docs/api/core/functions/convertLengthToMeters.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / convertLengthToMeters # Function: convertLengthToMeters() > **convertLengthToMeters**(`length`, `unit`): `number` Defined in: [packages/core/src/domain/converters/length-unit.converter.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/converters/length-unit.converter.ts#L3) ## Parameters ### length `number` ### unit `"meters"` | `"yards"` ## Returns `number` --- --- url: /docs/api/core/functions/convertMeasurement.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / convertMeasurement # Function: convertMeasurement() > **convertMeasurement**(`param`, `valueRaw`, `unitRaw`): [`CanonicalMeasurement`](../type-aliases/CanonicalMeasurement.md) Defined in: [packages/core/src/domain/lab/unit-conversion.ts:50](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L50) Convert an entered value to canonical, passing through when unresolvable. ## Parameters ### param { `canonicalRefHigh?`: `number`; `canonicalRefLow?`: `number`; `canonicalUnit`: `string`; `key`: `string`; `knownUnits?`: `object`\[]; `loinc?`: `string`; `panel`: `"hemogram"` | `"biochemistry"` | `"lipids"` | `"hepatic"` | `"ions"` | `"iron"` | `"thyroid"` | `"vitamins"` | `"hormones"` | `"sports"`; `refBySex?`: { `female`: { `high?`: `number`; `low?`: `number`; }; `male`: { `high?`: `number`; `low?`: `number`; }; }; } | `undefined` ### valueRaw `number` ### unitRaw `string` ## Returns [`CanonicalMeasurement`](../type-aliases/CanonicalMeasurement.md) --- --- url: /docs/api/core/functions/createConsoleLogger.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createConsoleLogger # Function: createConsoleLogger() > **createConsoleLogger**(): [`Logger`](../type-aliases/Logger.md) Defined in: [packages/core/src/adapters/logger/console-logger.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/adapters/logger/console-logger.ts#L3) ## Returns [`Logger`](../type-aliases/Logger.md) --- --- url: /docs/api/garmin-connect/functions/createCookieFetch.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / createCookieFetch # Function: createCookieFetch() > **createCookieFetch**(): (`input`, `init?`) => `Promise`<`Response`> Defined in: [garmin-connect/src/adapters/http/cookie-fetch.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/http/cookie-fetch.ts#L3) ## Returns (`input`, `init?`) => `Promise`<`Response`> --- --- url: /docs/api/tcx/functions/createFastXmlTcxReader.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / createFastXmlTcxReader # Function: createFastXmlTcxReader() > **createFastXmlTcxReader**(`logger`): `TextReader` Defined in: [adapters/fast-xml-parser.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/adapters/fast-xml-parser.ts#L15) ## Parameters ### logger `Logger` ## Returns `TextReader` --- --- url: /docs/api/tcx/functions/createFastXmlTcxWriter.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / createFastXmlTcxWriter # Function: createFastXmlTcxWriter() > **createFastXmlTcxWriter**(`logger`, `validator`): `TextWriter` Defined in: [adapters/fast-xml-parser.ts:51](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/adapters/fast-xml-parser.ts#L51) ## Parameters ### logger `Logger` ### validator [`TcxValidator`](../type-aliases/TcxValidator.md) ## Returns `TextWriter` --- --- url: /docs/api/zwo/functions/createFastXmlZwiftReader.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / createFastXmlZwiftReader # Function: createFastXmlZwiftReader() > **createFastXmlZwiftReader**(`logger`, `validator`): `TextReader` Defined in: [adapters/fast-xml-parser.ts:36](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/adapters/fast-xml-parser.ts#L36) ## Parameters ### logger `Logger` ### validator [`ZwiftValidator`](../type-aliases/ZwiftValidator.md) ## Returns `TextReader` --- --- url: /docs/api/zwo/functions/createFastXmlZwiftWriter.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / createFastXmlZwiftWriter # Function: createFastXmlZwiftWriter() > **createFastXmlZwiftWriter**(`logger`, `validator`): `TextWriter` Defined in: [adapters/fast-xml-parser.ts:47](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/adapters/fast-xml-parser.ts#L47) ## Parameters ### logger `Logger` ### validator [`ZwiftValidator`](../type-aliases/ZwiftValidator.md) ## Returns `TextWriter` --- --- url: /docs/api/garmin-connect/functions/createFileTokenStore.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / createFileTokenStore # Function: createFileTokenStore() > **createFileTokenStore**(`filePath?`): [`TokenStore`](../type-aliases/TokenStore.md) Defined in: [garmin-connect/src/adapters/token-store/file-token-store.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/token-store/file-token-store.ts#L9) ## Parameters ### filePath? `string` = `DEFAULT_PATH` ## Returns [`TokenStore`](../type-aliases/TokenStore.md) --- --- url: /docs/api/core/functions/createFitParsingError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createFitParsingError # Function: createFitParsingError() > **createFitParsingError**(`message`, `cause?`): [`FitParsingError`](../classes/FitParsingError.md) Defined in: [packages/core/src/domain/types/fit-errors.ts:45](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/fit-errors.ts#L45) Factory function to create a FitParsingError. Provides a functional programming style alternative to using `new FitParsingError()`. ## Parameters ### message `string` Error message describing the parsing failure ### cause? `unknown` Optional underlying error that caused the parsing failure ## Returns [`FitParsingError`](../classes/FitParsingError.md) A new FitParsingError instance ## Example ```typescript import { createFitParsingError } from '@kaiord/core'; throw createFitParsingError('Failed to parse FIT file', originalError); ``` --- --- url: /docs/api/fit/functions/createFitReader.md --- [**@kaiord/fit**](../README.md) *** [@kaiord/fit](../README.md) / createFitReader # Function: createFitReader() > **createFitReader**(`logger?`): `BinaryReader` Defined in: [fit/src/index.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/fit/src/index.ts#L18) ## Parameters ### logger? `Logger` ## Returns `BinaryReader` --- --- url: /docs/api/fit/functions/createFitWriter.md --- [**@kaiord/fit**](../README.md) *** [@kaiord/fit](../README.md) / createFitWriter # Function: createFitWriter() > **createFitWriter**(`logger?`): `BinaryWriter` Defined in: [fit/src/index.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/fit/src/index.ts#L21) ## Parameters ### logger? `Logger` ## Returns `BinaryWriter` --- --- url: /docs/api/garmin-connect/functions/createGarminAuthProvider.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / createGarminAuthProvider # Function: createGarminAuthProvider() > **createGarminAuthProvider**(`options`): `AuthProvider` Defined in: [garmin-connect/src/adapters/auth/garmin-auth-provider.ts:45](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/auth/garmin-auth-provider.ts#L45) ## Parameters ### options `GarminAuthProviderOptions` ## Returns `AuthProvider` --- --- url: /docs/api/garmin-connect/functions/createGarminConnectClient.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / createGarminConnectClient # Function: createGarminConnectClient() > **createGarminConnectClient**(`options?`): [`GarminConnectClient`](../type-aliases/GarminConnectClient.md) Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.ts#L28) Create a Garmin Connect client with auth, workout service, and optional token auto-restore. ## Parameters ### options? [`GarminConnectClientOptions`](../type-aliases/GarminConnectClientOptions.md) ## Returns [`GarminConnectClient`](../type-aliases/GarminConnectClient.md) ## Example ```ts const client = createGarminConnectClient({ tokenStore: createFileTokenStore(), retry: { maxRetries: 3 }, }); const { restored } = await client.init(); if (!restored) await client.auth.login(email, password); ``` --- --- url: /docs/api/fit/functions/createGarminFitSdkReader.md --- [**@kaiord/fit**](../README.md) *** [@kaiord/fit](../README.md) / createGarminFitSdkReader # Function: createGarminFitSdkReader() > **createGarminFitSdkReader**(`logger`): `BinaryReader` Defined in: [fit/src/adapters/garmin-fitsdk.ts:62](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/fit/src/adapters/garmin-fitsdk.ts#L62) ## Parameters ### logger `Logger` ## Returns `BinaryReader` --- --- url: /docs/api/fit/functions/createGarminFitSdkWriter.md --- [**@kaiord/fit**](../README.md) *** [@kaiord/fit](../README.md) / createGarminFitSdkWriter # Function: createGarminFitSdkWriter() > **createGarminFitSdkWriter**(`logger`): `BinaryWriter` Defined in: [fit/src/adapters/garmin-fitsdk.ts:93](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/fit/src/adapters/garmin-fitsdk.ts#L93) ## Parameters ### logger `Logger` ## Returns `BinaryWriter` --- --- url: /docs/api/core/functions/createGarminParsingError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createGarminParsingError # Function: createGarminParsingError() > **createGarminParsingError**(`message`, `cause?`): [`GarminParsingError`](../classes/GarminParsingError.md) Defined in: [packages/core/src/domain/types/garmin-errors.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/garmin-errors.ts#L10) ## Parameters ### message `string` ### cause? `unknown` ## Returns [`GarminParsingError`](../classes/GarminParsingError.md) --- --- url: /docs/api/garmin/functions/createGarminReader.md --- [**@kaiord/garmin**](../README.md) *** [@kaiord/garmin](../README.md) / createGarminReader # Function: createGarminReader() > **createGarminReader**(`logger?`): `TextReader` Defined in: [index.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/index.ts#L24) ## Parameters ### logger? `Logger` ## Returns `TextReader` --- --- url: /docs/api/garmin/functions/createGarminWriter.md --- [**@kaiord/garmin**](../README.md) *** [@kaiord/garmin](../README.md) / createGarminWriter # Function: createGarminWriter() > **createGarminWriter**(`options?`): `TextWriter` Defined in: [index.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/index.ts#L27) ## Parameters ### options? `Logger` | [`GarminWriterOptions`](../type-aliases/GarminWriterOptions.md) ## Returns `TextWriter` --- --- url: /docs/api/core/functions/createKrdValidationError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createKrdValidationError # Function: createKrdValidationError() > **createKrdValidationError**(`message`, `errors`): [`KrdValidationError`](../classes/KrdValidationError.md) Defined in: [packages/core/src/domain/types/krd-errors.ts:49](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/krd-errors.ts#L49) Factory function to create a KrdValidationError. Provides a functional programming style alternative to using `new KrdValidationError()`. ## Parameters ### message `string` Error message describing the validation failure ### errors [`ValidationError`](../type-aliases/ValidationError.md)\[] Array of validation errors with field-level details ## Returns [`KrdValidationError`](../classes/KrdValidationError.md) A new KrdValidationError instance ## Example ```typescript import { createKrdValidationError } from '@kaiord/core'; throw createKrdValidationError('KRD validation failed', [ { field: 'version', message: 'Required field missing' }, { field: 'type', message: 'Invalid value' } ]); ``` --- --- url: /docs/api/garmin-connect/functions/createMemoryTokenStore.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / createMemoryTokenStore # Function: createMemoryTokenStore() > **createMemoryTokenStore**(): [`TokenStore`](../type-aliases/TokenStore.md) Defined in: [garmin-connect/src/adapters/token-store/memory-token-store.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/token-store/memory-token-store.ts#L3) ## Returns [`TokenStore`](../type-aliases/TokenStore.md) --- --- url: /docs/api/core/functions/createNoopAnalytics.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createNoopAnalytics # Function: createNoopAnalytics() > **createNoopAnalytics**(): [`Analytics`](../type-aliases/Analytics.md) Defined in: [packages/core/src/adapters/analytics/noop-analytics.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/adapters/analytics/noop-analytics.ts#L3) ## Returns [`Analytics`](../type-aliases/Analytics.md) --- --- url: /docs/api/core/functions/createSchemaValidator.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createSchemaValidator # Function: createSchemaValidator() > **createSchemaValidator**(): [`SchemaValidator`](../type-aliases/SchemaValidator.md) Defined in: [packages/core/src/domain/validation/schema-validator.ts:8](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/schema-validator.ts#L8) ## Returns [`SchemaValidator`](../type-aliases/SchemaValidator.md) --- --- url: /docs/api/mcp/functions/createServer.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / createServer # Function: createServer() > **createServer**(): `McpServer` Defined in: [server/create-server.ts:44](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/server/create-server.ts#L44) ## Returns `McpServer` --- --- url: /docs/api/core/functions/createServiceApiError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createServiceApiError # Function: createServiceApiError() > **createServiceApiError**(`message`, `statusCode?`, `cause?`): [`ServiceApiError`](../classes/ServiceApiError.md) Defined in: [packages/core/src/domain/types/service-errors.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L41) ## Parameters ### message `string` ### statusCode? `number` ### cause? `unknown` ## Returns [`ServiceApiError`](../classes/ServiceApiError.md) --- --- url: /docs/api/core/functions/createServiceAuthError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createServiceAuthError # Function: createServiceAuthError() > **createServiceAuthError**(`message`, `cause?`): [`ServiceAuthError`](../classes/ServiceAuthError.md) Defined in: [packages/core/src/domain/types/service-errors.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/service-errors.ts#L18) ## Parameters ### message `string` ### cause? `unknown` ## Returns [`ServiceAuthError`](../classes/ServiceAuthError.md) --- --- url: /docs/api/mcp/functions/createStderrLogger.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / createStderrLogger # Function: createStderrLogger() > **createStderrLogger**(): `Logger` Defined in: [adapters/stderr-logger.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/adapters/stderr-logger.ts#L3) ## Returns `Logger` --- --- url: /docs/api/core/functions/createTcxParsingError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createTcxParsingError # Function: createTcxParsingError() > **createTcxParsingError**(`message`, `cause?`): [`TcxParsingError`](../classes/TcxParsingError.md) Defined in: [packages/core/src/domain/types/tcx-errors.ts:36](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tcx-errors.ts#L36) Factory function to create a TcxParsingError. ## Parameters ### message `string` Error message describing the parsing failure ### cause? `unknown` Optional underlying error that caused the parsing failure ## Returns [`TcxParsingError`](../classes/TcxParsingError.md) A new TcxParsingError instance --- --- url: /docs/api/tcx/functions/createTcxReader.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / createTcxReader # Function: createTcxReader() > **createTcxReader**(`logger?`): `TextReader` Defined in: [index.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/index.ts#L14) ## Parameters ### logger? `Logger` ## Returns `TextReader` --- --- url: /docs/api/core/functions/createTcxValidationError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createTcxValidationError # Function: createTcxValidationError() > **createTcxValidationError**(`message`, `errors`): [`TcxValidationError`](../classes/TcxValidationError.md) Defined in: [packages/core/src/domain/types/tcx-errors.ts:72](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/tcx-errors.ts#L72) Factory function to create a TcxValidationError. ## Parameters ### message `string` Error message describing the validation failure ### errors [`ValidationError`](../type-aliases/ValidationError.md)\[] Array of validation errors with field-level details ## Returns [`TcxValidationError`](../classes/TcxValidationError.md) A new TcxValidationError instance --- --- url: /docs/api/tcx/functions/createTcxWriter.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / createTcxWriter # Function: createTcxWriter() > **createTcxWriter**(`logger?`): `TextWriter` Defined in: [index.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/index.ts#L19) ## Parameters ### logger? `Logger` ## Returns `TextWriter` --- --- url: /docs/api/garmin-connect/functions/createTokenManager.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / createTokenManager # Function: createTokenManager() > **createTokenManager**(`options`): `TokenManager` Defined in: [garmin-connect/src/adapters/token/token-manager.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/token/token-manager.ts#L18) ## Parameters ### options `Options` ## Returns `TokenManager` --- --- url: /docs/api/core/functions/createToleranceChecker.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createToleranceChecker # Function: createToleranceChecker() > **createToleranceChecker**(`config?`): [`ToleranceChecker`](../type-aliases/ToleranceChecker.md) Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:62](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L62) ## Parameters ### config? #### cadenceTolerance `number` = `...` #### distanceTolerance `number` = `...` #### ftpTolerance `number` = `...` #### hrTolerance `number` = `...` #### paceTolerance `number` = `...` #### powerTolerance `number` = `...` #### timeTolerance `number` = `...` ## Returns [`ToleranceChecker`](../type-aliases/ToleranceChecker.md) --- --- url: /docs/api/core/functions/createUnsupportedKrdTypeError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createUnsupportedKrdTypeError # Function: createUnsupportedKrdTypeError() > **createUnsupportedKrdTypeError**(`krdType`, `adapterName`): [`UnsupportedKrdTypeError`](../classes/UnsupportedKrdTypeError.md) Defined in: [packages/core/src/domain/types/unsupported-krd-type-error.ts:49](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/unsupported-krd-type-error.ts#L49) Factory function to create an UnsupportedKrdTypeError. ## Parameters ### krdType `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` The offending `krd.type` value. ### adapterName `string` The name of the rejecting adapter (e.g. "tcx"). ## Returns [`UnsupportedKrdTypeError`](../classes/UnsupportedKrdTypeError.md) --- --- url: /docs/api/core/functions/createWorkoutKRD.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createWorkoutKRD # Function: createWorkoutKRD() > **createWorkoutKRD**(`workout`, `options?`): `object` Defined in: [packages/core/src/domain/converters/workout-to-krd.converter.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/converters/workout-to-krd.converter.ts#L21) Creates a valid KRD envelope for a structured workout. Validates unknown input against workoutSchema before wrapping. Designed as a validation boundary for agent-provided data. ## Parameters ### workout `unknown` Unknown data to validate and wrap in KRD format ### options? `CreateWorkoutKRDOptions` Optional overrides (created timestamp for testability) ## Returns `object` Valid KRD with type "structured\_workout" ### events? > `optional` **events?**: `object`\[] ### extensions? > `optional` **extensions?**: `object` #### Index Signature \[`key`: `string`]: `unknown` #### extensions.course? > `optional` **course?**: `unknown` #### extensions.course\_points? > `optional` **course\_points?**: `unknown` #### extensions.fit? > `optional` **fit?**: `unknown` #### extensions.health? > `optional` **health?**: `object` ##### Index Signature \[`key`: `string`]: `unknown` #### extensions.health.bodyComposition? > `optional` **bodyComposition?**: `object` #### extensions.health.bodyComposition.basalMetabolicRateKcal? > `optional` **basalMetabolicRateKcal?**: `number` #### extensions.health.bodyComposition.bmi? > `optional` **bmi?**: `number` #### extensions.health.bodyComposition.bodyFatPercent? > `optional` **bodyFatPercent?**: `number` #### extensions.health.bodyComposition.bodyWaterPercent? > `optional` **bodyWaterPercent?**: `number` #### extensions.health.bodyComposition.boneMassKilograms? > `optional` **boneMassKilograms?**: `number` #### extensions.health.bodyComposition.externalId? > `optional` **externalId?**: `string` #### extensions.health.bodyComposition.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.bodyComposition.kind > **kind**: `"bodyComposition"` #### extensions.health.bodyComposition.leanMassKilograms? > `optional` **leanMassKilograms?**: `number` #### extensions.health.bodyComposition.measuredAt > **measuredAt**: `string` #### extensions.health.bodyComposition.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.bodyComposition.version > **version**: `string` = `healthVersionSchema` #### extensions.health.bodyComposition.visceralFatRating? > `optional` **visceralFatRating?**: `number` #### extensions.health.daily? > `optional` **daily?**: `object` #### extensions.health.daily.activeCalories > **activeCalories**: `number` #### extensions.health.daily.date > **date**: `string` #### extensions.health.daily.externalId? > `optional` **externalId?**: `string` #### extensions.health.daily.floorsClimbed? > `optional` **floorsClimbed?**: `number` #### extensions.health.daily.intensityMinutes > **intensityMinutes**: `object` #### extensions.health.daily.intensityMinutes.moderate > **moderate**: `number` #### extensions.health.daily.intensityMinutes.vigorous > **vigorous**: `number` #### extensions.health.daily.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.daily.kind > **kind**: `"daily"` #### extensions.health.daily.restingCalories > **restingCalories**: `number` #### extensions.health.daily.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.daily.steps > **steps**: `number` #### extensions.health.daily.version > **version**: `string` = `healthVersionSchema` #### extensions.health.hrv? > `optional` **hrv?**: `object` #### extensions.health.hrv.externalId? > `optional` **externalId?**: `string` #### extensions.health.hrv.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.hrv.kind > **kind**: `"hrv"` #### extensions.health.hrv.measuredAt > **measuredAt**: `string` #### extensions.health.hrv.measurementWindow > **measurementWindow**: `"overnight"` | `"spot"` #### extensions.health.hrv.rMSSD > **rMSSD**: `number` #### extensions.health.hrv.score? > `optional` **score?**: `number` #### extensions.health.hrv.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.hrv.version > **version**: `string` = `healthVersionSchema` #### extensions.health.sleep? > `optional` **sleep?**: `object` #### extensions.health.sleep.endTime > **endTime**: `string` #### extensions.health.sleep.externalId? > `optional` **externalId?**: `string` #### extensions.health.sleep.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.sleep.kind > **kind**: `"sleep"` #### extensions.health.sleep.restingHeartRate? > `optional` **restingHeartRate?**: `number` #### extensions.health.sleep.score? > `optional` **score?**: `number` #### extensions.health.sleep.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.sleep.stages > **stages**: `object`\[] #### extensions.health.sleep.startTime > **startTime**: `string` #### extensions.health.sleep.totalDurationSeconds > **totalDurationSeconds**: `number` #### extensions.health.sleep.version > **version**: `string` = `healthVersionSchema` #### extensions.health.stress? > `optional` **stress?**: `object` #### extensions.health.stress.averageLevel > **averageLevel**: `number` #### extensions.health.stress.endTime > **endTime**: `string` #### extensions.health.stress.externalId? > `optional` **externalId?**: `string` #### extensions.health.stress.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.stress.kind > **kind**: `"stress"` #### extensions.health.stress.peakLevel > **peakLevel**: `number` #### extensions.health.stress.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.stress.startTime > **startTime**: `string` #### extensions.health.stress.version > **version**: `string` = `healthVersionSchema` #### extensions.health.weight? > `optional` **weight?**: `object` #### extensions.health.weight.externalId? > `optional` **externalId?**: `string` #### extensions.health.weight.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.weight.kind > **kind**: `"weight"` #### extensions.health.weight.measuredAt > **measuredAt**: `string` #### extensions.health.weight.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.weight.version > **version**: `string` = `healthVersionSchema` #### extensions.health.weight.weightKilograms > **weightKilograms**: `number` #### extensions.structured\_workout? > `optional` **structured\_workout?**: `unknown` ### laps? > `optional` **laps?**: `object`\[] ### metadata > **metadata**: `object` = `krdMetadataSchema` #### metadata.created > **created**: `string` #### metadata.manufacturer? > `optional` **manufacturer?**: `string` #### metadata.product? > `optional` **product?**: `string` #### metadata.serialNumber? > `optional` **serialNumber?**: `string` #### metadata.sport? > `optional` **sport?**: `string` ##### See sportSchema for known sport values. Accepts custom strings for forward compatibility. Optional at the metadata level because health-metric KRD types (sleep, weight, HRV, daily wellness, body composition, stress) have no associated sport. A conditional refinement on `krdSchema` still requires `sport` for the three legacy workout/activity/course types so v1.x consumers see no change for those. #### metadata.subSport? > `optional` **subSport?**: `string` ### records? > `optional` **records?**: `object`\[] ### sessions? > `optional` **sessions?**: `object`\[] ### type > **type**: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` = `fileTypeSchema` ### version > **version**: `string` ## Throws If workout validation fails --- --- url: /docs/api/tcx/functions/createXsdTcxValidator.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / createXsdTcxValidator # Function: createXsdTcxValidator() > **createXsdTcxValidator**(`logger`): [`TcxValidator`](../type-aliases/TcxValidator.md) Defined in: [adapters/xsd-validator.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/adapters/xsd-validator.ts#L7) ## Parameters ### logger `Logger` ## Returns [`TcxValidator`](../type-aliases/TcxValidator.md) --- --- url: /docs/api/zwo/functions/createXsdZwiftValidator.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / createXsdZwiftValidator # Function: createXsdZwiftValidator() > **createXsdZwiftValidator**(`logger`): [`ZwiftValidator`](../type-aliases/ZwiftValidator.md) Defined in: [adapters/xsd-validator.ts:47](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/adapters/xsd-validator.ts#L47) Creates a Zwift validator with full XSD schema validation. Only available in Node.js environments. ## Parameters ### logger `Logger` Logger instance for diagnostic messages ## Returns [`ZwiftValidator`](../type-aliases/ZwiftValidator.md) ZwiftValidator function with XSD validation --- --- url: /docs/api/core/functions/createZwiftParsingError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createZwiftParsingError # Function: createZwiftParsingError() > **createZwiftParsingError**(`message`, `cause?`): [`ZwiftParsingError`](../classes/ZwiftParsingError.md) Defined in: [packages/core/src/domain/types/zwift-errors.ts:36](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/zwift-errors.ts#L36) Factory function to create a ZwiftParsingError. ## Parameters ### message `string` Error message describing the parsing failure ### cause? `unknown` Optional underlying error that caused the parsing failure ## Returns [`ZwiftParsingError`](../classes/ZwiftParsingError.md) A new ZwiftParsingError instance --- --- url: /docs/api/zwo/functions/createZwiftReader.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / createZwiftReader # Function: createZwiftReader() > **createZwiftReader**(`logger?`): `TextReader` Defined in: [index.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/index.ts#L17) ## Parameters ### logger? `Logger` ## Returns `TextReader` --- --- url: /docs/api/core/functions/createZwiftValidationError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / createZwiftValidationError # Function: createZwiftValidationError() > **createZwiftValidationError**(`message`, `errors`): [`ZwiftValidationError`](../classes/ZwiftValidationError.md) Defined in: [packages/core/src/domain/types/zwift-errors.ts:72](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/zwift-errors.ts#L72) Factory function to create a ZwiftValidationError. ## Parameters ### message `string` Error message describing the validation failure ### errors [`ValidationError`](../type-aliases/ValidationError.md)\[] Array of validation errors with field-level details ## Returns [`ZwiftValidationError`](../classes/ZwiftValidationError.md) A new ZwiftValidationError instance --- --- url: /docs/api/zwo/functions/createZwiftValidator.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / createZwiftValidator # Function: createZwiftValidator() > **createZwiftValidator**(`logger`): [`ZwiftValidator`](../type-aliases/ZwiftValidator.md) Defined in: [adapters/xsd-validator.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/adapters/xsd-validator.ts#L28) Creates a Zwift validator that automatically chooses the appropriate validation strategy: * In Node.js: Full XSD schema validation * In browsers: XML well-formedness validation only This ensures the library works in both environments without requiring separate builds. ## Parameters ### logger `Logger` Logger instance for diagnostic messages ## Returns [`ZwiftValidator`](../type-aliases/ZwiftValidator.md) ZwiftValidator function --- --- url: /docs/api/zwo/functions/createZwiftWriter.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / createZwiftWriter # Function: createZwiftWriter() > **createZwiftWriter**(`logger?`): `TextWriter` Defined in: [index.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/index.ts#L23) ## Parameters ### logger? `Logger` ## Returns `TextWriter` --- --- url: /docs/api/core/functions/customParameterKey.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / customParameterKey # Function: customParameterKey() > **customParameterKey**(`slug`): `string` Defined in: [packages/core/src/domain/lab/lab-parameter-catalog.ts:44](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter-catalog.ts#L44) Build a free-parameter key for the long tail (`custom:`). ## Parameters ### slug `string` ## Returns `string` --- --- url: /docs/api/core/functions/deriveExternalId.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / deriveExternalId # Function: deriveExternalId() > **deriveExternalId**(`input`): `string` Defined in: [packages/core/src/domain/ingest/derive-external-id.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/ingest/derive-external-id.ts#L11) Derives a stable external id for a health record from its payload + measuredAt timestamp. The `k1:` prefix is a version tag: if the hash projection ever changes, the prefix can be bumped to `k2:` so downstream migration code can distinguish old ids from new ones without inspecting content. ## Parameters ### input #### measuredAt `string` #### payload `Record`<`string`, `unknown`> ## Returns `string` --- --- url: /docs/api/mcp/functions/detectFormatFromPath.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / detectFormatFromPath # Function: detectFormatFromPath() > **detectFormatFromPath**(`filePath`): `"fit"` | `"tcx"` | `"zwo"` | `"gcn"` | `"krd"` | `null` Defined in: [utils/detect-format-from-path.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/utils/detect-format-from-path.ts#L6) ## Parameters ### filePath `string` ## Returns `"fit"` | `"tcx"` | `"zwo"` | `"gcn"` | `"krd"` | `null` --- --- url: /docs/api/fit/functions/encodeBodyCompositionFit.md --- [**@kaiord/fit**](../README.md) *** [@kaiord/fit](../README.md) / encodeBodyCompositionFit # Function: encodeBodyCompositionFit() > **encodeBodyCompositionFit**(`krd`, `logger?`): `Uint8Array` Defined in: [fit/src/adapters/garmin-fitsdk.ts:52](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/fit/src/adapters/garmin-fitsdk.ts#L52) Converts a KRD carrying weight and/or body composition into real FIT file bytes (a `weight_scale`/mesgNum-30 message) ready to POST to Garmin's upload endpoint. Emits `weight_scale`, not `body_composition` (mesgNum 41), which is absent from the SDK Profile and would throw at the Encoder. ## Parameters ### krd #### events? `object`\[] #### extensions? {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; } #### extensions.course? `unknown` #### extensions.course\_points? `unknown` #### extensions.fit? `unknown` #### extensions.health? {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; } #### extensions.health.bodyComposition? { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; } #### extensions.health.bodyComposition.basalMetabolicRateKcal? `number` #### extensions.health.bodyComposition.bmi? `number` #### extensions.health.bodyComposition.bodyFatPercent? `number` #### extensions.health.bodyComposition.bodyWaterPercent? `number` #### extensions.health.bodyComposition.boneMassKilograms? `number` #### extensions.health.bodyComposition.externalId? `string` #### extensions.health.bodyComposition.kaiordRecordId? `string` #### extensions.health.bodyComposition.kind `"bodyComposition"` #### extensions.health.bodyComposition.leanMassKilograms? `number` #### extensions.health.bodyComposition.measuredAt `string` #### extensions.health.bodyComposition.sourceBridgeId? `string` #### extensions.health.bodyComposition.version `string` #### extensions.health.bodyComposition.visceralFatRating? `number` #### extensions.health.daily? { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; } #### extensions.health.daily.activeCalories `number` #### extensions.health.daily.date `string` #### extensions.health.daily.externalId? `string` #### extensions.health.daily.floorsClimbed? `number` #### extensions.health.daily.intensityMinutes { `moderate`: `number`; `vigorous`: `number`; } #### extensions.health.daily.intensityMinutes.moderate `number` #### extensions.health.daily.intensityMinutes.vigorous `number` #### extensions.health.daily.kaiordRecordId? `string` #### extensions.health.daily.kind `"daily"` #### extensions.health.daily.restingCalories `number` #### extensions.health.daily.sourceBridgeId? `string` #### extensions.health.daily.steps `number` #### extensions.health.daily.version `string` #### extensions.health.hrv? { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; } #### extensions.health.hrv.externalId? `string` #### extensions.health.hrv.kaiordRecordId? `string` #### extensions.health.hrv.kind `"hrv"` #### extensions.health.hrv.measuredAt `string` #### extensions.health.hrv.measurementWindow `"overnight"` | `"spot"` #### extensions.health.hrv.rMSSD `number` #### extensions.health.hrv.score? `number` #### extensions.health.hrv.sourceBridgeId? `string` #### extensions.health.hrv.version `string` #### extensions.health.sleep? { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; } #### extensions.health.sleep.endTime `string` #### extensions.health.sleep.externalId? `string` #### extensions.health.sleep.kaiordRecordId? `string` #### extensions.health.sleep.kind `"sleep"` #### extensions.health.sleep.restingHeartRate? `number` #### extensions.health.sleep.score? `number` #### extensions.health.sleep.sourceBridgeId? `string` #### extensions.health.sleep.stages `object`\[] #### extensions.health.sleep.startTime `string` #### extensions.health.sleep.totalDurationSeconds `number` #### extensions.health.sleep.version `string` #### extensions.health.stress? { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; } #### extensions.health.stress.averageLevel `number` #### extensions.health.stress.endTime `string` #### extensions.health.stress.externalId? `string` #### extensions.health.stress.kaiordRecordId? `string` #### extensions.health.stress.kind `"stress"` #### extensions.health.stress.peakLevel `number` #### extensions.health.stress.sourceBridgeId? `string` #### extensions.health.stress.startTime `string` #### extensions.health.stress.version `string` #### extensions.health.weight? { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; } #### extensions.health.weight.externalId? `string` #### extensions.health.weight.kaiordRecordId? `string` #### extensions.health.weight.kind `"weight"` #### extensions.health.weight.measuredAt `string` #### extensions.health.weight.sourceBridgeId? `string` #### extensions.health.weight.version `string` #### extensions.health.weight.weightKilograms `number` #### extensions.structured\_workout? `unknown` #### laps? `object`\[] #### metadata { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; } #### metadata.created `string` #### metadata.manufacturer? `string` #### metadata.product? `string` #### metadata.serialNumber? `string` #### metadata.sport? `string` #### metadata.subSport? `string` #### records? `object`\[] #### sessions? `object`\[] #### type `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` #### version `string` ### logger? `Logger` ## Returns `Uint8Array` --- --- url: /docs/api/fit/functions/encodeFitMessages.md --- [**@kaiord/fit**](../README.md) *** [@kaiord/fit](../README.md) / encodeFitMessages # Function: encodeFitMessages() > **encodeFitMessages**(`messages`, `logger`): `Uint8Array` Defined in: [fit/src/adapters/garmin-fitsdk.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/fit/src/adapters/garmin-fitsdk.ts#L23) Encodes a list of raw FIT messages (each carrying a `mesgNum`) into real FIT file bytes via the @garmin/fitsdk `Encoder`. Shared by the workout writer and the body-composition upload path so both drive the same real SDK encode. ## Parameters ### messages `unknown`\[] ### logger `Logger` ## Returns `Uint8Array` --- --- url: /docs/api/core/functions/estimateExpectedActivityKcal.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / estimateExpectedActivityKcal # Function: estimateExpectedActivityKcal() > **estimateExpectedActivityKcal**(`input`): `number` Defined in: [packages/core/src/application/energy/expected-activity-kcal.ts:82](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expected-activity-kcal.ts#L82) Estimate a planned workout's activity kcal via the first applicable tier (power → running-distance → MET). Result is rounded to integer kcal. ## Parameters ### input [`ExpectedActivityKcalInput`](../type-aliases/ExpectedActivityKcalInput.md) ## Returns `number` ## Throws RangeError when required inputs are not positive and finite, or when an optional input is present but not non-negative and finite. --- --- url: /docs/api/core/functions/exponentialMovingAverage.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / exponentialMovingAverage # Function: exponentialMovingAverage() > **exponentialMovingAverage**(`points`, `options`): [`EmaResult`](../type-aliases/EmaResult.md)\[] Defined in: [packages/core/src/application/energy/ema.ts:60](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L60) Compute the running EMA of a dated series (ascending by date). Returns a same-length series of `{ date, ema }`; the first ema equals the first value. ## Parameters ### points readonly [`EmaPoint`](../type-aliases/EmaPoint.md)\[] ### options [`EmaOptions`](../type-aliases/EmaOptions.md) ## Returns [`EmaResult`](../type-aliases/EmaResult.md)\[] ## Throws RangeError when `windowDays` is not positive and finite, or when any point value is non-finite. --- --- url: /docs/api/core/functions/extractWorkout.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / extractWorkout # Function: extractWorkout() > **extractWorkout**(`krd`): `object` Defined in: [packages/core/src/domain/validation/extract-workout.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/extract-workout.ts#L17) Extracts and validates the structured workout from a KRD object. Checks that the KRD type is "structured\_workout" and validates the workout in extensions.structured\_workout against workoutSchema. ## Parameters ### krd KRD object to extract workout from #### events? `object`\[] = `...` #### extensions? {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; } = `...` #### extensions.course? `unknown` = `...` #### extensions.course\_points? `unknown` = `...` #### extensions.fit? `unknown` = `...` #### extensions.health? {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; } = `...` #### extensions.health.bodyComposition? { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; } = `...` #### extensions.health.bodyComposition.basalMetabolicRateKcal? `number` = `...` #### extensions.health.bodyComposition.bmi? `number` = `...` #### extensions.health.bodyComposition.bodyFatPercent? `number` = `...` #### extensions.health.bodyComposition.bodyWaterPercent? `number` = `...` #### extensions.health.bodyComposition.boneMassKilograms? `number` = `...` #### extensions.health.bodyComposition.externalId? `string` = `...` #### extensions.health.bodyComposition.kaiordRecordId? `string` = `...` #### extensions.health.bodyComposition.kind `"bodyComposition"` = `...` #### extensions.health.bodyComposition.leanMassKilograms? `number` = `...` #### extensions.health.bodyComposition.measuredAt `string` = `...` #### extensions.health.bodyComposition.sourceBridgeId? `string` = `...` #### extensions.health.bodyComposition.version `string` = `healthVersionSchema` #### extensions.health.bodyComposition.visceralFatRating? `number` = `...` #### extensions.health.daily? { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; } = `...` #### extensions.health.daily.activeCalories `number` = `...` #### extensions.health.daily.date `string` = `...` #### extensions.health.daily.externalId? `string` = `...` #### extensions.health.daily.floorsClimbed? `number` = `...` #### extensions.health.daily.intensityMinutes { `moderate`: `number`; `vigorous`: `number`; } = `...` #### extensions.health.daily.intensityMinutes.moderate `number` = `...` #### extensions.health.daily.intensityMinutes.vigorous `number` = `...` #### extensions.health.daily.kaiordRecordId? `string` = `...` #### extensions.health.daily.kind `"daily"` = `...` #### extensions.health.daily.restingCalories `number` = `...` #### extensions.health.daily.sourceBridgeId? `string` = `...` #### extensions.health.daily.steps `number` = `...` #### extensions.health.daily.version `string` = `healthVersionSchema` #### extensions.health.hrv? { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; } = `...` #### extensions.health.hrv.externalId? `string` = `...` #### extensions.health.hrv.kaiordRecordId? `string` = `...` #### extensions.health.hrv.kind `"hrv"` = `...` #### extensions.health.hrv.measuredAt `string` = `...` #### extensions.health.hrv.measurementWindow `"overnight"` | `"spot"` = `...` #### extensions.health.hrv.rMSSD `number` = `...` #### extensions.health.hrv.score? `number` = `...` #### extensions.health.hrv.sourceBridgeId? `string` = `...` #### extensions.health.hrv.version `string` = `healthVersionSchema` #### extensions.health.sleep? { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; } = `...` #### extensions.health.sleep.endTime `string` = `...` #### extensions.health.sleep.externalId? `string` = `...` #### extensions.health.sleep.kaiordRecordId? `string` = `...` #### extensions.health.sleep.kind `"sleep"` = `...` #### extensions.health.sleep.restingHeartRate? `number` = `...` #### extensions.health.sleep.score? `number` = `...` #### extensions.health.sleep.sourceBridgeId? `string` = `...` #### extensions.health.sleep.stages `object`\[] = `...` #### extensions.health.sleep.startTime `string` = `...` #### extensions.health.sleep.totalDurationSeconds `number` = `...` #### extensions.health.sleep.version `string` = `healthVersionSchema` #### extensions.health.stress? { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; } = `...` #### extensions.health.stress.averageLevel `number` = `...` #### extensions.health.stress.endTime `string` = `...` #### extensions.health.stress.externalId? `string` = `...` #### extensions.health.stress.kaiordRecordId? `string` = `...` #### extensions.health.stress.kind `"stress"` = `...` #### extensions.health.stress.peakLevel `number` = `...` #### extensions.health.stress.sourceBridgeId? `string` = `...` #### extensions.health.stress.startTime `string` = `...` #### extensions.health.stress.version `string` = `healthVersionSchema` #### extensions.health.weight? { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; } = `...` #### extensions.health.weight.externalId? `string` = `...` #### extensions.health.weight.kaiordRecordId? `string` = `...` #### extensions.health.weight.kind `"weight"` = `...` #### extensions.health.weight.measuredAt `string` = `...` #### extensions.health.weight.sourceBridgeId? `string` = `...` #### extensions.health.weight.version `string` = `healthVersionSchema` #### extensions.health.weight.weightKilograms `number` = `...` #### extensions.structured\_workout? `unknown` = `...` #### laps? `object`\[] = `...` #### metadata { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; } = `krdMetadataSchema` #### metadata.created `string` = `...` #### metadata.manufacturer? `string` = `...` #### metadata.product? `string` = `...` #### metadata.serialNumber? `string` = `...` #### metadata.sport? `string` = `...` **See** sportSchema for known sport values. Accepts custom strings for forward compatibility. Optional at the metadata level because health-metric KRD types (sleep, weight, HRV, daily wellness, body composition, stress) have no associated sport. A conditional refinement on `krdSchema` still requires `sport` for the three legacy workout/activity/course types so v1.x consumers see no change for those. #### metadata.subSport? `string` = `...` #### records? `object`\[] = `...` #### sessions? `object`\[] = `...` #### type `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` = `fileTypeSchema` #### version `string` = `...` ## Returns Validated Workout object ### extensions? > `optional` **extensions?**: `Record`<`string`, `unknown`> ### name? > `optional` **name?**: `string` ### notes? > `optional` **notes?**: `string` Workout-level free-text coaching instructions (e.g. Train2Go coach descriptions, possibly containing markdown `[label](url)` links). Distinct from per-step `notes` and from the short `name`. No length cap here; format adapters whose target imposes one (FIT step notes: 256) truncate best-effort at export rather than rejecting the KRD. ### poolLength? > `optional` **poolLength?**: `number` meters — always normalized to meters on ingest ### poolLengthUnit? > `optional` **poolLengthUnit?**: `"meters"` ### sport > **sport**: `"generic"` | `"running"` | `"cycling"` | `"transition"` | `"fitness_equipment"` | `"swimming"` | `"basketball"` | `"soccer"` | `"tennis"` | `"american_football"` | `"training"` | `"walking"` | `"cross_country_skiing"` | `"alpine_skiing"` | `"snowboarding"` | `"rowing"` | `"mountaineering"` | `"hiking"` | `"multisport"` | `"paddling"` | `"flying"` | `"e_biking"` | `"motorcycling"` | `"boating"` | `"driving"` | `"golf"` | `"hang_gliding"` | `"horseback_riding"` | `"hunting"` | `"fishing"` | `"inline_skating"` | `"rock_climbing"` | `"sailing"` | `"ice_skating"` | `"sky_diving"` | `"snowshoeing"` | `"snowmobiling"` | `"stand_up_paddleboarding"` | `"surfing"` | `"wakeboarding"` | `"water_skiing"` | `"kayaking"` | `"rafting"` | `"windsurfing"` | `"kitesurfing"` | `"tactical"` | `"jumpmaster"` | `"boxing"` | `"floor_climbing"` | `"baseball"` | `"diving"` | `"shooting"` | `"winter_sport"` | `"grinding"` | `"hiit"` | `"video_gaming"` | `"racket"` | `"wheelchair_push_walk"` | `"wheelchair_push_run"` | `"meditation"` | `"para_sport"` | `"disc_golf"` | `"team_sport"` | `"cricket"` | `"rugby"` | `"hockey"` | `"lacrosse"` | `"volleyball"` | `"water_tubing"` | `"wakesurfing"` | `"water_sport"` | `"archery"` | `"mixed_martial_arts"` | `"motor_sports"` | `"snorkeling"` | `"dance"` | `"jump_rope"` | `"pool_apnea"` | `"mobility"` | `"geocaching"` | `"canoeing"` = `sportSchema` ### steps > **steps**: ({ `duration`: { `seconds`: `number`; `type`: `"time"`; } | { `meters`: `number`; `type`: `"distance"`; } | { `bpm`: `number`; `type`: `"heart_rate_less_than"`; } | { `bpm`: `number`; `repeatFrom`: `number`; `type`: `"repeat_until_heart_rate_greater_than"`; } | { `calories`: `number`; `type`: `"calories"`; } | { `type`: `"power_less_than"`; `watts`: `number`; } | { `type`: `"power_greater_than"`; `watts`: `number`; } | { `repeatFrom`: `number`; `seconds`: `number`; `type`: `"repeat_until_time"`; } | { `meters`: `number`; `repeatFrom`: `number`; `type`: `"repeat_until_distance"`; } | { `calories`: `number`; `repeatFrom`: `number`; `type`: `"repeat_until_calories"`; } | { `bpm`: `number`; `repeatFrom`: `number`; `type`: `"repeat_until_heart_rate_less_than"`; } | { `repeatFrom`: `number`; `type`: `"repeat_until_power_less_than"`; `watts`: `number`; } | { `repeatFrom`: `number`; `type`: `"repeat_until_power_greater_than"`; `watts`: `number`; } | { `type`: `"open"`; }; `durationType`: `"time"` | `"distance"` | `"heart_rate_less_than"` | `"repeat_until_heart_rate_greater_than"` | `"calories"` | `"power_less_than"` | `"power_greater_than"` | `"repeat_until_time"` | `"repeat_until_distance"` | `"repeat_until_calories"` | `"repeat_until_heart_rate_less_than"` | `"repeat_until_power_less_than"` | `"repeat_until_power_greater_than"` | `"open"`; `equipment?`: `"none"` | `"swim_fins"` | `"swim_kickboard"` | `"swim_paddles"` | `"swim_pull_buoy"` | `"swim_snorkel"`; `extensions?`: `Record`<`string`, `unknown`>; `intensity?`: `"warmup"` | `"active"` | `"cooldown"` | `"rest"` | `"recovery"` | `"interval"` | `"other"`; `name?`: `string`; `notes?`: `string`; `stepIndex`: `number`; `target`: { `type`: `"power"`; `value`: { `max`: `number`; `min`: `number`; `unit`: `"range"`; } | { `unit`: `"watts"`; `value`: `number`; } | { `unit`: `"percent_ftp"`; `value`: `number`; } | { `unit`: `"zone"`; `value`: `number`; }; } | { `type`: `"heart_rate"`; `value`: { `max`: `number`; `min`: `number`; `unit`: `"range"`; } | { `unit`: `"bpm"`; `value`: `number`; } | { `unit`: `"zone"`; `value`: `number`; } | { `unit`: `"percent_max"`; `value`: `number`; }; } | { `type`: `"cadence"`; `value`: { `max`: `number`; `min`: `number`; `unit`: `"range"`; } | { `unit`: `"rpm"`; `value`: `number`; }; } | { `type`: `"pace"`; `value`: { `max`: `number`; `min`: `number`; `unit`: `"range"`; } | { `unit`: `"mps"`; `value`: `number`; } | { `unit`: `"zone"`; `value`: `number`; }; } | { `type`: `"stroke_type"`; `value`: { `unit`: `"swim_stroke"`; `value`: `number`; }; } | { `type`: `"open"`; }; `targetType`: `"cadence"` | `"power"` | `"open"` | `"heart_rate"` | `"pace"` | `"stroke_type"`; } | { `id?`: `string`; `repeatCount`: `number`; `steps`: `object`\[]; })\[] ### subSport? > `optional` **subSport?**: `"match"` | `"map"` | `"generic"` | `"treadmill"` | `"street"` | `"trail"` | `"track"` | `"spin"` | `"indoor_cycling"` | `"road"` | `"mountain"` | `"downhill"` | `"recumbent"` | `"cyclocross"` | `"hand_cycling"` | `"track_cycling"` | `"indoor_rowing"` | `"elliptical"` | `"stair_climbing"` | `"lap_swimming"` | `"open_water"` | `"flexibility_training"` | `"strength_training"` | `"warm_up"` | `"exercise"` | `"challenge"` | `"indoor_skiing"` | `"cardio_training"` | `"indoor_walking"` | `"e_bike_fitness"` | `"bmx"` | `"casual_walking"` | `"speed_walking"` | `"bike_to_run_transition"` | `"run_to_bike_transition"` | `"swim_to_bike_transition"` | `"atv"` | `"motocross"` | `"backcountry"` | `"resort"` | `"rc_drone"` | `"wingsuit"` | `"whitewater"` | `"skate_skiing"` | `"yoga"` | `"pilates"` | `"indoor_running"` | `"gravel_cycling"` | `"e_bike_mountain"` | `"commuting"` | `"mixed_surface"` | `"navigate"` | `"track_me"` | `"single_gas_diving"` | `"multi_gas_diving"` | `"gauge_diving"` | `"apnea_diving"` | `"apnea_hunting"` | `"virtual_activity"` | `"obstacle"` | `"all"` ## Throws If KRD is not a structured workout or workout is invalid --- --- url: /docs/api/core/functions/fingerprintSnapshot.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / fingerprintSnapshot # Function: fingerprintSnapshot() > **fingerprintSnapshot**(`profileId`, `snapshot`): `string` Defined in: [packages/core/src/protocol/profile-snapshot.ts:127](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/protocol/profile-snapshot.ts#L127) ## Parameters ### profileId `string` ### snapshot #### activeSport? `"running"` | `"cycling"` | `"swimming"` = `...` #### generatedAt `string` = `...` #### heartRate { `lthr?`: `number`; `max?`: `number`; } = `...` #### heartRate.lthr? `number` = `...` #### heartRate.max? `number` = `...` #### profile { `bodyWeight?`: `number`; `name`: `string`; } = `...` #### profile.bodyWeight? `number` = `...` #### profile.name `string` = `...` #### schemaVersion `1` = `...` #### thresholds { `cycling?`: { `ftp?`: `number`; }; `running?`: { `lthr?`: `number`; `thresholdPaceSecPerKm?`: `number`; }; `swimming?`: { `cssPaceSecPer100m?`: `number`; }; } = `...` #### thresholds.cycling? { `ftp?`: `number`; } = `...` #### thresholds.cycling.ftp? `number` = `...` #### thresholds.running? { `lthr?`: `number`; `thresholdPaceSecPerKm?`: `number`; } = `...` #### thresholds.running.lthr? `number` = `...` #### thresholds.running.thresholdPaceSecPerKm? `number` = `...` #### thresholds.swimming? { `cssPaceSecPer100m?`: `number`; } = `...` #### thresholds.swimming.cssPaceSecPer100m? `number` = `...` ## Returns `string` --- --- url: /docs/api/mcp/functions/formatError.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / formatError # Function: formatError() > **formatError**(`error`): [`ToolResult`](../type-aliases/ToolResult.md) Defined in: [utils/error-formatter.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/utils/error-formatter.ts#L17) ## Parameters ### error `unknown` ## Returns [`ToolResult`](../type-aliases/ToolResult.md) --- --- url: /docs/api/mcp/functions/formatSuccess.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / formatSuccess # Function: formatSuccess() > **formatSuccess**(`text`): [`ToolResult`](../type-aliases/ToolResult.md) Defined in: [utils/error-formatter.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/utils/error-formatter.ts#L13) ## Parameters ### text `string` ## Returns [`ToolResult`](../type-aliases/ToolResult.md) --- --- url: /docs/api/core/functions/fromBinary.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / fromBinary # Function: fromBinary() > **fromBinary**(`buffer`, `reader`, `logger?`): `Promise`<{ `events?`: `object`\[]; `extensions?`: {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; }; `laps?`: `object`\[]; `metadata`: { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; }; `records?`: `object`\[]; `sessions?`: `object`\[]; `type`: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"`; `version`: `string`; }> Defined in: [packages/core/src/application/from-format.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/from-format.ts#L17) Converts binary format data to KRD with validation. ## Parameters ### buffer `Uint8Array` ### reader [`BinaryReader`](../type-aliases/BinaryReader.md) ### logger? [`Logger`](../type-aliases/Logger.md) ## Returns `Promise`<{ `events?`: `object`\[]; `extensions?`: {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; }; `laps?`: `object`\[]; `metadata`: { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; }; `records?`: `object`\[]; `sessions?`: `object`\[]; `type`: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"`; `version`: `string`; }> ## Example ```typescript import { fromBinary } from '@kaiord/core'; import { fitReader } from '@kaiord/fit'; const krd = await fromBinary(buffer, fitReader); ``` --- --- url: /docs/api/core/functions/fromCanonicalValue.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / fromCanonicalValue # Function: fromCanonicalValue() > **fromCanonicalValue**(`valueCanonical`, `unit`): `number` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L14) Inverse of [toCanonicalValue](toCanonicalValue.md): valueRaw = (canonical − offset) / factor. ## Parameters ### valueCanonical `number` ### unit [`AffineUnit`](../type-aliases/AffineUnit.md) ## Returns `number` --- --- url: /docs/api/core/functions/fromText.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / fromText # Function: fromText() > **fromText**(`text`, `reader`, `logger?`): `Promise`<{ `events?`: `object`\[]; `extensions?`: {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; }; `laps?`: `object`\[]; `metadata`: { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; }; `records?`: `object`\[]; `sessions?`: `object`\[]; `type`: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"`; `version`: `string`; }> Defined in: [packages/core/src/application/from-format.ts:40](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/from-format.ts#L40) Converts text format data to KRD with validation. ## Parameters ### text `string` ### reader [`TextReader`](../type-aliases/TextReader.md) ### logger? [`Logger`](../type-aliases/Logger.md) ## Returns `Promise`<{ `events?`: `object`\[]; `extensions?`: {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; }; `laps?`: `object`\[]; `metadata`: { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; }; `records?`: `object`\[]; `sessions?`: `object`\[]; `type`: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"`; `version`: `string`; }> ## Example ```typescript import { fromText } from '@kaiord/core'; import { tcxReader } from '@kaiord/tcx'; const krd = await fromText(xmlString, tcxReader); ``` --- --- url: /docs/api/core/functions/getLabParameter.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / getLabParameter # Function: getLabParameter() > **getLabParameter**(`key`): { `canonicalRefHigh?`: `number`; `canonicalRefLow?`: `number`; `canonicalUnit`: `string`; `key`: `string`; `knownUnits?`: `object`\[]; `loinc?`: `string`; `panel`: `"hemogram"` | `"biochemistry"` | `"lipids"` | `"hepatic"` | `"ions"` | `"iron"` | `"thyroid"` | `"vitamins"` | `"hormones"` | `"sports"`; `refBySex?`: { `female`: { `high?`: `number`; `low?`: `number`; }; `male`: { `high?`: `number`; `low?`: `number`; }; }; } | `undefined` Defined in: [packages/core/src/domain/lab/lab-parameter-catalog.ts:37](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter-catalog.ts#L37) Look up a core parameter by its canonical key. ## Parameters ### key `string` ## Returns { `canonicalRefHigh?`: `number`; `canonicalRefLow?`: `number`; `canonicalUnit`: `string`; `key`: `string`; `knownUnits?`: `object`\[]; `loinc?`: `string`; `panel`: `"hemogram"` | `"biochemistry"` | `"lipids"` | `"hepatic"` | `"ions"` | `"iron"` | `"thyroid"` | `"vitamins"` | `"hormones"` | `"sports"`; `refBySex?`: { `female`: { `high?`: `number`; `low?`: `number`; }; `male`: { `high?`: `number`; `low?`: `number`; }; }; } | `undefined` --- --- url: /docs/api/core/functions/isCustomParameterKey.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / isCustomParameterKey # Function: isCustomParameterKey() > **isCustomParameterKey**(`key`): `boolean` Defined in: [packages/core/src/domain/lab/lab-parameter-catalog.ts:49](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter-catalog.ts#L49) Whether a parameter key denotes a free (custom) parameter. ## Parameters ### key `string` ## Returns `boolean` --- --- url: /docs/api/core/functions/isHealthFileType.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / isHealthFileType # Function: isHealthFileType() > **isHealthFileType**(`value`): value is "sleep\_record" | "weight\_measurement" | "hrv\_summary" | "daily\_wellness" | "body\_composition" | "stress\_episode" Defined in: [packages/core/src/domain/schemas/file-type.ts:51](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/file-type.ts#L51) ## Parameters ### value `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` ## Returns value is "sleep\_record" | "weight\_measurement" | "hrv\_summary" | "daily\_wellness" | "body\_composition" | "stress\_episode" --- --- url: /docs/api/core/functions/isPowerZone.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / isPowerZone # Function: isPowerZone() > **isPowerZone**(`value`): `value is PowerZone` Defined in: [packages/core/src/domain/zones/power-zones.ts:38](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/zones/power-zones.ts#L38) Type guard: narrows `number` to `PowerZone` when value is an integer in \[1, 7]. ## Parameters ### value `number` ## Returns `value is PowerZone` --- --- url: /docs/api/core/functions/isRepetitionBlock.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / isRepetitionBlock # Function: isRepetitionBlock() > **isRepetitionBlock**(`step`): step is { id?: string; repeatCount: number; steps: { duration: { seconds: number; type: "time" } | { meters: number; type: "distance" } | { bpm: number; type: "heart\_rate\_less\_than" } | { bpm: number; repeatFrom: number; type: "repeat\_until\_heart\_rate\_greater\_than" } | { calories: number; type: "calories" } | { type: "power\_less\_than"; watts: number } | { type: "power\_greater\_than"; watts: number } | { repeatFrom: number; seconds: number; type: "repeat\_until\_time" } | { meters: number; repeatFrom: number; type: "repeat\_until\_distance" } | { calories: number; repeatFrom: number; type: "repeat\_until\_calories" } | { bpm: number; repeatFrom: number; type: "repeat\_until\_heart\_rate\_less\_than" } | { repeatFrom: number; type: "repeat\_until\_power\_less\_than"; watts: number } | { repeatFrom: number; type: "repeat\_until\_power\_greater\_than"; watts: number } | { type: "open" }; durationType: "time" | "distance" | "heart\_rate\_less\_than" | "repeat\_until\_heart\_rate\_greater\_than" | "calories" | "power\_less\_than" | "power\_greater\_than" | "repeat\_until\_time" | "repeat\_until\_distance" | "repeat\_until\_calories" | "repeat\_until\_heart\_rate\_less\_than" | "repeat\_until\_power\_less\_than" | "repeat\_until\_power\_greater\_than" | "open"; equipment?: "none" | "swim\_fins" | "swim\_kickboard" | "swim\_paddles" | "swim\_pull\_buoy" | "swim\_snorkel"; extensions?: Record\; intensity?: "warmup" | "active" | "cooldown" | "rest" | "recovery" | "interval" | "other"; name?: string; notes?: string; stepIndex: number; target: { type: "power"; value: { max: number; min: number; unit: "range" } | { unit: "watts"; value: number } | { unit: "percent\_ftp"; value: number } | { unit: "zone"; value: number } } | { type: "heart\_rate"; value: { max: number; min: number; unit: "range" } | { unit: "bpm"; value: number } | { unit: "zone"; value: number } | { unit: "percent\_max"; value: number } } | { type: "cadence"; value: { max: number; min: number; unit: "range" } | { unit: "rpm"; value: number } } | { type: "pace"; value: { max: number; min: number; unit: "range" } | { unit: "mps"; value: number } | { unit: "zone"; value: number } } | { type: "stroke\_type"; value: { unit: "swim\_stroke"; value: number } } | { type: "open" }; targetType: "cadence" | "power" | "open" | "heart\_rate" | "pace" | "stroke\_type" }\[] } Defined in: [packages/core/src/domain/type-guards.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/type-guards.ts#L9) Type guard to check if a workout step is a RepetitionBlock. Checks for both `repeatCount` and `steps` properties to reliably discriminate between WorkoutStep and RepetitionBlock union members. ## Parameters ### step { `duration`: { `seconds`: `number`; `type`: `"time"`; } | { `meters`: `number`; `type`: `"distance"`; } | { `bpm`: `number`; `type`: `"heart_rate_less_than"`; } | { `bpm`: `number`; `repeatFrom`: `number`; `type`: `"repeat_until_heart_rate_greater_than"`; } | { `calories`: `number`; `type`: `"calories"`; } | { `type`: `"power_less_than"`; `watts`: `number`; } | { `type`: `"power_greater_than"`; `watts`: `number`; } | { `repeatFrom`: `number`; `seconds`: `number`; `type`: `"repeat_until_time"`; } | { `meters`: `number`; `repeatFrom`: `number`; `type`: `"repeat_until_distance"`; } | { `calories`: `number`; `repeatFrom`: `number`; `type`: `"repeat_until_calories"`; } | { `bpm`: `number`; `repeatFrom`: `number`; `type`: `"repeat_until_heart_rate_less_than"`; } | { `repeatFrom`: `number`; `type`: `"repeat_until_power_less_than"`; `watts`: `number`; } | { `repeatFrom`: `number`; `type`: `"repeat_until_power_greater_than"`; `watts`: `number`; } | { `type`: `"open"`; }; `durationType`: `"time"` | `"distance"` | `"heart_rate_less_than"` | `"repeat_until_heart_rate_greater_than"` | `"calories"` | `"power_less_than"` | `"power_greater_than"` | `"repeat_until_time"` | `"repeat_until_distance"` | `"repeat_until_calories"` | `"repeat_until_heart_rate_less_than"` | `"repeat_until_power_less_than"` | `"repeat_until_power_greater_than"` | `"open"`; `equipment?`: `"none"` | `"swim_fins"` | `"swim_kickboard"` | `"swim_paddles"` | `"swim_pull_buoy"` | `"swim_snorkel"`; `extensions?`: `Record`<`string`, `unknown`>; `intensity?`: `"warmup"` | `"active"` | `"cooldown"` | `"rest"` | `"recovery"` | `"interval"` | `"other"`; `name?`: `string`; `notes?`: `string`; `stepIndex`: `number`; `target`: { `type`: `"power"`; `value`: { `max`: `number`; `min`: `number`; `unit`: `"range"`; } | { `unit`: `"watts"`; `value`: `number`; } | { `unit`: `"percent_ftp"`; `value`: `number`; } | { `unit`: `"zone"`; `value`: `number`; }; } | { `type`: `"heart_rate"`; `value`: { `max`: `number`; `min`: `number`; `unit`: `"range"`; } | { `unit`: `"bpm"`; `value`: `number`; } | { `unit`: `"zone"`; `value`: `number`; } | { `unit`: `"percent_max"`; `value`: `number`; }; } | { `type`: `"cadence"`; `value`: { `max`: `number`; `min`: `number`; `unit`: `"range"`; } | { `unit`: `"rpm"`; `value`: `number`; }; } | { `type`: `"pace"`; `value`: { `max`: `number`; `min`: `number`; `unit`: `"range"`; } | { `unit`: `"mps"`; `value`: `number`; } | { `unit`: `"zone"`; `value`: `number`; }; } | { `type`: `"stroke_type"`; `value`: { `unit`: `"swim_stroke"`; `value`: `number`; }; } | { `type`: `"open"`; }; `targetType`: `"cadence"` | `"power"` | `"open"` | `"heart_rate"` | `"pace"` | `"stroke_type"`; } | { `id?`: `string`; `repeatCount`: `number`; `steps`: `object`\[]; } ## Returns step is { id?: string; repeatCount: number; steps: { duration: { seconds: number; type: "time" } | { meters: number; type: "distance" } | { bpm: number; type: "heart\_rate\_less\_than" } | { bpm: number; repeatFrom: number; type: "repeat\_until\_heart\_rate\_greater\_than" } | { calories: number; type: "calories" } | { type: "power\_less\_than"; watts: number } | { type: "power\_greater\_than"; watts: number } | { repeatFrom: number; seconds: number; type: "repeat\_until\_time" } | { meters: number; repeatFrom: number; type: "repeat\_until\_distance" } | { calories: number; repeatFrom: number; type: "repeat\_until\_calories" } | { bpm: number; repeatFrom: number; type: "repeat\_until\_heart\_rate\_less\_than" } | { repeatFrom: number; type: "repeat\_until\_power\_less\_than"; watts: number } | { repeatFrom: number; type: "repeat\_until\_power\_greater\_than"; watts: number } | { type: "open" }; durationType: "time" | "distance" | "heart\_rate\_less\_than" | "repeat\_until\_heart\_rate\_greater\_than" | "calories" | "power\_less\_than" | "power\_greater\_than" | "repeat\_until\_time" | "repeat\_until\_distance" | "repeat\_until\_calories" | "repeat\_until\_heart\_rate\_less\_than" | "repeat\_until\_power\_less\_than" | "repeat\_until\_power\_greater\_than" | "open"; equipment?: "none" | "swim\_fins" | "swim\_kickboard" | "swim\_paddles" | "swim\_pull\_buoy" | "swim\_snorkel"; extensions?: Record\; intensity?: "warmup" | "active" | "cooldown" | "rest" | "recovery" | "interval" | "other"; name?: string; notes?: string; stepIndex: number; target: { type: "power"; value: { max: number; min: number; unit: "range" } | { unit: "watts"; value: number } | { unit: "percent\_ftp"; value: number } | { unit: "zone"; value: number } } | { type: "heart\_rate"; value: { max: number; min: number; unit: "range" } | { unit: "bpm"; value: number } | { unit: "zone"; value: number } | { unit: "percent\_max"; value: number } } | { type: "cadence"; value: { max: number; min: number; unit: "range" } | { unit: "rpm"; value: number } } | { type: "pace"; value: { max: number; min: number; unit: "range" } | { unit: "mps"; value: number } | { unit: "zone"; value: number } } | { type: "stroke\_type"; value: { unit: "swim\_stroke"; value: number } } | { type: "open" }; targetType: "cadence" | "power" | "open" | "heart\_rate" | "pace" | "stroke\_type" }\[] } --- --- url: /docs/api/garmin/functions/mapGarminSportToKrd.md --- [**@kaiord/garmin**](../README.md) *** [@kaiord/garmin](../README.md) / mapGarminSportToKrd # Function: mapGarminSportToKrd() > **mapGarminSportToKrd**(`sportTypeKey`): `"running"` | `"cycling"` | `"hiking"` | `"swimming"` | `"generic"` | `"transition"` | `"fitness_equipment"` | `"basketball"` | `"soccer"` | `"tennis"` | `"american_football"` | `"training"` | `"walking"` | `"cross_country_skiing"` | `"alpine_skiing"` | `"snowboarding"` | `"rowing"` | `"mountaineering"` | `"multisport"` | `"paddling"` | `"flying"` | `"e_biking"` | `"motorcycling"` | `"boating"` | `"driving"` | `"golf"` | `"hang_gliding"` | `"horseback_riding"` | `"hunting"` | `"fishing"` | `"inline_skating"` | `"rock_climbing"` | `"sailing"` | `"ice_skating"` | `"sky_diving"` | `"snowshoeing"` | `"snowmobiling"` | `"stand_up_paddleboarding"` | `"surfing"` | `"wakeboarding"` | `"water_skiing"` | `"kayaking"` | `"rafting"` | `"windsurfing"` | `"kitesurfing"` | `"tactical"` | `"jumpmaster"` | `"boxing"` | `"floor_climbing"` | `"baseball"` | `"diving"` | `"shooting"` | `"winter_sport"` | `"grinding"` | `"hiit"` | `"video_gaming"` | `"racket"` | `"wheelchair_push_walk"` | `"wheelchair_push_run"` | `"meditation"` | `"para_sport"` | `"disc_golf"` | `"team_sport"` | `"cricket"` | `"rugby"` | `"hockey"` | `"lacrosse"` | `"volleyball"` | `"water_tubing"` | `"wakesurfing"` | `"water_sport"` | `"archery"` | `"mixed_martial_arts"` | `"motor_sports"` | `"snorkeling"` | `"dance"` | `"jump_rope"` | `"pool_apnea"` | `"mobility"` | `"geocaching"` | `"canoeing"` Defined in: [adapters/mappers/sport.mapper.ts:39](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/adapters/mappers/sport.mapper.ts#L39) ## Parameters ### sportTypeKey `string` ## Returns `"running"` | `"cycling"` | `"hiking"` | `"swimming"` | `"generic"` | `"transition"` | `"fitness_equipment"` | `"basketball"` | `"soccer"` | `"tennis"` | `"american_football"` | `"training"` | `"walking"` | `"cross_country_skiing"` | `"alpine_skiing"` | `"snowboarding"` | `"rowing"` | `"mountaineering"` | `"multisport"` | `"paddling"` | `"flying"` | `"e_biking"` | `"motorcycling"` | `"boating"` | `"driving"` | `"golf"` | `"hang_gliding"` | `"horseback_riding"` | `"hunting"` | `"fishing"` | `"inline_skating"` | `"rock_climbing"` | `"sailing"` | `"ice_skating"` | `"sky_diving"` | `"snowshoeing"` | `"snowmobiling"` | `"stand_up_paddleboarding"` | `"surfing"` | `"wakeboarding"` | `"water_skiing"` | `"kayaking"` | `"rafting"` | `"windsurfing"` | `"kitesurfing"` | `"tactical"` | `"jumpmaster"` | `"boxing"` | `"floor_climbing"` | `"baseball"` | `"diving"` | `"shooting"` | `"winter_sport"` | `"grinding"` | `"hiit"` | `"video_gaming"` | `"racket"` | `"wheelchair_push_walk"` | `"wheelchair_push_run"` | `"meditation"` | `"para_sport"` | `"disc_golf"` | `"team_sport"` | `"cricket"` | `"rugby"` | `"hockey"` | `"lacrosse"` | `"volleyball"` | `"water_tubing"` | `"wakesurfing"` | `"water_sport"` | `"archery"` | `"mixed_martial_arts"` | `"motor_sports"` | `"snorkeling"` | `"dance"` | `"jump_rope"` | `"pool_apnea"` | `"mobility"` | `"geocaching"` | `"canoeing"` --- --- url: /docs/api/core/functions/metForSport.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / metForSport # Function: metForSport() > **metForSport**(`sport`): `number` Defined in: [packages/core/src/application/energy/met-table.ts:74](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/met-table.ts#L74) Resolve a sport's MET value, falling back to [DEFAULT\_MET](../variables/DEFAULT_MET.md) for any sport absent from [MET\_TABLE](../variables/MET_TABLE.md). ## Parameters ### sport `"generic"` | `"running"` | `"cycling"` | `"transition"` | `"fitness_equipment"` | `"swimming"` | `"basketball"` | `"soccer"` | `"tennis"` | `"american_football"` | `"training"` | `"walking"` | `"cross_country_skiing"` | `"alpine_skiing"` | `"snowboarding"` | `"rowing"` | `"mountaineering"` | `"hiking"` | `"multisport"` | `"paddling"` | `"flying"` | `"e_biking"` | `"motorcycling"` | `"boating"` | `"driving"` | `"golf"` | `"hang_gliding"` | `"horseback_riding"` | `"hunting"` | `"fishing"` | `"inline_skating"` | `"rock_climbing"` | `"sailing"` | `"ice_skating"` | `"sky_diving"` | `"snowshoeing"` | `"snowmobiling"` | `"stand_up_paddleboarding"` | `"surfing"` | `"wakeboarding"` | `"water_skiing"` | `"kayaking"` | `"rafting"` | `"windsurfing"` | `"kitesurfing"` | `"tactical"` | `"jumpmaster"` | `"boxing"` | `"floor_climbing"` | `"baseball"` | `"diving"` | `"shooting"` | `"winter_sport"` | `"grinding"` | `"hiit"` | `"video_gaming"` | `"racket"` | `"wheelchair_push_walk"` | `"wheelchair_push_run"` | `"meditation"` | `"para_sport"` | `"disc_golf"` | `"team_sport"` | `"cricket"` | `"rugby"` | `"hockey"` | `"lacrosse"` | `"volleyball"` | `"water_tubing"` | `"wakesurfing"` | `"water_sport"` | `"archery"` | `"mixed_martial_arts"` | `"motor_sports"` | `"snorkeling"` | `"dance"` | `"jump_rope"` | `"pool_apnea"` | `"mobility"` | `"geocaching"` | `"canoeing"` ## Returns `number` --- --- url: /docs/api/core/functions/neatFactorForActivityLevel.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / neatFactorForActivityLevel # Function: neatFactorForActivityLevel() > **neatFactorForActivityLevel**(`level?`): `number` Defined in: [packages/core/src/application/energy/activity-factor.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/activity-factor.ts#L34) Resolve the NEAT multiplier for an activity level, falling back to `DEFAULT_NEAT_FACTOR` when the level is unset (`undefined`/`null`). ## Parameters ### level? [`ActivityLevel`](../type-aliases/ActivityLevel.md) | `null` ## Returns `number` --- --- url: /docs/api/core/functions/parseRefTextBounds.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / parseRefTextBounds # Function: parseRefTextBounds() > **parseRefTextBounds**(`refText`): `Bounds` | `undefined` Defined in: [packages/core/src/domain/lab/ref-text.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/ref-text.ts#L16) Parse a printed reference range into numeric bounds. Recognizes `"low-high"`, `"< high"`, and `"> low"` (with unicode dashes and `≤ / ≥`). Returns `undefined` for text that carries no numeric bounds (e.g. `"negativo"`), so the caller can flag the value as `"unknown"`. ## Parameters ### refText `string` ## Returns `Bounds` | `undefined` --- --- url: /docs/api/core/functions/percentFtpToZone.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / percentFtpToZone # Function: percentFtpToZone() > **percentFtpToZone**(`percent`): [`PowerZone`](../type-aliases/PowerZone.md) Defined in: [packages/core/src/domain/zones/power-zones.ts:73](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/zones/power-zones.ts#L73) Inverse of `zoneToPercentFtp`: map a percent-FTP value back to the zone whose canonical percent equals it exactly. Round-trip identity: `percentFtpToZone(zoneToPercentFtp(z)) === z` for every `z` in \[1, 7]. ## Parameters ### percent `number` ## Returns [`PowerZone`](../type-aliases/PowerZone.md) ## Throws RangeError when `percent` does not exactly match any of the seven canonical band values (55, 75, 90, 105, 120, 150, 200). This function is intentionally a discrete inverse, not a nearest-band classifier — adapters that need fuzzy classification should layer that policy on top. --- --- url: /docs/api/core/functions/resolveAffineUnit.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / resolveAffineUnit # Function: resolveAffineUnit() > **resolveAffineUnit**(`param`, `unitRaw`): [`AffineUnit`](../type-aliases/AffineUnit.md) | `null` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L28) Resolve the affine transform for `unitRaw` on a parameter. The canonical unit maps to identity (factor 1). A free parameter (`param` undefined) or an unrecognized unit returns `null`, signalling passthrough (no conversion). ## Parameters ### param { `canonicalRefHigh?`: `number`; `canonicalRefLow?`: `number`; `canonicalUnit`: `string`; `key`: `string`; `knownUnits?`: `object`\[]; `loinc?`: `string`; `panel`: `"hemogram"` | `"biochemistry"` | `"lipids"` | `"hepatic"` | `"ions"` | `"iron"` | `"thyroid"` | `"vitamins"` | `"hormones"` | `"sports"`; `refBySex?`: { `female`: { `high?`: `number`; `low?`: `number`; }; `male`: { `high?`: `number`; `low?`: `number`; }; }; } | `undefined` ### unitRaw `string` ## Returns [`AffineUnit`](../type-aliases/AffineUnit.md) | `null` --- --- url: /docs/api/core/functions/resolveDayExpenditure.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / resolveDayExpenditure # Function: resolveDayExpenditure() > **resolveDayExpenditure**(`input`): [`DayExpenditureResult`](../type-aliases/DayExpenditureResult.md) Defined in: [packages/core/src/application/energy/expenditure.ts:102](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L102) Resolve a day's total energy expenditure, preferring measured device data over the predicted BMR + expected-activity model. ## Parameters ### input [`DayExpenditureInput`](../type-aliases/DayExpenditureInput.md) ## Returns [`DayExpenditureResult`](../type-aliases/DayExpenditureResult.md) --- --- url: /docs/api/core/functions/sportCategory.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / sportCategory # Function: sportCategory() > **sportCategory**(`sport`): [`SportCategory`](../type-aliases/SportCategory.md) Defined in: [packages/core/src/domain/schemas/sport-category.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/sport-category.ts#L26) Classify a sport into its capability category. Unknown / non-endurance sports (training, rowing, tennis, …) fall through to `other`. ## Parameters ### sport `"generic"` | `"running"` | `"cycling"` | `"transition"` | `"fitness_equipment"` | `"swimming"` | `"basketball"` | `"soccer"` | `"tennis"` | `"american_football"` | `"training"` | `"walking"` | `"cross_country_skiing"` | `"alpine_skiing"` | `"snowboarding"` | `"rowing"` | `"mountaineering"` | `"hiking"` | `"multisport"` | `"paddling"` | `"flying"` | `"e_biking"` | `"motorcycling"` | `"boating"` | `"driving"` | `"golf"` | `"hang_gliding"` | `"horseback_riding"` | `"hunting"` | `"fishing"` | `"inline_skating"` | `"rock_climbing"` | `"sailing"` | `"ice_skating"` | `"sky_diving"` | `"snowshoeing"` | `"snowmobiling"` | `"stand_up_paddleboarding"` | `"surfing"` | `"wakeboarding"` | `"water_skiing"` | `"kayaking"` | `"rafting"` | `"windsurfing"` | `"kitesurfing"` | `"tactical"` | `"jumpmaster"` | `"boxing"` | `"floor_climbing"` | `"baseball"` | `"diving"` | `"shooting"` | `"winter_sport"` | `"grinding"` | `"hiit"` | `"video_gaming"` | `"racket"` | `"wheelchair_push_walk"` | `"wheelchair_push_run"` | `"meditation"` | `"para_sport"` | `"disc_golf"` | `"team_sport"` | `"cricket"` | `"rugby"` | `"hockey"` | `"lacrosse"` | `"volleyball"` | `"water_tubing"` | `"wakesurfing"` | `"water_sport"` | `"archery"` | `"mixed_martial_arts"` | `"motor_sports"` | `"snorkeling"` | `"dance"` | `"jump_rope"` | `"pool_apnea"` | `"mobility"` | `"geocaching"` | `"canoeing"` ## Returns [`SportCategory`](../type-aliases/SportCategory.md) --- --- url: /docs/api/core/functions/toBinary.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / toBinary # Function: toBinary() > **toBinary**(`krd`, `writer`, `logger?`): `Promise`<`Uint8Array`<`ArrayBufferLike`>> Defined in: [packages/core/src/application/to-format.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/to-format.ts#L17) Converts KRD to binary format with validation. ## Parameters ### krd #### events? `object`\[] = `...` #### extensions? {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; } = `...` #### extensions.course? `unknown` = `...` #### extensions.course\_points? `unknown` = `...` #### extensions.fit? `unknown` = `...` #### extensions.health? {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; } = `...` #### extensions.health.bodyComposition? { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; } = `...` #### extensions.health.bodyComposition.basalMetabolicRateKcal? `number` = `...` #### extensions.health.bodyComposition.bmi? `number` = `...` #### extensions.health.bodyComposition.bodyFatPercent? `number` = `...` #### extensions.health.bodyComposition.bodyWaterPercent? `number` = `...` #### extensions.health.bodyComposition.boneMassKilograms? `number` = `...` #### extensions.health.bodyComposition.externalId? `string` = `...` #### extensions.health.bodyComposition.kaiordRecordId? `string` = `...` #### extensions.health.bodyComposition.kind `"bodyComposition"` = `...` #### extensions.health.bodyComposition.leanMassKilograms? `number` = `...` #### extensions.health.bodyComposition.measuredAt `string` = `...` #### extensions.health.bodyComposition.sourceBridgeId? `string` = `...` #### extensions.health.bodyComposition.version `string` = `healthVersionSchema` #### extensions.health.bodyComposition.visceralFatRating? `number` = `...` #### extensions.health.daily? { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; } = `...` #### extensions.health.daily.activeCalories `number` = `...` #### extensions.health.daily.date `string` = `...` #### extensions.health.daily.externalId? `string` = `...` #### extensions.health.daily.floorsClimbed? `number` = `...` #### extensions.health.daily.intensityMinutes { `moderate`: `number`; `vigorous`: `number`; } = `...` #### extensions.health.daily.intensityMinutes.moderate `number` = `...` #### extensions.health.daily.intensityMinutes.vigorous `number` = `...` #### extensions.health.daily.kaiordRecordId? `string` = `...` #### extensions.health.daily.kind `"daily"` = `...` #### extensions.health.daily.restingCalories `number` = `...` #### extensions.health.daily.sourceBridgeId? `string` = `...` #### extensions.health.daily.steps `number` = `...` #### extensions.health.daily.version `string` = `healthVersionSchema` #### extensions.health.hrv? { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; } = `...` #### extensions.health.hrv.externalId? `string` = `...` #### extensions.health.hrv.kaiordRecordId? `string` = `...` #### extensions.health.hrv.kind `"hrv"` = `...` #### extensions.health.hrv.measuredAt `string` = `...` #### extensions.health.hrv.measurementWindow `"overnight"` | `"spot"` = `...` #### extensions.health.hrv.rMSSD `number` = `...` #### extensions.health.hrv.score? `number` = `...` #### extensions.health.hrv.sourceBridgeId? `string` = `...` #### extensions.health.hrv.version `string` = `healthVersionSchema` #### extensions.health.sleep? { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; } = `...` #### extensions.health.sleep.endTime `string` = `...` #### extensions.health.sleep.externalId? `string` = `...` #### extensions.health.sleep.kaiordRecordId? `string` = `...` #### extensions.health.sleep.kind `"sleep"` = `...` #### extensions.health.sleep.restingHeartRate? `number` = `...` #### extensions.health.sleep.score? `number` = `...` #### extensions.health.sleep.sourceBridgeId? `string` = `...` #### extensions.health.sleep.stages `object`\[] = `...` #### extensions.health.sleep.startTime `string` = `...` #### extensions.health.sleep.totalDurationSeconds `number` = `...` #### extensions.health.sleep.version `string` = `healthVersionSchema` #### extensions.health.stress? { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; } = `...` #### extensions.health.stress.averageLevel `number` = `...` #### extensions.health.stress.endTime `string` = `...` #### extensions.health.stress.externalId? `string` = `...` #### extensions.health.stress.kaiordRecordId? `string` = `...` #### extensions.health.stress.kind `"stress"` = `...` #### extensions.health.stress.peakLevel `number` = `...` #### extensions.health.stress.sourceBridgeId? `string` = `...` #### extensions.health.stress.startTime `string` = `...` #### extensions.health.stress.version `string` = `healthVersionSchema` #### extensions.health.weight? { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; } = `...` #### extensions.health.weight.externalId? `string` = `...` #### extensions.health.weight.kaiordRecordId? `string` = `...` #### extensions.health.weight.kind `"weight"` = `...` #### extensions.health.weight.measuredAt `string` = `...` #### extensions.health.weight.sourceBridgeId? `string` = `...` #### extensions.health.weight.version `string` = `healthVersionSchema` #### extensions.health.weight.weightKilograms `number` = `...` #### extensions.structured\_workout? `unknown` = `...` #### laps? `object`\[] = `...` #### metadata { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; } = `krdMetadataSchema` #### metadata.created `string` = `...` #### metadata.manufacturer? `string` = `...` #### metadata.product? `string` = `...` #### metadata.serialNumber? `string` = `...` #### metadata.sport? `string` = `...` **See** sportSchema for known sport values. Accepts custom strings for forward compatibility. Optional at the metadata level because health-metric KRD types (sleep, weight, HRV, daily wellness, body composition, stress) have no associated sport. A conditional refinement on `krdSchema` still requires `sport` for the three legacy workout/activity/course types so v1.x consumers see no change for those. #### metadata.subSport? `string` = `...` #### records? `object`\[] = `...` #### sessions? `object`\[] = `...` #### type `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` = `fileTypeSchema` #### version `string` = `...` ### writer [`BinaryWriter`](../type-aliases/BinaryWriter.md) ### logger? [`Logger`](../type-aliases/Logger.md) ## Returns `Promise`<`Uint8Array`<`ArrayBufferLike`>> ## Example ```typescript import { toBinary } from '@kaiord/core'; import { fitWriter } from '@kaiord/fit'; const buffer = await toBinary(krd, fitWriter); ``` --- --- url: /docs/api/core/functions/toCanonicalValue.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / toCanonicalValue # Function: toCanonicalValue() > **toCanonicalValue**(`valueRaw`, `unit`): `number` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L9) valueCanonical = valueRaw × factor + offset (offset defaults to 0). ## Parameters ### valueRaw `number` ### unit [`AffineUnit`](../type-aliases/AffineUnit.md) ## Returns `number` --- --- url: /docs/api/core/functions/toText.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / toText # Function: toText() > **toText**(`krd`, `writer`, `logger?`): `Promise`<`string`> Defined in: [packages/core/src/application/to-format.ts:40](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/to-format.ts#L40) Converts KRD to text format with validation. ## Parameters ### krd #### events? `object`\[] = `...` #### extensions? {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; } = `...` #### extensions.course? `unknown` = `...` #### extensions.course\_points? `unknown` = `...` #### extensions.fit? `unknown` = `...` #### extensions.health? {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; }; } = `...` #### extensions.health.bodyComposition? { `basalMetabolicRateKcal?`: `number`; `bmi?`: `number`; `bodyFatPercent?`: `number`; `bodyWaterPercent?`: `number`; `boneMassKilograms?`: `number`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"bodyComposition"`; `leanMassKilograms?`: `number`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `visceralFatRating?`: `number`; } = `...` #### extensions.health.bodyComposition.basalMetabolicRateKcal? `number` = `...` #### extensions.health.bodyComposition.bmi? `number` = `...` #### extensions.health.bodyComposition.bodyFatPercent? `number` = `...` #### extensions.health.bodyComposition.bodyWaterPercent? `number` = `...` #### extensions.health.bodyComposition.boneMassKilograms? `number` = `...` #### extensions.health.bodyComposition.externalId? `string` = `...` #### extensions.health.bodyComposition.kaiordRecordId? `string` = `...` #### extensions.health.bodyComposition.kind `"bodyComposition"` = `...` #### extensions.health.bodyComposition.leanMassKilograms? `number` = `...` #### extensions.health.bodyComposition.measuredAt `string` = `...` #### extensions.health.bodyComposition.sourceBridgeId? `string` = `...` #### extensions.health.bodyComposition.version `string` = `healthVersionSchema` #### extensions.health.bodyComposition.visceralFatRating? `number` = `...` #### extensions.health.daily? { `activeCalories`: `number`; `date`: `string`; `externalId?`: `string`; `floorsClimbed?`: `number`; `intensityMinutes`: { `moderate`: `number`; `vigorous`: `number`; }; `kaiordRecordId?`: `string`; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: `string`; `steps`: `number`; `version`: `string`; } = `...` #### extensions.health.daily.activeCalories `number` = `...` #### extensions.health.daily.date `string` = `...` #### extensions.health.daily.externalId? `string` = `...` #### extensions.health.daily.floorsClimbed? `number` = `...` #### extensions.health.daily.intensityMinutes { `moderate`: `number`; `vigorous`: `number`; } = `...` #### extensions.health.daily.intensityMinutes.moderate `number` = `...` #### extensions.health.daily.intensityMinutes.vigorous `number` = `...` #### extensions.health.daily.kaiordRecordId? `string` = `...` #### extensions.health.daily.kind `"daily"` = `...` #### extensions.health.daily.restingCalories `number` = `...` #### extensions.health.daily.sourceBridgeId? `string` = `...` #### extensions.health.daily.steps `number` = `...` #### extensions.health.daily.version `string` = `healthVersionSchema` #### extensions.health.hrv? { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: `"overnight"` | `"spot"`; `rMSSD`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `version`: `string`; } = `...` #### extensions.health.hrv.externalId? `string` = `...` #### extensions.health.hrv.kaiordRecordId? `string` = `...` #### extensions.health.hrv.kind `"hrv"` = `...` #### extensions.health.hrv.measuredAt `string` = `...` #### extensions.health.hrv.measurementWindow `"overnight"` | `"spot"` = `...` #### extensions.health.hrv.rMSSD `number` = `...` #### extensions.health.hrv.score? `number` = `...` #### extensions.health.hrv.sourceBridgeId? `string` = `...` #### extensions.health.hrv.version `string` = `healthVersionSchema` #### extensions.health.sleep? { `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"sleep"`; `restingHeartRate?`: `number`; `score?`: `number`; `sourceBridgeId?`: `string`; `stages`: `object`\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; } = `...` #### extensions.health.sleep.endTime `string` = `...` #### extensions.health.sleep.externalId? `string` = `...` #### extensions.health.sleep.kaiordRecordId? `string` = `...` #### extensions.health.sleep.kind `"sleep"` = `...` #### extensions.health.sleep.restingHeartRate? `number` = `...` #### extensions.health.sleep.score? `number` = `...` #### extensions.health.sleep.sourceBridgeId? `string` = `...` #### extensions.health.sleep.stages `object`\[] = `...` #### extensions.health.sleep.startTime `string` = `...` #### extensions.health.sleep.totalDurationSeconds `number` = `...` #### extensions.health.sleep.version `string` = `healthVersionSchema` #### extensions.health.stress? { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: `string`; `startTime`: `string`; `version`: `string`; } = `...` #### extensions.health.stress.averageLevel `number` = `...` #### extensions.health.stress.endTime `string` = `...` #### extensions.health.stress.externalId? `string` = `...` #### extensions.health.stress.kaiordRecordId? `string` = `...` #### extensions.health.stress.kind `"stress"` = `...` #### extensions.health.stress.peakLevel `number` = `...` #### extensions.health.stress.sourceBridgeId? `string` = `...` #### extensions.health.stress.startTime `string` = `...` #### extensions.health.stress.version `string` = `healthVersionSchema` #### extensions.health.weight? { `externalId?`: `string`; `kaiordRecordId?`: `string`; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: `string`; `version`: `string`; `weightKilograms`: `number`; } = `...` #### extensions.health.weight.externalId? `string` = `...` #### extensions.health.weight.kaiordRecordId? `string` = `...` #### extensions.health.weight.kind `"weight"` = `...` #### extensions.health.weight.measuredAt `string` = `...` #### extensions.health.weight.sourceBridgeId? `string` = `...` #### extensions.health.weight.version `string` = `healthVersionSchema` #### extensions.health.weight.weightKilograms `number` = `...` #### extensions.structured\_workout? `unknown` = `...` #### laps? `object`\[] = `...` #### metadata { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; } = `krdMetadataSchema` #### metadata.created `string` = `...` #### metadata.manufacturer? `string` = `...` #### metadata.product? `string` = `...` #### metadata.serialNumber? `string` = `...` #### metadata.sport? `string` = `...` **See** sportSchema for known sport values. Accepts custom strings for forward compatibility. Optional at the metadata level because health-metric KRD types (sleep, weight, HRV, daily wellness, body composition, stress) have no associated sport. A conditional refinement on `krdSchema` still requires `sport` for the three legacy workout/activity/course types so v1.x consumers see no change for those. #### metadata.subSport? `string` = `...` #### records? `object`\[] = `...` #### sessions? `object`\[] = `...` #### type `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` = `fileTypeSchema` #### version `string` = `...` ### writer [`TextWriter`](../type-aliases/TextWriter.md) ### logger? [`Logger`](../type-aliases/Logger.md) ## Returns `Promise`<`string`> ## Example ```typescript import { toText } from '@kaiord/core'; import { tcxWriter } from '@kaiord/tcx'; const xml = await toText(krd, tcxWriter); ``` --- --- url: /docs/api/core/functions/validateKrd.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / validateKrd # Function: validateKrd() > **validateKrd**(`krd`): `object` Defined in: [packages/core/src/domain/validation/validate-krd.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/validate-krd.ts#L13) Validates unknown data against the KRD schema. ## Parameters ### krd `unknown` Data to validate ## Returns `object` Validated and parsed KRD object (via Zod's result.data) ### events? > `optional` **events?**: `object`\[] ### extensions? > `optional` **extensions?**: `object` #### Index Signature \[`key`: `string`]: `unknown` #### extensions.course? > `optional` **course?**: `unknown` #### extensions.course\_points? > `optional` **course\_points?**: `unknown` #### extensions.fit? > `optional` **fit?**: `unknown` #### extensions.health? > `optional` **health?**: `object` ##### Index Signature \[`key`: `string`]: `unknown` #### extensions.health.bodyComposition? > `optional` **bodyComposition?**: `object` #### extensions.health.bodyComposition.basalMetabolicRateKcal? > `optional` **basalMetabolicRateKcal?**: `number` #### extensions.health.bodyComposition.bmi? > `optional` **bmi?**: `number` #### extensions.health.bodyComposition.bodyFatPercent? > `optional` **bodyFatPercent?**: `number` #### extensions.health.bodyComposition.bodyWaterPercent? > `optional` **bodyWaterPercent?**: `number` #### extensions.health.bodyComposition.boneMassKilograms? > `optional` **boneMassKilograms?**: `number` #### extensions.health.bodyComposition.externalId? > `optional` **externalId?**: `string` #### extensions.health.bodyComposition.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.bodyComposition.kind > **kind**: `"bodyComposition"` #### extensions.health.bodyComposition.leanMassKilograms? > `optional` **leanMassKilograms?**: `number` #### extensions.health.bodyComposition.measuredAt > **measuredAt**: `string` #### extensions.health.bodyComposition.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.bodyComposition.version > **version**: `string` = `healthVersionSchema` #### extensions.health.bodyComposition.visceralFatRating? > `optional` **visceralFatRating?**: `number` #### extensions.health.daily? > `optional` **daily?**: `object` #### extensions.health.daily.activeCalories > **activeCalories**: `number` #### extensions.health.daily.date > **date**: `string` #### extensions.health.daily.externalId? > `optional` **externalId?**: `string` #### extensions.health.daily.floorsClimbed? > `optional` **floorsClimbed?**: `number` #### extensions.health.daily.intensityMinutes > **intensityMinutes**: `object` #### extensions.health.daily.intensityMinutes.moderate > **moderate**: `number` #### extensions.health.daily.intensityMinutes.vigorous > **vigorous**: `number` #### extensions.health.daily.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.daily.kind > **kind**: `"daily"` #### extensions.health.daily.restingCalories > **restingCalories**: `number` #### extensions.health.daily.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.daily.steps > **steps**: `number` #### extensions.health.daily.version > **version**: `string` = `healthVersionSchema` #### extensions.health.hrv? > `optional` **hrv?**: `object` #### extensions.health.hrv.externalId? > `optional` **externalId?**: `string` #### extensions.health.hrv.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.hrv.kind > **kind**: `"hrv"` #### extensions.health.hrv.measuredAt > **measuredAt**: `string` #### extensions.health.hrv.measurementWindow > **measurementWindow**: `"overnight"` | `"spot"` #### extensions.health.hrv.rMSSD > **rMSSD**: `number` #### extensions.health.hrv.score? > `optional` **score?**: `number` #### extensions.health.hrv.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.hrv.version > **version**: `string` = `healthVersionSchema` #### extensions.health.sleep? > `optional` **sleep?**: `object` #### extensions.health.sleep.endTime > **endTime**: `string` #### extensions.health.sleep.externalId? > `optional` **externalId?**: `string` #### extensions.health.sleep.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.sleep.kind > **kind**: `"sleep"` #### extensions.health.sleep.restingHeartRate? > `optional` **restingHeartRate?**: `number` #### extensions.health.sleep.score? > `optional` **score?**: `number` #### extensions.health.sleep.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.sleep.stages > **stages**: `object`\[] #### extensions.health.sleep.startTime > **startTime**: `string` #### extensions.health.sleep.totalDurationSeconds > **totalDurationSeconds**: `number` #### extensions.health.sleep.version > **version**: `string` = `healthVersionSchema` #### extensions.health.stress? > `optional` **stress?**: `object` #### extensions.health.stress.averageLevel > **averageLevel**: `number` #### extensions.health.stress.endTime > **endTime**: `string` #### extensions.health.stress.externalId? > `optional` **externalId?**: `string` #### extensions.health.stress.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.stress.kind > **kind**: `"stress"` #### extensions.health.stress.peakLevel > **peakLevel**: `number` #### extensions.health.stress.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.stress.startTime > **startTime**: `string` #### extensions.health.stress.version > **version**: `string` = `healthVersionSchema` #### extensions.health.weight? > `optional` **weight?**: `object` #### extensions.health.weight.externalId? > `optional` **externalId?**: `string` #### extensions.health.weight.kaiordRecordId? > `optional` **kaiordRecordId?**: `string` #### extensions.health.weight.kind > **kind**: `"weight"` #### extensions.health.weight.measuredAt > **measuredAt**: `string` #### extensions.health.weight.sourceBridgeId? > `optional` **sourceBridgeId?**: `string` #### extensions.health.weight.version > **version**: `string` = `healthVersionSchema` #### extensions.health.weight.weightKilograms > **weightKilograms**: `number` #### extensions.structured\_workout? > `optional` **structured\_workout?**: `unknown` ### laps? > `optional` **laps?**: `object`\[] ### metadata > **metadata**: `object` = `krdMetadataSchema` #### metadata.created > **created**: `string` #### metadata.manufacturer? > `optional` **manufacturer?**: `string` #### metadata.product? > `optional` **product?**: `string` #### metadata.serialNumber? > `optional` **serialNumber?**: `string` #### metadata.sport? > `optional` **sport?**: `string` ##### See sportSchema for known sport values. Accepts custom strings for forward compatibility. Optional at the metadata level because health-metric KRD types (sleep, weight, HRV, daily wellness, body composition, stress) have no associated sport. A conditional refinement on `krdSchema` still requires `sport` for the three legacy workout/activity/course types so v1.x consumers see no change for those. #### metadata.subSport? > `optional` **subSport?**: `string` ### records? > `optional` **records?**: `object`\[] ### sessions? > `optional` **sessions?**: `object`\[] ### type > **type**: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` = `fileTypeSchema` ### version > **version**: `string` ## Throws When validation fails --- --- url: /docs/api/core/functions/validateRoundTrip.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / validateRoundTrip # Function: validateRoundTrip() > **validateRoundTrip**(`binaryReader`, `binaryWriter`, `toleranceChecker`, `logger`): `object` Defined in: [packages/core/src/application/round-trip/validate-round-trip.ts:36](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/round-trip/validate-round-trip.ts#L36) Validates round-trip conversion between a binary format and KRD. Format-agnostic in mechanism: it depends only on the injected `BinaryReader`/`BinaryWriter` ports, so it validates any binary adapter (FIT today). It exposes `validateBinaryRoundTrip` (binary → KRD → binary) and `validateKrdRoundTrip` (KRD → binary → KRD), each returning the tolerance violations found. Default tolerances: time ±1 s, power ±1 W or ±1% FTP, heart rate ±1 bpm, cadence ±1 rpm. ## Parameters ### binaryReader [`BinaryReader`](../type-aliases/BinaryReader.md) binary-format reader implementation ### binaryWriter [`BinaryWriter`](../type-aliases/BinaryWriter.md) binary-format writer implementation ### toleranceChecker [`ToleranceChecker`](../type-aliases/ToleranceChecker.md) tolerance checker with configured thresholds ### logger [`Logger`](../type-aliases/Logger.md) logger for operation tracking ## Returns ### validateBinaryRoundTrip > **validateBinaryRoundTrip**: (`params`) => `Promise`<`object`\[]> #### Parameters ##### params ###### originalBinary `Uint8Array` #### Returns `Promise`<`object`\[]> ### ~~validateFitToKrdToFit~~ > **validateFitToKrdToFit**: (`params`) => `Promise`<`object`\[]> #### Parameters ##### params ###### originalFit `Uint8Array` #### Returns `Promise`<`object`\[]> #### Deprecated Use [validateBinaryRoundTrip](#validateroundtrip); the reader/writer are format-agnostic binary ports, not FIT-specific. ### validateKrdRoundTrip > **validateKrdRoundTrip**: (`params`) => `Promise`<`object`\[]> #### Parameters ##### params ###### originalKrd { `events?`: `object`\[]; `extensions?`: {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: ... | ...; `bmi?`: ... | ...; `bodyFatPercent?`: ... | ...; `bodyWaterPercent?`: ... | ...; `boneMassKilograms?`: ... | ...; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"bodyComposition"`; `leanMassKilograms?`: ... | ...; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `visceralFatRating?`: ... | ...; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: ... | ...; `floorsClimbed?`: ... | ...; `intensityMinutes`: { `moderate`: ...; `vigorous`: ...; }; `kaiordRecordId?`: ... | ...; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: ... | ...; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: ... | ...; `rMSSD`: `number`; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"sleep"`; `restingHeartRate?`: ... | ...; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `stages`: ...\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: ... | ...; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; }; `laps?`: `object`\[]; `metadata`: { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; }; `records?`: `object`\[]; `sessions?`: `object`\[]; `type`: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"`; `version`: `string`; } ###### originalKrd.events? `object`\[] = `...` ###### originalKrd.extensions? {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: ... | ...; `bmi?`: ... | ...; `bodyFatPercent?`: ... | ...; `bodyWaterPercent?`: ... | ...; `boneMassKilograms?`: ... | ...; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"bodyComposition"`; `leanMassKilograms?`: ... | ...; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `visceralFatRating?`: ... | ...; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: ... | ...; `floorsClimbed?`: ... | ...; `intensityMinutes`: { `moderate`: ...; `vigorous`: ...; }; `kaiordRecordId?`: ... | ...; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: ... | ...; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: ... | ...; `rMSSD`: `number`; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"sleep"`; `restingHeartRate?`: ... | ...; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `stages`: ...\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: ... | ...; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; } = `...` ###### originalKrd.extensions.course? `unknown` = `...` ###### originalKrd.extensions.course\_points? `unknown` = `...` ###### originalKrd.extensions.fit? `unknown` = `...` ###### originalKrd.extensions.health? {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: ... | ...; `bmi?`: ... | ...; `bodyFatPercent?`: ... | ...; `bodyWaterPercent?`: ... | ...; `boneMassKilograms?`: ... | ...; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"bodyComposition"`; `leanMassKilograms?`: ... | ...; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `visceralFatRating?`: ... | ...; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: ... | ...; `floorsClimbed?`: ... | ...; `intensityMinutes`: { `moderate`: ...; `vigorous`: ...; }; `kaiordRecordId?`: ... | ...; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: ... | ...; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: ... | ...; `rMSSD`: `number`; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"sleep"`; `restingHeartRate?`: ... | ...; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `stages`: ...\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: ... | ...; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `weightKilograms`: `number`; }; } = `...` ###### originalKrd.extensions.health.bodyComposition? { `basalMetabolicRateKcal?`: ... | ...; `bmi?`: ... | ...; `bodyFatPercent?`: ... | ...; `bodyWaterPercent?`: ... | ...; `boneMassKilograms?`: ... | ...; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"bodyComposition"`; `leanMassKilograms?`: ... | ...; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `visceralFatRating?`: ... | ...; } = `...` ###### originalKrd.extensions.health.bodyComposition.basalMetabolicRateKcal? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.bmi? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.bodyFatPercent? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.bodyWaterPercent? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.boneMassKilograms? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.externalId? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.kind `"bodyComposition"` = `...` ###### originalKrd.extensions.health.bodyComposition.leanMassKilograms? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.measuredAt `string` = `...` ###### originalKrd.extensions.health.bodyComposition.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.bodyComposition.visceralFatRating? ... | ... = `...` ###### originalKrd.extensions.health.daily? { `activeCalories`: `number`; `date`: `string`; `externalId?`: ... | ...; `floorsClimbed?`: ... | ...; `intensityMinutes`: { `moderate`: ...; `vigorous`: ...; }; `kaiordRecordId?`: ... | ...; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: ... | ...; `steps`: `number`; `version`: `string`; } = `...` ###### originalKrd.extensions.health.daily.activeCalories `number` = `...` ###### originalKrd.extensions.health.daily.date `string` = `...` ###### originalKrd.extensions.health.daily.externalId? ... | ... = `...` ###### originalKrd.extensions.health.daily.floorsClimbed? ... | ... = `...` ###### originalKrd.extensions.health.daily.intensityMinutes { `moderate`: ...; `vigorous`: ...; } = `...` ###### originalKrd.extensions.health.daily.intensityMinutes.moderate ... = `...` ###### originalKrd.extensions.health.daily.intensityMinutes.vigorous ... = `...` ###### originalKrd.extensions.health.daily.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.daily.kind `"daily"` = `...` ###### originalKrd.extensions.health.daily.restingCalories `number` = `...` ###### originalKrd.extensions.health.daily.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.daily.steps `number` = `...` ###### originalKrd.extensions.health.daily.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.hrv? { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: ... | ...; `rMSSD`: `number`; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `version`: `string`; } = `...` ###### originalKrd.extensions.health.hrv.externalId? ... | ... = `...` ###### originalKrd.extensions.health.hrv.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.hrv.kind `"hrv"` = `...` ###### originalKrd.extensions.health.hrv.measuredAt `string` = `...` ###### originalKrd.extensions.health.hrv.measurementWindow ... | ... = `...` ###### originalKrd.extensions.health.hrv.rMSSD `number` = `...` ###### originalKrd.extensions.health.hrv.score? ... | ... = `...` ###### originalKrd.extensions.health.hrv.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.hrv.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.sleep? { `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"sleep"`; `restingHeartRate?`: ... | ...; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `stages`: ...\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; } = `...` ###### originalKrd.extensions.health.sleep.endTime `string` = `...` ###### originalKrd.extensions.health.sleep.externalId? ... | ... = `...` ###### originalKrd.extensions.health.sleep.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.sleep.kind `"sleep"` = `...` ###### originalKrd.extensions.health.sleep.restingHeartRate? ... | ... = `...` ###### originalKrd.extensions.health.sleep.score? ... | ... = `...` ###### originalKrd.extensions.health.sleep.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.sleep.stages ...\[] = `...` ###### originalKrd.extensions.health.sleep.startTime `string` = `...` ###### originalKrd.extensions.health.sleep.totalDurationSeconds `number` = `...` ###### originalKrd.extensions.health.sleep.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.stress? { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: ... | ...; `startTime`: `string`; `version`: `string`; } = `...` ###### originalKrd.extensions.health.stress.averageLevel `number` = `...` ###### originalKrd.extensions.health.stress.endTime `string` = `...` ###### originalKrd.extensions.health.stress.externalId? ... | ... = `...` ###### originalKrd.extensions.health.stress.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.stress.kind `"stress"` = `...` ###### originalKrd.extensions.health.stress.peakLevel `number` = `...` ###### originalKrd.extensions.health.stress.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.stress.startTime `string` = `...` ###### originalKrd.extensions.health.stress.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.weight? { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `weightKilograms`: `number`; } = `...` ###### originalKrd.extensions.health.weight.externalId? ... | ... = `...` ###### originalKrd.extensions.health.weight.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.weight.kind `"weight"` = `...` ###### originalKrd.extensions.health.weight.measuredAt `string` = `...` ###### originalKrd.extensions.health.weight.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.weight.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.weight.weightKilograms `number` = `...` ###### originalKrd.extensions.structured\_workout? `unknown` = `...` ###### originalKrd.laps? `object`\[] = `...` ###### originalKrd.metadata { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; } = `krdMetadataSchema` ###### originalKrd.metadata.created `string` = `...` ###### originalKrd.metadata.manufacturer? `string` = `...` ###### originalKrd.metadata.product? `string` = `...` ###### originalKrd.metadata.serialNumber? `string` = `...` ###### originalKrd.metadata.sport? `string` = `...` **See** sportSchema for known sport values. Accepts custom strings for forward compatibility. Optional at the metadata level because health-metric KRD types (sleep, weight, HRV, daily wellness, body composition, stress) have no associated sport. A conditional refinement on `krdSchema` still requires `sport` for the three legacy workout/activity/course types so v1.x consumers see no change for those. ###### originalKrd.metadata.subSport? `string` = `...` ###### originalKrd.records? `object`\[] = `...` ###### originalKrd.sessions? `object`\[] = `...` ###### originalKrd.type `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` = `fileTypeSchema` ###### originalKrd.version `string` = `...` #### Returns `Promise`<`object`\[]> ### ~~validateKrdToFitToKrd~~ > **validateKrdToFitToKrd**: (`params`) => `Promise`<`object`\[]> #### Parameters ##### params ###### originalKrd { `events?`: `object`\[]; `extensions?`: {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: ... | ...; `bmi?`: ... | ...; `bodyFatPercent?`: ... | ...; `bodyWaterPercent?`: ... | ...; `boneMassKilograms?`: ... | ...; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"bodyComposition"`; `leanMassKilograms?`: ... | ...; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `visceralFatRating?`: ... | ...; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: ... | ...; `floorsClimbed?`: ... | ...; `intensityMinutes`: { `moderate`: ...; `vigorous`: ...; }; `kaiordRecordId?`: ... | ...; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: ... | ...; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: ... | ...; `rMSSD`: `number`; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"sleep"`; `restingHeartRate?`: ... | ...; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `stages`: ...\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: ... | ...; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; }; `laps?`: `object`\[]; `metadata`: { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; }; `records?`: `object`\[]; `sessions?`: `object`\[]; `type`: `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"`; `version`: `string`; } ###### originalKrd.events? `object`\[] = `...` ###### originalKrd.extensions? {\[`key`: `string`]: `unknown`; `course?`: `unknown`; `course_points?`: `unknown`; `fit?`: `unknown`; `health?`: {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: ... | ...; `bmi?`: ... | ...; `bodyFatPercent?`: ... | ...; `bodyWaterPercent?`: ... | ...; `boneMassKilograms?`: ... | ...; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"bodyComposition"`; `leanMassKilograms?`: ... | ...; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `visceralFatRating?`: ... | ...; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: ... | ...; `floorsClimbed?`: ... | ...; `intensityMinutes`: { `moderate`: ...; `vigorous`: ...; }; `kaiordRecordId?`: ... | ...; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: ... | ...; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: ... | ...; `rMSSD`: `number`; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"sleep"`; `restingHeartRate?`: ... | ...; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `stages`: ...\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: ... | ...; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `weightKilograms`: `number`; }; }; `structured_workout?`: `unknown`; } = `...` ###### originalKrd.extensions.course? `unknown` = `...` ###### originalKrd.extensions.course\_points? `unknown` = `...` ###### originalKrd.extensions.fit? `unknown` = `...` ###### originalKrd.extensions.health? {\[`key`: `string`]: `unknown`; `bodyComposition?`: { `basalMetabolicRateKcal?`: ... | ...; `bmi?`: ... | ...; `bodyFatPercent?`: ... | ...; `bodyWaterPercent?`: ... | ...; `boneMassKilograms?`: ... | ...; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"bodyComposition"`; `leanMassKilograms?`: ... | ...; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `visceralFatRating?`: ... | ...; }; `daily?`: { `activeCalories`: `number`; `date`: `string`; `externalId?`: ... | ...; `floorsClimbed?`: ... | ...; `intensityMinutes`: { `moderate`: ...; `vigorous`: ...; }; `kaiordRecordId?`: ... | ...; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: ... | ...; `steps`: `number`; `version`: `string`; }; `hrv?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: ... | ...; `rMSSD`: `number`; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `version`: `string`; }; `sleep?`: { `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"sleep"`; `restingHeartRate?`: ... | ...; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `stages`: ...\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; }; `stress?`: { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: ... | ...; `startTime`: `string`; `version`: `string`; }; `weight?`: { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `weightKilograms`: `number`; }; } = `...` ###### originalKrd.extensions.health.bodyComposition? { `basalMetabolicRateKcal?`: ... | ...; `bmi?`: ... | ...; `bodyFatPercent?`: ... | ...; `bodyWaterPercent?`: ... | ...; `boneMassKilograms?`: ... | ...; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"bodyComposition"`; `leanMassKilograms?`: ... | ...; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `visceralFatRating?`: ... | ...; } = `...` ###### originalKrd.extensions.health.bodyComposition.basalMetabolicRateKcal? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.bmi? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.bodyFatPercent? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.bodyWaterPercent? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.boneMassKilograms? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.externalId? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.kind `"bodyComposition"` = `...` ###### originalKrd.extensions.health.bodyComposition.leanMassKilograms? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.measuredAt `string` = `...` ###### originalKrd.extensions.health.bodyComposition.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.bodyComposition.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.bodyComposition.visceralFatRating? ... | ... = `...` ###### originalKrd.extensions.health.daily? { `activeCalories`: `number`; `date`: `string`; `externalId?`: ... | ...; `floorsClimbed?`: ... | ...; `intensityMinutes`: { `moderate`: ...; `vigorous`: ...; }; `kaiordRecordId?`: ... | ...; `kind`: `"daily"`; `restingCalories`: `number`; `sourceBridgeId?`: ... | ...; `steps`: `number`; `version`: `string`; } = `...` ###### originalKrd.extensions.health.daily.activeCalories `number` = `...` ###### originalKrd.extensions.health.daily.date `string` = `...` ###### originalKrd.extensions.health.daily.externalId? ... | ... = `...` ###### originalKrd.extensions.health.daily.floorsClimbed? ... | ... = `...` ###### originalKrd.extensions.health.daily.intensityMinutes { `moderate`: ...; `vigorous`: ...; } = `...` ###### originalKrd.extensions.health.daily.intensityMinutes.moderate ... = `...` ###### originalKrd.extensions.health.daily.intensityMinutes.vigorous ... = `...` ###### originalKrd.extensions.health.daily.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.daily.kind `"daily"` = `...` ###### originalKrd.extensions.health.daily.restingCalories `number` = `...` ###### originalKrd.extensions.health.daily.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.daily.steps `number` = `...` ###### originalKrd.extensions.health.daily.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.hrv? { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"hrv"`; `measuredAt`: `string`; `measurementWindow`: ... | ...; `rMSSD`: `number`; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `version`: `string`; } = `...` ###### originalKrd.extensions.health.hrv.externalId? ... | ... = `...` ###### originalKrd.extensions.health.hrv.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.hrv.kind `"hrv"` = `...` ###### originalKrd.extensions.health.hrv.measuredAt `string` = `...` ###### originalKrd.extensions.health.hrv.measurementWindow ... | ... = `...` ###### originalKrd.extensions.health.hrv.rMSSD `number` = `...` ###### originalKrd.extensions.health.hrv.score? ... | ... = `...` ###### originalKrd.extensions.health.hrv.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.hrv.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.sleep? { `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"sleep"`; `restingHeartRate?`: ... | ...; `score?`: ... | ...; `sourceBridgeId?`: ... | ...; `stages`: ...\[]; `startTime`: `string`; `totalDurationSeconds`: `number`; `version`: `string`; } = `...` ###### originalKrd.extensions.health.sleep.endTime `string` = `...` ###### originalKrd.extensions.health.sleep.externalId? ... | ... = `...` ###### originalKrd.extensions.health.sleep.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.sleep.kind `"sleep"` = `...` ###### originalKrd.extensions.health.sleep.restingHeartRate? ... | ... = `...` ###### originalKrd.extensions.health.sleep.score? ... | ... = `...` ###### originalKrd.extensions.health.sleep.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.sleep.stages ...\[] = `...` ###### originalKrd.extensions.health.sleep.startTime `string` = `...` ###### originalKrd.extensions.health.sleep.totalDurationSeconds `number` = `...` ###### originalKrd.extensions.health.sleep.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.stress? { `averageLevel`: `number`; `endTime`: `string`; `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"stress"`; `peakLevel`: `number`; `sourceBridgeId?`: ... | ...; `startTime`: `string`; `version`: `string`; } = `...` ###### originalKrd.extensions.health.stress.averageLevel `number` = `...` ###### originalKrd.extensions.health.stress.endTime `string` = `...` ###### originalKrd.extensions.health.stress.externalId? ... | ... = `...` ###### originalKrd.extensions.health.stress.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.stress.kind `"stress"` = `...` ###### originalKrd.extensions.health.stress.peakLevel `number` = `...` ###### originalKrd.extensions.health.stress.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.stress.startTime `string` = `...` ###### originalKrd.extensions.health.stress.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.weight? { `externalId?`: ... | ...; `kaiordRecordId?`: ... | ...; `kind`: `"weight"`; `measuredAt`: `string`; `sourceBridgeId?`: ... | ...; `version`: `string`; `weightKilograms`: `number`; } = `...` ###### originalKrd.extensions.health.weight.externalId? ... | ... = `...` ###### originalKrd.extensions.health.weight.kaiordRecordId? ... | ... = `...` ###### originalKrd.extensions.health.weight.kind `"weight"` = `...` ###### originalKrd.extensions.health.weight.measuredAt `string` = `...` ###### originalKrd.extensions.health.weight.sourceBridgeId? ... | ... = `...` ###### originalKrd.extensions.health.weight.version `string` = `healthVersionSchema` ###### originalKrd.extensions.health.weight.weightKilograms `number` = `...` ###### originalKrd.extensions.structured\_workout? `unknown` = `...` ###### originalKrd.laps? `object`\[] = `...` ###### originalKrd.metadata { `created`: `string`; `manufacturer?`: `string`; `product?`: `string`; `serialNumber?`: `string`; `sport?`: `string`; `subSport?`: `string`; } = `krdMetadataSchema` ###### originalKrd.metadata.created `string` = `...` ###### originalKrd.metadata.manufacturer? `string` = `...` ###### originalKrd.metadata.product? `string` = `...` ###### originalKrd.metadata.serialNumber? `string` = `...` ###### originalKrd.metadata.sport? `string` = `...` **See** sportSchema for known sport values. Accepts custom strings for forward compatibility. Optional at the metadata level because health-metric KRD types (sleep, weight, HRV, daily wellness, body composition, stress) have no associated sport. A conditional refinement on `krdSchema` still requires `sport` for the three legacy workout/activity/course types so v1.x consumers see no change for those. ###### originalKrd.metadata.subSport? `string` = `...` ###### originalKrd.records? `object`\[] = `...` ###### originalKrd.sessions? `object`\[] = `...` ###### originalKrd.type `"structured_workout"` | `"recorded_activity"` | `"course"` | `"sleep_record"` | `"weight_measurement"` | `"hrv_summary"` | `"daily_wellness"` | `"body_composition"` | `"stress_episode"` = `fileTypeSchema` ###### originalKrd.version `string` = `...` #### Returns `Promise`<`object`\[]> #### Deprecated Use [validateKrdRoundTrip](#validateroundtrip). --- --- url: /docs/api/core/functions/zoneToPercentFtp.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / zoneToPercentFtp # Function: zoneToPercentFtp() > **zoneToPercentFtp**(`zone`): `number` Defined in: [packages/core/src/domain/zones/power-zones.ts:51](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/zones/power-zones.ts#L51) Map a Coggan power zone (1..7) to its percent-FTP value. ## Parameters ### zone `number` ## Returns `number` ## Throws RangeError when `zone` is not an integer in the closed interval \[1, 7]. The contract is strict: `0`, `8`, `-1`, `NaN`, `Infinity`, and non-integers like `1.5` are all rejected. The helper MUST NOT return `undefined`, `null`, or a silently clamped value. --- --- url: /docs/api/core/type-aliases/Activity.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Activity # Type Alias: Activity > **Activity** = `z.infer`<*typeof* [`activitySchema`](../variables/activitySchema.md)> Defined in: [packages/core/src/domain/schemas/activity.ts:50](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/activity.ts#L50) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/ActivityLevel.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ActivityLevel # Type Alias: ActivityLevel > **ActivityLevel** = `"sedentary"` | `"light"` | `"moderate"` | `"active"` | `"very_active"` Defined in: [packages/core/src/application/energy/activity-factor.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/activity-factor.ts#L15) Activity-level NEAT factors applied to the predicted basal expenditure. These multipliers are deliberately LOWER than the classic TDEE activity multipliers (which run ~1.2–1.9). The predicted expenditure already adds scheduled-workout energy separately via `expectedActivityKcal`, so the factor here only covers Non-Exercise Activity Thermogenesis (NEAT) — daily movement, posture, fidgeting, occupational activity — NOT structured exercise. Using a full TDEE multiplier would double-count the workout kcal. The default (unset activity level) is `sedentary` (1.2), the most conservative assumption, so an incomplete profile never over-states maintenance. --- --- url: /docs/api/core/type-aliases/ActivitySummary.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ActivitySummary # Type Alias: ActivitySummary > **ActivitySummary** = `z.infer`<*typeof* [`activitySummarySchema`](../variables/activitySummarySchema.md)> Defined in: [packages/core/src/domain/schemas/activity.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/activity.ts#L34) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/AdaptiveTdeeResult.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / AdaptiveTdeeResult # Type Alias: AdaptiveTdeeResult > **AdaptiveTdeeResult** = `object` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:40](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L40) ## Properties ### isEstimate > **isEstimate**: `true` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:44](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L44) Always true: the value is inferred from observed history, not modeled. *** ### maintenanceKcal > **maintenanceKcal**: `number` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:42](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L42) Back-calculated maintenance energy (kcal/day). Always an estimate. *** ### sufficientData > **sufficientData**: `boolean` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:46](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L46) True once `daysWithData >= MIN_ADAPTIVE_DAYS` and the window is valid. --- --- url: /docs/api/core/type-aliases/AffineUnit.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / AffineUnit # Type Alias: AffineUnit > **AffineUnit** = `object` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L3) ## Properties ### factorToCanonical > **factorToCanonical**: `number` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:4](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L4) *** ### offsetToCanonical? > `optional` **offsetToCanonical?**: `number` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:5](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L5) --- --- url: /docs/api/core/type-aliases/Analytics.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Analytics # Type Alias: Analytics > **Analytics** = `object` Defined in: [packages/core/src/ports/analytics.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/analytics.ts#L3) ## Properties ### event > **event**: (`name`, `props?`) => `void` Defined in: [packages/core/src/ports/analytics.ts:5](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/analytics.ts#L5) #### Parameters ##### name `string` ##### props? [`AnalyticsEvent`](AnalyticsEvent.md) #### Returns `void` *** ### pageView > **pageView**: (`path`) => `void` Defined in: [packages/core/src/ports/analytics.ts:4](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/analytics.ts#L4) #### Parameters ##### path `string` #### Returns `void` --- --- url: /docs/api/core/type-aliases/AnalyticsEvent.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / AnalyticsEvent # Type Alias: AnalyticsEvent > **AnalyticsEvent** = `Record`<`string`, `string` | `number` | `boolean`> Defined in: [packages/core/src/ports/analytics.ts:1](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/analytics.ts#L1) --- --- url: /docs/api/core/type-aliases/AssembleDayEnergyBalanceInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / AssembleDayEnergyBalanceInput # Type Alias: AssembleDayEnergyBalanceInput > **AssembleDayEnergyBalanceInput** = `object` Defined in: [packages/core/src/application/energy/day-balance.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L29) ## Properties ### date > **date**: `string` Defined in: [packages/core/src/application/energy/day-balance.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L31) ISO date (YYYY-MM-DD) the balance covers. *** ### expenditure > **expenditure**: [`ResolvedExpenditure`](ResolvedExpenditure.md) Defined in: [packages/core/src/application/energy/day-balance.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L33) Resolved expenditure (`{ basalKcal, activityKcal, expenditureKcal, source }`). *** ### intakeKcal > **intakeKcal**: `number` | `null` Defined in: [packages/core/src/application/energy/day-balance.ts:35](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L35) Logged intake kcal; `null` means the day is untracked. *** ### macroActuals? > `optional` **macroActuals?**: [`MacroNutrients`](MacroNutrients.md) Defined in: [packages/core/src/application/energy/day-balance.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L41) Optional logged macro actuals (present once intake is tracked). *** ### macroTargets? > `optional` **macroTargets?**: [`MacroNutrients`](MacroNutrients.md) Defined in: [packages/core/src/application/energy/day-balance.ts:39](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L39) Optional derived macro targets (present once a goal is active). *** ### targetKcal > **targetKcal**: `number` | `null` Defined in: [packages/core/src/application/energy/day-balance.ts:37](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L37) Active goal target kcal; `null` when no goal is active. --- --- url: /docs/api/core/type-aliases/AuthProvider.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / AuthProvider # Type Alias: AuthProvider > **AuthProvider** = `object` Defined in: [packages/core/src/ports/auth-provider.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/auth-provider.ts#L9) Port for authentication against a remote service. ## Properties ### export\_tokens > **export\_tokens**: () => `Promise`<[`TokenData`](TokenData.md)> Defined in: [packages/core/src/ports/auth-provider.ts:12](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/auth-provider.ts#L12) #### Returns `Promise`<[`TokenData`](TokenData.md)> *** ### is\_authenticated > **is\_authenticated**: () => `boolean` Defined in: [packages/core/src/ports/auth-provider.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/auth-provider.ts#L11) #### Returns `boolean` *** ### login > **login**: (`username`, `password`) => `Promise`<`void`> Defined in: [packages/core/src/ports/auth-provider.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/auth-provider.ts#L10) #### Parameters ##### username `string` ##### password `string` #### Returns `Promise`<`void`> *** ### logout > **logout**: () => `Promise`<`void`> Defined in: [packages/core/src/ports/auth-provider.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/auth-provider.ts#L14) #### Returns `Promise`<`void`> *** ### restore\_tokens > **restore\_tokens**: (`tokens`) => `Promise`<`void`> Defined in: [packages/core/src/ports/auth-provider.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/auth-provider.ts#L13) #### Parameters ##### tokens [`TokenData`](TokenData.md) #### Returns `Promise`<`void`> --- --- url: /docs/api/core/type-aliases/BinaryReader.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BinaryReader # Type Alias: BinaryReader > **BinaryReader** = (`buffer`) => `Promise`<[`KRD`](KRD.md)> Defined in: [packages/core/src/ports/format-strategy.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/format-strategy.ts#L6) Reads binary data (e.g. FIT) and converts it to KRD. ## Parameters ### buffer `Uint8Array` ## Returns `Promise`<[`KRD`](KRD.md)> --- --- url: /docs/api/core/type-aliases/BinaryWriter.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BinaryWriter # Type Alias: BinaryWriter > **BinaryWriter** = (`krd`) => `Promise`<`Uint8Array`> Defined in: [packages/core/src/ports/format-strategy.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/format-strategy.ts#L16) Converts KRD to binary output (e.g. FIT). ## Parameters ### krd [`KRD`](KRD.md) ## Returns `Promise`<`Uint8Array`> --- --- url: /docs/api/core/type-aliases/BiologicalSex.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BiologicalSex # Type Alias: BiologicalSex > **BiologicalSex** = `"male"` | `"female"` Defined in: [packages/core/src/domain/lab/lab-flag.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L9) --- --- url: /docs/api/core/type-aliases/BmrFormula.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BmrFormula # Type Alias: BmrFormula > **BmrFormula** = `"mifflin-st-jeor"` | `"katch-mcardle"` Defined in: [packages/core/src/application/energy/bmr.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L9) Basal-metabolic-rate estimation. Pure functions, no adapter/external deps. Mifflin-St Jeor is the default; Katch-McArdle is used when a body-fat fraction is known, since lean-mass-based BMR is more accurate. The chosen formula is returned so callers (UI/chatbot) can explain the number. --- --- url: /docs/api/core/type-aliases/BmrInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BmrInput # Type Alias: BmrInput > **BmrInput** = `object` Defined in: [packages/core/src/application/energy/bmr.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L13) ## Properties ### age > **age**: `number` Defined in: [packages/core/src/application/energy/bmr.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L16) *** ### bodyFatFraction? > `optional` **bodyFatFraction?**: `number` Defined in: [packages/core/src/application/energy/bmr.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L19) Body-fat as a fraction in \[0, 1); enables Katch-McArdle. *** ### heightCm > **heightCm**: `number` Defined in: [packages/core/src/application/energy/bmr.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L15) *** ### sex > **sex**: [`Sex`](Sex.md) Defined in: [packages/core/src/application/energy/bmr.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L17) *** ### weightKg > **weightKg**: `number` Defined in: [packages/core/src/application/energy/bmr.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L14) --- --- url: /docs/api/core/type-aliases/BmrResult.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BmrResult # Type Alias: BmrResult > **BmrResult** = `object` Defined in: [packages/core/src/application/energy/bmr.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L22) ## Properties ### formula > **formula**: [`BmrFormula`](BmrFormula.md) Defined in: [packages/core/src/application/energy/bmr.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L24) *** ### kcal > **kcal**: `number` Defined in: [packages/core/src/application/energy/bmr.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L23) --- --- url: /docs/api/core/type-aliases/BodyComposition.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BodyComposition # Type Alias: BodyComposition > **BodyComposition** = `z.infer`<*typeof* [`bodyCompositionSchema`](../variables/bodyCompositionSchema.md)> Defined in: [packages/core/src/domain/schemas/health/body-composition.ts:48](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/body-composition.ts#L48) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/BridgeId.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BridgeId # Type Alias: BridgeId > **BridgeId** = `string` Defined in: [packages/core/src/domain/managed-data-type.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L28) Opaque bridge identifier — a stable string per bridge package (A-9). --- --- url: /docs/api/core/type-aliases/CadenceValue.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / CadenceValue # Type Alias: CadenceValue > **CadenceValue** = `z.infer`<*typeof* `cadenceValueSchema`> Defined in: [packages/core/src/domain/schemas/target-values/cadence.ts:51](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-values/cadence.ts#L51) TypeScript type for cadence target value, inferred from cadenceValueSchema. Discriminated union representing cadence targets in various units. --- --- url: /docs/api/core/type-aliases/CanonicalMeasurement.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / CanonicalMeasurement # Type Alias: CanonicalMeasurement > **CanonicalMeasurement** = `object` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:44](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L44) ## Properties ### unitCanonical > **unitCanonical**: `string` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:46](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L46) *** ### valueCanonical > **valueCanonical**: `number` Defined in: [packages/core/src/domain/lab/unit-conversion.ts:45](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/unit-conversion.ts#L45) --- --- url: /docs/api/core/type-aliases/CatalogFallback.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / CatalogFallback # Type Alias: CatalogFallback > **CatalogFallback** = `Bounds` & `object` Defined in: [packages/core/src/domain/lab/lab-flag.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L14) Canonical catalog fallback range for a parameter, optionally sex-aware. ## Type Declaration ### bySex? > `optional` **bySex?**: `object` #### bySex.female > **female**: `Bounds` #### bySex.male > **male**: `Bounds` --- --- url: /docs/api/core/type-aliases/ComputeAdaptiveTdeeInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ComputeAdaptiveTdeeInput # Type Alias: ComputeAdaptiveTdeeInput > **ComputeAdaptiveTdeeInput** = `object` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L29) ## Properties ### avgDailyIntakeKcal > **avgDailyIntakeKcal**: `number` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L31) Average logged daily intake (kcal) over the window. *** ### daysWithData > **daysWithData**: `number` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:37](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L37) Days with usable paired data; gates `sufficientData`. *** ### weightChangeKg > **weightChangeKg**: `number` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L33) Smoothed weight change over the window (kg; negative = loss). *** ### windowDays > **windowDays**: `number` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:35](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L35) Calendar span of the window (days); the rate denominator. --- --- url: /docs/api/core/type-aliases/ComputeDailyDeltaInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ComputeDailyDeltaInput # Type Alias: ComputeDailyDeltaInput > **ComputeDailyDeltaInput** = `object` Defined in: [packages/core/src/application/energy/goal-delta.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L33) ## Properties ### currentWeightKg > **currentWeightKg**: `number` Defined in: [packages/core/src/application/energy/goal-delta.ts:35](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L35) *** ### goalType > **goalType**: [`GoalType`](GoalType.md) Defined in: [packages/core/src/application/energy/goal-delta.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L34) *** ### maintenanceKcal > **maintenanceKcal**: `number` Defined in: [packages/core/src/application/energy/goal-delta.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L41) *** ### overrideCap? > `optional` **overrideCap?**: `boolean` Defined in: [packages/core/src/application/energy/goal-delta.ts:46](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L46) When true and a safety cap would bind, return the raw (unclamped) delta while still reporting `capped`/`capReason` so callers keep the warning. *** ### targetDate > **targetDate**: `string` Defined in: [packages/core/src/application/energy/goal-delta.ts:38](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L38) ISO date (YYYY-MM-DD) for the planned horizon. *** ### targetWeightKg > **targetWeightKg**: `number` Defined in: [packages/core/src/application/energy/goal-delta.ts:36](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L36) *** ### today > **today**: `string` Defined in: [packages/core/src/application/energy/goal-delta.ts:40](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L40) ISO date (YYYY-MM-DD) for "now". --- --- url: /docs/api/core/type-aliases/ComputeDailyDeltaResult.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ComputeDailyDeltaResult # Type Alias: ComputeDailyDeltaResult > **ComputeDailyDeltaResult** = `object` Defined in: [packages/core/src/application/energy/goal-cap.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-cap.ts#L9) Safety-cap resolution for the daily goal delta. Pure; no external deps. A cap either binds (clamp the delta to the safe value) or is overridden (the user accepted an unsafe pace, so the raw delta is used). In both bound cases `capped`/`capReason` stay set so the UI keeps its warning. ## Properties ### capped > **capped**: `boolean` Defined in: [packages/core/src/application/energy/goal-cap.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-cap.ts#L11) *** ### capReason > **capReason**: `string` | `null` Defined in: [packages/core/src/application/energy/goal-cap.ts:12](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-cap.ts#L12) *** ### dailyDeltaKcal > **dailyDeltaKcal**: `number` Defined in: [packages/core/src/application/energy/goal-cap.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-cap.ts#L10) *** ### overridden > **overridden**: `boolean` Defined in: [packages/core/src/application/energy/goal-cap.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-cap.ts#L14) True when a cap would have bound but the user overrode it. --- --- url: /docs/api/core/type-aliases/ComputeFlagInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ComputeFlagInput # Type Alias: ComputeFlagInput > **ComputeFlagInput** = `object` Defined in: [packages/core/src/domain/lab/lab-flag.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L18) ## Properties ### catalogFallback? > `optional` **catalogFallback?**: [`CatalogFallback`](CatalogFallback.md) Defined in: [packages/core/src/domain/lab/lab-flag.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L23) *** ### refHighCanonical? > `optional` **refHighCanonical?**: `number` Defined in: [packages/core/src/domain/lab/lab-flag.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L21) *** ### refLowCanonical? > `optional` **refLowCanonical?**: `number` Defined in: [packages/core/src/domain/lab/lab-flag.ts:20](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L20) *** ### refText? > `optional` **refText?**: `string` Defined in: [packages/core/src/domain/lab/lab-flag.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L22) *** ### sex? > `optional` **sex?**: [`BiologicalSex`](BiologicalSex.md) Defined in: [packages/core/src/domain/lab/lab-flag.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L24) *** ### valueCanonical > **valueCanonical**: `number` Defined in: [packages/core/src/domain/lab/lab-flag.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L19) --- --- url: /docs/api/core/type-aliases/ComputeMacroTargetsInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ComputeMacroTargetsInput # Type Alias: ComputeMacroTargetsInput > **ComputeMacroTargetsInput** = `object` Defined in: [packages/core/src/application/energy/macro-targets.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/macro-targets.ts#L31) ## Properties ### goalType > **goalType**: [`GoalType`](GoalType.md) Defined in: [packages/core/src/application/energy/macro-targets.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/macro-targets.ts#L34) *** ### targetKcal > **targetKcal**: `number` Defined in: [packages/core/src/application/energy/macro-targets.ts:32](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/macro-targets.ts#L32) *** ### weightKg > **weightKg**: `number` Defined in: [packages/core/src/application/energy/macro-targets.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/macro-targets.ts#L33) --- --- url: /docs/api/core/type-aliases/ComputePeriodizedTargetInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ComputePeriodizedTargetInput # Type Alias: ComputePeriodizedTargetInput > **ComputePeriodizedTargetInput** = `object` Defined in: [packages/core/src/application/energy/periodized-target.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/periodized-target.ts#L16) ## Properties ### bmrKcal > **bmrKcal**: `number` Defined in: [packages/core/src/application/energy/periodized-target.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/periodized-target.ts#L17) *** ### dailyDeltaKcal > **dailyDeltaKcal**: `number` Defined in: [packages/core/src/application/energy/periodized-target.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/periodized-target.ts#L21) Signed daily delta from `computeDailyDelta` (negative = deficit). *** ### expectedActivityKcal > **expectedActivityKcal**: `number` Defined in: [packages/core/src/application/energy/periodized-target.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/periodized-target.ts#L19) Per-day expected activity kcal; 0 until Phase 4 wires per-day estimates. *** ### floorKcal? > `optional` **floorKcal?**: `number` Defined in: [packages/core/src/application/energy/periodized-target.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/periodized-target.ts#L23) Lower bound on the target; defaults to FLOOR\_KCAL. --- --- url: /docs/api/core/type-aliases/DailyWellness.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DailyWellness # Type Alias: DailyWellness > **DailyWellness** = `z.infer`<*typeof* [`dailyWellnessSchema`](../variables/dailyWellnessSchema.md)> Defined in: [packages/core/src/domain/schemas/health/daily.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/daily.ts#L31) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/DayEnergyBalance.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DayEnergyBalance # Type Alias: DayEnergyBalance > **DayEnergyBalance** = `z.infer`<*typeof* [`dayEnergyBalanceSchema`](../variables/dayEnergyBalanceSchema.md)> Defined in: [packages/core/src/domain/schemas/health/energy-balance.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/energy-balance.ts#L41) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/DayExpenditureInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DayExpenditureInput # Type Alias: DayExpenditureInput > **DayExpenditureInput** = `object` Defined in: [packages/core/src/application/energy/expenditure.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L19) ## Properties ### basalActivityFactor? > `optional` **basalActivityFactor?**: `number` Defined in: [packages/core/src/application/energy/expenditure.ts:30](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L30) NEAT multiplier applied to BMR for the predicted basal; defaults to 1. The measured path ignores it. *** ### bmrKcal > **bmrKcal**: `number` Defined in: [packages/core/src/application/energy/expenditure.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L23) Basal metabolic rate (kcal/day) for the predicted fallback. *** ### expectedActivityKcal > **expectedActivityKcal**: `number` Defined in: [packages/core/src/application/energy/expenditure.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L25) Estimated activity kcal for the predicted fallback (Phase 4 input). *** ### measured? > `optional` **measured?**: [`MeasuredWellness`](MeasuredWellness.md) Defined in: [packages/core/src/application/energy/expenditure.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L21) Present only when device wellness covers the day. --- --- url: /docs/api/core/type-aliases/DayExpenditureResult.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DayExpenditureResult # Type Alias: DayExpenditureResult > **DayExpenditureResult** = `object` Defined in: [packages/core/src/application/energy/expenditure.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L33) ## Properties ### activityKcal > **activityKcal**: `number` Defined in: [packages/core/src/application/energy/expenditure.ts:35](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L35) *** ### basalKcal > **basalKcal**: `number` Defined in: [packages/core/src/application/energy/expenditure.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L34) *** ### expenditureKcal > **expenditureKcal**: `number` Defined in: [packages/core/src/application/energy/expenditure.ts:36](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L36) *** ### source > **source**: [`ExpenditureSource`](ExpenditureSource.md) Defined in: [packages/core/src/application/energy/expenditure.ts:37](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L37) --- --- url: /docs/api/core/type-aliases/Duration.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Duration # Type Alias: Duration > **Duration** = `z.infer`<*typeof* [`durationSchema`](../variables/durationSchema.md)> Defined in: [packages/core/src/domain/schemas/duration.ts:93](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/duration.ts#L93) TypeScript type for workout step duration, inferred from [durationSchema](../variables/durationSchema.md). Discriminated union type representing all possible duration specifications. --- --- url: /docs/api/core/type-aliases/DurationType.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DurationType # Type Alias: DurationType > **DurationType** = `z.infer`<*typeof* [`durationTypeSchema`](../variables/durationTypeSchema.md)> Defined in: [packages/core/src/domain/schemas/duration-type.ts:40](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/duration-type.ts#L40) TypeScript type for duration type, inferred from [durationTypeSchema](../variables/durationTypeSchema.md). String literal union of all possible duration types. --- --- url: /docs/api/core/type-aliases/EmaOptions.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / EmaOptions # Type Alias: EmaOptions > **EmaOptions** = `object` Defined in: [packages/core/src/application/energy/ema.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L27) ## Properties ### windowDays > **windowDays**: `number` Defined in: [packages/core/src/application/energy/ema.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L29) Smoothing window in days; alpha = 2 / (windowDays + 1). Must be > 0. --- --- url: /docs/api/core/type-aliases/EmaPoint.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / EmaPoint # Type Alias: EmaPoint > **EmaPoint** = `object` Defined in: [packages/core/src/application/energy/ema.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L21) Exponential moving average (EMA) over a dated numeric series. Pure; no adapter/external deps. Used to smooth noisy daily weigh-ins into a trend line (and reusable for any other dated signal). Points MUST be ascending by date; the returned series mirrors the input one-to-one, each entry carrying the running EMA up to and including that point. Alpha derivation: a `windowDays` span maps to the standard smoothing factor alpha = 2 / (windowDays + 1) the same relation used for an N-period EMA. A larger window yields a smaller alpha and therefore a heavier, slower-moving trend. The first point seeds the EMA with its own value (ema\[0] = value\[0]); each subsequent point updates it as `ema = alpha * value + (1 - alpha) * prevEma`. Guards: empty input returns `[]`; a non-finite `windowDays` (≤ 0) or any non-finite point value throws a RangeError rather than propagating NaN. ## Properties ### date > **date**: `string` Defined in: [packages/core/src/application/energy/ema.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L23) ISO date (YYYY-MM-DD); the series MUST be ascending by date. *** ### value > **value**: `number` Defined in: [packages/core/src/application/energy/ema.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L24) --- --- url: /docs/api/core/type-aliases/EmaResult.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / EmaResult # Type Alias: EmaResult > **EmaResult** = `object` Defined in: [packages/core/src/application/energy/ema.ts:32](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L32) ## Properties ### date > **date**: `string` Defined in: [packages/core/src/application/energy/ema.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L33) *** ### ema > **ema**: `number` Defined in: [packages/core/src/application/energy/ema.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/ema.ts#L34) --- --- url: /docs/api/core/type-aliases/EnergyBalanceRollup.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / EnergyBalanceRollup # Type Alias: EnergyBalanceRollup > **EnergyBalanceRollup** = `object` Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L22) ## Properties ### avgExpenditureKcal > **avgExpenditureKcal**: `number` Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L26) *** ### avgIntakeKcal > **avgIntakeKcal**: `number` | `null` Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L27) *** ### dayCount > **dayCount**: `number` Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L29) *** ### daysTracked > **daysTracked**: `number` Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L28) *** ### totalExpenditureKcal > **totalExpenditureKcal**: `number` Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L23) *** ### totalIntakeKcal > **totalIntakeKcal**: `number` Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L24) *** ### totalNetKcal > **totalNetKcal**: `number` Defined in: [packages/core/src/application/energy/aggregate-energy-balance.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/aggregate-energy-balance.ts#L25) --- --- url: /docs/api/core/type-aliases/EnergyGoal.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / EnergyGoal # Type Alias: EnergyGoal > **EnergyGoal** = `z.infer`<*typeof* [`energyGoalSchema`](../variables/energyGoalSchema.md)> Defined in: [packages/core/src/domain/schemas/health/energy-goal.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/energy-goal.ts#L21) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/Equipment.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Equipment # Type Alias: Equipment > **Equipment** = `z.infer`<*typeof* [`equipmentSchema`](../variables/equipmentSchema.md)> Defined in: [packages/core/src/domain/schemas/equipment.ts:37](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/equipment.ts#L37) TypeScript type for equipment, inferred from [equipmentSchema](../variables/equipmentSchema.md). String literal union of supported equipment types. --- --- url: /docs/api/core/type-aliases/ExpectedActivityKcalInput.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ExpectedActivityKcalInput # Type Alias: ExpectedActivityKcalInput > **ExpectedActivityKcalInput** = `object` Defined in: [packages/core/src/application/energy/expected-activity-kcal.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expected-activity-kcal.ts#L25) ## Properties ### avgPowerWatts? > `optional` **avgPowerWatts?**: `number` Defined in: [packages/core/src/application/energy/expected-activity-kcal.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expected-activity-kcal.ts#L29) *** ### distanceKm? > `optional` **distanceKm?**: `number` Defined in: [packages/core/src/application/energy/expected-activity-kcal.ts:30](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expected-activity-kcal.ts#L30) *** ### durationSec > **durationSec**: `number` Defined in: [packages/core/src/application/energy/expected-activity-kcal.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expected-activity-kcal.ts#L27) *** ### sport > **sport**: [`Sport`](Sport.md) Defined in: [packages/core/src/application/energy/expected-activity-kcal.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expected-activity-kcal.ts#L26) *** ### weightKg > **weightKg**: `number` Defined in: [packages/core/src/application/energy/expected-activity-kcal.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expected-activity-kcal.ts#L28) --- --- url: /docs/api/core/type-aliases/ExpenditureSource.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ExpenditureSource # Type Alias: ExpenditureSource > **ExpenditureSource** = `z.infer`<*typeof* [`expenditureSourceSchema`](../variables/expenditureSourceSchema.md)> Defined in: [packages/core/src/domain/schemas/health/energy-balance.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/energy-balance.ts#L16) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/mcp/type-aliases/FileFormat.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / FileFormat # Type Alias: FileFormat > **FileFormat** = `z.infer`<*typeof* [`formatSchema`](../variables/formatSchema.md)> Defined in: [types/tool-schemas.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/types/tool-schemas.ts#L7) --- --- url: /docs/api/core/type-aliases/FileType.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / FileType # Type Alias: FileType > **FileType** = `z.infer`<*typeof* [`fileTypeSchema`](../variables/fileTypeSchema.md)> Defined in: [packages/core/src/domain/schemas/file-type.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/file-type.ts#L25) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/garmin-connect/type-aliases/GarminConnectClient.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / GarminConnectClient # Type Alias: GarminConnectClient > **GarminConnectClient** = `object` Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L9) @kaiord/garmin-connect - Garmin Connect API client for Kaiord ## Properties ### auth > **auth**: `AuthProvider` Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L10) *** ### init > **init**: () => `Promise`<[`InitResult`](InitResult.md)> Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:12](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L12) #### Returns `Promise`<[`InitResult`](InitResult.md)> *** ### service > **service**: [`GarminWorkoutClient`](GarminWorkoutClient.md) Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L11) --- --- url: /docs/api/garmin-connect/type-aliases/GarminConnectClientOptions.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / GarminConnectClientOptions # Type Alias: GarminConnectClientOptions > **GarminConnectClientOptions** = `object` Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L15) @kaiord/garmin-connect - Garmin Connect API client for Kaiord ## Properties ### fetchFn? > `optional` **fetchFn?**: `FetchFn` Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L18) *** ### logger? > `optional` **logger?**: `Logger` Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L16) *** ### retry? > `optional` **retry?**: [`RetryOptions`](RetryOptions.md) Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L19) *** ### tokenStore? > `optional` **tokenStore?**: [`TokenStore`](TokenStore.md) Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L17) --- --- url: /docs/api/garmin-connect/type-aliases/GarminWorkoutClient.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / GarminWorkoutClient # Type Alias: GarminWorkoutClient > **GarminWorkoutClient** = `WorkoutService` Defined in: [garmin-connect/src/adapters/client/garmin-workout-service.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-workout-service.ts#L26) --- --- url: /docs/api/garmin/type-aliases/GarminWriterOptions.md --- [**@kaiord/garmin**](../README.md) *** [@kaiord/garmin](../README.md) / GarminWriterOptions # Type Alias: GarminWriterOptions > **GarminWriterOptions** = `object` Defined in: [index.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/index.ts#L19) ## Properties ### logger? > `optional` **logger?**: `Logger` Defined in: [index.ts:20](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/index.ts#L20) *** ### paceZones? > `optional` **paceZones?**: [`PaceZoneTable`](PaceZoneTable.md) Defined in: [index.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/index.ts#L21) --- --- url: /docs/api/core/type-aliases/GoalType.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / GoalType # Type Alias: GoalType > **GoalType** = `z.infer`<*typeof* [`goalTypeSchema`](../variables/goalTypeSchema.md)> Defined in: [packages/core/src/domain/schemas/health/energy-goal.ts:12](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/energy-goal.ts#L12) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/HashProjection.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / HashProjection # Type Alias: HashProjection\

> **HashProjection**<`P`> = (`payload`) => `Record`<`string`, `unknown`> Defined in: [packages/core/src/domain/managed-data-type.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L31) Projects a payload to the canonical fields that determine identity. ## Type Parameters ### P `P` ## Parameters ### payload `P` ## Returns `Record`<`string`, `unknown`> --- --- url: /docs/api/core/type-aliases/HealthExtensionPayload.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / HealthExtensionPayload # Type Alias: HealthExtensionPayload > **HealthExtensionPayload** = `z.infer`<*typeof* [`healthExtensionPayloadSchema`](../variables/healthExtensionPayloadSchema.md)> Defined in: [packages/core/src/domain/schemas/health/index.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/index.ts#L34) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/HealthFileType.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / HealthFileType # Type Alias: HealthFileType > **HealthFileType** = *typeof* [`healthFileTypes`](../variables/healthFileTypes.md)\[`number`] Defined in: [packages/core/src/domain/schemas/file-type.ts:49](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/file-type.ts#L49) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/HeartRateSeries.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / HeartRateSeries # Type Alias: HeartRateSeries > **HeartRateSeries** = `z.infer`<*typeof* [`heartRateSeriesSchema`](../variables/heartRateSeriesSchema.md)> Defined in: [packages/core/src/domain/schemas/health/heart-rate-series.ts:39](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/heart-rate-series.ts#L39) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/HeartRateValue.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / HeartRateValue # Type Alias: HeartRateValue > **HeartRateValue** = `z.infer`<*typeof* `heartRateValueSchema`> Defined in: [packages/core/src/domain/schemas/target-values/heart-rate.ts:59](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-values/heart-rate.ts#L59) TypeScript type for heart rate target value, inferred from heartRateValueSchema. Discriminated union representing heart rate targets in various units. --- --- url: /docs/api/core/type-aliases/HrvSummary.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / HrvSummary # Type Alias: HrvSummary > **HrvSummary** = `z.infer`<*typeof* [`hrvSummarySchema`](../variables/hrvSummarySchema.md)> Defined in: [packages/core/src/domain/schemas/health/hrv.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/hrv.ts#L22) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/garmin-connect/type-aliases/InitResult.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / InitResult # Type Alias: InitResult > **InitResult** = `object` Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L7) @kaiord/garmin-connect - Garmin Connect API client for Kaiord ## Properties ### restored > **restored**: `boolean` Defined in: [garmin-connect/src/adapters/client/garmin-connect-client.types.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/client/garmin-connect-client.types.ts#L7) --- --- url: /docs/api/core/type-aliases/Intensity.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Intensity # Type Alias: Intensity > **Intensity** = `z.infer`<*typeof* [`intensitySchema`](../variables/intensitySchema.md)> Defined in: [packages/core/src/domain/schemas/intensity.ts:38](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/intensity.ts#L38) TypeScript type for intensity level, inferred from [intensitySchema](../variables/intensitySchema.md). String literal union of supported intensity levels. --- --- url: /docs/api/core/type-aliases/KnownUnit.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KnownUnit # Type Alias: KnownUnit > **KnownUnit** = `z.infer`<*typeof* [`knownUnitSchema`](../variables/knownUnitSchema.md)> Defined in: [packages/core/src/domain/lab/lab-parameter.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter.ts#L16) --- --- url: /docs/api/core/type-aliases/KRD.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KRD # Type Alias: KRD > **KRD** = `z.infer`<*typeof* [`krdSchema`](../variables/krdSchema.md)> Defined in: [packages/core/src/domain/schemas/krd/index.ts:128](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/index.ts#L128) TypeScript type for the complete KRD format, inferred from [krdSchema](../variables/krdSchema.md). KRD (Kaiord Representation Definition) is the canonical JSON format for workout, activity, course, and health data. --- --- url: /docs/api/core/type-aliases/KRDEvent.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KRDEvent # Type Alias: KRDEvent > **KRDEvent** = `z.infer`<*typeof* [`krdEventSchema`](../variables/krdEventSchema.md)> Defined in: [packages/core/src/domain/schemas/krd/event.ts:43](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/event.ts#L43) TypeScript type for KRD event, inferred from [krdEventSchema](../variables/krdEventSchema.md). Represents a workout event (start, stop, pause, lap, etc.). --- --- url: /docs/api/core/type-aliases/KRDExtensions.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KRDExtensions # Type Alias: KRDExtensions > **KRDExtensions** = `z.infer`<*typeof* [`krdExtensionsSchema`](../variables/krdExtensionsSchema.md)> Defined in: [packages/core/src/domain/schemas/krd/index.ts:59](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/index.ts#L59) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/KRDLap.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KRDLap # Type Alias: KRDLap > **KRDLap** = `z.infer`<*typeof* [`krdLapSchema`](../variables/krdLapSchema.md)> Defined in: [packages/core/src/domain/schemas/krd/lap.ts:75](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/lap.ts#L75) TypeScript type for KRD lap, inferred from [krdLapSchema](../variables/krdLapSchema.md). --- --- url: /docs/api/core/type-aliases/KRDLapTrigger.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KRDLapTrigger # Type Alias: KRDLapTrigger > **KRDLapTrigger** = `z.infer`<*typeof* [`krdLapTriggerSchema`](../variables/krdLapTriggerSchema.md)> Defined in: [packages/core/src/domain/schemas/krd/lap.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/lap.ts#L19) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/KRDMetadata.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KRDMetadata # Type Alias: KRDMetadata > **KRDMetadata** = `z.infer`<*typeof* [`krdMetadataSchema`](../variables/krdMetadataSchema.md)> Defined in: [packages/core/src/domain/schemas/krd/metadata.ts:49](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/metadata.ts#L49) TypeScript type for KRD metadata, inferred from [krdMetadataSchema](../variables/krdMetadataSchema.md). Contains file-level metadata including creation timestamp, device information, and sport type. --- --- url: /docs/api/core/type-aliases/KRDRecord.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KRDRecord # Type Alias: KRDRecord > **KRDRecord** = `z.infer`<*typeof* [`krdRecordSchema`](../variables/krdRecordSchema.md)> Defined in: [packages/core/src/domain/schemas/krd/record.ts:56](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/record.ts#L56) TypeScript type for KRD record, inferred from [krdRecordSchema](../variables/krdRecordSchema.md). Represents a time-series data point with GPS, heart rate, power, and other metrics. --- --- url: /docs/api/core/type-aliases/KRDSession.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KRDSession # Type Alias: KRDSession > **KRDSession** = `z.infer`<*typeof* [`krdSessionSchema`](../variables/krdSessionSchema.md)> Defined in: [packages/core/src/domain/schemas/krd/session.ts:68](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/session.ts#L68) TypeScript type for KRD session, inferred from [krdSessionSchema](../variables/krdSessionSchema.md). Represents a complete training session with timing, distance, and performance metrics. --- --- url: /docs/api/core/type-aliases/LabFlag.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LabFlag # Type Alias: LabFlag > **LabFlag** = `z.infer`<*typeof* [`labFlagSchema`](../variables/labFlagSchema.md)> Defined in: [packages/core/src/domain/lab/lab-flag.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L7) --- --- url: /docs/api/core/type-aliases/LabPanel.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LabPanel # Type Alias: LabPanel > **LabPanel** = `z.infer`<*typeof* [`labPanelSchema`](../variables/labPanelSchema.md)> Defined in: [packages/core/src/domain/lab/lab-parameter.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter.ts#L31) --- --- url: /docs/api/core/type-aliases/LabParameter.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LabParameter # Type Alias: LabParameter > **LabParameter** = `z.infer`<*typeof* [`labParameterSchema`](../variables/labParameterSchema.md)> Defined in: [packages/core/src/domain/lab/lab-parameter.ts:46](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter.ts#L46) --- --- url: /docs/api/core/type-aliases/LabProvenance.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LabProvenance # Type Alias: LabProvenance > **LabProvenance** = `z.infer`<*typeof* [`labProvenanceSchema`](../variables/labProvenanceSchema.md)> Defined in: [packages/core/src/domain/lab/lab-provenance.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-provenance.ts#L15) --- --- url: /docs/api/core/type-aliases/LabRefRange.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LabRefRange # Type Alias: LabRefRange > **LabRefRange** = `z.infer`<*typeof* [`labRefRangeSchema`](../variables/labRefRangeSchema.md)> Defined in: [packages/core/src/domain/lab/lab-parameter.ts:8](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter.ts#L8) --- --- url: /docs/api/core/type-aliases/LabRefSource.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LabRefSource # Type Alias: LabRefSource > **LabRefSource** = `z.infer`<*typeof* [`labRefSourceSchema`](../variables/labRefSourceSchema.md)> Defined in: [packages/core/src/domain/lab/lab-value.ts:8](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-value.ts#L8) --- --- url: /docs/api/core/type-aliases/LabReport.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LabReport # Type Alias: LabReport > **LabReport** = `z.infer`<*typeof* [`labReportSchema`](../variables/labReportSchema.md)> Defined in: [packages/core/src/domain/lab/lab-report.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-report.ts#L23) --- --- url: /docs/api/core/type-aliases/LabValue.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LabValue # Type Alias: LabValue > **LabValue** = `z.infer`<*typeof* [`labValueSchema`](../variables/labValueSchema.md)> Defined in: [packages/core/src/domain/lab/lab-value.ts:37](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-value.ts#L37) --- --- url: /docs/api/core/type-aliases/LengthUnit.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LengthUnit # Type Alias: LengthUnit > **LengthUnit** = `z.infer`<*typeof* [`lengthUnitSchema`](../variables/lengthUnitSchema.md)> Defined in: [packages/core/src/domain/schemas/length-unit.ts:5](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/length-unit.ts#L5) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/ListOptions.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ListOptions # Type Alias: ListOptions > **ListOptions** = `object` Defined in: [packages/core/src/ports/workout-service.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L22) Options for listing workouts. ## Properties ### limit? > `optional` **limit?**: `number` Defined in: [packages/core/src/ports/workout-service.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L22) *** ### offset? > `optional` **offset?**: `number` Defined in: [packages/core/src/ports/workout-service.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L22) --- --- url: /docs/api/garmin-connect/type-aliases/ListOptions.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / ListOptions # Type Alias: ListOptions > **ListOptions** = `object` Defined in: core/dist/index.d.ts:4142 Options for listing workouts. ## Properties ### limit? > `optional` **limit?**: `number` Defined in: core/dist/index.d.ts:4144 *** ### offset? > `optional` **offset?**: `number` Defined in: core/dist/index.d.ts:4143 --- --- url: /docs/api/core/type-aliases/Logger.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Logger # Type Alias: Logger > **Logger** = `object` Defined in: [packages/core/src/ports/logger.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/logger.ts#L3) ## Properties ### debug > **debug**: (`message`, `context?`) => `void` Defined in: [packages/core/src/ports/logger.ts:4](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/logger.ts#L4) #### Parameters ##### message `string` ##### context? `Record`<`string`, `unknown`> #### Returns `void` *** ### error > **error**: (`message`, `context?`) => `void` Defined in: [packages/core/src/ports/logger.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/logger.ts#L7) #### Parameters ##### message `string` ##### context? `Record`<`string`, `unknown`> #### Returns `void` *** ### info > **info**: (`message`, `context?`) => `void` Defined in: [packages/core/src/ports/logger.ts:5](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/logger.ts#L5) #### Parameters ##### message `string` ##### context? `Record`<`string`, `unknown`> #### Returns `void` *** ### warn > **warn**: (`message`, `context?`) => `void` Defined in: [packages/core/src/ports/logger.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/logger.ts#L6) #### Parameters ##### message `string` ##### context? `Record`<`string`, `unknown`> #### Returns `void` --- --- url: /docs/api/core/type-aliases/LogLevel.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LogLevel # Type Alias: LogLevel > **LogLevel** = `"debug"` | `"info"` | `"warn"` | `"error"` Defined in: [packages/core/src/ports/logger.ts:1](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/logger.ts#L1) --- --- url: /docs/api/core/type-aliases/MacroNutrients.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / MacroNutrients # Type Alias: MacroNutrients > **MacroNutrients** = `z.infer`<*typeof* [`macroNutrientsSchema`](../variables/macroNutrientsSchema.md)> Defined in: [packages/core/src/domain/schemas/health/nutrition.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/nutrition.ts#L18) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/ManagedDataRegistryEntry.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ManagedDataRegistryEntry # Type Alias: ManagedDataRegistryEntry > **ManagedDataRegistryEntry** = `object` Defined in: [packages/core/src/domain/managed-data-type.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L33) ## Properties ### capabilities > **capabilities**: `object` Defined in: [packages/core/src/domain/managed-data-type.ts:36](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L36) #### export? > `optional` **export?**: `string` #### import? > `optional` **import?**: `string` *** ### hashProjection? > `optional` **hashProjection?**: [`HashProjection`](HashProjection.md)<`unknown`> Defined in: [packages/core/src/domain/managed-data-type.ts:37](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L37) *** ### label > **label**: `string` Defined in: [packages/core/src/domain/managed-data-type.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L34) *** ### schema > **schema**: `z.ZodTypeAny` Defined in: [packages/core/src/domain/managed-data-type.ts:35](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L35) --- --- url: /docs/api/core/type-aliases/ManagedDataType.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ManagedDataType # Type Alias: ManagedDataType > **ManagedDataType** = *typeof* [`managedDataTypes`](../variables/managedDataTypes.md)\[`number`] Defined in: [packages/core/src/domain/managed-data-type.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L25) --- --- url: /docs/api/core/type-aliases/MealSlot.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / MealSlot # Type Alias: MealSlot > **MealSlot** = `z.infer`<*typeof* [`mealSlotSchema`](../variables/mealSlotSchema.md)> Defined in: [packages/core/src/domain/schemas/health/nutrition.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/nutrition.ts#L27) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/MeasuredWellness.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / MeasuredWellness # Type Alias: MeasuredWellness > **MeasuredWellness** = `object` Defined in: [packages/core/src/application/energy/expenditure.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L14) Ingested device calories for a day, when a connection covers it. ## Properties ### activeCalories > **activeCalories**: `number` Defined in: [packages/core/src/application/energy/expenditure.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L15) *** ### restingCalories > **restingCalories**: `number` Defined in: [packages/core/src/application/energy/expenditure.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/expenditure.ts#L16) --- --- url: /docs/api/core/type-aliases/PaceValue.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / PaceValue # Type Alias: PaceValue > **PaceValue** = `z.infer`<*typeof* `paceValueSchema`> Defined in: [packages/core/src/domain/schemas/target-values/pace.ts:55](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-values/pace.ts#L55) TypeScript type for pace target value, inferred from paceValueSchema. Discriminated union representing pace targets in various units. --- --- url: /docs/api/garmin/type-aliases/PaceZoneEntry.md --- [**@kaiord/garmin**](../README.md) *** [@kaiord/garmin](../README.md) / PaceZoneEntry # Type Alias: PaceZoneEntry > **PaceZoneEntry** = `object` Defined in: [adapters/converters/target-types.ts:12](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/adapters/converters/target-types.ts#L12) ## Properties ### maxMps > **maxMps**: `number` Defined in: [adapters/converters/target-types.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/adapters/converters/target-types.ts#L15) *** ### minMps > **minMps**: `number` Defined in: [adapters/converters/target-types.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/adapters/converters/target-types.ts#L14) *** ### zone > **zone**: `number` Defined in: [adapters/converters/target-types.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/adapters/converters/target-types.ts#L13) --- --- url: /docs/api/garmin/type-aliases/PaceZoneTable.md --- [**@kaiord/garmin**](../README.md) *** [@kaiord/garmin](../README.md) / PaceZoneTable # Type Alias: PaceZoneTable > **PaceZoneTable** = [`PaceZoneEntry`](PaceZoneEntry.md)\[] Defined in: [adapters/converters/target-types.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/adapters/converters/target-types.ts#L18) --- --- url: /docs/api/core/type-aliases/PlannedSession.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / PlannedSession # Type Alias: PlannedSession > **PlannedSession** = `z.infer`<*typeof* [`plannedSessionSchema`](../variables/plannedSessionSchema.md)> Defined in: [packages/core/src/domain/schemas/planned-session.ts:49](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/planned-session.ts#L49) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/PlannedSessionStatus.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / PlannedSessionStatus # Type Alias: PlannedSessionStatus > **PlannedSessionStatus** = `z.infer`<*typeof* [`plannedSessionStatusSchema`](../variables/plannedSessionStatusSchema.md)> Defined in: [packages/core/src/domain/schemas/planned-session.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/planned-session.ts#L13) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/PowerValue.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / PowerValue # Type Alias: PowerValue > **PowerValue** = `z.infer`<*typeof* `powerValueSchema`> Defined in: [packages/core/src/domain/schemas/target-values/power.ts:63](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-values/power.ts#L63) TypeScript type for power target value, inferred from powerValueSchema. Discriminated union representing power targets in various units. --- --- url: /docs/api/core/type-aliases/PowerZone.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / PowerZone # Type Alias: PowerZone > **PowerZone** = `1` | `2` | `3` | `4` | `5` | `6` | `7` Defined in: [packages/core/src/domain/zones/power-zones.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/zones/power-zones.ts#L18) Coggan 7-band power-zone-to-percent-FTP table. Single source of truth for translating a discrete cycling power zone (1..7) into the percent-of-FTP value the zone represents. Lives in the domain layer because the mapping is a fitness-domain truth (Coggan power-zone definitions), not a format encoding. Zone 1 (Recovery): 55% FTP Zone 2 (Endurance): 75% FTP Zone 3 (Tempo): 90% FTP Zone 4 (Threshold): 105% FTP Zone 5 (VO2 Max): 120% FTP Zone 6 (Anaerobic): 150% FTP Zone 7 (Neuromuscular): 200% FTP --- --- url: /docs/api/core/type-aliases/ProfileSnapshot.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ProfileSnapshot # Type Alias: ProfileSnapshot > **ProfileSnapshot** = `z.infer`<*typeof* [`profileSnapshotSchema`](../variables/profileSnapshotSchema.md)> Defined in: [packages/core/src/protocol/profile-snapshot.ts:96](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/protocol/profile-snapshot.ts#L96) --- --- url: /docs/api/core/type-aliases/PushResult.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / PushResult # Type Alias: PushResult > **PushResult** = `object` Defined in: [packages/core/src/ports/workout-service.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L17) Result of pushing a workout to a remote service. ## Properties ### id > **id**: `string` Defined in: [packages/core/src/ports/workout-service.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L17) *** ### name > **name**: `string` Defined in: [packages/core/src/ports/workout-service.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L17) *** ### url? > `optional` **url?**: `string` Defined in: [packages/core/src/ports/workout-service.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L17) --- --- url: /docs/api/garmin-connect/type-aliases/PushResult.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / PushResult # Type Alias: PushResult > **PushResult** = `object` Defined in: core/dist/index.d.ts:4134 Result of pushing a workout to a remote service. ## Properties ### id > **id**: `string` Defined in: core/dist/index.d.ts:4135 *** ### name > **name**: `string` Defined in: core/dist/index.d.ts:4136 *** ### url? > `optional` **url?**: `string` Defined in: core/dist/index.d.ts:4137 --- --- url: /docs/api/core/type-aliases/RepetitionBlock.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / RepetitionBlock # Type Alias: RepetitionBlock > **RepetitionBlock** = `z.infer`<*typeof* [`repetitionBlockSchema`](../variables/repetitionBlockSchema.md)> Defined in: [packages/core/src/domain/schemas/workout.ts:65](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/workout.ts#L65) TypeScript type for a repetition block, inferred from [repetitionBlockSchema](../variables/repetitionBlockSchema.md). Represents a group of workout steps that repeat multiple times. --- --- url: /docs/api/core/type-aliases/ResolvedExpenditure.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ResolvedExpenditure # Type Alias: ResolvedExpenditure > **ResolvedExpenditure** = `object` Defined in: [packages/core/src/application/energy/day-balance.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L22) The expenditure portion already resolved by `resolveDayExpenditure`. ## Properties ### activityKcal > **activityKcal**: `number` Defined in: [packages/core/src/application/energy/day-balance.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L24) *** ### basalKcal > **basalKcal**: `number` Defined in: [packages/core/src/application/energy/day-balance.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L23) *** ### expenditureKcal > **expenditureKcal**: `number` Defined in: [packages/core/src/application/energy/day-balance.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L25) *** ### source > **source**: [`ExpenditureSource`](ExpenditureSource.md) Defined in: [packages/core/src/application/energy/day-balance.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/day-balance.ts#L26) --- --- url: /docs/api/garmin-connect/type-aliases/RetryOptions.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / RetryOptions # Type Alias: RetryOptions > **RetryOptions** = `object` Defined in: [garmin-connect/src/adapters/http/retry.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/http/retry.ts#L11) ## Properties ### baseDelay? > `optional` **baseDelay?**: `number` Defined in: [garmin-connect/src/adapters/http/retry.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/http/retry.ts#L13) *** ### logger? > `optional` **logger?**: `Logger` Defined in: [garmin-connect/src/adapters/http/retry.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/http/retry.ts#L16) *** ### maxDelay? > `optional` **maxDelay?**: `number` Defined in: [garmin-connect/src/adapters/http/retry.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/http/retry.ts#L14) *** ### maxRetries? > `optional` **maxRetries?**: `number` Defined in: [garmin-connect/src/adapters/http/retry.ts:12](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/http/retry.ts#L12) *** ### randomFn? > `optional` **randomFn?**: () => `number` Defined in: [garmin-connect/src/adapters/http/retry.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/http/retry.ts#L15) #### Returns `number` --- --- url: /docs/api/core/type-aliases/SchemaValidator.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SchemaValidator # Type Alias: SchemaValidator > **SchemaValidator** = `object` Defined in: [packages/core/src/domain/validation/schema-validator.ts:4](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/schema-validator.ts#L4) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD ## Properties ### validate > **validate**: (`krd`) => [`ValidationError`](ValidationError.md)\[] Defined in: [packages/core/src/domain/validation/schema-validator.ts:5](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/schema-validator.ts#L5) #### Parameters ##### krd `unknown` #### Returns [`ValidationError`](ValidationError.md)\[] --- --- url: /docs/api/core/type-aliases/Sex.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Sex # Type Alias: Sex > **Sex** = `"male"` | `"female"` Defined in: [packages/core/src/application/energy/bmr.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/bmr.ts#L11) --- --- url: /docs/api/core/type-aliases/SleepRecord.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SleepRecord # Type Alias: SleepRecord > **SleepRecord** = `z.infer`<*typeof* [`sleepRecordSchema`](../variables/sleepRecordSchema.md)> Defined in: [packages/core/src/domain/schemas/health/sleep.ts:59](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/sleep.ts#L59) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/SleepStage.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SleepStage # Type Alias: SleepStage > **SleepStage** = `z.infer`<*typeof* [`sleepStageSchema`](../variables/sleepStageSchema.md)> Defined in: [packages/core/src/domain/schemas/health/sleep.ts:20](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/sleep.ts#L20) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/Sport.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Sport # Type Alias: Sport > **Sport** = `z.infer`<*typeof* [`sportSchema`](../variables/sportSchema.md)> Defined in: [packages/core/src/domain/schemas/sport.ts:97](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/sport.ts#L97) String literal union of supported sport types, inferred from [sportSchema](../variables/sportSchema.md). --- --- url: /docs/api/core/type-aliases/SportCategory.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SportCategory # Type Alias: SportCategory > **SportCategory** = `"cycling"` | `"running"` | `"swimming"` | `"other"` Defined in: [packages/core/src/domain/schemas/sport-category.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/sport-category.ts#L10) Coarse capability category for a sport. Behavioural logic (zone/threshold models, lossy adapter collapse to TCX/ZWO) branches on this category, never on the open-ended [Sport](Sport.md) identity — so widening the sport vocabulary never requires touching that logic. `other` is the default and behaves like `generic` (no power/pace model; collapses to TCX `Other`). --- --- url: /docs/api/core/type-aliases/StrainSummary.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / StrainSummary # Type Alias: StrainSummary > **StrainSummary** = `z.infer`<*typeof* [`strainSummarySchema`](../variables/strainSummarySchema.md)> Defined in: [packages/core/src/domain/schemas/health/strain.ts:42](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/strain.ts#L42) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/StressEpisode.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / StressEpisode # Type Alias: StressEpisode > **StressEpisode** = `z.infer`<*typeof* [`stressEpisodeSchema`](../variables/stressEpisodeSchema.md)> Defined in: [packages/core/src/domain/schemas/health/stress.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/stress.ts#L41) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/StrokeTypeValue.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / StrokeTypeValue # Type Alias: StrokeTypeValue > **StrokeTypeValue** = `z.infer`<*typeof* `strokeTypeValueSchema`> Defined in: [packages/core/src/domain/schemas/target-values/stroke-type.ts:33](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-values/stroke-type.ts#L33) TypeScript type for stroke type target value, inferred from strokeTypeValueSchema. Represents swimming stroke type targets. --- --- url: /docs/api/core/type-aliases/SubSport.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SubSport # Type Alias: SubSport > **SubSport** = `z.infer`<*typeof* [`subSportSchema`](../variables/subSportSchema.md)> Defined in: [packages/core/src/domain/schemas/sub-sport.ts:93](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/sub-sport.ts#L93) TypeScript type for sub-sport, inferred from [subSportSchema](../variables/subSportSchema.md). String literal union of supported sub-sport types. --- --- url: /docs/api/core/type-aliases/SwimStroke.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SwimStroke # Type Alias: SwimStroke > **SwimStroke** = `z.infer`<*typeof* [`swimStrokeSchema`](../variables/swimStrokeSchema.md)> Defined in: [packages/core/src/domain/schemas/swim-stroke.ts:38](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/swim-stroke.ts#L38) TypeScript type for swim stroke, inferred from [swimStrokeSchema](../variables/swimStrokeSchema.md). String literal union of supported swim stroke types. --- --- url: /docs/api/core/type-aliases/Target.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Target # Type Alias: Target > **Target** = `z.infer`<*typeof* [`targetSchema`](../variables/targetSchema.md)> Defined in: [packages/core/src/domain/schemas/target.ts:50](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target.ts#L50) TypeScript type for workout step target, inferred from [targetSchema](../variables/targetSchema.md). Discriminated union type representing all possible target specifications. --- --- url: /docs/api/core/type-aliases/TargetType.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TargetType # Type Alias: TargetType > **TargetType** = `z.infer`<*typeof* [`targetTypeSchema`](../variables/targetTypeSchema.md)> Defined in: [packages/core/src/domain/schemas/target-type.ts:32](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-type.ts#L32) TypeScript type for target type, inferred from [targetTypeSchema](../variables/targetTypeSchema.md). String literal union of all possible target types. --- --- url: /docs/api/core/type-aliases/TargetUnit.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TargetUnit # Type Alias: TargetUnit > **TargetUnit** = `z.infer`<*typeof* [`targetUnitSchema`](../variables/targetUnitSchema.md)> Defined in: [packages/core/src/domain/schemas/target-values/unit.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-values/unit.ts#L34) TypeScript type for target unit, inferred from [targetUnitSchema](../variables/targetUnitSchema.md). String literal union of all possible target units. --- --- url: /docs/api/tcx/type-aliases/TcxValidationResult.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / TcxValidationResult # Type Alias: TcxValidationResult > **TcxValidationResult** = `object` Defined in: [types.ts:1](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/types.ts#L1) ## Properties ### errors > **errors**: `object`\[] Defined in: [types.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/types.ts#L3) #### message > **message**: `string` #### path > **path**: `string` *** ### valid > **valid**: `boolean` Defined in: [types.ts:2](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/types.ts#L2) --- --- url: /docs/api/tcx/type-aliases/TcxValidator.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / TcxValidator # Type Alias: TcxValidator > **TcxValidator** = (`xmlString`) => `Promise`<[`TcxValidationResult`](TcxValidationResult.md)> Defined in: [types.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/types.ts#L6) ## Parameters ### xmlString `string` ## Returns `Promise`<[`TcxValidationResult`](TcxValidationResult.md)> --- --- url: /docs/api/core/type-aliases/TextReader.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TextReader # Type Alias: TextReader > **TextReader** = (`text`) => `Promise`<[`KRD`](KRD.md)> Defined in: [packages/core/src/ports/format-strategy.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/format-strategy.ts#L11) Reads text data (e.g. TCX, ZWO, GPX) and converts it to KRD. ## Parameters ### text `string` ## Returns `Promise`<[`KRD`](KRD.md)> --- --- url: /docs/api/core/type-aliases/TextWriter.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TextWriter # Type Alias: TextWriter > **TextWriter** = (`krd`) => `Promise`<`string`> Defined in: [packages/core/src/ports/format-strategy.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/format-strategy.ts#L21) Converts KRD to text output (e.g. TCX, ZWO, GPX). ## Parameters ### krd [`KRD`](KRD.md) ## Returns `Promise`<`string`> --- --- url: /docs/api/core/type-aliases/TokenData.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TokenData # Type Alias: TokenData > **TokenData** = `Record`<`string`, `unknown`> Defined in: [packages/core/src/ports/auth-provider.ts:4](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/auth-provider.ts#L4) Opaque token data for session persistence. --- --- url: /docs/api/garmin-connect/type-aliases/TokenData.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / TokenData # Type Alias: TokenData > **TokenData** = `Record`<`string`, `unknown`> Defined in: core/dist/index.d.ts:4083 Opaque token data for session persistence. --- --- url: /docs/api/garmin-connect/type-aliases/TokenReader.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / TokenReader # Type Alias: TokenReader > **TokenReader** = `Pick`<`TokenManager`, `"getAccessToken"` | `"getGeneration"` | `"refresh"` | `"isAuthenticated"`> Defined in: [garmin-connect/src/adapters/token/token-manager.types.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin-connect/src/adapters/token/token-manager.types.ts#L15) --- --- url: /docs/api/core/type-aliases/TokenStore.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TokenStore # Type Alias: TokenStore > **TokenStore** = `object` Defined in: [packages/core/src/ports/token-store.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/token-store.ts#L6) Port for persisting authentication tokens between sessions. ## Properties ### clear > **clear**: () => `Promise`<`void`> Defined in: [packages/core/src/ports/token-store.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/token-store.ts#L9) #### Returns `Promise`<`void`> *** ### load > **load**: () => `Promise`<[`TokenData`](TokenData.md) | `null`> Defined in: [packages/core/src/ports/token-store.ts:8](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/token-store.ts#L8) #### Returns `Promise`<[`TokenData`](TokenData.md) | `null`> *** ### save > **save**: (`tokens`) => `Promise`<`void`> Defined in: [packages/core/src/ports/token-store.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/token-store.ts#L7) #### Parameters ##### tokens [`TokenData`](TokenData.md) #### Returns `Promise`<`void`> --- --- url: /docs/api/garmin-connect/type-aliases/TokenStore.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / TokenStore # Type Alias: TokenStore > **TokenStore** = `object` Defined in: core/dist/index.d.ts:4115 Port for persisting authentication tokens between sessions. ## Properties ### clear > **clear**: () => `Promise`<`void`> Defined in: core/dist/index.d.ts:4118 #### Returns `Promise`<`void`> *** ### load > **load**: () => `Promise`<[`TokenData`](TokenData.md) | `null`> Defined in: core/dist/index.d.ts:4117 #### Returns `Promise`<[`TokenData`](TokenData.md) | `null`> *** ### save > **save**: (`tokens`) => `Promise`<`void`> Defined in: core/dist/index.d.ts:4116 #### Parameters ##### tokens [`TokenData`](TokenData.md) #### Returns `Promise`<`void`> --- --- url: /docs/api/core/type-aliases/ToleranceChecker.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ToleranceChecker # Type Alias: ToleranceChecker > **ToleranceChecker** = `object` Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:35](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L35) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD ## Properties ### checkCadence > **checkCadence**: (`expected`, `actual`) => `ToleranceViolation` | `null` Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:46](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L46) #### Parameters ##### expected `number` ##### actual `number` #### Returns `ToleranceViolation` | `null` *** ### checkDistance > **checkDistance**: (`expected`, `actual`) => `ToleranceViolation` | `null` Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:37](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L37) #### Parameters ##### expected `number` ##### actual `number` #### Returns `ToleranceViolation` | `null` *** ### checkHeartRate > **checkHeartRate**: (`expected`, `actual`) => `ToleranceViolation` | `null` Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:42](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L42) #### Parameters ##### expected `number` ##### actual `number` #### Returns `ToleranceViolation` | `null` *** ### checkPace > **checkPace**: (`expected`, `actual`) => `ToleranceViolation` | `null` Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:47](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L47) #### Parameters ##### expected `number` ##### actual `number` #### Returns `ToleranceViolation` | `null` *** ### checkPower > **checkPower**: (`expected`, `actual`) => `ToleranceViolation` | `null` Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L41) #### Parameters ##### expected `number` ##### actual `number` #### Returns `ToleranceViolation` | `null` *** ### checkTime > **checkTime**: (`expected`, `actual`) => `ToleranceViolation` | `null` Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:36](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L36) #### Parameters ##### expected `number` ##### actual `number` #### Returns `ToleranceViolation` | `null` --- --- url: /docs/api/core/type-aliases/ToleranceConfig.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ToleranceConfig # Type Alias: ToleranceConfig > **ToleranceConfig** = `z.infer`<*typeof* [`toleranceConfigSchema`](../variables/toleranceConfigSchema.md)> Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L13) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/ToleranceViolation.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ToleranceViolation # Type Alias: ToleranceViolation > **ToleranceViolation** = `object` Defined in: [packages/core/src/domain/types/error-types.ts:50](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L50) Tolerance violation details for a specific field. Used by [ToleranceExceededError](../classes/ToleranceExceededError.md) to provide detailed information about round-trip conversion errors. ## Example ```typescript const violation: ToleranceViolation = { field: 'power', expected: 250, actual: 252, deviation: 2, tolerance: 1 }; ``` ## Properties ### actual > **actual**: `number` Defined in: [packages/core/src/domain/types/error-types.ts:56](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L56) Actual value after round-trip conversion *** ### deviation > **deviation**: `number` Defined in: [packages/core/src/domain/types/error-types.ts:58](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L58) Absolute deviation from expected value *** ### expected > **expected**: `number` Defined in: [packages/core/src/domain/types/error-types.ts:54](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L54) Expected value from original data *** ### field > **field**: `string` Defined in: [packages/core/src/domain/types/error-types.ts:52](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L52) The field that exceeded tolerance *** ### tolerance > **tolerance**: `number` Defined in: [packages/core/src/domain/types/error-types.ts:60](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L60) Maximum allowed tolerance --- --- url: /docs/api/mcp/type-aliases/ToolResult.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / ToolResult # Type Alias: ToolResult > **ToolResult** = `object` Defined in: [utils/error-formatter.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/utils/error-formatter.ts#L6) ## Properties ### content > **content**: `object`\[] Defined in: [utils/error-formatter.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/utils/error-formatter.ts#L7) #### text > **text**: `string` #### type > **type**: `"text"` *** ### isError? > `optional` **isError?**: `boolean` Defined in: [utils/error-formatter.ts:8](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/utils/error-formatter.ts#L8) *** ### structuredContent? > `optional` **structuredContent?**: `object` Defined in: [utils/error-formatter.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/utils/error-formatter.ts#L10) Machine-readable failure classification for AI-agent branching. #### error > **error**: `McpErrorClassification` --- --- url: /docs/api/core/type-aliases/TrainingZoneBand.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TrainingZoneBand # Type Alias: TrainingZoneBand > **TrainingZoneBand** = `z.infer`<*typeof* [`trainingZoneBandSchema`](../variables/trainingZoneBandSchema.md)> Defined in: [packages/core/src/domain/schemas/training-zones.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/training-zones.ts#L14) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/TrainingZones.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TrainingZones # Type Alias: TrainingZones > **TrainingZones** = `z.infer`<*typeof* [`trainingZonesSchema`](../variables/trainingZonesSchema.md)> Defined in: [packages/core/src/domain/schemas/training-zones.ts:40](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/training-zones.ts#L40) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/TrainingZoneSet.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / TrainingZoneSet # Type Alias: TrainingZoneSet > **TrainingZoneSet** = `z.infer`<*typeof* [`trainingZoneSetSchema`](../variables/trainingZoneSetSchema.md)> Defined in: [packages/core/src/domain/schemas/training-zones.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/training-zones.ts#L24) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/ValidateRoundTrip.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ValidateRoundTrip # Type Alias: ValidateRoundTrip > **ValidateRoundTrip** = `ReturnType`<*typeof* [`validateRoundTrip`](../functions/validateRoundTrip.md)> Defined in: [packages/core/src/application/round-trip/validate-round-trip.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/round-trip/validate-round-trip.ts#L19) TypeScript type for the validateRoundTrip use case function. Automatically inferred from the [validateRoundTrip](../functions/validateRoundTrip.md) factory function. --- --- url: /docs/api/core/type-aliases/ValidationError.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / ValidationError # Type Alias: ValidationError > **ValidationError** = `object` Defined in: [packages/core/src/domain/types/error-types.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L16) Validation error details for a specific field. Used by [KrdValidationError](../classes/KrdValidationError.md) to provide detailed information about validation failures. ## Example ```typescript const error: ValidationError = { field: 'version', message: 'Required field missing', expected: 'string', actual: undefined }; ``` ## Properties ### actual? > `optional` **actual?**: `unknown` Defined in: [packages/core/src/domain/types/error-types.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L31) Optional actual value that failed validation *** ### code? > `optional` **code?**: `string` Defined in: [packages/core/src/domain/types/error-types.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L27) Stable, language-free machine code for the failure (e.g. `min_gt_max`, `invalid_type`). Presentation layers localize by this code, never by matching `message` text (see the `failure-semantics` spec). Absent when the source issue carries no derivable code. *** ### expected? > `optional` **expected?**: `unknown` Defined in: [packages/core/src/domain/types/error-types.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L29) Optional expected value or type *** ### field > **field**: `string` Defined in: [packages/core/src/domain/types/error-types.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L18) The field path that failed validation *** ### message > **message**: `string` Defined in: [packages/core/src/domain/types/error-types.ts:20](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/types/error-types.ts#L20) Human-readable (English) error message --- --- url: /docs/api/core/type-aliases/VitalsSummary.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / VitalsSummary # Type Alias: VitalsSummary > **VitalsSummary** = `z.infer`<*typeof* [`vitalsSummarySchema`](../variables/vitalsSummarySchema.md)> Defined in: [packages/core/src/domain/schemas/health/vitals.ts:39](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/vitals.ts#L39) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/WeightMeasurement.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / WeightMeasurement # Type Alias: WeightMeasurement > **WeightMeasurement** = `z.infer`<*typeof* [`weightMeasurementSchema`](../variables/weightMeasurementSchema.md)> Defined in: [packages/core/src/domain/schemas/health/weight.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/weight.ts#L22) @kaiord/core - Public API Bidirectional conversion between workout formats (FIT, TCX, ZWO, Garmin) and KRD --- --- url: /docs/api/core/type-aliases/Workout.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / Workout # Type Alias: Workout > **Workout** = `z.infer`<*typeof* [`workoutSchema`](../variables/workoutSchema.md)> Defined in: [packages/core/src/domain/schemas/workout.ts:72](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/workout.ts#L72) TypeScript type for a complete workout, inferred from [workoutSchema](../variables/workoutSchema.md). Represents a structured workout definition with metadata and steps. --- --- url: /docs/api/core/type-aliases/WorkoutService.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / WorkoutService # Type Alias: WorkoutService > **WorkoutService** = `object` Defined in: [packages/core/src/ports/workout-service.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L27) Port for a remote workout service (push/pull/list/delete). ## Properties ### list > **list**: (`options?`) => `Promise`<[`WorkoutSummary`](WorkoutSummary.md)\[]> Defined in: [packages/core/src/ports/workout-service.ts:30](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L30) #### Parameters ##### options? [`ListOptions`](ListOptions.md) #### Returns `Promise`<[`WorkoutSummary`](WorkoutSummary.md)\[]> *** ### pull > **pull**: (`workoutId`) => `Promise`<[`KRD`](KRD.md)> Defined in: [packages/core/src/ports/workout-service.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L29) #### Parameters ##### workoutId `string` #### Returns `Promise`<[`KRD`](KRD.md)> *** ### push > **push**: (`krd`) => `Promise`<[`PushResult`](PushResult.md)> Defined in: [packages/core/src/ports/workout-service.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L28) #### Parameters ##### krd [`KRD`](KRD.md) #### Returns `Promise`<[`PushResult`](PushResult.md)> *** ### remove > **remove**: (`workoutId`) => `Promise`<`void`> Defined in: [packages/core/src/ports/workout-service.ts:31](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L31) #### Parameters ##### workoutId `string` #### Returns `Promise`<`void`> --- --- url: /docs/api/core/type-aliases/WorkoutStep.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / WorkoutStep # Type Alias: WorkoutStep > **WorkoutStep** = `z.infer`<*typeof* [`workoutStepSchema`](../variables/workoutStepSchema.md)> Defined in: [packages/core/src/domain/schemas/workout-step.ts:45](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/workout-step.ts#L45) TypeScript type for a workout step, inferred from [workoutStepSchema](../variables/workoutStepSchema.md). Represents an individual interval or segment within a workout. --- --- url: /docs/api/core/type-aliases/WorkoutSummary.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / WorkoutSummary # Type Alias: WorkoutSummary > **WorkoutSummary** = `object` Defined in: [packages/core/src/ports/workout-service.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L6) Summary of a remote workout (listing view). ## Properties ### created\_at > **created\_at**: `string` Defined in: [packages/core/src/ports/workout-service.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L10) *** ### id > **id**: `string` Defined in: [packages/core/src/ports/workout-service.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L7) *** ### name > **name**: `string` Defined in: [packages/core/src/ports/workout-service.ts:8](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L8) *** ### sport > **sport**: `string` Defined in: [packages/core/src/ports/workout-service.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L9) *** ### updated\_at > **updated\_at**: `string` Defined in: [packages/core/src/ports/workout-service.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/ports/workout-service.ts#L11) --- --- url: /docs/api/garmin-connect/type-aliases/WorkoutSummary.md --- [**@kaiord/garmin-connect**](../README.md) *** [@kaiord/garmin-connect](../README.md) / WorkoutSummary # Type Alias: WorkoutSummary > **WorkoutSummary** = `object` Defined in: core/dist/index.d.ts:4124 Summary of a remote workout (listing view). ## Properties ### created\_at > **created\_at**: `string` Defined in: core/dist/index.d.ts:4128 *** ### id > **id**: `string` Defined in: core/dist/index.d.ts:4125 *** ### name > **name**: `string` Defined in: core/dist/index.d.ts:4126 *** ### sport > **sport**: `string` Defined in: core/dist/index.d.ts:4127 *** ### updated\_at > **updated\_at**: `string` Defined in: core/dist/index.d.ts:4129 --- --- url: /docs/api/zwo/type-aliases/ZwiftValidationError.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / ZwiftValidationError # Type Alias: ZwiftValidationError > **ZwiftValidationError** = `object` Defined in: [types.ts:1](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/types.ts#L1) ## Properties ### field > **field**: `string` Defined in: [types.ts:2](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/types.ts#L2) *** ### message > **message**: `string` Defined in: [types.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/types.ts#L3) --- --- url: /docs/api/zwo/type-aliases/ZwiftValidationResult.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / ZwiftValidationResult # Type Alias: ZwiftValidationResult > **ZwiftValidationResult** = `object` Defined in: [types.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/types.ts#L6) ## Properties ### errors > **errors**: [`ZwiftValidationError`](ZwiftValidationError.md)\[] Defined in: [types.ts:8](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/types.ts#L8) *** ### valid > **valid**: `boolean` Defined in: [types.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/types.ts#L7) --- --- url: /docs/api/zwo/type-aliases/ZwiftValidator.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / ZwiftValidator # Type Alias: ZwiftValidator > **ZwiftValidator** = (`xmlString`) => `Promise`<[`ZwiftValidationResult`](ZwiftValidationResult.md)> Defined in: [types.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/types.ts#L11) ## Parameters ### xmlString `string` ## Returns `Promise`<[`ZwiftValidationResult`](ZwiftValidationResult.md)> --- --- url: /docs/api/core/variables/activitySchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / activitySchema # Variable: activitySchema > `const` **activitySchema**: `ZodObject`<{ `kind`: `ZodLiteral`<`"activity"`>; `krd`: `ZodOptional`<`ZodObject`<{ `events`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `data`: `ZodOptional`<`ZodNumber`>; `eventGroup`: `ZodOptional`<`ZodNumber`>; `eventType`: `ZodEnum`<{ `event_activity_start`: ...; `event_lap`: ...; `event_marker`: ...; `event_pause`: ...; `event_resume`: ...; `event_session_start`: ...; `event_start`: ...; `event_stop`: ...; `event_timer`: ...; `event_workout_step_change`: ...; }>; `message`: `ZodOptional`<`ZodString`>; `timestamp`: `ZodISODateTime`; }, `$strip`>>>; `extensions`: `ZodOptional`<`ZodObject`<{ `course`: `ZodOptional`<`ZodUnknown`>; `course_points`: `ZodOptional`<`ZodUnknown`>; `fit`: `ZodOptional`<`ZodUnknown`>; `health`: `ZodOptional`<`ZodObject`<{ `bodyComposition`: ...; `daily`: ...; `hrv`: ...; `sleep`: ...; `stress`: ...; `weight`: ...; }, `$catchall`<...>>>; `structured_workout`: `ZodOptional`<`ZodUnknown`>; }, `$catchall`<`ZodUnknown`>>>; `laps`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `avgCadence`: `ZodOptional`<`ZodNumber`>; `avgHeartRate`: `ZodOptional`<`ZodNumber`>; `avgPower`: `ZodOptional`<`ZodNumber`>; `avgSpeed`: `ZodOptional`<`ZodNumber`>; `maxCadence`: `ZodOptional`<`ZodNumber`>; `maxHeartRate`: `ZodOptional`<`ZodNumber`>; `maxPower`: `ZodOptional`<`ZodNumber`>; `maxSpeed`: `ZodOptional`<`ZodNumber`>; `normalizedPower`: `ZodOptional`<`ZodNumber`>; `numLengths`: `ZodOptional`<`ZodNumber`>; `sport`: `ZodOptional`<`ZodEnum`<...>>; `startTime`: `ZodISODateTime`; `subSport`: `ZodOptional`<`ZodEnum`<...>>; `swimStroke`: `ZodOptional`<`ZodEnum`<...>>; `totalAscent`: `ZodOptional`<`ZodNumber`>; `totalCalories`: `ZodOptional`<`ZodNumber`>; `totalDescent`: `ZodOptional`<`ZodNumber`>; `totalDistance`: `ZodOptional`<`ZodNumber`>; `totalElapsedTime`: `ZodNumber`; `totalTimerTime`: `ZodOptional`<`ZodNumber`>; `trigger`: `ZodOptional`<`ZodEnum`<...>>; `workoutStepIndex`: `ZodOptional`<`ZodNumber`>; }, `$strip`>>>; `metadata`: `ZodObject`<{ `created`: `ZodISODateTime`; `manufacturer`: `ZodOptional`<`ZodString`>; `product`: `ZodOptional`<`ZodString`>; `serialNumber`: `ZodOptional`<`ZodString`>; `sport`: `ZodOptional`<`ZodString`>; `subSport`: `ZodOptional`<`ZodString`>; }, `$strip`>; `records`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `altitude`: `ZodOptional`<`ZodNumber`>; `cadence`: `ZodOptional`<`ZodNumber`>; `distance`: `ZodOptional`<`ZodNumber`>; `heartRate`: `ZodOptional`<`ZodNumber`>; `position`: `ZodOptional`<`ZodObject`<..., ...>>; `power`: `ZodOptional`<`ZodNumber`>; `speed`: `ZodOptional`<`ZodNumber`>; `stanceTime`: `ZodOptional`<`ZodNumber`>; `stepLength`: `ZodOptional`<`ZodNumber`>; `temperature`: `ZodOptional`<`ZodNumber`>; `timestamp`: `ZodISODateTime`; `verticalOscillation`: `ZodOptional`<`ZodNumber`>; }, `$strip`>>>; `sessions`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `avgCadence`: `ZodOptional`<`ZodNumber`>; `avgHeartRate`: `ZodOptional`<`ZodNumber`>; `avgPower`: `ZodOptional`<`ZodNumber`>; `avgSpeed`: `ZodOptional`<`ZodNumber`>; `intensityFactor`: `ZodOptional`<`ZodNumber`>; `maxCadence`: `ZodOptional`<`ZodNumber`>; `maxHeartRate`: `ZodOptional`<`ZodNumber`>; `maxPower`: `ZodOptional`<`ZodNumber`>; `maxSpeed`: `ZodOptional`<`ZodNumber`>; `normalizedPower`: `ZodOptional`<`ZodNumber`>; `sport`: `ZodString`; `startTime`: `ZodISODateTime`; `subSport`: `ZodOptional`<`ZodString`>; `totalAscent`: `ZodOptional`<`ZodNumber`>; `totalCalories`: `ZodOptional`<`ZodNumber`>; `totalDescent`: `ZodOptional`<`ZodNumber`>; `totalDistance`: `ZodOptional`<`ZodNumber`>; `totalElapsedTime`: `ZodNumber`; `totalTimerTime`: `ZodOptional`<`ZodNumber`>; `trainingStressScore`: `ZodOptional`<`ZodNumber`>; }, `$strip`>>>; `type`: `ZodEnum`<{ `body_composition`: `"body_composition"`; `course`: `"course"`; `daily_wellness`: `"daily_wellness"`; `hrv_summary`: `"hrv_summary"`; `recorded_activity`: `"recorded_activity"`; `sleep_record`: `"sleep_record"`; `stress_episode`: `"stress_episode"`; `structured_workout`: `"structured_workout"`; `weight_measurement`: `"weight_measurement"`; }>; `version`: `ZodString`; }, `$strip`>>; `summary`: `ZodObject`<{ `avg_heart_rate`: `ZodOptional`<`ZodNumber`>; `avg_power`: `ZodOptional`<`ZodNumber`>; `date`: `ZodISODate`; `distance_meters`: `ZodOptional`<`ZodNumber`>; `duration_seconds`: `ZodOptional`<`ZodNumber`>; `source`: `ZodString`; `source_id`: `ZodString`; `sport`: `ZodString`; `start_time`: `ZodOptional`<`ZodISODateTime`>; `sub_sport`: `ZodOptional`<`ZodString`>; `total_calories`: `ZodOptional`<`ZodNumber`>; }, `$strip`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/activity.ts:43](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/activity.ts#L43) Zod schema for an `activity` — a first-class executed session (the executed side of a SessionMatch). Shape mirrors the health records' `{ summary, krd? }` split: a mandatory summary for list/match reads plus the optional full KRD payload attached when the source provides recorded detail (records/laps/sessions). --- --- url: /docs/api/core/variables/activitySummarySchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / activitySummarySchema # Variable: activitySummarySchema > `const` **activitySummarySchema**: `ZodObject`<{ `avg_heart_rate`: `ZodOptional`<`ZodNumber`>; `avg_power`: `ZodOptional`<`ZodNumber`>; `date`: `ZodISODate`; `distance_meters`: `ZodOptional`<`ZodNumber`>; `duration_seconds`: `ZodOptional`<`ZodNumber`>; `source`: `ZodString`; `source_id`: `ZodString`; `sport`: `ZodString`; `start_time`: `ZodOptional`<`ZodISODateTime`>; `sub_sport`: `ZodOptional`<`ZodString`>; `total_calories`: `ZodOptional`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/activity.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/activity.ts#L11) Zod schema for the lightweight summary carried by every `activity` (executed session). The summary is always present — the calendar and SessionMatch read from it — while the full recorded detail is optional (see [activitySchema](activitySchema.md)). --- --- url: /docs/api/core/variables/BODY_FAT_TOLERANCE_PERCENT.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / BODY\_FAT\_TOLERANCE\_PERCENT # Variable: BODY\_FAT\_TOLERANCE\_PERCENT > `const` **BODY\_FAT\_TOLERANCE\_PERCENT**: `0.1` = `0.1` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L14) --- --- url: /docs/api/core/variables/bodyCompositionSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / bodyCompositionSchema # Variable: bodyCompositionSchema > `const` **bodyCompositionSchema**: `ZodObject`<{ `basalMetabolicRateKcal`: `ZodOptional`<`ZodNumber`>; `bmi`: `ZodOptional`<`ZodNumber`>; `bodyFatPercent`: `ZodOptional`<`ZodNumber`>; `bodyWaterPercent`: `ZodOptional`<`ZodNumber`>; `boneMassKilograms`: `ZodOptional`<`ZodNumber`>; `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"bodyComposition"`>; `leanMassKilograms`: `ZodOptional`<`ZodNumber`>; `measuredAt`: `ZodISODateTime`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `version`: `ZodString`; `visceralFatRating`: `ZodOptional`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/body-composition.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/body-composition.ts#L14) Zod schema for `extensions.health.bodyComposition` — a body-composition snapshot captured at a point in time. Each metric field is optional because devices vary in what they report (a basic scale may emit only `bodyFatPercent`, a Garmin Index scale emits the full set). A refinement requires that at least one metric field be present so empty payloads are rejected. --- --- url: /docs/api/core/variables/CUSTOM_PARAMETER_PREFIX.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / CUSTOM\_PARAMETER\_PREFIX # Variable: CUSTOM\_PARAMETER\_PREFIX > `const` **CUSTOM\_PARAMETER\_PREFIX**: `"custom:"` = `"custom:"` Defined in: [packages/core/src/domain/lab/lab-parameter-catalog.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter-catalog.ts#L41) --- --- url: /docs/api/core/variables/DAILY_KCAL_TOLERANCE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DAILY\_KCAL\_TOLERANCE # Variable: DAILY\_KCAL\_TOLERANCE > `const` **DAILY\_KCAL\_TOLERANCE**: `1` = `1` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L13) --- --- url: /docs/api/core/variables/DAILY_STEPS_TOLERANCE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DAILY\_STEPS\_TOLERANCE # Variable: DAILY\_STEPS\_TOLERANCE > `const` **DAILY\_STEPS\_TOLERANCE**: `0` = `0` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:12](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L12) --- --- url: /docs/api/core/variables/dailyWellnessSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / dailyWellnessSchema # Variable: dailyWellnessSchema > `const` **dailyWellnessSchema**: `ZodObject`<{ `activeCalories`: `ZodNumber`; `date`: `ZodISODate`; `externalId`: `ZodOptional`<`ZodString`>; `floorsClimbed`: `ZodOptional`<`ZodNumber`>; `intensityMinutes`: `ZodObject`<{ `moderate`: `ZodNumber`; `vigorous`: `ZodNumber`; }, `$strip`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"daily"`>; `restingCalories`: `ZodNumber`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `steps`: `ZodNumber`; `version`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/daily.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/daily.ts#L14) Zod schema for `extensions.health.daily` — a day-scoped wellness summary covering steps, calories, and intensity minutes. Garmin FIT `file_type` values `monitoringA (15)`, `monitoringDaily (28)`, and `monitoringB (32)` all map to this single sub-schema; consumers that need to discriminate the source can do so via a future additive field in a v2.x minor version. --- --- url: /docs/api/core/variables/dayEnergyBalanceSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / dayEnergyBalanceSchema # Variable: dayEnergyBalanceSchema > `const` **dayEnergyBalanceSchema**: `ZodObject`<{ `activity_kcal`: `ZodNumber`; `basal_kcal`: `ZodNumber`; `date`: `ZodISODate`; `expenditure_kcal`: `ZodNumber`; `intake_kcal`: `ZodNullable`<`ZodNumber`>; `macro_actuals`: `ZodOptional`<`ZodObject`<{ `carb_g`: `ZodNumber`; `fat_g`: `ZodNumber`; `kcal`: `ZodNumber`; `protein_g`: `ZodNumber`; }, `$strip`>>; `macro_targets`: `ZodOptional`<`ZodObject`<{ `carb_g`: `ZodNumber`; `fat_g`: `ZodNumber`; `kcal`: `ZodNumber`; `protein_g`: `ZodNumber`; }, `$strip`>>; `net_kcal`: `ZodNullable`<`ZodNumber`>; `source`: `ZodEnum`<{ `measured`: `"measured"`; `mixed`: `"mixed"`; `predicted`: `"predicted"`; }>; `target_kcal`: `ZodNullable`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/energy-balance.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/energy-balance.ts#L28) Computed per-day energy-balance view-model — not a persisted payload but the shape the SPA/chatbot read. `intake_kcal` is nullable: `null` means the day is untracked (never a silent zero). `net_kcal` is correspondingly nullable — without a tracked intake there is no net (never a misleading zero or full-surplus). `target_kcal` is nullable when no goal is active. Macro targets and actuals are optional because they only exist once a goal / intake is present. --- --- url: /docs/api/core/variables/DEFAULT_MET.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DEFAULT\_MET # Variable: DEFAULT\_MET > `const` **DEFAULT\_MET**: `6` = `6.0` Defined in: [packages/core/src/application/energy/met-table.ts:20](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/met-table.ts#L20) Fallback MET for any `Sport` not present in [MET\_TABLE](MET_TABLE.md). --- --- url: /docs/api/core/variables/DEFAULT_NEAT_FACTOR.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DEFAULT\_NEAT\_FACTOR # Variable: DEFAULT\_NEAT\_FACTOR > `const` **DEFAULT\_NEAT\_FACTOR**: `1.2` = `1.2` Defined in: [packages/core/src/application/energy/activity-factor.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/activity-factor.ts#L19) NEAT factor used when the profile has no `activityLevel` set. --- --- url: /docs/api/core/variables/DEFAULT_TOLERANCES.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / DEFAULT\_TOLERANCES # Variable: DEFAULT\_TOLERANCES > `const` **DEFAULT\_TOLERANCES**: [`ToleranceConfig`](../type-aliases/ToleranceConfig.md) Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L15) --- --- url: /docs/api/core/variables/durationSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / durationSchema # Variable: durationSchema > `const` **durationSchema**: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `seconds`: `ZodNumber`; `type`: `ZodLiteral`<`"time"`>; }, `$strip`>, `ZodObject`<{ `meters`: `ZodNumber`; `type`: `ZodLiteral`<`"distance"`>; }, `$strip`>, `ZodObject`<{ `bpm`: `ZodNumber`; `type`: `ZodLiteral`<`"heart_rate_less_than"`>; }, `$strip`>, `ZodObject`<{ `bpm`: `ZodNumber`; `repeatFrom`: `ZodNumber`; `type`: `ZodLiteral`<`"repeat_until_heart_rate_greater_than"`>; }, `$strip`>], `"type"`> Defined in: [packages/core/src/domain/schemas/duration.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/duration.ts#L21) Zod schema for workout step duration. Validates duration specifications using discriminated unions based on duration type. Supports time-based, distance-based, heart rate conditional, power conditional, calorie-based, and open durations. `repeatFrom` (on the `repeat_until_*` variants) is a 0-based **step index**, not a repeat count: execution jumps back to the step at that index and repeats the steps from there up to the current one until the variant's condition is met (elapsed time, distance, calories, or the HR/power threshold crossing). --- --- url: /docs/api/core/variables/durationTypeSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / durationTypeSchema # Variable: durationTypeSchema > `const` **durationTypeSchema**: `ZodEnum`<{ `calories`: `"calories"`; `distance`: `"distance"`; `heart_rate_less_than`: `"heart_rate_less_than"`; `open`: `"open"`; `power_greater_than`: `"power_greater_than"`; `power_less_than`: `"power_less_than"`; `repeat_until_calories`: `"repeat_until_calories"`; `repeat_until_distance`: `"repeat_until_distance"`; `repeat_until_heart_rate_greater_than`: `"repeat_until_heart_rate_greater_than"`; `repeat_until_heart_rate_less_than`: `"repeat_until_heart_rate_less_than"`; `repeat_until_power_greater_than`: `"repeat_until_power_greater_than"`; `repeat_until_power_less_than`: `"repeat_until_power_less_than"`; `repeat_until_time`: `"repeat_until_time"`; `time`: `"time"`; }> Defined in: [packages/core/src/domain/schemas/duration-type.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/duration-type.ts#L18) Zod schema for duration type enumeration. Defines all possible duration types for workout steps. ## Example ```typescript import { durationTypeSchema } from '@kaiord/core'; const timeType = durationTypeSchema.enum.time; const distanceType = durationTypeSchema.enum.distance; const result = durationTypeSchema.safeParse('time'); ``` --- --- url: /docs/api/core/variables/energyGoalSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / energyGoalSchema # Variable: energyGoalSchema > `const` **energyGoalSchema**: `ZodObject`<{ `goal_type`: `ZodEnum`<{ `fat_loss`: `"fat_loss"`; `maintain`: `"maintain"`; `muscle_gain`: `"muscle_gain"`; }>; `start_weight_kg`: `ZodNumber`; `target_date`: `ZodISODate`; `target_weight_kg`: `ZodNumber`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/energy-goal.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/energy-goal.ts#L14) --- --- url: /docs/api/core/variables/equipmentSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / equipmentSchema # Variable: equipmentSchema > `const` **equipmentSchema**: `ZodEnum`<{ `none`: `"none"`; `swim_fins`: `"swim_fins"`; `swim_kickboard`: `"swim_kickboard"`; `swim_paddles`: `"swim_paddles"`; `swim_pull_buoy`: `"swim_pull_buoy"`; `swim_snorkel`: `"swim_snorkel"`; }> Defined in: [packages/core/src/domain/schemas/equipment.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/equipment.ts#L23) Zod schema for equipment type enumeration. Defines swimming equipment types that can be specified for workout steps. ## Example ```typescript import { equipmentSchema } from '@kaiord/core'; // Access enum values const fins = equipmentSchema.enum.swim_fins; const kickboard = equipmentSchema.enum.swim_kickboard; // Validate equipment const result = equipmentSchema.safeParse('swim_fins'); if (result.success) { console.log('Valid equipment:', result.data); } ``` --- --- url: /docs/api/core/variables/expenditureSourceSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / expenditureSourceSchema # Variable: expenditureSourceSchema > `const` **expenditureSourceSchema**: `ZodEnum`<{ `measured`: `"measured"`; `mixed`: `"mixed"`; `predicted`: `"predicted"`; }> Defined in: [packages/core/src/domain/schemas/health/energy-balance.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/energy-balance.ts#L10) Provenance of a resolved day expenditure: `measured` from ingested device calories, `predicted` from BMR + expected activity, or `mixed` when the day blends both. --- --- url: /docs/api/core/variables/fileTypeSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / fileTypeSchema # Variable: fileTypeSchema > `const` **fileTypeSchema**: `ZodEnum`<{ `body_composition`: `"body_composition"`; `course`: `"course"`; `daily_wellness`: `"daily_wellness"`; `hrv_summary`: `"hrv_summary"`; `recorded_activity`: `"recorded_activity"`; `sleep_record`: `"sleep_record"`; `stress_episode`: `"stress_episode"`; `structured_workout`: `"structured_workout"`; `weight_measurement`: `"weight_measurement"`; }> Defined in: [packages/core/src/domain/schemas/file-type.ts:13](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/file-type.ts#L13) KRD `type` discriminator. The first three variants are the legacy workout/activity/course types (KRD v1.x). The latter six are the health-metric types introduced in KRD v2.0 (see the `health-data` capability). All nine values share the same root KRD document shape; per-type invariants are enforced by the `krdSchema` refinement (`metadata.sport` requirement) and by the `extensions.health.*` discriminated union (`healthExtensionPayloadSchema`). --- --- url: /docs/api/core/variables/FIT_TO_SWIM_STROKE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / FIT\_TO\_SWIM\_STROKE # Variable: FIT\_TO\_SWIM\_STROKE > `const` **FIT\_TO\_SWIM\_STROKE**: `Record`<`number`, [`SwimStroke`](../type-aliases/SwimStroke.md)> Defined in: [packages/core/src/domain/schemas/swim-stroke.ts:74](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/swim-stroke.ts#L74) Bidirectional mapping from FIT protocol numeric values to swim stroke. Used for converting FIT format to KRD swim strokes. ## Example ```typescript import { FIT_TO_SWIM_STROKE } from '@kaiord/core'; const stroke = FIT_TO_SWIM_STROKE[0]; // 'freestyle' ``` --- --- url: /docs/api/fit/variables/fitReader.md --- [**@kaiord/fit**](../README.md) *** [@kaiord/fit](../README.md) / fitReader # Variable: fitReader > `const` **fitReader**: `BinaryReader` Defined in: [fit/src/index.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/fit/src/index.ts#L24) --- --- url: /docs/api/fit/variables/fitWriter.md --- [**@kaiord/fit**](../README.md) *** [@kaiord/fit](../README.md) / fitWriter # Variable: fitWriter > `const` **fitWriter**: `BinaryWriter` Defined in: [fit/src/index.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/fit/src/index.ts#L25) --- --- url: /docs/api/core/variables/FLOOR_KCAL.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / FLOOR\_KCAL # Variable: FLOOR\_KCAL > `const` **FLOOR\_KCAL**: `1200` = `1200` Defined in: [packages/core/src/application/energy/goal-delta.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L27) Hard lower bound on planned daily intake (kcal); never go below. --- --- url: /docs/api/mcp/variables/FORMAT_REGISTRY.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / FORMAT\_REGISTRY # Variable: FORMAT\_REGISTRY > `const` **FORMAT\_REGISTRY**: `Record`<[`FileFormat`](../type-aliases/FileFormat.md), `FormatDescriptor`> Defined in: [utils/format-registry.ts:32](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/utils/format-registry.ts#L32) --- --- url: /docs/api/mcp/variables/formatSchema.md --- [**@kaiord/mcp**](../README.md) *** [@kaiord/mcp](../README.md) / formatSchema # Variable: formatSchema > `const` **formatSchema**: `ZodEnum`<{ `fit`: `"fit"`; `gcn`: `"gcn"`; `krd`: `"krd"`; `tcx`: `"tcx"`; `zwo`: `"zwo"`; }> Defined in: [types/tool-schemas.ts:5](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/mcp/src/types/tool-schemas.ts#L5) --- --- url: /docs/api/garmin/variables/garminReader.md --- [**@kaiord/garmin**](../README.md) *** [@kaiord/garmin](../README.md) / garminReader # Variable: garminReader > `const` **garminReader**: `TextReader` Defined in: [index.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/index.ts#L41) --- --- url: /docs/api/garmin/variables/garminWriter.md --- [**@kaiord/garmin**](../README.md) *** [@kaiord/garmin](../README.md) / garminWriter # Variable: garminWriter > `const` **garminWriter**: `TextWriter` Defined in: [index.ts:42](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/garmin/src/index.ts#L42) --- --- url: /docs/api/core/variables/goalTypeSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / goalTypeSchema # Variable: goalTypeSchema > `const` **goalTypeSchema**: `ZodEnum`<{ `fat_loss`: `"fat_loss"`; `maintain`: `"maintain"`; `muscle_gain`: `"muscle_gain"`; }> Defined in: [packages/core/src/domain/schemas/health/energy-goal.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/energy-goal.ts#L10) Body-composition objective driving the deficit/surplus engine. `fat_loss` and `muscle_gain` move weight toward `target_weight_kg`; `maintain` holds it. Weights are strictly positive kilograms and `target_date` is an ISO calendar date marking the planned horizon. --- --- url: /docs/api/core/variables/healthExtensionPayloadSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / healthExtensionPayloadSchema # Variable: healthExtensionPayloadSchema > `const` **healthExtensionPayloadSchema**: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `endTime`: `ZodISODateTime`; `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"sleep"`>; `restingHeartRate`: `ZodOptional`<`ZodNumber`>; `score`: `ZodOptional`<`ZodNumber`>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `stages`: `ZodArray`<`ZodObject`<{ `durationSeconds`: `ZodNumber`; `stage`: `ZodEnum`<{ `awake`: `"awake"`; `deep`: `"deep"`; `light`: `"light"`; `rem`: `"rem"`; }>; `startTime`: `ZodISODateTime`; }, `$strip`>>; `startTime`: `ZodISODateTime`; `totalDurationSeconds`: `ZodNumber`; `version`: `ZodString`; }, `$strip`>, `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"weight"`>; `measuredAt`: `ZodISODateTime`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `version`: `ZodString`; `weightKilograms`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"hrv"`>; `measuredAt`: `ZodISODateTime`; `measurementWindow`: `ZodEnum`<{ `overnight`: `"overnight"`; `spot`: `"spot"`; }>; `rMSSD`: `ZodNumber`; `score`: `ZodOptional`<`ZodNumber`>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `version`: `ZodString`; }, `$strip`>], `"kind"`> Defined in: [packages/core/src/domain/schemas/health/index.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/index.ts#L22) Tagged discriminated union of the health-metric payloads carried under `extensions.health.` in KRD v2.0: the six bidirectional FIT-core types plus the read-only wearable-session metrics `strain`, `vitals`, and `heart-rate-series`. The `kind` discriminator selects the variant; sub-schemas validate their own per-metric invariants. --- --- url: /docs/api/core/variables/healthFileTypes.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / healthFileTypes # Variable: healthFileTypes > `const` **healthFileTypes**: readonly \[`"sleep_record"`, `"weight_measurement"`, `"hrv_summary"`, `"daily_wellness"`, `"body_composition"`, `"stress_episode"`] Defined in: [packages/core/src/domain/schemas/file-type.ts:40](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/file-type.ts#L40) Health-metric types introduced in KRD v2.0. They MUST NOT carry `metadata.sport`; their payload lives in `extensions.health.`. --- --- url: /docs/api/core/variables/HEART_RATE_SERIES_BPM_TOLERANCE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / HEART\_RATE\_SERIES\_BPM\_TOLERANCE # Variable: HEART\_RATE\_SERIES\_BPM\_TOLERANCE > `const` **HEART\_RATE\_SERIES\_BPM\_TOLERANCE**: `0` = `0` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L25) --- --- url: /docs/api/core/variables/heartRateSeriesSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / heartRateSeriesSchema # Variable: heartRateSeriesSchema > `const` **heartRateSeriesSchema**: `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `intervalSeconds`: `ZodNumber`; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"heart-rate-series"`>; `samples`: `ZodArray`<`ZodNullable`<`ZodNumber`>>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `startTime`: `ZodISODateTime`; `version`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/heart-rate-series.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/heart-rate-series.ts#L16) Zod schema for `extensions.health.heart-rate-series` — a read-only, source-agnostic, compact uniform-interval daily heart-rate trace. Unlike the six FIT-core health types it is not mandated to round-trip through FIT, and unlike a recorded activity it is not tied to a workout session. `samples` is a fixed-cadence array of per-slot heart-rate readings starting at `startTime`, spaced `intervalSeconds` apart; `null` marks a missing slot (a sensor gap). A refinement requires at least one non-null sample — an all-gap series carries no information and is rejected. --- --- url: /docs/api/core/variables/HRV_TOLERANCE_MS.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / HRV\_TOLERANCE\_MS # Variable: HRV\_TOLERANCE\_MS > `const` **HRV\_TOLERANCE\_MS**: `1` = `1` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L11) --- --- url: /docs/api/core/variables/hrvSummarySchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / hrvSummarySchema # Variable: hrvSummarySchema > `const` **hrvSummarySchema**: `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"hrv"`>; `measuredAt`: `ZodISODateTime`; `measurementWindow`: `ZodEnum`<{ `overnight`: `"overnight"`; `spot`: `"spot"`; }>; `rMSSD`: `ZodNumber`; `score`: `ZodOptional`<`ZodNumber`>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `version`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/hrv.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/hrv.ts#L10) Zod schema for `extensions.health.hrv` — a heart-rate-variability summary captured either overnight (Garmin Body Battery / HRV Status) or as a spot measurement. --- --- url: /docs/api/core/variables/intensitySchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / intensitySchema # Variable: intensitySchema > `const` **intensitySchema**: `ZodEnum`<{ `active`: `"active"`; `cooldown`: `"cooldown"`; `interval`: `"interval"`; `other`: `"other"`; `recovery`: `"recovery"`; `rest`: `"rest"`; `warmup`: `"warmup"`; }> Defined in: [packages/core/src/domain/schemas/intensity.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/intensity.ts#L23) Zod schema for intensity level enumeration. Defines workout step intensity levels. ## Example ```typescript import { intensitySchema } from '@kaiord/core'; // Access enum values const warmup = intensitySchema.enum.warmup; const active = intensitySchema.enum.active; // Validate intensity const result = intensitySchema.safeParse('warmup'); if (result.success) { console.log('Valid intensity:', result.data); } ``` --- --- url: /docs/api/core/variables/KCAL_PER_KG_FAT.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / KCAL\_PER\_KG\_FAT # Variable: KCAL\_PER\_KG\_FAT > `const` **KCAL\_PER\_KG\_FAT**: `7700` = `7700` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L24) Energy density of body fat (kcal per kg) used for the balance identity. --- --- url: /docs/api/core/variables/knownUnitSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / knownUnitSchema # Variable: knownUnitSchema > `const` **knownUnitSchema**: `ZodObject`<{ `factorToCanonical`: `ZodNumber`; `offsetToCanonical`: `ZodOptional`<`ZodNumber`>; `unit`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/lab/lab-parameter.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter.ts#L11) A unit convertible to the canonical unit by an affine transform. --- --- url: /docs/api/core/variables/krdEventSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / krdEventSchema # Variable: krdEventSchema > `const` **krdEventSchema**: `ZodObject`<{ `data`: `ZodOptional`<`ZodNumber`>; `eventGroup`: `ZodOptional`<`ZodNumber`>; `eventType`: `ZodEnum`<{ `event_activity_start`: `"event_activity_start"`; `event_lap`: `"event_lap"`; `event_marker`: `"event_marker"`; `event_pause`: `"event_pause"`; `event_resume`: `"event_resume"`; `event_session_start`: `"event_session_start"`; `event_start`: `"event_start"`; `event_stop`: `"event_stop"`; `event_timer`: `"event_timer"`; `event_workout_step_change`: `"event_workout_step_change"`; }>; `message`: `ZodOptional`<`ZodString`>; `timestamp`: `ZodISODateTime`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/krd/event.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/event.ts#L19) Zod schema for KRD event object. Validates workout events (start, stop, pause, lap, etc.). ## Example ```typescript import { krdEventSchema } from '@kaiord/core'; const event = krdEventSchema.parse({ timestamp: '2025-01-15T10:30:00Z', eventType: 'event_lap', data: 1 }); ``` --- --- url: /docs/api/core/variables/krdExtensionsSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / krdExtensionsSchema # Variable: krdExtensionsSchema > `const` **krdExtensionsSchema**: `ZodObject`<{ `course`: `ZodOptional`<`ZodUnknown`>; `course_points`: `ZodOptional`<`ZodUnknown`>; `fit`: `ZodOptional`<`ZodUnknown`>; `health`: `ZodOptional`<`ZodObject`<{ `bodyComposition`: `ZodOptional`<`ZodObject`<{ `basalMetabolicRateKcal`: `ZodOptional`<`ZodNumber`>; `bmi`: `ZodOptional`<`ZodNumber`>; `bodyFatPercent`: `ZodOptional`<`ZodNumber`>; `bodyWaterPercent`: `ZodOptional`<`ZodNumber`>; `boneMassKilograms`: `ZodOptional`<`ZodNumber`>; `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"bodyComposition"`>; `leanMassKilograms`: `ZodOptional`<`ZodNumber`>; `measuredAt`: `ZodISODateTime`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `version`: `ZodString`; `visceralFatRating`: `ZodOptional`<`ZodNumber`>; }, `$strip`>>; `daily`: `ZodOptional`<`ZodObject`<{ `activeCalories`: `ZodNumber`; `date`: `ZodISODate`; `externalId`: `ZodOptional`<`ZodString`>; `floorsClimbed`: `ZodOptional`<`ZodNumber`>; `intensityMinutes`: `ZodObject`<{ `moderate`: `ZodNumber`; `vigorous`: `ZodNumber`; }, `$strip`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"daily"`>; `restingCalories`: `ZodNumber`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `steps`: `ZodNumber`; `version`: `ZodString`; }, `$strip`>>; `hrv`: `ZodOptional`<`ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"hrv"`>; `measuredAt`: `ZodISODateTime`; `measurementWindow`: `ZodEnum`<{ `overnight`: `"overnight"`; `spot`: `"spot"`; }>; `rMSSD`: `ZodNumber`; `score`: `ZodOptional`<`ZodNumber`>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `version`: `ZodString`; }, `$strip`>>; `sleep`: `ZodOptional`<`ZodObject`<{ `endTime`: `ZodISODateTime`; `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"sleep"`>; `restingHeartRate`: `ZodOptional`<`ZodNumber`>; `score`: `ZodOptional`<`ZodNumber`>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `stages`: `ZodArray`<`ZodObject`<{ `durationSeconds`: ...; `stage`: ...; `startTime`: ...; }, `$strip`>>; `startTime`: `ZodISODateTime`; `totalDurationSeconds`: `ZodNumber`; `version`: `ZodString`; }, `$strip`>>; `stress`: `ZodOptional`<`ZodObject`<{ `averageLevel`: `ZodNumber`; `endTime`: `ZodISODateTime`; `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"stress"`>; `peakLevel`: `ZodNumber`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `startTime`: `ZodISODateTime`; `version`: `ZodString`; }, `$strip`>>; `weight`: `ZodOptional`<`ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"weight"`>; `measuredAt`: `ZodISODateTime`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `version`: `ZodString`; `weightKilograms`: `ZodNumber`; }, `$strip`>>; }, `$catchall`<`ZodUnknown`>>>; `structured_workout`: `ZodOptional`<`ZodUnknown`>; }, `$catchall`<`ZodUnknown`>> Defined in: [packages/core/src/domain/schemas/krd/index.ts:39](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/index.ts#L39) Tagged shape for KRD `extensions`. Reserved namespaces are validated when present: * `structured_workout`, `fit`, `course`, `course_points` carry adapter- specific payloads whose shape is narrowed by downstream consumers (e.g. the SPA editor's `ui-workout` view). * `health.` payloads are validated against the `health-data` capability sub-schemas. `catchall(z.unknown())` keeps unknown adapter-defined namespaces round-trippable per the extension preservation rule in `openspec/specs/krd-format`. --- --- url: /docs/api/core/variables/krdLapSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / krdLapSchema # Variable: krdLapSchema > `const` **krdLapSchema**: `ZodObject`<{ `avgCadence`: `ZodOptional`<`ZodNumber`>; `avgHeartRate`: `ZodOptional`<`ZodNumber`>; `avgPower`: `ZodOptional`<`ZodNumber`>; `avgSpeed`: `ZodOptional`<`ZodNumber`>; `maxCadence`: `ZodOptional`<`ZodNumber`>; `maxHeartRate`: `ZodOptional`<`ZodNumber`>; `maxPower`: `ZodOptional`<`ZodNumber`>; `maxSpeed`: `ZodOptional`<`ZodNumber`>; `normalizedPower`: `ZodOptional`<`ZodNumber`>; `numLengths`: `ZodOptional`<`ZodNumber`>; `sport`: `ZodOptional`<`ZodEnum`<{ `alpine_skiing`: `"alpine_skiing"`; `american_football`: `"american_football"`; `archery`: `"archery"`; `baseball`: `"baseball"`; `basketball`: `"basketball"`; `boating`: `"boating"`; `boxing`: `"boxing"`; `canoeing`: `"canoeing"`; `cricket`: `"cricket"`; `cross_country_skiing`: `"cross_country_skiing"`; `cycling`: `"cycling"`; `dance`: `"dance"`; `disc_golf`: `"disc_golf"`; `diving`: `"diving"`; `driving`: `"driving"`; `e_biking`: `"e_biking"`; `fishing`: `"fishing"`; `fitness_equipment`: `"fitness_equipment"`; `floor_climbing`: `"floor_climbing"`; `flying`: `"flying"`; `generic`: `"generic"`; `geocaching`: `"geocaching"`; `golf`: `"golf"`; `grinding`: `"grinding"`; `hang_gliding`: `"hang_gliding"`; `hiit`: `"hiit"`; `hiking`: `"hiking"`; `hockey`: `"hockey"`; `horseback_riding`: `"horseback_riding"`; `hunting`: `"hunting"`; `ice_skating`: `"ice_skating"`; `inline_skating`: `"inline_skating"`; `jump_rope`: `"jump_rope"`; `jumpmaster`: `"jumpmaster"`; `kayaking`: `"kayaking"`; `kitesurfing`: `"kitesurfing"`; `lacrosse`: `"lacrosse"`; `meditation`: `"meditation"`; `mixed_martial_arts`: `"mixed_martial_arts"`; `mobility`: `"mobility"`; `motor_sports`: `"motor_sports"`; `motorcycling`: `"motorcycling"`; `mountaineering`: `"mountaineering"`; `multisport`: `"multisport"`; `paddling`: `"paddling"`; `para_sport`: `"para_sport"`; `pool_apnea`: `"pool_apnea"`; `racket`: `"racket"`; `rafting`: `"rafting"`; `rock_climbing`: `"rock_climbing"`; `rowing`: `"rowing"`; `rugby`: `"rugby"`; `running`: `"running"`; `sailing`: `"sailing"`; `shooting`: `"shooting"`; `sky_diving`: `"sky_diving"`; `snorkeling`: `"snorkeling"`; `snowboarding`: `"snowboarding"`; `snowmobiling`: `"snowmobiling"`; `snowshoeing`: `"snowshoeing"`; `soccer`: `"soccer"`; `stand_up_paddleboarding`: `"stand_up_paddleboarding"`; `surfing`: `"surfing"`; `swimming`: `"swimming"`; `tactical`: `"tactical"`; `team_sport`: `"team_sport"`; `tennis`: `"tennis"`; `training`: `"training"`; `transition`: `"transition"`; `video_gaming`: `"video_gaming"`; `volleyball`: `"volleyball"`; `wakeboarding`: `"wakeboarding"`; `wakesurfing`: `"wakesurfing"`; `walking`: `"walking"`; `water_skiing`: `"water_skiing"`; `water_sport`: `"water_sport"`; `water_tubing`: `"water_tubing"`; `wheelchair_push_run`: `"wheelchair_push_run"`; `wheelchair_push_walk`: `"wheelchair_push_walk"`; `windsurfing`: `"windsurfing"`; `winter_sport`: `"winter_sport"`; }>>; `startTime`: `ZodISODateTime`; `subSport`: `ZodOptional`<`ZodEnum`<{ `all`: `"all"`; `apnea_diving`: `"apnea_diving"`; `apnea_hunting`: `"apnea_hunting"`; `atv`: `"atv"`; `backcountry`: `"backcountry"`; `bike_to_run_transition`: `"bike_to_run_transition"`; `bmx`: `"bmx"`; `cardio_training`: `"cardio_training"`; `casual_walking`: `"casual_walking"`; `challenge`: `"challenge"`; `commuting`: `"commuting"`; `cyclocross`: `"cyclocross"`; `downhill`: `"downhill"`; `e_bike_fitness`: `"e_bike_fitness"`; `e_bike_mountain`: `"e_bike_mountain"`; `elliptical`: `"elliptical"`; `exercise`: `"exercise"`; `flexibility_training`: `"flexibility_training"`; `gauge_diving`: `"gauge_diving"`; `generic`: `"generic"`; `gravel_cycling`: `"gravel_cycling"`; `hand_cycling`: `"hand_cycling"`; `indoor_cycling`: `"indoor_cycling"`; `indoor_rowing`: `"indoor_rowing"`; `indoor_running`: `"indoor_running"`; `indoor_skiing`: `"indoor_skiing"`; `indoor_walking`: `"indoor_walking"`; `lap_swimming`: `"lap_swimming"`; `map`: `"map"`; `match`: `"match"`; `mixed_surface`: `"mixed_surface"`; `motocross`: `"motocross"`; `mountain`: `"mountain"`; `multi_gas_diving`: `"multi_gas_diving"`; `navigate`: `"navigate"`; `obstacle`: `"obstacle"`; `open_water`: `"open_water"`; `pilates`: `"pilates"`; `rc_drone`: `"rc_drone"`; `recumbent`: `"recumbent"`; `resort`: `"resort"`; `road`: `"road"`; `run_to_bike_transition`: `"run_to_bike_transition"`; `single_gas_diving`: `"single_gas_diving"`; `skate_skiing`: `"skate_skiing"`; `speed_walking`: `"speed_walking"`; `spin`: `"spin"`; `stair_climbing`: `"stair_climbing"`; `street`: `"street"`; `strength_training`: `"strength_training"`; `swim_to_bike_transition`: `"swim_to_bike_transition"`; `track`: `"track"`; `track_cycling`: `"track_cycling"`; `track_me`: `"track_me"`; `trail`: `"trail"`; `treadmill`: `"treadmill"`; `virtual_activity`: `"virtual_activity"`; `warm_up`: `"warm_up"`; `whitewater`: `"whitewater"`; `wingsuit`: `"wingsuit"`; `yoga`: `"yoga"`; }>>; `swimStroke`: `ZodOptional`<`ZodEnum`<{ `backstroke`: `"backstroke"`; `breaststroke`: `"breaststroke"`; `butterfly`: `"butterfly"`; `drill`: `"drill"`; `freestyle`: `"freestyle"`; `im`: `"im"`; `mixed`: `"mixed"`; }>>; `totalAscent`: `ZodOptional`<`ZodNumber`>; `totalCalories`: `ZodOptional`<`ZodNumber`>; `totalDescent`: `ZodOptional`<`ZodNumber`>; `totalDistance`: `ZodOptional`<`ZodNumber`>; `totalElapsedTime`: `ZodNumber`; `totalTimerTime`: `ZodOptional`<`ZodNumber`>; `trigger`: `ZodOptional`<`ZodEnum`<{ `distance`: `"distance"`; `fitness_equipment`: `"fitness_equipment"`; `manual`: `"manual"`; `position`: `"position"`; `session_end`: `"session_end"`; `time`: `"time"`; }>>; `workoutStepIndex`: `ZodOptional`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/krd/lap.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/lap.ts#L26) Zod schema for KRD lap object. Validates lap/interval data within a session. --- --- url: /docs/api/core/variables/krdLapTriggerSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / krdLapTriggerSchema # Variable: krdLapTriggerSchema > `const` **krdLapTriggerSchema**: `ZodEnum`<{ `distance`: `"distance"`; `fitness_equipment`: `"fitness_equipment"`; `manual`: `"manual"`; `position`: `"position"`; `session_end`: `"session_end"`; `time`: `"time"`; }> Defined in: [packages/core/src/domain/schemas/krd/lap.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/lap.ts#L10) KRD lap trigger types - what caused the lap to be recorded. --- --- url: /docs/api/core/variables/krdMetadataSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / krdMetadataSchema # Variable: krdMetadataSchema > `const` **krdMetadataSchema**: `ZodObject`<{ `created`: `ZodISODateTime`; `manufacturer`: `ZodOptional`<`ZodString`>; `product`: `ZodOptional`<`ZodString`>; `serialNumber`: `ZodOptional`<`ZodString`>; `sport`: `ZodOptional`<`ZodString`>; `subSport`: `ZodOptional`<`ZodString`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/krd/metadata.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/metadata.ts#L26) Zod schema for KRD metadata object. Validates file-level metadata including creation timestamp, device information, and sport type. ## Example ```typescript import { krdMetadataSchema } from '@kaiord/core'; // Validate metadata const result = krdMetadataSchema.safeParse({ created: '2025-01-15T10:30:00Z', manufacturer: 'garmin', product: 'fenix7', sport: 'running', subSport: 'trail' }); if (result.success) { console.log('Valid metadata:', result.data); } ``` --- --- url: /docs/api/core/variables/krdRecordSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / krdRecordSchema # Variable: krdRecordSchema > `const` **krdRecordSchema**: `ZodObject`<{ `altitude`: `ZodOptional`<`ZodNumber`>; `cadence`: `ZodOptional`<`ZodNumber`>; `distance`: `ZodOptional`<`ZodNumber`>; `heartRate`: `ZodOptional`<`ZodNumber`>; `position`: `ZodOptional`<`ZodObject`<{ `lat`: `ZodNumber`; `lon`: `ZodNumber`; }, `$strip`>>; `power`: `ZodOptional`<`ZodNumber`>; `speed`: `ZodOptional`<`ZodNumber`>; `stanceTime`: `ZodOptional`<`ZodNumber`>; `stepLength`: `ZodOptional`<`ZodNumber`>; `temperature`: `ZodOptional`<`ZodNumber`>; `timestamp`: `ZodISODateTime`; `verticalOscillation`: `ZodOptional`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/krd/record.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/record.ts#L21) Zod schema for KRD record object. Validates time-series data points (typically 1Hz or higher). ## Example ```typescript import { krdRecordSchema } from '@kaiord/core'; const record = krdRecordSchema.parse({ timestamp: '2025-01-15T10:30:00Z', position: { lat: 41.3851, lon: 2.1734 }, altitude: 12.5, heartRate: 145, power: 250 }); ``` --- --- url: /docs/api/core/variables/krdSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / krdSchema # Variable: krdSchema > `const` **krdSchema**: `ZodObject`<{ `events`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `data`: `ZodOptional`<`ZodNumber`>; `eventGroup`: `ZodOptional`<`ZodNumber`>; `eventType`: `ZodEnum`<{ `event_activity_start`: `"event_activity_start"`; `event_lap`: `"event_lap"`; `event_marker`: `"event_marker"`; `event_pause`: `"event_pause"`; `event_resume`: `"event_resume"`; `event_session_start`: `"event_session_start"`; `event_start`: `"event_start"`; `event_stop`: `"event_stop"`; `event_timer`: `"event_timer"`; `event_workout_step_change`: `"event_workout_step_change"`; }>; `message`: `ZodOptional`<`ZodString`>; `timestamp`: `ZodISODateTime`; }, `$strip`>>>; `extensions`: `ZodOptional`<`ZodObject`<{ `course`: `ZodOptional`<`ZodUnknown`>; `course_points`: `ZodOptional`<`ZodUnknown`>; `fit`: `ZodOptional`<`ZodUnknown`>; `health`: `ZodOptional`<`ZodObject`<{ `bodyComposition`: `ZodOptional`<`ZodObject`<{ `basalMetabolicRateKcal`: ...; `bmi`: ...; `bodyFatPercent`: ...; `bodyWaterPercent`: ...; `boneMassKilograms`: ...; `externalId`: ...; `kaiordRecordId`: ...; `kind`: ...; `leanMassKilograms`: ...; `measuredAt`: ...; `sourceBridgeId`: ...; `version`: ...; `visceralFatRating`: ...; }, `$strip`>>; `daily`: `ZodOptional`<`ZodObject`<{ `activeCalories`: ...; `date`: ...; `externalId`: ...; `floorsClimbed`: ...; `intensityMinutes`: ...; `kaiordRecordId`: ...; `kind`: ...; `restingCalories`: ...; `sourceBridgeId`: ...; `steps`: ...; `version`: ...; }, `$strip`>>; `hrv`: `ZodOptional`<`ZodObject`<{ `externalId`: ...; `kaiordRecordId`: ...; `kind`: ...; `measuredAt`: ...; `measurementWindow`: ...; `rMSSD`: ...; `score`: ...; `sourceBridgeId`: ...; `version`: ...; }, `$strip`>>; `sleep`: `ZodOptional`<`ZodObject`<{ `endTime`: ...; `externalId`: ...; `kaiordRecordId`: ...; `kind`: ...; `restingHeartRate`: ...; `score`: ...; `sourceBridgeId`: ...; `stages`: ...; `startTime`: ...; `totalDurationSeconds`: ...; `version`: ...; }, `$strip`>>; `stress`: `ZodOptional`<`ZodObject`<{ `averageLevel`: ...; `endTime`: ...; `externalId`: ...; `kaiordRecordId`: ...; `kind`: ...; `peakLevel`: ...; `sourceBridgeId`: ...; `startTime`: ...; `version`: ...; }, `$strip`>>; `weight`: `ZodOptional`<`ZodObject`<{ `externalId`: ...; `kaiordRecordId`: ...; `kind`: ...; `measuredAt`: ...; `sourceBridgeId`: ...; `version`: ...; `weightKilograms`: ...; }, `$strip`>>; }, `$catchall`<`ZodUnknown`>>>; `structured_workout`: `ZodOptional`<`ZodUnknown`>; }, `$catchall`<`ZodUnknown`>>>; `laps`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `avgCadence`: `ZodOptional`<`ZodNumber`>; `avgHeartRate`: `ZodOptional`<`ZodNumber`>; `avgPower`: `ZodOptional`<`ZodNumber`>; `avgSpeed`: `ZodOptional`<`ZodNumber`>; `maxCadence`: `ZodOptional`<`ZodNumber`>; `maxHeartRate`: `ZodOptional`<`ZodNumber`>; `maxPower`: `ZodOptional`<`ZodNumber`>; `maxSpeed`: `ZodOptional`<`ZodNumber`>; `normalizedPower`: `ZodOptional`<`ZodNumber`>; `numLengths`: `ZodOptional`<`ZodNumber`>; `sport`: `ZodOptional`<`ZodEnum`<{ `alpine_skiing`: `"alpine_skiing"`; `american_football`: `"american_football"`; `archery`: `"archery"`; `baseball`: `"baseball"`; `basketball`: `"basketball"`; `boating`: `"boating"`; `boxing`: `"boxing"`; `canoeing`: `"canoeing"`; `cricket`: `"cricket"`; `cross_country_skiing`: `"cross_country_skiing"`; `cycling`: `"cycling"`; `dance`: `"dance"`; `disc_golf`: `"disc_golf"`; `diving`: `"diving"`; `driving`: `"driving"`; `e_biking`: `"e_biking"`; `fishing`: `"fishing"`; `fitness_equipment`: `"fitness_equipment"`; `floor_climbing`: `"floor_climbing"`; `flying`: `"flying"`; `generic`: `"generic"`; `geocaching`: `"geocaching"`; `golf`: `"golf"`; `grinding`: `"grinding"`; `hang_gliding`: `"hang_gliding"`; `hiit`: `"hiit"`; `hiking`: `"hiking"`; `hockey`: `"hockey"`; `horseback_riding`: `"horseback_riding"`; `hunting`: `"hunting"`; `ice_skating`: `"ice_skating"`; `inline_skating`: `"inline_skating"`; `jump_rope`: `"jump_rope"`; `jumpmaster`: `"jumpmaster"`; `kayaking`: `"kayaking"`; `kitesurfing`: `"kitesurfing"`; `lacrosse`: `"lacrosse"`; `meditation`: `"meditation"`; `mixed_martial_arts`: `"mixed_martial_arts"`; `mobility`: `"mobility"`; `motor_sports`: `"motor_sports"`; `motorcycling`: `"motorcycling"`; `mountaineering`: `"mountaineering"`; `multisport`: `"multisport"`; `paddling`: `"paddling"`; `para_sport`: `"para_sport"`; `pool_apnea`: `"pool_apnea"`; `racket`: `"racket"`; `rafting`: `"rafting"`; `rock_climbing`: `"rock_climbing"`; `rowing`: `"rowing"`; `rugby`: `"rugby"`; `running`: `"running"`; `sailing`: `"sailing"`; `shooting`: `"shooting"`; `sky_diving`: `"sky_diving"`; `snorkeling`: `"snorkeling"`; `snowboarding`: `"snowboarding"`; `snowmobiling`: `"snowmobiling"`; `snowshoeing`: `"snowshoeing"`; `soccer`: `"soccer"`; `stand_up_paddleboarding`: `"stand_up_paddleboarding"`; `surfing`: `"surfing"`; `swimming`: `"swimming"`; `tactical`: `"tactical"`; `team_sport`: `"team_sport"`; `tennis`: `"tennis"`; `training`: `"training"`; `transition`: `"transition"`; `video_gaming`: `"video_gaming"`; `volleyball`: `"volleyball"`; `wakeboarding`: `"wakeboarding"`; `wakesurfing`: `"wakesurfing"`; `walking`: `"walking"`; `water_skiing`: `"water_skiing"`; `water_sport`: `"water_sport"`; `water_tubing`: `"water_tubing"`; `wheelchair_push_run`: `"wheelchair_push_run"`; `wheelchair_push_walk`: `"wheelchair_push_walk"`; `windsurfing`: `"windsurfing"`; `winter_sport`: `"winter_sport"`; }>>; `startTime`: `ZodISODateTime`; `subSport`: `ZodOptional`<`ZodEnum`<{ `all`: `"all"`; `apnea_diving`: `"apnea_diving"`; `apnea_hunting`: `"apnea_hunting"`; `atv`: `"atv"`; `backcountry`: `"backcountry"`; `bike_to_run_transition`: `"bike_to_run_transition"`; `bmx`: `"bmx"`; `cardio_training`: `"cardio_training"`; `casual_walking`: `"casual_walking"`; `challenge`: `"challenge"`; `commuting`: `"commuting"`; `cyclocross`: `"cyclocross"`; `downhill`: `"downhill"`; `e_bike_fitness`: `"e_bike_fitness"`; `e_bike_mountain`: `"e_bike_mountain"`; `elliptical`: `"elliptical"`; `exercise`: `"exercise"`; `flexibility_training`: `"flexibility_training"`; `gauge_diving`: `"gauge_diving"`; `generic`: `"generic"`; `gravel_cycling`: `"gravel_cycling"`; `hand_cycling`: `"hand_cycling"`; `indoor_cycling`: `"indoor_cycling"`; `indoor_rowing`: `"indoor_rowing"`; `indoor_running`: `"indoor_running"`; `indoor_skiing`: `"indoor_skiing"`; `indoor_walking`: `"indoor_walking"`; `lap_swimming`: `"lap_swimming"`; `map`: `"map"`; `match`: `"match"`; `mixed_surface`: `"mixed_surface"`; `motocross`: `"motocross"`; `mountain`: `"mountain"`; `multi_gas_diving`: `"multi_gas_diving"`; `navigate`: `"navigate"`; `obstacle`: `"obstacle"`; `open_water`: `"open_water"`; `pilates`: `"pilates"`; `rc_drone`: `"rc_drone"`; `recumbent`: `"recumbent"`; `resort`: `"resort"`; `road`: `"road"`; `run_to_bike_transition`: `"run_to_bike_transition"`; `single_gas_diving`: `"single_gas_diving"`; `skate_skiing`: `"skate_skiing"`; `speed_walking`: `"speed_walking"`; `spin`: `"spin"`; `stair_climbing`: `"stair_climbing"`; `street`: `"street"`; `strength_training`: `"strength_training"`; `swim_to_bike_transition`: `"swim_to_bike_transition"`; `track`: `"track"`; `track_cycling`: `"track_cycling"`; `track_me`: `"track_me"`; `trail`: `"trail"`; `treadmill`: `"treadmill"`; `virtual_activity`: `"virtual_activity"`; `warm_up`: `"warm_up"`; `whitewater`: `"whitewater"`; `wingsuit`: `"wingsuit"`; `yoga`: `"yoga"`; }>>; `swimStroke`: `ZodOptional`<`ZodEnum`<{ `backstroke`: `"backstroke"`; `breaststroke`: `"breaststroke"`; `butterfly`: `"butterfly"`; `drill`: `"drill"`; `freestyle`: `"freestyle"`; `im`: `"im"`; `mixed`: `"mixed"`; }>>; `totalAscent`: `ZodOptional`<`ZodNumber`>; `totalCalories`: `ZodOptional`<`ZodNumber`>; `totalDescent`: `ZodOptional`<`ZodNumber`>; `totalDistance`: `ZodOptional`<`ZodNumber`>; `totalElapsedTime`: `ZodNumber`; `totalTimerTime`: `ZodOptional`<`ZodNumber`>; `trigger`: `ZodOptional`<`ZodEnum`<{ `distance`: `"distance"`; `fitness_equipment`: `"fitness_equipment"`; `manual`: `"manual"`; `position`: `"position"`; `session_end`: `"session_end"`; `time`: `"time"`; }>>; `workoutStepIndex`: `ZodOptional`<`ZodNumber`>; }, `$strip`>>>; `metadata`: `ZodObject`<{ `created`: `ZodISODateTime`; `manufacturer`: `ZodOptional`<`ZodString`>; `product`: `ZodOptional`<`ZodString`>; `serialNumber`: `ZodOptional`<`ZodString`>; `sport`: `ZodOptional`<`ZodString`>; `subSport`: `ZodOptional`<`ZodString`>; }, `$strip`>; `records`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `altitude`: `ZodOptional`<`ZodNumber`>; `cadence`: `ZodOptional`<`ZodNumber`>; `distance`: `ZodOptional`<`ZodNumber`>; `heartRate`: `ZodOptional`<`ZodNumber`>; `position`: `ZodOptional`<`ZodObject`<{ `lat`: `ZodNumber`; `lon`: `ZodNumber`; }, `$strip`>>; `power`: `ZodOptional`<`ZodNumber`>; `speed`: `ZodOptional`<`ZodNumber`>; `stanceTime`: `ZodOptional`<`ZodNumber`>; `stepLength`: `ZodOptional`<`ZodNumber`>; `temperature`: `ZodOptional`<`ZodNumber`>; `timestamp`: `ZodISODateTime`; `verticalOscillation`: `ZodOptional`<`ZodNumber`>; }, `$strip`>>>; `sessions`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `avgCadence`: `ZodOptional`<`ZodNumber`>; `avgHeartRate`: `ZodOptional`<`ZodNumber`>; `avgPower`: `ZodOptional`<`ZodNumber`>; `avgSpeed`: `ZodOptional`<`ZodNumber`>; `intensityFactor`: `ZodOptional`<`ZodNumber`>; `maxCadence`: `ZodOptional`<`ZodNumber`>; `maxHeartRate`: `ZodOptional`<`ZodNumber`>; `maxPower`: `ZodOptional`<`ZodNumber`>; `maxSpeed`: `ZodOptional`<`ZodNumber`>; `normalizedPower`: `ZodOptional`<`ZodNumber`>; `sport`: `ZodString`; `startTime`: `ZodISODateTime`; `subSport`: `ZodOptional`<`ZodString`>; `totalAscent`: `ZodOptional`<`ZodNumber`>; `totalCalories`: `ZodOptional`<`ZodNumber`>; `totalDescent`: `ZodOptional`<`ZodNumber`>; `totalDistance`: `ZodOptional`<`ZodNumber`>; `totalElapsedTime`: `ZodNumber`; `totalTimerTime`: `ZodOptional`<`ZodNumber`>; `trainingStressScore`: `ZodOptional`<`ZodNumber`>; }, `$strip`>>>; `type`: `ZodEnum`<{ `body_composition`: `"body_composition"`; `course`: `"course"`; `daily_wellness`: `"daily_wellness"`; `hrv_summary`: `"hrv_summary"`; `recorded_activity`: `"recorded_activity"`; `sleep_record`: `"sleep_record"`; `stress_episode`: `"stress_episode"`; `structured_workout`: `"structured_workout"`; `weight_measurement`: `"weight_measurement"`; }>; `version`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/krd/index.ts:91](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/index.ts#L91) Zod schema for the complete KRD (Kaiord Representation Definition) format. KRD is a JSON-based canonical format for structured workout, recorded activity, course, and (as of v2.0) health-domain data. The `type` field is the top-level discriminator and gates the conditional `metadata.sport` invariant: * For `structured_workout`, `recorded_activity`, `course` — `metadata.sport` MUST be a non-empty string (preserved from v1.x). * For the six health types — `metadata.sport` MUST be absent or empty. MIME type: `application/vnd.kaiord+json` ## Example ```typescript import { krdSchema } from '@kaiord/core'; const krd = krdSchema.parse({ version: '2.0', type: 'sleep_record', metadata: { created: '2026-05-22T07:00:00Z' }, extensions: { health: { sleep: { ... } } } }); ``` --- --- url: /docs/api/core/variables/krdSessionSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / krdSessionSchema # Variable: krdSessionSchema > `const` **krdSessionSchema**: `ZodObject`<{ `avgCadence`: `ZodOptional`<`ZodNumber`>; `avgHeartRate`: `ZodOptional`<`ZodNumber`>; `avgPower`: `ZodOptional`<`ZodNumber`>; `avgSpeed`: `ZodOptional`<`ZodNumber`>; `intensityFactor`: `ZodOptional`<`ZodNumber`>; `maxCadence`: `ZodOptional`<`ZodNumber`>; `maxHeartRate`: `ZodOptional`<`ZodNumber`>; `maxPower`: `ZodOptional`<`ZodNumber`>; `maxSpeed`: `ZodOptional`<`ZodNumber`>; `normalizedPower`: `ZodOptional`<`ZodNumber`>; `sport`: `ZodString`; `startTime`: `ZodISODateTime`; `subSport`: `ZodOptional`<`ZodString`>; `totalAscent`: `ZodOptional`<`ZodNumber`>; `totalCalories`: `ZodOptional`<`ZodNumber`>; `totalDescent`: `ZodOptional`<`ZodNumber`>; `totalDistance`: `ZodOptional`<`ZodNumber`>; `totalElapsedTime`: `ZodNumber`; `totalTimerTime`: `ZodOptional`<`ZodNumber`>; `trainingStressScore`: `ZodOptional`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/krd/session.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/krd/session.ts#L22) Zod schema for KRD session object. Validates training session data including timing, distance, and performance metrics. ## Example ```typescript import { krdSessionSchema } from '@kaiord/core'; const session = krdSessionSchema.parse({ startTime: '2025-01-15T10:30:00Z', totalElapsedTime: 3600, totalDistance: 10000, sport: 'running', avgHeartRate: 145, avgPower: 250 }); ``` --- --- url: /docs/api/core/variables/LAB_PARAMETER_CATALOG.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / LAB\_PARAMETER\_CATALOG # Variable: LAB\_PARAMETER\_CATALOG > `const` **LAB\_PARAMETER\_CATALOG**: readonly [`LabParameter`](../type-aliases/LabParameter.md)\[] Defined in: [packages/core/src/domain/lab/lab-parameter-catalog.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter-catalog.ts#L19) Immutable reference catalog of the core lab parameters. Ranges and factors are orientative fallbacks — the user's report range is the authority. The long tail is modelled with free `custom:` parameters (no conversion, no fallback range) rather than extending this list. --- --- url: /docs/api/core/variables/labFlagSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / labFlagSchema # Variable: labFlagSchema > `const` **labFlagSchema**: `ZodEnum`<{ `high`: `"high"`; `in`: `"in"`; `low`: `"low"`; `unknown`: `"unknown"`; }> Defined in: [packages/core/src/domain/lab/lab-flag.ts:6](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-flag.ts#L6) Out-of-range flag for a measured value, always evaluated in canonical unit. --- --- url: /docs/api/core/variables/labPanelSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / labPanelSchema # Variable: labPanelSchema > `const` **labPanelSchema**: `ZodEnum`<{ `biochemistry`: `"biochemistry"`; `hemogram`: `"hemogram"`; `hepatic`: `"hepatic"`; `hormones`: `"hormones"`; `ions`: `"ions"`; `iron`: `"iron"`; `lipids`: `"lipids"`; `sports`: `"sports"`; `thyroid`: `"thyroid"`; `vitamins`: `"vitamins"`; }> Defined in: [packages/core/src/domain/lab/lab-parameter.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter.ts#L19) Panel/group a core parameter belongs to. --- --- url: /docs/api/core/variables/labParameterSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / labParameterSchema # Variable: labParameterSchema > `const` **labParameterSchema**: `ZodObject`<{ `canonicalRefHigh`: `ZodOptional`<`ZodNumber`>; `canonicalRefLow`: `ZodOptional`<`ZodNumber`>; `canonicalUnit`: `ZodString`; `key`: `ZodString`; `knownUnits`: `ZodOptional`<`ZodArray`<`ZodObject`<{ `factorToCanonical`: `ZodNumber`; `offsetToCanonical`: `ZodOptional`<`ZodNumber`>; `unit`: `ZodString`; }, `$strip`>>>; `loinc`: `ZodOptional`<`ZodString`>; `panel`: `ZodEnum`<{ `biochemistry`: `"biochemistry"`; `hemogram`: `"hemogram"`; `hepatic`: `"hepatic"`; `hormones`: `"hormones"`; `ions`: `"ions"`; `iron`: `"iron"`; `lipids`: `"lipids"`; `sports`: `"sports"`; `thyroid`: `"thyroid"`; `vitamins`: `"vitamins"`; }>; `refBySex`: `ZodOptional`<`ZodObject`<{ `female`: `ZodObject`<{ `high`: `ZodOptional`<`ZodNumber`>; `low`: `ZodOptional`<`ZodNumber`>; }, `$strip`>; `male`: `ZodObject`<{ `high`: `ZodOptional`<`ZodNumber`>; `low`: `ZodOptional`<`ZodNumber`>; }, `$strip`>; }, `$strip`>>; }, `$strip`> Defined in: [packages/core/src/domain/lab/lab-parameter.ts:34](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter.ts#L34) Static reference-data descriptor for a core lab parameter. --- --- url: /docs/api/core/variables/labProvenanceSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / labProvenanceSchema # Variable: labProvenanceSchema > `const` **labProvenanceSchema**: `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `source`: `ZodEnum`<{ `ai-extracted`: `"ai-extracted"`; `manual`: `"manual"`; `whoop`: `"whoop"`; }>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; }, `$strip`> Defined in: [packages/core/src/domain/lab/lab-provenance.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-provenance.ts#L9) Write provenance for lab records. The `sourceBridgeId` + `externalId` columns mirror the health-record provenance shape so a future promotion of labs into the Data Hub (a real labs bridge in V2+) is additive rather than a migration. V1 always writes `source: "manual"`. --- --- url: /docs/api/core/variables/labRefRangeSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / labRefRangeSchema # Variable: labRefRangeSchema > `const` **labRefRangeSchema**: `ZodObject`<{ `high`: `ZodOptional`<`ZodNumber`>; `low`: `ZodOptional`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/lab/lab-parameter.ts:4](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-parameter.ts#L4) Reference-range bounds expressed in a parameter's canonical unit. --- --- url: /docs/api/core/variables/labRefSourceSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / labRefSourceSchema # Variable: labRefSourceSchema > `const` **labRefSourceSchema**: `ZodEnum`<{ `catalog`: `"catalog"`; `none`: `"none"`; `report`: `"report"`; }> Defined in: [packages/core/src/domain/lab/lab-value.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-value.ts#L7) Where the effective reference range came from. --- --- url: /docs/api/core/variables/labReportSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / labReportSchema # Variable: labReportSchema > `const` **labReportSchema**: `ZodObject`<{ `date`: `ZodISODate`; `drawTime`: `ZodOptional`<`ZodString`>; `fasting`: `ZodOptional`<`ZodBoolean`>; `id`: `ZodString`; `labName`: `ZodOptional`<`ZodString`>; `notes`: `ZodOptional`<`ZodString`>; `profileId`: `ZodString`; `provenance`: `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `source`: `ZodEnum`<{ `ai-extracted`: `"ai-extracted"`; `manual`: `"manual"`; `whoop`: `"whoop"`; }>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; }, `$strip`>; }, `$strip`> Defined in: [packages/core/src/domain/lab/lab-report.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-report.ts#L11) A lab report — one dated analysis (draw) that groups N `LabValue` measurements. Flat shape (direct fields, no `krd` wrapper) following the `activity` principle of an own shape over generic infrastructure. Context fields (fasting / drawTime / notes) are optional per-report annotations. --- --- url: /docs/api/core/variables/labValueSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / labValueSchema # Variable: labValueSchema > `const` **labValueSchema**: `ZodObject`<{ `date`: `ZodISODate`; `flag`: `ZodEnum`<{ `high`: `"high"`; `in`: `"in"`; `low`: `"low"`; `unknown`: `"unknown"`; }>; `id`: `ZodString`; `parameterKey`: `ZodString`; `profileId`: `ZodString`; `provenance`: `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `source`: `ZodEnum`<{ `ai-extracted`: `"ai-extracted"`; `manual`: `"manual"`; `whoop`: `"whoop"`; }>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; }, `$strip`>; `refHigh`: `ZodOptional`<`ZodNumber`>; `refHighCanonical`: `ZodOptional`<`ZodNumber`>; `refLow`: `ZodOptional`<`ZodNumber`>; `refLowCanonical`: `ZodOptional`<`ZodNumber`>; `refSource`: `ZodEnum`<{ `catalog`: `"catalog"`; `none`: `"none"`; `report`: `"report"`; }>; `refText`: `ZodOptional`<`ZodString`>; `reportId`: `ZodString`; `unitCanonical`: `ZodString`; `unitRaw`: `ZodString`; `valueCanonical`: `ZodNumber`; `valueRaw`: `ZodNumber`; }, `$strip`> Defined in: [packages/core/src/domain/lab/lab-value.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/lab/lab-value.ts#L17) A single measured parameter belonging to a `LabReport`. `date` and `profileId` are denormalized from the report so the per-parameter series and the latest-per-parameter query are served straight from `labValues`. Values and reference bounds are stored both as entered (`*Raw`) and in the parameter's canonical unit (`*Canonical`) for comparable plotting. --- --- url: /docs/api/core/variables/lengthUnitSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / lengthUnitSchema # Variable: lengthUnitSchema > `const` **lengthUnitSchema**: `ZodEnum`<{ `meters`: `"meters"`; `yards`: `"yards"`; }> Defined in: [packages/core/src/domain/schemas/length-unit.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/length-unit.ts#L3) --- --- url: /docs/api/core/variables/macroNutrientsSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / macroNutrientsSchema # Variable: macroNutrientsSchema > `const` **macroNutrientsSchema**: `ZodObject`<{ `carb_g`: `ZodNumber`; `fat_g`: `ZodNumber`; `kcal`: `ZodNumber`; `protein_g`: `ZodNumber`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/nutrition.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/nutrition.ts#L11) Macro-nutrient value object: an energy total (`kcal`) plus its protein/carbohydrate/fat breakdown in grams. Used both for logged intake actuals and for derived macro targets, so it carries no `kind` discriminator and is not a health-extension payload — it is a reusable building block embedded in higher-level energy view-models. --- --- url: /docs/api/core/variables/MANAGED_DATA_REGISTRY.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / MANAGED\_DATA\_REGISTRY # Variable: MANAGED\_DATA\_REGISTRY > `const` **MANAGED\_DATA\_REGISTRY**: `Record`<[`ManagedDataType`](../type-aliases/ManagedDataType.md), [`ManagedDataRegistryEntry`](../type-aliases/ManagedDataRegistryEntry.md)> Defined in: [packages/core/src/domain/managed-data-type-registry.ts:28](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type-registry.ts#L28) --- --- url: /docs/api/core/variables/managedDataTypes.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / managedDataTypes # Variable: managedDataTypes > `const` **managedDataTypes**: readonly \[`"workout"`, `"planned-session"`, `"activity"`, `"training-zones"`, `"weight"`, `"sleep"`, `"hrv"`, `"daily-wellness"`, `"body-composition"`, `"stress"`, `"strain"`, `"vitals"`, `"heart-rate-series"`] Defined in: [packages/core/src/domain/managed-data-type.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/managed-data-type.ts#L9) --- --- url: /docs/api/core/variables/mealSlotSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / mealSlotSchema # Variable: mealSlotSchema > `const` **mealSlotSchema**: `ZodEnum`<{ `breakfast`: `"breakfast"`; `dinner`: `"dinner"`; `lunch`: `"lunch"`; `snack`: `"snack"`; }> Defined in: [packages/core/src/domain/schemas/health/nutrition.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/nutrition.ts#L25) Time-of-day slot a manual intake entry belongs to. Optional context on an entry; the four canonical slots cover the common logging cadence without a free-form bucket. --- --- url: /docs/api/core/variables/MET_TABLE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / MET\_TABLE # Variable: MET\_TABLE > `const` **MET\_TABLE**: `Partial`<`Record`<[`Sport`](../type-aliases/Sport.md), `number`>> Defined in: [packages/core/src/application/energy/met-table.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/met-table.ts#L26) Standard MET values per sport. Partial by design: unmapped sports resolve to [DEFAULT\_MET](DEFAULT_MET.md). Extend by adding the sport key with its reference MET. --- --- url: /docs/api/core/variables/MIN_ADAPTIVE_DAYS.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / MIN\_ADAPTIVE\_DAYS # Variable: MIN\_ADAPTIVE\_DAYS > `const` **MIN\_ADAPTIVE\_DAYS**: `14` = `14` Defined in: [packages/core/src/application/energy/adaptive-tdee.ts:27](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/adaptive-tdee.ts#L27) Minimum paired-history days before adaptive maintenance activates. --- --- url: /docs/api/core/variables/MUSCLE_SURPLUS_CAP.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / MUSCLE\_SURPLUS\_CAP # Variable: MUSCLE\_SURPLUS\_CAP > `const` **MUSCLE\_SURPLUS\_CAP**: `400` = `400` Defined in: [packages/core/src/application/energy/goal-delta.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/goal-delta.ts#L29) Conservative muscle-gain surplus cap (kcal/day, ~0.5 kg/month). --- --- url: /docs/api/core/variables/NEAT_FACTOR.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / NEAT\_FACTOR # Variable: NEAT\_FACTOR > `const` **NEAT\_FACTOR**: `Record`<[`ActivityLevel`](../type-aliases/ActivityLevel.md), `number`> Defined in: [packages/core/src/application/energy/activity-factor.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/application/energy/activity-factor.ts#L22) NEAT-only multipliers per activity level (workout kcal added separately). --- --- url: /docs/api/core/variables/plannedSessionSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / plannedSessionSchema # Variable: plannedSessionSchema > `const` **plannedSessionSchema**: `ZodObject`<{ `coach_notes`: `ZodOptional`<`ZodString`>; `completion_percent`: `ZodOptional`<`ZodNumber`>; `date`: `ZodISODate`; `duration_seconds`: `ZodOptional`<`ZodNumber`>; `intensity`: `ZodOptional`<`ZodNumber`>; `kind`: `ZodLiteral`<`"planned_session"`>; `source`: `ZodString`; `source_id`: `ZodString`; `sport`: `ZodString`; `status`: `ZodEnum`<{ `completed`: `"completed"`; `pending`: `"pending"`; `skipped`: `"skipped"`; }>; `title`: `ZodString`; `workload`: `ZodOptional`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/planned-session.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/planned-session.ts#L26) Zod schema for a `planned-session` — a single coach-prescribed session (what Train2Go delivers per calendar day). Replaces the decorative `training-plan` managed type: the routable unit is the individual session; the "plan" is the collection of sessions on the calendar. Snake\_case per the domain schema convention. Fields are derived from the persisted `CoachingActivityRecord` so a coaching activity maps to a planned session without loss: external identity, date, sport, prescribed load/intensity, coach notes, and workflow status. --- --- url: /docs/api/core/variables/plannedSessionStatusSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / plannedSessionStatusSchema # Variable: plannedSessionStatusSchema > `const` **plannedSessionStatusSchema**: `ZodEnum`<{ `completed`: `"completed"`; `pending`: `"pending"`; `skipped`: `"skipped"`; }> Defined in: [packages/core/src/domain/schemas/planned-session.ts:7](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/planned-session.ts#L7) Coach-owned workflow state for a planned session. Mirrors the discrete lifecycle carried on the persisted coaching record. --- --- url: /docs/api/core/variables/POWER_ZONE_PERCENT_FTP.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / POWER\_ZONE\_PERCENT\_FTP # Variable: POWER\_ZONE\_PERCENT\_FTP > `const` **POWER\_ZONE\_PERCENT\_FTP**: `Readonly`<`Record`<[`PowerZone`](../type-aliases/PowerZone.md), `number`>> Defined in: [packages/core/src/domain/zones/power-zones.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/zones/power-zones.ts#L22) --- --- url: /docs/api/core/variables/POWER_ZONES.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / POWER\_ZONES # Variable: POWER\_ZONES > `const` **POWER\_ZONES**: readonly [`PowerZone`](../type-aliases/PowerZone.md)\[] Defined in: [packages/core/src/domain/zones/power-zones.ts:20](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/zones/power-zones.ts#L20) --- --- url: /docs/api/core/variables/profileSnapshotSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / profileSnapshotSchema # Variable: profileSnapshotSchema > `const` **profileSnapshotSchema**: `ZodPipe`<`ZodUnknown`, `ZodObject`<{ `activeSport`: `ZodOptional`<`ZodEnum`<{ `cycling`: `"cycling"`; `running`: `"running"`; `swimming`: `"swimming"`; }>>; `generatedAt`: `ZodISODateTime`; `heartRate`: `ZodDefault`<`ZodObject`<{ `lthr`: `ZodOptional`<`ZodNumber`>; `max`: `ZodOptional`<`ZodNumber`>; }, `$strict`>>; `profile`: `ZodObject`<{ `bodyWeight`: `ZodOptional`<`ZodNumber`>; `name`: `ZodString`; }, `$strict`>; `schemaVersion`: `ZodLiteral`<`1`>; `thresholds`: `ZodDefault`<`ZodObject`<{ `cycling`: `ZodOptional`<`ZodObject`<{ `ftp`: `ZodOptional`<`ZodNumber`>; }, `$strict`>>; `running`: `ZodOptional`<`ZodObject`<{ `lthr`: `ZodOptional`<`ZodNumber`>; `thresholdPaceSecPerKm`: `ZodOptional`<`ZodNumber`>; }, `$strict`>>; `swimming`: `ZodOptional`<`ZodObject`<{ `cssPaceSecPer100m`: `ZodOptional`<`ZodNumber`>; }, `$strict`>>; }, `$strict`>>; }, `$strict`>> Defined in: [packages/core/src/protocol/profile-snapshot.ts:77](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/protocol/profile-snapshot.ts#L77) --- --- url: /docs/api/core/variables/repetitionBlockSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / repetitionBlockSchema # Variable: repetitionBlockSchema > `const` **repetitionBlockSchema**: `ZodObject`<{ `id`: `ZodOptional`<`ZodString`>; `repeatCount`: `ZodNumber`; `steps`: `ZodArray`<`ZodObject`<{ `duration`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `seconds`: `ZodNumber`; `type`: `ZodLiteral`<`"time"`>; }, `$strip`>, `ZodObject`<{ `meters`: `ZodNumber`; `type`: `ZodLiteral`<`"distance"`>; }, `$strip`>, `ZodObject`<{ `bpm`: `ZodNumber`; `type`: `ZodLiteral`<`"heart_rate_less_than"`>; }, `$strip`>, `ZodObject`<{ `bpm`: `ZodNumber`; `repeatFrom`: `ZodNumber`; `type`: `ZodLiteral`<`"repeat_until_heart_rate_greater_than"`>; }, `$strip`>], `"type"`>; `durationType`: `ZodEnum`<{ `calories`: `"calories"`; `distance`: `"distance"`; `heart_rate_less_than`: `"heart_rate_less_than"`; `open`: `"open"`; `power_greater_than`: `"power_greater_than"`; `power_less_than`: `"power_less_than"`; `repeat_until_calories`: `"repeat_until_calories"`; `repeat_until_distance`: `"repeat_until_distance"`; `repeat_until_heart_rate_greater_than`: `"repeat_until_heart_rate_greater_than"`; `repeat_until_heart_rate_less_than`: `"repeat_until_heart_rate_less_than"`; `repeat_until_power_greater_than`: `"repeat_until_power_greater_than"`; `repeat_until_power_less_than`: `"repeat_until_power_less_than"`; `repeat_until_time`: `"repeat_until_time"`; `time`: `"time"`; }>; `equipment`: `ZodOptional`<`ZodEnum`<{ `none`: `"none"`; `swim_fins`: `"swim_fins"`; `swim_kickboard`: `"swim_kickboard"`; `swim_paddles`: `"swim_paddles"`; `swim_pull_buoy`: `"swim_pull_buoy"`; `swim_snorkel`: `"swim_snorkel"`; }>>; `extensions`: `ZodOptional`<`ZodRecord`<`ZodString`, `ZodUnknown`>>; `intensity`: `ZodOptional`<`ZodEnum`<{ `active`: `"active"`; `cooldown`: `"cooldown"`; `interval`: `"interval"`; `other`: `"other"`; `recovery`: `"recovery"`; `rest`: `"rest"`; `warmup`: `"warmup"`; }>>; `name`: `ZodOptional`<`ZodString`>; `notes`: `ZodOptional`<`ZodString`>; `stepIndex`: `ZodNumber`; `target`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `type`: `ZodLiteral`<`"power"`>; `value`: `ZodDiscriminatedUnion`<\[..., ..., ..., ...], `"unit"`>; }, `$strip`>, `ZodObject`<{ `type`: `ZodLiteral`<`"heart_rate"`>; `value`: `ZodDiscriminatedUnion`<\[..., ..., ..., ...], `"unit"`>; }, `$strip`>, `ZodObject`<{ `type`: `ZodLiteral`<`"cadence"`>; `value`: `ZodDiscriminatedUnion`<\[..., ...], `"unit"`>; }, `$strip`>], `"type"`>; `targetType`: `ZodEnum`<{ `cadence`: `"cadence"`; `heart_rate`: `"heart_rate"`; `open`: `"open"`; `pace`: `"pace"`; `power`: `"power"`; `stroke_type`: `"stroke_type"`; }>; }, `$strip`>>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/workout.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/workout.ts#L15) Zod schema for a repetition block. Validates a group of workout steps that repeat multiple times. --- --- url: /docs/api/core/variables/SLEEP_STAGE_TOLERANCE_SECONDS.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SLEEP\_STAGE\_TOLERANCE\_SECONDS # Variable: SLEEP\_STAGE\_TOLERANCE\_SECONDS > `const` **SLEEP\_STAGE\_TOLERANCE\_SECONDS**: `60` = `60` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:8](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L8) Per-metric round-trip tolerances for the six health KRD types. Centralised so test suites import them rather than hardcoding values per fixture. See the `health-data` capability spec for rationale. --- --- url: /docs/api/core/variables/SLEEP_TOTAL_DURATION_TOLERANCE_SECONDS.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SLEEP\_TOTAL\_DURATION\_TOLERANCE\_SECONDS # Variable: SLEEP\_TOTAL\_DURATION\_TOLERANCE\_SECONDS > `const` **SLEEP\_TOTAL\_DURATION\_TOLERANCE\_SECONDS**: `60` = `60` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:9](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L9) --- --- url: /docs/api/core/variables/sleepRecordSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / sleepRecordSchema # Variable: sleepRecordSchema > `const` **sleepRecordSchema**: `ZodObject`<{ `endTime`: `ZodISODateTime`; `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"sleep"`>; `restingHeartRate`: `ZodOptional`<`ZodNumber`>; `score`: `ZodOptional`<`ZodNumber`>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `stages`: `ZodArray`<`ZodObject`<{ `durationSeconds`: `ZodNumber`; `stage`: `ZodEnum`<{ `awake`: `"awake"`; `deep`: `"deep"`; `light`: `"light"`; `rem`: `"rem"`; }>; `startTime`: `ZodISODateTime`; }, `$strip`>>; `startTime`: `ZodISODateTime`; `totalDurationSeconds`: `ZodNumber`; `version`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/sleep.ts:30](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/sleep.ts#L30) Zod schema for `extensions.health.sleep` — a single overnight sleep session with REM/deep/light/awake stages, total duration, and optional sleep score / resting heart rate. `version` is constrained to `2.x` so future additive evolution within the v2 line is accepted without bumping the canonical KRD version. --- --- url: /docs/api/core/variables/sleepStageSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / sleepStageSchema # Variable: sleepStageSchema > `const` **sleepStageSchema**: `ZodObject`<{ `durationSeconds`: `ZodNumber`; `stage`: `ZodEnum`<{ `awake`: `"awake"`; `deep`: `"deep"`; `light`: `"light"`; `rem`: `"rem"`; }>; `startTime`: `ZodISODateTime`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/sleep.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/sleep.ts#L14) Zod schema for a single sleep stage within a sleep session. Stages cover a contiguous time slice with one of four canonical Garmin sleep classifications. Adjacent stages do NOT have to be the same kind, but their durations MUST sum to the parent session total within the documented tolerance. --- --- url: /docs/api/core/variables/sportSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / sportSchema # Variable: sportSchema > `const` **sportSchema**: `ZodEnum`<{ `alpine_skiing`: `"alpine_skiing"`; `american_football`: `"american_football"`; `archery`: `"archery"`; `baseball`: `"baseball"`; `basketball`: `"basketball"`; `boating`: `"boating"`; `boxing`: `"boxing"`; `canoeing`: `"canoeing"`; `cricket`: `"cricket"`; `cross_country_skiing`: `"cross_country_skiing"`; `cycling`: `"cycling"`; `dance`: `"dance"`; `disc_golf`: `"disc_golf"`; `diving`: `"diving"`; `driving`: `"driving"`; `e_biking`: `"e_biking"`; `fishing`: `"fishing"`; `fitness_equipment`: `"fitness_equipment"`; `floor_climbing`: `"floor_climbing"`; `flying`: `"flying"`; `generic`: `"generic"`; `geocaching`: `"geocaching"`; `golf`: `"golf"`; `grinding`: `"grinding"`; `hang_gliding`: `"hang_gliding"`; `hiit`: `"hiit"`; `hiking`: `"hiking"`; `hockey`: `"hockey"`; `horseback_riding`: `"horseback_riding"`; `hunting`: `"hunting"`; `ice_skating`: `"ice_skating"`; `inline_skating`: `"inline_skating"`; `jump_rope`: `"jump_rope"`; `jumpmaster`: `"jumpmaster"`; `kayaking`: `"kayaking"`; `kitesurfing`: `"kitesurfing"`; `lacrosse`: `"lacrosse"`; `meditation`: `"meditation"`; `mixed_martial_arts`: `"mixed_martial_arts"`; `mobility`: `"mobility"`; `motor_sports`: `"motor_sports"`; `motorcycling`: `"motorcycling"`; `mountaineering`: `"mountaineering"`; `multisport`: `"multisport"`; `paddling`: `"paddling"`; `para_sport`: `"para_sport"`; `pool_apnea`: `"pool_apnea"`; `racket`: `"racket"`; `rafting`: `"rafting"`; `rock_climbing`: `"rock_climbing"`; `rowing`: `"rowing"`; `rugby`: `"rugby"`; `running`: `"running"`; `sailing`: `"sailing"`; `shooting`: `"shooting"`; `sky_diving`: `"sky_diving"`; `snorkeling`: `"snorkeling"`; `snowboarding`: `"snowboarding"`; `snowmobiling`: `"snowmobiling"`; `snowshoeing`: `"snowshoeing"`; `soccer`: `"soccer"`; `stand_up_paddleboarding`: `"stand_up_paddleboarding"`; `surfing`: `"surfing"`; `swimming`: `"swimming"`; `tactical`: `"tactical"`; `team_sport`: `"team_sport"`; `tennis`: `"tennis"`; `training`: `"training"`; `transition`: `"transition"`; `video_gaming`: `"video_gaming"`; `volleyball`: `"volleyball"`; `wakeboarding`: `"wakeboarding"`; `wakesurfing`: `"wakesurfing"`; `walking`: `"walking"`; `water_skiing`: `"water_skiing"`; `water_sport`: `"water_sport"`; `water_tubing`: `"water_tubing"`; `wheelchair_push_run`: `"wheelchair_push_run"`; `wheelchair_push_walk`: `"wheelchair_push_walk"`; `windsurfing`: `"windsurfing"`; `winter_sport`: `"winter_sport"`; }> Defined in: [packages/core/src/domain/schemas/sport.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/sport.ts#L10) Primary sport types supported by KRD, anchored on the Garmin FIT `Sport` enum (snake\_case here; the FIT adapter maps to/from camelCase). `generic` remains the terminal fallback. Granular variants live in `subSportSchema`. Access values via `.enum`, e.g. `sportSchema.enum.cycling`. --- --- url: /docs/api/core/variables/STALE_SNAPSHOT_THRESHOLD_DAYS.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / STALE\_SNAPSHOT\_THRESHOLD\_DAYS # Variable: STALE\_SNAPSHOT\_THRESHOLD\_DAYS > `const` **STALE\_SNAPSHOT\_THRESHOLD\_DAYS**: `7` = `7` Defined in: [packages/core/src/protocol/profile-snapshot.ts:105](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/protocol/profile-snapshot.ts#L105) Days after which a cached snapshot is considered stale and the popup SHALL render the placeholder instead of the cached athlete card. Rationale: a training-week cadence; revisit if telemetry from registered bridges suggests otherwise. --- --- url: /docs/api/core/variables/STRAIN_SCORE_TOLERANCE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / STRAIN\_SCORE\_TOLERANCE # Variable: STRAIN\_SCORE\_TOLERANCE > `const` **STRAIN\_SCORE\_TOLERANCE**: `0.1` = `0.1` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:19](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L19) --- --- url: /docs/api/core/variables/strainSummarySchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / strainSummarySchema # Variable: strainSummarySchema > `const` **strainSummarySchema**: `ZodObject`<{ `date`: `ZodISODate`; `dayAverageHeartRate`: `ZodOptional`<`ZodNumber`>; `dayMaxHeartRate`: `ZodOptional`<`ZodNumber`>; `energyKilojoules`: `ZodOptional`<`ZodNumber`>; `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"strain"`>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `strainScore`: `ZodNumber`; `version`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/strain.ts:14](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/strain.ts#L14) Zod schema for `extensions.health.strain` — a read-only, source-agnostic cardiovascular-load summary (e.g. WHOOP's 0–21 strain scale plus companion day-level heart-rate and energy figures). Unlike the six FIT-core health types it is not mandated to round-trip through FIT. A refinement requires `dayMaxHeartRate >= dayAverageHeartRate` when both are present. --- --- url: /docs/api/core/variables/STRESS_TOLERANCE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / STRESS\_TOLERANCE # Variable: STRESS\_TOLERANCE > `const` **STRESS\_TOLERANCE**: `0` = `0` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:15](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L15) --- --- url: /docs/api/core/variables/stressEpisodeSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / stressEpisodeSchema # Variable: stressEpisodeSchema > `const` **stressEpisodeSchema**: `ZodObject`<{ `averageLevel`: `ZodNumber`; `endTime`: `ZodISODateTime`; `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"stress"`>; `peakLevel`: `ZodNumber`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `startTime`: `ZodISODateTime`; `version`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/stress.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/stress.ts#L10) Zod schema for `extensions.health.stress` — a continuous stress episode with an average and peak level over a time window (0–100 on Garmin's device-side stress scale). --- --- url: /docs/api/core/variables/subSportSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / subSportSchema # Variable: subSportSchema > `const` **subSportSchema**: `ZodEnum`<{ `all`: `"all"`; `apnea_diving`: `"apnea_diving"`; `apnea_hunting`: `"apnea_hunting"`; `atv`: `"atv"`; `backcountry`: `"backcountry"`; `bike_to_run_transition`: `"bike_to_run_transition"`; `bmx`: `"bmx"`; `cardio_training`: `"cardio_training"`; `casual_walking`: `"casual_walking"`; `challenge`: `"challenge"`; `commuting`: `"commuting"`; `cyclocross`: `"cyclocross"`; `downhill`: `"downhill"`; `e_bike_fitness`: `"e_bike_fitness"`; `e_bike_mountain`: `"e_bike_mountain"`; `elliptical`: `"elliptical"`; `exercise`: `"exercise"`; `flexibility_training`: `"flexibility_training"`; `gauge_diving`: `"gauge_diving"`; `generic`: `"generic"`; `gravel_cycling`: `"gravel_cycling"`; `hand_cycling`: `"hand_cycling"`; `indoor_cycling`: `"indoor_cycling"`; `indoor_rowing`: `"indoor_rowing"`; `indoor_running`: `"indoor_running"`; `indoor_skiing`: `"indoor_skiing"`; `indoor_walking`: `"indoor_walking"`; `lap_swimming`: `"lap_swimming"`; `map`: `"map"`; `match`: `"match"`; `mixed_surface`: `"mixed_surface"`; `motocross`: `"motocross"`; `mountain`: `"mountain"`; `multi_gas_diving`: `"multi_gas_diving"`; `navigate`: `"navigate"`; `obstacle`: `"obstacle"`; `open_water`: `"open_water"`; `pilates`: `"pilates"`; `rc_drone`: `"rc_drone"`; `recumbent`: `"recumbent"`; `resort`: `"resort"`; `road`: `"road"`; `run_to_bike_transition`: `"run_to_bike_transition"`; `single_gas_diving`: `"single_gas_diving"`; `skate_skiing`: `"skate_skiing"`; `speed_walking`: `"speed_walking"`; `spin`: `"spin"`; `stair_climbing`: `"stair_climbing"`; `street`: `"street"`; `strength_training`: `"strength_training"`; `swim_to_bike_transition`: `"swim_to_bike_transition"`; `track`: `"track"`; `track_cycling`: `"track_cycling"`; `track_me`: `"track_me"`; `trail`: `"trail"`; `treadmill`: `"treadmill"`; `virtual_activity`: `"virtual_activity"`; `warm_up`: `"warm_up"`; `whitewater`: `"whitewater"`; `wingsuit`: `"wingsuit"`; `yoga`: `"yoga"`; }> Defined in: [packages/core/src/domain/schemas/sub-sport.ts:24](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/sub-sport.ts#L24) Zod schema for sub-sport type enumeration. Defines detailed sport subtypes for more specific categorization. Uses snake\_case for multi-word values following KRD format conventions. ## Example ```typescript import { subSportSchema } from '@kaiord/core'; // Access enum values const trail = subSportSchema.enum.trail; const indoorCycling = subSportSchema.enum.indoor_cycling; // Validate sub-sport const result = subSportSchema.safeParse('trail'); if (result.success) { console.log('Valid sub-sport:', result.data); } ``` --- --- url: /docs/api/core/variables/SWIM_STROKE_TO_FIT.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / SWIM\_STROKE\_TO\_FIT # Variable: SWIM\_STROKE\_TO\_FIT > `const` **SWIM\_STROKE\_TO\_FIT**: `object` Defined in: [packages/core/src/domain/schemas/swim-stroke.ts:52](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/swim-stroke.ts#L52) Bidirectional mapping from swim stroke to FIT protocol numeric values. Used for converting KRD swim strokes to FIT format. ## Type Declaration ### backstroke > `readonly` **backstroke**: `1` = `1` ### breaststroke > `readonly` **breaststroke**: `2` = `2` ### butterfly > `readonly` **butterfly**: `3` = `3` ### drill > `readonly` **drill**: `4` = `4` ### freestyle > `readonly` **freestyle**: `0` = `0` ### im > `readonly` **im**: `5` = `5` ### mixed > `readonly` **mixed**: `5` = `5` ## Example ```typescript import { SWIM_STROKE_TO_FIT } from '@kaiord/core'; const fitValue = SWIM_STROKE_TO_FIT.freestyle; // 0 ``` --- --- url: /docs/api/core/variables/swimStrokeSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / swimStrokeSchema # Variable: swimStrokeSchema > `const` **swimStrokeSchema**: `ZodEnum`<{ `backstroke`: `"backstroke"`; `breaststroke`: `"breaststroke"`; `butterfly`: `"butterfly"`; `drill`: `"drill"`; `freestyle`: `"freestyle"`; `im`: `"im"`; `mixed`: `"mixed"`; }> Defined in: [packages/core/src/domain/schemas/swim-stroke.ts:23](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/swim-stroke.ts#L23) Zod schema for swim stroke type enumeration. Defines swimming stroke types for workout steps. ## Example ```typescript import { swimStrokeSchema } from '@kaiord/core'; // Access enum values const freestyle = swimStrokeSchema.enum.freestyle; const backstroke = swimStrokeSchema.enum.backstroke; // Validate swim stroke const result = swimStrokeSchema.safeParse('freestyle'); if (result.success) { console.log('Valid swim stroke:', result.data); } ``` --- --- url: /docs/api/core/variables/targetSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / targetSchema # Variable: targetSchema > `const` **targetSchema**: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `type`: `ZodLiteral`<`"power"`>; `value`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `unit`: `ZodLiteral`<`"watts"`>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `unit`: `ZodLiteral`<`"percent_ftp"`>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `unit`: `ZodLiteral`<`"zone"`>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `max`: `ZodNumber`; `min`: `ZodNumber`; `unit`: `ZodLiteral`<`"range"`>; }, `$strip`>], `"unit"`>; }, `$strip`>, `ZodObject`<{ `type`: `ZodLiteral`<`"heart_rate"`>; `value`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `unit`: `ZodLiteral`<`"bpm"`>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `unit`: `ZodLiteral`<`"zone"`>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `unit`: `ZodLiteral`<`"percent_max"`>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `max`: `ZodNumber`; `min`: `ZodNumber`; `unit`: `ZodLiteral`<`"range"`>; }, `$strip`>], `"unit"`>; }, `$strip`>, `ZodObject`<{ `type`: `ZodLiteral`<`"cadence"`>; `value`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `unit`: `ZodLiteral`<`"rpm"`>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `max`: `ZodNumber`; `min`: `ZodNumber`; `unit`: `ZodLiteral`<`"range"`>; }, `$strip`>], `"unit"`>; }, `$strip`>], `"type"`> Defined in: [packages/core/src/domain/schemas/target.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target.ts#L21) Zod schema for workout step target. Validates target specifications using discriminated unions based on target type. Supports power, heart rate, cadence, pace, stroke type, and open targets. --- --- url: /docs/api/core/variables/targetTypeSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / targetTypeSchema # Variable: targetTypeSchema > `const` **targetTypeSchema**: `ZodEnum`<{ `cadence`: `"cadence"`; `heart_rate`: `"heart_rate"`; `open`: `"open"`; `pace`: `"pace"`; `power`: `"power"`; `stroke_type`: `"stroke_type"`; }> Defined in: [packages/core/src/domain/schemas/target-type.ts:18](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-type.ts#L18) Zod schema for target type enumeration. Defines all possible target types for workout steps. ## Example ```typescript import { targetTypeSchema } from '@kaiord/core'; const powerType = targetTypeSchema.enum.power; const hrType = targetTypeSchema.enum.heart_rate; const result = targetTypeSchema.safeParse('power'); ``` --- --- url: /docs/api/core/variables/targetUnitSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / targetUnitSchema # Variable: targetUnitSchema > `const` **targetUnitSchema**: `ZodEnum`<{ `bpm`: `"bpm"`; `mps`: `"mps"`; `percent_ftp`: `"percent_ftp"`; `percent_max`: `"percent_max"`; `range`: `"range"`; `rpm`: `"rpm"`; `swim_stroke`: `"swim_stroke"`; `watts`: `"watts"`; `zone`: `"zone"`; }> Defined in: [packages/core/src/domain/schemas/target-values/unit.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/target-values/unit.ts#L17) Zod schema for target unit enumeration. Defines all possible units for target values (watts, zones, percentages, ranges, etc.). ## Example ```typescript import { targetUnitSchema } from '@kaiord/core'; // Access enum values const watts = targetUnitSchema.enum.watts; const zone = targetUnitSchema.enum.zone; ``` --- --- url: /docs/api/tcx/variables/tcxReader.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / tcxReader # Variable: tcxReader > `const` **tcxReader**: `TextReader` Defined in: [index.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/index.ts#L25) --- --- url: /docs/api/tcx/variables/tcxWriter.md --- [**@kaiord/tcx**](../README.md) *** [@kaiord/tcx](../README.md) / tcxWriter # Variable: tcxWriter > `const` **tcxWriter**: `TextWriter` Defined in: [index.ts:26](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/tcx/src/index.ts#L26) --- --- url: /docs/api/core/variables/toleranceConfigSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / toleranceConfigSchema # Variable: toleranceConfigSchema > `const` **toleranceConfigSchema**: `ZodObject`<{ `cadenceTolerance`: `ZodNumber`; `distanceTolerance`: `ZodNumber`; `ftpTolerance`: `ZodNumber`; `hrTolerance`: `ZodNumber`; `paceTolerance`: `ZodNumber`; `powerTolerance`: `ZodNumber`; `timeTolerance`: `ZodNumber`; }, `$strip`> Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:3](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L3) --- --- url: /docs/api/core/variables/toleranceViolationSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / toleranceViolationSchema # Variable: toleranceViolationSchema > `const` **toleranceViolationSchema**: `ZodObject`<{ `actual`: `ZodNumber`; `deviation`: `ZodNumber`; `expected`: `ZodNumber`; `field`: `ZodString`; `tolerance`: `ZodNumber`; }, `$strip`> Defined in: [packages/core/src/domain/validation/tolerance-checker.ts:25](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/validation/tolerance-checker.ts#L25) --- --- url: /docs/api/core/variables/trainingZoneBandSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / trainingZoneBandSchema # Variable: trainingZoneBandSchema > `const` **trainingZoneBandSchema**: `ZodObject`<{ `label`: `ZodOptional`<`ZodString`>; `max`: `ZodOptional`<`ZodNumber`>; `min`: `ZodNumber`; `zone`: `ZodNumber`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/training-zones.ts:4](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/training-zones.ts#L4) A single band within a zone set (e.g. Coggan power zone 4). --- --- url: /docs/api/core/variables/trainingZoneSetSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / trainingZoneSetSchema # Variable: trainingZoneSetSchema > `const` **trainingZoneSetSchema**: `ZodObject`<{ `bands`: `ZodArray`<`ZodObject`<{ `label`: `ZodOptional`<`ZodString`>; `max`: `ZodOptional`<`ZodNumber`>; `min`: `ZodNumber`; `zone`: `ZodNumber`; }, `$strip`>>; `method`: `ZodOptional`<`ZodString`>; `metric`: `ZodEnum`<{ `heart_rate`: `"heart_rate"`; `pace`: `"pace"`; `power`: `"power"`; }>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/training-zones.ts:17](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/training-zones.ts#L17) An ordered set of bands for one quantity (power / heart rate / pace). --- --- url: /docs/api/core/variables/trainingZonesSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / trainingZonesSchema # Variable: trainingZonesSchema > `const` **trainingZonesSchema**: `ZodObject`<{ `kind`: `ZodLiteral`<`"training_zones"`>; `sets`: `ZodArray`<`ZodObject`<{ `bands`: `ZodArray`<`ZodObject`<{ `label`: `ZodOptional`<`ZodString`>; `max`: `ZodOptional`<`ZodNumber`>; `min`: `ZodNumber`; `zone`: `ZodNumber`; }, `$strip`>>; `method`: `ZodOptional`<`ZodString`>; `metric`: `ZodEnum`<{ `heart_rate`: `"heart_rate"`; `pace`: `"pace"`; `power`: `"power"`; }>; }, `$strip`>>; `sport`: `ZodString`; `threshold`: `ZodOptional`<`ZodNumber`>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/training-zones.ts:32](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/training-zones.ts#L32) Zod schema for `training-zones` — a per-sport set of training zone definitions imported from a coaching source. Snake\_case per the domain schema convention. Replaces the former `z.unknown()` passthrough so the managed-data registry validates every type it routes. --- --- url: /docs/api/core/variables/VITALS_RESPIRATORY_RATE_TOLERANCE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / VITALS\_RESPIRATORY\_RATE\_TOLERANCE # Variable: VITALS\_RESPIRATORY\_RATE\_TOLERANCE > `const` **VITALS\_RESPIRATORY\_RATE\_TOLERANCE**: `0.1` = `0.1` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:20](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L20) --- --- url: /docs/api/core/variables/VITALS_RESTING_HEART_RATE_TOLERANCE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / VITALS\_RESTING\_HEART\_RATE\_TOLERANCE # Variable: VITALS\_RESTING\_HEART\_RATE\_TOLERANCE > `const` **VITALS\_RESTING\_HEART\_RATE\_TOLERANCE**: `0` = `0` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:22](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L22) --- --- url: /docs/api/core/variables/VITALS_SPO2_TOLERANCE.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / VITALS\_SPO2\_TOLERANCE # Variable: VITALS\_SPO2\_TOLERANCE > `const` **VITALS\_SPO2\_TOLERANCE**: `0` = `0` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:21](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L21) --- --- url: /docs/api/core/variables/vitalsSummarySchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / vitalsSummarySchema # Variable: vitalsSummarySchema > `const` **vitalsSummarySchema**: `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"vitals"`>; `measuredAt`: `ZodISODateTime`; `respiratoryRate`: `ZodOptional`<`ZodNumber`>; `restingHeartRate`: `ZodOptional`<`ZodNumber`>; `skinTempCelsius`: `ZodOptional`<`ZodNumber`>; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `spo2Percent`: `ZodOptional`<`ZodNumber`>; `version`: `ZodString`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/vitals.ts:11](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/vitals.ts#L11) Zod schema for `extensions.health.vitals` — a read-only, source-agnostic daily-vitals summary folding respiratory rate, SpO₂, skin temperature, and resting heart rate into one payload. A refinement requires that at least one measurement field be present so empty payloads are rejected. --- --- url: /docs/api/core/variables/WEIGHT_TOLERANCE_KG.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / WEIGHT\_TOLERANCE\_KG # Variable: WEIGHT\_TOLERANCE\_KG > `const` **WEIGHT\_TOLERANCE\_KG**: `0.1` = `0.1` Defined in: [packages/core/src/domain/schemas/health/tolerances.ts:10](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/tolerances.ts#L10) --- --- url: /docs/api/core/variables/weightMeasurementSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / weightMeasurementSchema # Variable: weightMeasurementSchema > `const` **weightMeasurementSchema**: `ZodObject`<{ `externalId`: `ZodOptional`<`ZodString`>; `kaiordRecordId`: `ZodOptional`<`ZodString`>; `kind`: `ZodLiteral`<`"weight"`>; `measuredAt`: `ZodISODateTime`; `sourceBridgeId`: `ZodOptional`<`ZodString`>; `version`: `ZodString`; `weightKilograms`: `ZodNumber`; }, `$strip`> Defined in: [packages/core/src/domain/schemas/health/weight.ts:12](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/health/weight.ts#L12) Zod schema for `extensions.health.weight` — a scalar weight measurement captured at a point in time. Body-composition fields (fat percent, lean mass, water, BMI) live in the separate `body_composition` payload so scales that only report scalar weight produce a valid payload without partial fields. --- --- url: /docs/api/core/variables/workoutLikeFileTypes.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / workoutLikeFileTypes # Variable: workoutLikeFileTypes > `const` **workoutLikeFileTypes**: readonly \[`"structured_workout"`, `"recorded_activity"`, `"course"`] Defined in: [packages/core/src/domain/schemas/file-type.ts:30](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/file-type.ts#L30) Legacy workout/activity/course types that require `metadata.sport`. --- --- url: /docs/api/core/variables/workoutSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / workoutSchema # Variable: workoutSchema > `const` **workoutSchema**: `ZodObject`<{ `extensions`: `ZodOptional`<`ZodRecord`<`ZodString`, `ZodUnknown`>>; `name`: `ZodOptional`<`ZodString`>; `notes`: `ZodOptional`<`ZodString`>; `poolLength`: `ZodOptional`<`ZodNumber`>; `poolLengthUnit`: `ZodOptional`<`ZodLiteral`<`"meters"`>>; `sport`: `ZodEnum`<{ `alpine_skiing`: `"alpine_skiing"`; `american_football`: `"american_football"`; `archery`: `"archery"`; `baseball`: `"baseball"`; `basketball`: `"basketball"`; `boating`: `"boating"`; `boxing`: `"boxing"`; `canoeing`: `"canoeing"`; `cricket`: `"cricket"`; `cross_country_skiing`: `"cross_country_skiing"`; `cycling`: `"cycling"`; `dance`: `"dance"`; `disc_golf`: `"disc_golf"`; `diving`: `"diving"`; `driving`: `"driving"`; `e_biking`: `"e_biking"`; `fishing`: `"fishing"`; `fitness_equipment`: `"fitness_equipment"`; `floor_climbing`: `"floor_climbing"`; `flying`: `"flying"`; `generic`: `"generic"`; `geocaching`: `"geocaching"`; `golf`: `"golf"`; `grinding`: `"grinding"`; `hang_gliding`: `"hang_gliding"`; `hiit`: `"hiit"`; `hiking`: `"hiking"`; `hockey`: `"hockey"`; `horseback_riding`: `"horseback_riding"`; `hunting`: `"hunting"`; `ice_skating`: `"ice_skating"`; `inline_skating`: `"inline_skating"`; `jump_rope`: `"jump_rope"`; `jumpmaster`: `"jumpmaster"`; `kayaking`: `"kayaking"`; `kitesurfing`: `"kitesurfing"`; `lacrosse`: `"lacrosse"`; `meditation`: `"meditation"`; `mixed_martial_arts`: `"mixed_martial_arts"`; `mobility`: `"mobility"`; `motor_sports`: `"motor_sports"`; `motorcycling`: `"motorcycling"`; `mountaineering`: `"mountaineering"`; `multisport`: `"multisport"`; `paddling`: `"paddling"`; `para_sport`: `"para_sport"`; `pool_apnea`: `"pool_apnea"`; `racket`: `"racket"`; `rafting`: `"rafting"`; `rock_climbing`: `"rock_climbing"`; `rowing`: `"rowing"`; `rugby`: `"rugby"`; `running`: `"running"`; `sailing`: `"sailing"`; `shooting`: `"shooting"`; `sky_diving`: `"sky_diving"`; `snorkeling`: `"snorkeling"`; `snowboarding`: `"snowboarding"`; `snowmobiling`: `"snowmobiling"`; `snowshoeing`: `"snowshoeing"`; `soccer`: `"soccer"`; `stand_up_paddleboarding`: `"stand_up_paddleboarding"`; `surfing`: `"surfing"`; `swimming`: `"swimming"`; `tactical`: `"tactical"`; `team_sport`: `"team_sport"`; `tennis`: `"tennis"`; `training`: `"training"`; `transition`: `"transition"`; `video_gaming`: `"video_gaming"`; `volleyball`: `"volleyball"`; `wakeboarding`: `"wakeboarding"`; `wakesurfing`: `"wakesurfing"`; `walking`: `"walking"`; `water_skiing`: `"water_skiing"`; `water_sport`: `"water_sport"`; `water_tubing`: `"water_tubing"`; `wheelchair_push_run`: `"wheelchair_push_run"`; `wheelchair_push_walk`: `"wheelchair_push_walk"`; `windsurfing`: `"windsurfing"`; `winter_sport`: `"winter_sport"`; }>; `steps`: `ZodArray`<`ZodUnion`\, `ZodObject`<{ `meters`: ...; `type`: ...; }, `$strip`>, `ZodObject`<{ `bpm`: ...; `type`: ...; }, `$strip`>, `ZodObject`<{ `bpm`: ...; `repeatFrom`: ...; `type`: ...; }, `$strip`>], `"type"`>; `durationType`: `ZodEnum`<{ `calories`: `"calories"`; `distance`: `"distance"`; `heart_rate_less_than`: `"heart_rate_less_than"`; `open`: `"open"`; `power_greater_than`: `"power_greater_than"`; `power_less_than`: `"power_less_than"`; `repeat_until_calories`: `"repeat_until_calories"`; `repeat_until_distance`: `"repeat_until_distance"`; `repeat_until_heart_rate_greater_than`: `"repeat_until_heart_rate_greater_than"`; `repeat_until_heart_rate_less_than`: `"repeat_until_heart_rate_less_than"`; `repeat_until_power_greater_than`: `"repeat_until_power_greater_than"`; `repeat_until_power_less_than`: `"repeat_until_power_less_than"`; `repeat_until_time`: `"repeat_until_time"`; `time`: `"time"`; }>; `equipment`: `ZodOptional`<`ZodEnum`<{ `none`: `"none"`; `swim_fins`: `"swim_fins"`; `swim_kickboard`: `"swim_kickboard"`; `swim_paddles`: `"swim_paddles"`; `swim_pull_buoy`: `"swim_pull_buoy"`; `swim_snorkel`: `"swim_snorkel"`; }>>; `extensions`: `ZodOptional`<`ZodRecord`<`ZodString`, `ZodUnknown`>>; `intensity`: `ZodOptional`<`ZodEnum`<{ `active`: `"active"`; `cooldown`: `"cooldown"`; `interval`: `"interval"`; `other`: `"other"`; `recovery`: `"recovery"`; `rest`: `"rest"`; `warmup`: `"warmup"`; }>>; `name`: `ZodOptional`<`ZodString`>; `notes`: `ZodOptional`<`ZodString`>; `stepIndex`: `ZodNumber`; `target`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `type`: ...; `value`: ...; }, `$strip`>, `ZodObject`<{ `type`: ...; `value`: ...; }, `$strip`>, `ZodObject`<{ `type`: ...; `value`: ...; }, `$strip`>], `"type"`>; `targetType`: `ZodEnum`<{ `cadence`: `"cadence"`; `heart_rate`: `"heart_rate"`; `open`: `"open"`; `pace`: `"pace"`; `power`: `"power"`; `stroke_type`: `"stroke_type"`; }>; }, `$strip`>, `ZodObject`<{ `id`: `ZodOptional`<`ZodString`>; `repeatCount`: `ZodNumber`; `steps`: `ZodArray`<`ZodObject`<{ `duration`: `ZodDiscriminatedUnion`<..., ...>; `durationType`: `ZodEnum`<...>; `equipment`: `ZodOptional`<...>; `extensions`: `ZodOptional`<...>; `intensity`: `ZodOptional`<...>; `name`: `ZodOptional`<...>; `notes`: `ZodOptional`<...>; `stepIndex`: `ZodNumber`; `target`: `ZodDiscriminatedUnion`<..., ...>; `targetType`: `ZodEnum`<...>; }, `$strip`>>; }, `$strip`>]>>; `subSport`: `ZodOptional`<`ZodEnum`<{ `all`: `"all"`; `apnea_diving`: `"apnea_diving"`; `apnea_hunting`: `"apnea_hunting"`; `atv`: `"atv"`; `backcountry`: `"backcountry"`; `bike_to_run_transition`: `"bike_to_run_transition"`; `bmx`: `"bmx"`; `cardio_training`: `"cardio_training"`; `casual_walking`: `"casual_walking"`; `challenge`: `"challenge"`; `commuting`: `"commuting"`; `cyclocross`: `"cyclocross"`; `downhill`: `"downhill"`; `e_bike_fitness`: `"e_bike_fitness"`; `e_bike_mountain`: `"e_bike_mountain"`; `elliptical`: `"elliptical"`; `exercise`: `"exercise"`; `flexibility_training`: `"flexibility_training"`; `gauge_diving`: `"gauge_diving"`; `generic`: `"generic"`; `gravel_cycling`: `"gravel_cycling"`; `hand_cycling`: `"hand_cycling"`; `indoor_cycling`: `"indoor_cycling"`; `indoor_rowing`: `"indoor_rowing"`; `indoor_running`: `"indoor_running"`; `indoor_skiing`: `"indoor_skiing"`; `indoor_walking`: `"indoor_walking"`; `lap_swimming`: `"lap_swimming"`; `map`: `"map"`; `match`: `"match"`; `mixed_surface`: `"mixed_surface"`; `motocross`: `"motocross"`; `mountain`: `"mountain"`; `multi_gas_diving`: `"multi_gas_diving"`; `navigate`: `"navigate"`; `obstacle`: `"obstacle"`; `open_water`: `"open_water"`; `pilates`: `"pilates"`; `rc_drone`: `"rc_drone"`; `recumbent`: `"recumbent"`; `resort`: `"resort"`; `road`: `"road"`; `run_to_bike_transition`: `"run_to_bike_transition"`; `single_gas_diving`: `"single_gas_diving"`; `skate_skiing`: `"skate_skiing"`; `speed_walking`: `"speed_walking"`; `spin`: `"spin"`; `stair_climbing`: `"stair_climbing"`; `street`: `"street"`; `strength_training`: `"strength_training"`; `swim_to_bike_transition`: `"swim_to_bike_transition"`; `track`: `"track"`; `track_cycling`: `"track_cycling"`; `track_me`: `"track_me"`; `trail`: `"trail"`; `treadmill`: `"treadmill"`; `virtual_activity`: `"virtual_activity"`; `warm_up`: `"warm_up"`; `whitewater`: `"whitewater"`; `wingsuit`: `"wingsuit"`; `yoga`: `"yoga"`; }>>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/workout.ts:41](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/workout.ts#L41) Zod schema for a complete workout definition. Validates a structured workout with metadata and a sequence of steps or repetition blocks. `stepIndex` values on steps are advisory ordering metadata: producers SHOULD emit 0-based contiguous indices, but the schema deliberately does not enforce contiguity or uniqueness — adapters renumber steps when flattening repetition blocks (see the garmin adapter's flatten-segments converter) and consumers MUST rely on array order, not on index arithmetic. `poolLength` is bounded to \[1, 655] meters — generous enough for endless pools (~5 m) and the FIT protocol envelope, while rejecting nonsense values like 0.0001 or 99999. KRD always stores pool length normalized to meters; adapters that accept yard-based pools convert on ingest (see `length-unit.converter`), so `poolLengthUnit` is fixed to `"meters"` here rather than carrying the source unit. --- --- url: /docs/api/core/variables/workoutStepSchema.md --- [**@kaiord/core**](../README.md) *** [@kaiord/core](../README.md) / workoutStepSchema # Variable: workoutStepSchema > `const` **workoutStepSchema**: `ZodObject`<{ `duration`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `seconds`: `ZodNumber`; `type`: `ZodLiteral`<`"time"`>; }, `$strip`>, `ZodObject`<{ `meters`: `ZodNumber`; `type`: `ZodLiteral`<`"distance"`>; }, `$strip`>, `ZodObject`<{ `bpm`: `ZodNumber`; `type`: `ZodLiteral`<`"heart_rate_less_than"`>; }, `$strip`>, `ZodObject`<{ `bpm`: `ZodNumber`; `repeatFrom`: `ZodNumber`; `type`: `ZodLiteral`<`"repeat_until_heart_rate_greater_than"`>; }, `$strip`>], `"type"`>; `durationType`: `ZodEnum`<{ `calories`: `"calories"`; `distance`: `"distance"`; `heart_rate_less_than`: `"heart_rate_less_than"`; `open`: `"open"`; `power_greater_than`: `"power_greater_than"`; `power_less_than`: `"power_less_than"`; `repeat_until_calories`: `"repeat_until_calories"`; `repeat_until_distance`: `"repeat_until_distance"`; `repeat_until_heart_rate_greater_than`: `"repeat_until_heart_rate_greater_than"`; `repeat_until_heart_rate_less_than`: `"repeat_until_heart_rate_less_than"`; `repeat_until_power_greater_than`: `"repeat_until_power_greater_than"`; `repeat_until_power_less_than`: `"repeat_until_power_less_than"`; `repeat_until_time`: `"repeat_until_time"`; `time`: `"time"`; }>; `equipment`: `ZodOptional`<`ZodEnum`<{ `none`: `"none"`; `swim_fins`: `"swim_fins"`; `swim_kickboard`: `"swim_kickboard"`; `swim_paddles`: `"swim_paddles"`; `swim_pull_buoy`: `"swim_pull_buoy"`; `swim_snorkel`: `"swim_snorkel"`; }>>; `extensions`: `ZodOptional`<`ZodRecord`<`ZodString`, `ZodUnknown`>>; `intensity`: `ZodOptional`<`ZodEnum`<{ `active`: `"active"`; `cooldown`: `"cooldown"`; `interval`: `"interval"`; `other`: `"other"`; `recovery`: `"recovery"`; `rest`: `"rest"`; `warmup`: `"warmup"`; }>>; `name`: `ZodOptional`<`ZodString`>; `notes`: `ZodOptional`<`ZodString`>; `stepIndex`: `ZodNumber`; `target`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `type`: `ZodLiteral`<`"power"`>; `value`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `unit`: `ZodLiteral`<...>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `unit`: `ZodLiteral`<...>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `unit`: `ZodLiteral`<...>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `max`: `ZodNumber`; `min`: `ZodNumber`; `unit`: `ZodLiteral`<...>; }, `$strip`>], `"unit"`>; }, `$strip`>, `ZodObject`<{ `type`: `ZodLiteral`<`"heart_rate"`>; `value`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `unit`: `ZodLiteral`<...>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `unit`: `ZodLiteral`<...>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `unit`: `ZodLiteral`<...>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `max`: `ZodNumber`; `min`: `ZodNumber`; `unit`: `ZodLiteral`<...>; }, `$strip`>], `"unit"`>; }, `$strip`>, `ZodObject`<{ `type`: `ZodLiteral`<`"cadence"`>; `value`: `ZodDiscriminatedUnion`<\[`ZodObject`<{ `unit`: `ZodLiteral`<...>; `value`: `ZodNumber`; }, `$strip`>, `ZodObject`<{ `max`: `ZodNumber`; `min`: `ZodNumber`; `unit`: `ZodLiteral`<...>; }, `$strip`>], `"unit"`>; }, `$strip`>], `"type"`>; `targetType`: `ZodEnum`<{ `cadence`: `"cadence"`; `heart_rate`: `"heart_rate"`; `open`: `"open"`; `pace`: `"pace"`; `power`: `"power"`; `stroke_type`: `"stroke_type"`; }>; }, `$strip`> Defined in: [packages/core/src/domain/schemas/workout-step.ts:16](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/core/src/domain/schemas/workout-step.ts#L16) Zod schema for a workout step. Validates an individual interval or segment within a workout, including duration, target, and intensity. --- --- url: /docs/api/zwo/variables/zwiftReader.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / zwiftReader # Variable: zwiftReader > `const` **zwiftReader**: `TextReader` Defined in: [index.ts:29](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/index.ts#L29) --- --- url: /docs/api/zwo/variables/zwiftWriter.md --- [**@kaiord/zwo**](../README.md) *** [@kaiord/zwo](../README.md) / zwiftWriter # Variable: zwiftWriter > `const` **zwiftWriter**: `TextWriter` Defined in: [index.ts:30](https://github.com/pablo-albaladejo/kaiord/blob/68ee644626dfff19e67778ce4b4e0cf5c44b0120/packages/zwo/src/index.ts#L30)