semiotic 3.6.0 → 3.7.1

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 (122) hide show
  1. package/CLAUDE.md +192 -228
  2. package/README.md +70 -17
  3. package/ai/cli.js +41 -0
  4. package/ai/componentMetadata.cjs +11 -2
  5. package/ai/dist/mcp-server.js +625 -10
  6. package/ai/examples.md +98 -0
  7. package/ai/schema.json +581 -1
  8. package/ai/system-prompt.md +7 -4
  9. package/dist/components/AccessibleNavTree.d.ts +26 -0
  10. package/dist/components/Annotation.d.ts +41 -15
  11. package/dist/components/CategoryColors.d.ts +1 -1
  12. package/dist/components/ChartContainer.d.ts +32 -2
  13. package/dist/components/ChartGrid.d.ts +1 -1
  14. package/dist/components/ContextLayout.d.ts +1 -1
  15. package/dist/components/DataSummaryContext.d.ts +1 -1
  16. package/dist/components/DetailsPanel.d.ts +1 -1
  17. package/dist/components/Legend.d.ts +3 -2
  18. package/dist/components/LinkedCharts.d.ts +1 -1
  19. package/dist/components/ThemeProvider.d.ts +1 -1
  20. package/dist/components/Tooltip/FlippingTooltip.d.ts +1 -1
  21. package/dist/components/Tooltip/Tooltip.d.ts +2 -2
  22. package/dist/components/ai/annotationProvenance.d.ts +349 -0
  23. package/dist/components/ai/audienceProfile.d.ts +60 -3
  24. package/dist/components/ai/chartCapabilityTypes.d.ts +60 -2
  25. package/dist/components/ai/chartRoles.d.ts +27 -0
  26. package/dist/components/ai/conversationArc.d.ts +379 -0
  27. package/dist/components/ai/dataScaleProfile.d.ts +320 -0
  28. package/dist/components/ai/describeChart.d.ts +114 -0
  29. package/dist/components/ai/navigationTree.d.ts +45 -0
  30. package/dist/components/ai/qualityScorecard.d.ts +11 -0
  31. package/dist/components/ai/readerGrounding.d.ts +70 -0
  32. package/dist/components/ai/suggestCharts.d.ts +34 -1
  33. package/dist/components/ai/useConversationArc.d.ts +89 -0
  34. package/dist/components/ai/useNavigationSync.d.ts +61 -0
  35. package/dist/components/ai/variantDiscovery.d.ts +168 -0
  36. package/dist/components/charts/geo/ChoroplethMap.d.ts +2 -1
  37. package/dist/components/charts/network/CirclePack.d.ts +2 -1
  38. package/dist/components/charts/network/OrbitDiagram.d.ts +1 -1
  39. package/dist/components/charts/network/TreeDiagram.d.ts +2 -1
  40. package/dist/components/charts/network/Treemap.d.ts +2 -1
  41. package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +3 -0
  42. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +4 -1
  43. package/dist/components/charts/realtime/RealtimeLineChart.d.ts +3 -0
  44. package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +3 -0
  45. package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +3 -0
  46. package/dist/components/charts/shared/ChartError.d.ts +2 -1
  47. package/dist/components/charts/shared/annotationHierarchy.d.ts +42 -0
  48. package/dist/components/charts/shared/annotationResolvers.d.ts +3 -2
  49. package/dist/components/charts/shared/annotationRules.d.ts +16 -0
  50. package/dist/components/charts/shared/annotationTypes.d.ts +14 -0
  51. package/dist/components/charts/shared/auditAccessibility.d.ts +90 -0
  52. package/dist/components/charts/shared/chartSpecs.d.ts +2 -3
  53. package/dist/components/charts/shared/diagnoseConfig.d.ts +4 -6
  54. package/dist/components/charts/shared/selectionUtils.d.ts +5 -2
  55. package/dist/components/charts/shared/streamPropsHelpers.d.ts +2 -0
  56. package/dist/components/charts/shared/types.d.ts +5 -1
  57. package/dist/components/charts/shared/withChartWrapper.d.ts +1 -1
  58. package/dist/components/charts/value/BigNumber.capability.d.ts +13 -0
  59. package/dist/components/charts/value/BigNumber.d.ts +14 -0
  60. package/dist/components/charts/value/formatting.d.ts +40 -0
  61. package/dist/components/charts/value/thresholdSparkline.d.ts +40 -0
  62. package/dist/components/charts/value/types.d.ts +292 -0
  63. package/dist/components/charts/xy/MinimapChart.d.ts +2 -1
  64. package/dist/components/charts/xy/ScatterplotMatrix.d.ts +2 -1
  65. package/dist/components/realtime/lifecycleBands.d.ts +44 -0
  66. package/dist/components/realtime/types.d.ts +23 -8
  67. package/dist/components/recipes/annotationDensity.d.ts +69 -0
  68. package/dist/components/recipes/annotationLayout.d.ts +93 -0
  69. package/dist/components/semiotic-ai.d.ts +38 -15
  70. package/dist/components/semiotic-realtime.d.ts +2 -0
  71. package/dist/components/semiotic-recipes.d.ts +4 -0
  72. package/dist/components/semiotic-server.d.ts +2 -1
  73. package/dist/components/semiotic-utils.d.ts +8 -0
  74. package/dist/components/semiotic-value.d.ts +55 -0
  75. package/dist/components/semiotic.d.ts +7 -0
  76. package/dist/components/server/renderEvidence.d.ts +92 -0
  77. package/dist/components/server/renderToStaticSVG.d.ts +14 -1
  78. package/dist/components/server/staticAnnotations.d.ts +2 -0
  79. package/dist/components/stream/AccessibleDataTable.d.ts +15 -6
  80. package/dist/components/stream/FocusRing.d.ts +2 -1
  81. package/dist/components/stream/MarginalGraphics.d.ts +2 -1
  82. package/dist/components/stream/NetworkSVGOverlay.d.ts +13 -6
  83. package/dist/components/stream/OrdinalBrushOverlay.d.ts +19 -1
  84. package/dist/components/stream/OrdinalSVGOverlay.d.ts +4 -2
  85. package/dist/components/stream/SVGOverlay.d.ts +5 -2
  86. package/dist/components/stream/XYBrushOverlay.d.ts +21 -1
  87. package/dist/components/stream/geoTypes.d.ts +3 -0
  88. package/dist/components/stream/networkTypes.d.ts +2 -0
  89. package/dist/components/stream/ordinalTypes.d.ts +2 -0
  90. package/dist/components/stream/types.d.ts +2 -0
  91. package/dist/geo.min.js +1 -1
  92. package/dist/geo.module.min.js +1 -1
  93. package/dist/network.min.js +1 -1
  94. package/dist/network.module.min.js +1 -1
  95. package/dist/ordinal.min.js +1 -1
  96. package/dist/ordinal.module.min.js +1 -1
  97. package/dist/realtime.min.js +1 -1
  98. package/dist/realtime.module.min.js +1 -1
  99. package/dist/semiotic-ai.d.ts +38 -15
  100. package/dist/semiotic-ai.min.js +1 -1
  101. package/dist/semiotic-ai.module.min.js +1 -1
  102. package/dist/semiotic-realtime.d.ts +2 -0
  103. package/dist/semiotic-recipes.d.ts +4 -0
  104. package/dist/semiotic-recipes.min.js +1 -1
  105. package/dist/semiotic-recipes.module.min.js +1 -1
  106. package/dist/semiotic-server.d.ts +2 -1
  107. package/dist/semiotic-themes.min.js +1 -1
  108. package/dist/semiotic-themes.module.min.js +1 -1
  109. package/dist/semiotic-utils.d.ts +8 -0
  110. package/dist/semiotic-utils.min.js +1 -1
  111. package/dist/semiotic-utils.module.min.js +1 -1
  112. package/dist/semiotic-value.d.ts +55 -0
  113. package/dist/semiotic-value.min.js +2 -0
  114. package/dist/semiotic-value.module.min.js +2 -0
  115. package/dist/semiotic.d.ts +7 -0
  116. package/dist/semiotic.min.js +1 -1
  117. package/dist/semiotic.module.min.js +1 -1
  118. package/dist/server.min.js +1 -1
  119. package/dist/server.module.min.js +1 -1
  120. package/dist/xy.min.js +1 -1
  121. package/dist/xy.module.min.js +1 -1
  122. package/package.json +19 -5
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- semiotic-bundle-sizes:start -->
4
4
  <!-- Auto-generated by scripts/sync-bundle-sizes.mjs — do not edit by hand. -->
5
- **Use sub-path imports** — `semiotic/xy` (86KB gz), `semiotic/ordinal` (70KB gz), `semiotic/network` (64KB gz), `semiotic/geo` (52KB gz), `semiotic/realtime` (91KB gz), `semiotic/server` (122KB gz), `semiotic/utils` (22KB gz), `semiotic/recipes` (5KB gz), `semiotic/themes` (4KB gz), `semiotic/data` (3KB gz), `semiotic/ai` (211KB gz). Full `semiotic` is 190KB gz.
5
+ **Use sub-path imports** — `semiotic/xy` (90KB gz), `semiotic/ordinal` (74KB gz), `semiotic/network` (68KB gz), `semiotic/geo` (55KB gz), `semiotic/realtime` (95KB gz), `semiotic/server` (128KB gz), `semiotic/utils` (38KB gz), `semiotic/recipes` (9KB gz), `semiotic/themes` (4KB gz), `semiotic/data` (3KB gz), `semiotic/value` (6KB gz), `semiotic/ai` (250KB gz). Full `semiotic` is 203KB gz.
6
6
  <!-- semiotic-bundle-sizes:end -->
7
7
 
8
8
  ## Flat Array Data (`data: object[]`)
@@ -84,12 +84,15 @@ Callback receiving `ChartObservation`: `{ type: "hover"|"click"|"brush"|"selecti
84
84
  ### emphasis
85
85
  `emphasis="primary"` makes a chart span two columns inside a `ChartGrid`.
86
86
 
87
- ## Annotations (XY and ordinal charts)
87
+ ## Annotations (all chart families)
88
88
  - `annotations={[{ type: "y-threshold", value: 200, label: "SLA limit", color: "#e45050", labelPosition: "right" }]}` — horizontal reference line (works on XY and vertical ordinal charts). `labelPosition`: "left"|"center"|"right"
89
89
  - `annotations={[{ type: "x-threshold", value: 50, label: "Cutoff", labelPosition: "top" }]}` — vertical reference line. `labelPosition`: "top"|"center"|"bottom"
90
+ - `annotations={[{ type: "callout-circle", x: 5, y: 20, label: "Peak", radius: 12 }]}` — data-bound callout; use `callout-rect` with `width`/`height` for a rectangular subject
90
91
  - `annotations={[{ type: "category-highlight", category: "Q3 2024", color: "#4589ff", opacity: 0.15 }]}` — highlight a category column/row in ordinal charts
91
92
  - `annotations={[{ type: "widget", time: 42, latency: 850, dy: -10, content: <span>Alert</span> }]}` — place React element at data coordinates
92
93
  - `annotations={[{ type: "enclose", coordinates: [datum1, datum2], label: "Cluster" }]}` — circle enclosing data points
94
+ - `autoPlaceAnnotations={{ density: true, progressiveDisclosure: true, redundantCues: true }}` — opt-in placement, clutter management, and non-color association support
95
+ - Annotation metadata: `emphasis`, `defensive`, `provenance`, and `lifecycle`; use `applyAnnotationLifecycle`, `applyAnnotationStatus`, and `filterAnnotationsByStatus` from `semiotic/ai`
93
96
 
94
97
  ## Theming & Brand Styling
95
98
  All charts respond to CSS custom properties on any ancestor:
@@ -137,7 +140,7 @@ These rules are generated from `ai/behaviorContracts.cjs` and are consumed by `s
137
140
 
138
141
  ## Key Patterns
139
142
  - **Percentile band + main line**: Layer `<AreaChart yAccessor="p95" y0Accessor="p5" showLine={false} />` + `<LineChart yAccessor="p50" />`. AreaChart's `showLine` only draws the top edge, NOT a separate main line.
140
- - **SSR**: `renderChart("BarChart", props)` from `semiotic/server` — uses HOC names. Also `"Sparkline"` (no axes, 2px margins). `renderToImage()` (PNG), `renderToAnimatedGif()` (GIF), `renderDashboard()` (multi-chart). All accept `theme`. Required props: StackedBarChart needs `stackBy`, GroupedBarChart needs `groupBy`, StackedAreaChart needs `areaBy`, BubbleChart needs `sizeBy`, FunnelChart uses `stepAccessor`, GaugeChart needs `value` (`thresholds` optional).
143
+ - **SSR**: `renderChart("BarChart", props)` from `semiotic/server` — uses HOC names. Also `"Sparkline"` (no axes, 2px margins). `renderChartWithEvidence()` returns `{ svg, evidence }` (mark counts by scene type, axis domains, empty flag, annotation count, accessible name) so agents can verify the render drew data marks. `renderToImage()` (PNG), `renderToAnimatedGif()` (GIF), `renderDashboard()` (multi-chart). All accept `theme`. Required props: StackedBarChart needs `stackBy`, GroupedBarChart needs `groupBy`, StackedAreaChart needs `areaBy`, BubbleChart needs `sizeBy`, FunnelChart uses `stepAccessor`, GaugeChart needs `value` (`thresholds` optional).
141
144
  - **CLI**: `npx semiotic-ai --list` shows components/import paths/renderability; `npx semiotic-ai --schema GaugeChart` prints one component schema with metadata; `--doctor` validates props JSON and behavior contracts.
142
- - **MCP**: `npx semiotic-mcp` exposes tools (`getSchema`, `suggestChart`, `diagnoseConfig`, `renderChart`, `applyTheme`, `reportIssue`), resources (`semiotic://schema`, `semiotic://components`, `semiotic://behavior-contracts`, `semiotic://system-prompt`, `semiotic://examples`), and prompts (`build-semiotic-chart`, `debug-semiotic-chart`).
145
+ - **MCP**: `npx semiotic-mcp` exposes schema, suggestion, diagnosis, accessibility, grounding, issue, theme, static render (`renderChart`), and ChatGPT Apps render (`renderInteractiveChart`) tools. Resources include `semiotic://schema`, `semiotic://components`, `semiotic://behavior-contracts`, `semiotic://system-prompt`, `semiotic://examples`, and the widget template `ui://semiotic/chart-widget.html`. Prompts: `build-semiotic-chart`, `debug-semiotic-chart`.
143
146
  - **exportChart**: Pass the wrapper div, not the SVG element: `exportChart(wrapperDiv, { format: "png" })`. It finds canvas+SVG internally.
@@ -0,0 +1,26 @@
1
+ import * as React from "react";
2
+ import { type NavTreeNode } from "./ai/navigationTree";
3
+ export interface AccessibleNavTreeProps {
4
+ tree: NavTreeNode;
5
+ /** Accessible name for the tree. */
6
+ label?: string;
7
+ /** Show the tree visibly (default: screen-reader-only). */
8
+ visible?: boolean;
9
+ className?: string;
10
+ /** Fired when the active node changes (e.g. to highlight the matching mark). */
11
+ onActiveChange?: (node: NavTreeNode) => void;
12
+ /**
13
+ * Controlled active node id. When provided, the parent owns the active node
14
+ * (e.g. `useNavigationSync` driving it from the chart's hover). The tree
15
+ * auto-expands the path to a controlled active node so it stays visible.
16
+ */
17
+ activeId?: string;
18
+ /**
19
+ * `chartId` of the chart this tree describes. Correlates the reception
20
+ * telemetry the tree emits (`nav-node-focused` / `nav-branch-expanded`
21
+ * conversation-arc events) back to the chart. Events are only recorded while
22
+ * the conversation-arc store is enabled — zero-overhead otherwise.
23
+ */
24
+ chartId?: string;
25
+ }
26
+ export declare function AccessibleNavTree({ tree, label, visible, className, onActiveChange, activeId: controlledActiveId, chartId }: AccessibleNavTreeProps): React.JSX.Element;
@@ -1,11 +1,41 @@
1
1
  import * as React from "react";
2
+ type AnnotationEventHandlers = Record<string, (e: React.SyntheticEvent) => void>;
3
+ type AnnotationNote = {
4
+ label?: string;
5
+ title?: string;
6
+ wrap?: number;
7
+ orientation?: string;
8
+ align?: string;
9
+ noWrap?: boolean;
10
+ };
11
+ type AnnotationConnector = {
12
+ end?: "arrow";
13
+ type?: "line" | "curve";
14
+ curve?: number;
15
+ };
16
+ type AnnotationSubject = {
17
+ radius?: number;
18
+ radiusPadding?: number;
19
+ width?: number;
20
+ height?: number;
21
+ custom?: React.ReactElement | React.ReactElement[];
22
+ x?: number;
23
+ y?: number;
24
+ x1?: number;
25
+ x2?: number;
26
+ y1?: number;
27
+ y2?: number;
28
+ type?: string;
29
+ depth?: number;
30
+ [key: string]: unknown;
31
+ };
2
32
  /** Props for the single-annotation renderer. Consumed only by `SemioticAnnotation`
3
33
  * below; the broader annotation API flows through the frame-level `annotations`
4
34
  * array and its `svgAnnotationRules` hook. */
5
35
  export interface AnnotationProps {
6
36
  noteData: {
7
- eventListeners?: Record<string, (e: React.SyntheticEvent) => void>;
8
- events?: Record<string, (e: React.SyntheticEvent) => void>;
37
+ eventListeners?: AnnotationEventHandlers;
38
+ events?: AnnotationEventHandlers;
9
39
  type: string;
10
40
  screenCoordinates?: number[][];
11
41
  /** When truthy, `screenCoordinates` is read as a sequence of anchor points
@@ -19,25 +49,21 @@ export interface AnnotationProps {
19
49
  ny?: number;
20
50
  dx?: number;
21
51
  dy?: number;
22
- note: {
23
- label?: string;
24
- title?: string;
25
- wrap?: number;
26
- orientation?: string;
27
- align?: string;
28
- noWrap?: boolean;
29
- };
52
+ note: AnnotationNote;
30
53
  i?: number;
31
54
  fixedPosition?: boolean;
32
55
  label?: string;
33
- connector?: {
34
- end?: "arrow";
35
- };
36
- subject?: Record<string, unknown>;
56
+ connector?: AnnotationConnector;
57
+ subject?: AnnotationSubject;
37
58
  color?: string;
38
59
  className?: string;
39
60
  disable?: string[];
61
+ /** SVG opacity cascaded to every stroked/filled child of the annotation. */
62
+ opacity?: number;
63
+ /** SVG stroke-dasharray cascaded to every stroked child of the annotation. */
64
+ strokeDasharray?: string;
40
65
  [key: string]: unknown;
41
66
  };
42
67
  }
43
- export default function SemioticAnnotation(props: AnnotationProps): import("react/jsx-runtime").JSX.Element;
68
+ export default function SemioticAnnotation(props: AnnotationProps): React.JSX.Element;
69
+ export {};
@@ -37,7 +37,7 @@ export interface CategoryColorProviderProps {
37
37
  * </CategoryColorProvider>
38
38
  * ```
39
39
  */
40
- export declare function CategoryColorProvider({ colors, categories, colorScheme, children, }: CategoryColorProviderProps): import("react/jsx-runtime").JSX.Element;
40
+ export declare function CategoryColorProvider({ colors, categories, colorScheme, children, }: CategoryColorProviderProps): React.JSX.Element;
41
41
  export declare namespace CategoryColorProvider {
42
42
  var displayName: string;
43
43
  }
@@ -1,5 +1,6 @@
1
1
  import * as React from "react";
2
2
  import type { ChartConfig, CopyFormat } from "./export/chartConfig";
3
+ import { type DescribeLevel } from "./ai/describeChart";
3
4
  export interface ChartContainerProps {
4
5
  /** Chart title */
5
6
  title?: string;
@@ -26,8 +27,37 @@ export interface ChartContainerProps {
26
27
  /** Enable "Data Summary" action button — shows statistical summary + sample rows */
27
28
  dataSummary?: boolean;
28
29
  };
29
- /** Chart configuration for serialization. Enables the "Copy Config" toolbar action. */
30
- chartConfig?: ChartConfig;
30
+ /**
31
+ * Chart configuration. Enables the "Copy Config" toolbar action and the
32
+ * `describe`/`navigable` a11y affordances. Only `component` and `props` are
33
+ * required — the `version`/`createdAt` serialization metadata is optional
34
+ * here and synthesized when copying.
35
+ */
36
+ chartConfig?: Omit<ChartConfig, "version" | "createdAt"> & Partial<Pick<ChartConfig, "version" | "createdAt">>;
37
+ /**
38
+ * Auto-generate a layered (L1–L3) natural-language description from
39
+ * `chartConfig` and expose it at the container level — the opt-in path to a
40
+ * fuller accessible reading than the bare chart's terse aria-label. Requires
41
+ * `chartConfig`. `true` renders a screen-reader-only note; pass
42
+ * `{ visible: true }` to also show it as a visible caption, or `{ levels }`
43
+ * to choose verbosity. Backed by `describeChart()`.
44
+ */
45
+ describe?: boolean | {
46
+ levels?: DescribeLevel[];
47
+ visible?: boolean;
48
+ };
49
+ /**
50
+ * Mount a structured, screen-reader-navigable tree of the chart (chart →
51
+ * axes/series → data points), built from `chartConfig` — the Olli /
52
+ * Data Navigator model, as an opt-in at the container layer. Requires
53
+ * `chartConfig`. `true` renders it screen-reader-only; `{ visible: true }`
54
+ * shows it; `{ maxLeaves }` caps leaves per branch. Backed by
55
+ * `buildNavigationTree()` + `AccessibleNavTree`.
56
+ */
57
+ navigable?: boolean | {
58
+ visible?: boolean;
59
+ maxLeaves?: number;
60
+ };
31
61
  /** Additional controls rendered in the toolbar after built-in actions */
32
62
  controls?: React.ReactNode;
33
63
  /** Loading state — shows skeleton placeholder */
@@ -33,7 +33,7 @@ export interface ChartGridProps {
33
33
  * </ChartGrid>
34
34
  * ```
35
35
  */
36
- export declare function ChartGrid({ children, columns, minCellWidth, gap, className, style, }: ChartGridProps): import("react/jsx-runtime").JSX.Element;
36
+ export declare function ChartGrid({ children, columns, minCellWidth, gap, className, style, }: ChartGridProps): React.JSX.Element;
37
37
  export declare namespace ChartGrid {
38
38
  var displayName: string;
39
39
  }
@@ -32,7 +32,7 @@ export interface ContextLayoutProps {
32
32
  * </ContextLayout>
33
33
  * ```
34
34
  */
35
- export declare function ContextLayout({ children, context, position, contextSize, gap, className, style, }: ContextLayoutProps): import("react/jsx-runtime").JSX.Element;
35
+ export declare function ContextLayout({ children, context, position, contextSize, gap, className, style, }: ContextLayoutProps): React.JSX.Element;
36
36
  export declare namespace ContextLayout {
37
37
  var displayName: string;
38
38
  }
@@ -6,7 +6,7 @@ interface DataSummaryState {
6
6
  }
7
7
  export declare function DataSummaryProvider({ children }: {
8
8
  children: React.ReactNode;
9
- }): import("react/jsx-runtime").JSX.Element;
9
+ }): React.JSX.Element;
10
10
  export declare function useDataSummary(): DataSummaryState | null;
11
11
  export declare function useDataSummaryToggle(): (() => void) | null;
12
12
  export {};
@@ -32,7 +32,7 @@ export interface DetailsPanelProps {
32
32
  /** Inline style overrides */
33
33
  style?: React.CSSProperties;
34
34
  }
35
- export declare function DetailsPanel({ children, position, size, trigger, chartId, observation: directObservation, dismissOnEmpty, showClose, onToggle, className, style, }: DetailsPanelProps): import("react/jsx-runtime").JSX.Element | null;
35
+ export declare function DetailsPanel({ children, position, size, trigger, chartId, observation: directObservation, dismissOnEmpty, showClose, onToggle, className, style, }: DetailsPanelProps): React.JSX.Element | null;
36
36
  export declare namespace DetailsPanel {
37
37
  var displayName: string;
38
38
  }
@@ -1,8 +1,9 @@
1
+ import * as React from "react";
1
2
  import { LegendProps, GradientLegendConfig } from "./types/legendTypes";
2
3
  /** Gradient legend for continuous/sequential color scales */
3
4
  export declare function GradientLegend({ config, orientation, width, }: {
4
5
  config: GradientLegendConfig;
5
6
  orientation?: "vertical" | "horizontal";
6
7
  width?: number;
7
- }): import("react/jsx-runtime").JSX.Element;
8
- export default function Legend(props: LegendProps): import("react/jsx-runtime").JSX.Element;
8
+ }): React.JSX.Element;
9
+ export default function Legend(props: LegendProps): React.JSX.Element;
@@ -86,4 +86,4 @@ export declare function estimateLegendRowCount(labels: string[], width: number):
86
86
  * </LinkedCharts>
87
87
  * ```
88
88
  */
89
- export declare function LinkedCharts({ children, selections, showLegend, legendPosition, legendInteraction, legendSelectionName, legendField, }: LinkedChartsProps): import("react/jsx-runtime").JSX.Element;
89
+ export declare function LinkedCharts({ children, selections, showLegend, legendPosition, legendInteraction, legendSelectionName, legendField, }: LinkedChartsProps): React.JSX.Element;
@@ -7,7 +7,7 @@ interface ThemeProviderProps {
7
7
  theme?: ThemePresetName | SemioticThemeUpdate;
8
8
  children: React.ReactNode;
9
9
  }
10
- declare function ThemeProviderWrapper({ theme, children }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
10
+ declare function ThemeProviderWrapper({ theme, children }: ThemeProviderProps): React.JSX.Element;
11
11
  declare function useTheme(): SemioticTheme;
12
12
  export { ThemeProviderWrapper as ThemeProvider, useTheme };
13
13
  export { LIGHT_THEME, DARK_THEME, HIGH_CONTRAST_THEME };
@@ -45,5 +45,5 @@ interface FlippingTooltipProps {
45
45
  * guard, React throws `'NaN' is an invalid value for the 'top' css
46
46
  * style property` and the entire frame stops rendering.
47
47
  */
48
- export declare function FlippingTooltip({ x, y, containerWidth, containerHeight, margin, children, className, zIndex }: FlippingTooltipProps): import("react/jsx-runtime").JSX.Element | null;
48
+ export declare function FlippingTooltip({ x, y, containerWidth, containerHeight, margin, children, className, zIndex }: FlippingTooltipProps): React.JSX.Element | null;
49
49
  export {};
@@ -88,7 +88,7 @@ export declare const defaultTooltipStyle: React.CSSProperties;
88
88
  * />
89
89
  * ```
90
90
  */
91
- export declare function Tooltip(config?: TooltipConfig): (data: Record<string, unknown>) => import("react/jsx-runtime").JSX.Element | null;
91
+ export declare function Tooltip(config?: TooltipConfig): (data: Record<string, unknown>) => React.JSX.Element | null;
92
92
  /**
93
93
  * Create a multi-line tooltip that displays multiple fields
94
94
  *
@@ -131,7 +131,7 @@ export declare function Tooltip(config?: TooltipConfig): (data: Record<string, u
131
131
  * />
132
132
  * ```
133
133
  */
134
- export declare function MultiLineTooltip(config?: MultiLineTooltipConfig): (data: Record<string, unknown>) => import("react/jsx-runtime").JSX.Element | null;
134
+ export declare function MultiLineTooltip(config?: MultiLineTooltipConfig): (data: Record<string, unknown>) => React.JSX.Element | null;
135
135
  /**
136
136
  * Type for tooltip prop that chart components accept
137
137
  */
@@ -0,0 +1,349 @@
1
+ /**
2
+ * Where an annotation came from and how confident we should be in it.
3
+ * Lives on `annotation.provenance`.
4
+ */
5
+ export interface AnnotationProvenance {
6
+ /**
7
+ * Display name (or stable id) for who created the annotation — a
8
+ * person, agent, or watcher. Together with `authorKind` this expresses
9
+ * IDID §8's structured `author: { kind, id }`: `authorKind` is the
10
+ * actor category, `author` is the name/id.
11
+ */
12
+ author?: string;
13
+ /**
14
+ * Actor category — *who* created the annotation. IDID §8's
15
+ * `author.kind`. Distinct from `basis` (*how* it was derived) and from
16
+ * the coarser `source`. Open union; consumers may extend.
17
+ */
18
+ authorKind?: AnnotationActorKind;
19
+ /**
20
+ * Origin category. Recognized values are not exhaustive; consumers
21
+ * may extend with their own source labels. Coarser than the
22
+ * `authorKind` / `basis` pair — kept for back-compat and as a single
23
+ * convenience label when the finer split isn't needed.
24
+ */
25
+ source?: AnnotationSource;
26
+ /**
27
+ * Evidence type — *how* the annotation's claim was derived
28
+ * (a hand note, a statistical test, a rule, an LLM inference, an
29
+ * external source). IDID §8's `basis`. Distinct from `authorKind`
30
+ * (the actor) and `source` (the coarse origin): a `"human"` author can
31
+ * relay a `"statistical-test"` basis. Lets a reader weight a note by
32
+ * the strength of its evidence, not just who left it.
33
+ */
34
+ basis?: AnnotationBasis;
35
+ /**
36
+ * Confidence in the assertion, 0–1. `1` is a hand-placed user
37
+ * annotation; LLM-suggested annotations typically land below 0.8.
38
+ */
39
+ confidence?: number;
40
+ /** ISO 8601 timestamp marking when the annotation was created. */
41
+ createdAt?: string;
42
+ /**
43
+ * Identifier of the data snapshot the annotation was made against
44
+ * (IDID §8's `dataVersion`). Lets a consumer tell "this note was
45
+ * written about last week's data" from "this note still tracks the
46
+ * current data," independent of wall-clock freshness.
47
+ */
48
+ dataVersion?: string;
49
+ /**
50
+ * Stable, opaque identifier that survives data refresh and chart
51
+ * recreation. Used by the `"semantic"` anchor-resolution work to
52
+ * re-locate "the Q3 spike" after new data arrives, and as the target
53
+ * of another annotation's `lifecycle.supersedes`.
54
+ */
55
+ stableId?: string;
56
+ }
57
+ /**
58
+ * Actor category for an annotation — *who* created it. IDID §8 models
59
+ * this as `author.kind`. Open string union: `"system"` covers
60
+ * non-watcher automated placement, and consumers may pass any other
61
+ * label (it is preserved).
62
+ */
63
+ export type AnnotationActorKind = "human" | "agent" | "watcher" | "system" | (string & {});
64
+ /**
65
+ * Evidence type for an annotation — *how* its claim was derived. IDID
66
+ * §8's `basis`. Open string union so consumers can add evidence kinds
67
+ * (e.g. `"forecast"`, `"manual-review"`) without a type change.
68
+ */
69
+ export type AnnotationBasis = "human-note" | "statistical-test" | "rule" | "llm-inference" | "external-source" | "computed" | (string & {});
70
+ /**
71
+ * Recognized provenance sources. Open string union — consumers may
72
+ * pass any other label and it will be preserved.
73
+ */
74
+ export type AnnotationSource = "user" | "ai" | "agent" | "import" | "computed" | "system" | (string & {});
75
+ /**
76
+ * How an annotation ages relative to the chart's current data extent.
77
+ * Default visual treatment (defined in M2): `aging` dims, `stale`
78
+ * draws a dashed border, `expired` is hidden unless
79
+ * `showExpiredAnnotations` is on.
80
+ */
81
+ export type AnnotationFreshness = LifecycleBand;
82
+ import type { AnnotationAnchor } from "../realtime/types";
83
+ export type { AnnotationAnchor } from "../realtime/types";
84
+ import type { LifecycleBand, LifecycleBandThresholds } from "../realtime/lifecycleBands";
85
+ export { bandFromAge, DEFAULT_LIFECYCLE_THRESHOLDS } from "../realtime/lifecycleBands";
86
+ export type { LifecycleBand, LifecycleBandThresholds } from "../realtime/lifecycleBands";
87
+ /**
88
+ * Editorial standing of an annotation in a multiplayer conversation —
89
+ * is the note still believed? IDID §8's `status`. Orthogonal to the
90
+ * temporal `freshness` band: a note can be fresh-but-`disputed` or
91
+ * stale-but-`accepted`. Closed union — these four are the editorial
92
+ * state machine the editorial-lifecycle work drives:
93
+ *
94
+ * - `"proposed"` — placed but unreviewed (e.g. a watcher's auto-note).
95
+ * - `"accepted"` — confirmed by a human or agent.
96
+ * - `"disputed"` — contested; under review.
97
+ * - `"retracted"` — withdrawn; treat like an expired note.
98
+ */
99
+ export type AnnotationStatus = "proposed" | "accepted" | "disputed" | "retracted";
100
+ /**
101
+ * Lifecycle state for an annotation. Lives on `annotation.lifecycle`.
102
+ *
103
+ * Two orthogonal axes: the **temporal** band (`freshness`, derived from
104
+ * `createdAt` + `ttlHint`) and the **editorial** state (`status`,
105
+ * driven by the multiplayer accept/dispute/retract flow). `supersedes`
106
+ * links a revision to the note it replaces.
107
+ */
108
+ export interface AnnotationLifecycle {
109
+ /**
110
+ * Current freshness band. When omitted, `computeAnnotationFreshness`
111
+ * derives it from `ttlHint` and the data's current temporal extent.
112
+ */
113
+ freshness?: AnnotationFreshness;
114
+ /**
115
+ * Editorial standing (IDID §8's `status`). Set by the multiplayer
116
+ * accept/dispute/retract flow; orthogonal to `freshness`. When
117
+ * omitted, the annotation is treated as unconditionally shown (the
118
+ * pre-editorial-lifecycle behavior). Status-driven visual treatment
119
+ * is owed alongside the editorial-lifecycle work — the field ships
120
+ * first so it can be stamped now.
121
+ */
122
+ status?: AnnotationStatus;
123
+ /**
124
+ * `provenance.stableId` of the annotation this one replaces (IDID
125
+ * §8's `supersedes`). Forms a revision chain so a reader can trace how
126
+ * an interpretation changed; the superseded note is typically hidden
127
+ * once its replacement is `accepted`.
128
+ */
129
+ supersedes?: string;
130
+ /**
131
+ * How long this annotation should be considered fresh. Either an
132
+ * ISO 8601 duration string (`"PT24H"`, `"P7D"`) or a number of
133
+ * milliseconds. The freshness computation walks `fresh → aging
134
+ * → stale → expired` as the chart's "now" advances past
135
+ * `createdAt + ttlHint`.
136
+ */
137
+ ttlHint?: string | number;
138
+ /** Anchor resolution strategy. Defaults to `"fixed"` when omitted. */
139
+ anchor?: AnnotationAnchor;
140
+ }
141
+ /**
142
+ * Carries the new optional blocks onto whatever annotation type the
143
+ * chart accepts. Use as `Annotated<typeof myAnnotation>` for explicit
144
+ * typing, or call `withProvenance()` for inline authoring.
145
+ */
146
+ export type Annotated<T> = T & {
147
+ provenance?: AnnotationProvenance;
148
+ lifecycle?: AnnotationLifecycle;
149
+ };
150
+ /**
151
+ * Convenience builder — attaches provenance + lifecycle blocks to an
152
+ * annotation without disturbing its existing fields. Returns a new
153
+ * object; does not mutate. Pure function, safe to call in SSR.
154
+ *
155
+ * ```ts
156
+ * withProvenance(
157
+ * { type: "y-threshold", value: 100, label: "SLA breach" },
158
+ * {
159
+ * provenance: { author: "alice", source: "user", createdAt: "2026-05-20T14:00:00Z" },
160
+ * lifecycle: { ttlHint: "P30D", anchor: "semantic" },
161
+ * }
162
+ * )
163
+ * ```
164
+ */
165
+ export declare function withProvenance<T extends object>(annotation: T, blocks: {
166
+ provenance?: AnnotationProvenance;
167
+ lifecycle?: AnnotationLifecycle;
168
+ }): Annotated<T>;
169
+ /**
170
+ * Returns an ISO 8601 wall-clock timestamp suitable for stamping
171
+ * `provenance.createdAt`. Sugar over `new Date().toISOString()`, but
172
+ * named to make intent obvious in streaming consumers: "mark this
173
+ * annotation as created now, so the lifecycle helpers can age it."
174
+ *
175
+ * Pair with `applyAnnotationLifecycle({ dataExtent })` on time-series
176
+ * charts to have annotations age against chart-time rather than
177
+ * wall-clock — the chart's latest data point becomes the "now"
178
+ * reference, and recently-stamped annotations stay fresh for as long
179
+ * as new data is flowing.
180
+ */
181
+ export declare function currentTimestamp(): string;
182
+ /**
183
+ * Stamp an annotation with `provenance.createdAt = currentTimestamp()`
184
+ * (unless it already has a `createdAt`) and optional additional
185
+ * provenance fields. Intended for the streaming "I'm marking the
186
+ * latest data point" pattern, where the annotation's age should be
187
+ * measured from when the consumer added it.
188
+ *
189
+ * Equivalent to:
190
+ * ```ts
191
+ * withProvenance(ann, {
192
+ * provenance: { createdAt: currentTimestamp(), ...rest },
193
+ * lifecycle: ann.lifecycle,
194
+ * })
195
+ * ```
196
+ * — but reads cleaner at call sites and preserves any existing
197
+ * `createdAt`.
198
+ */
199
+ export declare function withCurrentProvenance<T extends object>(annotation: T, rest?: Omit<AnnotationProvenance, "createdAt"> & {
200
+ createdAt?: string;
201
+ }): Annotated<T>;
202
+ /**
203
+ * Options accepted by `computeAnnotationFreshness` and
204
+ * `applyAnnotationLifecycle`.
205
+ */
206
+ export interface ComputeAnnotationFreshnessOptions {
207
+ /**
208
+ * "Now" reference for age calculations. Number is epoch ms; string is
209
+ * any value `Date.parse` accepts. When omitted, defaults to the max
210
+ * of `dataExtent`, falling back to `Date.now()`.
211
+ */
212
+ now?: number | Date | string;
213
+ /**
214
+ * The chart's current temporal extent — typically `[oldest, newest]`
215
+ * x values. Used to derive a sensible "now" for streaming charts
216
+ * (where wall-clock time and the data's notion of "now" can drift).
217
+ */
218
+ dataExtent?: ReadonlyArray<number | Date | string> | {
219
+ min: number | Date | string;
220
+ max: number | Date | string;
221
+ };
222
+ /**
223
+ * Override the default age thresholds. Each value is a multiplier of
224
+ * `ttlHint`. Defaults: aging at 1×, stale at 1.5×, expired at 3×.
225
+ * Same shape as `LifecycleBandThresholds` from the shared primitive.
226
+ */
227
+ thresholds?: LifecycleBandThresholds;
228
+ }
229
+ /**
230
+ * Classify an annotation into a freshness band. Exported for tests and
231
+ * for consumers that want the per-annotation band without rebuilding
232
+ * the entire array.
233
+ *
234
+ * Returns the annotation's existing `lifecycle.freshness` verbatim if
235
+ * the annotation lacks the `createdAt` or `ttlHint` needed to compute
236
+ * a band — i.e. an explicit assignment always wins over inference.
237
+ */
238
+ export declare function annotationFreshnessFor<T>(annotation: Annotated<T>, nowMs: number, thresholds?: LifecycleBandThresholds): AnnotationFreshness;
239
+ /**
240
+ * Walk an annotations array and populate `lifecycle.freshness` on each
241
+ * entry from its `provenance.createdAt` and `lifecycle.ttlHint`.
242
+ *
243
+ * Pure function — returns a new array; does not mutate input. Safe
244
+ * to call in SSR. Annotations missing the inputs needed to compute a
245
+ * band keep whatever `lifecycle.freshness` they already had (so an
246
+ * explicit assignment always wins).
247
+ *
248
+ * For non-temporal charts, pass `now` explicitly. For streaming /
249
+ * time-series charts, pass `dataExtent` — the helper picks the latest
250
+ * value as "now" so freshness tracks chart-time, not wall-clock.
251
+ */
252
+ export declare function computeAnnotationFreshness<T>(annotations: ReadonlyArray<Annotated<T>>, options?: ComputeAnnotationFreshnessOptions): Annotated<T>[];
253
+ /**
254
+ * Style overrides per freshness band. Each map is partial — bands not
255
+ * present fall back to the defaults below. `null` for a value removes
256
+ * the default rather than applying it (e.g. `{ opacity: { aging: null } }`
257
+ * disables dimming aging annotations).
258
+ */
259
+ export interface AnnotationLifecycleTreatment {
260
+ opacity?: Partial<Record<AnnotationFreshness, number | null>>;
261
+ strokeDasharray?: Partial<Record<AnnotationFreshness, string | null>>;
262
+ /** Suffix appended to `label` for that band. Default suffixes are off. */
263
+ labelSuffix?: Partial<Record<AnnotationFreshness, string>>;
264
+ /**
265
+ * When true, expired annotations stay in the returned array (with
266
+ * the expired treatment applied). When false (default), expired
267
+ * annotations are filtered out — matching the "hidden by default"
268
+ * contract from the talk-readiness roadmap.
269
+ */
270
+ showExpiredAnnotations?: boolean;
271
+ }
272
+ export type ApplyAnnotationLifecycleOptions = ComputeAnnotationFreshnessOptions & AnnotationLifecycleTreatment;
273
+ /**
274
+ * Compute freshness and apply the default visual treatment in one pass.
275
+ *
276
+ * Behavior per band (overridable via options):
277
+ * - **fresh** — no change
278
+ * - **aging** — `opacity` 0.55
279
+ * - **stale** — `opacity` 0.35, `strokeDasharray` `"4 4"` (cascades
280
+ * through the annotation's stroked children)
281
+ * - **expired** — filtered out by default; pass
282
+ * `showExpiredAnnotations: true` to keep them with `opacity` 0.2 and
283
+ * `strokeDasharray` `"2 4"`
284
+ *
285
+ * Treatment composes cleanly with annotations that already carry their
286
+ * own `color` / `opacity` — explicit fields on the annotation win,
287
+ * the treatment only fills in what isn't already set.
288
+ */
289
+ export declare function applyAnnotationLifecycle<T>(annotations: ReadonlyArray<Annotated<T>>, options?: ApplyAnnotationLifecycleOptions): Annotated<T>[];
290
+ /**
291
+ * Style overrides per editorial status. Each map is partial — statuses not
292
+ * present fall back to the defaults below. `null` for a value removes the
293
+ * default rather than applying it.
294
+ */
295
+ export interface AnnotationStatusVisibility {
296
+ /**
297
+ * Keep `retracted` annotations instead of filtering them out. Default false
298
+ * — retracted is hidden like `expired`.
299
+ */
300
+ showRetractedAnnotations?: boolean;
301
+ /**
302
+ * Keep an annotation that another *present* note supersedes. Default false
303
+ * — a superseded note is hidden once its replacement is in the array.
304
+ */
305
+ showSupersededAnnotations?: boolean;
306
+ }
307
+ export interface AnnotationStatusTreatment extends AnnotationStatusVisibility {
308
+ /**
309
+ * Opacity *factor* per status, multiplied into any existing opacity so it
310
+ * composes with the freshness treatment (run `applyAnnotationLifecycle`
311
+ * first, then this). `null` disables the factor for that status.
312
+ */
313
+ opacity?: Partial<Record<AnnotationStatus, number | null>>;
314
+ strokeDasharray?: Partial<Record<AnnotationStatus, string | null>>;
315
+ /**
316
+ * Suffix appended to a string `label` for that status — the `disputed`
317
+ * default `" (?)"` is the query affordance the strategy calls for.
318
+ */
319
+ labelSuffix?: Partial<Record<AnnotationStatus, string>>;
320
+ }
321
+ /**
322
+ * Apply the default editorial visibility contract without changing annotation
323
+ * styling. Retracted notes and notes replaced by a present revision are hidden
324
+ * unless explicitly requested. Shared by visual treatment, chart descriptions,
325
+ * and navigation trees so they expose the same current set.
326
+ */
327
+ export declare function filterAnnotationsByStatus<T>(annotations: ReadonlyArray<Annotated<T>>, options?: AnnotationStatusVisibility): Annotated<T>[];
328
+ /**
329
+ * Apply the editorial-status visual treatment (M7) — the orthogonal companion
330
+ * to {@link applyAnnotationLifecycle}'s temporal-freshness treatment. The two
331
+ * compose (a note can be stale-and-disputed); run freshness first, then this.
332
+ *
333
+ * Per status (overridable via options):
334
+ * - **accepted** — no change (full weight).
335
+ * - **proposed** — `opacity` ×0.7, dashed `"3 3"`, `label` suffix `" (proposed)"`.
336
+ * An unreviewed (e.g. watcher) note reads provisionally.
337
+ * - **disputed** — `opacity` ×0.7, dashed `"2 3"`, `label` suffix `" (?)"`.
338
+ * The suffix is the query affordance: a contested note announces itself.
339
+ * - **retracted** — filtered out by default (like `expired`); pass
340
+ * `showRetractedAnnotations: true` to keep it at `opacity` ×0.25.
341
+ *
342
+ * Also resolves **supersession**: a note whose `provenance.stableId` is the
343
+ * `lifecycle.supersedes` target of another *present, non-retracted* note is
344
+ * hidden (the revision replaced it), unless `showSupersededAnnotations` is set.
345
+ *
346
+ * Pure — returns a new array; safe in SSR. Opacity is multiplied into any
347
+ * existing value, so it composes with freshness dimming and author-set opacity.
348
+ */
349
+ export declare function applyAnnotationStatus<T>(annotations: ReadonlyArray<Annotated<T>>, options?: AnnotationStatusTreatment): Annotated<T>[];