react-semaphor 0.1.544 → 0.1.546

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.
Files changed (179) hide show
  1. package/dist/analytics-protocol/index.js +405 -441
  2. package/dist/assistant-context/index.js +1 -1
  3. package/dist/assistant-protocol/index.js +100 -76
  4. package/dist/brand-studio/index.js +5 -5
  5. package/dist/briefings/index.js +55 -52
  6. package/dist/chunks/{class-utils-Df1OVOT1.js → _commonjsHelpers-DimLPMtv.js} +124 -98
  7. package/dist/chunks/{add-to-dashboard-BuAqfA2Y.js → add-to-dashboard-BQRAAnc3.js} +55 -33
  8. package/dist/chunks/{analytics-base-schemas-BFAoRlkU.js → analytics-base-schemas-BKs3flFS.js} +2 -2
  9. package/dist/chunks/{assistant-chat-BNLkCDml.js → assistant-chat-BPXhulAx.js} +2792 -2562
  10. package/dist/chunks/{bookmark-state-CXw7lZ50.js → bookmark-state-C4vetoa0.js} +7 -8
  11. package/dist/chunks/column-catalog-BYnochWQ.js +3363 -0
  12. package/dist/chunks/comparison-window-caption-C2xF-eWw.js +1433 -0
  13. package/dist/chunks/{context-ClREvqCZ.js → context-BerEBuFR.js} +11 -6
  14. package/dist/chunks/custom-visual-inputs-CkJW9pBS.js +295 -0
  15. package/dist/chunks/{dashboard-g5a4DKWq.js → dashboard-C3CoKbGY.js} +1 -1
  16. package/dist/chunks/dashboard-briefing-launcher-Be4h-7My.js +3734 -0
  17. package/dist/chunks/dashboard-controls-bxPrlSyp.js +2307 -0
  18. package/dist/chunks/{dashboard-json-7qT9jmfL.js → dashboard-json-BrjxIiRt.js} +6 -6
  19. package/dist/chunks/document-dashboard-inputs-CRVHpIHp.js +3010 -0
  20. package/dist/chunks/{edit-dashboard-visual-BfJwnRIZ.js → edit-dashboard-visual-DYYYDjY6.js} +5986 -6063
  21. package/dist/chunks/{filter-value-text-CYsVYPuD.js → filter-value-text-Ddf55Ku1.js} +8 -8
  22. package/dist/chunks/global-date-filter-utils-9d6m9-FE.js +11859 -0
  23. package/dist/chunks/index-CtoK1Lgu.js +586 -0
  24. package/dist/chunks/{index-DkAyQvC6.js → index-DkQkMKa1.js} +385 -339
  25. package/dist/chunks/list-filter-DsaTbM3J.js +15 -0
  26. package/dist/chunks/matrix-analytical-definition-B9vW-osb.js +717 -0
  27. package/dist/chunks/{matrix-card-DjwWcCo8.js → matrix-card-LiMEipvq.js} +3 -3
  28. package/dist/chunks/{matrix-formatter-CxJLkztA.js → matrix-formatter-DWEeC0_c.js} +55 -55
  29. package/dist/chunks/{matrix-member-presentation-CQGdVks6.js → matrix-member-presentation-DqzG-UhQ.js} +1 -1
  30. package/dist/chunks/{matrix-operation-contract-8OIO4gob.js → matrix-operation-contract-D6vYkZK4.js} +72 -72
  31. package/dist/chunks/{metric-comparison-DEwi9uc2.js → metric-comparison-zpGw4lD6.js} +2 -2
  32. package/dist/chunks/normalize-dashboard-for-dirty-check-XKgH3GFX.js +119 -0
  33. package/dist/chunks/{pivot-header-presentation-DHcx1XGQ.js → pivot-header-presentation-CQnIDtUv.js} +1 -1
  34. package/dist/chunks/{pivot-result-identity-DJhXXcns.js → pivot-result-identity-C-Q1j1Wb.js} +1 -1
  35. package/dist/chunks/{pivot-result-lifecycle-DM4CyGKs.js → pivot-result-lifecycle-pwq3b7LC.js} +571 -380
  36. package/dist/chunks/{raw-temporal-contract-C51YG48G.js → raw-temporal-contract-WuXA8jBP.js} +1 -1
  37. package/dist/chunks/{raw-temporal-presentation-CLiVi90c.js → raw-temporal-presentation-CBzrDOjM.js} +8 -8
  38. package/dist/chunks/rendered-file-D8xEuVVx.js +108 -0
  39. package/dist/chunks/{report-preferences-dialog-Df7VpRVW.js → report-preferences-dialog-4QEZWe5U.js} +637 -610
  40. package/dist/chunks/{report-runtime-context-Dq8XyODK.js → report-runtime-context-hWiTCzFV.js} +2 -2
  41. package/dist/chunks/resolve-dashboard-input-context-UpK_LBpL.js +5677 -0
  42. package/dist/chunks/{saved-dashboard-context-B-mQ--nV.js → saved-dashboard-context-D_I3Lxk0.js} +184 -212
  43. package/dist/chunks/selection-filter-compiler-BKXmyLrS.js +79 -0
  44. package/dist/chunks/{selection-reducer-Dj_8xD69.js → selection-reducer-CJzkTZio.js} +15 -15
  45. package/dist/chunks/{semaphor-ready-indicator-DDAxk8us.js → semaphor-ready-indicator-4zpRHE-X.js} +56832 -59068
  46. package/dist/chunks/{shelf-drop-preview-context-BSRPwaED.js → shelf-drop-preview-context-Cfw7TRAx.js} +890 -871
  47. package/dist/chunks/{source-entity-resolution-BYn9giz3.js → source-entity-resolution-BIGRvtbG.js} +13 -13
  48. package/dist/chunks/{switch-C3jLxlG0.js → switch-CEBOR4n7.js} +47 -48
  49. package/dist/chunks/{table-export-sheet-CPfGAQ9X.js → table-export-sheet-4X9mAG3V.js} +1 -1
  50. package/dist/chunks/table-settings-CunhoDUi.js +605 -0
  51. package/dist/chunks/{temporal-bucket-D7NBrrtL.js → temporal-bucket-CQOSbv9-.js} +26 -26
  52. package/dist/chunks/{token-types-DBbZVQsm.js → token-types-BMqRmT-C.js} +1 -1
  53. package/dist/chunks/{use-create-flow-overlay-state-BxzFviM-.js → use-create-flow-overlay-state-DZBZiiD-.js} +83 -83
  54. package/dist/chunks/{validators-DMHTpf7a.js → validators-C-aOQlTB.js} +713 -658
  55. package/dist/dashboard/index.js +2 -2
  56. package/dist/dashboard-authoring/index.js +1800 -1135
  57. package/dist/data-app-sdk/index.js +6 -6
  58. package/dist/data-app-sdk-adapters/index.js +3 -3
  59. package/dist/data-app-sdk-validation/index.js +14 -14
  60. package/dist/format-utils/index.js +198 -187
  61. package/dist/index.js +359 -325
  62. package/dist/layouts/index.js +5 -242
  63. package/dist/report-runtime-context/index.js +2 -2
  64. package/dist/shared/index.js +4 -5
  65. package/dist/style.css +1 -1
  66. package/dist/surfboard/index.js +2 -2
  67. package/dist/types/briefings/attachment-outcomes.d.ts +1 -1
  68. package/dist/types/briefings/attachments.d.ts +33 -6
  69. package/dist/types/briefings/index.d.ts +6 -5
  70. package/dist/types/components/index.d.ts +2 -0
  71. package/dist/types/components/surfboard/arrange-layout-button.d.ts +8 -0
  72. package/dist/types/components/surfboard/filter/types.d.ts +0 -14
  73. package/dist/types/components/surfboard/screen-size-preview-button.d.ts +7 -0
  74. package/dist/types/index.js +6 -6
  75. package/dist/types/lib/charts/table-chart-types.d.ts +4 -0
  76. package/dist/types/lib/charts/types.d.ts +2 -2
  77. package/dist/types/lib/dashboard-inputs/dashboard-filter-mapping-authoring.d.ts +68 -82
  78. package/dist/types/lib/dashboard-inputs/dashboard-input-target-context.d.ts +0 -8
  79. package/dist/types/lib/dashboard-inputs/dashboard-input-values.d.ts +41 -1
  80. package/dist/types/lib/dashboard-inputs/filter-settings.d.ts +201 -0
  81. package/dist/types/lib/dashboard-inputs/prepare-loaded-dashboard.d.ts +15 -0
  82. package/dist/types/lib/dashboard-inputs/resolve-dashboard-input-context.d.ts +7 -2
  83. package/dist/types/lib/dashboard-inputs/resolve-selection-input.d.ts +1 -1
  84. package/dist/types/lib/dashboard-viewer/captured-runtime-values.d.ts +40 -0
  85. package/dist/types/lib/dashboard-viewer/compatibility-input-storage.d.ts +16 -16
  86. package/dist/types/lib/dashboard-viewer/viewer-state.d.ts +11 -9
  87. package/dist/types/lib/download-pdf.d.ts +75 -1
  88. package/dist/types/lib/hooks/use-date-filter.d.ts +5 -0
  89. package/dist/types/lib/hooks/use-text-filter.d.ts +5 -0
  90. package/dist/types/lib/matrix-table/matrix-delivery-policy.d.ts +5 -4
  91. package/dist/types/lib/matrix-table/matrix-editor.d.ts +52 -0
  92. package/dist/types/lib/query-context/assemble-card-query.d.ts +158 -0
  93. package/dist/types/lib/query-context/build-card-query-context.d.ts +3 -3
  94. package/dist/types/lib/query-context/build-dashboard-card-query-contract.d.ts +15 -6
  95. package/dist/types/lib/query-context/build-dashboard-execution-snapshot.d.ts +11 -13
  96. package/dist/types/lib/query-context/compile-dashboard-card-filters.d.ts +22 -12
  97. package/dist/types/lib/query-context/dashboard-filter-mapping-resolution.d.ts +69 -0
  98. package/dist/types/lib/stores/dashboard-store.d.ts +159 -56
  99. package/dist/types/lib/stores/editor-store.d.ts +0 -3
  100. package/dist/types/lib/types/common-types.d.ts +29 -6
  101. package/dist/types/lib/types/explorer-types.d.ts +10 -0
  102. package/dist/types/lib/types/semantic-types.d.ts +84 -0
  103. package/dist/types/lib/utils/build-saved-editor-card.d.ts +20 -0
  104. package/dist/types/lib/utils/card-type-change.d.ts +16 -0
  105. package/dist/types/lib/utils/field-availability-context.d.ts +25 -0
  106. package/dist/types/lib/utils/field-placement.d.ts +96 -0
  107. package/dist/types/lib/utils/field-state-calculator.d.ts +161 -0
  108. package/dist/types/lib/utils/qualified-entity-name.d.ts +2 -0
  109. package/dist/types/shared/analytics-protocol/field-provenance.d.ts +89 -0
  110. package/dist/types/shared/analytics-protocol/index.d.ts +2 -0
  111. package/dist/types/shared/analytics-protocol/query-policies.d.ts +52 -0
  112. package/dist/types/shared/analytics-protocol/time-window-schema.d.ts +1 -1
  113. package/dist/types/shared/analytics-protocol/time-window.d.ts +40 -1
  114. package/dist/types/shared/assistant-context/saved-dashboard-context.d.ts +8 -12
  115. package/dist/types/shared/assistant-protocol/answer-text.d.ts +20 -0
  116. package/dist/types/shared/assistant-protocol/context.d.ts +21 -21
  117. package/dist/types/shared/assistant-protocol/index.d.ts +1 -0
  118. package/dist/types/shared/assistant-protocol/limits.d.ts +6 -1
  119. package/dist/types/shared/assistant-protocol/parts.d.ts +43 -3
  120. package/dist/types/shared/assistant-protocol/request.d.ts +14 -2
  121. package/dist/types/shared/dashboard-authoring/calculated-field-identity.d.ts +3 -0
  122. package/dist/types/shared/dashboard-authoring/changes/card-query-part.d.ts +487 -0
  123. package/dist/types/shared/dashboard-authoring/changes/card-types.d.ts +34 -0
  124. package/dist/types/shared/dashboard-authoring/changes/dashboard-change.d.ts +7886 -0
  125. package/dist/types/shared/dashboard-authoring/changes/diagnostics.d.ts +43 -0
  126. package/dist/types/shared/dashboard-authoring/changes/read-card-query.d.ts +54 -0
  127. package/dist/types/shared/dashboard-authoring/changes/resolve-dashboard-changes.d.ts +89 -0
  128. package/dist/types/shared/dashboard-authoring/column-catalog.d.ts +32 -0
  129. package/dist/types/shared/dashboard-authoring/contracts.d.ts +0 -55
  130. package/dist/types/shared/dashboard-authoring/control-execution-contract.d.ts +16 -6
  131. package/dist/types/shared/dashboard-authoring/dashboard-card-source-index.d.ts +9 -1
  132. package/dist/types/shared/dashboard-authoring/dashboard-filter-mapping-contract.d.ts +7 -0
  133. package/dist/types/shared/dashboard-authoring/dashboard-input-scope.d.ts +118 -0
  134. package/dist/types/shared/dashboard-authoring/filter-applicability.d.ts +75 -0
  135. package/dist/types/shared/dashboard-authoring/filter-model/ad-hoc-filter-values.d.ts +10 -0
  136. package/dist/types/shared/dashboard-authoring/filter-model/filter-definitions.d.ts +29 -0
  137. package/dist/types/shared/dashboard-authoring/filter-model/filter-values.d.ts +58 -0
  138. package/dist/types/shared/dashboard-authoring/filter-model/index.d.ts +7 -0
  139. package/dist/types/shared/dashboard-authoring/filter-model/prototype-document-inputs.d.ts +15 -0
  140. package/dist/types/shared/dashboard-authoring/filter-model/read-dashboard-filter-model.d.ts +78 -0
  141. package/dist/types/shared/dashboard-authoring/filter-model/stored-dashboard.d.ts +18 -0
  142. package/dist/types/shared/dashboard-authoring/filter-model/toolbar-filter-reach.d.ts +23 -0
  143. package/dist/types/shared/dashboard-authoring/index.d.ts +20 -2
  144. package/dist/types/shared/dashboard-authoring/operations/apply-dashboard-operations.d.ts +10 -37
  145. package/dist/types/shared/dashboard-authoring/operations/operation-types.d.ts +189 -0
  146. package/dist/types/shared/dashboard-authoring/outline/outline-dashboard.d.ts +94 -0
  147. package/dist/types/shared/dashboard-authoring/outline/outline-filters.d.ts +78 -0
  148. package/dist/types/shared/dashboard-authoring/validators.d.ts +1 -2
  149. package/dist/types/shared/format-utils/exporters/index.d.ts +2 -0
  150. package/dist/types/shared/format-utils/exporters/rendered-file.d.ts +106 -0
  151. package/dist/types/shared/layouts/engine/grid.d.ts +25 -0
  152. package/dist/types/shared/layouts/engine/index.d.ts +4 -0
  153. package/dist/types/shared/layouts/engine/sheet-layout.d.ts +7 -0
  154. package/dist/types/shared/layouts/engine/types.d.ts +125 -0
  155. package/dist/types/shared/layouts/index.d.ts +1 -2
  156. package/package.json +2 -2
  157. package/dist/chunks/_commonjsHelpers-BkfeUUK-.js +0 -28
  158. package/dist/chunks/apply-dashboard-operations-Bz4n1Lq6.js +0 -2260
  159. package/dist/chunks/calendar-day-equality-BmJAWduY.js +0 -460
  160. package/dist/chunks/comparison-window-caption-BTkrN3W4.js +0 -1623
  161. package/dist/chunks/custom-visual-inputs-DUtpYZOk.js +0 -323
  162. package/dist/chunks/dashboard-briefing-launcher-DQ_8O_e2.js +0 -3725
  163. package/dist/chunks/dashboard-controls-8RyBTQUO.js +0 -2315
  164. package/dist/chunks/dashboard-filter-value-compatibility-CwQ_iSNb.js +0 -108
  165. package/dist/chunks/document-dashboard-inputs-BC6p-ESg.js +0 -8087
  166. package/dist/chunks/document-sheet-utils-Duo9uLoH.js +0 -3619
  167. package/dist/chunks/matrix-analytical-definition-C7Gb0e12.js +0 -117
  168. package/dist/chunks/normalize-dashboard-for-dirty-check-Bk3VYv_q.js +0 -67
  169. package/dist/chunks/numeric-presentation-DESvLiu9.js +0 -5227
  170. package/dist/chunks/sort-target-MT1WK1vX.js +0 -29
  171. package/dist/chunks/stable-serialize-CfqXeiBP.js +0 -6
  172. package/dist/chunks/table-settings-CLZocegs.js +0 -501
  173. package/dist/chunks/use-debounced-dirty-check-BwAbnX_5.js +0 -59
  174. package/dist/types/lib/dashboard-inputs/dashboard-filter-mapping-storage-transition.d.ts +0 -88
  175. package/dist/types/lib/dashboard-inputs/dashboard-input-scope.d.ts +0 -10
  176. package/dist/types/shared/dashboard-authoring/change-compiler.d.ts +0 -7
  177. package/dist/types/shared/dashboard-authoring/layout-compiler.d.ts +0 -2
  178. package/dist/types/shared/layouts/create-frame-layouts.d.ts +0 -27
  179. package/dist/types/shared/layouts/frame-layouts.d.ts +0 -23
@@ -0,0 +1,96 @@
1
+ import { TCard, TCardPreferences } from '../types/common-types.js';
2
+ import { CardConfig, ContainerId, Field } from '../types/explorer-types.js';
3
+ import { MatrixCardCatalog } from '../matrix-table/matrix-card-adapter.js';
4
+ import { MatrixEditorChange } from '../matrix-table/matrix-editor.js';
5
+ import { FieldAvailabilityContext } from './field-availability-context.js';
6
+ import { FieldStateResult } from './field-state-calculator.js';
7
+ /**
8
+ * Field placement: the one rule for putting a field on a shelf.
9
+ *
10
+ * Every entry point (drop, move, reorder, click) and the drag preview call
11
+ * `evaluateFieldPlacement`; only `placeField` in `useFieldManagement` commits
12
+ * its outcome. The rules restate today's drag behavior per placement kind; see
13
+ * docs/implementation-plans/shelf-drop-placement/PLAN.md, "Placement rules".
14
+ *
15
+ * Evaluation is side-effect-free during the call: no id minting, store access,
16
+ * notifications, clock or random reads. New ids arrive in the context.
17
+ */
18
+ export type ShelfZone = Exclude<ContainerId, 'source'>;
19
+ export declare const SHELF_ZONES: readonly ShelfZone[];
20
+ export type FieldPlacement = {
21
+ /** The field-list field, or the pill being moved. */
22
+ field: Field;
23
+ /** 'source' is the field list. */
24
+ from: ContainerId;
25
+ to: ShelfZone;
26
+ /** Pill to insert in front of; absent means the end. */
27
+ beforeId?: string;
28
+ };
29
+ export type FieldPlacementKind = 'add' | 'move' | 'copy-to-sort' | 'reorder';
30
+ export type FieldPlacementNotice = {
31
+ kind: 'join-required';
32
+ fieldState?: FieldStateResult;
33
+ } | {
34
+ kind: 'invalid-field-type';
35
+ reason: string;
36
+ } | {
37
+ kind: 'already-on-shelf';
38
+ zone: ShelfZone;
39
+ } | {
40
+ kind: 'sort-needs-shelf-field';
41
+ } | {
42
+ kind: 'cannot-sort-from-pivot';
43
+ } | {
44
+ kind: 'matrix-refused';
45
+ message: string;
46
+ };
47
+ export type FieldPlacementCommit = {
48
+ cardKind: 'standard';
49
+ config: CardConfig;
50
+ /** null leaves the card's preferences untouched. */
51
+ preferences: TCardPreferences | null;
52
+ } | {
53
+ cardKind: 'matrix';
54
+ change: MatrixEditorChange;
55
+ };
56
+ export type FieldPlacementOutcome = {
57
+ kind: 'placed';
58
+ commit: FieldPlacementCommit;
59
+ }
60
+ /** A standard reorder onto its own slot. */
61
+ | {
62
+ kind: 'unchanged';
63
+ } | {
64
+ kind: 'refused';
65
+ notice: FieldPlacementNotice;
66
+ };
67
+ export type FieldPlacementContext = {
68
+ availability: FieldAvailabilityContext;
69
+ /** Ignored for standard cards. */
70
+ matrixCatalog: MatrixCardCatalog;
71
+ /** A string exactly when `needsNewFieldId` is true. */
72
+ newFieldId: string | null;
73
+ };
74
+ /** Reserved id for standard-card previews. Never matches a minted id and never reaches the store. */
75
+ export declare const PLACEMENT_PREVIEW_FIELD_ID = "__placement-preview__";
76
+ /**
77
+ * Reserved id for Matrix previews. The Matrix spec validates instance ids as
78
+ * UUIDs, so the preview needs one; minted ids are random v4 UUIDs and never
79
+ * equal this fixed value. Never reaches the store.
80
+ */
81
+ export declare const MATRIX_PLACEMENT_PREVIEW_ID = "00000000-0000-4000-8000-000000000000";
82
+ /** The preview id for a card type. */
83
+ export declare function placementPreviewId(cardType: TCard['type'] | undefined): string;
84
+ export declare function classifyFieldPlacement(placement: Pick<FieldPlacement, 'from' | 'to'>): FieldPlacementKind;
85
+ /** Standard cards: every kind except reorder. Matrix: only from the field list. */
86
+ export declare function needsNewFieldId(cardType: TCard['type'] | undefined, placement: Pick<FieldPlacement, 'from' | 'to'>): boolean;
87
+ /**
88
+ * A standard card's shelf as the editor shows it: stored fields with their
89
+ * shelf identity resolved and a label defaulted from the name.
90
+ */
91
+ export declare function readStandardShelf(config: CardConfig | undefined, zone: ContainerId): Field[];
92
+ export declare function evaluateStandardPlacement(card: TCard, placement: FieldPlacement, context: FieldPlacementContext): FieldPlacementOutcome;
93
+ /** The one evaluation. Dispatches on card type. Side-effect-free. */
94
+ export declare function evaluateFieldPlacement(card: TCard, placement: FieldPlacement, context: FieldPlacementContext): FieldPlacementOutcome;
95
+ /** Preview text for the shelf header while a field hovers it. */
96
+ export declare function placementNoticeReason(notice: FieldPlacementNotice, shelfLabel: string): string;
@@ -0,0 +1,161 @@
1
+ import { Field, JoinPlan } from '../types/explorer-types.js';
2
+ import { JoinabilityMap } from '../types/semantic-types.js';
3
+ import { AutoJoinMetadata } from '../types/query-types.js';
4
+ import { resolveFieldDatasetDependencies, FieldDatasetDependency } from './field-dependencies.js';
5
+ import { getQualifiedEntityName } from './qualified-entity-name.js';
6
+ export interface DatasetIdentityAlias {
7
+ name: string;
8
+ table?: string | null;
9
+ catalog?: string | null;
10
+ schema?: string | null;
11
+ }
12
+ /**
13
+ * Field draggability states for the query builder
14
+ *
15
+ * - **base**: Field is from the base dataset (first dataset selected)
16
+ * - **draggable**: Field has a direct relationship to base dataset (1-hop)
17
+ * - **indirect**: Field requires a multi-hop join (2-hop via intermediate dataset)
18
+ * - **setup**: A relationship exists but the engine will not use it on its
19
+ * own (not set to auto-join). The user can fix this; until then the field
20
+ * is blocked exactly like `unreachable`.
21
+ * - **unreachable**: No relationship path exists to this field's dataset
22
+ *
23
+ * Calculated fields take the worst state among the datasets they read from.
24
+ */
25
+ export type FieldDraggableState = 'base' | 'draggable' | 'indirect' | 'setup' | 'unreachable'
26
+ /**
27
+ * Nothing is on the shelves and the dataset is not one of the chart's
28
+ * data-source datasets. Not a fault to fix: the customer chose their
29
+ * datasets and this field reads another one. Blocked, with the path to
30
+ * using it (add the dataset) offered as information.
31
+ */
32
+ | 'absent';
33
+ /** Per-dataset availability, attached to calculated-field results. */
34
+ export interface FieldDependencyState {
35
+ /** Catalog dataset name. */
36
+ entityName: string;
37
+ /** Customer-facing dataset label. */
38
+ label: string;
39
+ state: FieldDraggableState;
40
+ /** Customer-facing sentence when the dataset is not simply available. */
41
+ reason?: string;
42
+ }
43
+ /**
44
+ * Result of field state calculation
45
+ */
46
+ export interface FieldStateResult {
47
+ /** The calculated draggability state */
48
+ state: FieldDraggableState;
49
+ /** For indirect joins: the path through intermediate datasets */
50
+ joinPath?: string[];
51
+ /** `joinPath` as readers see it: dataset labels, in path order. */
52
+ joinPathLabels?: string[];
53
+ /** Short tooltip text explaining the state (row `title`). */
54
+ tooltip?: string;
55
+ /**
56
+ * Customer-facing explanation when the field cannot be added as-is.
57
+ * Precise: names the dataset and the actual problem.
58
+ */
59
+ reason?: string;
60
+ /** The one thing the user can do about `reason`, when there is one. */
61
+ action?: string;
62
+ /**
63
+ * Dataset labels that `reason` mentions, so the UI can set them off from
64
+ * the surrounding sentence (a chip) without parsing the text.
65
+ */
66
+ mentions?: string[];
67
+ /**
68
+ * Non-blocking caution from governed catalog metadata, for example a
69
+ * one-to-many join that can repeat an aggregate. Shown in the preview.
70
+ */
71
+ warning?: string;
72
+ /**
73
+ * Datasets a calculated field reads from, each with its own state.
74
+ * Undefined for base fields (their dataset is their group).
75
+ */
76
+ dependencies?: FieldDependencyState[];
77
+ /**
78
+ * False when availability could not be checked (relationship map still
79
+ * loading, or a dependency could not be traced). UI must not present
80
+ * such a field as verified-ready.
81
+ */
82
+ verified?: boolean;
83
+ /** Indicates if this field is already selected/in the query */
84
+ isSelected?: boolean;
85
+ }
86
+ /** States that block adding the field to the query. */
87
+ export declare function isBlockedFieldState(state: FieldDraggableState | undefined): boolean;
88
+ export interface FieldStateContext {
89
+ joinabilityMap: JoinabilityMap | null;
90
+ selectedFields: Field[];
91
+ joinPlan?: JoinPlan;
92
+ autoJoinMetadata?: AutoJoinMetadata;
93
+ baseEntityName?: string;
94
+ datasetAliases?: DatasetIdentityAlias[];
95
+ /**
96
+ * Whether the card reads from a semantic domain. Drives the fallback when
97
+ * `joinabilityMap` is null:
98
+ * - true -> the map is still loading: report `verified: false`.
99
+ * - false -> physical datasets: reachability comes from the join plan.
100
+ * - undefined (legacy callers) -> everything draggable, as before.
101
+ */
102
+ hasSemanticDomain?: boolean;
103
+ /** Customer-facing dataset labels keyed by dataset name. */
104
+ datasetLabels?: Record<string, string>;
105
+ /**
106
+ * The datasets the chart's data source lists (`DataSource.selectedEntities`),
107
+ * in order. When nothing is on the shelves yet, these ARE the chart's
108
+ * datasets: a calculated field's dependencies are judged against them,
109
+ * so the card talks about the dataset the customer actually picked
110
+ * instead of the calculation's own first input.
111
+ */
112
+ dataSourceEntities?: DatasetAnchorRef[];
113
+ }
114
+ /** Minimal entity reference the calculator needs to identify a dataset. */
115
+ export type DatasetAnchorRef = Parameters<typeof getQualifiedEntityName>[0];
116
+ /**
117
+ * Customer-facing words for a state, in one place. The row tag under a
118
+ * dependency and the title of the refusal toast both read from here.
119
+ */
120
+ export declare function getFieldStateCopy(state: FieldDraggableState | undefined): {
121
+ /** Short tag beside a blocking dependency; null when nothing blocks. */
122
+ tag: string | null;
123
+ /** Title of the refusal toast. */
124
+ toastTitle: string;
125
+ };
126
+ /**
127
+ * Calculate the draggability state for a field in the query builder
128
+ *
129
+ * This determines whether a field can be dragged based on:
130
+ * - Current selected fields (what's already in the query)
131
+ * - Joinability map (what relationships exist between datasets)
132
+ * - For calculated fields: the datasets their inputs read from
133
+ *
134
+ * **Fallback behavior**:
135
+ * - No joinability map and no `hasSemanticDomain` flag: all fields draggable
136
+ * (legacy callers, no restrictions)
137
+ * - No fields selected yet: base fields are draggable (first selection
138
+ * establishes the base dataset); calculated fields are judged against the
139
+ * data source's datasets when there are any, else against their own first
140
+ * dataset
141
+ */
142
+ export declare function calculateFieldState(field: Field, context: FieldStateContext): FieldStateResult;
143
+ /** One data-source dataset's connection to the visual's base, for the Datasets panel. */
144
+ export interface DataSourceConnection {
145
+ /** Dataset identity (name in semantic mode, qualified table in physical). */
146
+ entityName: string;
147
+ label: string;
148
+ state: FieldDraggableState;
149
+ reason?: string;
150
+ action?: string;
151
+ mentions?: string[];
152
+ }
153
+ /**
154
+ * How each selected dataset connects to the visual's base dataset, using
155
+ * the same identity, base cascade, and per-dataset evaluation as the field
156
+ * list. The Datasets panel shows this at selection time so the customer
157
+ * learns about an unconnected dataset before the first drag. Order and
158
+ * verdicts match `calculateFieldState` for a field of that dataset.
159
+ */
160
+ export declare function describeDataSourceConnections(context: FieldStateContext): DataSourceConnection[];
161
+ export { resolveFieldDatasetDependencies, type FieldDatasetDependency };
@@ -0,0 +1,2 @@
1
+ import { DatabaseEntityReference } from '../types/explorer-types.js';
2
+ export declare function getQualifiedEntityName(target: Pick<DatabaseEntityReference, 'type' | 'database' | 'schema' | 'name'>): string;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * A column's aggregate and label, written with what they record about where
3
+ * they came from, in one place (MCP dashboard editing, ledger V-18). Every
4
+ * producer writes through here (the editor's aggregate menu and rename, the
5
+ * governed compiler, the MCP's stated labels) and every reader asks here, so
6
+ * the value and its provenance always tell one story. Before, the editor's
7
+ * aggregate menu changed `aggregate` and `aggregateOrigin` but left the
8
+ * compiler's record (`effectiveAggregate`, `aggregateSource`) stale, and the
9
+ * compiler copied a catalog `aggregateOrigin: "default"` onto an aggregate the
10
+ * caller chose.
11
+ */
12
+ export type MetricAggregateSource = 'semantic_model' | 'caller_override' | 'default_sum';
13
+ /** A measure's aggregate and its provenance, as a saved column carries them (structural: any field type fits). */
14
+ export type MetricAggregateProvenance<A extends string = string> = {
15
+ aggregate?: A;
16
+ aggregateOrigin?: 'default' | 'explicit';
17
+ semanticAggregate?: A;
18
+ effectiveAggregate?: A;
19
+ aggregateSource?: MetricAggregateSource;
20
+ /** The field's type, which decides the default aggregate (`defaultMetricAggregate`). */
21
+ dataType?: string;
22
+ };
23
+ /** A column's label and its provenance. */
24
+ export type LabelProvenance = {
25
+ label?: string;
26
+ labelOrigin?: 'semantic' | 'override';
27
+ derivedLabel?: string;
28
+ };
29
+ /**
30
+ * The aggregate a measure gets when nobody chooses one, the one rule the
31
+ * editor (a field dropped on the measures), the governed compiler and every
32
+ * reader share: the semantic model's, else SUM for a number (or a type not
33
+ * known) and COUNT for anything else.
34
+ */
35
+ export declare function defaultMetricAggregate<A extends string>(semanticAggregate: A | undefined, dataType?: string): A | 'SUM' | 'COUNT';
36
+ /**
37
+ * The compiler's record of a measure's aggregate: the aggregate it runs, and
38
+ * whether that is the default or an override. Asking for SUM on a SUM measure
39
+ * is not an override (Analytics MCP focus 1.4b).
40
+ */
41
+ export declare function metricAggregateRecord<A extends string>(input: {
42
+ aggregate: A;
43
+ semanticAggregate?: A;
44
+ dataType?: string;
45
+ }): {
46
+ effectiveAggregate: A;
47
+ aggregateSource: MetricAggregateSource;
48
+ };
49
+ /**
50
+ * What to set on a measure for a new aggregate: the aggregate, whether
51
+ * someone chose it (`aggregateOrigin`), and, when the column carries the
52
+ * compiler's record, that record refreshed. A patch, for the editor's column
53
+ * updates; `withMetricAggregate` applies it.
54
+ */
55
+ export declare function metricAggregatePatch<A extends string>(column: Pick<MetricAggregateProvenance<A>, 'semanticAggregate' | 'effectiveAggregate' | 'aggregateSource' | 'dataType'>, aggregate: A, origin: 'default' | 'explicit'): MetricAggregateProvenance<A>;
56
+ /** A measure with a new aggregate and its provenance (`metricAggregatePatch`). */
57
+ export declare function withMetricAggregate<T extends MetricAggregateProvenance>(column: T, aggregate: NonNullable<T['aggregate']>, origin: 'default' | 'explicit'): T;
58
+ /**
59
+ * The aggregate a measure runs: `aggregate`, which the query builder reads;
60
+ * the compiler's record only when it is all the column has. Readers ask here,
61
+ * so a column saved with a stale record is still read as it runs.
62
+ */
63
+ export declare function metricColumnAggregate<A extends string>(column: Pick<MetricAggregateProvenance<A>, 'aggregate' | 'effectiveAggregate'>): A | undefined;
64
+ /**
65
+ * Whether someone chose a measure's aggregate rather than it being the
66
+ * default: the one reading of every stored shape. A column written here says
67
+ * so in `aggregateOrigin`; one saved before carries either the editor's mark,
68
+ * the compiler's record (an override, or a default the aggregate no longer
69
+ * equals because an editor change left the record stale), or neither (read as
70
+ * chosen, so a query states it).
71
+ */
72
+ export declare function isMetricAggregateChosen(column: MetricAggregateProvenance): boolean;
73
+ /** The keys an authored label sets together. */
74
+ export declare const AUTHORED_LABEL_KEYS: readonly string[];
75
+ /**
76
+ * What to set for a label someone wrote: an override, which the editor never
77
+ * refreshes as a generated label, and no `derivedLabel`, so the field display
78
+ * rule reads it as authored even when it repeats the synthesized text. A
79
+ * patch for the editor's column updates (`derivedLabel: undefined` drops it
80
+ * when saved); `withAuthoredLabel` applies it to a column.
81
+ */
82
+ export declare function authoredLabelPatch(label: string): LabelProvenance;
83
+ /** A column with a label someone wrote (`authoredLabelPatch`). */
84
+ export declare function withAuthoredLabel<T extends LabelProvenance>(column: T, label: string): T;
85
+ /**
86
+ * What to set for a generated label (an aggregate's "Average of Sales"): the
87
+ * label as a refreshable semantic hint, unless someone wrote the label.
88
+ */
89
+ export declare function generatedLabelPatch(column: Pick<LabelProvenance, 'labelOrigin'>, label: string): LabelProvenance;
@@ -28,6 +28,8 @@ export * from './relative-date-label.js';
28
28
  export * from './operation-temporal-state.js';
29
29
  export * from './aggregate-expression.js';
30
30
  export * from './measure-aggregation-profile.js';
31
+ export * from './field-provenance.js';
32
+ export * from './query-policies.js';
31
33
  export * from './analytics-refusal.js';
32
34
  export * from './visual-choice.js';
33
35
  /**
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Small pure policies of how a query runs, shared by the governed compiler
3
+ * and the query builder (semaphor-app) and by whatever reads a saved card
4
+ * back (MCP dashboard editing, ledger V-19). Each was written once on the
5
+ * compiling side and again, inverted, on the reading side; a change to one
6
+ * copy would have broken the other silently. Grounding and SQL generation
7
+ * stay app-owned: these are the string and ordering rules only.
8
+ */
9
+ /**
10
+ * The sort a query gets when it states none: the grouped date ascending;
11
+ * else, when something is grouped, the primary measure (the first when none
12
+ * is named) descending; else none.
13
+ */
14
+ export declare function defaultQuerySort<T>(parts: {
15
+ groupedDate?: T;
16
+ measures: readonly T[];
17
+ grouped: boolean;
18
+ primaryMeasure?: T;
19
+ }): {
20
+ target: T;
21
+ direction: 'asc' | 'desc';
22
+ } | undefined;
23
+ /** The saved condition operators that run a LIKE pattern. */
24
+ export type SavedPatternOperator = 'contains' | 'startsWith' | 'endsWith' | 'like' | 'not like';
25
+ export declare const SAVED_PATTERN_OPERATORS: ReadonlySet<string>;
26
+ /** A LIKE wildcard: `%` or `_`. */
27
+ export declare function hasLikeWildcard(value: string): boolean;
28
+ /**
29
+ * The LIKE pattern a saved condition runs (the query builder's rule):
30
+ * `contains` matches anywhere, `startsWith` and `endsWith` at one end, and
31
+ * `like` and `not like` run the value as written.
32
+ */
33
+ export declare function savedConditionPattern(operator: SavedPatternOperator, value: string): {
34
+ pattern: string;
35
+ negate: boolean;
36
+ };
37
+ /**
38
+ * The pattern a public `contains` filter runs (the compiler's rule): the
39
+ * value wrapped in `%...%`, unless it already holds a wildcard.
40
+ */
41
+ export declare function containsFilterPattern(value: string): string;
42
+ /**
43
+ * A saved pattern condition as the public `contains` / `not_contains` filter
44
+ * that runs the same pattern again, or undefined when none does (a pattern
45
+ * without a wildcard matches a value exactly). Checked against
46
+ * `containsFilterPattern` itself, so the reading can never drift from the
47
+ * compiler.
48
+ */
49
+ export declare function statedPatternFilter(operator: SavedPatternOperator, value: string): {
50
+ operator: 'contains' | 'not_contains';
51
+ value: string;
52
+ } | undefined;
@@ -160,7 +160,7 @@ export declare function semaphorTimeWindowSchemas(options?: {
160
160
  start: string;
161
161
  end: string;
162
162
  }>;
163
- timeWindow: z.ZodUnion<[z.ZodEffects<z.ZodObject<{
163
+ timeWindow: z.ZodUnion<readonly [z.ZodEffects<z.ZodObject<{
164
164
  kind: z.ZodOptional<z.ZodLiteral<"relative">>;
165
165
  unit: z.ZodEnum<["second", "minute", "hour", "day", "week", "month", "quarter", "year"]>;
166
166
  value: z.ZodNumber;
@@ -1,4 +1,5 @@
1
- import { SemaphorRelativeTimeWindow, SemaphorTimeGrain } from './contracts.js';
1
+ import { SemaphorCalendarTimeWindow, SemaphorRelativeTimeWindow, SemaphorTimeGrain, SemaphorTimeWindow } from './contracts.js';
2
+ import { RelativeDateFilter } from './relative-date-filter.js';
2
3
  /** Units a calendar window ("this month", "previous quarter") can name. */
3
4
  export declare const SEMAPHOR_CALENDAR_TIME_WINDOW_UNITS: readonly ["day", "week", "month", "quarter", "year"];
4
5
  export declare const SEMAPHOR_CALENDAR_TIME_WINDOW_PERIODS: readonly ["this", "previous"];
@@ -11,3 +12,41 @@ export declare const SEMAPHOR_TIME_WINDOW_MAX_VALUE: Readonly<Record<SemaphorTim
11
12
  * latest available data; a saved card that should keep rolling states "now".
12
13
  */
13
14
  export declare function resolveTimeWindowAnchor(timeWindow: Pick<SemaphorRelativeTimeWindow, 'anchor'>): 'now' | 'latest_available';
15
+ /** A rolling "last N units" window (`kind` "relative" or omitted). */
16
+ export declare function isRelativeTimeWindow(timeWindow: SemaphorTimeWindow | null | undefined): timeWindow is SemaphorRelativeTimeWindow;
17
+ /** A whole calendar period, such as this month or the previous quarter. */
18
+ export declare function isCalendarTimeWindow(timeWindow: SemaphorTimeWindow | null | undefined): timeWindow is SemaphorCalendarTimeWindow;
19
+ /**
20
+ * A window as a dashboard filter's default. Filter defaults run to now (the
21
+ * editor's presets and the filter runtime have no latest-data anchor), so a
22
+ * rolling window without an anchor is anchored at now, and one anchored to
23
+ * the latest available data is not a filter default (null), never quietly
24
+ * moved to now. The one conversion every writer and checker of a filter
25
+ * default uses.
26
+ */
27
+ export declare function timeWindowToFilterDefault(timeWindow: SemaphorTimeWindow): RelativeDateFilter | null;
28
+ /** A rolling week, month, quarter or year that includes the current, partial one: no filter preset holds it. */
29
+ export declare function isPartialRollingPeriod(timeWindow: SemaphorTimeWindow): boolean;
30
+ /**
31
+ * The time window a filter default states, the inverse of
32
+ * `timeWindowToFilterDefault`, so what an agent reads back is what it would
33
+ * write: the last N days with today (`between` days from 1-N to 0), complete
34
+ * periods, this or the previous period; a rolling window saved before is
35
+ * read as rolling. Null for any other stored default, such as `between` on
36
+ * whole weeks or months, which no time window states.
37
+ */
38
+ export declare function filterDefaultToTimeWindow(meta: RelativeDateFilter): SemaphorTimeWindow | null;
39
+ /**
40
+ * The relative date an agent time window persists as (plan D10, amended by
41
+ * analytics kernel K11), or null when it can't stay relative: absolute
42
+ * windows, second units, and complete minute or hour periods. A window
43
+ * anchored to the latest available data (an omitted anchor included) counts
44
+ * back from its own field's data anchor (`relativeTo: 'latest_data'`).
45
+ * `completeness` is the completeness the run used, when it was inferred.
46
+ * Moved from semaphor-app's query-spec-filters so a card's date window and a
47
+ * dashboard filter's default period convert through one owner (MCP dashboard
48
+ * editing, ledger P3-04).
49
+ */
50
+ export declare function timeWindowToRelativeDateFilter(timeWindow: SemaphorTimeWindow, options?: {
51
+ completeness?: 'include_partial' | 'complete_periods';
52
+ }): RelativeDateFilter | null;
@@ -1,10 +1,9 @@
1
- import { DashboardInputExecutionSnapshot, TCard, TDashboard } from '../../lib/types/common-types.js';
2
- import { TFilterValue } from '../../components/surfboard/filter/types.js';
1
+ import { TCard, TDashboard } from '../../lib/types/common-types.js';
3
2
  import { CardViewStateMap } from '../../lib/dashboard-view-state/index.js';
4
3
  import { ControlContractOverrides } from '../../lib/dashboard-inputs/control-contract-overrides.js';
5
4
  import { SemanticExecutionPayload } from '../../lib/types/semantic-runtime-types.js';
6
5
  import { CalendarContext } from '../report-runtime-context/index.js';
7
- import { ViewerStoreInputValues } from '../../lib/dashboard-viewer/compatibility-input-storage.js';
6
+ import { CardRuntimeValues, StoredCaptureValues } from '../../lib/dashboard-viewer/captured-runtime-values.js';
8
7
  import { DashboardCardExecutionSnapshotResult } from '../../lib/query-context/build-dashboard-execution-snapshot.js';
9
8
  import { TransientInputContext } from '../../lib/dashboard-inputs/transient-input-context.js';
10
9
  import { DashboardCardLocation } from '../dashboard-authoring/document-section-cards.js';
@@ -26,10 +25,6 @@ export type SavedDashboardPlace = {
26
25
  /** Drill paths by card. */
27
26
  cardViewState?: CardViewStateMap;
28
27
  };
29
- /** The store's input values plus drill paths: what a card's snapshot is built from. */
30
- export type CardRuntimeValues = ViewerStoreInputValues & {
31
- cardViewState: CardViewStateMap;
32
- };
33
28
  export declare function projectSavedDashboardContext(input: {
34
29
  dashboard: TDashboard;
35
30
  place: SavedDashboardPlace;
@@ -40,7 +35,9 @@ export declare function projectSavedDashboardContext(input: {
40
35
  /**
41
36
  * What a browser opening the saved dashboard at `place` sends with a message:
42
37
  * the context and, for an asked-about card, its replay fields, both from the
43
- * one snapshot (ledger P3-92). The regression set sends exactly this.
38
+ * one snapshot (ledger P3-92), and the dashboard it projected, which a person
39
+ * who may change it sends as `openDashboard` (Phase 7, D7-29). The regression
40
+ * set sends exactly this.
44
41
  */
45
42
  export declare function projectSavedDashboardTurn(input: {
46
43
  dashboard: TDashboard;
@@ -50,6 +47,7 @@ export declare function projectSavedDashboardTurn(input: {
50
47
  }): {
51
48
  context: AssistantContext;
52
49
  cardReplay?: AssistantCardReplayFields;
50
+ openDashboard: TDashboard;
53
51
  };
54
52
  /** The turn request's fields for an asked-about card: its request, or why it has none. */
55
53
  export type AssistantCardReplayFields = {
@@ -115,11 +113,9 @@ export declare function cardReplayOf(input: {
115
113
  * contract, and a saved input snapshot. Every field is optional; none at all
116
114
  * is a fresh viewer (saved defaults).
117
115
  */
118
- export type SavedCardHost = {
119
- filterValues?: readonly TFilterValue[];
120
- controlValues?: Readonly<Record<string, unknown>>;
116
+ /** A scheduled card attachment's saved values, with the host's control contract. */
117
+ export type SavedCardHost = StoredCaptureValues & {
121
118
  controlContract?: ControlContractOverrides;
122
- dashboardInputExecutionSnapshot?: DashboardInputExecutionSnapshot;
123
119
  };
124
120
  /**
125
121
  * A saved card's request as a host opens it: by default a fresh viewer
@@ -0,0 +1,20 @@
1
+ import { AssistantPart } from './parts.js';
2
+ /**
3
+ * Which of an answer's text is the answer (analytics agent Plan 1, P7-23):
4
+ * its last run of text, the text after the last step that more text follows.
5
+ * Text the model wrote before such a step ("Need the domain and fields.") is
6
+ * a working note: the transcript shows it while the assistant works, and not
7
+ * as the answer once more text follows a later step. An answer followed by a
8
+ * last query and nothing after it keeps its text, so no answer that wrote
9
+ * anything comes out empty. A step is a stage that reads data (a query, a
10
+ * lookup); a change to the dashboard, showing a result or asking the person a
11
+ * question is not one, so an answer written before its change stays the
12
+ * answer (P7-45). One rule for the transcript, the turn record and the eval.
13
+ */
14
+ export type AnswerPartKind = 'text' | 'step' | 'other';
15
+ /** The parts that are working notes: text before the last step that comes before the answer's last text. */
16
+ export declare function workingNotesOf<T>(parts: readonly T[], kindOf: (part: T) => AnswerPartKind): ReadonlySet<T>;
17
+ /** A stored part's kind for `workingNotesOf`. */
18
+ export declare function storedPartKind(part: AssistantPart): AnswerPartKind;
19
+ /** A stored answer's text: its text parts after the last step, a paragraph each. */
20
+ export declare function answerTextOf(parts: readonly AssistantPart[]): string;