@bitcobblers/wod-wiki-wql 0.51.2196 → 0.53.2203

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { LRParser } from '@lezer/lr';
2
2
  import { LanguageSupport, HighlightStyle, LRLanguage } from '@codemirror/language';
3
3
  import { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
4
4
  import { Extension } from '@codemirror/state';
5
- import { SummaryCoverage, BlockIndexRow, Note, EventRecord, PageNote, Page, NotePlacement, AnalyticsDataPoint, FeedId, NotebookId, NotebookOrigin, ResultOrigin, StoredOutputStatement, NoteBlockChange } from '@bitcobblers/wod-wiki-core';
5
+ import { SummaryCoverage, BlockIndexRow, Note, EventRecord, FeedSourceCatalogRow, FeedNotebookCatalogRow, PageNote, Page, NotePlacement, AnalyticsDataPoint, FeedId, NotebookId, NotebookOrigin, ResultOrigin, StoredOutputStatement, NoteBlockChange } from '@bitcobblers/wod-wiki-core';
6
6
  export { DEFAULT_NOTEBOOK_SLUGS, DefaultNotebookSlug, FeedId, LinkWidget, NotebookId, NotebookOrigin, ParsedFrontmatter, SYSTEM_DEFAULT_OUTPUT_UNIT, TypedTagItem, UnitConversionError, convertViaCatalog, dimensionKeyOf, extractFrontmatterTags, extractTypedFrontmatterTags, getList, getScalar, isNoteEditable, lookupUnit, notebookSlugFromId, parseFlatProperties, parseFrontmatter, parseFrontmatterBody, parseFrontmatterCategories, parseFrontmatterProps, serializeFrontmatter, stripFrontmatter, systemDefaultUnit, toNotebookId } from '@bitcobblers/wod-wiki-core';
7
7
  import { IEffort } from '@bitcobblers/wod-wiki-lang';
8
8
  export { IEffort } from '@bitcobblers/wod-wiki-lang';
@@ -76,7 +76,7 @@ type WqlGrain = (typeof WQL_GRAINS)[number];
76
76
  * planes (ticket 08) are first-class targets: `:notebook{}` lists the
77
77
  * notes across every notebook, `:page{}` the page placements, `:tag{}` the tags,
78
78
  * `:equipment{}` the equipment notes — the latter two resolve to notes. */
79
- declare const WQL_FIND_TARGETS: readonly ["note", "block", "effort", "session", "segment", "event", "notebook", "page", "tag", "equipment"];
79
+ declare const WQL_FIND_TARGETS: readonly ["note", "block", "effort", "session", "segment", "event", "notebook", "page", "tag", "equipment", "feed"];
80
80
  type WqlFindTarget = (typeof WQL_FIND_TARGETS)[number];
81
81
  /** Canonical source filter values: the allowed storage locations. Corpus-
82
82
  * delivered notes carry `notebook:<slug>` source ids, so `notebooks` spans
@@ -91,7 +91,7 @@ type WqlSourceValue = (typeof WQL_SOURCE_VALUES)[number];
91
91
  * container planes (targets of their own name). `:notebook{}` stays a NOTE
92
92
  * plane (ticket 05): it returns every notebook's notes, delegating to the
93
93
  * note executor. */
94
- declare const WQL_SOURCE_HEADS: readonly ["note", "notes", "block", "effort", "session", "segment", "event", "journal", "notebook", "notebooks", "playground", "page", "tag", "equipment", "dashboard"];
94
+ declare const WQL_SOURCE_HEADS: readonly ["note", "notes", "block", "effort", "session", "segment", "event", "journal", "notebook", "notebooks", "playground", "page", "tag", "equipment", "feed", "feeds", "dashboard"];
95
95
  type WqlSourceHead = (typeof WQL_SOURCE_HEADS)[number];
96
96
  /** Storage scope a source-scoped note head binds (undefined = plain target). */
97
97
  declare const WQL_SOURCE_HEAD_SCOPES: Readonly<Record<string, WqlSourceValue>>;
@@ -112,11 +112,11 @@ declare const WQL_NOTE_DEFAULT_SOURCES: readonly WqlSourceValue[];
112
112
  declare const WQL_FUNCTION_HEADS: readonly ["sum", "avg", "min", "max", "count", "last", "delta"];
113
113
  type WqlFunctionHead = WqlAggregator;
114
114
  /** Colon chart heads — terminal pipeline sinks (`:timeseries`, `:bar`, …). */
115
- declare const WQL_CHART_HEADS: readonly ["timeseries", "bar", "table", "donut", "toplist", "value"];
115
+ declare const WQL_CHART_HEADS: readonly ["timeseries", "bar", "stacked-bar", "table", "list", "donut", "toplist", "value", "goal-rings", "zone-distribution"];
116
116
  type WqlChartHead = (typeof WQL_CHART_HEADS)[number];
117
117
  /** Standard datasets the host registers per page/run before children
118
118
  * evaluate (`@session` active session, `@today` civil-day telemetry+notes). */
119
- declare const WQL_STANDARD_DATASETS: readonly ["@session", "@today"];
119
+ declare const WQL_STANDARD_DATASETS: readonly ["@session", "@today", "@note"];
120
120
  type WqlStandardDataset = (typeof WQL_STANDARD_DATASETS)[number];
121
121
  /** Result planes — `rows:<plane>` narrows raw output-statement rows by the
122
122
  * unified store's promoted `outputType` column. The STORE vocabulary is
@@ -141,7 +141,7 @@ type WqlContentFilterKey = (typeof WQL_CONTENT_FILTER_KEYS)[number];
141
141
  * deliberately absent — it needs new grammar/engine semantics and is
142
142
  * deferred to its own ticket.
143
143
  */
144
- declare const WQL_SOURCES: readonly ["note", "block", "effort", "session", "segment", "event", "notebook", "page", "tag", "equipment"];
144
+ declare const WQL_SOURCES: readonly ["note", "block", "effort", "session", "segment", "event", "notebook", "page", "tag", "equipment", "feed"];
145
145
  type WqlSource = WqlFindTarget;
146
146
  /** Rollup periods the aggregate grammar accepts (wql.ts: N > 1, unit d|w). */
147
147
  declare const WQL_ROLLUP_PERIODS: readonly ["2w", "4w"];
@@ -181,28 +181,31 @@ declare const Head = 4;
181
181
  declare const Word = 5;
182
182
  declare const Aggregator$1 = 6;
183
183
  declare const Metric = 7;
184
- declare const Filters = 8;
185
- declare const Filter = 9;
186
- declare const Negate = 10;
187
- declare const TagKey = 11;
188
- declare const TagValue$1 = 12;
189
- declare const Value = 13;
190
- declare const Star = 14;
191
- declare const Quoted = 15;
192
- declare const DatasetReference = 16;
193
- declare const At = 17;
194
- declare const Single = 18;
195
- declare const GroupBy = 19;
196
- declare const By = 20;
197
- declare const Dimension = 21;
198
- declare const Rollup = 22;
199
- declare const RollupDot = 23;
200
- declare const Int = 24;
184
+ declare const ParamRef = 8;
185
+ declare const Dollar = 9;
186
+ declare const Filters = 10;
187
+ declare const Filter = 11;
188
+ declare const Negate = 12;
189
+ declare const TagKey = 13;
190
+ declare const TagValue$1 = 14;
191
+ declare const Value = 15;
192
+ declare const Star = 16;
193
+ declare const Quoted = 17;
194
+ declare const DatasetReference = 18;
195
+ declare const At = 19;
196
+ declare const Single = 20;
197
+ declare const GroupBy = 21;
198
+ declare const By = 22;
199
+ declare const Dimension = 23;
200
+ declare const Rollup = 24;
201
+ declare const RollupDot = 25;
202
+ declare const Int = 26;
201
203
 
202
204
  declare const wql_parser_terms_At: typeof At;
203
205
  declare const wql_parser_terms_By: typeof By;
204
206
  declare const wql_parser_terms_DatasetReference: typeof DatasetReference;
205
207
  declare const wql_parser_terms_Dimension: typeof Dimension;
208
+ declare const wql_parser_terms_Dollar: typeof Dollar;
206
209
  declare const wql_parser_terms_Filter: typeof Filter;
207
210
  declare const wql_parser_terms_Filters: typeof Filters;
208
211
  declare const wql_parser_terms_GroupBy: typeof GroupBy;
@@ -210,6 +213,7 @@ declare const wql_parser_terms_Head: typeof Head;
210
213
  declare const wql_parser_terms_Int: typeof Int;
211
214
  declare const wql_parser_terms_Metric: typeof Metric;
212
215
  declare const wql_parser_terms_Negate: typeof Negate;
216
+ declare const wql_parser_terms_ParamRef: typeof ParamRef;
213
217
  declare const wql_parser_terms_Pipeline: typeof Pipeline;
214
218
  declare const wql_parser_terms_Query: typeof Query;
215
219
  declare const wql_parser_terms_Quoted: typeof Quoted;
@@ -222,7 +226,7 @@ declare const wql_parser_terms_TagKey: typeof TagKey;
222
226
  declare const wql_parser_terms_Value: typeof Value;
223
227
  declare const wql_parser_terms_Word: typeof Word;
224
228
  declare namespace wql_parser_terms {
225
- export { Aggregator$1 as Aggregator, wql_parser_terms_At as At, wql_parser_terms_By as By, wql_parser_terms_DatasetReference as DatasetReference, wql_parser_terms_Dimension as Dimension, wql_parser_terms_Filter as Filter, wql_parser_terms_Filters as Filters, wql_parser_terms_GroupBy as GroupBy, wql_parser_terms_Head as Head, wql_parser_terms_Int as Int, wql_parser_terms_Metric as Metric, wql_parser_terms_Negate as Negate, wql_parser_terms_Pipeline as Pipeline, wql_parser_terms_Query as Query, wql_parser_terms_Quoted as Quoted, wql_parser_terms_Rollup as Rollup, wql_parser_terms_RollupDot as RollupDot, wql_parser_terms_Single as Single, wql_parser_terms_Stage as Stage, wql_parser_terms_Star as Star, wql_parser_terms_TagKey as TagKey, TagValue$1 as TagValue, wql_parser_terms_Value as Value, wql_parser_terms_Word as Word };
229
+ export { Aggregator$1 as Aggregator, wql_parser_terms_At as At, wql_parser_terms_By as By, wql_parser_terms_DatasetReference as DatasetReference, wql_parser_terms_Dimension as Dimension, wql_parser_terms_Dollar as Dollar, wql_parser_terms_Filter as Filter, wql_parser_terms_Filters as Filters, wql_parser_terms_GroupBy as GroupBy, wql_parser_terms_Head as Head, wql_parser_terms_Int as Int, wql_parser_terms_Metric as Metric, wql_parser_terms_Negate as Negate, wql_parser_terms_ParamRef as ParamRef, wql_parser_terms_Pipeline as Pipeline, wql_parser_terms_Query as Query, wql_parser_terms_Quoted as Quoted, wql_parser_terms_Rollup as Rollup, wql_parser_terms_RollupDot as RollupDot, wql_parser_terms_Single as Single, wql_parser_terms_Stage as Stage, wql_parser_terms_Star as Star, wql_parser_terms_TagKey as TagKey, TagValue$1 as TagValue, wql_parser_terms_Value as Value, wql_parser_terms_Word as Word };
226
230
  }
227
231
 
228
232
  /**
@@ -242,9 +246,10 @@ interface ParsedWqlRollupSuffix {
242
246
  unit: string;
243
247
  raw: string;
244
248
  }
245
- /** A window clause (C1): relative (`last 8w`) or civil-date range
246
- * (`from 2026-01-01 [to 2026-03-31]`). One window per query — `last` and
247
- * `from` are mutually exclusive (validated as a C3-style conflict). */
249
+ /** A window clause (C1): relative (`last 8w`), civil-date range
250
+ * (`from 2026-01-01 [to 2026-03-31]`), or a `$param` reference (`last $range`
251
+ * or `last $weeks w`). One window per query — `last` and `from` are mutually
252
+ * exclusive (validated as a C3-style conflict). */
248
253
  type ParsedWqlWindowSuffix = {
249
254
  kind: 'relative';
250
255
  size: number;
@@ -255,6 +260,11 @@ type ParsedWqlWindowSuffix = {
255
260
  start: string;
256
261
  end?: string;
257
262
  raw: string;
263
+ } | {
264
+ kind: 'param';
265
+ param: string;
266
+ unit?: 'd' | 'w';
267
+ raw: string;
258
268
  };
259
269
  interface ParsedWqlSuffixes {
260
270
  /** Outer cross-store join clause text (`where ...`). */
@@ -312,8 +322,14 @@ type Aggregator = WqlAggregator;
312
322
  interface TagValue {
313
323
  value: string;
314
324
  wildcard: boolean;
325
+ /** Parameter name (without `$`) when authored as a `$param` atom. */
326
+ param?: string;
315
327
  }
316
328
  interface TagFilter {
329
+ /** `'spreadParam'` when authored as a bare `$param` filter (`{$scope}`); `'kv'` (default) otherwise. */
330
+ kind?: 'kv' | 'spreadParam';
331
+ /** Parameter name (without `$`) when `kind === 'spreadParam'`. */
332
+ param?: string;
317
333
  key: string;
318
334
  negate: boolean;
319
335
  values: TagValue[];
@@ -355,8 +371,10 @@ interface ParsedAggregateQuery {
355
371
  family: 'aggregate';
356
372
  raw: string;
357
373
  agg: Aggregator;
358
- /** Canonical Metric Key (fact row `metricKey`). */
374
+ /** Canonical Metric Key (fact row `metricKey`), or `$param` when parameterized. */
359
375
  metric: string;
376
+ /** Parameter name (without `$`) when `metric` was authored as `$param`. */
377
+ metricParam?: string;
360
378
  filters: TagFilter[];
361
379
  /** Tag keys, or virtual dims: day | week | session | round. */
362
380
  groupBy: string[];
@@ -436,6 +454,10 @@ type QueryWindow = {
436
454
  kind: 'range';
437
455
  start: string;
438
456
  end?: string;
457
+ } | {
458
+ kind: 'param';
459
+ param: string;
460
+ unit?: 'd' | 'w';
439
461
  };
440
462
  type AnyParsedQuery = ParsedAggregateQuery | ParsedFindQuery | ParsedPipelineQuery;
441
463
  /** Type guard: true for content-discovery queries. */
@@ -594,6 +616,178 @@ declare function findTargetAdvisories(query: ParsedFindQuery): string[];
594
616
  /** Serialize any parsed query to canonical WQL text. Total: never throws. */
595
617
  declare function serialize(parsed: AnyParsedQuery): string;
596
618
 
619
+ /**
620
+ * First-class WQL `$param` (`ParamRef`) inspection and AST-level binding.
621
+ *
622
+ * Queries containing `$scope`, `effort:$effort`, `sum:$metric{}`, or
623
+ * `last $range` parse directly into typed AST nodes without pre-parse regex
624
+ * text substitution. At execution time, `bindQueryParams` binds active
625
+ * parameter values onto the AST — cleanly dropping empty optional filters
626
+ * (`$scope = ""`) instead of producing trailing-comma syntax errors, and
627
+ * routing content-only scope filters (`notebook:…`, `source:…`) on aggregate
628
+ * queries into a `where :note{…}` join.
629
+ */
630
+
631
+ /**
632
+ * Collect all `$param` names referenced anywhere in a parsed WQL AST, in
633
+ * deterministic appearance order.
634
+ */
635
+ declare function collectQueryParams(parsed: AnyParsedQuery): string[];
636
+ /** Parse a filter fragment (`effort:snatch, discipline:weightlifting` or `:note{tags:pr}`) into `TagFilter[]`. */
637
+ declare function parseFilterFragment(fragment: string): {
638
+ filters: TagFilter[];
639
+ error?: string;
640
+ };
641
+ /**
642
+ * Bind `$param` AST nodes (`ParamRef`) on a parsed query using `params`.
643
+ *
644
+ * If any referenced `$param` is absent from `params` (`params[name] === undefined`),
645
+ * returns `{ parsed, missing }` without mutating `parsed` so callers can surface
646
+ * `unknownTokensMessage(missing)`. Empty string values (`""`) are treated as
647
+ * "unfiltered / unset" for filter and window parameters.
648
+ */
649
+ declare function bindQueryParams(parsed: AnyParsedQuery, params: Record<string, string>): {
650
+ parsed: AnyParsedQuery;
651
+ missing: string[];
652
+ };
653
+
654
+ /**
655
+ * Shared widget type vocabulary and legacy ```query:<type>[-<N>|-full] fence
656
+ * suffix parser. Kept free of `queryBlockCodec` / `dashboard/model` imports so
657
+ * both modules can depend on it without a cycle.
658
+ */
659
+ declare const DASHBOARD_WIDGET_TYPES: readonly ["table", "list", "value", "timeseries", "bar", "donut", "toplist", "stacked-bar", "goal-rings", "zone-distribution"];
660
+ type DashboardWidgetType = (typeof DASHBOARD_WIDGET_TYPES)[number];
661
+ declare function isDashboardWidgetType(type: string): type is DashboardWidgetType;
662
+ declare const DASHBOARD_GRID_MAX_COLS = 4;
663
+ interface QueryWidgetSuffix {
664
+ /** Raw widget type from the tag, lowercased; '' for a bare ```query fence. */
665
+ type: string;
666
+ /** Grid column span 1..4 (`-N`). */
667
+ spanCols?: number;
668
+ /** Full-row flag (`-full`). Mutually exclusive with spanCols. */
669
+ spanFull?: boolean;
670
+ /** Presentation attributes: `key=value` tokens after the type/span
671
+ * (decision 22 — positional params ride the fence tag, not the body). */
672
+ attributes: Record<string, string>;
673
+ /** Attribute order for stable re-serialization. */
674
+ attributeOrder: string[];
675
+ /** Set when the suffix is malformed (the type is still reported raw). */
676
+ error?: string;
677
+ }
678
+ /**
679
+ * Parse the suffix after `query:` in a fence tag — `<type>`, `<type>-<N>` or
680
+ * `<type>-full`. Unknown types parse fine (renderers badge them); structural
681
+ * problems (empty type, bad span, `-N-full` combo) set `error`.
682
+ */
683
+ declare function parseQueryWidgetSuffix(suffix: string): QueryWidgetSuffix;
684
+
685
+ /**
686
+ * queryBlockCodec — Canonical `QueryBlockObject` model and lossless YAML /
687
+ * 1-line shorthand codec for ```query fences.
688
+ *
689
+ * Design boundary:
690
+ * - **YAML** inside ```query owns layout, presentation, titles, multi-series
691
+ * composition, formulas, goals, table columns, and sorting.
692
+ * - **WQL** inside `query:` / `series[].query:` (and bare 1-line shorthand
693
+ * fences like `:session{result:<id>}`) owns search and data selection.
694
+ *
695
+ * Zero external runtime dependencies — safe in Web Workers, CLI, and browser.
696
+ */
697
+
698
+ type QueryViewKind = 'table' | 'list' | 'value' | 'timeseries' | 'bar' | 'donut' | 'toplist' | 'stacked-bar' | 'goal-rings' | 'zone-distribution';
699
+ interface QuerySeriesSpec {
700
+ id: string;
701
+ label?: string;
702
+ /** Standard WQL query expression (when this layer is a data query). */
703
+ query?: string;
704
+ /** Arithmetic / correlation formula referencing sibling series ids. */
705
+ formula?: string;
706
+ normalize?: string;
707
+ unit?: string;
708
+ /** When false, computed as an intermediate dependency (e.g. for a formula) without plotting. */
709
+ visible?: boolean;
710
+ }
711
+ type ScalarOrParam = number | {
712
+ param: string;
713
+ };
714
+ interface QuerySortSpec {
715
+ col: string;
716
+ dir: 'asc' | 'desc';
717
+ }
718
+ interface QueryBlockObject {
719
+ title?: string;
720
+ description?: string;
721
+ /** Active view kind (defaults to `'table'`). Unknown legacy types ride `rawViewType`. */
722
+ view: QueryViewKind;
723
+ /** Preserved raw view string when a legacy fence named an unknown widget type. */
724
+ rawViewType?: string;
725
+ span?: 1 | 2 | 3 | 4 | 'full';
726
+ unit?: string;
727
+ window?: QueryWindow;
728
+ groupBy?: string[];
729
+ /** Shorthand single WQL query when there is 1 data layer and no formula. */
730
+ query?: string;
731
+ /** Multi-layer series & formula definitions. */
732
+ series?: QuerySeriesSpec[];
733
+ /** Table presentation options. */
734
+ columns?: string[];
735
+ sort?: QuerySortSpec[];
736
+ limit?: number;
737
+ /** Chart / threshold options. */
738
+ goal?: ScalarOrParam;
739
+ targets?: ScalarOrParam[];
740
+ comparePr?: boolean;
741
+ /** Preserved extra legacy attributes. */
742
+ attributes?: Record<string, string>;
743
+ /** Malformed fence/YAML syntax error, if any. */
744
+ error?: string;
745
+ }
746
+ interface ParseQueryBlockOptions {
747
+ /** Optional fence tag (`query`, `query:timeseries-2 goal=$x`, or suffix `timeseries-2`). */
748
+ fenceTag?: string;
749
+ /** Legacy fallback title from an adjacent `## Heading` above the fence. */
750
+ adjacentTitle?: string;
751
+ /** Legacy fallback description/question from an adjacent paragraph above the fence. */
752
+ adjacentDescription?: string;
753
+ }
754
+ /** True when `rawBody` is authored in YAML `key: value` form (not bare WQL or legacy QueryDocument). */
755
+ declare function isYamlQueryBlockBody(rawBody: string): boolean;
756
+ /**
757
+ * Parse any ```query fence body (canonical YAML, 1-line WQL shorthand, or
758
+ * legacy QueryDocument + fence-tag suffix) into a canonical `QueryBlockObject`.
759
+ */
760
+ declare function parseQueryBlock(rawBody: string, options?: ParseQueryBlockOptions): QueryBlockObject;
761
+ /**
762
+ * True when `obj` can serialize as a zero-boilerplate 1-line WQL shorthand
763
+ * inside ```query (e.g. `:session{result:<id>}`) without losing any layout metadata.
764
+ */
765
+ declare function isDefaultShorthandQueryBlock(obj: QueryBlockObject): boolean;
766
+ /**
767
+ * Serialize a `QueryBlockObject` into the inner content of a ```query fence:
768
+ * - Emits 1-line WQL shorthand when `isDefaultShorthandQueryBlock(obj)` holds;
769
+ * - Otherwise emits clean, deterministic 2-space YAML.
770
+ */
771
+ declare function serializeQueryBlock(obj: QueryBlockObject, opts?: {
772
+ forceYaml?: boolean;
773
+ }): string;
774
+ /** Serialize a full fenced ```query markdown block (opening fence + body + closing fence). */
775
+ declare function serializeQueryBlockFence(obj: QueryBlockObject, opts?: {
776
+ forceYaml?: boolean;
777
+ }): string;
778
+ /**
779
+ * Compile a `QueryBlockObject` into an executable WQL / `QueryDocument` text
780
+ * consumed by `SharedQueryDocumentRunner` and `QueryService`.
781
+ */
782
+ declare function queryBlockToDocumentText(obj: QueryBlockObject): string;
783
+ /** Derive widget `attributes` map (`goal`, `targets`, `comparePr`, `label.<id>`) from `QueryBlockObject`. */
784
+ declare function queryBlockAttributes(obj: QueryBlockObject): {
785
+ attributes: Record<string, string>;
786
+ attributeOrder: string[];
787
+ };
788
+ /** Collect all `$param` names referenced anywhere in a `QueryBlockObject` (queries, window, goal, targets). */
789
+ declare function collectQueryBlockParams(obj: QueryBlockObject): string[];
790
+
597
791
  /**
598
792
  * Canonical discipline vocabulary — the single source of truth for effort
599
793
  * disciplines across the resolver, the TIS factor table, fact-row tags, the
@@ -703,6 +897,23 @@ interface WqlCompletionOptions {
703
897
  */
704
898
  catalog?: IFieldCatalog;
705
899
  }
900
+ type WqlCursorStageRole = 'source' | 'reduce' | 'sink' | 'binding' | 'defaults';
901
+ interface WqlCursorStageInfo {
902
+ role: WqlCursorStageRole;
903
+ /** 0-indexed pipeline stage index within the active line (0 = source, 1+ = reduce/sink). */
904
+ stageIndex: number;
905
+ /** 0-indexed transform index (0 for first reducer stage, 1 for second, etc.). */
906
+ reduceIndex?: number;
907
+ head?: string;
908
+ from: number;
909
+ to: number;
910
+ }
911
+ /**
912
+ * Resolve the active pipeline stage role and character range at `pos` inside
913
+ * a single-line or multi-line WQL document — powers WqlComposer visual stage
914
+ * feedback (`source` → `reduce` → `sink`).
915
+ */
916
+ declare function resolveWqlCursorStage(doc: string, pos: number): WqlCursorStageInfo;
706
917
  declare function wqlCompletionSource(options_?: WqlCompletionOptions): (context: CompletionContext) => CompletionResult | Promise<CompletionResult | null> | null;
707
918
  declare function wqlCompletion(options?: WqlCompletionOptions): Extension;
708
919
  /**
@@ -843,6 +1054,10 @@ declare function resolveWindowRange(w: {
843
1054
  kind: 'range';
844
1055
  start: string;
845
1056
  end?: string;
1057
+ } | {
1058
+ kind: 'param';
1059
+ param: string;
1060
+ unit?: 'd' | 'w';
846
1061
  } | undefined, ctx: ExecutionContext): ResolvedRange | undefined;
847
1062
  /** Half-open membership predicate: start included, exclusive end excluded
848
1063
  * (a metric exactly at Monday midnight belongs only to the new week).
@@ -887,6 +1102,11 @@ interface DocumentAssignment {
887
1102
  /** For kind 'query' — the parsed query of any family (defaults merged at run). */
888
1103
  queryText?: string;
889
1104
  parsed?: AnyParsedQuery;
1105
+ /** When a pipeline starts from a previously bound assignment (`kb = bench | :sum{…}`). */
1106
+ sourceRef?: string;
1107
+ /** The pipe stages after `<sourceRef> |` (`:sum{…} | :bar{…}`). */
1108
+ pipeTail?: string;
1109
+ transformsText?: string;
890
1110
  formula?: DocumentFormula;
891
1111
  raw: string;
892
1112
  }
@@ -894,6 +1114,8 @@ interface QueryDocument {
894
1114
  defaults?: DocumentDefaults;
895
1115
  assignments: DocumentAssignment[];
896
1116
  show: string[];
1117
+ /** Optional terminal chart sink on the `show` line (`show a, b | :stacked-bar{…}`). */
1118
+ showChart?: PipelineSink;
897
1119
  /** True when the body carried no document constructs (legacy single query). */
898
1120
  degenerate: boolean;
899
1121
  }
@@ -1121,6 +1343,11 @@ interface NoteRelationBundle {
1121
1343
  /** Resolved junction pages by page id. */
1122
1344
  pages: Page[];
1123
1345
  }
1346
+ interface FeedCatalogQueryStore {
1347
+ getAllFeeds(): Promise<FeedSourceCatalogRow[]>;
1348
+ getAllNotebooks(): Promise<FeedNotebookCatalogRow[]>;
1349
+ getRemoteNotebookNotes?(slug: string, feedId?: string): Promise<Note[]>;
1350
+ }
1124
1351
  interface QueryServiceStores {
1125
1352
  eventStore?: EventStore;
1126
1353
  noteStore?: NoteQueryStore;
@@ -1132,6 +1359,10 @@ interface QueryServiceStores {
1132
1359
  blockEffortsStore?: {
1133
1360
  getAllFromIndex(index: string, key: string): Promise<any[]>;
1134
1361
  };
1362
+ /** Serves equipment containment rows (`block_equipment` store). */
1363
+ blockEquipmentStore?: {
1364
+ getAllFromIndex(index: string, key: string): Promise<any[]>;
1365
+ };
1135
1366
  /** Serves tag records (`tags` store). `getAll` backs the `:tag{}` plane;
1136
1367
  * absent → the plane resolves to no rows. */
1137
1368
  tagsStore?: {
@@ -1170,6 +1401,8 @@ interface QueryServiceStores {
1170
1401
  };
1171
1402
  /** Optional notebook subscription checker for feed-owned notes/notebooks. */
1172
1403
  isNotebookSubscribed?: (feedId: string, chunkId: string) => boolean;
1404
+ /** Distributed feed & notebook catalog seam for `:feed{}`, `:notebook{type:notebook}`, and zero-import remote previews. */
1405
+ feedCatalogStore?: FeedCatalogQueryStore;
1173
1406
  }
1174
1407
 
1175
1408
  /**
@@ -1225,7 +1458,7 @@ declare function feedOfItem(item: {
1225
1458
  * (`seedNoteSourceId`/`chunkIdFor`) derives the sourceId from the same path
1226
1459
  * the importer stamps as `sourcePath`.
1227
1460
  */
1228
- declare function notebookOfItem(item: {
1461
+ interface NotebookResolvableItem {
1229
1462
  id?: string;
1230
1463
  noteId?: string;
1231
1464
  sourceId?: string;
@@ -1236,8 +1469,16 @@ declare function notebookOfItem(item: {
1236
1469
  feedSourceId?: string;
1237
1470
  sourcePath?: string;
1238
1471
  notebookId?: string;
1472
+ notebookIds?: readonly string[];
1239
1473
  tags?: readonly string[];
1240
- }): NotebookId | undefined;
1474
+ }
1475
+ /**
1476
+ * Resolve ALL notebooks an item belongs to (many-to-many).
1477
+ * User-owned notes retain their base container (`notebook/journal` or `notebook/playground`)
1478
+ * alongside every promoted user notebook (`notebookIds`, `notebookId`, `notebook:` tags).
1479
+ */
1480
+ declare function notebooksOfItem(item: NotebookResolvableItem): NotebookId[];
1481
+ declare function notebookOfItem(item: NotebookResolvableItem): NotebookId | undefined;
1241
1482
  /**
1242
1483
  * Who owns the notebook a row resolves to — the editability key (ticket 05).
1243
1484
  * Pure over the row's own fields, and exact for every reachable state:
@@ -1251,7 +1492,7 @@ declare function notebookOfItem(item: {
1251
1492
  * A user-owned copy (clone) keeps its provenance stamps but resolves through
1252
1493
  * tier 1, so it is editable while its origin stays visible.
1253
1494
  */
1254
- declare function notebookOriginOfItem(item: Parameters<typeof notebookOfItem>[0]): NotebookOrigin | undefined;
1495
+ declare function notebookOriginOfItem(item: NotebookResolvableItem): NotebookOrigin | undefined;
1255
1496
  declare function feedIdOfItem(item: {
1256
1497
  feedSourceId?: string;
1257
1498
  seedChunkId?: string;
@@ -1397,6 +1638,8 @@ interface QueryOptions {
1397
1638
  /** Captured execution context (ticket 12) — one `{instant, timeZone}`
1398
1639
  * capture per document run; defaults to a fresh system capture. */
1399
1640
  context?: ExecutionContext;
1641
+ /** Active `$param` bindings applied to `ParamRef` AST nodes at execution time. */
1642
+ params?: Record<string, string>;
1400
1643
  }
1401
1644
  /** Options for `runFind` / `runFindBlock` — overrides for the parsed WQL. */
1402
1645
  interface FindOptions {
@@ -1409,6 +1652,12 @@ interface FindOptions {
1409
1652
  /** Captured execution context (ticket 12). */
1410
1653
  context?: ExecutionContext;
1411
1654
  isNotebookSubscribed?: (feedId: string, chunkId: string) => boolean;
1655
+ /** When true (e.g. pipeline source feeding a numeric reducer), skip container/placement hydration. */
1656
+ skipContainers?: boolean;
1657
+ /** Active `$param` bindings applied to `ParamRef` AST nodes at execution time. */
1658
+ params?: Record<string, string>;
1659
+ /** When 'containers' (e.g. `/notebooks` library plane), `:notebook{…}` returns Notebook container rows instead of member Notes. */
1660
+ notebookPlane?: 'notes' | 'containers';
1412
1661
  }
1413
1662
  interface QueryResult {
1414
1663
  parsed: ParsedAggregateQuery;
@@ -1484,7 +1733,9 @@ declare class QueryService {
1484
1733
  private readonly relationStore?;
1485
1734
  private readonly datasetStore?;
1486
1735
  private readonly isNotebookSubscribed?;
1736
+ private readonly feedCatalogStore?;
1487
1737
  private blockEffortsStore;
1738
+ private blockEquipmentStore;
1488
1739
  private tagsStore;
1489
1740
  private noteTagsStore;
1490
1741
  constructor(storesOrEventStore?: QueryServiceStores | EventStore, noteStore?: NoteQueryStore, blockStore?: BlockQueryStore, effortStore?: EffortQueryStore);
@@ -1553,6 +1804,19 @@ declare class QueryService {
1553
1804
  * stages look up `pageSources` (then an injected datasetStore)
1554
1805
  * synchronously; no database roundtrip. */
1555
1806
  runPipelineParsed(parsed: AnyParsedQuery, options?: PipelineOptions): Promise<PipelineResult>;
1807
+ /**
1808
+ * Evaluate pipeline tail stages (`:sum{…} | :bar{…}`) over an already-fetched
1809
+ * `FindQueryResult` (or `FamilyRunPayload`). Resolves and caches `content.events`
1810
+ * on the first call so multiple downstream named branches (`kb = bench | :sum{…}`,
1811
+ * `bb = bench | :sum{…}`) share the exact `EventRecord[]` slice in memory.
1812
+ */
1813
+ runPipelineFromFind(content: {
1814
+ notes?: Note[];
1815
+ blocks?: BlockIndexRow[];
1816
+ events?: EventRecord[];
1817
+ runs?: RowsRun[];
1818
+ table?: TabularResult;
1819
+ }, pipeTail: string, options?: PipelineOptions): Promise<PipelineResult>;
1556
1820
  /** Events behind a content source — resolved ONLY when a transform needs
1557
1821
  * them: session/table sources already carry their rows; note sources read
1558
1822
  * the per-note index; block sources read the content index. */
@@ -1589,10 +1853,12 @@ declare class QueryService {
1589
1853
  private noteContentMap;
1590
1854
  /** Collect wod blockContentIds owned by a find query's content matches. */
1591
1855
  private contentIdsFromFindResult;
1592
- /** Load note tag labels only when the query touches 'tags'. Batched when
1593
- * a relationStore is injected — one bundle read per run instead of a
1594
- * junction read per row's note. */
1595
- private loadNoteTags;
1856
+ /**
1857
+ * Load 3-tier fact dimensions (`noteTags`, `typedNoteTags`, `effortsBySlug`)
1858
+ * in at most one batched `relationStore.getBatches` call and one
1859
+ * `effortStore.getAllEfforts` call per query run.
1860
+ */
1861
+ private loadFactDimensions;
1596
1862
  /** Resolve matching note IDs for an exercise slug via the block_efforts containment index. */
1597
1863
  private getNoteIdsForEffort;
1598
1864
  /** Resolve matching note IDs for a canonical typed tag (e.g. equipment:kettlebell). */
@@ -1609,6 +1875,17 @@ declare class QueryService {
1609
1875
  * management surface) is the app's NotebookService model, not WQL rows.
1610
1876
  */
1611
1877
  runFindNotebook(parsed: ParsedFindQuery, options?: FindOptions): Promise<FindQueryResult>;
1878
+ /**
1879
+ * Execute `:feed{}` — the distributed Feed sources plane.
1880
+ * Returns one synthetic Note-shaped row per registered Feed source
1881
+ * (including "My Published Feed" when local public content or server snapshot exists).
1882
+ */
1883
+ runFindFeed(parsed: ParsedFindQuery, _options?: FindOptions): Promise<FindQueryResult>;
1884
+ /**
1885
+ * Execute `:notebook{type:notebook, ...}` — the Notebook container listing
1886
+ * across user-owned local notebooks and manifest-discovered remote Feed notebooks.
1887
+ */
1888
+ private runFindNotebookContainers;
1612
1889
  /**
1613
1890
  * Execute a :page query (ticket 08) — the placement plane. Results are
1614
1891
  * the placed notes; `placements` carries every page each note sits on
@@ -1720,6 +1997,7 @@ interface DocumentOutput {
1720
1997
  interface DocumentResult {
1721
1998
  outputs: DocumentOutput[];
1722
1999
  diagnostics: string[];
2000
+ showChart?: PipelineSink;
1723
2001
  }
1724
2002
  /** Payload surfaces the ticket-19 family dispatch may hand back. */
1725
2003
  interface FamilyRunPayload {
@@ -1728,6 +2006,7 @@ interface FamilyRunPayload {
1728
2006
  notes?: Note[];
1729
2007
  blocks?: BlockIndexRow[];
1730
2008
  efforts?: unknown[];
2009
+ events?: EventRecord[];
1731
2010
  containers?: Record<string, NoteContainer>;
1732
2011
  placements?: Record<string, NotePlacement[]>;
1733
2012
  runs?: RowsRun[];
@@ -1746,6 +2025,9 @@ interface QueryDocumentRunnerOptions {
1746
2025
  /** Pipeline queries (`:source | :fn | :chart`, `@dataset | …`) surface
1747
2026
  * the pipeline result — the host's QueryService.runPipeline. */
1748
2027
  runPipeline?: (queryText: string) => Promise<FamilyRunPayload>;
2028
+ /** Evaluate pipeline tail stages (`:sum{…} | :bar{…}`) over an already-evaluated find payload (shared source DAG). */
2029
+ runPipelineFromFind?: (sourceFind: FamilyRunPayload, pipeTail: string) => Promise<FamilyRunPayload>;
2030
+ runAggregateEvents?: (queryText: string, events: readonly EventRecord[], sourceFind?: FamilyRunPayload) => Promise<FamilyRunPayload>;
1749
2031
  }
1750
2032
  declare class QueryDocumentRunner$1 {
1751
2033
  private readonly runAggregate;
@@ -1825,11 +2107,14 @@ interface QueryDocumentRunnerHost {
1825
2107
  runs?: RowsRun[];
1826
2108
  table?: TabularResult;
1827
2109
  unit?: string;
2110
+ events?: EventRecord[];
1828
2111
  error?: string;
1829
2112
  }>;
1830
2113
  /** Pipeline execution (`:source | :fn | :chart`, `@dataset | …`) — the
1831
2114
  * host's QueryService.runPipeline. */
1832
2115
  runPipeline?(queryText: string, context?: ExecutionContext): Promise<FamilyRunPayload>;
2116
+ /** Evaluate pipeline tail stages over an already-evaluated find payload (shared source DAG). */
2117
+ runPipelineFromFind?(sourceFind: FamilyRunPayload, pipeTail: string, context?: ExecutionContext): Promise<FamilyRunPayload>;
1833
2118
  /** Injected formula evaluator override (engine/app composition adapts
1834
2119
  * lang's calc evaluator); the built-in pointwise evaluator otherwise. */
1835
2120
  formulaEvaluator?: FormulaEvaluator;
@@ -1924,16 +2209,6 @@ interface SummaryFactSourceOutput {
1924
2209
  declare function normalizeSummaryFacts(logs: readonly SummaryFactSourceOutput[], identity: SummaryFactIdentity): AnalyticsDataPoint[];
1925
2210
  /** Identity for unified event-row emission — same fields as the fact identity. */
1926
2211
  type EventRowIdentity = SummaryFactIdentity;
1927
- /**
1928
- * Logs → event rows, 1:1 per statement (ticket 002). Deterministic ids
1929
- * `${resultId}:${seq}`; query-critical scalars promoted top-level.
1930
- *
1931
- * Ticket 12 temporal anchoring: the row timestamp is the statement's OWN
1932
- * timeSpan start when it has one — the workout-start timestamp never
1933
- * relocates a metric observation whose own instant differs. Statements with
1934
- * a timeSpan carry per-metric temporal anchors ('instant') so projection
1935
- * groups each observation under its own date.
1936
- */
1937
2212
  declare function toEventRows(logs: readonly StoredOutputStatement[], identity: SummaryFactIdentity): EventRecord[];
1938
2213
  /**
1939
2214
  * Tier-2 analytics outputs → deterministic summary event rows (tickets
@@ -1949,7 +2224,12 @@ declare function toSummaryEventRows(logs: readonly StoredOutputStatement[], iden
1949
2224
  * from the row's label metric as fallback. Deterministic fact ids:
1950
2225
  * `${record.id}:${factOrdinal}`.
1951
2226
  */
2227
+ interface ProjectEventToFactsFilter {
2228
+ metricKey?: string;
2229
+ }
2230
+ declare function matchesFactMetricKey(metricKey: string | undefined, queryMetric: string | undefined): boolean;
1952
2231
  declare function projectEventToFacts(record: EventRecord): AnalyticsDataPoint[];
2232
+ declare function projectEventToFacts(record: EventRecord, filter?: ProjectEventToFactsFilter): AnalyticsDataPoint[];
1953
2233
  /**
1954
2234
  * Inverse of {@link toEventRows}/{@link toSummaryEventRows}: rebuild the
1955
2235
  * statement stream a session's event rows represent. Event rows keep their
@@ -2005,9 +2285,7 @@ declare function hasLegacyIdentity(row: Record<string, unknown>): boolean;
2005
2285
  * This module is pure — no React, no editor, no query service — so the editor
2006
2286
  * extensions, the inline block renderer, and the dashboard route all share it.
2007
2287
  */
2008
- declare const DASHBOARD_WIDGET_TYPES: readonly ["table", "list", "value", "timeseries", "bar", "donut", "toplist", "stacked-bar", "goal-rings", "zone-distribution"];
2009
- type DashboardWidgetType = (typeof DASHBOARD_WIDGET_TYPES)[number];
2010
- declare function isDashboardWidgetType(type: string): type is DashboardWidgetType;
2288
+
2011
2289
  /** The widget type a block renders as: a bare ```query fence defaults to `table`. */
2012
2290
  declare function resolveWidgetType(type: string | undefined): string;
2013
2291
  /** Shared badge messages — the editor, inline renderer, and route all word these identically. */
@@ -2021,28 +2299,6 @@ declare const PLANNED_WIDGET_TYPES: readonly string[];
2021
2299
  * placeholder badge (#901).
2022
2300
  */
2023
2301
  declare function isProposedMetric(metricKey: string | undefined): boolean;
2024
- declare const DASHBOARD_GRID_MAX_COLS = 4;
2025
- interface QueryWidgetSuffix {
2026
- /** Raw widget type from the tag, lowercased; '' for a bare ```query fence. */
2027
- type: string;
2028
- /** Grid column span 1..4 (`-N`). */
2029
- spanCols?: number;
2030
- /** Full-row flag (`-full`). Mutually exclusive with spanCols. */
2031
- spanFull?: boolean;
2032
- /** Presentation attributes: `key=value` tokens after the type/span
2033
- * (decision 22 — positional params ride the fence tag, not the body). */
2034
- attributes: Record<string, string>;
2035
- /** Attribute order for stable re-serialization. */
2036
- attributeOrder: string[];
2037
- /** Set when the suffix is malformed (the type is still reported raw). */
2038
- error?: string;
2039
- }
2040
- /**
2041
- * Parse the suffix after `query:` in a fence tag — `<type>`, `<type>-<N>` or
2042
- * `<type>-full`. Unknown types parse fine (renderers badge them); structural
2043
- * problems (empty type, bad span, `-N-full` combo) set `error`.
2044
- */
2045
- declare function parseQueryWidgetSuffix(suffix: string): QueryWidgetSuffix;
2046
2302
  /** Frontmatter meta shape. */
2047
2303
  type DashboardMeta = Record<string, string | number | string[]>;
2048
2304
  interface DashboardToken {
@@ -2085,6 +2341,8 @@ interface DashboardSectionInput {
2085
2341
  subtype?: string;
2086
2342
  /** Raw inner content of the section. */
2087
2343
  content: string;
2344
+ /** Raw fence tag (`query` or `query:bar-2`) when parsed from markdown. */
2345
+ fenceTag?: string;
2088
2346
  /** Widget type suffix parsed from the fence tag (query sections). */
2089
2347
  widgetType?: string;
2090
2348
  /** Grid column span parsed from the fence tag (query sections). */
@@ -2104,18 +2362,20 @@ interface DashboardWidget {
2104
2362
  type: string;
2105
2363
  spanCols?: number;
2106
2364
  spanFull?: boolean;
2107
- /** Full fenced body — a Query Document (decision 22), comment lines
2108
- * stripped, surrounding whitespace trimmed, line structure preserved. */
2365
+ /** Executable Query Document / WQL string consumed by runners and validators. */
2109
2366
  body: string;
2110
- /** Malformed fence-suffix reason — renderers badge instead of executing. */
2367
+ /** Raw fenced text before YAML → QueryDocument compilation. */
2368
+ rawBody?: string;
2369
+ /** Canonical structured QueryBlockObject parsed from YAML, 1-line shorthand, or legacy fences. */
2370
+ queryObject?: QueryBlockObject;
2371
+ /** Malformed fence-suffix or YAML reason — renderers badge instead of executing. */
2111
2372
  widgetError?: string;
2112
- /** Fence-tag presentation attributes (decision 22) — positional params
2113
- * ride the tag, never the body. */
2373
+ /** Presentation attributes (`goal`, `targets`, `comparePr`, `label.<id>`, or legacy tag attrs). */
2114
2374
  attributes: Record<string, string>;
2115
2375
  attributeOrder: string[];
2116
- /** Title from the markdown heading directly above (or above the question). */
2376
+ /** Title from inline YAML `title:` (preferred) or markdown heading directly above. */
2117
2377
  title?: string;
2118
- /** Coaching question from the paragraph directly above the block. */
2378
+ /** Coaching question / description from inline YAML `description:` or paragraph directly above. */
2119
2379
  question?: string;
2120
2380
  }
2121
2381
  interface DashboardDocument {
@@ -2179,18 +2439,19 @@ declare function buildDashboardScaffold(title?: string): string;
2179
2439
  */
2180
2440
 
2181
2441
  interface WidgetSpec {
2182
- /** Card title — renders as a `## ` heading above the block. */
2442
+ /** Card title — persisted as `title:` inside the YAML ```query fence. */
2183
2443
  title?: string;
2184
- /** Coaching question — the paragraph between the heading and the block. */
2444
+ /** Coaching question / description — persisted as `description:` inside YAML. */
2185
2445
  question?: string;
2186
- /** Raw widget type from the fence suffix ('' → the `table` default). */
2446
+ /** Raw widget type (`''` → the `table` default). */
2187
2447
  type: string;
2188
2448
  spanCols?: number;
2189
2449
  spanFull?: boolean;
2190
- /** The composed Query Document text — stored verbatim as the block body
2191
- * (single-line or multi-line; decision 22). */
2450
+ /** The composed WQL / Query Document text. */
2192
2451
  wql: string;
2193
- /** Fence-tag presentation attributes (goal targets, …). */
2452
+ /** Optional pre-built structured `QueryBlockObject` (preferred by `<QueryObjectBuilder />`). */
2453
+ queryObject?: QueryBlockObject;
2454
+ /** Presentation attributes (goal targets, …). */
2194
2455
  attributes?: Record<string, string>;
2195
2456
  /** Attribute emission order (defaults to Object key order). */
2196
2457
  attributeOrder?: string[];
@@ -2201,7 +2462,9 @@ type WidgetSpan = Pick<WidgetSpec, 'spanCols' | 'spanFull'>;
2201
2462
  declare function widgetFenceTag(spec: Pick<WidgetSpec, 'type' | 'spanCols' | 'spanFull' | 'attributes' | 'attributeOrder'>): string;
2202
2463
  /** Block body: the Query Document text verbatim (trimmed). */
2203
2464
  declare function widgetBodyLine(spec: Pick<WidgetSpec, 'wql'>): string;
2204
- /** The markdown lines of a whole widget group (heading? / question? / fence block). */
2465
+ /** Convert a `WidgetSpec` into its canonical `QueryBlockObject`. */
2466
+ declare function widgetSpecToQueryObject(spec: WidgetSpec): QueryBlockObject;
2467
+ /** The markdown lines of a widget — canonical self-contained ```query block (YAML or 1-line shorthand). */
2205
2468
  declare function renderWidgetGroup(spec: WidgetSpec): string[];
2206
2469
  /**
2207
2470
  * Append a new widget group at the end of the note body. Frontmatter and all
@@ -2325,6 +2588,28 @@ declare function extractNoteWqlOverride(rawContent?: string): string | undefined
2325
2588
  * `EntityScopeDescriptor`.
2326
2589
  */
2327
2590
  declare function resolveEntityScope(input: ResolveEntityScopeInput): EntityScopeDescriptor;
2591
+ interface ResolveQueryExecutionScopeInput {
2592
+ noteId?: string;
2593
+ rawContent?: string;
2594
+ tokenValues?: Record<string, string>;
2595
+ pageSources?: PageSourceRegistry | ReadonlyMap<string, PageSourceEntry>;
2596
+ noteEvents?: EventRecord[];
2597
+ note?: Note;
2598
+ }
2599
+ interface QueryExecutionScope {
2600
+ tokens: Record<string, string>;
2601
+ pageSources: PageSourceRegistry;
2602
+ }
2603
+ /**
2604
+ * Resolve the unified execution scope (tokens + page dataset registry) for
2605
+ * a ```query block or Dashboard Widget.
2606
+ *
2607
+ * Merge precedence:
2608
+ * 1. Entity scope defaults (`note`, `thisnote`, `scope`, `metric`) when `noteId` is given
2609
+ * 2. Frontmatter `dashboard.*` token defaults when `rawContent` is given
2610
+ * 3. Caller `tokenValues` overrides
2611
+ */
2612
+ declare function resolveQueryExecutionScope(input?: ResolveQueryExecutionScopeInput): QueryExecutionScope;
2328
2613
  /**
2329
2614
  * Infer default Dashboard Widget specs for turning any WQL query or
2330
2615
  * `EntityScopeDescriptor` into a multi-widget Dashboard Note.
@@ -2343,17 +2628,98 @@ interface BuildScopedDashboardOptions {
2343
2628
  */
2344
2629
  declare function buildDashboardFromScope(options: BuildScopedDashboardOptions): string;
2345
2630
 
2631
+ /**
2632
+ * INTEGRATION STATUS (wayfinder): intentionally unwired — no production
2633
+ * consumer yet. Wiring is the open item of wayfinder ticket 20 (runner/store wiring); do not
2634
+ * delete these exports (they are the tested deliverable awaiting cutover).
2635
+ * Query cache, scan coalescing, and invalidation (wayfinder
2636
+ * datadog-analytics ticket 20, per the invalidation and performance
2637
+ * contract).
2638
+ *
2639
+ * - Cache keys are STRUCTURAL: normalized AST, resolved range instants,
2640
+ * effective timezone, captured instant, store generation, and active
2641
+ * unit defaults. Changing any dimension invalidates by key.
2642
+ * - Scan coalescing: widgets sharing one resolved range share one in-flight
2643
+ * store fetch — coalescing never merges semantically different queries
2644
+ * beyond the shared raw fetch.
2645
+ * - Invalidation: commits to results/notes/efforts/catalog bump an
2646
+ * in-memory generation and post ANALYTICS_MUTATION on BroadcastChannel
2647
+ * 'wodwiki.analytics'; a received receipt advances the local epoch so
2648
+ * generation comparisons stay correct across reloads.
2649
+ *
2650
+ * Pure module: the channel factory is injected (tests pass a fake; the app
2651
+ * passes `new BroadcastChannel('wodwiki.analytics')`).
2652
+ */
2653
+
2654
+ /** Cross-tab invalidation bus. Every tab owns one bus over one channel. */
2655
+ declare class AnalyticsInvalidationBus {
2656
+ private readonly makeChannel;
2657
+ private channel?;
2658
+ private generation;
2659
+ private readonly listeners;
2660
+ constructor(makeChannel: () => BroadcastChannel | undefined);
2661
+ get generationId(): number;
2662
+ /** Commit hook: bump local generation and broadcast the receipt. */
2663
+ publishMutation(): Promise<void>;
2664
+ /** Listen for receipts from OTHER tabs (and this one). */
2665
+ subscribe(): void;
2666
+ onChange(listener: () => void): () => void;
2667
+ private notify;
2668
+ }
2669
+ /** Structural cache: entries carry the generation they were computed under;
2670
+ * a read against a different generation is a miss (and drops the entry).
2671
+ *
2672
+ * Bounded LRU: the cache holds at most `maxEntries` (default 64) entries.
2673
+ * A read refreshes recency; a write evicts the least-recently-used entry
2674
+ * when the cache is full. The bound keeps browser memory flat — an
2675
+ * unbounded cache over a long-lived dashboard session grows with every
2676
+ * distinct query the user ever ran. */
2677
+ declare class QueryCache {
2678
+ private readonly entries;
2679
+ private readonly maxEntries;
2680
+ constructor(bus: AnalyticsInvalidationBus, options?: {
2681
+ maxEntries?: number;
2682
+ });
2683
+ get(key: string, generation: number): unknown;
2684
+ set(key: string, value: unknown, generation: number): void;
2685
+ clear(): void;
2686
+ /** Current entry count — the LRU bound's observable state. */
2687
+ get size(): number;
2688
+ }
2689
+ interface CacheKeyContext {
2690
+ rangeStart?: number;
2691
+ rangeEnd?: number;
2692
+ timeZone?: string;
2693
+ instant?: number;
2694
+ generation: number;
2695
+ /** Active system default output units (dimension → unit). */
2696
+ unitDefaults?: Record<string, string | undefined>;
2697
+ }
2698
+ /** Structural cache key: canonical AST + every context dimension. */
2699
+ declare function computeCacheKey(parsed: AnyParsedQuery, context: CacheKeyContext): string;
2700
+ /**
2701
+ * Wrap a UnifiedEventStore's range fetch with in-flight coalescing: calls
2702
+ * sharing an identical resolved range join one fetch; different ranges scan
2703
+ * separately. A mutation through the returned `invalidate()` clears the
2704
+ * in-flight map (entries are short-lived by construction).
2705
+ */
2706
+ declare function coalescingEventStore<S extends {
2707
+ getEventsByTimeRange(start: number, end: number): Promise<unknown>;
2708
+ }>(inner: S): S & {
2709
+ invalidateInFlight(): void;
2710
+ };
2711
+
2346
2712
  /**
2347
2713
  * Auto-generated build version metadata.
2348
2714
  * Do not edit directly; updated by scripts/stamp-version.ts
2349
2715
  */
2350
- declare const VERSION = "0.51.2196";
2351
- declare const GIT_SHA = "817bc28";
2352
- declare const BUILD_TIME = "2026-11-05T23:36:56.914Z";
2716
+ declare const VERSION = "0.53.2203";
2717
+ declare const GIT_SHA = "522974d";
2718
+ declare const BUILD_TIME = "2026-11-11T22:34:03.328Z";
2353
2719
  declare const SEMVER: {
2354
- readonly version: "0.51.2196";
2355
- readonly gitSha: "817bc28";
2356
- readonly buildTime: "2026-11-05T23:36:56.914Z";
2720
+ readonly version: "0.53.2203";
2721
+ readonly gitSha: "522974d";
2722
+ readonly buildTime: "2026-11-11T22:34:03.328Z";
2357
2723
  };
2358
2724
 
2359
- export { type Aggregator, type AnyParsedQuery, BUILD_TIME, type BlockQueryStore, type BuildScopedDashboardOptions, CONTENT_GROUPING_DIMENSIONS, type CatalogFieldSuggestion, type CatalogValueSuggestion, type ComparisonOp, DASHBOARD_GRID_MAX_COLS, DASHBOARD_WIDGET_TYPES, DEFAULT_DASHBOARD_TITLE, DISCIPLINE_FACTORS, type DashboardDocument, type DashboardMeta, type DashboardParsedSection, type DashboardSectionInput, type DashboardToken, type DashboardWidget, type DashboardWidgetType, type DocumentAssignment, type DocumentDefaults, type DocumentFormula, type DocumentOutput, type DocumentResult, EFFORT_DISCIPLINES, type EffortDiscipline, type EffortQueryStore, type EntityScopeDescriptor, type EntityScopeKind, type EventRowIdentity, type EventStore, type ExecutionContext, type FamilyRunPayload, type FindOptions, type FindPredicate, type FindQueryResult, type FormulaEvaluation, type FormulaEvaluator, GIT_SHA, type IFieldCatalog, type MetricPredicate, type NoteContainer, type NoteQueryStore, type NoteRelationBundle, type OperandValue, type OutputUnitResolution, PLANNED_WIDGET_TYPES, type PageSourceEntry, PageSourceRegistry, type ParsedAggregateQuery, type ParsedDocument, type ParsedFindQuery, type ParsedPipelineQuery, type ParsedRowsQuery, type ParsedWqlRollupSuffix, type ParsedWqlSuffixes, type ParsedWqlWindowSuffix, type PipelineOptions, type PipelineResult, type PipelineSink, type PipelineSource, type PointwiseInputs, type QueryDocument, QueryDocumentRunner$1 as QueryDocumentRunner, type QueryDocumentRunnerHost, type QueryDocumentRunnerOptions, type QueryOptions, type QueryResult, QueryService, type QueryServiceStores, type QueryWidgetSuffix, type QueryWindow, type ResolveEntityScopeInput, type ResolvedRange, type RowsPipes, type RowsQueryResult, type RowsRun, SEMVER, SOURCE_ID_SHAPES, type Series, type SeriesPoint, QueryDocumentRunner as SharedQueryDocumentRunner, type SharedRunnerOptions, type SummaryFactIdentity, type SummaryFactSourceOutput, type TabularColumn, type TabularGroup, type TabularResult, type TagFilter, type TagValue, UNASSIGNED, type UnitBearingFact, type UnitFamily, VERSION, WQL_AGGREGATORS, WQL_CALC_TARGETS, WQL_CHART_HEADS, WQL_COMPARISON_OPS, WQL_CONTENT_FILTER_KEYS, WQL_CONTENT_ONLY_KEYS, WQL_DISPLAY_UNITS, WQL_EFFORT_FILTER_KEYS, WQL_FIND_TARGETS, WQL_FUNCTION_HEADS, WQL_GRAINS, WQL_INTENSITY_TIERS, WQL_KEYWORDS, WQL_METRIC_AGGREGATES, WQL_METRIC_FAMILIES, WQL_NOTE_DEFAULT_SOURCES, WQL_NOTE_HEAD_ALIASES, WQL_RESULT_PLANES, WQL_ROLLUP_PERIODS, WQL_SOURCES, WQL_SOURCE_HEADS, WQL_SOURCE_HEAD_SCOPES, WQL_SOURCE_VALUES, WQL_STANDARD_DATASETS, WQL_TAG_KEYS, WQL_TYPED_TAG_KEYS, WQL_TYPE_HEADS, WQL_VIRTUAL_DIMS, type WidgetOpResult, type WidgetSpan, type WidgetSpec, type WqlAggregator, type WqlCalcTarget, type WqlChartHead, type WqlComparisonOp, type WqlCompletionOptions, type WqlContentFilterKey, type WqlDisplayUnit, type WqlDomainOrder, type WqlDomainPredicate, type WqlDomainReadResult, type WqlFindTarget, type WqlFunctionHead, type WqlGrain, type WqlIntensityTier, type WqlKeyword, type WqlMetricAggregate, type WqlMetricFamily, type WqlResultPlane, type WqlRollupPeriod, type WqlSource, type WqlSourceHead, type WqlSourceValue, type WqlStandardDataset, type WqlTagKey, type WqlTypedTagKey, type WqlVirtualDim, allowedFilterTypesForTarget, appendSuffixes, appendWidget, buildDashboardDocument, buildDashboardFromScope, buildDashboardScaffold, buildDrillDownQuery, buildWidgetsForWqlScope, captureContext, chunkIdOfItem, civilDateAdd, civilDateDiff, civilDateOf, civilDatesCoveredByRange, civilMonday, consumesRollupFacts, convertDisplay, createBuiltinFormulaEvaluator, dashboardSlug, defaultTokenValues, disciplineFactorFor, duplicateWidget, eventsToStoredLogs, extractDashboardTokens, extractNoteWqlOverride, feedIdOfItem, feedOfItem, findTargetAdvisories, getUnitFamily, hasLegacyIdentity, inRange, isAggregateQuery, isDashboardMeta, isDashboardWidgetType, isEffortDiscipline, isFindQuery, isItemSubscribed, isPipelineQuery, isProposedMetric, migrateLegacyChunkId, migrateLegacyDashboardBodies, migrateLegacyRouteId, migrateLegacyRow, migrateLegacySourceId, migrateLegacySourcePath, moveWidget, normalizeSummaryFacts, normalizeWql, notebookOfItem, notebookOriginOfItem, notebookSlugOfSourceId, parseDashboardNote, parseDocument, parseQuery, parseQueryWidgetSuffix, parseWqlSuffixes, projectEventToFacts, referencedTokens, removeWidget, renderWidgetGroup, resizeWidget, resolveCanonicalMetricKey, resolveEntityScope, resolveOutputUnit, resolveWidgetType, resolveWindowRange, rowsParseError, serialize, serializeDocument, setDashboardTokenValue, sourceMatches, sourceShape, splitAtWhere, substituteTokens, substituteTokens$1 as substituteTokensRaw, supportsWqlFilterKey, systemTimeZone, toEventRows, toSummaryEventRows, unknownTokensMessage, unknownWidgetTypeMessage, updateWidget, widgetBodyLine, widgetFenceTag, wql, wqlCompletion, wqlCompletionSource, wqlFilterKeys, wqlGroupingDimensions, wqlHighlightStyle, wqlLanguage, parser as wqlParser, wql_parser_terms as wqlTerms, zonedNoon, zonedStartOfDay };
2725
+ export { type Aggregator, AnalyticsInvalidationBus, type AnyParsedQuery, BUILD_TIME, type BlockQueryStore, type BuildScopedDashboardOptions, CONTENT_GROUPING_DIMENSIONS, type CacheKeyContext, type CatalogFieldSuggestion, type CatalogValueSuggestion, type ComparisonOp, DASHBOARD_GRID_MAX_COLS, DASHBOARD_WIDGET_TYPES, DEFAULT_DASHBOARD_TITLE, DISCIPLINE_FACTORS, type DashboardDocument, type DashboardMeta, type DashboardParsedSection, type DashboardSectionInput, type DashboardToken, type DashboardWidget, type DashboardWidgetType, type DocumentAssignment, type DocumentDefaults, type DocumentFormula, type DocumentOutput, type DocumentResult, EFFORT_DISCIPLINES, type EffortDiscipline, type EffortQueryStore, type EntityScopeDescriptor, type EntityScopeKind, type EventRowIdentity, type EventStore, type ExecutionContext, type FamilyRunPayload, type FeedCatalogQueryStore, type FindOptions, type FindPredicate, type FindQueryResult, type FormulaEvaluation, type FormulaEvaluator, GIT_SHA, type IFieldCatalog, type MetricPredicate, type NoteContainer, type NoteQueryStore, type NoteRelationBundle, type NotebookResolvableItem, type OperandValue, type OutputUnitResolution, PLANNED_WIDGET_TYPES, type PageSourceEntry, PageSourceRegistry, type ParseQueryBlockOptions, type ParsedAggregateQuery, type ParsedDocument, type ParsedFindQuery, type ParsedPipelineQuery, type ParsedRowsQuery, type ParsedWqlRollupSuffix, type ParsedWqlSuffixes, type ParsedWqlWindowSuffix, type PipelineOptions, type PipelineResult, type PipelineSink, type PipelineSource, type PointwiseInputs, type ProjectEventToFactsFilter, type QueryBlockObject, QueryCache, type QueryDocument, QueryDocumentRunner$1 as QueryDocumentRunner, type QueryDocumentRunnerHost, type QueryDocumentRunnerOptions, type QueryExecutionScope, type QueryOptions, type QueryResult, type QuerySeriesSpec, QueryService, type QueryServiceStores, type QuerySortSpec, type QueryViewKind, type QueryWidgetSuffix, type QueryWindow, type ResolveEntityScopeInput, type ResolveQueryExecutionScopeInput, type ResolvedRange, type RowsPipes, type RowsQueryResult, type RowsRun, SEMVER, SOURCE_ID_SHAPES, type ScalarOrParam, type Series, type SeriesPoint, QueryDocumentRunner as SharedQueryDocumentRunner, type SharedRunnerOptions, type SummaryFactIdentity, type SummaryFactSourceOutput, type TabularColumn, type TabularGroup, type TabularResult, type TagFilter, type TagValue, UNASSIGNED, type UnitBearingFact, type UnitFamily, VERSION, WQL_AGGREGATORS, WQL_CALC_TARGETS, WQL_CHART_HEADS, WQL_COMPARISON_OPS, WQL_CONTENT_FILTER_KEYS, WQL_CONTENT_ONLY_KEYS, WQL_DISPLAY_UNITS, WQL_EFFORT_FILTER_KEYS, WQL_FIND_TARGETS, WQL_FUNCTION_HEADS, WQL_GRAINS, WQL_INTENSITY_TIERS, WQL_KEYWORDS, WQL_METRIC_AGGREGATES, WQL_METRIC_FAMILIES, WQL_NOTE_DEFAULT_SOURCES, WQL_NOTE_HEAD_ALIASES, WQL_RESULT_PLANES, WQL_ROLLUP_PERIODS, WQL_SOURCES, WQL_SOURCE_HEADS, WQL_SOURCE_HEAD_SCOPES, WQL_SOURCE_VALUES, WQL_STANDARD_DATASETS, WQL_TAG_KEYS, WQL_TYPED_TAG_KEYS, WQL_TYPE_HEADS, WQL_VIRTUAL_DIMS, type WidgetOpResult, type WidgetSpan, type WidgetSpec, type WqlAggregator, type WqlCalcTarget, type WqlChartHead, type WqlComparisonOp, type WqlCompletionOptions, type WqlContentFilterKey, type WqlCursorStageInfo, type WqlCursorStageRole, type WqlDisplayUnit, type WqlDomainOrder, type WqlDomainPredicate, type WqlDomainReadResult, type WqlFindTarget, type WqlFunctionHead, type WqlGrain, type WqlIntensityTier, type WqlKeyword, type WqlMetricAggregate, type WqlMetricFamily, type WqlResultPlane, type WqlRollupPeriod, type WqlSource, type WqlSourceHead, type WqlSourceValue, type WqlStandardDataset, type WqlTagKey, type WqlTypedTagKey, type WqlVirtualDim, allowedFilterTypesForTarget, appendSuffixes, appendWidget, bindQueryParams, buildDashboardDocument, buildDashboardFromScope, buildDashboardScaffold, buildDrillDownQuery, buildWidgetsForWqlScope, captureContext, chunkIdOfItem, civilDateAdd, civilDateDiff, civilDateOf, civilDatesCoveredByRange, civilMonday, coalescingEventStore, collectQueryBlockParams, collectQueryParams, computeCacheKey, consumesRollupFacts, convertDisplay, createBuiltinFormulaEvaluator, dashboardSlug, defaultTokenValues, disciplineFactorFor, duplicateWidget, eventsToStoredLogs, extractDashboardTokens, extractNoteWqlOverride, feedIdOfItem, feedOfItem, findTargetAdvisories, getUnitFamily, hasLegacyIdentity, inRange, isAggregateQuery, isDashboardMeta, isDashboardWidgetType, isDefaultShorthandQueryBlock, isEffortDiscipline, isFindQuery, isItemSubscribed, isPipelineQuery, isProposedMetric, isYamlQueryBlockBody, matchesFactMetricKey, migrateLegacyChunkId, migrateLegacyDashboardBodies, migrateLegacyRouteId, migrateLegacyRow, migrateLegacySourceId, migrateLegacySourcePath, moveWidget, normalizeSummaryFacts, normalizeWql, notebookOfItem, notebookOriginOfItem, notebookSlugOfSourceId, notebooksOfItem, parseDashboardNote, parseDocument, parseFilterFragment, parseQuery, parseQueryBlock, parseQueryWidgetSuffix, parseWqlSuffixes, projectEventToFacts, queryBlockAttributes, queryBlockToDocumentText, referencedTokens, removeWidget, renderWidgetGroup, resizeWidget, resolveCanonicalMetricKey, resolveEntityScope, resolveOutputUnit, resolveQueryExecutionScope, resolveWidgetType, resolveWindowRange, resolveWqlCursorStage, rowsParseError, serialize, serializeDocument, serializeQueryBlock, serializeQueryBlockFence, setDashboardTokenValue, sourceMatches, sourceShape, splitAtWhere, substituteTokens, substituteTokens$1 as substituteTokensRaw, supportsWqlFilterKey, systemTimeZone, toEventRows, toSummaryEventRows, unknownTokensMessage, unknownWidgetTypeMessage, updateWidget, widgetBodyLine, widgetFenceTag, widgetSpecToQueryObject, wql, wqlCompletion, wqlCompletionSource, wqlFilterKeys, wqlGroupingDimensions, wqlHighlightStyle, wqlLanguage, parser as wqlParser, wql_parser_terms as wqlTerms, zonedNoon, zonedStartOfDay };