@bitcobblers/wod-wiki-core 0.35.2116 → 0.35.2117

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -461,7 +461,9 @@ interface UnitDefinition {
461
461
  * unitless (factor 1).
462
462
  */
463
463
  declare const UNIT_CATALOG: readonly UnitDefinition[];
464
- /** Look up a unit by canonical spelling or alias (case-insensitive). */
464
+ /** Look up a unit by canonical spelling or alias (case-insensitive). Stored
465
+ * event rows are a trust boundary — a missing/legacy unit arrives as
466
+ * undefined at runtime despite the static type. */
465
467
  declare function lookupUnit(spelling: string): UnitDefinition | undefined;
466
468
  /** The named result dimension of a unit spelling, or undefined when the
467
469
  * spelling is not in the catalog. */
@@ -863,13 +865,7 @@ interface Segment {
863
865
  metrics?: MetricContainer;
864
866
  }
865
867
 
866
- /**
867
- * Content-stable identity for a workout block.
868
- *
869
- * A 32-bit FNV-1a hash of the trimmed fenced content, formatted as `bc-<8 hex>`.
870
- * Survives clone / reorder / edit-above so results and facts keyed by it stay
871
- * linked across runs.
872
- */
868
+ /** Cross-note fingerprint of the trimmed, unfenced workout body. Never an occurrence ID. */
873
869
  declare function blockContentId(content: string): string;
874
870
 
875
871
  /**
@@ -936,20 +932,44 @@ interface WorkoutResults {
936
932
  completed: boolean;
937
933
  }
938
934
 
939
- type SegmentDataType = 'script' | 'youtube' | 'markdown' | 'header' | 'frontmatter' | 'wod' | 'title' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
935
+ type NoteBlockKind = 'wod' | 'query' | 'widget' | 'embed';
936
+ interface NoteBlock {
937
+ id: string;
938
+ kind: NoteBlockKind;
939
+ version: number;
940
+ sourceRevision: number;
941
+ from: number;
942
+ to: number;
943
+ dialect?: 'time' | 'log';
944
+ sport?: string;
945
+ }
946
+ interface BlockRevision {
947
+ noteId: string;
948
+ blockId: string;
949
+ version: number;
950
+ kind: NoteBlockKind;
951
+ rawContent: string;
952
+ savedAt: number;
953
+ dialect?: 'time' | 'log';
954
+ sport?: string;
955
+ }
940
956
  type NoteKind = 'journal' | 'template' | 'playground' | 'feed' | 'dashboard' | 'page' | (string & {});
941
957
  interface Note {
942
958
  id: string;
943
959
  title: string;
960
+ rawContent: string;
961
+ sourceRevision: number;
962
+ blocks: Record<string, NoteBlock>;
944
963
  date?: number;
945
964
  createdAt: number;
946
965
  type?: NoteKind;
947
966
  sourceId?: string;
948
967
  catalog?: string;
949
968
  tags?: string[];
950
- /** Original seed file path (e.g. `markdown/collections/girls/fran.md`) — the
951
- * deterministic UUID is derived from this path; retained for seed content
952
- * reconstruction (canvas routes, collection READMEs, block-index lookup). */
969
+ seedOrigin?: 'seed' | 'user';
970
+ seedVersion?: number;
971
+ seedChunkId?: string;
972
+ /** Authored seed path used for deterministic identity and routing. */
953
973
  sourcePath?: string;
954
974
  }
955
975
  interface Page {
@@ -985,48 +1005,36 @@ interface NoteTag {
985
1005
  noteId: string;
986
1006
  tagId: string;
987
1007
  }
988
- interface NoteSegment {
989
- id: string;
990
- version: number;
991
- noteId: string;
992
- position?: number;
993
- pageId?: string;
994
- dataType: SegmentDataType;
995
- data: unknown;
996
- rawContent: string;
997
- createdAt: number;
998
- updatedAt?: number;
999
- isHistory?: boolean;
1000
- }
1001
1008
  interface BlockIndexRow {
1002
- /** Composite key: `${noteId}:${segmentId}:${segmentVersion}` */
1009
+ /** Current occurrence key `${noteId}:${blockId}`. */
1003
1010
  id: string;
1004
1011
  noteId: string;
1005
- segmentId: string;
1006
- segmentVersion: number;
1012
+ blockId: string;
1013
+ blockVersion: number;
1014
+ sourceRevision: number;
1015
+ from: number;
1016
+ to: number;
1007
1017
  position?: number;
1008
- dataType: string;
1018
+ dataType: NoteBlock['kind'];
1009
1019
  blockContentId?: string;
1010
1020
  rawContent: string;
1011
1021
  noteTitle: string;
1012
1022
  createdAt: number;
1013
1023
  isStatic?: boolean;
1014
1024
  sourceId?: string;
1025
+ sourcePath?: string;
1026
+ routeId?: string;
1015
1027
  }
1016
1028
  type ResultOrigin = 'journal' | 'playground' | 'user';
1017
1029
  interface Session {
1018
1030
  id: string;
1019
- segmentId?: string;
1020
- segmentVersion?: number;
1021
1031
  noteId: string;
1022
- blockId?: string;
1032
+ blockId: string;
1033
+ blockVersion: number;
1023
1034
  blockContentId?: string;
1024
- version?: number;
1025
1035
  origin?: ResultOrigin;
1026
1036
  pageId?: string;
1027
- /** Write-path lifecycle (ticket 005): row born 'in-progress' at workout
1028
- * start, flipped to 'completed' at finalize. Absent = 'completed'
1029
- * (legacy rows predate streaming). */
1037
+ /** Born in-progress at run start, completed when finalization commits. */
1030
1038
  status?: 'in-progress' | 'completed';
1031
1039
  /** When workout started */
1032
1040
  startTime: number;
@@ -1073,8 +1081,8 @@ interface AnalyticsDataPoint {
1073
1081
  * partitions) — normalized key → value, resolved by factTagValue after
1074
1082
  * the structural switch so `by {coach}` / `{coach:greg}` work. */
1075
1083
  dimensions?: Record<string, string>;
1076
- segmentId: string;
1077
- segmentVersion: number;
1084
+ blockId: string;
1085
+ blockVersion: number;
1078
1086
  resultId: string;
1079
1087
  type: string;
1080
1088
  value: unknown;
@@ -1145,8 +1153,8 @@ interface EventRecord {
1145
1153
  dialect?: string;
1146
1154
  stackLevel?: number;
1147
1155
  completionReason?: string;
1148
- segmentId?: string;
1149
- segmentVersion?: number;
1156
+ blockId?: string;
1157
+ blockVersion?: number;
1150
1158
  /** Per-metric temporal anchors (ticket 12) — parallel to `metrics` when
1151
1159
  * the producing statement carries its own instants/dates:
1152
1160
  * 'instant' = recorded occurrence instant; 'civil-date' = recorded civil
@@ -1253,6 +1261,28 @@ interface CatalogBackfillState {
1253
1261
  revision: number;
1254
1262
  updatedAt: number;
1255
1263
  }
1264
+ interface BlockEffort {
1265
+ id: string;
1266
+ noteId: string;
1267
+ blockId: string;
1268
+ blockContentId?: string;
1269
+ effortSlug: string;
1270
+ isStatic?: boolean;
1271
+ sourcePath?: string;
1272
+ createdAt: number;
1273
+ }
1274
+ interface Membership {
1275
+ id: string;
1276
+ displayName: string;
1277
+ picture?: string;
1278
+ weight?: number;
1279
+ weightUnit?: 'kg' | 'lb';
1280
+ height?: number;
1281
+ heightUnit?: 'cm' | 'in';
1282
+ birthDate?: string;
1283
+ createdAt: number;
1284
+ updatedAt?: number;
1285
+ }
1256
1286
 
1257
1287
  /**
1258
1288
  * State of a WOD block
@@ -1292,7 +1322,7 @@ type FrontMatterSubtype = 'default' | 'youtube' | 'strava' | 'amazon' | 'file' |
1292
1322
  interface ScriptBlock {
1293
1323
  /** Unique identifier for this block */
1294
1324
  id: string;
1295
- /** Content-stable identity */
1325
+ /** Cross-note content fingerprint, never occurrence identity. */
1296
1326
  contentId?: string;
1297
1327
  /** Workout fence tag ('time' runnable / 'log' recorded) */
1298
1328
  dialect?: FenceDialect;
@@ -1324,6 +1354,13 @@ interface Section {
1324
1354
  id: string;
1325
1355
  contentId?: string;
1326
1356
  type: SectionType;
1357
+ /** Half-open UTF-16 offsets in the exact authored document. */
1358
+ from: number;
1359
+ to: number;
1360
+ contentFrom?: number;
1361
+ contentTo?: number;
1362
+ querySuffix?: string;
1363
+ separatorAfter?: string;
1327
1364
  subtype?: string;
1328
1365
  rawContent: string;
1329
1366
  displayContent: string;
@@ -1387,14 +1424,6 @@ interface IScript {
1387
1424
  getAt(index: number): ICodeStatement | undefined;
1388
1425
  }
1389
1426
 
1390
- /**
1391
- * Try to match a line against known workout fence patterns.
1392
- * Returns the base tag and optional :sport suffix, or null otherwise.
1393
- */
1394
- declare function matchDialectFence(trimmedLine: string): {
1395
- dialect: FenceDialect;
1396
- sport?: string;
1397
- } | null;
1398
1427
  /**
1399
1428
  * Detects all WOD blocks in markdown content.
1400
1429
  * Recognises ```time and ```log as valid workout fences (optional :sport suffix).
@@ -1421,33 +1450,44 @@ declare function findBlockAtLine(blocks: ScriptBlock[], lineNumber: number): Scr
1421
1450
  */
1422
1451
  declare function extractBlockContent(content: string, startLine: number, endLine: number): string;
1423
1452
 
1424
- interface SectionMetadata {
1425
- id: string;
1426
- version: number;
1427
- createdAt: number;
1428
- }
1429
- /**
1430
- * Generate a deterministic section ID from type, startLine (0-indexed), and a content hash.
1431
- * Stable across re-parses when structure doesn't change.
1432
- */
1433
- declare function generateSectionId(type: SectionType | string, startLine: number, content: string): string;
1434
-
1435
- declare function parseDocumentSections(content: string, scriptBlocks?: ScriptBlock[]): Section[];
1453
+ declare const KNOWN_SECTION_WIDGETS: readonly string[];
1454
+ declare function matchDialectFence(trimmedLine: string): {
1455
+ dialect: 'time' | 'log';
1456
+ sport?: string;
1457
+ } | null;
1458
+ interface SectionRecognitionOptions {
1459
+ registeredWidgets?: ReadonlySet<string> | readonly string[];
1460
+ }
1461
+ interface ReconcileNoteBlocksOptions extends SectionRecognitionOptions {
1462
+ sourceRevision: number;
1463
+ /** Current-source occurrence lineage, not a previous document's locations. */
1464
+ blocks?: Record<string, NoteBlock>;
1465
+ createId?: () => string;
1466
+ }
1467
+ declare function parseDocumentSections(content: string, options?: SectionRecognitionOptions): Section[];
1468
+ declare function actionableSectionKind(section: Section): NoteBlock['kind'] | null;
1469
+ declare function reconcileNoteBlocks(rawContent: string, options: ReconcileNoteBlocksOptions): Record<string, NoteBlock>;
1470
+ declare function validateNoteBlocks(rawContent: string, blocks: Record<string, NoteBlock>, sourceRevision: number, options?: SectionRecognitionOptions): void;
1471
+ interface NoteBlockChange {
1472
+ from: number;
1473
+ to: number;
1474
+ insert: string;
1475
+ }
1476
+ declare function mapNoteBlockChanges(blocks: Record<string, NoteBlock>, changes: readonly NoteBlockChange[]): Record<string, NoteBlock>;
1436
1477
  declare function buildRawContent(sections: Section[]): string;
1437
1478
  declare function calculateTotalLines(sections: Section[]): number;
1438
- declare function matchSectionIds(oldSections: Section[], newSections: Section[]): Section[];
1439
1479
 
1440
1480
  /**
1441
1481
  * Auto-generated build version metadata.
1442
1482
  * Do not edit directly; updated by scripts/stamp-version.ts
1443
1483
  */
1444
- declare const VERSION = "0.35.2116";
1445
- declare const GIT_SHA = "a4d411f";
1446
- declare const BUILD_TIME = "2026-10-12T00:14:24.795Z";
1484
+ declare const VERSION = "0.35.2117";
1485
+ declare const GIT_SHA = "03d1dfc";
1486
+ declare const BUILD_TIME = "2026-10-12T20:08:12.374Z";
1447
1487
  declare const SEMVER: {
1448
- readonly version: "0.35.2116";
1449
- readonly gitSha: "a4d411f";
1450
- readonly buildTime: "2026-10-12T00:14:24.795Z";
1488
+ readonly version: "0.35.2117";
1489
+ readonly gitSha: "03d1dfc";
1490
+ readonly buildTime: "2026-10-12T20:08:12.374Z";
1451
1491
  };
1452
1492
 
1453
- export { type AnalyticsDataPoint, type AnalyticsGraphConfig, type AnalyticsGroup, type Attachment, BUILD_TIME, type BlockIndexRow, BlockKey, type CatalogBackfillState, CodeMetadata, CodeStatement, type DialectAnalysis, type DimensionKey, type DisplayStatus, type EventGrain, type EventRecord, type FenceDialect, type FieldCatalogEntry, type FieldContribution, type FieldLeaf, type FieldRef, type FieldSourceRecord, type FieldValueKind, type FieldValueRecord, type FrontMatterSubtype, GIT_SHA, type IBlockKey, type ICodeMetadata, type ICodeStatement, type IDialect, type IDialectTagDescriptor, type IMetric, type IMetricOwnershipResolver, type IMetricSource, type IOutputStatement, type IScript, KNOWN_OUTPUT_TYPES, LEGACY_ORIGIN_TO_OWNERSHIP_LAYER, METRIC_OWNERSHIP_LAYER_CHAIN, Metric, type MetricAction, MetricContainer, type MetricFilter, type MetricOrigin, type MetricOwnershipLayer, type MetricOwnershipLedger, type MetricOwnershipOutcome, type MetricOwnershipPromotionCandidate, type MetricOwnershipQuery, type MetricOwnershipResolvedContribution, type MetricOwnershipTypeExplanation, type MetricTemporal, MetricType, type MetricWithOptionalOwnershipLayer, NOTEBOOK_TAG_PREFIX, type Note, type NoteKind, type NoteSegment, type NoteTag, type Notebook, type NullValueKind, type Origin, OutputStatement, type OutputStatementOptions, type OutputStatementType, OwnershipResolver, type Page, type PageNote, type ParseError, ParsedCodeStatement, type ReducerStats, type ResultOrigin, SEMVER, SYSTEM_DEFAULT_OUTPUT_UNIT, type ScriptBlock, type ScriptBlockState, type Section, type SectionDocument, type SectionMetadata, type SectionType, type Segment, type SegmentDataType, type Session, type StoredOutputStatement, type SummaryCoverage, type Tag, type TagType, type TagTypeRecord, type TimeSpan, UNIT_CATALOG, UnitConversionError, type UnitDefinition, type UnitErrorCode, VALID_FENCE_DIALECTS, VERSION, type VisualizerFilter, type VisualizerSize, type WorkoutResults, type WorkoutSectionType, blockContentId, buildRawContent, calculateTotalLines, convertViaCatalog, createMetricOwnershipLedger, detectScriptBlocks, dimensionKeyOf, extractBlockContent, fieldRefFromKey, fieldRefKey, findBlockAtLine, flattenFieldLeaves, fromNotebookTag, generateSectionId, getMetricOwnershipLayer, isNotebookTag, isWorkoutSectionType, lookupUnit, matchDialectFence, matchSectionIds, normalizeFieldComponent, normalizeFieldPath, ownershipRank, parseDocumentSections, resolveLayer, runAffordance, systemDefaultUnit, toNotebookTag, valueKindOf };
1493
+ export { type AnalyticsDataPoint, type AnalyticsGraphConfig, type AnalyticsGroup, type Attachment, BUILD_TIME, type BlockEffort, type BlockIndexRow, BlockKey, type BlockRevision, type CatalogBackfillState, CodeMetadata, CodeStatement, type DialectAnalysis, type DimensionKey, type DisplayStatus, type EventGrain, type EventRecord, type FenceDialect, type FieldCatalogEntry, type FieldContribution, type FieldLeaf, type FieldRef, type FieldSourceRecord, type FieldValueKind, type FieldValueRecord, type FrontMatterSubtype, GIT_SHA, type IBlockKey, type ICodeMetadata, type ICodeStatement, type IDialect, type IDialectTagDescriptor, type IMetric, type IMetricOwnershipResolver, type IMetricSource, type IOutputStatement, type IScript, KNOWN_OUTPUT_TYPES, KNOWN_SECTION_WIDGETS, LEGACY_ORIGIN_TO_OWNERSHIP_LAYER, METRIC_OWNERSHIP_LAYER_CHAIN, type Membership, Metric, type MetricAction, MetricContainer, type MetricFilter, type MetricOrigin, type MetricOwnershipLayer, type MetricOwnershipLedger, type MetricOwnershipOutcome, type MetricOwnershipPromotionCandidate, type MetricOwnershipQuery, type MetricOwnershipResolvedContribution, type MetricOwnershipTypeExplanation, type MetricTemporal, MetricType, type MetricWithOptionalOwnershipLayer, NOTEBOOK_TAG_PREFIX, type Note, type NoteBlock, type NoteBlockChange, type NoteBlockKind, type NoteKind, type NoteTag, type Notebook, type NullValueKind, type Origin, OutputStatement, type OutputStatementOptions, type OutputStatementType, OwnershipResolver, type Page, type PageNote, type ParseError, ParsedCodeStatement, type ReconcileNoteBlocksOptions, type ReducerStats, type ResultOrigin, SEMVER, SYSTEM_DEFAULT_OUTPUT_UNIT, type ScriptBlock, type ScriptBlockState, type Section, type SectionDocument, type SectionRecognitionOptions, type SectionType, type Segment, type Session, type StoredOutputStatement, type SummaryCoverage, type Tag, type TagType, type TagTypeRecord, type TimeSpan, UNIT_CATALOG, UnitConversionError, type UnitDefinition, type UnitErrorCode, VALID_FENCE_DIALECTS, VERSION, type VisualizerFilter, type VisualizerSize, type WorkoutResults, type WorkoutSectionType, actionableSectionKind, blockContentId, buildRawContent, calculateTotalLines, convertViaCatalog, createMetricOwnershipLedger, detectScriptBlocks, dimensionKeyOf, extractBlockContent, fieldRefFromKey, fieldRefKey, findBlockAtLine, flattenFieldLeaves, fromNotebookTag, getMetricOwnershipLayer, isNotebookTag, isWorkoutSectionType, lookupUnit, mapNoteBlockChanges, matchDialectFence, normalizeFieldComponent, normalizeFieldPath, ownershipRank, parseDocumentSections, reconcileNoteBlocks, resolveLayer, runAffordance, systemDefaultUnit, toNotebookTag, validateNoteBlocks, valueKindOf };
package/dist/index.d.ts CHANGED
@@ -461,7 +461,9 @@ interface UnitDefinition {
461
461
  * unitless (factor 1).
462
462
  */
463
463
  declare const UNIT_CATALOG: readonly UnitDefinition[];
464
- /** Look up a unit by canonical spelling or alias (case-insensitive). */
464
+ /** Look up a unit by canonical spelling or alias (case-insensitive). Stored
465
+ * event rows are a trust boundary — a missing/legacy unit arrives as
466
+ * undefined at runtime despite the static type. */
465
467
  declare function lookupUnit(spelling: string): UnitDefinition | undefined;
466
468
  /** The named result dimension of a unit spelling, or undefined when the
467
469
  * spelling is not in the catalog. */
@@ -863,13 +865,7 @@ interface Segment {
863
865
  metrics?: MetricContainer;
864
866
  }
865
867
 
866
- /**
867
- * Content-stable identity for a workout block.
868
- *
869
- * A 32-bit FNV-1a hash of the trimmed fenced content, formatted as `bc-<8 hex>`.
870
- * Survives clone / reorder / edit-above so results and facts keyed by it stay
871
- * linked across runs.
872
- */
868
+ /** Cross-note fingerprint of the trimmed, unfenced workout body. Never an occurrence ID. */
873
869
  declare function blockContentId(content: string): string;
874
870
 
875
871
  /**
@@ -936,20 +932,44 @@ interface WorkoutResults {
936
932
  completed: boolean;
937
933
  }
938
934
 
939
- type SegmentDataType = 'script' | 'youtube' | 'markdown' | 'header' | 'frontmatter' | 'wod' | 'title' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
935
+ type NoteBlockKind = 'wod' | 'query' | 'widget' | 'embed';
936
+ interface NoteBlock {
937
+ id: string;
938
+ kind: NoteBlockKind;
939
+ version: number;
940
+ sourceRevision: number;
941
+ from: number;
942
+ to: number;
943
+ dialect?: 'time' | 'log';
944
+ sport?: string;
945
+ }
946
+ interface BlockRevision {
947
+ noteId: string;
948
+ blockId: string;
949
+ version: number;
950
+ kind: NoteBlockKind;
951
+ rawContent: string;
952
+ savedAt: number;
953
+ dialect?: 'time' | 'log';
954
+ sport?: string;
955
+ }
940
956
  type NoteKind = 'journal' | 'template' | 'playground' | 'feed' | 'dashboard' | 'page' | (string & {});
941
957
  interface Note {
942
958
  id: string;
943
959
  title: string;
960
+ rawContent: string;
961
+ sourceRevision: number;
962
+ blocks: Record<string, NoteBlock>;
944
963
  date?: number;
945
964
  createdAt: number;
946
965
  type?: NoteKind;
947
966
  sourceId?: string;
948
967
  catalog?: string;
949
968
  tags?: string[];
950
- /** Original seed file path (e.g. `markdown/collections/girls/fran.md`) — the
951
- * deterministic UUID is derived from this path; retained for seed content
952
- * reconstruction (canvas routes, collection READMEs, block-index lookup). */
969
+ seedOrigin?: 'seed' | 'user';
970
+ seedVersion?: number;
971
+ seedChunkId?: string;
972
+ /** Authored seed path used for deterministic identity and routing. */
953
973
  sourcePath?: string;
954
974
  }
955
975
  interface Page {
@@ -985,48 +1005,36 @@ interface NoteTag {
985
1005
  noteId: string;
986
1006
  tagId: string;
987
1007
  }
988
- interface NoteSegment {
989
- id: string;
990
- version: number;
991
- noteId: string;
992
- position?: number;
993
- pageId?: string;
994
- dataType: SegmentDataType;
995
- data: unknown;
996
- rawContent: string;
997
- createdAt: number;
998
- updatedAt?: number;
999
- isHistory?: boolean;
1000
- }
1001
1008
  interface BlockIndexRow {
1002
- /** Composite key: `${noteId}:${segmentId}:${segmentVersion}` */
1009
+ /** Current occurrence key `${noteId}:${blockId}`. */
1003
1010
  id: string;
1004
1011
  noteId: string;
1005
- segmentId: string;
1006
- segmentVersion: number;
1012
+ blockId: string;
1013
+ blockVersion: number;
1014
+ sourceRevision: number;
1015
+ from: number;
1016
+ to: number;
1007
1017
  position?: number;
1008
- dataType: string;
1018
+ dataType: NoteBlock['kind'];
1009
1019
  blockContentId?: string;
1010
1020
  rawContent: string;
1011
1021
  noteTitle: string;
1012
1022
  createdAt: number;
1013
1023
  isStatic?: boolean;
1014
1024
  sourceId?: string;
1025
+ sourcePath?: string;
1026
+ routeId?: string;
1015
1027
  }
1016
1028
  type ResultOrigin = 'journal' | 'playground' | 'user';
1017
1029
  interface Session {
1018
1030
  id: string;
1019
- segmentId?: string;
1020
- segmentVersion?: number;
1021
1031
  noteId: string;
1022
- blockId?: string;
1032
+ blockId: string;
1033
+ blockVersion: number;
1023
1034
  blockContentId?: string;
1024
- version?: number;
1025
1035
  origin?: ResultOrigin;
1026
1036
  pageId?: string;
1027
- /** Write-path lifecycle (ticket 005): row born 'in-progress' at workout
1028
- * start, flipped to 'completed' at finalize. Absent = 'completed'
1029
- * (legacy rows predate streaming). */
1037
+ /** Born in-progress at run start, completed when finalization commits. */
1030
1038
  status?: 'in-progress' | 'completed';
1031
1039
  /** When workout started */
1032
1040
  startTime: number;
@@ -1073,8 +1081,8 @@ interface AnalyticsDataPoint {
1073
1081
  * partitions) — normalized key → value, resolved by factTagValue after
1074
1082
  * the structural switch so `by {coach}` / `{coach:greg}` work. */
1075
1083
  dimensions?: Record<string, string>;
1076
- segmentId: string;
1077
- segmentVersion: number;
1084
+ blockId: string;
1085
+ blockVersion: number;
1078
1086
  resultId: string;
1079
1087
  type: string;
1080
1088
  value: unknown;
@@ -1145,8 +1153,8 @@ interface EventRecord {
1145
1153
  dialect?: string;
1146
1154
  stackLevel?: number;
1147
1155
  completionReason?: string;
1148
- segmentId?: string;
1149
- segmentVersion?: number;
1156
+ blockId?: string;
1157
+ blockVersion?: number;
1150
1158
  /** Per-metric temporal anchors (ticket 12) — parallel to `metrics` when
1151
1159
  * the producing statement carries its own instants/dates:
1152
1160
  * 'instant' = recorded occurrence instant; 'civil-date' = recorded civil
@@ -1253,6 +1261,28 @@ interface CatalogBackfillState {
1253
1261
  revision: number;
1254
1262
  updatedAt: number;
1255
1263
  }
1264
+ interface BlockEffort {
1265
+ id: string;
1266
+ noteId: string;
1267
+ blockId: string;
1268
+ blockContentId?: string;
1269
+ effortSlug: string;
1270
+ isStatic?: boolean;
1271
+ sourcePath?: string;
1272
+ createdAt: number;
1273
+ }
1274
+ interface Membership {
1275
+ id: string;
1276
+ displayName: string;
1277
+ picture?: string;
1278
+ weight?: number;
1279
+ weightUnit?: 'kg' | 'lb';
1280
+ height?: number;
1281
+ heightUnit?: 'cm' | 'in';
1282
+ birthDate?: string;
1283
+ createdAt: number;
1284
+ updatedAt?: number;
1285
+ }
1256
1286
 
1257
1287
  /**
1258
1288
  * State of a WOD block
@@ -1292,7 +1322,7 @@ type FrontMatterSubtype = 'default' | 'youtube' | 'strava' | 'amazon' | 'file' |
1292
1322
  interface ScriptBlock {
1293
1323
  /** Unique identifier for this block */
1294
1324
  id: string;
1295
- /** Content-stable identity */
1325
+ /** Cross-note content fingerprint, never occurrence identity. */
1296
1326
  contentId?: string;
1297
1327
  /** Workout fence tag ('time' runnable / 'log' recorded) */
1298
1328
  dialect?: FenceDialect;
@@ -1324,6 +1354,13 @@ interface Section {
1324
1354
  id: string;
1325
1355
  contentId?: string;
1326
1356
  type: SectionType;
1357
+ /** Half-open UTF-16 offsets in the exact authored document. */
1358
+ from: number;
1359
+ to: number;
1360
+ contentFrom?: number;
1361
+ contentTo?: number;
1362
+ querySuffix?: string;
1363
+ separatorAfter?: string;
1327
1364
  subtype?: string;
1328
1365
  rawContent: string;
1329
1366
  displayContent: string;
@@ -1387,14 +1424,6 @@ interface IScript {
1387
1424
  getAt(index: number): ICodeStatement | undefined;
1388
1425
  }
1389
1426
 
1390
- /**
1391
- * Try to match a line against known workout fence patterns.
1392
- * Returns the base tag and optional :sport suffix, or null otherwise.
1393
- */
1394
- declare function matchDialectFence(trimmedLine: string): {
1395
- dialect: FenceDialect;
1396
- sport?: string;
1397
- } | null;
1398
1427
  /**
1399
1428
  * Detects all WOD blocks in markdown content.
1400
1429
  * Recognises ```time and ```log as valid workout fences (optional :sport suffix).
@@ -1421,33 +1450,44 @@ declare function findBlockAtLine(blocks: ScriptBlock[], lineNumber: number): Scr
1421
1450
  */
1422
1451
  declare function extractBlockContent(content: string, startLine: number, endLine: number): string;
1423
1452
 
1424
- interface SectionMetadata {
1425
- id: string;
1426
- version: number;
1427
- createdAt: number;
1428
- }
1429
- /**
1430
- * Generate a deterministic section ID from type, startLine (0-indexed), and a content hash.
1431
- * Stable across re-parses when structure doesn't change.
1432
- */
1433
- declare function generateSectionId(type: SectionType | string, startLine: number, content: string): string;
1434
-
1435
- declare function parseDocumentSections(content: string, scriptBlocks?: ScriptBlock[]): Section[];
1453
+ declare const KNOWN_SECTION_WIDGETS: readonly string[];
1454
+ declare function matchDialectFence(trimmedLine: string): {
1455
+ dialect: 'time' | 'log';
1456
+ sport?: string;
1457
+ } | null;
1458
+ interface SectionRecognitionOptions {
1459
+ registeredWidgets?: ReadonlySet<string> | readonly string[];
1460
+ }
1461
+ interface ReconcileNoteBlocksOptions extends SectionRecognitionOptions {
1462
+ sourceRevision: number;
1463
+ /** Current-source occurrence lineage, not a previous document's locations. */
1464
+ blocks?: Record<string, NoteBlock>;
1465
+ createId?: () => string;
1466
+ }
1467
+ declare function parseDocumentSections(content: string, options?: SectionRecognitionOptions): Section[];
1468
+ declare function actionableSectionKind(section: Section): NoteBlock['kind'] | null;
1469
+ declare function reconcileNoteBlocks(rawContent: string, options: ReconcileNoteBlocksOptions): Record<string, NoteBlock>;
1470
+ declare function validateNoteBlocks(rawContent: string, blocks: Record<string, NoteBlock>, sourceRevision: number, options?: SectionRecognitionOptions): void;
1471
+ interface NoteBlockChange {
1472
+ from: number;
1473
+ to: number;
1474
+ insert: string;
1475
+ }
1476
+ declare function mapNoteBlockChanges(blocks: Record<string, NoteBlock>, changes: readonly NoteBlockChange[]): Record<string, NoteBlock>;
1436
1477
  declare function buildRawContent(sections: Section[]): string;
1437
1478
  declare function calculateTotalLines(sections: Section[]): number;
1438
- declare function matchSectionIds(oldSections: Section[], newSections: Section[]): Section[];
1439
1479
 
1440
1480
  /**
1441
1481
  * Auto-generated build version metadata.
1442
1482
  * Do not edit directly; updated by scripts/stamp-version.ts
1443
1483
  */
1444
- declare const VERSION = "0.35.2116";
1445
- declare const GIT_SHA = "a4d411f";
1446
- declare const BUILD_TIME = "2026-10-12T00:14:24.795Z";
1484
+ declare const VERSION = "0.35.2117";
1485
+ declare const GIT_SHA = "03d1dfc";
1486
+ declare const BUILD_TIME = "2026-10-12T20:08:12.374Z";
1447
1487
  declare const SEMVER: {
1448
- readonly version: "0.35.2116";
1449
- readonly gitSha: "a4d411f";
1450
- readonly buildTime: "2026-10-12T00:14:24.795Z";
1488
+ readonly version: "0.35.2117";
1489
+ readonly gitSha: "03d1dfc";
1490
+ readonly buildTime: "2026-10-12T20:08:12.374Z";
1451
1491
  };
1452
1492
 
1453
- export { type AnalyticsDataPoint, type AnalyticsGraphConfig, type AnalyticsGroup, type Attachment, BUILD_TIME, type BlockIndexRow, BlockKey, type CatalogBackfillState, CodeMetadata, CodeStatement, type DialectAnalysis, type DimensionKey, type DisplayStatus, type EventGrain, type EventRecord, type FenceDialect, type FieldCatalogEntry, type FieldContribution, type FieldLeaf, type FieldRef, type FieldSourceRecord, type FieldValueKind, type FieldValueRecord, type FrontMatterSubtype, GIT_SHA, type IBlockKey, type ICodeMetadata, type ICodeStatement, type IDialect, type IDialectTagDescriptor, type IMetric, type IMetricOwnershipResolver, type IMetricSource, type IOutputStatement, type IScript, KNOWN_OUTPUT_TYPES, LEGACY_ORIGIN_TO_OWNERSHIP_LAYER, METRIC_OWNERSHIP_LAYER_CHAIN, Metric, type MetricAction, MetricContainer, type MetricFilter, type MetricOrigin, type MetricOwnershipLayer, type MetricOwnershipLedger, type MetricOwnershipOutcome, type MetricOwnershipPromotionCandidate, type MetricOwnershipQuery, type MetricOwnershipResolvedContribution, type MetricOwnershipTypeExplanation, type MetricTemporal, MetricType, type MetricWithOptionalOwnershipLayer, NOTEBOOK_TAG_PREFIX, type Note, type NoteKind, type NoteSegment, type NoteTag, type Notebook, type NullValueKind, type Origin, OutputStatement, type OutputStatementOptions, type OutputStatementType, OwnershipResolver, type Page, type PageNote, type ParseError, ParsedCodeStatement, type ReducerStats, type ResultOrigin, SEMVER, SYSTEM_DEFAULT_OUTPUT_UNIT, type ScriptBlock, type ScriptBlockState, type Section, type SectionDocument, type SectionMetadata, type SectionType, type Segment, type SegmentDataType, type Session, type StoredOutputStatement, type SummaryCoverage, type Tag, type TagType, type TagTypeRecord, type TimeSpan, UNIT_CATALOG, UnitConversionError, type UnitDefinition, type UnitErrorCode, VALID_FENCE_DIALECTS, VERSION, type VisualizerFilter, type VisualizerSize, type WorkoutResults, type WorkoutSectionType, blockContentId, buildRawContent, calculateTotalLines, convertViaCatalog, createMetricOwnershipLedger, detectScriptBlocks, dimensionKeyOf, extractBlockContent, fieldRefFromKey, fieldRefKey, findBlockAtLine, flattenFieldLeaves, fromNotebookTag, generateSectionId, getMetricOwnershipLayer, isNotebookTag, isWorkoutSectionType, lookupUnit, matchDialectFence, matchSectionIds, normalizeFieldComponent, normalizeFieldPath, ownershipRank, parseDocumentSections, resolveLayer, runAffordance, systemDefaultUnit, toNotebookTag, valueKindOf };
1493
+ export { type AnalyticsDataPoint, type AnalyticsGraphConfig, type AnalyticsGroup, type Attachment, BUILD_TIME, type BlockEffort, type BlockIndexRow, BlockKey, type BlockRevision, type CatalogBackfillState, CodeMetadata, CodeStatement, type DialectAnalysis, type DimensionKey, type DisplayStatus, type EventGrain, type EventRecord, type FenceDialect, type FieldCatalogEntry, type FieldContribution, type FieldLeaf, type FieldRef, type FieldSourceRecord, type FieldValueKind, type FieldValueRecord, type FrontMatterSubtype, GIT_SHA, type IBlockKey, type ICodeMetadata, type ICodeStatement, type IDialect, type IDialectTagDescriptor, type IMetric, type IMetricOwnershipResolver, type IMetricSource, type IOutputStatement, type IScript, KNOWN_OUTPUT_TYPES, KNOWN_SECTION_WIDGETS, LEGACY_ORIGIN_TO_OWNERSHIP_LAYER, METRIC_OWNERSHIP_LAYER_CHAIN, type Membership, Metric, type MetricAction, MetricContainer, type MetricFilter, type MetricOrigin, type MetricOwnershipLayer, type MetricOwnershipLedger, type MetricOwnershipOutcome, type MetricOwnershipPromotionCandidate, type MetricOwnershipQuery, type MetricOwnershipResolvedContribution, type MetricOwnershipTypeExplanation, type MetricTemporal, MetricType, type MetricWithOptionalOwnershipLayer, NOTEBOOK_TAG_PREFIX, type Note, type NoteBlock, type NoteBlockChange, type NoteBlockKind, type NoteKind, type NoteTag, type Notebook, type NullValueKind, type Origin, OutputStatement, type OutputStatementOptions, type OutputStatementType, OwnershipResolver, type Page, type PageNote, type ParseError, ParsedCodeStatement, type ReconcileNoteBlocksOptions, type ReducerStats, type ResultOrigin, SEMVER, SYSTEM_DEFAULT_OUTPUT_UNIT, type ScriptBlock, type ScriptBlockState, type Section, type SectionDocument, type SectionRecognitionOptions, type SectionType, type Segment, type Session, type StoredOutputStatement, type SummaryCoverage, type Tag, type TagType, type TagTypeRecord, type TimeSpan, UNIT_CATALOG, UnitConversionError, type UnitDefinition, type UnitErrorCode, VALID_FENCE_DIALECTS, VERSION, type VisualizerFilter, type VisualizerSize, type WorkoutResults, type WorkoutSectionType, actionableSectionKind, blockContentId, buildRawContent, calculateTotalLines, convertViaCatalog, createMetricOwnershipLedger, detectScriptBlocks, dimensionKeyOf, extractBlockContent, fieldRefFromKey, fieldRefKey, findBlockAtLine, flattenFieldLeaves, fromNotebookTag, getMetricOwnershipLayer, isNotebookTag, isWorkoutSectionType, lookupUnit, mapNoteBlockChanges, matchDialectFence, normalizeFieldComponent, normalizeFieldPath, ownershipRank, parseDocumentSections, reconcileNoteBlocks, resolveLayer, runAffordance, systemDefaultUnit, toNotebookTag, validateNoteBlocks, valueKindOf };