@bitcobblers/wod-wiki-lang 0.48.2171 → 0.48.2172

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.
@@ -800,6 +800,13 @@ declare function compoundName(d: DimVector): string | undefined;
800
800
 
801
801
  type CalcOrigin = 'analyzed' | 'analyzed-estimated' | 'user';
802
802
  type CalcScope = 'segment' | 'workout' | 'store';
803
+ /** A note summary that failed registration — surfaced, never silently dropped. */
804
+ interface CalcRegistrationDiagnostic {
805
+ /** The summary calc id that failed to register. */
806
+ id: string;
807
+ /** Why it was skipped (the registration error message). */
808
+ message: string;
809
+ }
803
810
  interface CalcNode {
804
811
  id: string;
805
812
  kind: 'metric' | 'lookup' | 'builtin' | 'wql' | 'expr';
@@ -994,6 +1001,8 @@ interface ShakeOutQueueOptions {
994
1001
  readonly sources: readonly PropertyRuleInput[];
995
1002
  readonly lookups?: LookupRegistry;
996
1003
  readonly lastEffortSlug?: string;
1004
+ /** Structural outputs may evaluate rules without surfacing diagnostics. */
1005
+ readonly emitDiagnostics?: boolean;
997
1006
  }
998
1007
  /**
999
1008
  * Extract `metrics:` and `summaries:` maps from a parsed frontmatter record
@@ -1006,12 +1015,13 @@ declare function extractPropertyRulesFromMeta(meta: Readonly<Record<string, unkn
1006
1015
  * `summaries.<key>` contributions on tags (including nested tags).
1007
1016
  */
1008
1017
  declare function extractTagPropertyRules(tags: TagIndex | undefined, slugs: readonly string[]): PropertyRuleInput[];
1009
- /**
1010
- * Compile `summaries:` equations across stacked Property Notes into workout-scope
1011
- * `CalculationDefinition` records. Higher-precedence layers shadow lower layers
1012
- * when both define the same summary key.
1013
- */
1018
+ /** Compiled note summaries plus the unresolved dependencies found while compiling. */
1019
+ interface CompiledPropertySummaries {
1020
+ defs: CalculationDefinition[];
1021
+ diagnostics: CalcRegistrationDiagnostic[];
1022
+ }
1014
1023
  declare function compilePropertySummaryCalcs(sources: readonly PropertyRuleInput[]): CalculationDefinition[];
1024
+ declare function compilePropertySummaryCalcsWithDiagnostics(sources: readonly PropertyRuleInput[]): CompiledPropertySummaries;
1015
1025
  /**
1016
1026
  * Run the two-stage Metric Shake-Out Queue on a statement's MetricContainer.
1017
1027
  */
@@ -1541,6 +1551,21 @@ interface IBlockRef {
1541
1551
  markComplete(reason?: string): void;
1542
1552
  }
1543
1553
 
1554
+ /**
1555
+ * INowProvider — the only seam for "what time is it" in the runtime.
1556
+ * Events, actions, and behaviors that need a timestamp take a now-fn
1557
+ * in their constructor; the runtime passes its single provider down.
1558
+ * Tests pass a frozen clock so the timeline is deterministic.
1559
+ */
1560
+ interface INowProvider {
1561
+ now(): Date;
1562
+ nowMs(): number;
1563
+ }
1564
+ /** Default provider: reads wall clock. */
1565
+ declare const wallClockNow: INowProvider;
1566
+ /** A provider that always returns the same Date (for tests). */
1567
+ declare function frozenNow(at: Date): INowProvider;
1568
+
1544
1569
  /**
1545
1570
  * TimeSpan represents a discrete segment of a block's **Time** — a single
1546
1571
  * start/stop recording within the spans collection.
@@ -1580,21 +1605,6 @@ declare class TimeSpan implements TimeSpan$1 {
1580
1605
  get endDate(): Date | undefined;
1581
1606
  }
1582
1607
 
1583
- /**
1584
- * INowProvider — the only seam for "what time is it" in the runtime.
1585
- * Events, actions, and behaviors that need a timestamp take a now-fn
1586
- * in their constructor; the runtime passes its single provider down.
1587
- * Tests pass a frozen clock so the timeline is deterministic.
1588
- */
1589
- interface INowProvider {
1590
- now(): Date;
1591
- nowMs(): number;
1592
- }
1593
- /** Default provider: reads wall clock. */
1594
- declare const wallClockNow: INowProvider;
1595
- /** A provider that always returns the same Date (for tests). */
1596
- declare function frozenNow(at: Date): INowProvider;
1597
-
1598
1608
  /**
1599
1609
  * IRuntimeClock provides time tracking for the runtime.
1600
1610
  *
@@ -1877,6 +1887,8 @@ interface IBehaviorContext {
1877
1887
  readonly block: IBlockRef;
1878
1888
  /** Current runtime clock */
1879
1889
  readonly clock: IRuntimeClock;
1890
+ /** Live wall-clock provider, independent of execution snapshots. */
1891
+ readonly nowProvider: INowProvider;
1880
1892
  /**
1881
1893
  * Current stack level (depth) of the block.
1882
1894
  * 0 = root block, 1 = first child, etc.
@@ -2991,4 +3003,4 @@ declare function getRuntimeNowMs(): number;
2991
3003
  /** Creates an INowProvider that reads the browser sender-clock when available. */
2992
3004
  declare function createBrowserRuntimeNow(): INowProvider;
2993
3005
 
2994
- export { type SoundProfile as $, type AnalyticsContext as A, type BehaviorEventType as B, type IMemoryLocation as C, type IRuntimeBehavior as D, type EffortResolverOptions as E, type IBlockContext as F, type MetricVisibility as G, type BlockLifecycleOptions as H, type IEquipment as I, type CompletionDecision as J, type IRuntimeMemory as K, TypedMemoryReference as L, type MemoryTag as M, type MemorySearchCriteria as N, type OutputListener as O, type IMemoryReference as P, type RuntimeStackLogger as Q, type ReferenceIndex as R, type SubscribeOptions as S, TimeSpan as T, type Unsubscribe as U, type StackObserver as V, WhiteboardScript as W, type StackSnapshot as X, type StackListener as Y, MemoryTypeEnum as Z, type IAnchorValue as _, type ReferenceResolutionDefaults as a, type MemoryValueOf as a$, type ButtonConfig as a0, type IEventHandler as a1, type HandlerScope as a2, type IScriptRuntime as a3, type TestableBlockConfig as a4, type IRuntimeOptions as a5, ScriptRuntime as a6, type EventHandlerOptions as a7, type EventCallback as a8, type TimerState as a9, DIM_LENGTH as aA, DIM_MASS as aB, DIM_TIME as aC, DIM_ZERO as aD, DISCIPLINE_FACTORS as aE, type DisplayState as aF, EFFORT_DISCIPLINES as aG, EFFORT_REGISTRY_ORIGINS as aH, type EffortBaseAttributes as aI, type EffortDerivation as aJ, type EffortDiscipline as aK, type EffortMaterializer as aL, type EffortResolvedFrom as aM, type EvalContext as aN, type FenceDialect as aO, type FragmentDisplayState as aP, type FragmentState as aQ, type IAnalyticsProcessorDescriptor as aR, INTENSITY_TIERS as aS, type IScript as aT, type IntensityTier as aU, type InterceptMode as aV, type LookupFieldDef as aW, type LookupLayer as aX, MemoryLocation as aY, type MemoryType as aZ, type MemoryTypeMap as a_, type CalculationDefinition as aa, type PropertyRuleInput as ab, type IRealtimeProcessor as ac, type ISummaryProcessor as ad, type DimVector as ae, type CalcLine as af, type ExprNode as ag, type CalcScope as ah, type ILookupTable as ai, LookupRegistry as aj, type ProjectionResult as ak, ABSENT as al, type BinaryOp as am, type ButtonVariant as an, type ButtonsState as ao, CalcEvalError as ap, type CalcNode as aq, type CalcOrigin as ar, type CalcVariant as as, type ChildrenStatusState as at, type CompletionState as au, DEFAULT_RESOLVER_OPTIONS as av, DEFAULT_RUNTIME_OPTIONS as aw, DEFAULT_SOUND_PROFILE as ax, DIM_COUNT as ay, DIM_ENERGY as az, type IEffort as b, NAMED_COMPOUNDS as b0, type PropertySourceLayer as b1, type ReferenceCatalog as b2, type ResolvedReferences as b3, type RoundState as b4, type RuntimeState as b5, SEED_PRECEDENCE_RANK as b6, type ScriptRuntimeDependencies as b7, type SeedPrecedenceTier as b8, type ShakeOutQueueOptions as b9, getMetricVisibility as bA, getRuntimeNowMs as bB, isDimensionless as bC, isEffortDiscipline as bD, isFragmentTag as bE, num as bF, parseSoundTrigger as bG, resolveEntityRank as bH, resolveEntityTier as bI, resolveProfileRules as bJ, resolveSourceRank as bK, resolveSourceTier as bL, runMetricShakeOutQueue as bM, slugifyRefLabel as bN, str as bO, subDim as bP, truthy as bQ, wallClockNow as bR, type ShakeOutResult as ba, type SkippedDependencyDiagnostic as bb, type SoundRule as bc, type SoundTriggerAnchor as bd, type SoundTriggerPoint as be, type StackEvent as bf, type TimerDirection as bg, VISIBILITY_ICONS as bh, VISIBILITY_LABELS as bi, type Val as bj, addDim as bk, compilePropertySummaryCalcs as bl, compoundName as bm, createBrowserRuntimeNow as bn, createReferenceIndex as bo, dedupeEntitiesByPrecedence as bp, dimEquals as bq, disciplineFactorFor as br, evaluate as bs, extractPropertyRulesFromMeta as bt, extractStatementRefs as bu, extractTagPropertyRules as bv, filterTagsByVisibility as bw, formatDim as bx, formatSoundTrigger as by, frozenNow as bz, type IEffortResolver as c, type IEffortRegistry as d, type EffortResolutionOptions as e, type ResolvedEffort as f, type EffortRegistrySource as g, type IEquipmentRegistry as h, type EquipmentStorageAdapter as i, type EffortStorageAdapter as j, type IRuntimeActionable as k, type IEventBus as l, type IRuntimeStack as m, type IRuntimeClock as n, type IJitCompiler as o, type INowProvider as p, type RuntimeStackOptions as q, type RuntimeError as r, type IEvent as s, type IRuntimeAction as t, type IAnalyticsEngine as u, type IRuntimeBlock as v, type IBehaviorContext as w, type BehaviorEventListener as x, type Unsubscribe$1 as y, type OutputOptions as z };
3006
+ export { type SoundProfile as $, type AnalyticsContext as A, type BehaviorEventType as B, type IMemoryLocation as C, type IRuntimeBehavior as D, type EffortResolverOptions as E, type IBlockContext as F, type MetricVisibility as G, type BlockLifecycleOptions as H, type IEquipment as I, type CompletionDecision as J, type IRuntimeMemory as K, TypedMemoryReference as L, type MemoryTag as M, type MemorySearchCriteria as N, type OutputListener as O, type IMemoryReference as P, type RuntimeStackLogger as Q, type ReferenceIndex as R, type SubscribeOptions as S, TimeSpan as T, type Unsubscribe as U, type StackObserver as V, WhiteboardScript as W, type StackSnapshot as X, type StackListener as Y, MemoryTypeEnum as Z, type IAnchorValue as _, type ReferenceResolutionDefaults as a, type MemoryType as a$, type ButtonConfig as a0, type IEventHandler as a1, type HandlerScope as a2, type IScriptRuntime as a3, type TestableBlockConfig as a4, type IRuntimeOptions as a5, ScriptRuntime as a6, type EventHandlerOptions as a7, type EventCallback as a8, type TimerState as a9, DIM_COUNT as aA, DIM_ENERGY as aB, DIM_LENGTH as aC, DIM_MASS as aD, DIM_TIME as aE, DIM_ZERO as aF, DISCIPLINE_FACTORS as aG, type DisplayState as aH, EFFORT_DISCIPLINES as aI, EFFORT_REGISTRY_ORIGINS as aJ, type EffortBaseAttributes as aK, type EffortDerivation as aL, type EffortDiscipline as aM, type EffortMaterializer as aN, type EffortResolvedFrom as aO, type EvalContext as aP, type FenceDialect as aQ, type FragmentDisplayState as aR, type FragmentState as aS, type IAnalyticsProcessorDescriptor as aT, INTENSITY_TIERS as aU, type IScript as aV, type IntensityTier as aW, type InterceptMode as aX, type LookupFieldDef as aY, type LookupLayer as aZ, MemoryLocation as a_, type CalculationDefinition as aa, type PropertyRuleInput as ab, type IRealtimeProcessor as ac, type ISummaryProcessor as ad, type DimVector as ae, type CalcLine as af, type ExprNode as ag, type CalcScope as ah, type ILookupTable as ai, LookupRegistry as aj, type CalcRegistrationDiagnostic as ak, type ProjectionResult as al, ABSENT as am, type BinaryOp as an, type ButtonVariant as ao, type ButtonsState as ap, CalcEvalError as aq, type CalcNode as ar, type CalcOrigin as as, type CalcVariant as at, type ChildrenStatusState as au, type CompiledPropertySummaries as av, type CompletionState as aw, DEFAULT_RESOLVER_OPTIONS as ax, DEFAULT_RUNTIME_OPTIONS as ay, DEFAULT_SOUND_PROFILE as az, type IEffort as b, type MemoryTypeMap as b0, type MemoryValueOf as b1, NAMED_COMPOUNDS as b2, type PropertySourceLayer as b3, type ReferenceCatalog as b4, type ResolvedReferences as b5, type RoundState as b6, type RuntimeState as b7, SEED_PRECEDENCE_RANK as b8, type ScriptRuntimeDependencies as b9, formatDim as bA, formatSoundTrigger as bB, frozenNow as bC, getMetricVisibility as bD, getRuntimeNowMs as bE, isDimensionless as bF, isEffortDiscipline as bG, isFragmentTag as bH, num as bI, parseSoundTrigger as bJ, resolveEntityRank as bK, resolveEntityTier as bL, resolveProfileRules as bM, resolveSourceRank as bN, resolveSourceTier as bO, runMetricShakeOutQueue as bP, slugifyRefLabel as bQ, str as bR, subDim as bS, truthy as bT, wallClockNow as bU, type SeedPrecedenceTier as ba, type ShakeOutQueueOptions as bb, type ShakeOutResult as bc, type SkippedDependencyDiagnostic as bd, type SoundRule as be, type SoundTriggerAnchor as bf, type SoundTriggerPoint as bg, type StackEvent as bh, type TimerDirection as bi, VISIBILITY_ICONS as bj, VISIBILITY_LABELS as bk, type Val as bl, addDim as bm, compilePropertySummaryCalcs as bn, compilePropertySummaryCalcsWithDiagnostics as bo, compoundName as bp, createBrowserRuntimeNow as bq, createReferenceIndex as br, dedupeEntitiesByPrecedence as bs, dimEquals as bt, disciplineFactorFor as bu, evaluate as bv, extractPropertyRulesFromMeta as bw, extractStatementRefs as bx, extractTagPropertyRules as by, filterTagsByVisibility as bz, type IEffortResolver as c, type IEffortRegistry as d, type EffortResolutionOptions as e, type ResolvedEffort as f, type EffortRegistrySource as g, type IEquipmentRegistry as h, type EquipmentStorageAdapter as i, type EffortStorageAdapter as j, type IRuntimeActionable as k, type IEventBus as l, type IRuntimeStack as m, type IRuntimeClock as n, type IJitCompiler as o, type INowProvider as p, type RuntimeStackOptions as q, type RuntimeError as r, type IEvent as s, type IRuntimeAction as t, type IAnalyticsEngine as u, type IRuntimeBlock as v, type IBehaviorContext as w, type BehaviorEventListener as x, type Unsubscribe$1 as y, type OutputOptions as z };
@@ -800,6 +800,13 @@ declare function compoundName(d: DimVector): string | undefined;
800
800
 
801
801
  type CalcOrigin = 'analyzed' | 'analyzed-estimated' | 'user';
802
802
  type CalcScope = 'segment' | 'workout' | 'store';
803
+ /** A note summary that failed registration — surfaced, never silently dropped. */
804
+ interface CalcRegistrationDiagnostic {
805
+ /** The summary calc id that failed to register. */
806
+ id: string;
807
+ /** Why it was skipped (the registration error message). */
808
+ message: string;
809
+ }
803
810
  interface CalcNode {
804
811
  id: string;
805
812
  kind: 'metric' | 'lookup' | 'builtin' | 'wql' | 'expr';
@@ -994,6 +1001,8 @@ interface ShakeOutQueueOptions {
994
1001
  readonly sources: readonly PropertyRuleInput[];
995
1002
  readonly lookups?: LookupRegistry;
996
1003
  readonly lastEffortSlug?: string;
1004
+ /** Structural outputs may evaluate rules without surfacing diagnostics. */
1005
+ readonly emitDiagnostics?: boolean;
997
1006
  }
998
1007
  /**
999
1008
  * Extract `metrics:` and `summaries:` maps from a parsed frontmatter record
@@ -1006,12 +1015,13 @@ declare function extractPropertyRulesFromMeta(meta: Readonly<Record<string, unkn
1006
1015
  * `summaries.<key>` contributions on tags (including nested tags).
1007
1016
  */
1008
1017
  declare function extractTagPropertyRules(tags: TagIndex | undefined, slugs: readonly string[]): PropertyRuleInput[];
1009
- /**
1010
- * Compile `summaries:` equations across stacked Property Notes into workout-scope
1011
- * `CalculationDefinition` records. Higher-precedence layers shadow lower layers
1012
- * when both define the same summary key.
1013
- */
1018
+ /** Compiled note summaries plus the unresolved dependencies found while compiling. */
1019
+ interface CompiledPropertySummaries {
1020
+ defs: CalculationDefinition[];
1021
+ diagnostics: CalcRegistrationDiagnostic[];
1022
+ }
1014
1023
  declare function compilePropertySummaryCalcs(sources: readonly PropertyRuleInput[]): CalculationDefinition[];
1024
+ declare function compilePropertySummaryCalcsWithDiagnostics(sources: readonly PropertyRuleInput[]): CompiledPropertySummaries;
1015
1025
  /**
1016
1026
  * Run the two-stage Metric Shake-Out Queue on a statement's MetricContainer.
1017
1027
  */
@@ -1541,6 +1551,21 @@ interface IBlockRef {
1541
1551
  markComplete(reason?: string): void;
1542
1552
  }
1543
1553
 
1554
+ /**
1555
+ * INowProvider — the only seam for "what time is it" in the runtime.
1556
+ * Events, actions, and behaviors that need a timestamp take a now-fn
1557
+ * in their constructor; the runtime passes its single provider down.
1558
+ * Tests pass a frozen clock so the timeline is deterministic.
1559
+ */
1560
+ interface INowProvider {
1561
+ now(): Date;
1562
+ nowMs(): number;
1563
+ }
1564
+ /** Default provider: reads wall clock. */
1565
+ declare const wallClockNow: INowProvider;
1566
+ /** A provider that always returns the same Date (for tests). */
1567
+ declare function frozenNow(at: Date): INowProvider;
1568
+
1544
1569
  /**
1545
1570
  * TimeSpan represents a discrete segment of a block's **Time** — a single
1546
1571
  * start/stop recording within the spans collection.
@@ -1580,21 +1605,6 @@ declare class TimeSpan implements TimeSpan$1 {
1580
1605
  get endDate(): Date | undefined;
1581
1606
  }
1582
1607
 
1583
- /**
1584
- * INowProvider — the only seam for "what time is it" in the runtime.
1585
- * Events, actions, and behaviors that need a timestamp take a now-fn
1586
- * in their constructor; the runtime passes its single provider down.
1587
- * Tests pass a frozen clock so the timeline is deterministic.
1588
- */
1589
- interface INowProvider {
1590
- now(): Date;
1591
- nowMs(): number;
1592
- }
1593
- /** Default provider: reads wall clock. */
1594
- declare const wallClockNow: INowProvider;
1595
- /** A provider that always returns the same Date (for tests). */
1596
- declare function frozenNow(at: Date): INowProvider;
1597
-
1598
1608
  /**
1599
1609
  * IRuntimeClock provides time tracking for the runtime.
1600
1610
  *
@@ -1877,6 +1887,8 @@ interface IBehaviorContext {
1877
1887
  readonly block: IBlockRef;
1878
1888
  /** Current runtime clock */
1879
1889
  readonly clock: IRuntimeClock;
1890
+ /** Live wall-clock provider, independent of execution snapshots. */
1891
+ readonly nowProvider: INowProvider;
1880
1892
  /**
1881
1893
  * Current stack level (depth) of the block.
1882
1894
  * 0 = root block, 1 = first child, etc.
@@ -2991,4 +3003,4 @@ declare function getRuntimeNowMs(): number;
2991
3003
  /** Creates an INowProvider that reads the browser sender-clock when available. */
2992
3004
  declare function createBrowserRuntimeNow(): INowProvider;
2993
3005
 
2994
- export { type SoundProfile as $, type AnalyticsContext as A, type BehaviorEventType as B, type IMemoryLocation as C, type IRuntimeBehavior as D, type EffortResolverOptions as E, type IBlockContext as F, type MetricVisibility as G, type BlockLifecycleOptions as H, type IEquipment as I, type CompletionDecision as J, type IRuntimeMemory as K, TypedMemoryReference as L, type MemoryTag as M, type MemorySearchCriteria as N, type OutputListener as O, type IMemoryReference as P, type RuntimeStackLogger as Q, type ReferenceIndex as R, type SubscribeOptions as S, TimeSpan as T, type Unsubscribe as U, type StackObserver as V, WhiteboardScript as W, type StackSnapshot as X, type StackListener as Y, MemoryTypeEnum as Z, type IAnchorValue as _, type ReferenceResolutionDefaults as a, type MemoryValueOf as a$, type ButtonConfig as a0, type IEventHandler as a1, type HandlerScope as a2, type IScriptRuntime as a3, type TestableBlockConfig as a4, type IRuntimeOptions as a5, ScriptRuntime as a6, type EventHandlerOptions as a7, type EventCallback as a8, type TimerState as a9, DIM_LENGTH as aA, DIM_MASS as aB, DIM_TIME as aC, DIM_ZERO as aD, DISCIPLINE_FACTORS as aE, type DisplayState as aF, EFFORT_DISCIPLINES as aG, EFFORT_REGISTRY_ORIGINS as aH, type EffortBaseAttributes as aI, type EffortDerivation as aJ, type EffortDiscipline as aK, type EffortMaterializer as aL, type EffortResolvedFrom as aM, type EvalContext as aN, type FenceDialect as aO, type FragmentDisplayState as aP, type FragmentState as aQ, type IAnalyticsProcessorDescriptor as aR, INTENSITY_TIERS as aS, type IScript as aT, type IntensityTier as aU, type InterceptMode as aV, type LookupFieldDef as aW, type LookupLayer as aX, MemoryLocation as aY, type MemoryType as aZ, type MemoryTypeMap as a_, type CalculationDefinition as aa, type PropertyRuleInput as ab, type IRealtimeProcessor as ac, type ISummaryProcessor as ad, type DimVector as ae, type CalcLine as af, type ExprNode as ag, type CalcScope as ah, type ILookupTable as ai, LookupRegistry as aj, type ProjectionResult as ak, ABSENT as al, type BinaryOp as am, type ButtonVariant as an, type ButtonsState as ao, CalcEvalError as ap, type CalcNode as aq, type CalcOrigin as ar, type CalcVariant as as, type ChildrenStatusState as at, type CompletionState as au, DEFAULT_RESOLVER_OPTIONS as av, DEFAULT_RUNTIME_OPTIONS as aw, DEFAULT_SOUND_PROFILE as ax, DIM_COUNT as ay, DIM_ENERGY as az, type IEffort as b, NAMED_COMPOUNDS as b0, type PropertySourceLayer as b1, type ReferenceCatalog as b2, type ResolvedReferences as b3, type RoundState as b4, type RuntimeState as b5, SEED_PRECEDENCE_RANK as b6, type ScriptRuntimeDependencies as b7, type SeedPrecedenceTier as b8, type ShakeOutQueueOptions as b9, getMetricVisibility as bA, getRuntimeNowMs as bB, isDimensionless as bC, isEffortDiscipline as bD, isFragmentTag as bE, num as bF, parseSoundTrigger as bG, resolveEntityRank as bH, resolveEntityTier as bI, resolveProfileRules as bJ, resolveSourceRank as bK, resolveSourceTier as bL, runMetricShakeOutQueue as bM, slugifyRefLabel as bN, str as bO, subDim as bP, truthy as bQ, wallClockNow as bR, type ShakeOutResult as ba, type SkippedDependencyDiagnostic as bb, type SoundRule as bc, type SoundTriggerAnchor as bd, type SoundTriggerPoint as be, type StackEvent as bf, type TimerDirection as bg, VISIBILITY_ICONS as bh, VISIBILITY_LABELS as bi, type Val as bj, addDim as bk, compilePropertySummaryCalcs as bl, compoundName as bm, createBrowserRuntimeNow as bn, createReferenceIndex as bo, dedupeEntitiesByPrecedence as bp, dimEquals as bq, disciplineFactorFor as br, evaluate as bs, extractPropertyRulesFromMeta as bt, extractStatementRefs as bu, extractTagPropertyRules as bv, filterTagsByVisibility as bw, formatDim as bx, formatSoundTrigger as by, frozenNow as bz, type IEffortResolver as c, type IEffortRegistry as d, type EffortResolutionOptions as e, type ResolvedEffort as f, type EffortRegistrySource as g, type IEquipmentRegistry as h, type EquipmentStorageAdapter as i, type EffortStorageAdapter as j, type IRuntimeActionable as k, type IEventBus as l, type IRuntimeStack as m, type IRuntimeClock as n, type IJitCompiler as o, type INowProvider as p, type RuntimeStackOptions as q, type RuntimeError as r, type IEvent as s, type IRuntimeAction as t, type IAnalyticsEngine as u, type IRuntimeBlock as v, type IBehaviorContext as w, type BehaviorEventListener as x, type Unsubscribe$1 as y, type OutputOptions as z };
3006
+ export { type SoundProfile as $, type AnalyticsContext as A, type BehaviorEventType as B, type IMemoryLocation as C, type IRuntimeBehavior as D, type EffortResolverOptions as E, type IBlockContext as F, type MetricVisibility as G, type BlockLifecycleOptions as H, type IEquipment as I, type CompletionDecision as J, type IRuntimeMemory as K, TypedMemoryReference as L, type MemoryTag as M, type MemorySearchCriteria as N, type OutputListener as O, type IMemoryReference as P, type RuntimeStackLogger as Q, type ReferenceIndex as R, type SubscribeOptions as S, TimeSpan as T, type Unsubscribe as U, type StackObserver as V, WhiteboardScript as W, type StackSnapshot as X, type StackListener as Y, MemoryTypeEnum as Z, type IAnchorValue as _, type ReferenceResolutionDefaults as a, type MemoryType as a$, type ButtonConfig as a0, type IEventHandler as a1, type HandlerScope as a2, type IScriptRuntime as a3, type TestableBlockConfig as a4, type IRuntimeOptions as a5, ScriptRuntime as a6, type EventHandlerOptions as a7, type EventCallback as a8, type TimerState as a9, DIM_COUNT as aA, DIM_ENERGY as aB, DIM_LENGTH as aC, DIM_MASS as aD, DIM_TIME as aE, DIM_ZERO as aF, DISCIPLINE_FACTORS as aG, type DisplayState as aH, EFFORT_DISCIPLINES as aI, EFFORT_REGISTRY_ORIGINS as aJ, type EffortBaseAttributes as aK, type EffortDerivation as aL, type EffortDiscipline as aM, type EffortMaterializer as aN, type EffortResolvedFrom as aO, type EvalContext as aP, type FenceDialect as aQ, type FragmentDisplayState as aR, type FragmentState as aS, type IAnalyticsProcessorDescriptor as aT, INTENSITY_TIERS as aU, type IScript as aV, type IntensityTier as aW, type InterceptMode as aX, type LookupFieldDef as aY, type LookupLayer as aZ, MemoryLocation as a_, type CalculationDefinition as aa, type PropertyRuleInput as ab, type IRealtimeProcessor as ac, type ISummaryProcessor as ad, type DimVector as ae, type CalcLine as af, type ExprNode as ag, type CalcScope as ah, type ILookupTable as ai, LookupRegistry as aj, type CalcRegistrationDiagnostic as ak, type ProjectionResult as al, ABSENT as am, type BinaryOp as an, type ButtonVariant as ao, type ButtonsState as ap, CalcEvalError as aq, type CalcNode as ar, type CalcOrigin as as, type CalcVariant as at, type ChildrenStatusState as au, type CompiledPropertySummaries as av, type CompletionState as aw, DEFAULT_RESOLVER_OPTIONS as ax, DEFAULT_RUNTIME_OPTIONS as ay, DEFAULT_SOUND_PROFILE as az, type IEffort as b, type MemoryTypeMap as b0, type MemoryValueOf as b1, NAMED_COMPOUNDS as b2, type PropertySourceLayer as b3, type ReferenceCatalog as b4, type ResolvedReferences as b5, type RoundState as b6, type RuntimeState as b7, SEED_PRECEDENCE_RANK as b8, type ScriptRuntimeDependencies as b9, formatDim as bA, formatSoundTrigger as bB, frozenNow as bC, getMetricVisibility as bD, getRuntimeNowMs as bE, isDimensionless as bF, isEffortDiscipline as bG, isFragmentTag as bH, num as bI, parseSoundTrigger as bJ, resolveEntityRank as bK, resolveEntityTier as bL, resolveProfileRules as bM, resolveSourceRank as bN, resolveSourceTier as bO, runMetricShakeOutQueue as bP, slugifyRefLabel as bQ, str as bR, subDim as bS, truthy as bT, wallClockNow as bU, type SeedPrecedenceTier as ba, type ShakeOutQueueOptions as bb, type ShakeOutResult as bc, type SkippedDependencyDiagnostic as bd, type SoundRule as be, type SoundTriggerAnchor as bf, type SoundTriggerPoint as bg, type StackEvent as bh, type TimerDirection as bi, VISIBILITY_ICONS as bj, VISIBILITY_LABELS as bk, type Val as bl, addDim as bm, compilePropertySummaryCalcs as bn, compilePropertySummaryCalcsWithDiagnostics as bo, compoundName as bp, createBrowserRuntimeNow as bq, createReferenceIndex as br, dedupeEntitiesByPrecedence as bs, dimEquals as bt, disciplineFactorFor as bu, evaluate as bv, extractPropertyRulesFromMeta as bw, extractStatementRefs as bx, extractTagPropertyRules as by, filterTagsByVisibility as bz, type IEffortResolver as c, type IEffortRegistry as d, type EffortResolutionOptions as e, type ResolvedEffort as f, type EffortRegistrySource as g, type IEquipmentRegistry as h, type EquipmentStorageAdapter as i, type EffortStorageAdapter as j, type IRuntimeActionable as k, type IEventBus as l, type IRuntimeStack as m, type IRuntimeClock as n, type IJitCompiler as o, type INowProvider as p, type RuntimeStackOptions as q, type RuntimeError as r, type IEvent as s, type IRuntimeAction as t, type IAnalyticsEngine as u, type IRuntimeBlock as v, type IBehaviorContext as w, type BehaviorEventListener as x, type Unsubscribe$1 as y, type OutputOptions as z };
package/dist/index.cjs CHANGED
@@ -4609,7 +4609,7 @@ function tagToDocument(tag) {
4609
4609
  lines.push(`# ${tag.label}`);
4610
4610
  lines.push("");
4611
4611
  lines.push("```query");
4612
- lines.push(`find:note{${filterExpr}}`);
4612
+ lines.push(`:note{${filterExpr}}`);
4613
4613
  lines.push("```");
4614
4614
  }
4615
4615
  return lines.join("\n");
@@ -7115,6 +7115,9 @@ var BehaviorContext = class {
7115
7115
  * capabilities.
7116
7116
  */
7117
7117
  _capabilities;
7118
+ get nowProvider() {
7119
+ return this.runtime.nowProvider;
7120
+ }
7118
7121
  // ============================================================================
7119
7122
  // Event Subscription
7120
7123
  // ============================================================================
@@ -8018,15 +8021,10 @@ var CountdownTimerBehavior = class {
8018
8021
  }
8019
8022
  this.subscriptions.push(
8020
8023
  ctx.subscribe("tick", (_event, tickCtx) => {
8021
- const timer = readTimer(tickCtx);
8022
- if (!timer || timer.direction !== "down" || timer.durationMs === void 0) {
8023
- return [];
8024
- }
8025
8024
  if (mode === "complete-block" && tickCtx.block.isComplete) {
8026
8025
  return [];
8027
8026
  }
8028
- const elapsed = calculateElapsed(timer, tickCtx.clock.currentDate.getTime());
8029
- if (elapsed < timer.durationMs) return [];
8027
+ if (!this.hasExpired(tickCtx)) return [];
8030
8028
  this.handleExpiry(tickCtx, mode);
8031
8029
  return [new ClearChildrenAction(tickCtx.block.key.toString())];
8032
8030
  }, { scope: "bubble" })
@@ -8055,6 +8053,10 @@ var CountdownTimerBehavior = class {
8055
8053
  return [];
8056
8054
  }
8057
8055
  onNext(ctx) {
8056
+ if ((this.config.mode ?? "complete-block") === "complete-block" && !ctx.block.isComplete && this.hasExpired(ctx)) {
8057
+ ctx.markComplete("timer-expired");
8058
+ return [new PopBlockAction(), new ClearChildrenAction(ctx.block.key.toString())];
8059
+ }
8058
8060
  if (this.config.required && !ctx.block.isComplete) {
8059
8061
  ctx.emitEvent({
8060
8062
  name: "timer:skip-attempt",
@@ -8126,6 +8128,18 @@ var CountdownTimerBehavior = class {
8126
8128
  }
8127
8129
  }
8128
8130
  }
8131
+ /**
8132
+ * True when the countdown has fully elapsed against the context's clock.
8133
+ * Single definition of "expired" shared by the tick subscription and the
8134
+ * Next-time reconcile, so display (spans) and runtime cannot diverge.
8135
+ */
8136
+ hasExpired(ctx) {
8137
+ const timer = readTimer(ctx);
8138
+ if (!timer || timer.direction !== "down" || timer.durationMs === void 0) {
8139
+ return false;
8140
+ }
8141
+ return calculateElapsed(timer, ctx.nowProvider.nowMs()) >= timer.durationMs;
8142
+ }
8129
8143
  getRemainingCountdownMs(ctx) {
8130
8144
  const timer = readTimer(ctx);
8131
8145
  if (!timer || timer.direction !== "down" || !timer.durationMs) {
@@ -9676,34 +9690,51 @@ function extractTagPropertyRules(tags2, slugs) {
9676
9690
  for (const slug of slugs) {
9677
9691
  const resolved = resolveTagContributions(tags2, slug);
9678
9692
  if (resolved.metrics.length === 0) continue;
9679
- const metrics = {};
9680
- const summaries = {};
9681
- for (const m of resolved.metrics) {
9682
- const key = m.type.trim();
9683
- if (!key) continue;
9684
- if (key.startsWith("summaries.")) {
9685
- const subKey = key.slice("summaries.".length).trim();
9686
- if (subKey && !(subKey in summaries)) {
9687
- summaries[subKey] = String(m.value);
9693
+ const tagMetrics = {};
9694
+ const tagSummaries = {};
9695
+ const categoryMetrics = {};
9696
+ const categorySummaries = {};
9697
+ for (const involvedSlug of resolved.tags) {
9698
+ const definition = tags2.resolve(involvedSlug);
9699
+ if (!definition) continue;
9700
+ const metrics = definition.isCategory ? categoryMetrics : tagMetrics;
9701
+ const summaries = definition.isCategory ? categorySummaries : tagSummaries;
9702
+ for (const m of definition.contributions) {
9703
+ if (m.kind !== "metric") continue;
9704
+ const key = m.type.trim();
9705
+ if (!key) continue;
9706
+ if (key.startsWith("summaries.")) {
9707
+ const subKey = key.slice("summaries.".length).trim();
9708
+ if (subKey && !(subKey in summaries)) {
9709
+ summaries[subKey] = String(m.value);
9710
+ }
9711
+ } else if (!(key in metrics)) {
9712
+ metrics[key] = m.unit ? `${String(m.value)} ${m.unit}` : m.value === null || typeof m.value === "boolean" ? String(m.value) : m.value;
9688
9713
  }
9689
- } else if (!(key in metrics)) {
9690
- metrics[key] = m.unit ? `${String(m.value)} ${m.unit}` : m.value === null || typeof m.value === "boolean" ? String(m.value) : m.value;
9691
9714
  }
9692
9715
  }
9693
- if (Object.keys(metrics).length > 0 || Object.keys(summaries).length > 0) {
9694
- rules.push({
9695
- layer: "tag",
9696
- sourceSlug: slug,
9697
- metrics,
9698
- summaries
9699
- });
9716
+ if (Object.keys(tagMetrics).length > 0 || Object.keys(tagSummaries).length > 0) {
9717
+ rules.push({ layer: "tag", sourceSlug: slug, metrics: tagMetrics, summaries: tagSummaries });
9718
+ }
9719
+ if (Object.keys(categoryMetrics).length > 0 || Object.keys(categorySummaries).length > 0) {
9720
+ rules.push({ layer: "category", sourceSlug: slug, metrics: categoryMetrics, summaries: categorySummaries });
9700
9721
  }
9701
9722
  }
9702
9723
  return rules;
9703
9724
  }
9725
+ var SUMMARY_LAYER_PRECEDENCE = {
9726
+ note: 6,
9727
+ tag: 5,
9728
+ effort: 4,
9729
+ equipment: 3,
9730
+ category: 1
9731
+ };
9704
9732
  function compilePropertySummaryCalcs(sources) {
9733
+ return compilePropertySummaryCalcsWithDiagnostics(sources).defs;
9734
+ }
9735
+ function compilePropertySummaryCalcsWithDiagnostics(sources) {
9705
9736
  const ordered = [...sources].sort(
9706
- (a, b) => LAYER_PRECEDENCE[b.layer] - LAYER_PRECEDENCE[a.layer]
9737
+ (a, b) => SUMMARY_LAYER_PRECEDENCE[b.layer] - SUMMARY_LAYER_PRECEDENCE[a.layer]
9707
9738
  );
9708
9739
  const chosen = /* @__PURE__ */ new Map();
9709
9740
  for (const source of ordered) {
@@ -9728,6 +9759,19 @@ function compilePropertySummaryCalcs(sources) {
9728
9759
  }
9729
9760
  }
9730
9761
  }
9762
+ const diagnostics = [];
9763
+ for (const [key, expr2] of chosen) {
9764
+ try {
9765
+ const missing = [...collectRequiredRefs(parseCalcLine(`summary = ${expr2}`).expr)].filter((ref) => !customAtomsMap.has(ref) && STREAM_ATOMS[ref] === void 0 && CONTEXT_ATOMS[ref] === void 0);
9766
+ for (const ref of missing) {
9767
+ customAtomsMap.set(ref, DIM_ZERO);
9768
+ }
9769
+ if (missing.length > 0) {
9770
+ diagnostics.push({ id: key, message: `Summary ${key}: missing ${[...new Set(missing)].join(", ")}` });
9771
+ }
9772
+ } catch {
9773
+ }
9774
+ }
9731
9775
  const customAtoms = Object.fromEntries(customAtomsMap);
9732
9776
  const defs = [];
9733
9777
  for (const [key, expr2] of chosen) {
@@ -9751,7 +9795,7 @@ function compilePropertySummaryCalcs(sources) {
9751
9795
  } catch {
9752
9796
  }
9753
9797
  }
9754
- return defs;
9798
+ return { defs, diagnostics };
9755
9799
  }
9756
9800
  function collectRequiredRefs(node, into = /* @__PURE__ */ new Set()) {
9757
9801
  if (!node) return into;
@@ -10006,6 +10050,7 @@ function runMetricShakeOutQueue(container, options) {
10006
10050
  }
10007
10051
  const unresolved = new Set(pendingEquations);
10008
10052
  const notApplicable = /* @__PURE__ */ new Set();
10053
+ const unresolvable = /* @__PURE__ */ new Set();
10009
10054
  const makeEvalContext = () => ({
10010
10055
  resolveRef: (name2) => readContainerMetricAtom(container, name2, inferredDims, options.lastEffortSlug),
10011
10056
  callFunction: (name2, args, rawArgs) => {
@@ -10029,7 +10074,12 @@ function runMetricShakeOutQueue(container, options) {
10029
10074
  continue;
10030
10075
  }
10031
10076
  const val = evaluate(rule.ast, ctx);
10032
- if (val.kind !== "number") continue;
10077
+ if (val.kind !== "number") {
10078
+ unresolved.delete(rule);
10079
+ unresolvable.add(rule);
10080
+ progressed = true;
10081
+ continue;
10082
+ }
10033
10083
  let dim = val.dim;
10034
10084
  if (rule.unit && AUTHORITATIVE_CASTS[rule.unit]) {
10035
10085
  dim = DIM_ZERO;
@@ -10061,14 +10111,8 @@ function runMetricShakeOutQueue(container, options) {
10061
10111
  const deferredRuntime = [];
10062
10112
  const diagnostics = [];
10063
10113
  const finalCtx = makeEvalContext();
10064
- for (const rule of unresolved) {
10065
- if (notApplicable.has(rule)) continue;
10066
- const missing = rule.dependencies.filter((dep) => finalCtx.resolveRef(dep).kind === "absent");
10067
- if (missing.length === 0) continue;
10068
- if (options.stage === "plan") {
10069
- deferredRuntime.push(rule.key);
10070
- continue;
10071
- }
10114
+ const emitDiagnostic = (rule, missing) => {
10115
+ if (options.emitDiagnostics === false) return;
10072
10116
  const diag = {
10073
10117
  target: rule.key,
10074
10118
  expression: rule.expression,
@@ -10080,8 +10124,8 @@ function runMetricShakeOutQueue(container, options) {
10080
10124
  container.add({
10081
10125
  type: wodWikiCore.MetricType.Diagnostic,
10082
10126
  name: `diagnostic.${rule.key}`,
10083
- value: `Skipped ${rule.key}: missing ${missing.join(", ")}`,
10084
- image: `Skipped ${rule.key} (missing ${missing.join(", ")})`,
10127
+ value: `Skipped ${rule.key}: ${missing.length > 0 ? `missing ${missing.join(", ")}` : "expression could not be evaluated"}`,
10128
+ image: `Skipped ${rule.key} (${missing.length > 0 ? `missing ${missing.join(", ")}` : "expression could not be evaluated"})`,
10085
10129
  origin: "diagnostic",
10086
10130
  metadata: {
10087
10131
  diagnostic: "skipped-dependency",
@@ -10092,6 +10136,23 @@ function runMetricShakeOutQueue(container, options) {
10092
10136
  missing
10093
10137
  }
10094
10138
  });
10139
+ };
10140
+ for (const rule of unresolved) {
10141
+ if (notApplicable.has(rule)) continue;
10142
+ const missing = rule.dependencies.filter((dep) => finalCtx.resolveRef(dep).kind === "absent");
10143
+ if (missing.length === 0) continue;
10144
+ if (options.stage === "plan") {
10145
+ deferredRuntime.push(rule.key);
10146
+ continue;
10147
+ }
10148
+ emitDiagnostic(rule, missing);
10149
+ }
10150
+ for (const rule of unresolvable) {
10151
+ if (options.stage === "plan") {
10152
+ deferredRuntime.push(rule.key);
10153
+ continue;
10154
+ }
10155
+ emitDiagnostic(rule, []);
10095
10156
  }
10096
10157
  return {
10097
10158
  resolved,
@@ -12438,6 +12499,8 @@ var CalcEngine = class {
12438
12499
  activatedTags = /* @__PURE__ */ new Set();
12439
12500
  /** The tags the run activates — a note-level bundle of attachments. */
12440
12501
  runTags;
12502
+ /** Registration diagnostics are stamped once per workout, on the first leaf. */
12503
+ summaryDiagnosticsStamped = false;
12441
12504
  /**
12442
12505
  * Whether a calculation runs here.
12443
12506
  *
@@ -12474,12 +12537,41 @@ var CalcEngine = class {
12474
12537
  const appliedTags = this.appliedTags(output);
12475
12538
  const tagSources = extractTagPropertyRules(this.deps.tags, appliedTags);
12476
12539
  const allSources = [...tagSources, ...this.deps.propertySources ?? []];
12540
+ const hasExerciseStatement = output.metrics.rawMetrics.some((metric) => metric.type === wodWikiCore.MetricType.Effort && String(metric.value ?? metric.image ?? "").trim().toLowerCase() !== "rest");
12541
+ if (!this.summaryDiagnosticsStamped && (this.deps.summaryDiagnostics?.length ?? 0) > 0) {
12542
+ this.summaryDiagnosticsStamped = true;
12543
+ for (const diagnostic of this.deps.summaryDiagnostics ?? []) {
12544
+ output.metrics.add({
12545
+ type: wodWikiCore.MetricType.Diagnostic,
12546
+ name: `diagnostic.${diagnostic.id}`,
12547
+ value: diagnostic.message,
12548
+ image: diagnostic.message,
12549
+ origin: "diagnostic",
12550
+ timestamp: /* @__PURE__ */ new Date(),
12551
+ metadata: { diagnostic: "summary-registration", target: diagnostic.id }
12552
+ });
12553
+ }
12554
+ }
12477
12555
  if (allSources.length > 0) {
12556
+ const spanMs = typeof output.timeSpan?.started === "number" && typeof output.timeSpan.ended === "number" ? output.timeSpan.ended - output.timeSpan.started : 0;
12557
+ const existingElapsed = output.metrics.rawMetrics.map((m) => m.type === wodWikiCore.MetricType.Elapsed && typeof m.value === "number" ? m.value : void 0).reduce((found, v) => v ?? found, void 0);
12558
+ if (spanMs > 0 && (existingElapsed === void 0 || existingElapsed === 0)) {
12559
+ output.metrics.add({
12560
+ type: wodWikiCore.MetricType.Elapsed,
12561
+ name: "elapsed",
12562
+ value: spanMs,
12563
+ unit: "ms",
12564
+ image: `${spanMs} ms`,
12565
+ origin: "analyzed",
12566
+ timestamp: /* @__PURE__ */ new Date()
12567
+ });
12568
+ }
12478
12569
  runMetricShakeOutQueue(output.metrics, {
12479
12570
  stage: "log",
12480
12571
  sources: allSources,
12481
12572
  lookups: this.deps.lookups,
12482
- lastEffortSlug: this.lastSegmentEffort
12573
+ lastEffortSlug: this.lastSegmentEffort,
12574
+ emitDiagnostics: hasExerciseStatement
12483
12575
  });
12484
12576
  }
12485
12577
  const atoms = buildSegmentAtoms(output, this.lastSegmentEffort);
@@ -13718,12 +13810,21 @@ function createCalcStack(options) {
13718
13810
  const allTagSlugs = (options.tags?.list() ?? []).map((t2) => t2.slug);
13719
13811
  const tagRules = extractTagPropertyRules(options.tags, allTagSlugs);
13720
13812
  const combinedSources = [...options.propertySources ?? [], ...tagRules];
13813
+ const diagnostics = [];
13721
13814
  if (combinedSources.length > 0) {
13722
- for (const def of compilePropertySummaryCalcs(combinedSources)) {
13723
- registry.register(def);
13815
+ const compiled = compilePropertySummaryCalcsWithDiagnostics(combinedSources);
13816
+ diagnostics.push(...compiled.diagnostics);
13817
+ for (const def of compiled.defs) {
13818
+ try {
13819
+ registry.register(def);
13820
+ } catch (err) {
13821
+ const message = `Skipped summary ${def.id}: ${err instanceof Error ? err.message : String(err)}`;
13822
+ diagnostics.push({ id: def.id, message });
13823
+ console.error(`[createCalcStack] ${message}`);
13824
+ }
13724
13825
  }
13725
13826
  }
13726
- return { lookups, registry };
13827
+ return { lookups, registry, diagnostics };
13727
13828
  }
13728
13829
  function createCalcEngine(dialect, options) {
13729
13830
  const stack = createCalcStack(options);
@@ -13733,7 +13834,8 @@ function createCalcEngine(dialect, options) {
13733
13834
  userProfile: options.userProfile,
13734
13835
  tags: options.tags,
13735
13836
  activeTags: options.activeTags,
13736
- propertySources: options.propertySources
13837
+ propertySources: options.propertySources,
13838
+ summaryDiagnostics: stack.diagnostics
13737
13839
  });
13738
13840
  }
13739
13841
 
@@ -15994,6 +16096,7 @@ exports.commonFixtureSet = commonFixtureSet;
15994
16096
  exports.compareStatement = compareStatement;
15995
16097
  exports.compileLineForm = compileLineForm;
15996
16098
  exports.compilePropertySummaryCalcs = compilePropertySummaryCalcs;
16099
+ exports.compilePropertySummaryCalcsWithDiagnostics = compilePropertySummaryCalcsWithDiagnostics;
15997
16100
  exports.composeDivUnit = composeDivUnit;
15998
16101
  exports.composeMulUnit = composeMulUnit;
15999
16102
  exports.compoundName = compoundName;