@meetreeve/ui 0.8.1 → 0.10.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.mts CHANGED
@@ -599,9 +599,115 @@ declare function ContextSwitcher({ items, activeRefId, onSelect, footer, placeho
599
599
  * is the whole backend round-trip (list/connect/disconnect), injected as
600
600
  * `client` (Matt's decision, 2026-07-25): Reeve passes one built on its own
601
601
  * fetch client; a tenant clone passes ~10 lines of its own.
602
+ *
603
+ * Ownership & sharing (DEV-5654 / CD-5): a personal/org kind toggle at
604
+ * connect time, owner attribution on connected tiles, a shared-with-me
605
+ * section, and a manage-sharing panel over the CD-2 grants API. Everything
606
+ * is data-driven from the CD-4 ownership axes the entry carries; the
607
+ * package has no auth deps and must never hardcode a role check. The
608
+ * sharing surface only renders when the injected client provides the
609
+ * optional grant methods, so a pre-CD-5 client keeps working unchanged.
602
610
  */
603
611
  type ConnectableTransport = "composio" | "native";
604
612
  type ConnectableCapability = "read" | "write" | "readwrite";
613
+ type ConnectionKind = "personal" | "org";
614
+ type ConnectorGranteeType = "user" | "role";
615
+ /** An RBAC role a grant can target, injected via the entry data (CD-2). */
616
+ interface ConnectorRoleOption {
617
+ id: string;
618
+ name: string;
619
+ }
620
+ /**
621
+ * Whether this entry may be connected org-wide, and with which role options
622
+ * the sharing UI can grant. Always supplied by the server through the entry
623
+ * data (CD-4) — never inferred client-side from who the viewer is.
624
+ */
625
+ interface OrgConnectPolicy {
626
+ permitted: boolean;
627
+ /** Human-readable reason shown on the disabled org option. */
628
+ reason?: string | null;
629
+ /** Role options offered by manage-sharing's "role" grantee type. */
630
+ role_options?: ConnectorRoleOption[];
631
+ }
632
+ /** One live grant on a connection, as the CD-2 grants API reports it. */
633
+ interface ConnectorGrant {
634
+ id: string;
635
+ grantee_type: ConnectorGranteeType;
636
+ grantee_id: string;
637
+ /** Display name when the server resolves one; falls back to grantee_id. */
638
+ grantee_name?: string | null;
639
+ }
640
+ interface ConnectorGrantInput {
641
+ granteeType: ConnectorGranteeType;
642
+ granteeId: string;
643
+ }
644
+ /**
645
+ * One credential input on the paste path (DEV-7849 / G1). Data-driven per
646
+ * provider exactly like the legacy cockpit modal's `fieldDefs` prop, which
647
+ * this shape is lifted from (src/components/connectors/dual-auth-modal.tsx)
648
+ * — the package renders `label`/`placeholder` generically and never knows
649
+ * which provider it is rendering.
650
+ */
651
+ interface ConnectorCredentialField {
652
+ key: string;
653
+ label: string;
654
+ placeholder?: string | null;
655
+ /** Input type; "password" masks the value. Defaults to "text". */
656
+ type?: "text" | "password" | "url";
657
+ /** Only an explicit `false` makes a field optional. */
658
+ required?: boolean;
659
+ /** Prefilled value the form starts from (e.g. PostHog's default host);
660
+ * submitted as-is when the customer doesn't change it. */
661
+ defaultValue?: string | null;
662
+ }
663
+ /** One numbered step of a setup guide; `copyable` is a literal to paste. */
664
+ interface ConnectorGuideStep {
665
+ text: string;
666
+ copyable?: string | null;
667
+ }
668
+ /**
669
+ * A fully-rendered setup guide as the server returns it (SG-1). The backend
670
+ * refuses to render a guide it cannot fully ground, so this is never a
671
+ * partially interpolated guide — see `hasUngroundedPlaceholder` for what
672
+ * happens if one ever arrives anyway.
673
+ */
674
+ interface ConnectorSetupGuide {
675
+ prerequisites: string[];
676
+ steps: ConnectorGuideStep[];
677
+ verify: string;
678
+ scope_note: string;
679
+ }
680
+ /**
681
+ * The result of testing a credential WITHOUT storing it (DEV-7852 / G4).
682
+ *
683
+ * `valid` is deliberately tri-state and mirrors the server's own semantics
684
+ * (`TestCredentialsResponse`): true/false for a provider with a live
685
+ * verifier, null for one that has none. null is NOT a pass — the UI says so
686
+ * in words rather than showing a green check it cannot justify.
687
+ */
688
+ interface ConnectorCredentialTestResult {
689
+ valid: boolean | null;
690
+ /** The account the verifier resolved, shown on success. */
691
+ account_name?: string | null;
692
+ /**
693
+ * Why the test failed. Already redacted server-side (the repo's
694
+ * no-raw-error-passthrough invariant) — the picker renders it verbatim and
695
+ * never composes its own message out of an upstream envelope.
696
+ */
697
+ error?: string | null;
698
+ /**
699
+ * Failure reasons keyed by credential field key. For a multi-field
700
+ * credential bundle a bare "invalid credentials" is close to useless, so
701
+ * anything that can be attributed to one field is rendered on that field.
702
+ */
703
+ field_errors?: Record<string, string> | null;
704
+ /**
705
+ * What the stored credential would actually be able to do, as read back
706
+ * from the verifier — e.g. "reporting only, this token cannot publish".
707
+ * Absent when the verifier reports no permission set.
708
+ */
709
+ permissions_note?: string | null;
710
+ }
605
711
  interface ConnectableEntry {
606
712
  slug: string;
607
713
  name: string;
@@ -614,19 +720,80 @@ interface ConnectableEntry {
614
720
  status: "connected" | "not_connected";
615
721
  connected_account_id: string | null;
616
722
  since: string | null;
723
+ /**
724
+ * Ownership axes (DEV-5654 / CD-5, from the CD-4 list endpoint). All
725
+ * optional so a pre-CD-4 payload keeps rendering exactly as before:
726
+ * absent fields mean no owner attribution, no shared-with-me grouping,
727
+ * and no manage-sharing affordance.
728
+ */
729
+ kind?: ConnectionKind | null;
730
+ owner?: {
731
+ id: string;
732
+ name: string;
733
+ } | null;
734
+ /** Set when the viewer sees this connection through a grant. */
735
+ shared_by?: {
736
+ id: string;
737
+ name: string;
738
+ } | null;
739
+ /** true = the viewer owns this connection (enables manage-sharing). */
740
+ owned_by_viewer?: boolean;
617
741
  };
618
742
  /** true = tenant has a live connection but the entry left the allowlist. */
619
743
  deprecated: boolean;
744
+ /** Org-connect permission + role options for this entry (CD-4). */
745
+ org_connect?: OrgConnectPolicy | null;
746
+ /**
747
+ * Fully-rendered setup guide for this entry, or null/absent when the
748
+ * server has none for it (DEV-7849 / G1). Absent is the NORMAL state
749
+ * while the guide registry fills in (G2/G3), never an error.
750
+ */
751
+ guide?: ConnectorSetupGuide | null;
752
+ /**
753
+ * Credential fields for the bring-your-own-credential path (DEV-7849).
754
+ * Absent or empty = this entry has no paste path and only the OAuth
755
+ * connect button renders, exactly as before.
756
+ */
757
+ credential_fields?: ConnectorCredentialField[] | null;
620
758
  }
621
759
  interface ConnectorPickerClient {
622
760
  listConnectable(opts: {
623
761
  purpose?: string;
624
762
  }): Promise<ConnectableEntry[]>;
625
- /** composio -> open the returned connect_url; native may resolve with none. */
626
- connect(entry: ConnectableEntry): Promise<{
763
+ /**
764
+ * composio -> open the returned connect_url; native may resolve with none.
765
+ * `opts.kind` is additive (DEV-5654): a pre-CD-5 client declaring only
766
+ * `connect(entry)` still satisfies this signature and simply ignores it.
767
+ */
768
+ connect(entry: ConnectableEntry, opts?: {
769
+ kind: ConnectionKind;
770
+ }): Promise<{
627
771
  connect_url?: string;
628
772
  }>;
629
773
  disconnect(entry: ConnectableEntry): Promise<void>;
774
+ /**
775
+ * Sharing over the CD-2 grants API (DEV-5654) — all three optional. The
776
+ * manage-sharing UI renders only when every one of them is provided;
777
+ * otherwise the picker behaves exactly as it did before CD-5.
778
+ */
779
+ listGrants?(entry: ConnectableEntry): Promise<ConnectorGrant[]>;
780
+ grant?(entry: ConnectableEntry, input: ConnectorGrantInput): Promise<void>;
781
+ revokeGrant?(entry: ConnectableEntry, grantId: string): Promise<void>;
782
+ /**
783
+ * Store a pasted credential (DEV-7849 / G1). Optional, same posture as the
784
+ * grant methods: the credential form renders only when the injected client
785
+ * provides this, so a pre-G1 client keeps working unchanged. Rejecting
786
+ * with an Error surfaces that message on the form.
787
+ */
788
+ submitCredentials?(entry: ConnectableEntry, values: Record<string, string>, opts?: {
789
+ kind: ConnectionKind;
790
+ }): Promise<void>;
791
+ /**
792
+ * Validate a credential without storing it (DEV-7852 / G4). Optional for
793
+ * the same reason `submitCredentials` is: a client that cannot test simply
794
+ * gets the G1 form with no Test action and no test gate.
795
+ */
796
+ testCredentials?(entry: ConnectableEntry, values: Record<string, string>): Promise<ConnectorCredentialTestResult>;
630
797
  }
631
798
  /**
632
799
  * Structurally identical to the app's own `DnaLens` (src/lib/dna-lens.ts) —
@@ -651,4 +818,4 @@ interface ConnectorPickerProps {
651
818
  }
652
819
  declare function ConnectorPicker({ client, purpose, lens, layout, onConnected, }: ConnectorPickerProps): react.JSX.Element | null;
653
820
 
654
- export { type AppRungItem, AppSidebar, type AppSidebarBrand, type AppSidebarModuleDef, type AppSidebarProps, type AppSidebarTopItem, type Brand, BrandGlyph, type BrandGlyphProps, type ConnectableCapability, type ConnectableEntry, type ConnectableTransport, ConnectorPicker, type ConnectorPickerClient, type ConnectorPickerLens, type ConnectorPickerProps, type ContextOrgGroup, ContextSwitcher, type ContextSwitcherItem, type ContextSwitcherProps, type FallbackModuleDef, Flyout, type FlyoutChild, type FlyoutProps, GLYPH_CANVAS_FILL, type GroupRungItem, type HeaderNavItem, LOCKUP_GAP, LOCKUP_ROW, MARK_CAP_RATIO, MARK_WEIGHT, REEVE_ACCENT, ResponsiveHeader, type ResponsiveHeaderProps, type RungItem, type SidebarLadder, type SidebarLadderParsed, type SidebarRung, type UseLadderRungOptions, WORDMARK_WEIGHT, deriveFallbackLadder, faviconUrl, groupByOrg, reconcileLadder, resolveLadder, useLadderRung, useResponsivePlaceholder, zSidebarLadder };
821
+ export { type AppRungItem, AppSidebar, type AppSidebarBrand, type AppSidebarModuleDef, type AppSidebarProps, type AppSidebarTopItem, type Brand, BrandGlyph, type BrandGlyphProps, type ConnectableCapability, type ConnectableEntry, type ConnectableTransport, type ConnectionKind, type ConnectorCredentialField, type ConnectorCredentialTestResult, type ConnectorGrant, type ConnectorGrantInput, type ConnectorGranteeType, type ConnectorGuideStep, ConnectorPicker, type ConnectorPickerClient, type ConnectorPickerLens, type ConnectorPickerProps, type ConnectorRoleOption, type ConnectorSetupGuide, type ContextOrgGroup, ContextSwitcher, type ContextSwitcherItem, type ContextSwitcherProps, type FallbackModuleDef, Flyout, type FlyoutChild, type FlyoutProps, GLYPH_CANVAS_FILL, type GroupRungItem, type HeaderNavItem, LOCKUP_GAP, LOCKUP_ROW, MARK_CAP_RATIO, MARK_WEIGHT, type OrgConnectPolicy, REEVE_ACCENT, ResponsiveHeader, type ResponsiveHeaderProps, type RungItem, type SidebarLadder, type SidebarLadderParsed, type SidebarRung, type UseLadderRungOptions, WORDMARK_WEIGHT, deriveFallbackLadder, faviconUrl, groupByOrg, reconcileLadder, resolveLadder, useLadderRung, useResponsivePlaceholder, zSidebarLadder };
package/dist/index.d.ts CHANGED
@@ -599,9 +599,115 @@ declare function ContextSwitcher({ items, activeRefId, onSelect, footer, placeho
599
599
  * is the whole backend round-trip (list/connect/disconnect), injected as
600
600
  * `client` (Matt's decision, 2026-07-25): Reeve passes one built on its own
601
601
  * fetch client; a tenant clone passes ~10 lines of its own.
602
+ *
603
+ * Ownership & sharing (DEV-5654 / CD-5): a personal/org kind toggle at
604
+ * connect time, owner attribution on connected tiles, a shared-with-me
605
+ * section, and a manage-sharing panel over the CD-2 grants API. Everything
606
+ * is data-driven from the CD-4 ownership axes the entry carries; the
607
+ * package has no auth deps and must never hardcode a role check. The
608
+ * sharing surface only renders when the injected client provides the
609
+ * optional grant methods, so a pre-CD-5 client keeps working unchanged.
602
610
  */
603
611
  type ConnectableTransport = "composio" | "native";
604
612
  type ConnectableCapability = "read" | "write" | "readwrite";
613
+ type ConnectionKind = "personal" | "org";
614
+ type ConnectorGranteeType = "user" | "role";
615
+ /** An RBAC role a grant can target, injected via the entry data (CD-2). */
616
+ interface ConnectorRoleOption {
617
+ id: string;
618
+ name: string;
619
+ }
620
+ /**
621
+ * Whether this entry may be connected org-wide, and with which role options
622
+ * the sharing UI can grant. Always supplied by the server through the entry
623
+ * data (CD-4) — never inferred client-side from who the viewer is.
624
+ */
625
+ interface OrgConnectPolicy {
626
+ permitted: boolean;
627
+ /** Human-readable reason shown on the disabled org option. */
628
+ reason?: string | null;
629
+ /** Role options offered by manage-sharing's "role" grantee type. */
630
+ role_options?: ConnectorRoleOption[];
631
+ }
632
+ /** One live grant on a connection, as the CD-2 grants API reports it. */
633
+ interface ConnectorGrant {
634
+ id: string;
635
+ grantee_type: ConnectorGranteeType;
636
+ grantee_id: string;
637
+ /** Display name when the server resolves one; falls back to grantee_id. */
638
+ grantee_name?: string | null;
639
+ }
640
+ interface ConnectorGrantInput {
641
+ granteeType: ConnectorGranteeType;
642
+ granteeId: string;
643
+ }
644
+ /**
645
+ * One credential input on the paste path (DEV-7849 / G1). Data-driven per
646
+ * provider exactly like the legacy cockpit modal's `fieldDefs` prop, which
647
+ * this shape is lifted from (src/components/connectors/dual-auth-modal.tsx)
648
+ * — the package renders `label`/`placeholder` generically and never knows
649
+ * which provider it is rendering.
650
+ */
651
+ interface ConnectorCredentialField {
652
+ key: string;
653
+ label: string;
654
+ placeholder?: string | null;
655
+ /** Input type; "password" masks the value. Defaults to "text". */
656
+ type?: "text" | "password" | "url";
657
+ /** Only an explicit `false` makes a field optional. */
658
+ required?: boolean;
659
+ /** Prefilled value the form starts from (e.g. PostHog's default host);
660
+ * submitted as-is when the customer doesn't change it. */
661
+ defaultValue?: string | null;
662
+ }
663
+ /** One numbered step of a setup guide; `copyable` is a literal to paste. */
664
+ interface ConnectorGuideStep {
665
+ text: string;
666
+ copyable?: string | null;
667
+ }
668
+ /**
669
+ * A fully-rendered setup guide as the server returns it (SG-1). The backend
670
+ * refuses to render a guide it cannot fully ground, so this is never a
671
+ * partially interpolated guide — see `hasUngroundedPlaceholder` for what
672
+ * happens if one ever arrives anyway.
673
+ */
674
+ interface ConnectorSetupGuide {
675
+ prerequisites: string[];
676
+ steps: ConnectorGuideStep[];
677
+ verify: string;
678
+ scope_note: string;
679
+ }
680
+ /**
681
+ * The result of testing a credential WITHOUT storing it (DEV-7852 / G4).
682
+ *
683
+ * `valid` is deliberately tri-state and mirrors the server's own semantics
684
+ * (`TestCredentialsResponse`): true/false for a provider with a live
685
+ * verifier, null for one that has none. null is NOT a pass — the UI says so
686
+ * in words rather than showing a green check it cannot justify.
687
+ */
688
+ interface ConnectorCredentialTestResult {
689
+ valid: boolean | null;
690
+ /** The account the verifier resolved, shown on success. */
691
+ account_name?: string | null;
692
+ /**
693
+ * Why the test failed. Already redacted server-side (the repo's
694
+ * no-raw-error-passthrough invariant) — the picker renders it verbatim and
695
+ * never composes its own message out of an upstream envelope.
696
+ */
697
+ error?: string | null;
698
+ /**
699
+ * Failure reasons keyed by credential field key. For a multi-field
700
+ * credential bundle a bare "invalid credentials" is close to useless, so
701
+ * anything that can be attributed to one field is rendered on that field.
702
+ */
703
+ field_errors?: Record<string, string> | null;
704
+ /**
705
+ * What the stored credential would actually be able to do, as read back
706
+ * from the verifier — e.g. "reporting only, this token cannot publish".
707
+ * Absent when the verifier reports no permission set.
708
+ */
709
+ permissions_note?: string | null;
710
+ }
605
711
  interface ConnectableEntry {
606
712
  slug: string;
607
713
  name: string;
@@ -614,19 +720,80 @@ interface ConnectableEntry {
614
720
  status: "connected" | "not_connected";
615
721
  connected_account_id: string | null;
616
722
  since: string | null;
723
+ /**
724
+ * Ownership axes (DEV-5654 / CD-5, from the CD-4 list endpoint). All
725
+ * optional so a pre-CD-4 payload keeps rendering exactly as before:
726
+ * absent fields mean no owner attribution, no shared-with-me grouping,
727
+ * and no manage-sharing affordance.
728
+ */
729
+ kind?: ConnectionKind | null;
730
+ owner?: {
731
+ id: string;
732
+ name: string;
733
+ } | null;
734
+ /** Set when the viewer sees this connection through a grant. */
735
+ shared_by?: {
736
+ id: string;
737
+ name: string;
738
+ } | null;
739
+ /** true = the viewer owns this connection (enables manage-sharing). */
740
+ owned_by_viewer?: boolean;
617
741
  };
618
742
  /** true = tenant has a live connection but the entry left the allowlist. */
619
743
  deprecated: boolean;
744
+ /** Org-connect permission + role options for this entry (CD-4). */
745
+ org_connect?: OrgConnectPolicy | null;
746
+ /**
747
+ * Fully-rendered setup guide for this entry, or null/absent when the
748
+ * server has none for it (DEV-7849 / G1). Absent is the NORMAL state
749
+ * while the guide registry fills in (G2/G3), never an error.
750
+ */
751
+ guide?: ConnectorSetupGuide | null;
752
+ /**
753
+ * Credential fields for the bring-your-own-credential path (DEV-7849).
754
+ * Absent or empty = this entry has no paste path and only the OAuth
755
+ * connect button renders, exactly as before.
756
+ */
757
+ credential_fields?: ConnectorCredentialField[] | null;
620
758
  }
621
759
  interface ConnectorPickerClient {
622
760
  listConnectable(opts: {
623
761
  purpose?: string;
624
762
  }): Promise<ConnectableEntry[]>;
625
- /** composio -> open the returned connect_url; native may resolve with none. */
626
- connect(entry: ConnectableEntry): Promise<{
763
+ /**
764
+ * composio -> open the returned connect_url; native may resolve with none.
765
+ * `opts.kind` is additive (DEV-5654): a pre-CD-5 client declaring only
766
+ * `connect(entry)` still satisfies this signature and simply ignores it.
767
+ */
768
+ connect(entry: ConnectableEntry, opts?: {
769
+ kind: ConnectionKind;
770
+ }): Promise<{
627
771
  connect_url?: string;
628
772
  }>;
629
773
  disconnect(entry: ConnectableEntry): Promise<void>;
774
+ /**
775
+ * Sharing over the CD-2 grants API (DEV-5654) — all three optional. The
776
+ * manage-sharing UI renders only when every one of them is provided;
777
+ * otherwise the picker behaves exactly as it did before CD-5.
778
+ */
779
+ listGrants?(entry: ConnectableEntry): Promise<ConnectorGrant[]>;
780
+ grant?(entry: ConnectableEntry, input: ConnectorGrantInput): Promise<void>;
781
+ revokeGrant?(entry: ConnectableEntry, grantId: string): Promise<void>;
782
+ /**
783
+ * Store a pasted credential (DEV-7849 / G1). Optional, same posture as the
784
+ * grant methods: the credential form renders only when the injected client
785
+ * provides this, so a pre-G1 client keeps working unchanged. Rejecting
786
+ * with an Error surfaces that message on the form.
787
+ */
788
+ submitCredentials?(entry: ConnectableEntry, values: Record<string, string>, opts?: {
789
+ kind: ConnectionKind;
790
+ }): Promise<void>;
791
+ /**
792
+ * Validate a credential without storing it (DEV-7852 / G4). Optional for
793
+ * the same reason `submitCredentials` is: a client that cannot test simply
794
+ * gets the G1 form with no Test action and no test gate.
795
+ */
796
+ testCredentials?(entry: ConnectableEntry, values: Record<string, string>): Promise<ConnectorCredentialTestResult>;
630
797
  }
631
798
  /**
632
799
  * Structurally identical to the app's own `DnaLens` (src/lib/dna-lens.ts) —
@@ -651,4 +818,4 @@ interface ConnectorPickerProps {
651
818
  }
652
819
  declare function ConnectorPicker({ client, purpose, lens, layout, onConnected, }: ConnectorPickerProps): react.JSX.Element | null;
653
820
 
654
- export { type AppRungItem, AppSidebar, type AppSidebarBrand, type AppSidebarModuleDef, type AppSidebarProps, type AppSidebarTopItem, type Brand, BrandGlyph, type BrandGlyphProps, type ConnectableCapability, type ConnectableEntry, type ConnectableTransport, ConnectorPicker, type ConnectorPickerClient, type ConnectorPickerLens, type ConnectorPickerProps, type ContextOrgGroup, ContextSwitcher, type ContextSwitcherItem, type ContextSwitcherProps, type FallbackModuleDef, Flyout, type FlyoutChild, type FlyoutProps, GLYPH_CANVAS_FILL, type GroupRungItem, type HeaderNavItem, LOCKUP_GAP, LOCKUP_ROW, MARK_CAP_RATIO, MARK_WEIGHT, REEVE_ACCENT, ResponsiveHeader, type ResponsiveHeaderProps, type RungItem, type SidebarLadder, type SidebarLadderParsed, type SidebarRung, type UseLadderRungOptions, WORDMARK_WEIGHT, deriveFallbackLadder, faviconUrl, groupByOrg, reconcileLadder, resolveLadder, useLadderRung, useResponsivePlaceholder, zSidebarLadder };
821
+ export { type AppRungItem, AppSidebar, type AppSidebarBrand, type AppSidebarModuleDef, type AppSidebarProps, type AppSidebarTopItem, type Brand, BrandGlyph, type BrandGlyphProps, type ConnectableCapability, type ConnectableEntry, type ConnectableTransport, type ConnectionKind, type ConnectorCredentialField, type ConnectorCredentialTestResult, type ConnectorGrant, type ConnectorGrantInput, type ConnectorGranteeType, type ConnectorGuideStep, ConnectorPicker, type ConnectorPickerClient, type ConnectorPickerLens, type ConnectorPickerProps, type ConnectorRoleOption, type ConnectorSetupGuide, type ContextOrgGroup, ContextSwitcher, type ContextSwitcherItem, type ContextSwitcherProps, type FallbackModuleDef, Flyout, type FlyoutChild, type FlyoutProps, GLYPH_CANVAS_FILL, type GroupRungItem, type HeaderNavItem, LOCKUP_GAP, LOCKUP_ROW, MARK_CAP_RATIO, MARK_WEIGHT, type OrgConnectPolicy, REEVE_ACCENT, ResponsiveHeader, type ResponsiveHeaderProps, type RungItem, type SidebarLadder, type SidebarLadderParsed, type SidebarRung, type UseLadderRungOptions, WORDMARK_WEIGHT, deriveFallbackLadder, faviconUrl, groupByOrg, reconcileLadder, resolveLadder, useLadderRung, useResponsivePlaceholder, zSidebarLadder };