@validation-os/dashboard 0.6.1 → 0.7.0

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
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { Collection, AnyRecord, Relation } from '@validation-os/core';
4
- import { PortfolioProgress, StageExperimentInput, MoveKind, NextMoveInput, JourneyEvent, BeliefStage, NextMove, Progress, MoverKind, TrajectoryPoint } from '@validation-os/core/derivation';
4
+ import { PortfolioProgress, StageExperimentInput, MoveKind, NextMoveInput, BeliefStage, JourneyEvent, NextMove, JourneyEventKind, ConfSign, StageKey, Progress, MoverKind, TrajectoryPoint } from '@validation-os/core/derivation';
5
5
  export { StageKey } from '@validation-os/core/derivation';
6
6
 
7
7
  /**
@@ -592,6 +592,24 @@ interface JourneyView {
592
592
  /** Killed (Invalidated) / moot / null — the drill-in's terminal state. */
593
593
  resolved: "killed" | "moot" | null;
594
594
  }
595
+ /** The dot's tone against an event — how that moment read for the belief. */
596
+ declare function eventTone(event: JourneyEvent): Tone;
597
+ /**
598
+ * The step-in an event offers (OPS-1294's human set: assumption edit · score
599
+ * impact · write decision), or null for an event there is nothing to act on.
600
+ *
601
+ * The story is where step-in lives — the rail is pure status (OPS-1297). Two
602
+ * acts are deliberately absent: designing a test (no experiment-design form on
603
+ * this surface) and recording a reading (its form lives with the evidence, not
604
+ * the narrative). An unscored belief has no `score` event at all, so its
605
+ * score-impact act rides the next-move card instead.
606
+ */
607
+ declare function eventStepIn(kind: JourneyEventKind): {
608
+ form: StoryStepIn;
609
+ cta: string;
610
+ } | null;
611
+ /** The forms the story can open — the OPS-1294 set, minus experiment design. */
612
+ type StoryStepIn = "edit-belief" | "score-impact" | "write-decision";
595
613
  /**
596
614
  * Build one belief's journey from the four registers. Returns null when the
597
615
  * belief id isn't in the assumptions register. `now` is passed in (an ISO date)
@@ -599,6 +617,266 @@ interface JourneyView {
599
617
  */
600
618
  declare function buildJourney(assumptionId: string, records: NextMoveRecords, now: string): JourneyView | null;
601
619
 
620
+ /**
621
+ * The per-belief journey — the drill-in altitude (design OPS-1297, build
622
+ * OPS-1330), mounted on the record page. An A+B hybrid:
623
+ *
624
+ * - at rest, a compact **read-only stage rail** — the same Framed → Planned →
625
+ * Tested → Known spine the pipeline board draws, zoomed to one belief. The
626
+ * rail is pure status: nothing to act on there;
627
+ * - it **expands into the chronological story** through the record page's
628
+ * existing "Why?" reveal idiom — the dated event log (bet → score →
629
+ * experiment → readings → confidence-cross → now), ending in the ranked
630
+ * next-move card (OPS-1292).
631
+ *
632
+ * **Step-in is story-only** (OPS-1297): the next-move card and the per-event
633
+ * edits carry the OPS-1294 human set (edit the bet · score impact · write
634
+ * decision), and manual override lives at the foot of the story. There is
635
+ * deliberately no experiment-design form here.
636
+ *
637
+ * The narrative is the *loop* story — why the number is what it is. It is not
638
+ * the raw record history: that audit trail belongs to the record page itself
639
+ * (OPS-1282) and this must not retell it. Every number arrives derived through
640
+ * `buildJourney`; nothing is computed here.
641
+ */
642
+ interface BeliefJourneyProps {
643
+ /** This belief's journey, already derived (`buildJourney`). */
644
+ journey: JourneyView;
645
+ /** The belief record itself — what the step-in forms write against. */
646
+ assumption: AnyRecord;
647
+ basePath?: string;
648
+ /** Navigate the shell — used by the story's manual override. */
649
+ onNavigate: (route: Route) => void;
650
+ /** Re-read the registers after a step-in writes. */
651
+ onChanged: () => void;
652
+ }
653
+ declare function BeliefJourney({ journey, assumption, basePath, onNavigate, onChanged, }: BeliefJourneyProps): react.JSX.Element;
654
+
655
+ /**
656
+ * The four loop meters as data — the Framed → Planned → Tested → Known spine
657
+ * turned into captions and fills, once (OPS-1330).
658
+ *
659
+ * Two surfaces draw the same four meters for one belief: the pipeline board's
660
+ * row (OPS-1300, the cross-belief altitude) and the journey rail (this ticket,
661
+ * the same spine zoomed to one belief). The *classification* is already shared
662
+ * in core (`deriveBeliefStage`, OPS-1329); this shares the layer above it — what
663
+ * each meter is captioned and how full it reads — so a board row and a rail can
664
+ * never disagree about a belief while looking at the same numbers.
665
+ *
666
+ * Only the mapping is shared, not the markup: each surface renders these its own
667
+ * way (the board as a compact horizontal track, the rail as the labelled spine).
668
+ * Pure, so the captions are unit-tested here rather than through two DOMs.
669
+ */
670
+
671
+ /**
672
+ * How a meter fills: `fill` runs left→right (0–100%); `signed` is anchored at
673
+ * the middle and leans by sign — the Known gauge, which never "completes".
674
+ */
675
+ type MeterKind = "fill" | "signed";
676
+ /** One meter, ready to render. */
677
+ interface StageMeterView {
678
+ /** Its place on the spine, "1"–"4" — the caption's index. */
679
+ n: string;
680
+ /** The stage it meters. */
681
+ key: StageKey;
682
+ /** Its display name — "Framed", "Planned", "Tested", "Known". */
683
+ name: string;
684
+ /** The caption: "Framed 60%", "No test", "Tested 1/3", "Known +40". */
685
+ label: string;
686
+ /**
687
+ * How full it reads, as a percentage of the track. A `signed` meter fills
688
+ * from the midpoint, so its span is 0–50 (a full lean is half the track).
689
+ */
690
+ pct: number;
691
+ /** Nothing has happened on this meter yet — the caption reads muted. */
692
+ muted: boolean;
693
+ kind: MeterKind;
694
+ /** Replaces the caption when set — the Known meter's kill-zone re-test flag. */
695
+ flag?: string;
696
+ /** Which way a `signed` meter leans. */
697
+ sign?: ConfSign;
698
+ }
699
+ /**
700
+ * The meter fields a belief carries. Both `BeliefStage` (the rail) and
701
+ * `PipelineRow` (the board) satisfy this structurally, so neither has to be
702
+ * converted before rendering.
703
+ */
704
+ interface StageMeterInput {
705
+ framed: number;
706
+ planned: boolean;
707
+ tested: {
708
+ settled: number;
709
+ total: number;
710
+ };
711
+ confidence: number;
712
+ confSign: ConfSign;
713
+ killZone: boolean;
714
+ }
715
+ /**
716
+ * One belief's four meters, in spine order. Nothing is derived here — the
717
+ * numbers arrive already computed (`deriveBeliefStage`); this only decides how
718
+ * each one reads.
719
+ */
720
+ declare function stageMeters(input: StageMeterInput): StageMeterView[];
721
+
722
+ /**
723
+ * The cross-surface cold-start view-model (OPS-1331) — pure, no React, no I/O,
724
+ * so the "what does the dashboard show before any beliefs exist?" mapping is
725
+ * unit-tested at this seam (like `next-move.ts` / `pipeline.ts` / `journey.ts`).
726
+ *
727
+ * The dashboard has three workflow surfaces, and each one had a basic one-line
728
+ * empty state from its own build (OPS-1304 front door, OPS-1300 pipeline). Now
729
+ * that all three surfaces exist (OPS-1330 journey landed), this replaces them
730
+ * with one designed pass: a founder who opens the dashboard before any beliefs
731
+ * exist is *guided in* rather than shown blank meters.
732
+ *
733
+ * Two cold states, one module:
734
+ *
735
+ * - **Cross-surface cold start** — zero beliefs exist. The front door and the
736
+ * pipeline each get a designed empty state (a hero with a first-bet CTA, an
737
+ * honest 0% burn-up with an invitation), and a shared first-run onboarding
738
+ * line ties the three surfaces together. Trigger: `records.assumptions`
739
+ * is empty.
740
+ * - **Journey no-history cold state** — a belief exists but has no evidence
741
+ * yet (no score, no test, no reading). The rail renders honestly (framed at
742
+ * its completeness %, 0/0 bars); the story's cold-state copy names the
743
+ * belief's first move in plain language, rather than showing two sparse
744
+ * events with nothing between. Trigger: the story has only the structural
745
+ * `bet` + `now` events.
746
+ *
747
+ * No number is invented: the pipeline's cold burn-up reads 0% because there is
748
+ * no risk to retire; the journey's cold rail reads the belief's real framing %
749
+ * and 0/0 tests. The copy is plain and consistent across both themes (it
750
+ * carries no tone — these are invitations, not status).
751
+ */
752
+
753
+ /** The cross-surface cold start — zero beliefs exist. */
754
+ interface ColdStart {
755
+ /** True when no assumptions exist in the register. */
756
+ cold: boolean;
757
+ /** The first-run onboarding line — shared across every cold surface. */
758
+ onboarding: string;
759
+ /** The front-door hero copy. */
760
+ next: NextColdStart;
761
+ /** The pipeline cold-board copy. */
762
+ pipeline: PipelineColdStart;
763
+ }
764
+ /** The front-door cold-start hero copy. */
765
+ interface NextColdStart {
766
+ /** The hero's eyebrow — a small label above the headline. */
767
+ eyebrow: string;
768
+ /** The hero's headline — the one line a founder reads. */
769
+ headline: string;
770
+ /** The hero's supporting line, under the headline. */
771
+ body: string;
772
+ /** The primary CTA on the cold hero. */
773
+ cta: string;
774
+ }
775
+ /** The pipeline cold-start copy. */
776
+ interface PipelineColdStart {
777
+ /** The burn-up's headline reading (honest: 0%, no risk to retire). */
778
+ headline: string;
779
+ /** The line under the 0% — what the founder does next. */
780
+ invitation: string;
781
+ /** The empty board's body copy. */
782
+ boardBody: string;
783
+ /** The empty board's CTA. */
784
+ boardCta: string;
785
+ }
786
+ /** The journey's no-history cold-state copy. */
787
+ interface JourneyColdState {
788
+ /** True when the belief has no evidence yet (only the structural events). */
789
+ cold: boolean;
790
+ /** The eyebrow on the cold-state card. */
791
+ eyebrow: string;
792
+ /** The cold-state body — names the belief's first move in plain language. */
793
+ body: string;
794
+ }
795
+ /** The shared first-run onboarding line — one tone across all three surfaces. */
796
+ declare const FIRST_RUN_LINE: string;
797
+ /**
798
+ * The cross-surface cold start, derived from the fetched registers. Cold when
799
+ * no assumptions exist; warm otherwise. Pure — the surfaces branch on `cold`
800
+ * and read the copy off the result.
801
+ */
802
+ declare function coldStartFor(records: NextMoveRecords): ColdStart;
803
+ /**
804
+ * The journey's no-history cold state. Cold when the belief's story has only
805
+ * the two structural events (the `bet` it opened with and the `now` that
806
+ * anchors today) — no score, no test, no reading, no confidence-cross. The
807
+ * rail still renders honestly (its real framing % and 0/0 tests); this only
808
+ * shapes the story's copy so a founder with one fresh belief isn't shown two
809
+ * sparse events with nothing between.
810
+ *
811
+ * The body names the belief's own next move in plain language when one exists,
812
+ * so the cold state still points forward.
813
+ */
814
+ declare function journeyColdState(journey: JourneyView): JourneyColdState;
815
+
816
+ /**
817
+ * The pure edit-logic seam — which fields a register lets you edit, how a
818
+ * form draft maps back to a version-guarded patch, and the plain-language
819
+ * conflict copy. Kept as pure data/functions (no DOM) so the edit behaviour
820
+ * is unit-testable exactly like `columns.ts`; the drawer component consumes it.
821
+ *
822
+ * Derived numbers (Confidence, Risk, Derived Impact, Strength) are never
823
+ * editable — they are computed server-side on write (spec user story 4/11),
824
+ * so they never appear here. Relation links are set through `link`, a separate
825
+ * story, so relation-id fields aren't editable inputs either.
826
+ */
827
+
828
+ /** The plain-language conflict prompt — never version jargon (user story 12).
829
+ * The API returns its own copy on a 409; this is the client-side fallback. */
830
+ declare const CONFLICT_MESSAGE: string;
831
+ type FieldKind = "text" | "textarea" | "number" | "select";
832
+ interface FieldEditor {
833
+ /** The record key this editor writes. */
834
+ key: string;
835
+ /** Plain-language label shown beside the input. */
836
+ label: string;
837
+ kind: FieldKind;
838
+ /** For `select`: the allowed options (a leading blank = "unset"). */
839
+ options?: readonly string[];
840
+ /** An empty input clears the field to `null` rather than "". */
841
+ nullable?: boolean;
842
+ }
843
+ /** The fields a register lets you edit, in render order. */
844
+ declare function editableFields(register: Collection): FieldEditor[];
845
+ /** A form draft is a plain string map keyed by field — what the inputs hold. */
846
+ type Draft = Record<string, string>;
847
+ /** Build the initial form draft from a record: every editable field becomes a
848
+ * string input value, and missing values become empty inputs. */
849
+ declare function draftFrom(register: Collection, record: AnyRecord): Draft;
850
+ /**
851
+ * A version-guarded patch from a draft: the loaded `version` plus only the
852
+ * fields whose value actually changed (so an untouched save doesn't churn
853
+ * unrelated fields). The API rejects a stale version with a 409.
854
+ */
855
+ declare function buildPatch(register: Collection, original: AnyRecord, draft: Draft): Record<string, unknown>;
856
+ /** Whether a draft differs from the record it was loaded from. */
857
+ declare function hasEdits(register: Collection, original: AnyRecord, draft: Draft): boolean;
858
+
859
+ /**
860
+ * The editable-field stack for a register — the inputs an edit form is made of,
861
+ * driven by `edit.ts`'s schema (which fields are editable, and as what control).
862
+ *
863
+ * Factored out of the record drawer so the drawer and the journey's "edit the
864
+ * bet" step-in (OPS-1330) render the same controls from the same schema: two
865
+ * surfaces editing one register should never drift into two different forms.
866
+ * Derived numbers are never here — they are computed on write (OPS-1251).
867
+ */
868
+ declare function EditFields({ register, draft, onField, }: {
869
+ register: Collection;
870
+ draft: Draft;
871
+ onField: (key: string, value: string) => void;
872
+ }): react.JSX.Element;
873
+ /** One editable field, as the control its `kind` calls for. */
874
+ declare function FieldInput({ field, value, onChange, }: {
875
+ field: FieldEditor;
876
+ value: string | undefined;
877
+ onChange: (value: string) => void;
878
+ }): react.JSX.Element;
879
+
602
880
  interface RegisterCountsProps {
603
881
  counts: Counts;
604
882
  /** Optional caption under the tiles (e.g. the backend the numbers came from). */
@@ -829,6 +1107,24 @@ interface ScoreImpactFormProps {
829
1107
  * ranking. The optional justification records *why* that weight.
830
1108
  */
831
1109
  declare function ScoreImpactForm({ assumption, basePath, onDone, onCancel, }: ScoreImpactFormProps): react.JSX.Element;
1110
+ interface EditBeliefFormProps {
1111
+ /** The assumption being edited (its version guards the write). */
1112
+ assumption: AnyRecord;
1113
+ basePath?: string;
1114
+ /** Called after a successful save. */
1115
+ onDone: () => void;
1116
+ onCancel: () => void;
1117
+ }
1118
+ /**
1119
+ * Edit the bet itself — the assumption-edit half of the OPS-1294 step-in set,
1120
+ * reached from the journey story's `bet` event. It renders the register's
1121
+ * editable fields from the same schema the drawer uses (`EditFields`), so the
1122
+ * two never drift, and writes only the fields actually changed: the patch is
1123
+ * diffed against the record it opened on, so a teammate's concurrent edit to an
1124
+ * untouched field survives. Framing completeness (the rail's Framed meter)
1125
+ * recomputes server-side on write.
1126
+ */
1127
+ declare function EditBeliefForm({ assumption, basePath, onDone, onCancel, }: EditBeliefFormProps): react.JSX.Element;
832
1128
  interface WriteDecisionFormProps {
833
1129
  /** The belief the decision rests on or resolves. */
834
1130
  assumption: AnyRecord;
@@ -950,49 +1246,6 @@ interface UseLinkResult {
950
1246
  /** Wire a relation; the API sets both ends and recomputes derived fields. */
951
1247
  declare function useLink(basePath?: string): UseLinkResult;
952
1248
 
953
- /**
954
- * The pure edit-logic seam — which fields a register lets you edit, how a
955
- * form draft maps back to a version-guarded patch, and the plain-language
956
- * conflict copy. Kept as pure data/functions (no DOM) so the edit behaviour
957
- * is unit-testable exactly like `columns.ts`; the drawer component consumes it.
958
- *
959
- * Derived numbers (Confidence, Risk, Derived Impact, Strength) are never
960
- * editable — they are computed server-side on write (spec user story 4/11),
961
- * so they never appear here. Relation links are set through `link`, a separate
962
- * story, so relation-id fields aren't editable inputs either.
963
- */
964
-
965
- /** The plain-language conflict prompt — never version jargon (user story 12).
966
- * The API returns its own copy on a 409; this is the client-side fallback. */
967
- declare const CONFLICT_MESSAGE: string;
968
- type FieldKind = "text" | "textarea" | "number" | "select";
969
- interface FieldEditor {
970
- /** The record key this editor writes. */
971
- key: string;
972
- /** Plain-language label shown beside the input. */
973
- label: string;
974
- kind: FieldKind;
975
- /** For `select`: the allowed options (a leading blank = "unset"). */
976
- options?: readonly string[];
977
- /** An empty input clears the field to `null` rather than "". */
978
- nullable?: boolean;
979
- }
980
- /** The fields a register lets you edit, in render order. */
981
- declare function editableFields(register: Collection): FieldEditor[];
982
- /** A form draft is a plain string map keyed by field — what the inputs hold. */
983
- type Draft = Record<string, string>;
984
- /** Build the initial form draft from a record: every editable field becomes a
985
- * string input value, and missing values become empty inputs. */
986
- declare function draftFrom(register: Collection, record: AnyRecord): Draft;
987
- /**
988
- * A version-guarded patch from a draft: the loaded `version` plus only the
989
- * fields whose value actually changed (so an untouched save doesn't churn
990
- * unrelated fields). The API rejects a stale version with a 409.
991
- */
992
- declare function buildPatch(register: Collection, original: AnyRecord, draft: Draft): Record<string, unknown>;
993
- /** Whether a draft differs from the record it was loaded from. */
994
- declare function hasEdits(register: Collection, original: AnyRecord, draft: Draft): boolean;
995
-
996
1249
  /**
997
1250
  * Per-register table columns and value formatting — the presentational shape
998
1251
  * of the browse tables, kept as pure data/functions so it is unit-testable
@@ -1295,4 +1548,4 @@ declare const REGISTER_GROUPS: {
1295
1548
  registers: Collection[];
1296
1549
  }[];
1297
1550
 
1298
- export { type BacklinkItem, CONFLICT_MESSAGE, type CellKind, type ColumnDef, ConfidenceCell, type Counts, type DashboardConfig, type Draft, type ExperimentView, type FieldEditor, type FieldKind, type FormField, type GlossaryTerm, GlossaryText, type GlossaryTextProps, type GroupBucket, type GroupByAxis, type HumanText, type JourneyEventView, type JourneyView, type LinkArgs, type LinkChoice, type LinkifyNode, type LinkifyOptions, type Meter, type MovePresentation, type NeedsHumanByRegister, type NeedsHumanCounts, type NeighbourChip, type NestedGroup, type NextMoveRecords, NextMoveSurface, type NextMoveSurfaceProps, type OtherMover, type Pill, type PipelineRow, PipelineSurface, type PipelineView, REGISTER_GROUPS, REGISTER_ICON, REGISTER_LABEL, REGISTER_ORDER, REGISTER_SINGULAR, REGISTER_SUBTITLE, RISK_CRIT, RISK_WARN, RecordDrawer, type RecordDrawerProps, RecordForm, type RecordFormProps, RecordPage, type RecordPageModel, type RecordPageProps, type RecordTabId, RegisterBrowser, type RegisterBrowserProps, type RegisterContext, RegisterCounts, type RegisterCountsProps, RegisterTable, type RegisterTableProps, type RelatedSet, RelationEditor, type RelationEditorProps, type RelationPanel, type ResolvedRow, type RiskBand, RiskBar, type Route, type SaveResult, type SavedView, type ScoreChip, ScoreImpactForm, type ScoreImpactFormProps, type ShapedRegister, SidebarNav, type SidebarNavProps, type SortSpec, Sparkline, StatTile, StatusPill, type StepInForm, SurfacePlaceholder, type SurfacePlaceholderProps, type TabDef, type TermPreview, type Tone, type Understanding, UnderstandingPanel, type UseCountsResult, type UseCreateResult, type UseLinkResult, type UseListResult, type UseNeedsHumanResult, type UseRecordResult, type UseSavedViewsResult, type UseUpdateResult, ValidationOSDashboard, type ValidationOSDashboardProps, type ViewDescriptor, WriteDecisionForm, type WriteDecisionFormProps, backlinkPanels, buildJourney, buildPatch, buildPipeline, buildRecordPage, buildUnderstanding, cellValue, columnsFor, confidenceTone, configureRiskBands, defaultTabId, dontConfuseWith, draftFrom, editableFields, emptyDraft, filterRecords, formFieldsFor, formatCount, formatRoute, formatSigned, formatValue, groupByAxesFor, groupRecords, hasEdits, headerPills, humanInputFields, interpretSave, leadingMeters, linkChoicesFrom, linkify, missingRequired, movePresentation, needsHumanCounts, nestReadingsByPlan, parseRoute, primaryLabel, riskBand, riskFraction, riskLevel, scoreChip, shapeRegister, sortRecords, sparklinePath, statusTone, tabsFor, toCreatePayload, toGlossaryTerms, toNextMoveInput, toStageExperimentInput, useCounts, useCreate, useLink, useList, useNeedsHuman, useRecord, useSavedViews, useUpdate, weekOverWeekDelta };
1551
+ export { type BacklinkItem, BeliefJourney, type BeliefJourneyProps, CONFLICT_MESSAGE, type CellKind, type ColdStart, type ColumnDef, ConfidenceCell, type Counts, type DashboardConfig, type Draft, EditBeliefForm, type EditBeliefFormProps, EditFields, type ExperimentView, FIRST_RUN_LINE, type FieldEditor, FieldInput, type FieldKind, type FormField, type GlossaryTerm, GlossaryText, type GlossaryTextProps, type GroupBucket, type GroupByAxis, type HumanText, type JourneyColdState, type JourneyEventView, type JourneyView, type LinkArgs, type LinkChoice, type LinkifyNode, type LinkifyOptions, type Meter, type MeterKind, type MovePresentation, type NeedsHumanByRegister, type NeedsHumanCounts, type NeighbourChip, type NestedGroup, type NextColdStart, type NextMoveRecords, NextMoveSurface, type NextMoveSurfaceProps, type OtherMover, type Pill, type PipelineColdStart, type PipelineRow, PipelineSurface, type PipelineView, REGISTER_GROUPS, REGISTER_ICON, REGISTER_LABEL, REGISTER_ORDER, REGISTER_SINGULAR, REGISTER_SUBTITLE, RISK_CRIT, RISK_WARN, RecordDrawer, type RecordDrawerProps, RecordForm, type RecordFormProps, RecordPage, type RecordPageModel, type RecordPageProps, type RecordTabId, RegisterBrowser, type RegisterBrowserProps, type RegisterContext, RegisterCounts, type RegisterCountsProps, RegisterTable, type RegisterTableProps, type RelatedSet, RelationEditor, type RelationEditorProps, type RelationPanel, type ResolvedRow, type RiskBand, RiskBar, type Route, type SaveResult, type SavedView, type ScoreChip, ScoreImpactForm, type ScoreImpactFormProps, type ShapedRegister, SidebarNav, type SidebarNavProps, type SortSpec, Sparkline, type StageMeterInput, type StageMeterView, StatTile, StatusPill, type StepInForm, type StoryStepIn, SurfacePlaceholder, type SurfacePlaceholderProps, type TabDef, type TermPreview, type Tone, type Understanding, UnderstandingPanel, type UseCountsResult, type UseCreateResult, type UseLinkResult, type UseListResult, type UseNeedsHumanResult, type UseRecordResult, type UseSavedViewsResult, type UseUpdateResult, ValidationOSDashboard, type ValidationOSDashboardProps, type ViewDescriptor, WriteDecisionForm, type WriteDecisionFormProps, backlinkPanels, buildJourney, buildPatch, buildPipeline, buildRecordPage, buildUnderstanding, cellValue, coldStartFor, columnsFor, confidenceTone, configureRiskBands, defaultTabId, dontConfuseWith, draftFrom, editableFields, emptyDraft, eventStepIn, eventTone, filterRecords, formFieldsFor, formatCount, formatRoute, formatSigned, formatValue, groupByAxesFor, groupRecords, hasEdits, headerPills, humanInputFields, interpretSave, journeyColdState, leadingMeters, linkChoicesFrom, linkify, missingRequired, movePresentation, needsHumanCounts, nestReadingsByPlan, parseRoute, primaryLabel, riskBand, riskFraction, riskLevel, scoreChip, shapeRegister, sortRecords, sparklinePath, stageMeters, statusTone, tabsFor, toCreatePayload, toGlossaryTerms, toNextMoveInput, toStageExperimentInput, useCounts, useCreate, useLink, useList, useNeedsHuman, useRecord, useSavedViews, useUpdate, weekOverWeekDelta };