@toolr/ui-design 0.1.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.
Files changed (112) hide show
  1. package/README.md +63 -0
  2. package/components/content/info-panel-primitives.tsx +297 -0
  3. package/components/diagrams/diagram-utils.tsx +908 -0
  4. package/components/hooks/use-click-outside.ts +27 -0
  5. package/components/hooks/use-dropdown-max-height.ts +20 -0
  6. package/components/hooks/use-navigation-history.ts +94 -0
  7. package/components/lib/ai-tools.tsx +44 -0
  8. package/components/lib/cn.ts +6 -0
  9. package/components/lib/form-colors.ts +32 -0
  10. package/components/lib/theme-engine.ts +97 -0
  11. package/components/lib/toolr-brand.tsx +31 -0
  12. package/components/sections/ai-tools-paths/index.ts +37 -0
  13. package/components/sections/ai-tools-paths/tools-paths-panel.tsx +212 -0
  14. package/components/sections/ai-tools-paths/types.ts +111 -0
  15. package/components/sections/ai-tools-paths/use-tools-paths.ts +159 -0
  16. package/components/sections/captured-issues/captured-issues-panel.tsx +214 -0
  17. package/components/sections/captured-issues/index.ts +38 -0
  18. package/components/sections/captured-issues/types.ts +113 -0
  19. package/components/sections/captured-issues/use-captured-issues.ts +111 -0
  20. package/components/sections/golden-snapshots/file-diff-viewer.tsx +420 -0
  21. package/components/sections/golden-snapshots/golden-sync-panel.tsx +223 -0
  22. package/components/sections/golden-snapshots/index.ts +145 -0
  23. package/components/sections/golden-snapshots/snapshot-manager.tsx +200 -0
  24. package/components/sections/golden-snapshots/status-overview.tsx +305 -0
  25. package/components/sections/golden-snapshots/types.ts +288 -0
  26. package/components/sections/golden-snapshots/use-golden-sync.ts +477 -0
  27. package/components/sections/golden-snapshots/version-manager.tsx +186 -0
  28. package/components/sections/prompt-editor/file-type-tabbed-prompt-editor.tsx +210 -0
  29. package/components/sections/prompt-editor/index.ts +121 -0
  30. package/components/sections/prompt-editor/simulator-prompt-editor.tsx +276 -0
  31. package/components/sections/prompt-editor/tabbed-prompt-editor.tsx +514 -0
  32. package/components/sections/prompt-editor/types.ts +101 -0
  33. package/components/sections/prompt-editor/use-prompt-editor.ts +131 -0
  34. package/components/sections/report-bug/error-logger.ts +392 -0
  35. package/components/sections/report-bug/index.ts +59 -0
  36. package/components/sections/report-bug/issue-reporter-api.ts +83 -0
  37. package/components/sections/report-bug/report-bug-form.tsx +282 -0
  38. package/components/sections/report-bug/screenshot-uploader.tsx +228 -0
  39. package/components/sections/report-bug/use-report-bug.ts +170 -0
  40. package/components/sections/snapshot-browser/index.ts +53 -0
  41. package/components/sections/snapshot-browser/snapshot-browser-panel.tsx +147 -0
  42. package/components/sections/snapshot-browser/snapshot-tree.tsx +451 -0
  43. package/components/sections/snapshot-browser/types.ts +106 -0
  44. package/components/sections/snapshot-browser/use-snapshot-browser.ts +125 -0
  45. package/components/sections/snippets-editor/index.ts +31 -0
  46. package/components/sections/snippets-editor/snippets-editor.tsx +381 -0
  47. package/components/sections/snippets-editor/types.ts +48 -0
  48. package/components/sections/snippets-editor/use-snippets-editor.ts +217 -0
  49. package/components/ui/action-dialog.tsx +309 -0
  50. package/components/ui/ai-action-button.tsx +137 -0
  51. package/components/ui/ai-execution-action-buttons.tsx +106 -0
  52. package/components/ui/badge.tsx +67 -0
  53. package/components/ui/bottom-panel-header.tsx +240 -0
  54. package/components/ui/breadcrumb.tsx +168 -0
  55. package/components/ui/checkbox.tsx +102 -0
  56. package/components/ui/collapsible-section.tsx +100 -0
  57. package/components/ui/confirm-badge.tsx +71 -0
  58. package/components/ui/detail-section.tsx +67 -0
  59. package/components/ui/detail-view-wrapper.tsx +55 -0
  60. package/components/ui/editor-placeholder-card.tsx +197 -0
  61. package/components/ui/editor-toolbar.tsx +123 -0
  62. package/components/ui/execution-details-panel.tsx +93 -0
  63. package/components/ui/extension-list-card.tsx +105 -0
  64. package/components/ui/file-structure-section.tsx +373 -0
  65. package/components/ui/file-tree.tsx +171 -0
  66. package/components/ui/files-panel.tsx +251 -0
  67. package/components/ui/filter-dropdown.tsx +173 -0
  68. package/components/ui/form-actions.tsx +127 -0
  69. package/components/ui/frontmatter-form-header.tsx +80 -0
  70. package/components/ui/icon-button.tsx +388 -0
  71. package/components/ui/input.tsx +211 -0
  72. package/components/ui/label.tsx +159 -0
  73. package/components/ui/layout-tab-bar.tsx +289 -0
  74. package/components/ui/modal.tsx +194 -0
  75. package/components/ui/nav-card.tsx +81 -0
  76. package/components/ui/navigation-bar.tsx +285 -0
  77. package/components/ui/number-input.tsx +165 -0
  78. package/components/ui/registry-browser.tsx +261 -0
  79. package/components/ui/registry-card.tsx +710 -0
  80. package/components/ui/registry-detail.tsx +224 -0
  81. package/components/ui/resizable-textarea.tsx +290 -0
  82. package/components/ui/scope-badge.tsx +67 -0
  83. package/components/ui/segmented-toggle.tsx +133 -0
  84. package/components/ui/select.tsx +172 -0
  85. package/components/ui/selection-grid.tsx +313 -0
  86. package/components/ui/setting-row.tsx +97 -0
  87. package/components/ui/snapshot-card.tsx +107 -0
  88. package/components/ui/snippets-panel.tsx +161 -0
  89. package/components/ui/sort-dropdown.tsx +109 -0
  90. package/components/ui/status-card.tsx +96 -0
  91. package/components/ui/tab-bar.tsx +340 -0
  92. package/components/ui/toggle.tsx +142 -0
  93. package/components/ui/tooltip.tsx +326 -0
  94. package/dist/content.d.ts +110 -0
  95. package/dist/content.js +195 -0
  96. package/dist/diagrams.d.ts +371 -0
  97. package/dist/diagrams.js +702 -0
  98. package/dist/index.d.ts +2714 -0
  99. package/dist/index.js +11220 -0
  100. package/dist/preset.d.ts +24 -0
  101. package/dist/preset.js +17 -0
  102. package/dist/tokens/tokens/primitives.css +45 -0
  103. package/dist/tokens/tokens/semantic.css +46 -0
  104. package/dist/tokens/tokens/theme.css +11 -0
  105. package/dist/tokens/tokens/tokens.json +65 -0
  106. package/index.ts +123 -0
  107. package/package.json +63 -0
  108. package/tailwind-preset.ts +22 -0
  109. package/tokens/primitives.css +45 -0
  110. package/tokens/semantic.css +46 -0
  111. package/tokens/theme.css +11 -0
  112. package/tokens/tokens.json +65 -0
@@ -0,0 +1,2714 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
3
+ import { ReactNode, MouseEvent, InputHTMLAttributes, ElementType, RefObject } from 'react';
4
+ import * as lucide_react from 'lucide-react';
5
+ import { LucideIcon } from 'lucide-react';
6
+ import { ClassValue } from 'clsx';
7
+
8
+ type FormColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky';
9
+
10
+ declare const SCALE_KEYS: readonly ["black", "950", "900", "800", "700", "600", "500", "400", "300", "200"];
11
+ type ScaleKey = (typeof SCALE_KEYS)[number];
12
+ type ThemeId = 'oled' | 'dark' | 'night' | 'soft' | 'bright' | 'paper' | 'muted';
13
+ declare const DARK_THEMES: ThemeId[];
14
+ declare const LIGHT_THEMES: ThemeId[];
15
+ declare const BASE_THEMES: Record<ThemeId, {
16
+ label: string;
17
+ maxSat: number;
18
+ lightness: Record<ScaleKey, number>;
19
+ }>;
20
+ interface AccentDef {
21
+ id: FormColor;
22
+ hue: number | null;
23
+ dotColor: string;
24
+ }
25
+ declare const ACCENT_DEFS: AccentDef[];
26
+ declare function satCurve(l: number): number;
27
+ declare function hslToHex(h: number, s: number, l: number): string;
28
+ declare function generateScale(theme: ThemeId, hue: number | null, maxSat: number): Record<ScaleKey, string>;
29
+ declare function isLightTheme(themeId: ThemeId): boolean;
30
+ declare function applyTheme(themeId: ThemeId, accentHue: number | null, root?: HTMLElement): void;
31
+
32
+ type ToolrAppId = 'toolr' | 'configr' | 'reviewr' | 'vibr' | 'learnr' | 'planr' | 'seedr';
33
+ declare const TOOLR_APPS: Record<ToolrAppId, {
34
+ name: string;
35
+ color: string;
36
+ }>;
37
+ declare function ToolrAppLogo({ app, color: colorOverride, size, className }: {
38
+ app?: ToolrAppId;
39
+ color?: string;
40
+ size?: number;
41
+ className?: string;
42
+ }): react_jsx_runtime.JSX.Element;
43
+
44
+ declare const AI_TOOL_LOGOS: {
45
+ readonly claude: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAMAAABF0y+mAAAAJFBMVEVHcEzZd1fZd1fZd1fZd1fad1jZd1fZd1fZd1fZd1fZd1fZd1deZDooAAAADHRSTlMA//F3mhLfyjpWsiMDGU5mAAABH0lEQVQokXVSWXbEIAzDuw33v28FJCnpTP3BA6+yRGvbLK39a0F9RUvHZ5CIazZwkm+VpCi1nZP1GpJEnq2NdabzU594N0XpzInRhq/7jvm8wsOjFfVmcQG4guTWZKYL8HSiA1XFHDjgHMqCpKfpNPgIXiZVVvSJ9yazOJARxBiYf/ZMoIUxrYGjRHs/di2nbdzDZxIb1maPriold3QlyFJCAonMd08A7/WhkN19PWDolSeiXU7URWPm8S3ewMCuvGpB+kigVXvWZKlgIVycF0Hjl6DIoVRCGKz9pE8W0QKXkgkIEmjzUDuh11TSuVkn348DLHs1Y7/kzTi+ksX8GLn0wBRrdvCQS949C43fstj6FhfM8Unfqqwv3gf3+/kDMJgHC0kwnjEAAAAASUVORK5CYII=";
46
+ readonly copilot: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjgiIGhlaWdodD0iMjgiIHZpZXdCb3g9IjAgMCAyOCAyOCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMjgiIGhlaWdodD0iMjgiIHJ4PSI2IiBmaWxsPSIjMWYxZjFmIi8+PHBhdGggZD0iTTE0IDVjLTQuOTcgMC05IDQuMDMtOSA5IDAgMy45NyAyLjU2IDcuMzQgNi4xMiA4LjUzLjQ1LjA4LjYxLS4xOS42MS0uNDN2LTEuNjdjLTIuNDkuNTQtMy4wMS0xLjA2LTMuMDEtMS4wNi0uNDEtMS4wNC0uOTktMS4zMS0uOTktMS4zMS0uODEtLjU2LjA2LS41NC4wNi0uNTQuOS4wNiAxLjM3LjkyIDEuMzcuOTIuOCAxLjM3IDIuMDkuOTggMi42Ljc0LjA4LS41OC4zMS0uOTguNTctMS4yLTEuOTktLjIzLTQuMDgtLjk5LTQuMDgtNC40MiAwLS45OC4zNS0xLjc4LjkyLTIuNDEtLjA5LS4yMy0uNC0xLjE0LjA5LTIuMzcgMCAwIC43NS0uMjQgMi40Ni45Mi43MS0uMiAxLjQ4LS4zIDIuMjQtLjNzMS41My4xIDIuMjQuMzFjMS43MS0xLjE2IDIuNDYtLjkyIDIuNDYtLjkyLjQ5IDEuMjMuMTggMi4xNC4wOSAyLjM3LjU3LjYzLjkyIDEuNDMuOTIgMi40MSAwIDMuNDQtMi4xIDQuMTktNC4wOSA0LjQxLjMyLjI4LjYxLjgyLjYxIDEuNjZ2Mi40NmMwIC4yNC4xNi41MS42MS40M0MxOS40NCAyMS4zNCAyMiAxOC4wMyAyMiAxNGMwLTQuOTctNC4wMy05LTktOVoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=";
47
+ readonly codex: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAP1BMVEVHcEwAgPgAgPgAgPcAgPcAgPcAgPcAgPcAgPcAgPcAd/dzsvq+2/2Kvvtfpvru+P/Z6/77/v83lvmnzfwbjPhuMd/TAAAACnRSTlMAF0adyun/9k+LLZxzywAAAXZJREFUeAFkUlmWwyAMC03qZITxAtz/rPNiaLpEvwhJCC1vpMe6PYn2bT3Sckf6e9KF55pux/SDvy9K2uiG7YNx7BQAgDdjP677r/PMXOhN2tOXPkSN2byUkis+XV75vBFA7mqugpE0BKY+M0DNuQIoXgbjlFinv1Zk0wxUAppeEin66ebe4Q2o7J6pq4zG0nLEfTPRDhUUNSlu3fKQeAwH0V5PQlPV1kHFfcZcl20GPAnuuWe1DIjx7HPZw+EkEOJ1cDcBtCBCLBGhGVVlimTQ3FxQbHgEgaoLuoVx6FiG+CQ8h4RWUFYVdHYhy8iDsEfI6IEjvTlrEJgxQq7DQ8W0kbgKgiAu85mPQYiiPZo+LdRnUcesGsZAzxVozp2MBa+q5293bx2gs2kgK2hgvb4b4mpsWgggbS9C+hgMcmtFrRT2ck37e9IAajHjjJ9hz9FO0n201+wn7rP/H76MQzjrIZQwI2deTqz5m4OZhR0oycLMhCQNACpMHlEZrAKTAAAAAElFTkSuQmCC";
48
+ readonly gemini: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEMklEQVR4Ab2XA5AkSRSGv5ddXb095t2tbdu2bW/wbNsXONuBs23bttY2p2e7Kt/1VNQZ3cMv4o9U46+XrxJCSIvLduTv0ezjPTGzfaGNCk5KWAEVyMVSrKFQSsJ6UUolWAp9j5i3j2hK7sG9uMl9Ke0NtQ8nuS+ZKn+IeAceSLj2qtZ3X7sHQACaXLC3434n/rQvNLWiSNk21CZR0ZQIFEUprJDalIKSgoo6QTuo1/PKiHr7A7nJoCQalnG/jPriB2ZSfSv3+zKh+ZO3fCfBk/t5n1uhaeTn54m9dw1m70Zqg/r1sjiySSvG5uXgeGUrdyTzuslhF5Sf70Ui5wR//tIZgFKbCHBxq/aMy42jas8xKmY2Cm7qyUGpbRS4fu1KrHEwyGyjmNbmwFZk30bqivXlCbZ6igptDYqD71HXJDCAcY0Aki5ssRwQoSaxxglkhPSUtxrJzvn3kGwzGsRQE6hUGIhiUJA0uScKfkkbdk+4DH/xA7jtJyHGqXYEfBPNLAKCIApqYU9hcxhzDvWXPEhp5xkYx62qgTACpI9AZNsPODtXYxQ8YLsY9uQ1oHDYyfRNGWnTfR7RaLzyBsTBiJKWyJZvyL97FrnPnU506w8kVCpMBNqXXUrzgUcxc8kD9O+1hHgsNzMDEiYhgJABanF/fIGCexeQ/8TxJDZ/zTYxbAuNHIgX0KXPCo5bfC9Tey8mN5aTJgIRbJgDlUMVd+Ub5N+3DH3kSHas/4RtSEphRNwc+vVcQq8WA9NEIBpEwAlzoEqYtR9QntL6+p2xvZYSa9qPGBAzDuVOFv+HBkkoGFGqTXLjl6x95gx+/PqJ33MjIZLRQuRQTTQaJ9F5JvHuC7DZRWxTHxdDAkmbhL4x4RRQeTSWS3nnuZR1m4+XVUBClBiWmFaUcMD6GUQgEk6BkjEaLyTZ5yj2L3yaRJ8j0HqF4fogbMewZct3fPHM6az6+vGM1gFHEDIi+xD8zkvw2s/ARuNgFBOatwjuuo+IfXgH+9e8V6l1wCETGg3CjrgCdaKIgCgYCxjFWf0O7se342z8rEq7oSMKmm4zipdgxP3jg9ZiVr+C89ntmG3fVWs3dADSToOCUVDfx6x6FueLO2HXL9XcDUMDkkkO2oPww0PI13cie9fX6IHEQSGdCf3lmUBVI815wICHONQ1ESdeYeKgEfRHiZdCTn3qitLcQ8nJLsEz7vdG4AEQpOdxgFDbiAhT+iwlmAJxHzT5yd1XirCKZmNh2GWQ04DaIj+vPvPGnEOXFsPwJbqyrLDgKgHocPreDgec7KctNFNRNLE1vJwSyIZlMMbf+gj7hd+VE15iK1QQ1kuMQ8N4YXCjzrfeSrUHxs85u8X3Qkir8zTPet7xvjGzFW3jG4kqYP9uICj/3h+OhX0xlGJseIUPhSZT7e+LsA/4ZVx9zHnFewB+BQL7BcuXk7EZAAAAAElFTkSuQmCC";
49
+ readonly opencode: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACshmLzAAABl0lEQVRYCe1XS2rDMBAd/70xBJoubJqVF83Sm+YooVcIPUDJTUpOUHIa71Ov0ht4Y/yJ6zEYHFnyZBKKNx4IkTSjNw/pzQhrT4tFDROaPmHuNvVMYPITMCkNVFVFhYz6DcMY9SsJ1HUNmqbB1+EAYRiOgqicSZLAx24HHZYsTkmgC46iCF7X627K+vc8j4wnNVAUBQmiCrhlL3kCIjilCerORTwWgTzP4X27hd/zGcRESOxltYLv4xFs2xbzKOcsAiimn9MJUFymeb21LEvIsqwVnDKbxHGNIgkQl8ymrDC5SADj0Mc1NgGjSW5Z1oAAliz6uMbaoes6vG027V3LNOD7PmAMx1gEENhxHHBdVypC9HGNTQCF2P36yWRrfb9qzDsvFcoD6zMBtgaw48nasWqduh0WAaz1IAjAalqtIZRbdbnA83LZPuFU0r6fRQC73+d+398/GP97H+AmGDAUFsgqwLZ7r92yl7yCOI4hTdO7OOCrSZlGfRnJFE+B9v3im9H34Zg8AQpABOTOSQ1wAbnxM4HJT+APfgFr0DSNhC0AAAAASUVORK5CYII=";
50
+ };
51
+ type AiToolKey = 'claude' | 'gemini' | 'codex' | 'copilot' | 'opencode';
52
+ declare const AI_TOOL_NAMES: Record<AiToolKey, string>;
53
+ declare function AiToolIcon({ tool, size, showName, className, style }: {
54
+ tool: string;
55
+ size?: number;
56
+ showName?: boolean;
57
+ className?: string;
58
+ style?: React.CSSProperties;
59
+ }): react_jsx_runtime.JSX.Element | null;
60
+
61
+ interface TooltipContent {
62
+ title?: string;
63
+ /** Description can be a string or React node for rich content with icons/colors */
64
+ description: string | ReactNode;
65
+ extra?: string;
66
+ }
67
+ type TooltipPosition = 'top' | 'bottom' | 'left' | 'right' | 'auto';
68
+ type TooltipAlign = 'start' | 'center' | 'end';
69
+ interface TooltipProps {
70
+ children: ReactNode;
71
+ /** Tooltip content with required title and description */
72
+ content: TooltipContent;
73
+ position?: TooltipPosition;
74
+ align?: TooltipAlign;
75
+ /** Allow multi-line content (disables whitespace-nowrap) */
76
+ multiline?: boolean;
77
+ /** Maximum width for multiline tooltips (number for px, string for CSS value, default '80vw') */
78
+ maxWidth?: number | string;
79
+ /** Maximum height for scrollable tooltips (only when interactive) */
80
+ maxHeight?: number;
81
+ /** Allow hovering into the tooltip and scrolling its content */
82
+ interactive?: boolean;
83
+ /** Trigger mode: 'hover' (default) or 'click' (toggle on click, dismiss on click-outside) */
84
+ trigger?: 'hover' | 'click';
85
+ /** Additional classes for the wrapper element (e.g., 'h-full' for flex containers) */
86
+ wrapperClassName?: string;
87
+ }
88
+ /**
89
+ * Portal-based tooltip that renders at document body level.
90
+ * This ensures tooltips always appear above all other elements,
91
+ * regardless of parent overflow or z-index settings.
92
+ */
93
+ declare function Tooltip({ children, content, position, align, multiline, maxWidth, maxHeight, trigger, interactive, wrapperClassName, }: TooltipProps): react_jsx_runtime.JSX.Element;
94
+ /**
95
+ * Simple tooltip wrapper for icon buttons.
96
+ * Provides consistent styling for action button tooltips.
97
+ */
98
+ declare function TooltipButton({ children, content, onClick, className, disabled, }: {
99
+ children: ReactNode;
100
+ content: TooltipContent;
101
+ onClick?: () => void;
102
+ className?: string;
103
+ disabled?: boolean;
104
+ }): react_jsx_runtime.JSX.Element;
105
+
106
+ declare const iconMap: {
107
+ readonly 'arrow-down-to-line': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
108
+ readonly 'arrow-left': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
109
+ readonly 'arrow-right': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
110
+ readonly 'arrow-up': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
111
+ readonly 'arrow-down': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
112
+ readonly 'chevron-left': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
113
+ readonly 'chevron-right': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
114
+ readonly 'chevron-up': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
115
+ readonly 'chevron-down': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
116
+ readonly 'chevrons-up-down': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
117
+ readonly 'chevrons-down-up': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
118
+ readonly check: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
119
+ readonly x: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
120
+ readonly plus: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
121
+ readonly minus: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
122
+ readonly pencil: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
123
+ readonly trash: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
124
+ readonly copy: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
125
+ readonly save: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
126
+ readonly refresh: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
127
+ readonly rotate: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
128
+ readonly undo: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
129
+ readonly redo: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
130
+ readonly search: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
131
+ readonly filter: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
132
+ readonly download: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
133
+ readonly upload: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
134
+ readonly 'external-link': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
135
+ readonly link: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
136
+ readonly unlink: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
137
+ readonly eye: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
138
+ readonly 'eye-off': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
139
+ readonly lock: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
140
+ readonly unlock: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
141
+ readonly settings: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
142
+ readonly 'more-h': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
143
+ readonly 'more-v': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
144
+ readonly loader: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
145
+ readonly 'check-circle': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
146
+ readonly 'alert-triangle': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
147
+ readonly 'x-circle': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
148
+ readonly info: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
149
+ readonly help: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
150
+ readonly user: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
151
+ readonly users: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
152
+ readonly folder: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
153
+ readonly file: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
154
+ readonly 'file-text': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
155
+ readonly image: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
156
+ readonly code: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
157
+ readonly terminal: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
158
+ readonly star: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
159
+ readonly heart: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
160
+ readonly bell: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
161
+ readonly bookmark: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
162
+ readonly tag: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
163
+ readonly pin: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
164
+ readonly mail: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
165
+ readonly send: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
166
+ readonly globe: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
167
+ readonly database: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
168
+ readonly cloud: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
169
+ readonly wand: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
170
+ readonly shield: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
171
+ readonly 'shield-check': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
172
+ readonly zap: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
173
+ readonly sparkles: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
174
+ readonly play: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
175
+ readonly pause: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
176
+ readonly stop: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
177
+ readonly 'stop-circle': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
178
+ readonly 'circle-play': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
179
+ readonly scan: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
180
+ readonly menu: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
181
+ readonly grip: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
182
+ readonly maximize: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
183
+ readonly minimize: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
184
+ readonly webhook: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
185
+ readonly bot: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
186
+ readonly puzzle: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
187
+ readonly plug: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
188
+ readonly 'panel-bottom-close': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
189
+ readonly package: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
190
+ readonly wrench: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
191
+ readonly store: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
192
+ readonly 'scroll-text': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
193
+ readonly cpu: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
194
+ readonly 'flask-conical': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
195
+ readonly layers: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
196
+ readonly timer: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
197
+ readonly camera: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
198
+ readonly 'alert-circle': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
199
+ readonly 'file-code': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
200
+ readonly gauge: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
201
+ readonly home: react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
202
+ readonly 'pie-chart': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
203
+ readonly 'settings-2': react.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & react.RefAttributes<SVGSVGElement>>;
204
+ };
205
+ type IconName = keyof typeof iconMap;
206
+ interface ActionItem {
207
+ icon: IconName;
208
+ onClick: () => void;
209
+ color?: IconButtonColor;
210
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
211
+ variant?: IconButtonVariant;
212
+ tooltip?: TooltipContent;
213
+ disabled?: boolean;
214
+ status?: IconButtonStatus;
215
+ active?: boolean;
216
+ href?: string;
217
+ testId?: string;
218
+ }
219
+ type IconButtonStatus = 'loading' | 'success' | 'warning' | 'error';
220
+ type IconButtonColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky';
221
+ type IconButtonVariant = 'filled' | 'outline';
222
+ interface IconButtonProps {
223
+ icon: IconName | ReactNode;
224
+ onClick?: (e?: MouseEvent) => void;
225
+ /** When provided, renders an <a> tag instead of <button>. Opens in a new tab. */
226
+ href?: string;
227
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
228
+ color?: IconButtonColor;
229
+ variant?: IconButtonVariant;
230
+ active?: boolean;
231
+ disabled?: boolean;
232
+ /** Async action status. Overrides icon, color, and active state when set. */
233
+ status?: IconButtonStatus;
234
+ /** Tooltip shown on hover. Title and description are required. */
235
+ tooltip?: TooltipContent;
236
+ tooltipPosition?: 'bottom' | 'bottom-left' | 'left' | 'right' | 'top' | 'top-left' | 'top-right';
237
+ badge?: number | string;
238
+ badgeColor?: 'red' | 'blue' | 'green' | 'orange';
239
+ strikethrough?: boolean;
240
+ className?: string;
241
+ /** Test ID for E2E testing */
242
+ testId?: string;
243
+ }
244
+ declare function IconButton({ icon, onClick, href, size, color, variant, active, disabled, status, tooltip, tooltipPosition, badge, badgeColor, strikethrough, className, testId, }: IconButtonProps): react_jsx_runtime.JSX.Element;
245
+ interface CollapseButtonProps {
246
+ collapsed: boolean;
247
+ onToggle: () => void;
248
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
249
+ tooltipPosition?: 'bottom' | 'bottom-left' | 'left' | 'right' | 'top' | 'top-left' | 'top-right';
250
+ }
251
+ declare function CollapseButton({ collapsed, onToggle, size, tooltipPosition }: CollapseButtonProps): react_jsx_runtime.JSX.Element;
252
+
253
+ type LabelColor = 'neutral' | 'green' | 'red' | 'blue' | 'yellow' | 'orange' | 'purple' | 'amber' | 'emerald' | 'cyan' | 'indigo' | 'teal' | 'violet' | 'pink';
254
+ interface LabelProps {
255
+ text: string;
256
+ color: LabelColor;
257
+ /** Leading icon(s). Pass a single name or an array for multiple icons before text. */
258
+ icon?: IconName | IconName[];
259
+ /** Custom icon component. Takes precedence over icon. */
260
+ IconComponent?: React.ComponentType<{
261
+ className?: string;
262
+ }>;
263
+ tooltip: {
264
+ title?: string;
265
+ description: string;
266
+ };
267
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
268
+ textTransform?: 'capitalize' | 'lowercase' | 'uppercase';
269
+ onClick?: () => void;
270
+ className?: string;
271
+ testId?: string;
272
+ }
273
+ declare function Label({ text, color, icon, IconComponent: CustomIcon, tooltip, size, textTransform, onClick, className, testId, }: LabelProps): react_jsx_runtime.JSX.Element;
274
+
275
+ /**
276
+ * Badge - Outline-styled pill badge for displaying counts or short labels
277
+ *
278
+ * Used by:
279
+ * - TabBar, BottomPanelHeader - tab count badges
280
+ * - NavCard - card count badges
281
+ * - Any UI that needs a small inline indicator
282
+ *
283
+ * Features:
284
+ * - Outline variant matching IconButton outline style (border + text, no fill)
285
+ * - Accepts numbers (auto-caps at 99+) or short strings ("New")
286
+ * - 13 color variants
287
+ * - 5 size variants (xss, xs, sm, md, lg)
288
+ */
289
+ type BadgeColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky';
290
+ interface BadgeProps {
291
+ value: number | string;
292
+ color?: BadgeColor;
293
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
294
+ className?: string;
295
+ testId?: string;
296
+ }
297
+ declare function Badge({ value, color, size, className, testId, }: BadgeProps): react_jsx_runtime.JSX.Element;
298
+
299
+ /**
300
+ * ConfirmBadge - Outline-styled check badge for indicating selection/confirmation
301
+ *
302
+ * Used by:
303
+ * - SelectionGrid - selected state indicator on cards
304
+ * - Any UI that needs a small check/confirmed indicator
305
+ *
306
+ * Features:
307
+ * - Outline variant matching IconButton outline style (border + text, no fill)
308
+ * - 13 color variants
309
+ * - 5 size variants (xss, xs, sm, md, lg)
310
+ */
311
+ type ConfirmBadgeColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky';
312
+ interface ConfirmBadgeProps {
313
+ color?: ConfirmBadgeColor;
314
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
315
+ className?: string;
316
+ testId?: string;
317
+ }
318
+ declare function ConfirmBadge({ color, size, className, testId, }: ConfirmBadgeProps): react_jsx_runtime.JSX.Element;
319
+
320
+ /**
321
+ * Checkbox - Controlled checkbox input with check icon
322
+ *
323
+ * Used by:
324
+ * - Settings forms - boolean preference toggles
325
+ * - Filter panels - multi-select filters
326
+ * - List items - selection state
327
+ */
328
+ type CheckboxSize = 'xss' | 'xs' | 'sm' | 'md' | 'lg';
329
+ type CheckboxColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky' | 'pink' | 'teal';
330
+ type CheckboxVariant = 'outline' | 'filled';
331
+ interface CheckboxProps {
332
+ checked: boolean;
333
+ onChange: (checked: boolean) => void;
334
+ disabled?: boolean;
335
+ size?: CheckboxSize;
336
+ color?: CheckboxColor;
337
+ variant?: CheckboxVariant;
338
+ className?: string;
339
+ /** Test ID for E2E testing */
340
+ testId?: string;
341
+ }
342
+ declare function Checkbox({ checked, onChange, disabled, size, color, variant, className, testId, }: CheckboxProps): react_jsx_runtime.JSX.Element;
343
+
344
+ /**
345
+ * Toggle - iOS-style switch toggle
346
+ *
347
+ * Used by:
348
+ * - Settings pages - boolean preferences
349
+ * - Feature flags - enable/disable features
350
+ * - List items - inline toggle controls
351
+ */
352
+ type ToggleColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky' | 'pink' | 'teal';
353
+ type ToggleSize = 'xss' | 'xs' | 'sm' | 'md' | 'lg';
354
+ type ToggleVariant = 'outline' | 'filled';
355
+ interface ToggleProps {
356
+ checked: boolean;
357
+ onChange: (checked: boolean) => void;
358
+ disabled?: boolean;
359
+ size?: ToggleSize;
360
+ className?: string;
361
+ color?: ToggleColor;
362
+ variant?: ToggleVariant;
363
+ /** Test ID for E2E testing */
364
+ testId?: string;
365
+ }
366
+ declare function Toggle({ checked, onChange, disabled, size, className, color, testId, }: ToggleProps): react_jsx_runtime.JSX.Element;
367
+
368
+ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'size' | 'type'> {
369
+ value: string;
370
+ onChange: (value: string) => void;
371
+ type?: 'text' | 'search' | 'password';
372
+ debounceMs?: number;
373
+ error?: boolean | string;
374
+ variant?: 'filled' | 'outline';
375
+ color?: FormColor;
376
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
377
+ mono?: boolean;
378
+ /** Test ID for E2E testing */
379
+ testId?: string;
380
+ /** Element rendered inside the input (right side), visible on hover/focus. Use IconButton size="xss". */
381
+ actionSlot?: ReactNode;
382
+ }
383
+ declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
384
+
385
+ interface NumberInputProps {
386
+ value: number;
387
+ onChange: (value: number) => void;
388
+ min?: number;
389
+ max?: number;
390
+ step?: number;
391
+ variant?: 'filled' | 'outline';
392
+ color?: FormColor;
393
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
394
+ disabled?: boolean;
395
+ className?: string;
396
+ }
397
+ declare function NumberInput({ value, onChange, min, max, step, variant, color, size, disabled, className, }: NumberInputProps): react_jsx_runtime.JSX.Element;
398
+
399
+ type ScopeType = 'user' | 'project' | 'local' | 'read-only';
400
+ interface ScopeBadgeProps {
401
+ scope: ScopeType;
402
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
403
+ }
404
+ declare function ScopeBadge({ scope, size }: ScopeBadgeProps): react_jsx_runtime.JSX.Element;
405
+
406
+ interface SegmentedToggleOption<T extends string> {
407
+ value: T;
408
+ icon: ReactNode;
409
+ tooltip: TooltipContent;
410
+ }
411
+ interface SegmentedToggleProps<T extends string> {
412
+ options: SegmentedToggleOption<T>[];
413
+ value: T;
414
+ onChange: (value: T) => void;
415
+ accentColor?: 'blue' | 'purple' | 'orange' | 'green' | 'pink' | 'amber' | 'emerald' | 'teal' | 'sky';
416
+ /** Visual style: 'filled' (default) has a container background, 'outline' is transparent */
417
+ variant?: 'filled' | 'outline';
418
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
419
+ tooltipPosition?: TooltipPosition;
420
+ testId?: string;
421
+ disabled?: boolean;
422
+ /** Tooltip shown on the entire toggle when disabled */
423
+ disabledTooltip?: TooltipContent;
424
+ }
425
+ declare function SegmentedToggle<T extends string>({ options, value, onChange, accentColor, variant, size, tooltipPosition, testId, disabled, disabledTooltip, }: SegmentedToggleProps<T>): react_jsx_runtime.JSX.Element;
426
+
427
+ interface ResizableTextareaBaseProps {
428
+ wrapperClassName?: string;
429
+ resizable?: boolean;
430
+ variant?: 'filled' | 'outline';
431
+ color?: FormColor;
432
+ }
433
+ interface ResizableTextareaFieldProps extends ResizableTextareaBaseProps, Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'color'> {
434
+ mode?: never;
435
+ language?: never;
436
+ children?: never;
437
+ minHeight?: never;
438
+ onHeightChange?: never;
439
+ }
440
+ interface ResizableTextareaCodeProps extends ResizableTextareaBaseProps {
441
+ mode: 'code';
442
+ language?: string;
443
+ value?: string;
444
+ onChange?: (value: string) => void;
445
+ readOnly?: boolean;
446
+ minHeight?: number;
447
+ onHeightChange?: (height: number) => void;
448
+ children?: never;
449
+ }
450
+ interface ResizableTextareaChildrenProps extends ResizableTextareaBaseProps {
451
+ mode?: never;
452
+ language?: never;
453
+ children: React.ReactNode;
454
+ minHeight?: number;
455
+ onHeightChange?: (height: number) => void;
456
+ }
457
+ type ResizableTextareaProps = ResizableTextareaFieldProps | ResizableTextareaCodeProps | ResizableTextareaChildrenProps;
458
+ declare function ResizableTextarea(props: ResizableTextareaProps): react_jsx_runtime.JSX.Element;
459
+
460
+ interface SelectOption<T extends string | number = string> {
461
+ value: T;
462
+ label: string;
463
+ icon?: ReactNode;
464
+ }
465
+ interface SelectProps<T extends string | number = string> {
466
+ value: T;
467
+ options: SelectOption<T>[];
468
+ onChange: (value: T) => void;
469
+ placeholder?: string;
470
+ variant?: 'filled' | 'outline';
471
+ color?: FormColor;
472
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
473
+ align?: 'left' | 'right';
474
+ disabled?: boolean;
475
+ className?: string;
476
+ }
477
+ declare function Select<T extends string | number = string>({ value, options, onChange, placeholder, variant, color, size, align, disabled, className, }: SelectProps<T>): react_jsx_runtime.JSX.Element;
478
+
479
+ interface FilterDropdownProps {
480
+ value: string;
481
+ onChange: (value: string) => void;
482
+ options: {
483
+ value: string;
484
+ label: string;
485
+ }[];
486
+ allLabel: string;
487
+ labelExtra?: ReactNode;
488
+ clearable?: boolean;
489
+ variant?: 'filled' | 'outline';
490
+ color?: FormColor;
491
+ }
492
+ declare function FilterDropdown({ value, onChange, options, allLabel, labelExtra, clearable, variant, color, }: FilterDropdownProps): react_jsx_runtime.JSX.Element;
493
+
494
+ interface SortField {
495
+ value: string;
496
+ label: string;
497
+ /** Label suffix when ascending (default: "↑") */
498
+ ascLabel?: string;
499
+ /** Label suffix when descending (default: "↓") */
500
+ descLabel?: string;
501
+ }
502
+ interface SortDropdownProps {
503
+ field: string;
504
+ ascending: boolean;
505
+ onFieldChange: (field: string) => void;
506
+ onToggleDirection: () => void;
507
+ fields: SortField[];
508
+ variant?: 'filled' | 'outline';
509
+ color?: FormColor;
510
+ }
511
+ declare function SortDropdown({ field, ascending, onFieldChange, onToggleDirection, fields, variant, color, }: SortDropdownProps): react_jsx_runtime.JSX.Element;
512
+
513
+ interface FormActionsProps {
514
+ /** Cancel handler — renders X button. Optional (e.g. AlertModal has no cancel). */
515
+ onCancel?: () => void;
516
+ cancelTooltip?: string;
517
+ /** Back handler — optional, renders left-arrow on the left side */
518
+ onBack?: () => void;
519
+ backTooltip?: string;
520
+ /** Minimize handler — optional, renders minimize icon before Cancel */
521
+ onMinimize?: () => void;
522
+ minimizeTooltip?: string;
523
+ /** Confirm handler — optional, renders between Cancel and Next */
524
+ onConfirm?: () => void;
525
+ confirmTooltip?: string;
526
+ confirmIcon?: IconName;
527
+ confirmColor?: IconButtonProps['color'];
528
+ confirmDisabled?: boolean;
529
+ confirmStatus?: IconButtonStatus;
530
+ /** Next handler — optional, renders right-arrow for wizard navigation */
531
+ onNext?: () => void;
532
+ nextTooltip?: string;
533
+ /** Status text shown on the left side of the footer */
534
+ statusText?: string;
535
+ border?: boolean;
536
+ padding?: 'compact' | 'normal' | 'modal';
537
+ }
538
+ declare function FormActions({ onCancel, cancelTooltip, onBack, backTooltip, onMinimize, minimizeTooltip, onConfirm, confirmTooltip, confirmIcon, confirmColor, confirmDisabled, confirmStatus, onNext, nextTooltip, statusText, border, padding, }: FormActionsProps): react_jsx_runtime.JSX.Element;
539
+
540
+ type ModalKind = 'info' | 'warning' | 'error' | 'orange' | 'success';
541
+ type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
542
+ interface ConfirmModalProps {
543
+ isOpen: boolean;
544
+ onClose: () => void;
545
+ onConfirm: () => void | Promise<void>;
546
+ title: string;
547
+ message: string;
548
+ warning?: string;
549
+ warningItems?: string[];
550
+ kind?: ModalKind;
551
+ confirmColor?: 'red' | 'blue' | 'orange' | 'yellow';
552
+ isLoading?: boolean;
553
+ confirmDisabled?: boolean;
554
+ }
555
+ declare function ConfirmModal({ isOpen, onClose, onConfirm, title, message, warning, warningItems, kind, confirmColor, isLoading, confirmDisabled, }: ConfirmModalProps): react_jsx_runtime.JSX.Element;
556
+ interface AlertModalProps {
557
+ isOpen: boolean;
558
+ onClose: () => void;
559
+ title: string;
560
+ message: string;
561
+ kind?: ModalKind;
562
+ }
563
+ declare function AlertModal({ isOpen, onClose, title, message, kind, }: AlertModalProps): react_jsx_runtime.JSX.Element;
564
+
565
+ type IconProps = {
566
+ className?: string;
567
+ style?: React.CSSProperties;
568
+ };
569
+ type CodingToolId = 'claude-code' | 'github-copilot' | 'codex-cli' | 'gemini-cli' | 'opencode';
570
+ type CodingToolPresetConfig = CodingToolId | {
571
+ id: CodingToolId;
572
+ description?: string;
573
+ disabled?: boolean;
574
+ };
575
+ interface SelectionCardItem {
576
+ id: string;
577
+ icon?: IconName;
578
+ /** Custom SVG icon component. Receives className and style. Takes precedence over `icon`. */
579
+ IconComponent?: React.ComponentType<IconProps>;
580
+ name: string;
581
+ description?: string;
582
+ /** Accent color for selected state border/bg. CSS color string like '#a78bfa' */
583
+ color?: string;
584
+ /** Named color for the confirm badge. Defaults to 'blue'. */
585
+ badgeColor?: ConfirmBadgeColor;
586
+ disabled?: boolean;
587
+ }
588
+ interface SelectionGridProps {
589
+ /** Custom items with manual icon/name/color configuration */
590
+ items?: SelectionCardItem[];
591
+ /** Built-in coding tool presets. Pass tool IDs or config objects. Ignored when `items` is provided. */
592
+ presets?: CodingToolPresetConfig[];
593
+ selectedIds: string[];
594
+ onSelect: (ids: string[]) => void;
595
+ /** Single selection or multiple */
596
+ mode?: 'single' | 'multiple';
597
+ /** Grid (icon-top cards) or list (icon-left rows) */
598
+ layout?: 'grid' | 'list';
599
+ /** Number of columns for grid layout (auto if not set) */
600
+ columns?: number;
601
+ className?: string;
602
+ }
603
+ declare function SelectionGrid({ items: itemsProp, presets, selectedIds, onSelect, mode, layout, columns, className, }: SelectionGridProps): react_jsx_runtime.JSX.Element;
604
+
605
+ /**
606
+ * ExecutionDetailsPanel - Shows AI execution configuration before running actions
607
+ *
608
+ * Displays tool, permissions, output format, CLI flags, and change handling.
609
+ * Optional "Allow direct edits" toggle with warning message.
610
+ * Used inside ActionDialog as the mandatory execution details section.
611
+ */
612
+ interface ExecutionDetailRow {
613
+ label: string;
614
+ value: string;
615
+ mono?: boolean;
616
+ }
617
+ interface ExecutionDetailsPanelProps {
618
+ details: ExecutionDetailRow[];
619
+ /** Show the "Allow direct edits" toggle */
620
+ allowDirectEdits?: boolean;
621
+ onAllowDirectEditsChange?: (value: boolean) => void;
622
+ /** Warning message shown below the toggle */
623
+ warningMessage?: string;
624
+ className?: string;
625
+ }
626
+ declare function ExecutionDetailsPanel({ details, allowDirectEdits, onAllowDirectEditsChange, warningMessage, className, }: ExecutionDetailsPanelProps): react_jsx_runtime.JSX.Element;
627
+
628
+ interface ActionDialogProps {
629
+ /** Dialog title */
630
+ title: string;
631
+ /** Subtitle text next to title */
632
+ subtitle?: string;
633
+ /** Icon displayed before title */
634
+ icon?: IconName;
635
+ /** Icon color */
636
+ iconColor?: string;
637
+ /** Settings gear button callback */
638
+ onSettings?: () => void;
639
+ /** Cancel/close callback */
640
+ onCancel?: () => void;
641
+ /** Submit/action callback */
642
+ onSubmit?: () => void;
643
+ /** Submit button label (shown in tooltip) */
644
+ submitLabel?: string;
645
+ /** Submit button icon */
646
+ submitIcon?: IconName;
647
+ /** Submit button color variant */
648
+ submitColor?: string;
649
+ /** Disable submit button */
650
+ submitDisabled?: boolean;
651
+ /** Status text shown in footer left */
652
+ statusText?: string;
653
+ /** Label above the selection grid (e.g. "AI Tool:") */
654
+ selectionLabel?: string;
655
+ /** Custom selection items - renders SelectionGrid when provided */
656
+ items?: SelectionCardItem[];
657
+ /** Built-in AI tool presets. Ignored when `items` is provided. */
658
+ presets?: CodingToolPresetConfig[];
659
+ /** Currently selected item IDs */
660
+ selectedIds?: string[];
661
+ /** Selection change handler */
662
+ onSelect?: (ids: string[]) => void;
663
+ /** Single or multiple selection */
664
+ selectionMode?: 'single' | 'multiple';
665
+ /** Grid (icon-top cards) or list (icon-left rows) */
666
+ selectionLayout?: 'grid' | 'list';
667
+ /** Grid column count (auto if not set) */
668
+ selectionColumns?: number;
669
+ /** Label above scenarios (e.g. "Select scenarios to run:") */
670
+ scenarioLabel?: string;
671
+ /** Scenario items - renders second SelectionGrid when provided */
672
+ scenarios?: SelectionCardItem[];
673
+ /** Currently selected scenario IDs */
674
+ selectedScenarioIds?: string[];
675
+ /** Scenario selection change handler */
676
+ onSelectScenarios?: (ids: string[]) => void;
677
+ /** Scenario grid layout */
678
+ scenarioLayout?: 'grid' | 'list';
679
+ /** Scenario grid column count */
680
+ scenarioColumns?: number;
681
+ /** Execution detail rows (Tool, Permissions, Output, CLI Flags, Changes) */
682
+ executionDetails: ExecutionDetailRow[];
683
+ /** Whether direct file edits are allowed */
684
+ allowDirectEdits?: boolean;
685
+ /** Callback to toggle direct edits - shows the toggle when provided */
686
+ onAllowDirectEditsChange?: (value: boolean) => void;
687
+ /** Warning message shown in the execution details section */
688
+ executionWarning?: string;
689
+ /** Additional content rendered between scenarios and execution details */
690
+ children?: React.ReactNode;
691
+ /** Additional className */
692
+ className?: string;
693
+ }
694
+ declare function ActionDialog({ title, subtitle, icon, iconColor, onSettings, onCancel, onSubmit, submitLabel, submitIcon, submitColor, submitDisabled, statusText, selectionLabel, items, presets, selectedIds, onSelect, selectionMode, selectionLayout, selectionColumns, scenarioLabel, scenarios, selectedScenarioIds, onSelectScenarios, scenarioLayout, scenarioColumns, executionDetails, allowDirectEdits, onAllowDirectEditsChange, executionWarning, children, className, }: ActionDialogProps): react.ReactPortal;
695
+
696
+ interface SettingRowBase {
697
+ label: string;
698
+ description?: string;
699
+ disabled?: boolean;
700
+ className?: string;
701
+ }
702
+ interface SettingRowToggle extends SettingRowBase {
703
+ type: 'toggle';
704
+ checked: boolean;
705
+ onChange: (checked: boolean) => void;
706
+ color?: ToggleColor;
707
+ size?: ToggleSize;
708
+ variant?: ToggleVariant;
709
+ }
710
+ interface SettingRowSelect extends SettingRowBase {
711
+ type: 'select';
712
+ value: string;
713
+ options: SelectOption[];
714
+ onChange: (value: string) => void;
715
+ selectSize?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
716
+ selectVariant?: 'filled' | 'outline';
717
+ }
718
+ interface SettingRowInput extends SettingRowBase {
719
+ type: 'input';
720
+ value: string;
721
+ onChange: (value: string) => void;
722
+ placeholder?: string;
723
+ inputSize?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
724
+ inputVariant?: 'filled' | 'outline';
725
+ }
726
+ type SettingRowProps = SettingRowToggle | SettingRowSelect | SettingRowInput;
727
+ declare function SettingRow(props: SettingRowProps): react_jsx_runtime.JSX.Element;
728
+
729
+ interface FileTreeNode {
730
+ name: string;
731
+ type: 'file' | 'directory';
732
+ children?: FileTreeNode[];
733
+ }
734
+ interface FileTreeProps {
735
+ nodes: FileTreeNode[];
736
+ rootName?: string;
737
+ selectedPath: string | null;
738
+ onSelectFile: (path: string) => void;
739
+ prefix?: string;
740
+ expandedPaths: Set<string>;
741
+ onTogglePath: (path: string) => void;
742
+ accentColor?: string;
743
+ }
744
+ /** Collect all directory paths that would be rendered in the tree */
745
+ declare function collectDirPaths(nodes: FileTreeNode[], rootName?: string, prefix?: string): Set<string>;
746
+ declare function FileTree({ nodes, rootName, selectedPath, onSelectFile, prefix, expandedPaths, onTogglePath, accentColor }: FileTreeProps): react_jsx_runtime.JSX.Element;
747
+
748
+ interface EditorToolbarProps {
749
+ /** Whether content has unsaved changes */
750
+ isDirty: boolean;
751
+ /** Whether save operation is in progress */
752
+ isSaving?: boolean;
753
+ /** Called when save button is clicked */
754
+ onSave: () => void;
755
+ /** Optional: Whether reset is available */
756
+ canReset?: boolean;
757
+ /** Optional: Called when reset button is clicked */
758
+ onReset?: () => void;
759
+ /** Optional: Tooltip for reset button */
760
+ resetTooltip?: {
761
+ title: string;
762
+ description: string;
763
+ };
764
+ /** Optional: Whether editor is read-only */
765
+ isReadOnly?: boolean;
766
+ /** Optional: Validation error preventing save */
767
+ hasError?: boolean;
768
+ /** Optional: Additional action buttons on the left side */
769
+ leftActions?: ActionItem[];
770
+ /** Optional: Additional action buttons on the right side (before save) */
771
+ rightActions?: ActionItem[];
772
+ }
773
+ declare function EditorToolbar({ isDirty, isSaving, onSave, canReset, onReset, resetTooltip, isReadOnly, hasError, leftActions, rightActions, }: EditorToolbarProps): react_jsx_runtime.JSX.Element | null;
774
+
775
+ /** Status banner configuration for outdated/info messages */
776
+ interface StatusBanner {
777
+ /** Message to display */
778
+ message: string;
779
+ /** Banner type affects styling */
780
+ type: 'warning' | 'info';
781
+ /** Optional action button label */
782
+ actionLabel?: string;
783
+ /** Optional action callback */
784
+ onAction?: () => void;
785
+ }
786
+ interface PanelTab<T extends string = string> {
787
+ /** Unique identifier for the tab */
788
+ id: T;
789
+ /** Display label */
790
+ label: string;
791
+ /** Icon name from iconMap */
792
+ icon?: IconName;
793
+ /** Custom icon component (should accept className for sizing) */
794
+ IconComponent?: React.ComponentType<{
795
+ className?: string;
796
+ style?: React.CSSProperties;
797
+ }>;
798
+ /** Optional count badge */
799
+ count?: number;
800
+ /** Color for the count badge */
801
+ countColor?: BadgeColor;
802
+ /** Tailwind classes for active text/border color (e.g., 'text-orange-400') */
803
+ activeTextClass?: string;
804
+ /** Tailwind classes for active border color (e.g., 'border-orange-400'). Defaults to 'border-current' */
805
+ activeBorderClass?: string;
806
+ /** Hide label on small screens */
807
+ hideLabel?: boolean;
808
+ /** Test ID for E2E testing */
809
+ testId?: string;
810
+ }
811
+ interface BottomPanelHeaderProps<T extends string = string> {
812
+ /** Array of tab configurations */
813
+ tabs: PanelTab<T>[];
814
+ /** Currently active tab ID */
815
+ activeTab: T;
816
+ /** Callback when tab changes */
817
+ onTabChange: (tabId: T) => void;
818
+ /** Action buttons to render (right side, before collapse button) */
819
+ actions?: ActionItem[];
820
+ /** Escape hatch: arbitrary ReactNode actions (e.g. AiActionButton) */
821
+ customActions?: ReactNode;
822
+ /** Custom class name for the header container */
823
+ className?: string;
824
+ /** Custom left content to replace tabs (e.g., for "ignored" mode) */
825
+ customLeftContent?: ReactNode;
826
+ /** Optional status banner (e.g., "Results may be outdated") */
827
+ statusBanner?: StatusBanner;
828
+ /** Callback when collapse button is clicked */
829
+ onCollapse?: () => void;
830
+ }
831
+ declare function BottomPanelHeader<T extends string = string>({ tabs, activeTab, onTabChange, actions, customActions, className, customLeftContent, statusBanner, onCollapse, }: BottomPanelHeaderProps<T>): react_jsx_runtime.JSX.Element;
832
+
833
+ interface FrontmatterFormHeaderProps {
834
+ collapsed: boolean;
835
+ onToggle: () => void;
836
+ /** Summary text shown when collapsed */
837
+ renderSummary: () => string;
838
+ children: ReactNode;
839
+ /** Whether frontmatter is currently enabled (content has ---) */
840
+ frontmatterEnabled?: boolean;
841
+ /** Toggle frontmatter on/off */
842
+ onFrontmatterToggle?: (enabled: boolean) => void;
843
+ readOnly?: boolean;
844
+ }
845
+ declare function FrontmatterFormHeader({ collapsed, onToggle, renderSummary, children, frontmatterEnabled, onFrontmatterToggle, readOnly, }: FrontmatterFormHeaderProps): react_jsx_runtime.JSX.Element;
846
+
847
+ interface EditorPlaceholderCardProps {
848
+ /** Placeholder name (without braces) */
849
+ name: string;
850
+ /** Description text */
851
+ description: string;
852
+ /** Value/example content */
853
+ value?: string;
854
+ /** Whether this placeholder is required */
855
+ required?: boolean;
856
+ /** Label for the value section (default: "Value:") */
857
+ valueLabel?: string;
858
+ /** Color scheme */
859
+ accentColor?: 'purple' | 'blue' | 'neutral' | 'sky';
860
+ /** Action buttons to show on the right (e.g., edit/delete for settings) */
861
+ actions?: ActionItem[];
862
+ /** Show copy button that copies the {{PLACEHOLDER}} syntax */
863
+ showCopyPlaceholder?: boolean;
864
+ /** Show copy button that copies the actual value */
865
+ showCopyValue?: boolean;
866
+ /** Hide the value behind ****** with a toggle to reveal */
867
+ hideValue?: boolean;
868
+ /** Additional class names */
869
+ className?: string;
870
+ }
871
+ declare function EditorPlaceholderCard({ name, description, value, required, valueLabel, accentColor, actions, showCopyPlaceholder, showCopyValue, hideValue, className, }: EditorPlaceholderCardProps): react_jsx_runtime.JSX.Element;
872
+
873
+ interface DetailViewWrapperProps {
874
+ /** Main editor content */
875
+ editorContent?: ReactNode;
876
+ /** Action buttons rendered in navigation bar */
877
+ actions?: ReactNode;
878
+ /** Optional bottom panel */
879
+ bottomPanel?: ReactNode;
880
+ /** Optional right sidebar */
881
+ rightSidebar?: ReactNode;
882
+ showRightSidebar?: boolean;
883
+ }
884
+ declare function DetailViewWrapper({ editorContent, actions, bottomPanel, rightSidebar, showRightSidebar, }: DetailViewWrapperProps): react_jsx_runtime.JSX.Element;
885
+
886
+ type RegistryItemType = 'skill' | 'hook' | 'agent' | 'command' | 'plugin' | 'mcp' | 'settings';
887
+ type ExtensionSource = 'project' | 'plugin' | 'user' | 'local';
888
+ declare function formatCategory(category: string): string;
889
+ interface SeedrItemStatus {
890
+ updateAvailable: boolean;
891
+ modified: boolean;
892
+ }
893
+ interface RegistryCardBase {
894
+ onClick: () => void;
895
+ flash?: 'success' | 'error' | 'warning' | null;
896
+ name: string;
897
+ type: string;
898
+ description?: string;
899
+ errorMessage?: string;
900
+ onInstall: () => void;
901
+ isInstalling?: boolean;
902
+ updatedAt?: string;
903
+ onDateClick?: () => void;
904
+ }
905
+ interface SeedrVariant extends RegistryCardBase {
906
+ variant: 'seedr';
907
+ author: string;
908
+ sourceType: string;
909
+ pluginType?: string;
910
+ wrapper?: string;
911
+ installedScopes?: ReadonlySet<ExtensionSource>;
912
+ viewScope?: 'user' | 'project';
913
+ status?: SeedrItemStatus;
914
+ compatibility: string[];
915
+ packageCounts?: Record<string, number>;
916
+ isDisabled?: boolean;
917
+ onActivate?: () => void;
918
+ onRemove?: (scope: ExtensionSource) => void;
919
+ onFilterSource?: () => void;
920
+ onFilterPluginType?: (pluginType: string) => void;
921
+ /** Render scope confirmation modal */
922
+ renderScopeConfirm?: (props: {
923
+ isOpen: boolean;
924
+ onClose: () => void;
925
+ onConfirm: () => void;
926
+ name: string;
927
+ }) => ReactNode;
928
+ }
929
+ interface ClaudePluginsVariant extends RegistryCardBase {
930
+ variant: 'claude-plugins';
931
+ author: string;
932
+ category?: string;
933
+ stars?: number;
934
+ downloads?: number;
935
+ installedScopes?: ReadonlySet<ExtensionSource>;
936
+ viewScope?: 'user' | 'project';
937
+ onRemove?: () => void;
938
+ onSortBy?: (field: string) => void;
939
+ onFilterCategory?: (category: string) => void;
940
+ /** Tool keys compatible with this item type */
941
+ compatibleTools?: string[];
942
+ /** Render scope confirmation modal */
943
+ renderScopeConfirm?: (props: {
944
+ isOpen: boolean;
945
+ onClose: () => void;
946
+ onConfirm: () => void;
947
+ name: string;
948
+ }) => ReactNode;
949
+ }
950
+ interface AitmplVariant extends RegistryCardBase {
951
+ variant: 'aitmpl';
952
+ category: string;
953
+ installedScopes?: ReadonlySet<ExtensionSource>;
954
+ viewScope?: 'user' | 'project';
955
+ onRemove?: () => void;
956
+ onFilterCategory?: (category: string) => void;
957
+ /** Render scope confirmation modal */
958
+ renderScopeConfirm?: (props: {
959
+ isOpen: boolean;
960
+ onClose: () => void;
961
+ onConfirm: () => void;
962
+ name: string;
963
+ }) => ReactNode;
964
+ }
965
+ interface SkillsShVariant extends RegistryCardBase {
966
+ variant: 'skills-sh';
967
+ author: string;
968
+ installs?: number;
969
+ installedScopes?: ReadonlySet<ExtensionSource>;
970
+ viewScope?: 'user' | 'project';
971
+ onRemove?: () => void;
972
+ /** All tool keys to show in bottom row */
973
+ allToolKeys?: string[];
974
+ /** Render scope confirmation modal */
975
+ renderScopeConfirm?: (props: {
976
+ isOpen: boolean;
977
+ onClose: () => void;
978
+ onConfirm: () => void;
979
+ name: string;
980
+ }) => ReactNode;
981
+ }
982
+ type RegistryCardProps = SeedrVariant | ClaudePluginsVariant | AitmplVariant | SkillsShVariant;
983
+ declare function RegistryCard(props: RegistryCardProps): react_jsx_runtime.JSX.Element;
984
+
985
+ type PreviewMode = 'format' | 'language' | 'plain';
986
+ type AccentColor = 'blue' | 'purple' | 'orange' | 'green' | 'pink' | 'amber' | 'emerald' | 'teal' | 'sky';
987
+ interface FileStructureSectionProps {
988
+ files: FileTreeNode[] | null;
989
+ rootName: string;
990
+ isLoading?: boolean;
991
+ error?: string | null;
992
+ onFetchContent: (relativePath: string) => Promise<string>;
993
+ /** Enable the Format option in the mode toggle (renders markdown). */
994
+ format?: boolean;
995
+ /** Enable the Language option in the mode toggle (syntax highlighting). */
996
+ language?: boolean;
997
+ /**
998
+ * Default active mode when multiple options are enabled.
999
+ * Only relevant when both `format` and `language` are true.
1000
+ * Defaults to `'format'` when both are set.
1001
+ */
1002
+ default?: PreviewMode;
1003
+ /** Accent color applied to icons, selected state, and the mode toggle. Defaults to 'blue'. */
1004
+ accentColor?: AccentColor;
1005
+ /** Custom renderer called when mode is 'language'. Receives the resolved language as third arg. */
1006
+ renderPreview?: (content: string, filePath: string, language: string) => ReactNode;
1007
+ }
1008
+ declare function getLanguageFromPath(filePath: string): string;
1009
+ declare function FileStructureSection({ files, rootName, isLoading, error, onFetchContent, format, language, default: defaultMode, accentColor, renderPreview, }: FileStructureSectionProps): react_jsx_runtime.JSX.Element | null;
1010
+
1011
+ interface RegistryDetailProps {
1012
+ icon: LucideIcon;
1013
+ iconColor: string;
1014
+ title: string;
1015
+ titleExtra?: ReactNode;
1016
+ subtitle: ReactNode;
1017
+ actionButton?: ReactNode;
1018
+ labels?: LabelProps[];
1019
+ description?: string;
1020
+ longDescription?: string;
1021
+ integration?: boolean;
1022
+ compatibleTools?: string[];
1023
+ files?: FileStructureSectionProps['files'];
1024
+ rootName?: string;
1025
+ onFetchContent?: FileStructureSectionProps['onFetchContent'];
1026
+ aboveHeader?: ReactNode;
1027
+ maxWidth?: string;
1028
+ children?: ReactNode;
1029
+ }
1030
+ declare function RegistryDetail({ icon: Icon, iconColor, title, titleExtra, subtitle, actionButton, labels, description, longDescription, integration, compatibleTools, files, rootName, onFetchContent, aboveHeader, maxWidth, children, }: RegistryDetailProps): react_jsx_runtime.JSX.Element;
1031
+
1032
+ interface RegistryBrowserProps {
1033
+ isLoading: boolean;
1034
+ loadingMessage?: string;
1035
+ error: string | null;
1036
+ isEmpty: boolean;
1037
+ emptyMessage?: string;
1038
+ onRetry?: () => void;
1039
+ searchQuery: string;
1040
+ onSearchChange: (q: string) => void;
1041
+ onSearchSubmit?: () => void;
1042
+ searchPlaceholder?: string;
1043
+ debounceKey?: number;
1044
+ debounceDurationMs?: number;
1045
+ toolbarCenter?: ReactNode;
1046
+ toolbarEnd?: ReactNode;
1047
+ onRefresh?: () => void;
1048
+ refreshTooltip?: {
1049
+ title?: string;
1050
+ description: string;
1051
+ };
1052
+ aboveGrid?: ReactNode;
1053
+ hasActiveFilters?: boolean;
1054
+ onResetFilters?: () => void;
1055
+ initialScrollTop?: number;
1056
+ onScrollChange?: (scrollTop: number) => void;
1057
+ maxWidth?: string;
1058
+ items: RegistryCardProps[];
1059
+ }
1060
+ declare function RegistryBrowser({ isLoading, loadingMessage, error, isEmpty, emptyMessage, onRetry, searchQuery, onSearchChange, onSearchSubmit, searchPlaceholder, debounceKey, debounceDurationMs, toolbarCenter, toolbarEnd, onRefresh, refreshTooltip, aboveGrid, hasActiveFilters, onResetFilters, initialScrollTop, onScrollChange, maxWidth, items, }: RegistryBrowserProps): react_jsx_runtime.JSX.Element;
1061
+
1062
+ type AiActionStatus = 'idle' | 'running' | 'completed';
1063
+ type AiCompletionResult = 'success' | 'partial' | 'error';
1064
+ interface AiActionButtonProps {
1065
+ /** Current execution status */
1066
+ status?: AiActionStatus;
1067
+ /** Result when status is 'completed' */
1068
+ completionResult?: AiCompletionResult;
1069
+ /** Icon shown in default state */
1070
+ icon: IconName;
1071
+ /** Icon shown when running (defaults to 'loader') */
1072
+ runningIcon?: IconName;
1073
+ /** Icon shown when completed successfully (defaults to 'check-circle') */
1074
+ completedIcon?: IconName;
1075
+ /** Base tooltip (title/description modified based on state) */
1076
+ tooltip: {
1077
+ title: string;
1078
+ description: string;
1079
+ };
1080
+ /** Tooltip title when running (defaults to "Show {title} Progress") */
1081
+ runningTooltipTitle?: string;
1082
+ /** Tooltip title when completed (defaults to "View {title} Results") */
1083
+ completedTooltipTitle?: string;
1084
+ onClick?: () => void;
1085
+ /** Force disabled state (in addition to automatic running state) */
1086
+ disabled?: boolean;
1087
+ /** Custom reason when force-disabled */
1088
+ disabledReason?: string;
1089
+ /** Color in default state */
1090
+ color?: IconButtonProps['color'];
1091
+ /** Color when completed successfully (defaults to 'green') */
1092
+ completedColor?: IconButtonProps['color'];
1093
+ size?: IconButtonProps['size'];
1094
+ className?: string;
1095
+ testId?: string;
1096
+ }
1097
+ declare function AiActionButton({ status, completionResult, icon, runningIcon, completedIcon, tooltip, runningTooltipTitle, completedTooltipTitle, onClick, disabled: forceDisabled, disabledReason, color, completedColor, size, className, testId, }: AiActionButtonProps): react_jsx_runtime.JSX.Element;
1098
+
1099
+ type ExecutionStatus = 'running' | 'success' | 'partial' | 'error';
1100
+ interface AiExecutionActionButtonsProps {
1101
+ /** Whether execution is currently running */
1102
+ isRunning: boolean;
1103
+ /** Whether all execution is complete */
1104
+ allDone: boolean;
1105
+ /** Called when minimize/pin button clicked - hide modal, continue process */
1106
+ onMinimize: () => void;
1107
+ /** Called when cancel/stop button clicked - kill process. If not provided, cancel button is hidden */
1108
+ onCancel?: () => void;
1109
+ /** Called when done/close button clicked */
1110
+ onClose: () => void;
1111
+ /** Completion status - affects done button icon/color */
1112
+ status?: ExecutionStatus;
1113
+ /** Prefix for test IDs (e.g., 'scan-modal' results in 'scan-modal-minimize-btn') */
1114
+ testIdPrefix?: string;
1115
+ }
1116
+ declare function AiExecutionActionButtons({ isRunning, allDone, onMinimize, onCancel, onClose, status, testIdPrefix, }: AiExecutionActionButtonsProps): react_jsx_runtime.JSX.Element;
1117
+
1118
+ /**
1119
+ * Issue Reporter API — Types and submission client
1120
+ *
1121
+ * Part of: Sections > Report a Bug
1122
+ *
1123
+ * This module defines the shared types for issue reporting and provides
1124
+ * the HTTP client that submits reports to a Cloudflare Worker endpoint.
1125
+ * The worker creates Linear issues with optional screenshot uploads and
1126
+ * duplicate detection.
1127
+ *
1128
+ * AI agent notes:
1129
+ * - workerUrl is passed per-call so different apps can use different endpoints
1130
+ * - linearTeamId/linearProjectId are sent in the request body, allowing one
1131
+ * worker to serve multiple apps (the worker must read these from the body)
1132
+ * - The worker source lives at /reviewr/workers/issue-reporter/
1133
+ * - ScreenshotAttachment.data is base64-encoded (no data URL prefix)
1134
+ * - SystemInfo must be provided by the consuming app (e.g. via Tauri invoke,
1135
+ * navigator.userAgent, or a custom endpoint)
1136
+ */
1137
+ type IssueType = 'bug' | 'feature' | 'question' | 'improvement' | 'documentation';
1138
+ declare const ISSUE_TYPES: {
1139
+ value: IssueType;
1140
+ label: string;
1141
+ }[];
1142
+ interface SystemInfo {
1143
+ os: string;
1144
+ osVersion: string;
1145
+ appVersion: string;
1146
+ arch: string;
1147
+ }
1148
+ interface ScreenshotAttachment {
1149
+ filename: string;
1150
+ data: string;
1151
+ contentType: string;
1152
+ }
1153
+ interface IssueReport {
1154
+ title: string;
1155
+ description: string;
1156
+ type: IssueType;
1157
+ stackTrace?: string;
1158
+ errorFingerprint?: string;
1159
+ systemInfo: SystemInfo;
1160
+ userEmail?: string;
1161
+ screenshots?: ScreenshotAttachment[];
1162
+ /** Target Linear team — allows one worker to serve multiple apps */
1163
+ linearTeamId?: string;
1164
+ /** Target Linear project (optional) */
1165
+ linearProjectId?: string;
1166
+ }
1167
+ interface IssueReportResult {
1168
+ success: boolean;
1169
+ issueId?: string;
1170
+ message: string;
1171
+ isDuplicate?: boolean;
1172
+ url?: string;
1173
+ }
1174
+ declare function submitIssueReport(workerUrl: string, report: IssueReport): Promise<IssueReportResult>;
1175
+
1176
+ /**
1177
+ * Error Logger — Automatic console error capture for issue reporting
1178
+ *
1179
+ * Part of: Sections > Report a Bug
1180
+ *
1181
+ * Provides a factory function to create app-specific error loggers.
1182
+ * Each logger instance has its own localStorage namespace and in-memory state.
1183
+ *
1184
+ * Usage:
1185
+ * const logger = createErrorLogger('myapp')
1186
+ * logger.init() // Call early in app startup to begin capturing
1187
+ * // Later, pass captured data to ReportBugForm:
1188
+ * <ReportBugForm
1189
+ * errorReport={logger.getFormattedReport()}
1190
+ * errorCount={logger.getErrorCount()}
1191
+ * warnCount={logger.getWarnCount()}
1192
+ * onErrorsSubmitted={() => { logger.markAsSubmitted(); logger.clearLogs() }}
1193
+ * />
1194
+ *
1195
+ * AI agent notes:
1196
+ * - createErrorLogger returns an isolated instance with its own storage prefix
1197
+ * - Three-list architecture: Current (active) -> Submitted (reported) | Dismissed (ignored)
1198
+ * - Errors are deduplicated by fingerprint (djb2 hash of first error line)
1199
+ * - init() intercepts console.error, console.warn, and window error events
1200
+ * - subscribe/getSnapshot are for React's useSyncExternalStore
1201
+ * - The form component (ReportBugForm) does NOT depend on this directly;
1202
+ * it accepts errorReport/errorCount as props, keeping the two decoupled
1203
+ */
1204
+ interface TrackedError {
1205
+ fingerprint: string;
1206
+ firstMessage: string;
1207
+ count: number;
1208
+ firstSeen: string;
1209
+ lastSeen: string;
1210
+ stack?: string;
1211
+ }
1212
+ interface ErrorLogger {
1213
+ /** Start capturing console.error, console.warn, and unhandled errors */
1214
+ init(): void;
1215
+ /** Number of unique current (unreported) errors */
1216
+ getErrorCount(): number;
1217
+ /** Number of warnings in the log buffer */
1218
+ getWarnCount(): number;
1219
+ /** Current errors not yet submitted or dismissed */
1220
+ getCurrentErrors(): TrackedError[];
1221
+ /** Previously submitted errors */
1222
+ getSubmittedErrors(): TrackedError[];
1223
+ /** Markdown-formatted error report for Linear issue submission */
1224
+ getFormattedReport(): string;
1225
+ /** Combined fingerprint of all current errors (for duplicate detection) */
1226
+ getErrorFingerprint(): string;
1227
+ /** Raw log output as a string */
1228
+ getLogs(): string;
1229
+ /** Move all current errors to the submitted list */
1230
+ markAsSubmitted(): void;
1231
+ /** Move all current errors to the dismissed list */
1232
+ markAsDismissed(): void;
1233
+ /** Clear the in-memory log buffer (does not affect tracked errors) */
1234
+ clearLogs(): void;
1235
+ /** For React useSyncExternalStore */
1236
+ subscribe(listener: () => void): () => void;
1237
+ /** For React useSyncExternalStore */
1238
+ getSnapshot(): number;
1239
+ }
1240
+ declare function createErrorLogger(storagePrefix: string): ErrorLogger;
1241
+
1242
+ interface ReportBugFormProps {
1243
+ /** URL of the issue reporter worker endpoint */
1244
+ workerUrl: string;
1245
+ /** Function that returns system info. Each app provides its own implementation. */
1246
+ getSystemInfo: () => Promise<SystemInfo>;
1247
+ /** Linear team ID — routes issues to the correct team */
1248
+ linearTeamId?: string;
1249
+ /** Linear project ID — associates issues with a project */
1250
+ linearProjectId?: string;
1251
+ /** Pre-formatted error report to optionally include (from error logger) */
1252
+ errorReport?: string;
1253
+ /** Error fingerprint for duplicate detection */
1254
+ errorFingerprint?: string;
1255
+ /** Number of captured errors (shown in checkbox label) */
1256
+ errorCount?: number;
1257
+ /** Number of captured warnings */
1258
+ warnCount?: number;
1259
+ /** Captured error entries to display when "include logs" is checked */
1260
+ capturedErrors?: TrackedError[];
1261
+ /** Called after successful submission */
1262
+ onSuccess?: (result: IssueReportResult) => void;
1263
+ /** Called on submission failure */
1264
+ onError?: (message: string) => void;
1265
+ /** Called when user clicks cancel (hidden if not provided) */
1266
+ onCancel?: () => void;
1267
+ /** Called when error logs are included in a successful submission */
1268
+ onErrorsSubmitted?: () => void;
1269
+ /** Override default API submission (for testing/mocking) */
1270
+ submitFn?: (report: IssueReport) => Promise<IssueReportResult>;
1271
+ className?: string;
1272
+ }
1273
+ declare function ReportBugForm({ workerUrl, getSystemInfo, linearTeamId, linearProjectId, errorReport, errorFingerprint, errorCount, warnCount, capturedErrors, onSuccess, onError, onCancel, onErrorsSubmitted, submitFn, className, }: ReportBugFormProps): react_jsx_runtime.JSX.Element;
1274
+
1275
+ /**
1276
+ * ScreenshotUploader — Drag & drop multi-image upload
1277
+ *
1278
+ * Part of: Sections > Report a Bug
1279
+ * Also usable standalone for any image upload scenario.
1280
+ *
1281
+ * Features:
1282
+ * - Drag & drop or click to select images
1283
+ * - Base64 encoding for API submission
1284
+ * - Preview thumbnails in a 3-column grid
1285
+ * - Total size limit enforcement (default 20MB)
1286
+ * - Individual screenshot removal
1287
+ *
1288
+ * AI agent notes:
1289
+ * - Fully controlled component: parent owns the screenshots array
1290
+ * - Screenshot.data is base64 without the data URL prefix
1291
+ * - The Screenshot type (with id, size) is for UI management;
1292
+ * ScreenshotAttachment (without id, size) is what gets sent to the API
1293
+ * - Used by ReportBugForm but exported independently
1294
+ */
1295
+ interface Screenshot {
1296
+ id: string;
1297
+ filename: string;
1298
+ data: string;
1299
+ contentType: string;
1300
+ size: number;
1301
+ }
1302
+ interface ScreenshotUploaderProps {
1303
+ screenshots: Screenshot[];
1304
+ onChange: (screenshots: Screenshot[]) => void;
1305
+ maxTotalSize?: number;
1306
+ disabled?: boolean;
1307
+ className?: string;
1308
+ }
1309
+ declare function ScreenshotUploader({ screenshots, onChange, maxTotalSize, disabled, className, }: ScreenshotUploaderProps): react_jsx_runtime.JSX.Element;
1310
+
1311
+ /**
1312
+ * useReportBug — Form state and submission hook
1313
+ *
1314
+ * Part of: Sections > Report a Bug
1315
+ *
1316
+ * Manages all form state (issue type, title, description, email, screenshots,
1317
+ * include-logs toggle) and the async submission flow with status updates.
1318
+ *
1319
+ * AI agent notes:
1320
+ * - This hook is used internally by ReportBugForm but can also be used
1321
+ * standalone for custom form UIs
1322
+ * - Uses callbacks (onSuccess/onError) instead of alert modals for flexibility
1323
+ * - Error data (errorReport, errorFingerprint) comes as options, not from
1324
+ * an imported error logger — keeps the hook decoupled
1325
+ * - The hook resets the form on successful submission
1326
+ * - submitFn can override the default API call (useful for testing/mocking)
1327
+ */
1328
+
1329
+ interface UseReportBugOptions {
1330
+ /** Issue reporter worker endpoint URL */
1331
+ workerUrl: string;
1332
+ /** Returns system info (OS, version, etc.) — each app provides its own */
1333
+ getSystemInfo: () => Promise<SystemInfo>;
1334
+ /** Linear team to route issues to */
1335
+ linearTeamId?: string;
1336
+ /** Linear project to associate issues with */
1337
+ linearProjectId?: string;
1338
+ /** Pre-formatted error report string (from error logger or custom source) */
1339
+ errorReport?: string;
1340
+ /** Combined error fingerprint for duplicate detection */
1341
+ errorFingerprint?: string;
1342
+ /** Called after successful submission */
1343
+ onSuccess?: (result: IssueReportResult) => void;
1344
+ /** Called on submission failure */
1345
+ onError?: (message: string) => void;
1346
+ /** Called when error logs are included in a successful submission */
1347
+ onErrorsSubmitted?: () => void;
1348
+ /** Override default API submission (useful for testing/mocking) */
1349
+ submitFn?: (report: IssueReport) => Promise<IssueReportResult>;
1350
+ }
1351
+ interface UseReportBugReturn {
1352
+ issueType: IssueType;
1353
+ setIssueType: (type: IssueType) => void;
1354
+ title: string;
1355
+ setTitle: (title: string) => void;
1356
+ description: string;
1357
+ setDescription: (desc: string) => void;
1358
+ email: string;
1359
+ setEmail: (email: string) => void;
1360
+ screenshots: Screenshot[];
1361
+ setScreenshots: (screenshots: Screenshot[]) => void;
1362
+ includeLogs: boolean;
1363
+ setIncludeLogs: (include: boolean) => void;
1364
+ isSubmitting: boolean;
1365
+ submissionStatus: string;
1366
+ emailHasError: boolean;
1367
+ canSubmit: boolean;
1368
+ handleSubmit: () => Promise<void>;
1369
+ }
1370
+ declare function useReportBug(options: UseReportBugOptions): UseReportBugReturn;
1371
+
1372
+ /**
1373
+ * Golden Snapshots — Shared type definitions
1374
+ *
1375
+ * Part of: Sections > Golden Snapshots
1376
+ *
1377
+ * These types define the CONTRACT between the UI layer (this package) and
1378
+ * the Rust/Tauri backend that each app must implement. Every type here has
1379
+ * a 1:1 mapping to a Rust struct returned by Tauri commands.
1380
+ *
1381
+ * IMPORTANT FOR AI AGENTS:
1382
+ * When adding a new field here, the corresponding Rust struct must also be
1383
+ * updated (and vice versa). The serde rename attributes in Rust use camelCase
1384
+ * to match these TypeScript interfaces.
1385
+ *
1386
+ * Generic design:
1387
+ * - Components are keyed by string name (not hardcoded to specific apps)
1388
+ * - Configr uses: "runtime", "verifier", "simulator", "generator"
1389
+ * - Reviewr uses: "runtime", plus app-specific components
1390
+ * - The UI renders whatever components the backend returns
1391
+ */
1392
+ /** Version info for a single component (runtime, verifier, etc.) */
1393
+ interface ComponentVersion {
1394
+ version: string;
1395
+ description?: string;
1396
+ updatedAt?: string;
1397
+ hash?: string;
1398
+ }
1399
+ /**
1400
+ * Golden metadata — describes the state of a golden (reference) or live (working) copy.
1401
+ *
1402
+ * Rust equivalent: `GoldenMeta` in mod.rs
1403
+ * Returned by: `get_status`, `get_golden_meta`
1404
+ *
1405
+ * `components` is a flat map of component name → version info.
1406
+ * Each app defines its own component names.
1407
+ */
1408
+ interface GoldenMeta {
1409
+ version: string;
1410
+ createdAt: string;
1411
+ description?: string;
1412
+ components: Record<string, ComponentVersion>;
1413
+ }
1414
+ /** Filesystem status of a directory (golden, live, snapshots, etc.) */
1415
+ interface DirectoryStatus {
1416
+ exists: boolean;
1417
+ path: string;
1418
+ fileCount: number;
1419
+ totalSizeBytes: number;
1420
+ }
1421
+ /** Info about the bundled seed archive */
1422
+ interface SeedInfo {
1423
+ exists: boolean;
1424
+ path: string;
1425
+ sizeBytes: number;
1426
+ modifiedAt?: string;
1427
+ meta?: GoldenMeta;
1428
+ fileCount: number;
1429
+ fileList: string[];
1430
+ }
1431
+ /**
1432
+ * Overall status of the golden/live system.
1433
+ *
1434
+ * Rust equivalent: `ConfigrStatus` in mod.rs (generalize the name per app)
1435
+ * Returned by: `get_status` command
1436
+ *
1437
+ * Contains metadata for both golden and live copies, directory statuses,
1438
+ * and seed info. The UI uses this to render the Status Overview panel.
1439
+ *
1440
+ * `directories` is a flat map so apps can have any number of tracked directories.
1441
+ * Convention: keys are "{component}Golden" and "{component}Live".
1442
+ */
1443
+ interface GoldenStatus {
1444
+ goldenMeta?: GoldenMeta;
1445
+ liveMeta?: GoldenMeta;
1446
+ directories: Record<string, DirectoryStatus>;
1447
+ seed: SeedInfo;
1448
+ }
1449
+ type FileDiffStatus = 'added' | 'removed' | 'modified' | 'unchanged';
1450
+ /** A single file's diff info between golden and live */
1451
+ interface FileDiffInfo {
1452
+ /** Relative path within the component directory */
1453
+ path: string;
1454
+ /** Which component this file belongs to (e.g. "runtime", "verifier") */
1455
+ component: string;
1456
+ status: FileDiffStatus;
1457
+ goldenSize: number;
1458
+ liveSize: number;
1459
+ }
1460
+ interface DiffSummary {
1461
+ added: number;
1462
+ removed: number;
1463
+ modified: number;
1464
+ unchanged: number;
1465
+ total: number;
1466
+ }
1467
+ /** Which components have changes between golden and live */
1468
+ type ChangedComponents = Record<string, boolean>;
1469
+ /**
1470
+ * Full diff result between golden and live directories.
1471
+ *
1472
+ * Rust equivalent: `GoldenLiveDiff` in mod.rs
1473
+ * Returned by: `get_golden_live_diff` command
1474
+ */
1475
+ interface GoldenLiveDiff {
1476
+ files: FileDiffInfo[];
1477
+ summary: DiffSummary;
1478
+ componentChanges: ChangedComponents;
1479
+ }
1480
+ /** A single snapshot entry in the manifest */
1481
+ interface SnapshotInfo {
1482
+ version: number;
1483
+ filename: string;
1484
+ createdAt: string;
1485
+ description?: string;
1486
+ pinned: boolean;
1487
+ metaVersion?: string;
1488
+ }
1489
+ /**
1490
+ * Manifest listing all snapshots.
1491
+ *
1492
+ * Rust equivalent: `SnapshotsManifest` in mod.rs
1493
+ * Returned by: `list_golden_snapshots` command
1494
+ */
1495
+ interface SnapshotsManifest {
1496
+ activeVersion: number;
1497
+ pinnedVersion?: number;
1498
+ snapshots: SnapshotInfo[];
1499
+ }
1500
+ /** Result from creating a new snapshot */
1501
+ interface CreateSnapshotResult {
1502
+ version: number;
1503
+ filename: string;
1504
+ seedUpdated: boolean;
1505
+ changedComponents: ChangedComponents;
1506
+ newMeta: GoldenMeta;
1507
+ }
1508
+ /** Result from resetting files */
1509
+ interface ResetResult {
1510
+ filesReset: number;
1511
+ }
1512
+ /**
1513
+ * GoldenSnapshotsApi — The callback interface that each app must implement.
1514
+ *
1515
+ * This is the bridge between the shared UI and the app-specific backend.
1516
+ * Each function maps to a Tauri command (or any other backend).
1517
+ *
1518
+ * ┌─────────────────────────────────────────────────────────────────────┐
1519
+ * │ RUST BACKEND IMPLEMENTATION GUIDE │
1520
+ * │ │
1521
+ * │ Each method below corresponds to a Tauri #[tauri::command]. │
1522
+ * │ The Rust reference implementation lives in: │
1523
+ * │ configr/development/src-tauri/src/commands/snapshots/ │
1524
+ * │ ├── mod.rs — Types + helpers │
1525
+ * │ ├── lifecycle.rs — All command implementations │
1526
+ * │ ├── runtime_init.rs — Bootstrap (seed → golden → live) │
1527
+ * │ └── zip_ops.rs — Zip archive utilities │
1528
+ * │ │
1529
+ * │ REQUIRED Tauri commands for full functionality: │
1530
+ * │ │
1531
+ * │ STATUS & METADATA: │
1532
+ * │ get_status() → GoldenStatus │
1533
+ * │ get_golden_meta() → GoldenMeta | null │
1534
+ * │ get_golden_live_diff() → GoldenLiveDiff │
1535
+ * │ │
1536
+ * │ FILE OPERATIONS: │
1537
+ * │ get_file_content_for_diff(component, path, source) → string|null │
1538
+ * │ save_live_file_content(component, path, content) → void │
1539
+ * │ reset_golden_file_to_live(component, path) → void │
1540
+ * │ reset_golden_component_to_live(component) → ResetResult │
1541
+ * │ │
1542
+ * │ SNAPSHOT MANAGEMENT (devtools only): │
1543
+ * │ create_golden_snapshot(description?) → CreateSnapshotResult │
1544
+ * │ list_golden_snapshots() → SnapshotsManifest │
1545
+ * │ restore_golden_snapshot(version, resetLive) → void │
1546
+ * │ pin_golden_snapshot(version, pinned) → void │
1547
+ * │ delete_golden_snapshot(version) → void │
1548
+ * │ │
1549
+ * │ VERSION MANAGEMENT: │
1550
+ * │ update_component_version(component, version, desc?) → void │
1551
+ * │ bump_golden_version(newVersion, desc?) → void │
1552
+ * │ │
1553
+ * │ DIRECTORY STRUCTURE (Rust backend must maintain): │
1554
+ * │ {app_data_dir}/ │
1555
+ * │ ├── golden/ — Reference copy (overwritten on update) │
1556
+ * │ │ ├── .meta/meta.json — GoldenMeta serialized │
1557
+ * │ │ └── {components}/ — One dir per component │
1558
+ * │ ├── live/ — Working copy (user edits preserved) │
1559
+ * │ │ ├── .meta/meta.json │
1560
+ * │ │ └── {components}/ │
1561
+ * │ └── snapshots/ — Versioned zip archives │
1562
+ * │ ├── manifest.json — SnapshotsManifest │
1563
+ * │ └── snapshot_v001_YYYY-MM-DD.zip │
1564
+ * │ │
1565
+ * │ KEY BEHAVIORS the Rust backend must implement: │
1566
+ * │ 1. Hash-based change detection between golden and live files │
1567
+ * │ 2. Semver auto-bump per component on snapshot creation │
1568
+ * │ 3. Selective sync: only update components without user changes │
1569
+ * │ 4. Snapshot pruning: keep N most recent + all pinned │
1570
+ * │ 5. Snapshot = zip of live dirs + meta.json │
1571
+ * │ 6. create_snapshot copies live → golden after archiving │
1572
+ * └─────────────────────────────────────────────────────────────────────┘
1573
+ */
1574
+ interface GoldenSnapshotsApi {
1575
+ /** Get overall system status (golden/live metadata, directory info, seed) */
1576
+ getStatus: () => Promise<GoldenStatus>;
1577
+ /** Get golden metadata only (lighter than full status) */
1578
+ getGoldenMeta: () => Promise<GoldenMeta | null>;
1579
+ /** Get file-level diff between golden and live directories */
1580
+ getDiff: () => Promise<GoldenLiveDiff>;
1581
+ /** Get content of a single file from golden or live */
1582
+ getFileContent: (component: string, path: string, source: 'golden' | 'live') => Promise<string | null>;
1583
+ /** Save edited content to a live file (devtools only) */
1584
+ saveFile: (component: string, path: string, content: string) => Promise<void>;
1585
+ /** Reset a single file: copy golden → live */
1586
+ resetFile: (component: string, path: string) => Promise<void>;
1587
+ /** Reset an entire component (or 'all'): copy golden → live */
1588
+ resetComponent: (component: string) => Promise<ResetResult>;
1589
+ /** Create a new snapshot from current live state */
1590
+ createSnapshot: (description?: string) => Promise<CreateSnapshotResult>;
1591
+ /** List all snapshots */
1592
+ listSnapshots: () => Promise<SnapshotsManifest>;
1593
+ /** Restore a snapshot by version number */
1594
+ restoreSnapshot: (version: number, resetLive: boolean) => Promise<void>;
1595
+ /** Pin/unpin a snapshot (pinned snapshots are never auto-pruned) */
1596
+ pinSnapshot: (version: number, pinned: boolean) => Promise<void>;
1597
+ /** Delete a snapshot */
1598
+ deleteSnapshot: (version: number) => Promise<void>;
1599
+ /** Update version for a single component */
1600
+ updateComponentVersion: (component: string, version: string, description?: string) => Promise<void>;
1601
+ /** Bump the overall golden version */
1602
+ bumpVersion: (newVersion: string, description?: string) => Promise<void>;
1603
+ }
1604
+
1605
+ interface DiffTreeNode {
1606
+ files: FileDiffInfo[];
1607
+ children: Record<string, DiffTreeNode>;
1608
+ }
1609
+ interface UseGoldenSyncOptions {
1610
+ api: GoldenSnapshotsApi;
1611
+ devtools: boolean;
1612
+ }
1613
+ declare function useGoldenSync({ api, devtools }: UseGoldenSyncOptions): {
1614
+ status: GoldenStatus | null;
1615
+ loading: boolean;
1616
+ error: string | null;
1617
+ lastAction: string | null;
1618
+ loadStatus: () => Promise<void>;
1619
+ diff: GoldenLiveDiff | null;
1620
+ diffLoading: boolean;
1621
+ loadDiff: () => Promise<void>;
1622
+ selectedDiffFile: FileDiffInfo | null;
1623
+ goldenContent: string | null;
1624
+ liveContent: string | null;
1625
+ editedLiveContent: string | null;
1626
+ setEditedLiveContent: react.Dispatch<react.SetStateAction<string | null>>;
1627
+ diffFilter: "all" | FileDiffStatus;
1628
+ setDiffFilter: react.Dispatch<react.SetStateAction<"all" | FileDiffStatus>>;
1629
+ diffSideBySide: boolean;
1630
+ setDiffSideBySide: react.Dispatch<react.SetStateAction<boolean>>;
1631
+ saving: boolean;
1632
+ hasUnsavedChanges: boolean;
1633
+ handleSelectDiffFile: (file: FileDiffInfo) => Promise<void>;
1634
+ handleSaveLiveFile: () => Promise<void>;
1635
+ resettingFile: string | null;
1636
+ resettingComponent: string | null;
1637
+ resettingAll: boolean;
1638
+ showResetAllDialog: boolean;
1639
+ setShowResetAllDialog: react.Dispatch<react.SetStateAction<boolean>>;
1640
+ handleResetFile: (file: FileDiffInfo) => Promise<void>;
1641
+ handleResetComponent: (component: string) => Promise<void>;
1642
+ handleResetAll: () => Promise<void>;
1643
+ groupedFiles: Map<string, DiffTreeNode>;
1644
+ collapsedCategories: Set<string>;
1645
+ toggleCategory: (category: string) => void;
1646
+ countFiles: (node: DiffTreeNode) => number;
1647
+ allCategoryKeys: string[];
1648
+ allExpanded: boolean;
1649
+ handleExpandAll: () => void;
1650
+ handleCollapseAll: () => void;
1651
+ manifest: SnapshotsManifest | null;
1652
+ manifestLoading: boolean;
1653
+ snapshotBusy: boolean;
1654
+ loadManifest: () => Promise<void>;
1655
+ handleCreateSnapshot: (description?: string) => Promise<void>;
1656
+ handleRestoreSnapshot: (version: number, resetLive: boolean) => Promise<void>;
1657
+ handlePinSnapshot: (version: number, pinned: boolean) => Promise<void>;
1658
+ handleDeleteSnapshot: (version: number) => Promise<void>;
1659
+ handleUpdateComponentVersion: (component: string, version: string, description?: string) => Promise<void>;
1660
+ handleBumpVersion: (newVersion: string, description?: string) => Promise<void>;
1661
+ refresh: () => Promise<void>;
1662
+ devtools: boolean;
1663
+ };
1664
+ type UseGoldenSyncReturn = ReturnType<typeof useGoldenSync>;
1665
+ declare function formatDate(isoString: string): string;
1666
+ declare function formatBytes(bytes: number): string;
1667
+ declare function getLanguage(path: string): string;
1668
+
1669
+ type TabId = 'status' | 'diff' | 'snapshots' | 'versions';
1670
+ interface GoldenSyncPanelProps {
1671
+ api: GoldenSnapshotsApi;
1672
+ components: string[];
1673
+ devtools?: boolean;
1674
+ componentLabels?: Record<string, string>;
1675
+ monacoTheme?: string;
1676
+ renderFileIcon?: (filename: string, component: string) => ReactNode;
1677
+ onTabChange?: (tab: TabId) => void;
1678
+ }
1679
+ declare function GoldenSyncPanel({ api, components, devtools, componentLabels, monacoTheme, renderFileIcon, onTabChange, }: GoldenSyncPanelProps): react_jsx_runtime.JSX.Element;
1680
+
1681
+ interface StatusOverviewProps {
1682
+ status: GoldenStatus | null;
1683
+ components: string[];
1684
+ componentLabels?: Record<string, string>;
1685
+ devtools: boolean;
1686
+ manifest?: SnapshotsManifest | null;
1687
+ resettingComponent: string | null;
1688
+ resettingAll: boolean;
1689
+ onResetComponent: (component: string) => void;
1690
+ onResetAll: () => void;
1691
+ }
1692
+ declare function StatusOverview({ status, components, componentLabels, devtools, manifest, resettingComponent, resettingAll, onResetComponent, onResetAll, }: StatusOverviewProps): react_jsx_runtime.JSX.Element;
1693
+
1694
+ interface FileDiffViewerProps {
1695
+ sync: UseGoldenSyncReturn;
1696
+ componentLabels?: Record<string, string>;
1697
+ monacoTheme?: string;
1698
+ renderFileIcon?: (filename: string, component: string) => ReactNode;
1699
+ }
1700
+ declare function FileDiffViewer({ sync, componentLabels, monacoTheme, renderFileIcon }: FileDiffViewerProps): react_jsx_runtime.JSX.Element;
1701
+
1702
+ interface SnapshotManagerProps {
1703
+ sync: UseGoldenSyncReturn;
1704
+ }
1705
+ declare function SnapshotManager({ sync }: SnapshotManagerProps): react_jsx_runtime.JSX.Element;
1706
+
1707
+ interface VersionManagerProps {
1708
+ sync: UseGoldenSyncReturn;
1709
+ components: string[];
1710
+ componentLabels?: Record<string, string>;
1711
+ }
1712
+ declare function VersionManager({ sync, components, componentLabels }: VersionManagerProps): react_jsx_runtime.JSX.Element;
1713
+
1714
+ /**
1715
+ * AI Tools Paths — Shared type definitions
1716
+ *
1717
+ * Part of: Sections > AI Tools Paths
1718
+ *
1719
+ * These types define the CONTRACT between the UI layer (this package) and
1720
+ * the Rust/Tauri backend that each app must implement. Every type here has
1721
+ * a 1:1 mapping to a Rust struct returned by Tauri commands.
1722
+ *
1723
+ * IMPORTANT FOR AI AGENTS:
1724
+ * When adding a new field here, the corresponding Rust struct must also be
1725
+ * updated (and vice versa). The serde rename attributes in Rust use camelCase
1726
+ * to match these TypeScript interfaces.
1727
+ *
1728
+ * Generic design:
1729
+ * - Tools are keyed by string ID (not hardcoded to specific tools)
1730
+ * - Configr uses: "claude", "gemini", "copilot", "codex", "opencode"
1731
+ * - Other apps can define their own tool sets
1732
+ * - The UI renders whatever tools the consumer provides
1733
+ */
1734
+ /** Per-tool configuration state */
1735
+ interface AiToolConfig {
1736
+ /** Unique identifier for the tool (e.g. "claude", "gemini") */
1737
+ id: string;
1738
+ /** Display name (e.g. "Claude Code", "Gemini CLI") */
1739
+ name: string;
1740
+ /** Whether the tool is enabled for use */
1741
+ enabled: boolean;
1742
+ /** User-configured or auto-detected binary path */
1743
+ binaryPath: string;
1744
+ /** Whether the tool was found during detection */
1745
+ detected: boolean;
1746
+ /** Path found by auto-detection (may differ from binaryPath if user overrode it) */
1747
+ detectedPath?: string;
1748
+ }
1749
+ /** Result of detecting a single tool's binary */
1750
+ interface ToolDetectionResult {
1751
+ /** Whether the binary was found */
1752
+ detected: boolean;
1753
+ /** Resolved path to the binary, if found */
1754
+ path?: string;
1755
+ }
1756
+ /**
1757
+ * ToolsPathsApi — The callback interface that each app must implement.
1758
+ *
1759
+ * This is the bridge between the shared UI and the app-specific backend.
1760
+ * Each function maps to a Tauri command (or any other backend).
1761
+ *
1762
+ * ┌─────────────────────────────────────────────────────────────────────┐
1763
+ * │ RUST BACKEND IMPLEMENTATION GUIDE │
1764
+ * │ │
1765
+ * │ Each method below corresponds to a Tauri #[tauri::command]. │
1766
+ * │ The Rust reference implementation lives in: │
1767
+ * │ configr/main/src-tauri/src/commands/tools/ │
1768
+ * │ ├── mod.rs — Types + helpers │
1769
+ * │ └── detection.rs — Binary detection logic │
1770
+ * │ │
1771
+ * │ REQUIRED Tauri commands for full functionality: │
1772
+ * │ │
1773
+ * │ DETECTION: │
1774
+ * │ detect_all_tools() → Record<string, ToolDetectionResult> │
1775
+ * │ Scans PATH and known install locations for all tool binaries. │
1776
+ * │ Returns a map of tool ID → detection result. │
1777
+ * │ │
1778
+ * │ detect_tool(toolId) → ToolDetectionResult │
1779
+ * │ Scans for a single tool binary. Used for per-tool refresh. │
1780
+ * │ │
1781
+ * │ VALIDATION: │
1782
+ * │ validate_binary_path(path) → bool │
1783
+ * │ Checks if a given path points to a valid executable. │
1784
+ * │ Typically: fs::metadata(path).is_ok() && is_executable(path) │
1785
+ * │ │
1786
+ * │ DETECTION STRATEGY (Rust backend should implement): │
1787
+ * │ 1. Check PATH environment variable (which <tool-binary>) │
1788
+ * │ 2. Check common install locations: │
1789
+ * │ - /usr/local/bin/<binary> │
1790
+ * │ - /opt/homebrew/bin/<binary> │
1791
+ * │ - ~/.local/bin/<binary> │
1792
+ * │ - ~/.cargo/bin/<binary> (for Rust-based tools) │
1793
+ * │ - ~/.npm/bin/<binary> (for npm-based tools) │
1794
+ * │ 3. Check tool-specific locations: │
1795
+ * │ - Claude: ~/.claude/bin/claude │
1796
+ * │ - Copilot: gh extension path │
1797
+ * │ 4. Return first valid path found, or detected: false │
1798
+ * └─────────────────────────────────────────────────────────────────────┘
1799
+ */
1800
+ interface ToolsPathsApi {
1801
+ /** Scan all tools and return detection results keyed by tool ID */
1802
+ detectAll: () => Promise<Record<string, ToolDetectionResult>>;
1803
+ /** Scan a single tool and return its detection result */
1804
+ detectTool: (toolId: string) => Promise<ToolDetectionResult>;
1805
+ /** Check if a given binary path is valid (exists and is executable) */
1806
+ validatePath: (path: string) => Promise<boolean>;
1807
+ }
1808
+
1809
+ interface ToolsPathsPanelProps {
1810
+ /** API adapter for backend operations (detection, validation) */
1811
+ api: ToolsPathsApi;
1812
+ /** Current tool configurations */
1813
+ tools: AiToolConfig[];
1814
+ /** Called when a tool's config changes. Consumer updates their state. */
1815
+ onToolConfigChange: (toolId: string, config: Partial<AiToolConfig>) => void;
1816
+ /** Optional render function for tool icons. Receives tool ID, returns ReactNode. */
1817
+ renderToolIcon?: (toolId: string) => ReactNode;
1818
+ className?: string;
1819
+ }
1820
+ declare function ToolsPathsPanel({ api, tools, onToolConfigChange, renderToolIcon, className, }: ToolsPathsPanelProps): react_jsx_runtime.JSX.Element;
1821
+
1822
+ /**
1823
+ * useToolsPaths — Tool detection and configuration state hook
1824
+ *
1825
+ * Part of: Sections > AI Tools Paths
1826
+ *
1827
+ * Manages tool detection state, per-tool refresh tracking, and path validation.
1828
+ * Used internally by ToolsPathsPanel but can also be used standalone for
1829
+ * custom UIs.
1830
+ *
1831
+ * AI agent notes:
1832
+ * - This hook does NOT store tool configs — the consumer owns that state.
1833
+ * It only manages detection/scanning ephemeral state.
1834
+ * - The hook tracks which tools have been scanned, which are currently
1835
+ * refreshing, and whether a full scan has completed.
1836
+ * - Path validation is debounced by the consumer (typically on blur or
1837
+ * after typing stops).
1838
+ */
1839
+
1840
+ interface UseToolsPathsOptions {
1841
+ api: ToolsPathsApi;
1842
+ tools: AiToolConfig[];
1843
+ onToolConfigChange: (toolId: string, config: Partial<AiToolConfig>) => void;
1844
+ }
1845
+ interface UseToolsPathsReturn {
1846
+ /** Whether a full scan is in progress */
1847
+ isDetecting: boolean;
1848
+ /** Whether a full scan has completed at least once */
1849
+ hasScanned: boolean;
1850
+ /** Set of tool IDs currently being individually refreshed */
1851
+ refreshingTools: Set<string>;
1852
+ /** Set of tool IDs that were found during the last scan */
1853
+ scannedTools: Set<string>;
1854
+ /** Run detection for all tools */
1855
+ detectAll: () => Promise<void>;
1856
+ /** Run detection for a single tool */
1857
+ detectTool: (toolId: string) => Promise<void>;
1858
+ /** Validate and update a tool's binary path */
1859
+ validateAndUpdatePath: (toolId: string, path: string) => Promise<void>;
1860
+ /** Toggle a tool's enabled state */
1861
+ toggleEnabled: (toolId: string) => void;
1862
+ }
1863
+ declare function useToolsPaths({ api, tools, onToolConfigChange }: UseToolsPathsOptions): UseToolsPathsReturn;
1864
+
1865
+ /**
1866
+ * Captured Issues — Shared type definitions
1867
+ *
1868
+ * Part of: Sections > Captured Issues
1869
+ *
1870
+ * These types define the CONTRACT between the UI layer (this package) and
1871
+ * the backend that each app must implement. Each type maps to a backend
1872
+ * data structure (Rust struct, API response, etc.).
1873
+ *
1874
+ * IMPORTANT FOR AI AGENTS:
1875
+ * When adding a new field here, the corresponding backend type must also be
1876
+ * updated. Rust backends use serde rename with camelCase to match these
1877
+ * TypeScript interfaces.
1878
+ */
1879
+ /** A captured error or warning entry from the error logger */
1880
+ interface CapturedError {
1881
+ /** Unique hash identifying this error (djb2 of message + stack) */
1882
+ fingerprint: string;
1883
+ /** First occurrence message text */
1884
+ message: string;
1885
+ /** Number of times this error has been seen */
1886
+ count: number;
1887
+ /** Severity level */
1888
+ level: 'error' | 'warning';
1889
+ /** ISO-8601 timestamp of first occurrence */
1890
+ firstSeen: string;
1891
+ /** ISO-8601 timestamp of most recent occurrence */
1892
+ lastSeen: string;
1893
+ }
1894
+ /** A previously reported error that was submitted with an issue */
1895
+ interface SubmittedError {
1896
+ /** Unique hash identifying this error */
1897
+ fingerprint: string;
1898
+ /** Error message text */
1899
+ message: string;
1900
+ /** Number of new occurrences since submission */
1901
+ count: number;
1902
+ /** ISO-8601 timestamp of when this error was submitted */
1903
+ submittedAt: string;
1904
+ }
1905
+ /**
1906
+ * CapturedIssuesApi — The callback interface that each app must implement.
1907
+ *
1908
+ * This is the bridge between the shared UI and the app-specific backend.
1909
+ * Each function maps to a backend command (Tauri command, API endpoint, etc.).
1910
+ *
1911
+ * ┌─────────────────────────────────────────────────────────────────────┐
1912
+ * │ RUST BACKEND IMPLEMENTATION GUIDE │
1913
+ * │ │
1914
+ * │ Each method below corresponds to a Tauri #[tauri::command]. │
1915
+ * │ The Rust reference implementation lives in: │
1916
+ * │ configr/main/src-tauri/src/commands/support.rs │
1917
+ * │ │
1918
+ * │ REQUIRED Tauri commands: │
1919
+ * │ │
1920
+ * │ get_system_info() → SystemInfo │
1921
+ * │ Returns { os, osVersion, appVersion, arch } │
1922
+ * │ Used to include environment details in issue reports. │
1923
+ * │ │
1924
+ * │ submit_issue(title, description, email, errors) → SubmitResult │
1925
+ * │ Sends the issue to your issue tracker (Linear, GitHub, etc.) │
1926
+ * │ Returns { success: bool, issue_id: Option<String> } │
1927
+ * │ │
1928
+ * │ dismiss_errors() → () │
1929
+ * │ Clears the current error log without submitting. │
1930
+ * │ Typically calls error_logger.clear_logs(). │
1931
+ * │ │
1932
+ * │ get_submitted_errors() → Vec<SubmittedError> │
1933
+ * │ Returns previously reported errors from local storage/DB. │
1934
+ * │ Used to show the "Previously Reported" section. │
1935
+ * │ │
1936
+ * │ Tauri adapter example: │
1937
+ * │ │
1938
+ * │ import { invoke } from '@tauri-apps/api/core' │
1939
+ * │ import type { CapturedIssuesApi } from '@toolr/ui-design' │
1940
+ * │ │
1941
+ * │ const api: CapturedIssuesApi = { │
1942
+ * │ getSystemInfo: () => invoke('get_system_info'), │
1943
+ * │ submitIssue: (data) => invoke('submit_issue', data), │
1944
+ * │ dismissErrors: () => invoke('dismiss_errors'), │
1945
+ * │ getSubmittedErrors: () => invoke('get_submitted_errors'), │
1946
+ * │ } │
1947
+ * └─────────────────────────────────────────────────────────────────────┘
1948
+ */
1949
+ interface CapturedIssuesApi {
1950
+ /** Get system environment info to include in issue reports */
1951
+ getSystemInfo: () => Promise<{
1952
+ os: string;
1953
+ osVersion: string;
1954
+ appVersion: string;
1955
+ arch: string;
1956
+ }>;
1957
+ /** Submit an issue with captured errors to the issue tracker */
1958
+ submitIssue: (data: {
1959
+ title: string;
1960
+ description: string;
1961
+ email: string;
1962
+ errors: CapturedError[];
1963
+ }) => Promise<{
1964
+ success: boolean;
1965
+ issueId?: string;
1966
+ }>;
1967
+ /** Dismiss/clear current errors without submitting */
1968
+ dismissErrors: () => Promise<void>;
1969
+ /** Get list of previously submitted errors */
1970
+ getSubmittedErrors: () => Promise<SubmittedError[]>;
1971
+ }
1972
+
1973
+ interface CapturedIssuesPanelProps {
1974
+ /** Backend API implementation */
1975
+ api: CapturedIssuesApi;
1976
+ /** Current captured errors to display */
1977
+ errors: CapturedError[];
1978
+ /** Called after errors are dismissed */
1979
+ onDismiss?: () => void;
1980
+ /** Called after successful submission */
1981
+ onSubmitSuccess?: (issueId?: string) => void;
1982
+ className?: string;
1983
+ }
1984
+ declare function CapturedIssuesPanel({ api, errors, onDismiss, onSubmitSuccess, className, }: CapturedIssuesPanelProps): react_jsx_runtime.JSX.Element;
1985
+
1986
+ /**
1987
+ * useCapturedIssues — State management hook for captured issues panel
1988
+ *
1989
+ * Part of: Sections > Captured Issues
1990
+ *
1991
+ * Manages form state (title, description, email), submission flow,
1992
+ * dismiss functionality, and previously reported errors loading.
1993
+ *
1994
+ * AI agent notes:
1995
+ * - This hook is used internally by CapturedIssuesPanel but can also
1996
+ * be used standalone for custom UIs
1997
+ * - All backend calls go through the CapturedIssuesApi interface
1998
+ * - The hook resets form fields on successful submission
1999
+ * - Previously reported errors are loaded once on mount
2000
+ */
2001
+
2002
+ interface UseCapturedIssuesOptions {
2003
+ api: CapturedIssuesApi;
2004
+ errors: CapturedError[];
2005
+ onDismiss?: () => void;
2006
+ onSubmitSuccess?: (issueId?: string) => void;
2007
+ }
2008
+ interface UseCapturedIssuesReturn {
2009
+ errorCount: number;
2010
+ warnCount: number;
2011
+ title: string;
2012
+ setTitle: (title: string) => void;
2013
+ description: string;
2014
+ setDescription: (desc: string) => void;
2015
+ email: string;
2016
+ setEmail: (email: string) => void;
2017
+ isSubmitting: boolean;
2018
+ submitError: string | null;
2019
+ submittedErrors: SubmittedError[];
2020
+ handleSubmit: () => Promise<void>;
2021
+ handleDismiss: () => Promise<void>;
2022
+ }
2023
+ declare function useCapturedIssues(options: UseCapturedIssuesOptions): UseCapturedIssuesReturn;
2024
+
2025
+ /**
2026
+ * Snapshot Browser — Shared type definitions
2027
+ *
2028
+ * Part of: Sections > Snapshot Browser
2029
+ *
2030
+ * These types define the CONTRACT between the UI layer (this package) and
2031
+ * the Rust/Tauri backend that each app must implement. Every type here has
2032
+ * a 1:1 mapping to a Rust struct returned by Tauri commands.
2033
+ *
2034
+ * IMPORTANT FOR AI AGENTS:
2035
+ * When adding a new field here, the corresponding Rust struct must also be
2036
+ * updated (and vice versa). The serde rename attributes in Rust use camelCase
2037
+ * to match these TypeScript interfaces.
2038
+ *
2039
+ * Data hierarchy:
2040
+ * SnapshotScope → SnapshotCategory → SnapshotItem → SnapshotEntry
2041
+ *
2042
+ * Example:
2043
+ * Scope: "Settings (Prompts)"
2044
+ * Category: "Verifier Prompts"
2045
+ * Item: "system-prompt"
2046
+ * Entry: { content: "You are a...", savedAt: "2026-02-25T10:00:00Z" }
2047
+ */
2048
+ /** A single snapshot — one saved version of content */
2049
+ interface SnapshotEntry {
2050
+ id: string;
2051
+ content: string;
2052
+ savedAt: string;
2053
+ label?: string;
2054
+ }
2055
+ /** An item containing snapshots (e.g. a specific prompt or file) */
2056
+ interface SnapshotItem {
2057
+ id: string;
2058
+ name: string;
2059
+ snapshots: SnapshotEntry[];
2060
+ }
2061
+ /** A category containing items (e.g. "Verifier Prompts", "Skills") */
2062
+ interface SnapshotCategory {
2063
+ id: string;
2064
+ name: string;
2065
+ icon?: string;
2066
+ items: SnapshotItem[];
2067
+ }
2068
+ /** A top-level scope containing categories (e.g. "Settings", "Extensions") */
2069
+ interface SnapshotScope {
2070
+ id: string;
2071
+ name: string;
2072
+ categories: SnapshotCategory[];
2073
+ }
2074
+ /**
2075
+ * SnapshotBrowserApi — The callback interface that each app must implement.
2076
+ *
2077
+ * This is the bridge between the shared UI and the app-specific backend.
2078
+ * Each function maps to a Tauri command (or any other backend).
2079
+ *
2080
+ * ┌─────────────────────────────────────────────────────────────────────┐
2081
+ * │ RUST BACKEND IMPLEMENTATION GUIDE │
2082
+ * │ │
2083
+ * │ Each method below corresponds to a Tauri #[tauri::command]. │
2084
+ * │ The Rust reference implementation lives in: │
2085
+ * │ configr/main/src-tauri/src/commands/snapshots/ │
2086
+ * │ │
2087
+ * │ REQUIRED Tauri commands: │
2088
+ * │ │
2089
+ * │ delete_snapshot(scope, category, item, snapshot) → void │
2090
+ * │ Deletes a single snapshot entry by its composite key. │
2091
+ * │ The four IDs form a unique path to the snapshot. │
2092
+ * │ │
2093
+ * │ clear_all_snapshots() → void │
2094
+ * │ Removes all snapshots across all scopes. │
2095
+ * │ Should clear the backing store completely. │
2096
+ * │ │
2097
+ * │ STORAGE STRUCTURE (Rust backend must maintain): │
2098
+ * │ Snapshots are stored as JSON in the app data directory: │
2099
+ * │ {app_data_dir}/ │
2100
+ * │ └── snapshots/ │
2101
+ * │ └── {scope}/ │
2102
+ * │ └── {category}/ │
2103
+ * │ └── {item}.json — SnapshotEntry[] serialized │
2104
+ * │ │
2105
+ * │ KEY BEHAVIORS the Rust backend must implement: │
2106
+ * │ 1. Pruning: when snapshot limit is reached, remove oldest entry │
2107
+ * │ 2. Atomic writes: use temp file + rename for crash safety │
2108
+ * │ 3. IDs should be stable (UUID or timestamp-based) │
2109
+ * └─────────────────────────────────────────────────────────────────────┘
2110
+ */
2111
+ interface SnapshotBrowserApi {
2112
+ /** Delete a single snapshot by its composite key */
2113
+ deleteSnapshot: (scopeId: string, categoryId: string, itemId: string, snapshotId: string) => Promise<void>;
2114
+ /** Clear all snapshots across all scopes */
2115
+ clearAllSnapshots: () => Promise<void>;
2116
+ }
2117
+
2118
+ interface SnapshotBrowserPanelProps {
2119
+ api: SnapshotBrowserApi;
2120
+ scopes: SnapshotScope[];
2121
+ snapshotLimit: number;
2122
+ onSnapshotLimitChange: (limit: number) => void;
2123
+ onClearAll?: () => void;
2124
+ className?: string;
2125
+ }
2126
+ declare function SnapshotBrowserPanel({ api, scopes, snapshotLimit, onSnapshotLimitChange, onClearAll, className, }: SnapshotBrowserPanelProps): react_jsx_runtime.JSX.Element;
2127
+
2128
+ interface SnapshotTreeProps {
2129
+ scopes: SnapshotScope[];
2130
+ searchQuery: string;
2131
+ onSearchChange: (query: string) => void;
2132
+ expandedPaths: Set<string>;
2133
+ onToggleExpand: (path: string) => void;
2134
+ onExpandAll: () => void;
2135
+ onCollapseAll: () => void;
2136
+ allExpanded: boolean;
2137
+ allExpandablePaths: string[];
2138
+ onDeleteSnapshot: (scopeId: string, categoryId: string, itemId: string, snapshotId: string) => void;
2139
+ deletingSnapshotId: string | null;
2140
+ className?: string;
2141
+ }
2142
+ declare function SnapshotTree({ scopes, searchQuery, onSearchChange, expandedPaths, onToggleExpand, onExpandAll, onCollapseAll, allExpanded, allExpandablePaths, onDeleteSnapshot, deletingSnapshotId, className, }: SnapshotTreeProps): react_jsx_runtime.JSX.Element;
2143
+
2144
+ /**
2145
+ * useSnapshotBrowser — State management hook for the snapshot tree browser
2146
+ *
2147
+ * Part of: Sections > Snapshot Browser
2148
+ *
2149
+ * Manages:
2150
+ * - Tree expansion state (expanded scopes, categories, items)
2151
+ * - Search filter with auto-expand on search
2152
+ * - Expand all / collapse all
2153
+ * - Total snapshot count computation
2154
+ * - Delete operations with loading state
2155
+ */
2156
+
2157
+ interface UseSnapshotBrowserOptions {
2158
+ scopes: SnapshotScope[];
2159
+ api: SnapshotBrowserApi;
2160
+ }
2161
+ interface UseSnapshotBrowserReturn {
2162
+ searchQuery: string;
2163
+ setSearchQuery: (query: string) => void;
2164
+ expandedPaths: Set<string>;
2165
+ toggleExpand: (path: string) => void;
2166
+ expandAll: () => void;
2167
+ collapseAll: () => void;
2168
+ allExpanded: boolean;
2169
+ totalSnapshotCount: number;
2170
+ allExpandablePaths: string[];
2171
+ deleteSnapshot: (scopeId: string, categoryId: string, itemId: string, snapshotId: string) => Promise<void>;
2172
+ deletingSnapshotId: string | null;
2173
+ }
2174
+ declare function useSnapshotBrowser({ scopes, api }: UseSnapshotBrowserOptions): UseSnapshotBrowserReturn;
2175
+
2176
+ /**
2177
+ * Snippets Editor — Shared type definitions
2178
+ *
2179
+ * Part of: Sections > Snippets Editor
2180
+ *
2181
+ * Snippets are reusable text blocks that can be referenced in prompts
2182
+ * using the {{SNIPPET_NAME}} syntax. Each snippet has a name (uppercase
2183
+ * with underscores), a description, and a value that gets substituted
2184
+ * at render time.
2185
+ *
2186
+ * Example usage in a prompt:
2187
+ * "Follow the coding standards defined in {{CODE_STYLE}}"
2188
+ *
2189
+ * The consuming app is responsible for the actual template substitution.
2190
+ * This UI only manages CRUD operations via the provided API.
2191
+ */
2192
+ /** A single snippet definition */
2193
+ interface SnippetData {
2194
+ /** Snippet name — must match SNIPPET_NAME_REGEX (e.g., PROJECT_CONTEXT) */
2195
+ name: string;
2196
+ /** Human-readable description of what this snippet contains */
2197
+ description: string;
2198
+ /** The actual snippet content that gets substituted for {{NAME}} */
2199
+ value: string;
2200
+ }
2201
+ /**
2202
+ * Validation regex for snippet names.
2203
+ * Must start with an uppercase letter, followed by uppercase letters, digits, or underscores.
2204
+ * Examples: MY_SNIPPET, CODE_STYLE, ERROR_HANDLING_V2
2205
+ */
2206
+ declare const SNIPPET_NAME_REGEX: RegExp;
2207
+ /**
2208
+ * SnippetsEditorApi — The callback interface that consuming apps must implement.
2209
+ *
2210
+ * Each method maps to a backend operation (Tauri command, API call, etc.).
2211
+ * The UI calls these methods and awaits their completion before updating state.
2212
+ */
2213
+ interface SnippetsEditorApi {
2214
+ /** Add a new snippet. Rejects if a snippet with the same name already exists. */
2215
+ addSnippet: (snippet: SnippetData) => Promise<void>;
2216
+ /** Update an existing snippet. originalName is used to find the snippet to replace. */
2217
+ updateSnippet: (originalName: string, snippet: SnippetData) => Promise<void>;
2218
+ /** Remove a snippet by name. */
2219
+ removeSnippet: (name: string) => Promise<void>;
2220
+ }
2221
+
2222
+ interface SnippetsEditorProps {
2223
+ api: SnippetsEditorApi;
2224
+ snippets: SnippetData[];
2225
+ /** Section title, e.g. "Skills Snippets" */
2226
+ title?: string;
2227
+ /** Section description, e.g. "Define snippets to reuse in skills prompts..." */
2228
+ description?: string;
2229
+ className?: string;
2230
+ }
2231
+ declare function SnippetsEditor({ api, snippets, title, description, className, }: SnippetsEditorProps): react_jsx_runtime.JSX.Element;
2232
+
2233
+ /**
2234
+ * useSnippetsEditor — Form state and CRUD hook for the snippets editor
2235
+ *
2236
+ * Part of: Sections > Snippets Editor
2237
+ *
2238
+ * Manages selected snippet, form data, edit/add mode, validation, search,
2239
+ * and CRUD operations via the provided API.
2240
+ *
2241
+ * AI agent notes:
2242
+ * - This hook is used internally by SnippetsEditor but can also be used
2243
+ * standalone for custom UIs
2244
+ * - Validation checks: required fields, SNIPPET_NAME_REGEX, duplicate names
2245
+ * - The hook does NOT hold the snippets array — it receives it as a param
2246
+ * so the consuming app owns the source of truth
2247
+ */
2248
+
2249
+ interface SnippetFormData {
2250
+ name: string;
2251
+ description: string;
2252
+ value: string;
2253
+ }
2254
+ interface UseSnippetsEditorOptions {
2255
+ api: SnippetsEditorApi;
2256
+ snippets: SnippetData[];
2257
+ }
2258
+ interface UseSnippetsEditorReturn {
2259
+ selectedName: string | null;
2260
+ selectSnippet: (name: string | null) => void;
2261
+ searchQuery: string;
2262
+ setSearchQuery: (query: string) => void;
2263
+ filteredSnippets: SnippetData[];
2264
+ formData: SnippetFormData;
2265
+ setFormField: (field: keyof SnippetFormData, value: string) => void;
2266
+ formError: string | null;
2267
+ isEditing: boolean;
2268
+ isAdding: boolean;
2269
+ startAdd: () => void;
2270
+ startEdit: (snippet: SnippetData) => void;
2271
+ cancelForm: () => void;
2272
+ save: () => Promise<void>;
2273
+ remove: (name: string) => Promise<void>;
2274
+ resetForm: () => void;
2275
+ isSaving: boolean;
2276
+ }
2277
+ declare function useSnippetsEditor({ api, snippets }: UseSnippetsEditorOptions): UseSnippetsEditorReturn;
2278
+
2279
+ /**
2280
+ * Prompt Editor — Shared type definitions
2281
+ *
2282
+ * Part of: Sections > Prompt Editor
2283
+ *
2284
+ * These types define the shape of prompt data and the API contract
2285
+ * between the UI layer and whatever backend stores prompts.
2286
+ */
2287
+
2288
+ /** A tool tab shown in the editor (e.g. Claude, Gemini, Copilot) */
2289
+ interface ToolTab {
2290
+ id: string;
2291
+ name: string;
2292
+ icon?: ReactNode;
2293
+ /** Short name for narrow layouts */
2294
+ shortName?: string;
2295
+ /** Tailwind text color class for the active state (e.g. "text-orange-400") */
2296
+ activeColor?: string;
2297
+ }
2298
+ /** A template variable available for insertion into prompts */
2299
+ interface PromptPlaceholder {
2300
+ name: string;
2301
+ description: string;
2302
+ example?: string;
2303
+ required?: boolean;
2304
+ /** Label for the value display (default: "Value:") */
2305
+ valueLabel?: string;
2306
+ }
2307
+ /** A saved snapshot of a prompt for version history */
2308
+ interface PromptSnapshot {
2309
+ content: string;
2310
+ savedAt: string;
2311
+ }
2312
+ /**
2313
+ * PromptEditorApi — optional callback interface for persistence.
2314
+ *
2315
+ * When provided, the editor can save, reset, and manage snapshots.
2316
+ * When omitted, the editor works in "controlled" mode where the
2317
+ * parent manages all state via props.
2318
+ */
2319
+ interface PromptEditorApi {
2320
+ /** Save the current prompt */
2321
+ savePrompt: (prompt: string) => Promise<void>;
2322
+ /** Get the default/reset value */
2323
+ getDefaultPrompt?: () => Promise<string>;
2324
+ /** Save a snapshot */
2325
+ saveSnapshot?: (content: string) => Promise<void>;
2326
+ /** Get saved snapshots */
2327
+ getSnapshots?: () => Promise<PromptSnapshot[]>;
2328
+ /** Delete a snapshot by timestamp */
2329
+ deleteSnapshot?: (savedAt: string) => Promise<void>;
2330
+ }
2331
+ /** A file type option in the sidebar selector */
2332
+ interface FileTypeOption {
2333
+ id: string;
2334
+ name: string;
2335
+ description?: string;
2336
+ icon?: ReactNode;
2337
+ }
2338
+ /** A scenario with child steps for the tree sidebar */
2339
+ interface ScenarioOption {
2340
+ id: string;
2341
+ name: string;
2342
+ description?: string;
2343
+ icon?: ReactNode;
2344
+ steps: Array<{
2345
+ id: string;
2346
+ name: string;
2347
+ }>;
2348
+ }
2349
+
2350
+ /**
2351
+ * usePromptEditor — Hook managing prompt editor state
2352
+ *
2353
+ * Part of: Sections > Prompt Editor
2354
+ *
2355
+ * Handles:
2356
+ * - Local content state (separate from saved content for dirty detection)
2357
+ * - Dirty state detection
2358
+ * - Save with Ctrl/Cmd+S keyboard shortcut
2359
+ * - Variable search/filter
2360
+ * - Active tab state
2361
+ */
2362
+
2363
+ interface UsePromptEditorOptions {
2364
+ /** Prompt content keyed by tool id */
2365
+ prompts: Record<string, string>;
2366
+ /** Called when saving (all modified prompts at once) */
2367
+ onPromptChange: (tool: string, value: string) => void;
2368
+ /** Available tool tabs */
2369
+ tools: ToolTab[];
2370
+ /** Available template variables */
2371
+ variables?: PromptPlaceholder[];
2372
+ }
2373
+ interface UsePromptEditorReturn {
2374
+ /** Currently active tool tab id */
2375
+ activeTab: string;
2376
+ setActiveTab: (tab: string) => void;
2377
+ /** Local editor content (may differ from saved prompts) */
2378
+ localContent: Record<string, string>;
2379
+ /** Current prompt for the active tab */
2380
+ currentPrompt: string;
2381
+ /** Whether any tab has unsaved changes */
2382
+ isDirty: boolean;
2383
+ /** Handle editor content change */
2384
+ handleEditorChange: (value: string | undefined) => void;
2385
+ /** Save all modified prompts */
2386
+ handleSave: () => void;
2387
+ /** Variable search state */
2388
+ variableSearch: string;
2389
+ setVariableSearch: (search: string) => void;
2390
+ /** Filtered variables based on search */
2391
+ filteredVariables: PromptPlaceholder[];
2392
+ }
2393
+ declare function usePromptEditor({ prompts, onPromptChange, tools, variables, }: UsePromptEditorOptions): UsePromptEditorReturn;
2394
+
2395
+ interface TabbedPromptEditorProps {
2396
+ /** Prompt content keyed by tool id */
2397
+ prompts: Record<string, string>;
2398
+ /** Called when a prompt is saved */
2399
+ onPromptChange: (tool: string, value: string) => void;
2400
+ /** Tool tabs to display */
2401
+ tools: ToolTab[];
2402
+ /** Default/reset prompts keyed by tool id */
2403
+ defaultPrompts?: Record<string, string>;
2404
+ /** Available template variables */
2405
+ variables?: PromptPlaceholder[];
2406
+ /** Called when reset is triggered */
2407
+ onReset?: (tool: string) => void;
2408
+ /** Called when save is triggered */
2409
+ onSave?: (tool: string, content: string) => void;
2410
+ /** When true, validates that prompt contains "## Verification Checklist" */
2411
+ validateChecklist?: boolean;
2412
+ /** When true, adds border and rounding for standalone usage */
2413
+ standalone?: boolean;
2414
+ className?: string;
2415
+ }
2416
+ declare function TabbedPromptEditor({ prompts, onPromptChange, tools, defaultPrompts, variables, onReset, onSave, validateChecklist, standalone, className, }: TabbedPromptEditorProps): react_jsx_runtime.JSX.Element;
2417
+
2418
+ interface FileTypeTabbedPromptEditorProps {
2419
+ /** Nested prompts: fileType -> tool -> prompt */
2420
+ prompts: Record<string, Record<string, string>>;
2421
+ /** Called when a prompt changes */
2422
+ onPromptChange: (fileType: string, tool: string, value: string) => void;
2423
+ /** Available file types for the sidebar */
2424
+ fileTypes: FileTypeOption[];
2425
+ /** Tool tabs to display */
2426
+ tools: ToolTab[];
2427
+ /** Default prompts for reset: fileType -> tool -> prompt */
2428
+ defaultPrompts?: Record<string, Record<string, string>>;
2429
+ /** Variables per file type */
2430
+ variables?: Record<string, PromptPlaceholder[]>;
2431
+ /** Called when reset is triggered */
2432
+ onReset?: (fileType: string, tool: string) => void;
2433
+ /** Called when save is triggered */
2434
+ onSave?: (fileType: string, tool: string, content: string) => void;
2435
+ /** Custom label for sidebar header (default: "Target") */
2436
+ selectorLabel?: string;
2437
+ /** Custom sublabel for sidebar header (default: "Select target file type") */
2438
+ selectorSublabel?: string;
2439
+ /** When true, validates "## Verification Checklist" section */
2440
+ validateChecklist?: boolean;
2441
+ className?: string;
2442
+ }
2443
+ declare function FileTypeTabbedPromptEditor({ prompts, onPromptChange, fileTypes, tools, defaultPrompts, variables, onReset, onSave, selectorLabel, selectorSublabel, validateChecklist, className, }: FileTypeTabbedPromptEditorProps): react_jsx_runtime.JSX.Element;
2444
+
2445
+ interface SimulatorPromptEditorProps {
2446
+ /** Nested prompts: scenario -> step -> tool -> prompt */
2447
+ prompts: Record<string, Record<string, Record<string, string>>>;
2448
+ /** Called when a prompt changes */
2449
+ onPromptChange: (scenario: string, step: string, tool: string, value: string) => void;
2450
+ /** Available scenarios with their steps */
2451
+ scenarios: ScenarioOption[];
2452
+ /** Tool tabs to display */
2453
+ tools: ToolTab[];
2454
+ /** Default prompts for reset: scenario -> step -> tool -> prompt */
2455
+ defaultPrompts?: Record<string, Record<string, Record<string, string>>>;
2456
+ /** Variables per scenario/step (key format: "scenario:step") */
2457
+ variables?: Record<string, PromptPlaceholder[]>;
2458
+ /** Called when reset is triggered */
2459
+ onReset?: (scenario: string, step: string, tool: string) => void;
2460
+ /** Called when save is triggered */
2461
+ onSave?: (scenario: string, step: string, tool: string, content: string) => void;
2462
+ /** When true, validates "## Verification Checklist" section */
2463
+ validateChecklist?: boolean;
2464
+ className?: string;
2465
+ }
2466
+ declare function SimulatorPromptEditor({ prompts, onPromptChange, scenarios, tools, defaultPrompts, variables, onReset, onSave, validateChecklist, className, }: SimulatorPromptEditorProps): react_jsx_runtime.JSX.Element;
2467
+
2468
+ interface CollapsibleSectionProps {
2469
+ title: string;
2470
+ icon?: IconName;
2471
+ iconColor?: string;
2472
+ defaultOpen?: boolean;
2473
+ badge?: string | number;
2474
+ badgeColor?: BadgeColor;
2475
+ children: React.ReactNode;
2476
+ className?: string;
2477
+ }
2478
+ declare function CollapsibleSection({ title, icon, iconColor, defaultOpen, badge, badgeColor, children, className, }: CollapsibleSectionProps): react_jsx_runtime.JSX.Element;
2479
+
2480
+ interface FileEntry {
2481
+ path: string;
2482
+ name: string;
2483
+ type: 'file' | 'folder';
2484
+ icon?: IconName;
2485
+ color?: string;
2486
+ badge?: string;
2487
+ children?: FileEntry[];
2488
+ }
2489
+ interface FilesPanelProps {
2490
+ files: FileEntry[];
2491
+ selectedPath?: string;
2492
+ onSelect?: (path: string) => void;
2493
+ onAction?: (action: string, path: string) => void;
2494
+ showSearch?: boolean;
2495
+ className?: string;
2496
+ }
2497
+ declare function FilesPanel({ files, selectedPath, onSelect, onAction, showSearch, className, }: FilesPanelProps): react_jsx_runtime.JSX.Element;
2498
+
2499
+ /** Searchable panel for browsing, copying, and inserting code snippets. */
2500
+ interface Snippet {
2501
+ id: string;
2502
+ label: string;
2503
+ language?: string;
2504
+ description?: string;
2505
+ code: string;
2506
+ tags?: string[];
2507
+ }
2508
+ interface SnippetsPanelProps {
2509
+ snippets: Snippet[];
2510
+ onInsert?: (id: string) => void;
2511
+ onCopy?: (id: string) => void;
2512
+ showSearch?: boolean;
2513
+ className?: string;
2514
+ }
2515
+ declare function SnippetsPanel({ snippets, onInsert, onCopy, showSearch, className, }: SnippetsPanelProps): react_jsx_runtime.JSX.Element;
2516
+
2517
+ interface BreadcrumbSegment {
2518
+ id: string;
2519
+ label: string;
2520
+ icon?: IconName;
2521
+ color?: string;
2522
+ onClick?: () => void;
2523
+ }
2524
+ interface BreadcrumbProps {
2525
+ segments: BreadcrumbSegment[];
2526
+ separator?: 'chevron' | 'slash' | 'dot';
2527
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
2528
+ className?: string;
2529
+ }
2530
+ declare function Breadcrumb({ segments, separator, size, className, }: BreadcrumbProps): react_jsx_runtime.JSX.Element;
2531
+
2532
+ interface NavigationBarProps {
2533
+ segments: BreadcrumbSegment[];
2534
+ canGoBack?: boolean;
2535
+ canGoForward?: boolean;
2536
+ onBack?: () => void;
2537
+ onForward?: () => void;
2538
+ showHistory?: boolean;
2539
+ historyEntries?: BreadcrumbSegment[][];
2540
+ onHistorySelect?: (index: number) => void;
2541
+ leadingAction?: {
2542
+ icon: IconName;
2543
+ onClick?: () => void;
2544
+ };
2545
+ separator?: 'chevron' | 'slash' | 'dot';
2546
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
2547
+ className?: string;
2548
+ }
2549
+ declare function NavigationBar({ segments, canGoBack, canGoForward, onBack, onForward, showHistory, historyEntries, onHistorySelect, leadingAction, separator, size, className, }: NavigationBarProps): react_jsx_runtime.JSX.Element;
2550
+
2551
+ interface Tab {
2552
+ id: string;
2553
+ label: string;
2554
+ icon?: IconName;
2555
+ color?: string;
2556
+ closable?: boolean;
2557
+ badge?: number | string;
2558
+ badgeColor?: BadgeColor;
2559
+ }
2560
+ interface TabBarProps {
2561
+ tabs: Tab[];
2562
+ activeId: string;
2563
+ onSelect: (id: string) => void;
2564
+ onClose?: (id: string) => void;
2565
+ variant?: 'underline' | 'pill' | 'card';
2566
+ size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg';
2567
+ className?: string;
2568
+ }
2569
+ declare function TabBar({ tabs, activeId, onSelect, onClose, variant, size, className, }: TabBarProps): react_jsx_runtime.JSX.Element;
2570
+
2571
+ interface LayoutTab {
2572
+ id: string;
2573
+ title: string;
2574
+ subtitle?: string;
2575
+ subtitleIcon?: ReactNode;
2576
+ icon?: ReactNode;
2577
+ color?: string;
2578
+ selectedColor?: string;
2579
+ titleColor?: string;
2580
+ iconColor?: string;
2581
+ subtitleColor?: string;
2582
+ subtitleIconColor?: string;
2583
+ closable?: boolean;
2584
+ }
2585
+ interface LayoutTabBarProps {
2586
+ tabs: LayoutTab[];
2587
+ activeId: string | null;
2588
+ onSelect: (id: string) => void;
2589
+ onClose?: (id: string) => void;
2590
+ onReorder?: (fromIndex: number, toIndex: number) => void;
2591
+ className?: string;
2592
+ }
2593
+ declare function LayoutTabBar({ tabs, activeId, onSelect, onClose, onReorder, className }: LayoutTabBarProps): react_jsx_runtime.JSX.Element;
2594
+
2595
+ interface NavCardProps {
2596
+ title: string;
2597
+ description?: string;
2598
+ icon?: IconName;
2599
+ iconColor?: string;
2600
+ badge?: number | string;
2601
+ badgeColor?: BadgeColor;
2602
+ onClick?: () => void;
2603
+ disabled?: boolean;
2604
+ className?: string;
2605
+ }
2606
+ declare function NavCard({ title, description, icon, iconColor, badge, badgeColor, onClick, disabled, className, }: NavCardProps): react_jsx_runtime.JSX.Element;
2607
+
2608
+ interface ExtensionListCardProps {
2609
+ /** Lucide icon component */
2610
+ icon: ElementType;
2611
+ /** Tailwind color class for icon (e.g. 'text-teal-400') */
2612
+ iconColor: string;
2613
+ /** Tailwind color class for left border (e.g. 'border-l-teal-400') */
2614
+ borderColor: string;
2615
+ /** Card title */
2616
+ title: string;
2617
+ /** Custom title class (defaults to 'text-white') */
2618
+ titleClassName?: string;
2619
+ /** Badges rendered after the title */
2620
+ badges?: ReactNode;
2621
+ /** Description text or node (can be string or ReactNode for custom formatting) */
2622
+ description?: ReactNode;
2623
+ /** Action buttons (shown on hover) */
2624
+ actions?: ReactNode;
2625
+ /** Metadata row at bottom. Can be a render function receiving hover state. */
2626
+ metadata?: ReactNode | ((isHovered: boolean) => ReactNode);
2627
+ /** Whether card is inactive/dimmed */
2628
+ isInactive?: boolean;
2629
+ /** Test ID for E2E testing */
2630
+ testId?: string;
2631
+ }
2632
+ declare const ExtensionListCard: react.NamedExoticComponent<ExtensionListCardProps>;
2633
+
2634
+ type StatusType = 'success' | 'warning' | 'error' | 'info' | 'neutral';
2635
+ interface StatusItem {
2636
+ label: string;
2637
+ value: string | number;
2638
+ status: StatusType;
2639
+ }
2640
+ interface StatusCardProps {
2641
+ title: string;
2642
+ icon?: IconName;
2643
+ iconColor?: string;
2644
+ items: StatusItem[];
2645
+ action?: {
2646
+ label: string;
2647
+ onClick: () => void;
2648
+ };
2649
+ className?: string;
2650
+ }
2651
+ declare function StatusCard({ title, icon, iconColor, items, action, className, }: StatusCardProps): react_jsx_runtime.JSX.Element;
2652
+
2653
+ /** Snapshot card with status stripe, stats grid, and sync/view actions. */
2654
+ type SnapshotStatus = 'synced' | 'pending' | 'conflict' | 'outdated';
2655
+ interface SnapshotCardProps {
2656
+ title: string;
2657
+ timestamp?: string;
2658
+ status: SnapshotStatus;
2659
+ description?: string;
2660
+ stats?: {
2661
+ label: string;
2662
+ value: string | number;
2663
+ }[];
2664
+ onSync?: () => void;
2665
+ onView?: () => void;
2666
+ className?: string;
2667
+ }
2668
+ declare function SnapshotCard({ title, timestamp, status, description, stats, onSync, onView, className, }: SnapshotCardProps): react_jsx_runtime.JSX.Element;
2669
+
2670
+ interface DetailRow {
2671
+ label: string;
2672
+ value: string;
2673
+ mono?: boolean;
2674
+ }
2675
+ interface DetailSectionProps {
2676
+ /** Section title (e.g., "Execution Details") */
2677
+ title: string;
2678
+ /** Icon before the title */
2679
+ icon?: IconName;
2680
+ /** Detail rows to display */
2681
+ rows: DetailRow[];
2682
+ className?: string;
2683
+ }
2684
+ declare function DetailSection({ title, icon, rows, className }: DetailSectionProps): react_jsx_runtime.JSX.Element;
2685
+
2686
+ /**
2687
+ * Close a menu/dropdown when clicking outside its ref element.
2688
+ * If ref is null, closes on any mousedown event.
2689
+ */
2690
+ declare function useClickOutside(ref: RefObject<HTMLElement | null> | null, isOpen: boolean, onClose: () => void): void;
2691
+
2692
+ /**
2693
+ * Constrains a dropdown menu's height to fit within the viewport.
2694
+ * Sets max-height = viewport bottom - element top - margin, and enables vertical scrolling.
2695
+ */
2696
+ declare function useDropdownMaxHeight<T extends HTMLElement>(isOpen: boolean, margin?: number): react.RefObject<T | null>;
2697
+
2698
+ /** Hook for managing back/forward navigation history with a breadcrumb segment stack. */
2699
+
2700
+ interface UseNavigationHistoryReturn {
2701
+ current: BreadcrumbSegment[] | null;
2702
+ canGoBack: boolean;
2703
+ canGoForward: boolean;
2704
+ push: (segments: BreadcrumbSegment[]) => void;
2705
+ goBack: () => void;
2706
+ goForward: () => void;
2707
+ goTo: (index: number) => void;
2708
+ history: BreadcrumbSegment[][];
2709
+ }
2710
+ declare function useNavigationHistory(initial?: BreadcrumbSegment[], maxEntries?: number): UseNavigationHistoryReturn;
2711
+
2712
+ declare function cn(...inputs: ClassValue[]): string;
2713
+
2714
+ export { ACCENT_DEFS, AI_TOOL_LOGOS, AI_TOOL_NAMES, type AccentColor, type AccentDef, ActionDialog, type ActionDialogProps, type ActionItem, AiActionButton, type AiActionButtonProps, type AiActionStatus, type AiCompletionResult, AiExecutionActionButtons, type AiExecutionActionButtonsProps, type AiToolConfig, AiToolIcon, type AiToolKey, AlertModal, type AlertModalProps, BASE_THEMES, Badge, type BadgeColor, type BadgeProps, BottomPanelHeader, type BottomPanelHeaderProps, Breadcrumb, type BreadcrumbProps, type BreadcrumbSegment, type CapturedError, type CapturedIssuesApi, CapturedIssuesPanel, type CapturedIssuesPanelProps, type ChangedComponents, Checkbox, type CheckboxColor, type CheckboxProps, type CheckboxSize, type CheckboxVariant, type CodingToolId, type CodingToolPresetConfig, CollapseButton, type CollapseButtonProps, CollapsibleSection, type CollapsibleSectionProps, type ComponentVersion, ConfirmBadge, type ConfirmBadgeColor, type ConfirmBadgeProps, ConfirmModal, type ConfirmModalProps, type CreateSnapshotResult, DARK_THEMES, type DetailRow, DetailSection, type DetailSectionProps, DetailViewWrapper, type DetailViewWrapperProps, type DiffSummary, type DiffTreeNode, type DirectoryStatus, EditorPlaceholderCard, type EditorPlaceholderCardProps, EditorToolbar, type EditorToolbarProps, type ErrorLogger, type ExecutionDetailRow, ExecutionDetailsPanel, type ExecutionDetailsPanelProps, type ExecutionStatus, ExtensionListCard, type ExtensionListCardProps, type ExtensionSource, type FileDiffInfo, type FileDiffStatus, FileDiffViewer, type FileDiffViewerProps, type FileEntry, FileStructureSection, type FileStructureSectionProps, FileTree, type FileTreeNode, type FileTreeProps, type FileTypeOption, FileTypeTabbedPromptEditor, type FileTypeTabbedPromptEditorProps, FilesPanel, type FilesPanelProps, FilterDropdown, type FilterDropdownProps, FormActions, type FormActionsProps, type FormColor, FrontmatterFormHeader, type FrontmatterFormHeaderProps, type GoldenLiveDiff, type GoldenMeta, type GoldenSnapshotsApi, type GoldenStatus, GoldenSyncPanel, type GoldenSyncPanelProps, ISSUE_TYPES, IconButton, type IconButtonColor, type IconButtonProps, type IconButtonStatus, type IconButtonVariant, type IconName, Input, type InputProps, type IssueReport, type IssueReportResult, type IssueType, LIGHT_THEMES, Label, type LabelColor, type LabelProps, type LayoutTab, LayoutTabBar, type LayoutTabBarProps, type ModalKind, type ModalSize, NavCard, type NavCardProps, NavigationBar, type NavigationBarProps, NumberInput, type NumberInputProps, type PanelTab, type PreviewMode, type PromptEditorApi, type PromptPlaceholder, type PromptSnapshot, RegistryBrowser, type RegistryBrowserProps, RegistryCard, type RegistryCardProps, RegistryDetail, type RegistryDetailProps, type RegistryItemType, ReportBugForm, type ReportBugFormProps, type ResetResult, ResizableTextarea, type ResizableTextareaProps, SCALE_KEYS, SNIPPET_NAME_REGEX, type ScaleKey, type ScenarioOption, ScopeBadge, type ScopeType, type Screenshot, type ScreenshotAttachment, ScreenshotUploader, type ScreenshotUploaderProps, type SeedInfo, type SeedrItemStatus, SegmentedToggle, type SegmentedToggleOption, type SegmentedToggleProps, Select, type SelectOption, type SelectProps, type SelectionCardItem, SelectionGrid, type SelectionGridProps, SettingRow, type SettingRowProps, SimulatorPromptEditor, type SimulatorPromptEditorProps, type SnapshotBrowserApi, SnapshotBrowserPanel, type SnapshotBrowserPanelProps, SnapshotCard, type SnapshotCardProps, type SnapshotCategory, type SnapshotEntry, type SnapshotInfo, type SnapshotItem, SnapshotManager, type SnapshotManagerProps, type SnapshotScope, SnapshotTree, type SnapshotTreeProps, type SnapshotsManifest, type Snippet, type SnippetData, SnippetsEditor, type SnippetsEditorApi, type SnippetsEditorProps, SnippetsPanel, type SnippetsPanelProps, SortDropdown, type SortDropdownProps, type SortField, type StatusBanner, StatusCard, type StatusCardProps, type StatusItem, StatusOverview, type StatusOverviewProps, type SubmittedError, type SystemInfo, TOOLR_APPS, type Tab, TabBar, type TabBarProps, TabbedPromptEditor, type TabbedPromptEditorProps, type ThemeId, Toggle, type ToggleColor, type ToggleProps, type ToggleSize, type ToggleVariant, type ToolDetectionResult, type ToolTab, type ToolrAppId, ToolrAppLogo, type ToolsPathsApi, ToolsPathsPanel, type ToolsPathsPanelProps, Tooltip, type TooltipAlign, TooltipButton, type TooltipContent, type TooltipPosition, type TrackedError, type UseCapturedIssuesOptions, type UseCapturedIssuesReturn, type UseGoldenSyncOptions, type UseGoldenSyncReturn, type UseNavigationHistoryReturn, type UsePromptEditorOptions, type UsePromptEditorReturn, type UseReportBugOptions, type UseReportBugReturn, type UseSnapshotBrowserOptions, type UseSnapshotBrowserReturn, type UseSnippetsEditorOptions, type UseSnippetsEditorReturn, type UseToolsPathsOptions, type UseToolsPathsReturn, VersionManager, type VersionManagerProps, applyTheme, cn, collectDirPaths, createErrorLogger, formatBytes, formatCategory, formatDate, generateScale, getLanguage, getLanguageFromPath, hslToHex, iconMap, isLightTheme, satCurve, submitIssueReport, useCapturedIssues, useClickOutside, useDropdownMaxHeight, useGoldenSync, useNavigationHistory, usePromptEditor, useReportBug, useSnapshotBrowser, useSnippetsEditor, useToolsPaths };