@bitcobblers/wod-wiki-lang 0.50.2189 → 0.50.2190

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.
@@ -981,8 +981,27 @@ interface PropertyRuleInput {
981
981
  readonly sourceSlug: string;
982
982
  readonly metrics?: Readonly<Record<string, string | number | readonly string[]>>;
983
983
  readonly summaries?: Readonly<Record<string, string>>;
984
+ readonly widgets?: Readonly<Record<string, string>>;
984
985
  readonly hints?: Readonly<Record<string, unknown>>;
985
986
  }
987
+ interface StackedDashboardWidgetDescriptor {
988
+ /** Unique key across the stacked note dashboard (`summary:<key>` or `widget:<key>`). */
989
+ readonly key: string;
990
+ /** Human-readable card title. */
991
+ readonly title: string;
992
+ /** Widget visualization type (`timeseries`, `bar`, `value`, `table`, `list`, …). */
993
+ readonly type: string;
994
+ /** WQL query string (supports `$scope`, `$note`, `$effort`, `$tag`, etc.). */
995
+ readonly wql: string;
996
+ /** Specificity layer that contributed this widget. */
997
+ readonly sourceLayer: PropertyRuleInput['layer'];
998
+ /** Source slug (`note-frontmatter`, tag slug, effort slug, etc.). */
999
+ readonly sourceSlug: string;
1000
+ /** Origin kind: derived from a `summaries.<key>` calculation or an explicit `widgets.<key>` rule. */
1001
+ readonly origin: 'summary' | 'widget';
1002
+ /** Canonical metric key when `origin === 'summary'`. */
1003
+ readonly metricKey?: string;
1004
+ }
986
1005
  interface SkippedDependencyDiagnostic {
987
1006
  readonly target: string;
988
1007
  readonly expression: string;
@@ -1022,6 +1041,17 @@ interface CompiledPropertySummaries {
1022
1041
  }
1023
1042
  declare function compilePropertySummaryCalcs(sources: readonly PropertyRuleInput[]): CalculationDefinition[];
1024
1043
  declare function compilePropertySummaryCalcsWithDiagnostics(sources: readonly PropertyRuleInput[]): CompiledPropertySummaries;
1044
+ /**
1045
+ * Resolve stacked Dashboard Widget descriptors from a Note and its stacked
1046
+ * Property Notes (`note > tag > effort > equipment > category`), combining:
1047
+ * 1. Explicit `widgets.<key>` contributions on the Note, Tags, Efforts, Equipment, or Tag Categories.
1048
+ * 2. Automatic widgets derived from stacked `summaries.<key>` calculations
1049
+ * (e.g. `sum:totalWork{$scope} by {week}` or `sum:workByEffort{$scope} by {effort}` when grouped).
1050
+ */
1051
+ declare function resolvePropertyDashboardWidgets(sources: readonly PropertyRuleInput[], options?: {
1052
+ scopeFilter?: string;
1053
+ includeSummaries?: boolean;
1054
+ }): StackedDashboardWidgetDescriptor[];
1025
1055
  /**
1026
1056
  * Run the two-stage Metric Shake-Out Queue on a statement's MetricContainer.
1027
1057
  */
@@ -3003,4 +3033,4 @@ declare function getRuntimeNowMs(): number;
3003
3033
  /** Creates an INowProvider that reads the browser sender-clock when available. */
3004
3034
  declare function createBrowserRuntimeNow(): INowProvider;
3005
3035
 
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 };
3036
+ 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, filterTagsByVisibility as bA, formatDim as bB, formatSoundTrigger as bC, frozenNow as bD, getMetricVisibility as bE, getRuntimeNowMs as bF, isDimensionless as bG, isEffortDiscipline as bH, isFragmentTag as bI, num as bJ, parseSoundTrigger as bK, resolveEntityRank as bL, resolveEntityTier as bM, resolveProfileRules as bN, resolvePropertyDashboardWidgets as bO, resolveSourceRank as bP, resolveSourceTier as bQ, runMetricShakeOutQueue as bR, slugifyRefLabel as bS, str as bT, subDim as bU, truthy as bV, wallClockNow as bW, 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 StackedDashboardWidgetDescriptor as bi, type TimerDirection as bj, VISIBILITY_ICONS as bk, VISIBILITY_LABELS as bl, type Val as bm, addDim as bn, compilePropertySummaryCalcs as bo, compilePropertySummaryCalcsWithDiagnostics as bp, compoundName as bq, createBrowserRuntimeNow as br, createReferenceIndex as bs, dedupeEntitiesByPrecedence as bt, dimEquals as bu, disciplineFactorFor as bv, evaluate as bw, extractPropertyRulesFromMeta as bx, extractStatementRefs as by, extractTagPropertyRules 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 };
@@ -981,8 +981,27 @@ interface PropertyRuleInput {
981
981
  readonly sourceSlug: string;
982
982
  readonly metrics?: Readonly<Record<string, string | number | readonly string[]>>;
983
983
  readonly summaries?: Readonly<Record<string, string>>;
984
+ readonly widgets?: Readonly<Record<string, string>>;
984
985
  readonly hints?: Readonly<Record<string, unknown>>;
985
986
  }
987
+ interface StackedDashboardWidgetDescriptor {
988
+ /** Unique key across the stacked note dashboard (`summary:<key>` or `widget:<key>`). */
989
+ readonly key: string;
990
+ /** Human-readable card title. */
991
+ readonly title: string;
992
+ /** Widget visualization type (`timeseries`, `bar`, `value`, `table`, `list`, …). */
993
+ readonly type: string;
994
+ /** WQL query string (supports `$scope`, `$note`, `$effort`, `$tag`, etc.). */
995
+ readonly wql: string;
996
+ /** Specificity layer that contributed this widget. */
997
+ readonly sourceLayer: PropertyRuleInput['layer'];
998
+ /** Source slug (`note-frontmatter`, tag slug, effort slug, etc.). */
999
+ readonly sourceSlug: string;
1000
+ /** Origin kind: derived from a `summaries.<key>` calculation or an explicit `widgets.<key>` rule. */
1001
+ readonly origin: 'summary' | 'widget';
1002
+ /** Canonical metric key when `origin === 'summary'`. */
1003
+ readonly metricKey?: string;
1004
+ }
986
1005
  interface SkippedDependencyDiagnostic {
987
1006
  readonly target: string;
988
1007
  readonly expression: string;
@@ -1022,6 +1041,17 @@ interface CompiledPropertySummaries {
1022
1041
  }
1023
1042
  declare function compilePropertySummaryCalcs(sources: readonly PropertyRuleInput[]): CalculationDefinition[];
1024
1043
  declare function compilePropertySummaryCalcsWithDiagnostics(sources: readonly PropertyRuleInput[]): CompiledPropertySummaries;
1044
+ /**
1045
+ * Resolve stacked Dashboard Widget descriptors from a Note and its stacked
1046
+ * Property Notes (`note > tag > effort > equipment > category`), combining:
1047
+ * 1. Explicit `widgets.<key>` contributions on the Note, Tags, Efforts, Equipment, or Tag Categories.
1048
+ * 2. Automatic widgets derived from stacked `summaries.<key>` calculations
1049
+ * (e.g. `sum:totalWork{$scope} by {week}` or `sum:workByEffort{$scope} by {effort}` when grouped).
1050
+ */
1051
+ declare function resolvePropertyDashboardWidgets(sources: readonly PropertyRuleInput[], options?: {
1052
+ scopeFilter?: string;
1053
+ includeSummaries?: boolean;
1054
+ }): StackedDashboardWidgetDescriptor[];
1025
1055
  /**
1026
1056
  * Run the two-stage Metric Shake-Out Queue on a statement's MetricContainer.
1027
1057
  */
@@ -3003,4 +3033,4 @@ declare function getRuntimeNowMs(): number;
3003
3033
  /** Creates an INowProvider that reads the browser sender-clock when available. */
3004
3034
  declare function createBrowserRuntimeNow(): INowProvider;
3005
3035
 
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 };
3036
+ 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, filterTagsByVisibility as bA, formatDim as bB, formatSoundTrigger as bC, frozenNow as bD, getMetricVisibility as bE, getRuntimeNowMs as bF, isDimensionless as bG, isEffortDiscipline as bH, isFragmentTag as bI, num as bJ, parseSoundTrigger as bK, resolveEntityRank as bL, resolveEntityTier as bM, resolveProfileRules as bN, resolvePropertyDashboardWidgets as bO, resolveSourceRank as bP, resolveSourceTier as bQ, runMetricShakeOutQueue as bR, slugifyRefLabel as bS, str as bT, subDim as bU, truthy as bV, wallClockNow as bW, 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 StackedDashboardWidgetDescriptor as bi, type TimerDirection as bj, VISIBILITY_ICONS as bk, VISIBILITY_LABELS as bl, type Val as bm, addDim as bn, compilePropertySummaryCalcs as bo, compilePropertySummaryCalcsWithDiagnostics as bp, compoundName as bq, createBrowserRuntimeNow as br, createReferenceIndex as bs, dedupeEntitiesByPrecedence as bt, dimEquals as bu, disciplineFactorFor as bv, evaluate as bw, extractPropertyRulesFromMeta as bx, extractStatementRefs as by, extractTagPropertyRules 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
@@ -3736,38 +3736,6 @@ function quoteYaml(val) {
3736
3736
  }
3737
3737
  return val;
3738
3738
  }
3739
- function parseFrontmatter(raw) {
3740
- const match = raw.match(FRONTMATTER_RE);
3741
- if (!match) return { meta: {}, body: raw };
3742
- const lines = match[1].split(/\r?\n/);
3743
- const meta2 = {};
3744
- for (let i = 0; i < lines.length; i++) {
3745
- const keyMatch = lines[i].match(/^([A-Za-z][\w.-]*)\s*:(.*)$/);
3746
- if (!keyMatch) continue;
3747
- const key = keyMatch[1];
3748
- const rawVal = keyMatch[2].trim();
3749
- if (rawVal === "") {
3750
- const items = [];
3751
- while (i + 1 < lines.length) {
3752
- const itemMatch = lines[i + 1].match(/^\s+-\s+(.+)$/);
3753
- if (!itemMatch) break;
3754
- items.push(unquote(itemMatch[1].trim()));
3755
- i++;
3756
- }
3757
- meta2[key] = items.length > 0 ? items : "";
3758
- } else {
3759
- const wasQuoted = /^(['"])(.*)\1$/.test(rawVal);
3760
- const value = unquote(rawVal);
3761
- const num2 = Number(value);
3762
- meta2[key] = !wasQuoted && value !== "" && !isNaN(num2) ? num2 : value;
3763
- }
3764
- }
3765
- return { meta: meta2, body: raw.slice(match[0].length) };
3766
- }
3767
- function getScalar(meta2, key) {
3768
- const value = meta2[key];
3769
- return typeof value === "string" || typeof value === "number" ? value : void 0;
3770
- }
3771
3739
  function getListStrict(meta2, key) {
3772
3740
  const value = meta2[key];
3773
3741
  if (value === void 0) return [];
@@ -3846,12 +3814,12 @@ function parseEffortFile(raw) {
3846
3814
  const blockMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
3847
3815
  if (!blockMatch) return null;
3848
3816
  const innerLines = blockMatch[1].split(/\r?\n/);
3849
- const { meta: meta2, body } = parseFrontmatter(raw);
3850
- const type = getScalar(meta2, "type");
3817
+ const { meta: meta2, body } = wodWikiCore.parseFrontmatter(raw);
3818
+ const type = wodWikiCore.getScalar(meta2, "type");
3851
3819
  if (type !== void 0 && type !== "effort") return null;
3852
- const id = getScalar(meta2, "id");
3853
- const slug = getScalar(meta2, "slug");
3854
- const label = getScalar(meta2, "label");
3820
+ const id = wodWikiCore.getScalar(meta2, "id");
3821
+ const slug = wodWikiCore.getScalar(meta2, "slug");
3822
+ const label = wodWikiCore.getScalar(meta2, "label");
3855
3823
  const aliases = getListStrict(meta2, "aliases");
3856
3824
  const equipment = getListStrict(meta2, "equipment");
3857
3825
  if (aliases === void 0 || equipment === void 0) return null;
@@ -3863,11 +3831,11 @@ function parseEffortFile(raw) {
3863
3831
  const metCandidate = meta2["metrics.met"] ?? metricsAttrs.met ?? baseAttrs.met;
3864
3832
  if (metProblem(metCandidate) !== null) return null;
3865
3833
  const met = Number(metCandidate);
3866
- const topDiscipline = getScalar(meta2, "discipline");
3834
+ const topDiscipline = wodWikiCore.getScalar(meta2, "discipline");
3867
3835
  const discipline = parseDiscipline(
3868
3836
  typeof topDiscipline === "string" ? topDiscipline : typeof baseAttrs.discipline === "string" ? baseAttrs.discipline : void 0
3869
3837
  );
3870
- const intensityTier = getScalar(meta2, "intensityTier") ?? getScalar(meta2, "intensity") ?? baseAttrs.intensityTier;
3838
+ const intensityTier = wodWikiCore.getScalar(meta2, "intensityTier") ?? wodWikiCore.getScalar(meta2, "intensity") ?? baseAttrs.intensityTier;
3871
3839
  const factorCandidate = meta2["metrics.disciplineFactor"] ?? metricsAttrs.disciplineFactor ?? baseAttrs.disciplineFactor;
3872
3840
  const disciplineFactor = typeof factorCandidate === "number" && Number.isFinite(factorCandidate) ? factorCandidate : void 0;
3873
3841
  const hints = readNestedSection(innerLines, "hints");
@@ -3892,11 +3860,11 @@ function parseEffortFile(raw) {
3892
3860
  };
3893
3861
  }
3894
3862
  function parseEquipmentFile(raw) {
3895
- const { meta: meta2, body } = parseFrontmatter(raw);
3896
- if (getScalar(meta2, "type") !== "equipment") return null;
3897
- const id = getScalar(meta2, "id");
3898
- const slug = getScalar(meta2, "slug");
3899
- const label = getScalar(meta2, "label");
3863
+ const { meta: meta2, body } = wodWikiCore.parseFrontmatter(raw);
3864
+ if (wodWikiCore.getScalar(meta2, "type") !== "equipment") return null;
3865
+ const id = wodWikiCore.getScalar(meta2, "id");
3866
+ const slug = wodWikiCore.getScalar(meta2, "slug");
3867
+ const label = wodWikiCore.getScalar(meta2, "label");
3900
3868
  const aliases = getListStrict(meta2, "aliases");
3901
3869
  if (id === void 0 || aliases === void 0) return null;
3902
3870
  if (identityProblems(slug, label).length > 0) return null;
@@ -3929,14 +3897,14 @@ function documentToEffort(doc, baseEffort) {
3929
3897
  return { effort: baseEffort ?? createDefaultEffort(), errors };
3930
3898
  }
3931
3899
  const innerLines = blockMatch[1].split(/\r?\n/);
3932
- const { meta: meta2, body } = parseFrontmatter(doc);
3900
+ const { meta: meta2, body } = wodWikiCore.parseFrontmatter(doc);
3933
3901
  const bodyText = body.replace(/^\r?\n+/, "") || void 0;
3934
- const id = getScalar(meta2, "id");
3935
- const slug = getScalar(meta2, "slug");
3936
- const label = getScalar(meta2, "label");
3937
- const registrySource = getScalar(meta2, "registrySource");
3938
- const createdAt = getScalar(meta2, "createdAt");
3939
- const updatedAt = getScalar(meta2, "updatedAt");
3902
+ const id = wodWikiCore.getScalar(meta2, "id");
3903
+ const slug = wodWikiCore.getScalar(meta2, "slug");
3904
+ const label = wodWikiCore.getScalar(meta2, "label");
3905
+ const registrySource = wodWikiCore.getScalar(meta2, "registrySource");
3906
+ const createdAt = wodWikiCore.getScalar(meta2, "createdAt");
3907
+ const updatedAt = wodWikiCore.getScalar(meta2, "updatedAt");
3940
3908
  const aliases = getListStrict(meta2, "aliases");
3941
3909
  const equipmentRaw = meta2["equipment"];
3942
3910
  const equipment = getListStrict(meta2, "equipment");
@@ -3961,12 +3929,12 @@ function documentToEffort(doc, baseEffort) {
3961
3929
  if (problem) errors.push(problem);
3962
3930
  else baseAttributes.met = Number(metRaw);
3963
3931
  }
3964
- if (getScalar(meta2, "met") !== void 0) {
3932
+ if (wodWikiCore.getScalar(meta2, "met") !== void 0) {
3965
3933
  errors.push(
3966
3934
  "Invalid met placement: 'met' must be nested under baseAttributes or metrics (missing baseAttributes.met)"
3967
3935
  );
3968
3936
  }
3969
- const topDiscipline = getScalar(meta2, "discipline");
3937
+ const topDiscipline = wodWikiCore.getScalar(meta2, "discipline");
3970
3938
  const discipline = parseDiscipline(
3971
3939
  typeof topDiscipline === "string" ? topDiscipline : typeof baseAttrs.discipline === "string" ? baseAttrs.discipline : void 0
3972
3940
  );
@@ -3975,7 +3943,7 @@ function documentToEffort(doc, baseEffort) {
3975
3943
  if (typeof factorCandidate === "number" && Number.isFinite(factorCandidate)) {
3976
3944
  baseAttributes.disciplineFactor = factorCandidate;
3977
3945
  }
3978
- const tierCandidate = getScalar(meta2, "intensityTier") ?? getScalar(meta2, "intensity") ?? baseAttrs.intensityTier;
3946
+ const tierCandidate = wodWikiCore.getScalar(meta2, "intensityTier") ?? wodWikiCore.getScalar(meta2, "intensity") ?? baseAttrs.intensityTier;
3979
3947
  if (typeof tierCandidate === "string" && (tierCandidate === "low" || tierCandidate === "moderate" || tierCandidate === "high")) {
3980
3948
  baseAttributes.intensityTier = tierCandidate;
3981
3949
  }
@@ -4087,15 +4055,15 @@ function documentToEquipment(doc, baseEquipment) {
4087
4055
  errors.push("Missing YAML frontmatter delimiters (---)");
4088
4056
  return { equipment: baseEquipment ?? createDefaultEquipment(), errors };
4089
4057
  }
4090
- const { meta: meta2, body } = parseFrontmatter(doc);
4058
+ const { meta: meta2, body } = wodWikiCore.parseFrontmatter(doc);
4091
4059
  const bodyText = body.replace(/^\r?\n+/, "") || void 0;
4092
- const type = getScalar(meta2, "type");
4093
- const id = getScalar(meta2, "id");
4094
- const slug = getScalar(meta2, "slug");
4095
- const label = getScalar(meta2, "label");
4096
- const registrySource = getScalar(meta2, "registrySource");
4097
- const createdAt = getScalar(meta2, "createdAt");
4098
- const updatedAt = getScalar(meta2, "updatedAt");
4060
+ const type = wodWikiCore.getScalar(meta2, "type");
4061
+ const id = wodWikiCore.getScalar(meta2, "id");
4062
+ const slug = wodWikiCore.getScalar(meta2, "slug");
4063
+ const label = wodWikiCore.getScalar(meta2, "label");
4064
+ const registrySource = wodWikiCore.getScalar(meta2, "registrySource");
4065
+ const createdAt = wodWikiCore.getScalar(meta2, "createdAt");
4066
+ const updatedAt = wodWikiCore.getScalar(meta2, "updatedAt");
4099
4067
  const aliases = getListStrict(meta2, "aliases");
4100
4068
  if (type !== "equipment") errors.push("Missing or invalid discriminator: frontmatter must declare `type: equipment`");
4101
4069
  if (!slug || !SLUG_RE.test(String(slug))) errors.push("Invalid slug: must be a canonical slug (lowercase letters, numbers, hyphens)");
@@ -4169,19 +4137,20 @@ function documentToTag(doc, defaultCategory = "tag") {
4169
4137
  };
4170
4138
  }
4171
4139
  const innerLines = blockMatch[1].split(/\r?\n/);
4172
- const { meta: meta2, body } = parseFrontmatter(doc);
4140
+ const { meta: meta2, body } = wodWikiCore.parseFrontmatter(doc);
4173
4141
  const bodyText = body.replace(/^\r?\n+/, "") || void 0;
4174
- const id = String(getScalar(meta2, "id") ?? `tag-${uuid.v7()}`);
4175
- const labelRaw = getScalar(meta2, "label") ?? getScalar(meta2, "slug") ?? "";
4142
+ const id = String(wodWikiCore.getScalar(meta2, "id") ?? `tag-${uuid.v7()}`);
4143
+ const labelRaw = wodWikiCore.getScalar(meta2, "label") ?? wodWikiCore.getScalar(meta2, "slug") ?? "";
4176
4144
  const label = String(labelRaw).trim();
4177
- const slug = String(getScalar(meta2, "slug") ?? label);
4178
- const category = String(getScalar(meta2, "category") ?? getScalar(meta2, "type") ?? defaultCategory).trim() || defaultCategory;
4145
+ const slug = String(wodWikiCore.getScalar(meta2, "slug") ?? label);
4146
+ const category = String(wodWikiCore.getScalar(meta2, "category") ?? wodWikiCore.getScalar(meta2, "type") ?? defaultCategory).trim() || defaultCategory;
4179
4147
  const aliases = getListStrict(meta2, "aliases") ?? [];
4180
4148
  const tags2 = getListStrict(meta2, "tags") ?? [];
4181
4149
  const functions = getListStrict(meta2, "functions") ?? [];
4182
4150
  if (!label) errors.push("Missing required field: label");
4183
4151
  const metrics = {};
4184
4152
  const summaries = {};
4153
+ const widgets = {};
4185
4154
  const nestedMetrics = readNestedSection(innerLines, "metrics") ?? {};
4186
4155
  for (const [k, v] of Object.entries(nestedMetrics)) {
4187
4156
  if (typeof v === "number" || typeof v === "string") metrics[k] = v;
@@ -4190,6 +4159,10 @@ function documentToTag(doc, defaultCategory = "tag") {
4190
4159
  for (const [k, v] of Object.entries(nestedSummaries)) {
4191
4160
  if (typeof v === "number" || typeof v === "string") summaries[k] = String(v);
4192
4161
  }
4162
+ const nestedWidgets = readNestedSection(innerLines, "widgets") ?? {};
4163
+ for (const [k, v] of Object.entries(nestedWidgets)) {
4164
+ if (typeof v === "number" || typeof v === "string") widgets[k] = String(v);
4165
+ }
4193
4166
  for (const [k, v] of Object.entries(meta2)) {
4194
4167
  if (k.startsWith("metrics.")) {
4195
4168
  const sub = k.slice("metrics.".length).trim();
@@ -4197,6 +4170,9 @@ function documentToTag(doc, defaultCategory = "tag") {
4197
4170
  } else if (k.startsWith("summaries.")) {
4198
4171
  const sub = k.slice("summaries.".length).trim();
4199
4172
  if (sub && !Array.isArray(v)) summaries[sub] = String(v);
4173
+ } else if (k.startsWith("widgets.")) {
4174
+ const sub = k.slice("widgets.".length).trim();
4175
+ if (sub && !Array.isArray(v)) widgets[sub] = String(v);
4200
4176
  }
4201
4177
  }
4202
4178
  return {
@@ -4208,6 +4184,7 @@ function documentToTag(doc, defaultCategory = "tag") {
4208
4184
  aliases,
4209
4185
  metrics,
4210
4186
  summaries,
4187
+ ...Object.keys(widgets).length > 0 ? { widgets } : {},
4211
4188
  tags: tags2,
4212
4189
  functions,
4213
4190
  ...bodyText ? { body: bodyText } : {}
@@ -4248,6 +4225,9 @@ function tagToDocument(tag) {
4248
4225
  for (const [k, v] of Object.entries(tag.summaries)) {
4249
4226
  lines.push(`summaries.${k}: ${quoteYaml(v)}`);
4250
4227
  }
4228
+ for (const [k, v] of Object.entries(tag.widgets ?? {})) {
4229
+ lines.push(`widgets.${k}: ${quoteYaml(v)}`);
4230
+ }
4251
4231
  lines.push("---");
4252
4232
  if (tag.body) {
4253
4233
  lines.push("");
@@ -4276,6 +4256,9 @@ function tagCategoryToDocument(category) {
4276
4256
  for (const [k, v] of Object.entries(category.summaries ?? {})) {
4277
4257
  lines.push(`summaries.${k}: ${quoteYaml(v)}`);
4278
4258
  }
4259
+ for (const [k, v] of Object.entries(category.widgets ?? {})) {
4260
+ lines.push(`widgets.${k}: ${quoteYaml(v)}`);
4261
+ }
4279
4262
  lines.push("---");
4280
4263
  if (category.body) {
4281
4264
  lines.push("");
@@ -4290,6 +4273,62 @@ function tagCategoryToDocument(category) {
4290
4273
  }
4291
4274
  return lines.join("\n");
4292
4275
  }
4276
+ function tagRecordToDocument(tag, categoryFallback = "tag") {
4277
+ const metrics = {};
4278
+ const summaries = {};
4279
+ const widgets = {};
4280
+ const tags2 = [];
4281
+ const functions = [];
4282
+ for (const c of tag.contributions ?? []) {
4283
+ if (c.kind === "metric" && c.type.startsWith("summaries.")) {
4284
+ summaries[c.type.slice("summaries.".length)] = String(c.value);
4285
+ } else if (c.kind === "metric" && c.type.startsWith("widgets.")) {
4286
+ widgets[c.type.slice("widgets.".length)] = String(c.value);
4287
+ } else if (c.kind === "metric" && c.type) {
4288
+ metrics[c.type] = c.unit ? `${String(c.value)} ${c.unit}` : c.value === null || typeof c.value === "boolean" ? String(c.value ?? "") : c.value;
4289
+ } else if (c.kind === "tag" && c.slug) {
4290
+ tags2.push(c.slug);
4291
+ } else if (c.kind === "function" && c.name) {
4292
+ functions.push(c.name);
4293
+ }
4294
+ }
4295
+ return tagToDocument({
4296
+ id: tag.id,
4297
+ slug: tag.label,
4298
+ label: tag.label,
4299
+ category: tag.type || categoryFallback,
4300
+ aliases: [],
4301
+ metrics,
4302
+ summaries,
4303
+ ...Object.keys(widgets).length > 0 ? { widgets } : {},
4304
+ tags: tags2,
4305
+ functions
4306
+ });
4307
+ }
4308
+ function tagCategoryRecordToDocument(category, record) {
4309
+ const title = record?.label || category.replace(/[-_]+/g, " ").trim().replace(/\b\w/g, (c) => c.toUpperCase());
4310
+ const metrics = {};
4311
+ const summaries = {};
4312
+ const widgets = {};
4313
+ for (const c of record?.contributions ?? []) {
4314
+ if (c.kind === "metric" && c.type.startsWith("summaries.")) {
4315
+ summaries[c.type.slice("summaries.".length)] = String(c.value);
4316
+ } else if (c.kind === "metric" && c.type.startsWith("widgets.")) {
4317
+ widgets[c.type.slice("widgets.".length)] = String(c.value);
4318
+ } else if (c.kind === "metric" && c.type) {
4319
+ metrics[c.type] = c.unit ? `${String(c.value)} ${c.unit}` : typeof c.value === "number" ? c.value : String(c.value);
4320
+ }
4321
+ }
4322
+ return tagCategoryToDocument({
4323
+ id: record?.id ?? `tag-type-${category}`,
4324
+ name: category,
4325
+ label: title || category,
4326
+ color: record?.color,
4327
+ metrics,
4328
+ summaries,
4329
+ ...Object.keys(widgets).length > 0 ? { widgets } : {}
4330
+ });
4331
+ }
4293
4332
 
4294
4333
  // src/effort-registry/fuzzyMatch.ts
4295
4334
  function levenshteinDistance(a, b) {
@@ -9732,6 +9771,7 @@ var STATEMENT_OWNED_ORIGINS = {
9732
9771
  function extractPropertyRulesFromMeta(meta2, layer, sourceSlug) {
9733
9772
  const metrics = {};
9734
9773
  const summaries = {};
9774
+ const widgets = {};
9735
9775
  for (const [rawKey, rawValue] of Object.entries(meta2)) {
9736
9776
  const key = rawKey.trim();
9737
9777
  if (key.startsWith("metrics.")) {
@@ -9756,13 +9796,25 @@ function extractPropertyRulesFromMeta(meta2, layer, sourceSlug) {
9756
9796
  summaries[childKey.trim()] = String(childVal);
9757
9797
  }
9758
9798
  }
9799
+ } else if (key.startsWith("widgets.")) {
9800
+ const subKey = key.slice("widgets.".length).trim();
9801
+ if (subKey && (typeof rawValue === "string" || typeof rawValue === "number")) {
9802
+ widgets[subKey] = String(rawValue);
9803
+ }
9804
+ } else if (key === "widgets" && isPlainObject(rawValue)) {
9805
+ for (const [childKey, childVal] of Object.entries(rawValue)) {
9806
+ if (typeof childVal === "string" || typeof childVal === "number") {
9807
+ widgets[childKey.trim()] = String(childVal);
9808
+ }
9809
+ }
9759
9810
  }
9760
9811
  }
9761
9812
  return {
9762
9813
  layer,
9763
9814
  sourceSlug,
9764
9815
  metrics,
9765
- summaries
9816
+ summaries,
9817
+ ...Object.keys(widgets).length > 0 ? { widgets } : {}
9766
9818
  };
9767
9819
  }
9768
9820
  function isSupportedMetricValue(val) {
@@ -9781,13 +9833,16 @@ function extractTagPropertyRules(tags2, slugs) {
9781
9833
  if (resolved.metrics.length === 0) continue;
9782
9834
  const tagMetrics = {};
9783
9835
  const tagSummaries = {};
9836
+ const tagWidgets = {};
9784
9837
  const categoryMetrics = {};
9785
9838
  const categorySummaries = {};
9839
+ const categoryWidgets = {};
9786
9840
  for (const involvedSlug of resolved.tags) {
9787
9841
  const definition = tags2.resolve(involvedSlug);
9788
9842
  if (!definition) continue;
9789
9843
  const metrics = definition.isCategory ? categoryMetrics : tagMetrics;
9790
9844
  const summaries = definition.isCategory ? categorySummaries : tagSummaries;
9845
+ const widgets = definition.isCategory ? categoryWidgets : tagWidgets;
9791
9846
  for (const m of definition.contributions) {
9792
9847
  if (m.kind !== "metric") continue;
9793
9848
  const key = m.type.trim();
@@ -9797,16 +9852,33 @@ function extractTagPropertyRules(tags2, slugs) {
9797
9852
  if (subKey && !(subKey in summaries)) {
9798
9853
  summaries[subKey] = String(m.value);
9799
9854
  }
9855
+ } else if (key.startsWith("widgets.")) {
9856
+ const subKey = key.slice("widgets.".length).trim();
9857
+ if (subKey && !(subKey in widgets)) {
9858
+ widgets[subKey] = String(m.value);
9859
+ }
9800
9860
  } else if (!(key in metrics)) {
9801
9861
  metrics[key] = m.unit ? `${String(m.value)} ${m.unit}` : m.value === null || typeof m.value === "boolean" ? String(m.value) : m.value;
9802
9862
  }
9803
9863
  }
9804
9864
  }
9805
- if (Object.keys(tagMetrics).length > 0 || Object.keys(tagSummaries).length > 0) {
9806
- rules.push({ layer: "tag", sourceSlug: slug, metrics: tagMetrics, summaries: tagSummaries });
9865
+ if (Object.keys(tagMetrics).length > 0 || Object.keys(tagSummaries).length > 0 || Object.keys(tagWidgets).length > 0) {
9866
+ rules.push({
9867
+ layer: "tag",
9868
+ sourceSlug: slug,
9869
+ metrics: tagMetrics,
9870
+ summaries: tagSummaries,
9871
+ ...Object.keys(tagWidgets).length > 0 ? { widgets: tagWidgets } : {}
9872
+ });
9807
9873
  }
9808
- if (Object.keys(categoryMetrics).length > 0 || Object.keys(categorySummaries).length > 0) {
9809
- rules.push({ layer: "category", sourceSlug: slug, metrics: categoryMetrics, summaries: categorySummaries });
9874
+ if (Object.keys(categoryMetrics).length > 0 || Object.keys(categorySummaries).length > 0 || Object.keys(categoryWidgets).length > 0) {
9875
+ rules.push({
9876
+ layer: "category",
9877
+ sourceSlug: slug,
9878
+ metrics: categoryMetrics,
9879
+ summaries: categorySummaries,
9880
+ ...Object.keys(categoryWidgets).length > 0 ? { widgets: categoryWidgets } : {}
9881
+ });
9810
9882
  }
9811
9883
  }
9812
9884
  return rules;
@@ -9868,6 +9940,9 @@ function compilePropertySummaryCalcsWithDiagnostics(sources) {
9868
9940
  try {
9869
9941
  const compiled = compileLineForm(line, { scope: "workout" });
9870
9942
  for (const def of compiled.defs) {
9943
+ const groupedMatch = expr2.match(/^\s*grouped\s*\(\s*([A-Za-z_][\w.]*)\s*,/);
9944
+ const isGrouped = Boolean(def.output?.isGrouped || groupedMatch);
9945
+ const groupBy = def.output?.groupBy ?? (groupedMatch ? [groupedMatch[1]] : void 0);
9871
9946
  defs.push({
9872
9947
  ...def,
9873
9948
  customAtoms,
@@ -9876,7 +9951,7 @@ function compilePropertySummaryCalcsWithDiagnostics(sources) {
9876
9951
  key: def.output?.key ?? key,
9877
9952
  emitType: def.output?.emitType ?? key,
9878
9953
  unit: def.output?.unit ?? "auto",
9879
- ...def.output?.isGrouped ? { isGrouped: true, groupBy: def.output.groupBy } : {},
9954
+ ...isGrouped ? { isGrouped: true, ...groupBy ? { groupBy } : {} } : {},
9880
9955
  ...def.output?.label ? { label: def.output.label } : {}
9881
9956
  }
9882
9957
  });
@@ -9886,6 +9961,87 @@ function compilePropertySummaryCalcsWithDiagnostics(sources) {
9886
9961
  }
9887
9962
  return { defs, diagnostics };
9888
9963
  }
9964
+ function parseWidgetSpecValue(key, rawSpec) {
9965
+ const trimmed = rawSpec.trim();
9966
+ const title = key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
9967
+ const prefixMatch = trimmed.match(/^([a-z][a-z0-9-]*)\s*\|\s*([\s\S]+)$/i);
9968
+ if (prefixMatch) {
9969
+ return {
9970
+ type: prefixMatch[1].toLowerCase(),
9971
+ wql: prefixMatch[2].trim(),
9972
+ title
9973
+ };
9974
+ }
9975
+ const sinkMatch = trimmed.match(/\|\s*:([a-z][a-z0-9-]*)\s*\{[^}]*\}\s*$/i);
9976
+ return {
9977
+ type: sinkMatch ? sinkMatch[1].toLowerCase() : "timeseries",
9978
+ wql: trimmed,
9979
+ title
9980
+ };
9981
+ }
9982
+ function resolvePropertyDashboardWidgets(sources, options = {}) {
9983
+ const ordered = [...sources].sort(
9984
+ (a, b) => SUMMARY_LAYER_PRECEDENCE[b.layer] - SUMMARY_LAYER_PRECEDENCE[a.layer]
9985
+ );
9986
+ const filterClause = options.scopeFilter?.trim() ?? "$scope";
9987
+ const includeSummaries = options.includeSummaries ?? true;
9988
+ const out = [];
9989
+ const seenKeys = /* @__PURE__ */ new Set();
9990
+ for (const source of ordered) {
9991
+ if (!source.widgets) continue;
9992
+ for (const [rawKey, rawSpec] of Object.entries(source.widgets)) {
9993
+ const key = rawKey.trim();
9994
+ if (!key || !rawSpec.trim() || seenKeys.has(`widget:${key}`)) continue;
9995
+ seenKeys.add(`widget:${key}`);
9996
+ const parsed = parseWidgetSpecValue(key, rawSpec);
9997
+ const resolvedWql = filterClause ? parsed.wql.replace(/\$scope\b/g, filterClause) : parsed.wql;
9998
+ out.push({
9999
+ key: `widget:${key}`,
10000
+ title: parsed.title,
10001
+ type: parsed.type,
10002
+ wql: resolvedWql,
10003
+ sourceLayer: source.layer,
10004
+ sourceSlug: source.sourceSlug,
10005
+ origin: "widget"
10006
+ });
10007
+ }
10008
+ }
10009
+ if (includeSummaries) {
10010
+ const chosenSummarySource = /* @__PURE__ */ new Map();
10011
+ for (const source of ordered) {
10012
+ if (!source.summaries) continue;
10013
+ for (const [rawKey, rawExpr] of Object.entries(source.summaries)) {
10014
+ const key = rawKey.trim();
10015
+ if (!key || !rawExpr.trim() || chosenSummarySource.has(key)) continue;
10016
+ chosenSummarySource.set(key, source);
10017
+ }
10018
+ }
10019
+ const compiled = compilePropertySummaryCalcs(sources);
10020
+ for (const def of compiled) {
10021
+ const metricKey = def.output?.key ?? def.id;
10022
+ if (!metricKey || seenKeys.has(`summary:${metricKey}`) || seenKeys.has(`widget:${metricKey}`)) continue;
10023
+ seenKeys.add(`summary:${metricKey}`);
10024
+ const source = chosenSummarySource.get(metricKey) ?? ordered[0];
10025
+ if (!source) continue;
10026
+ const isGrouped = Boolean(def.output?.isGrouped);
10027
+ const groupDim = def.output?.groupBy?.[0] ?? "effort";
10028
+ const label = def.output?.label ?? metricKey.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
10029
+ const braces = filterClause ? `{${filterClause}}` : "{}";
10030
+ const wql = isGrouped ? `sum:${metricKey}${braces} by {${groupDim}}` : `sum:${metricKey}${braces} by {week}`;
10031
+ out.push({
10032
+ key: `summary:${metricKey}`,
10033
+ title: label,
10034
+ type: isGrouped ? "bar" : "timeseries",
10035
+ wql,
10036
+ sourceLayer: source.layer,
10037
+ sourceSlug: source.sourceSlug,
10038
+ origin: "summary",
10039
+ metricKey
10040
+ });
10041
+ }
10042
+ }
10043
+ return out;
10044
+ }
9889
10045
  function collectRequiredRefs(node, into = /* @__PURE__ */ new Set()) {
9890
10046
  if (!node) return into;
9891
10047
  switch (node.kind) {
@@ -16309,6 +16465,7 @@ exports.resolveEntityRank = resolveEntityRank;
16309
16465
  exports.resolveEntityTier = resolveEntityTier;
16310
16466
  exports.resolveFusedEffortReferences = resolveFusedEffortReferences;
16311
16467
  exports.resolveProfileRules = resolveProfileRules;
16468
+ exports.resolvePropertyDashboardWidgets = resolvePropertyDashboardWidgets;
16312
16469
  exports.resolveSoundProfile = resolveSoundProfile;
16313
16470
  exports.resolveSourceRank = resolveSourceRank;
16314
16471
  exports.resolveSourceTier = resolveSourceTier;
@@ -16321,11 +16478,13 @@ exports.str = str;
16321
16478
  exports.strategyRegistry = strategyRegistry;
16322
16479
  exports.subDim = subDim;
16323
16480
  exports.summaryProcessorRegistry = summaryProcessorRegistry;
16481
+ exports.tagCategoryRecordToDocument = tagCategoryRecordToDocument;
16324
16482
  exports.tagCategoryToDocument = tagCategoryToDocument;
16325
16483
  exports.tagContributionMetrics = tagContributionMetrics;
16326
16484
  exports.tagMarkerSlug = tagMarkerSlug;
16327
16485
  exports.tagMarkerSlugs = tagMarkerSlugs;
16328
16486
  exports.tagMarkerType = tagMarkerType;
16487
+ exports.tagRecordToDocument = tagRecordToDocument;
16329
16488
  exports.tagToDocument = tagToDocument;
16330
16489
  exports.toStoredOutputStatement = toStoredOutputStatement;
16331
16490
  exports.truthy = truthy;