@zendir/ui 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 (359) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +589 -0
  4. package/dist/index.d.ts +8 -0
  5. package/dist/index.js +421 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/react/3d/EarthViewer.d.ts +46 -0
  8. package/dist/react/3d/EarthViewer.js +836 -0
  9. package/dist/react/3d/EarthViewer.js.map +1 -0
  10. package/dist/react/3d/SolarSystemViewer.d.ts +43 -0
  11. package/dist/react/3d/SolarSystemViewer.js +372 -0
  12. package/dist/react/3d/SolarSystemViewer.js.map +1 -0
  13. package/dist/react/3d/ZenSpace3D.d.ts +16 -0
  14. package/dist/react/3d/ZenSpace3D.js +1253 -0
  15. package/dist/react/3d/ZenSpace3D.js.map +1 -0
  16. package/dist/react/3d/ZenSpace3DCesium.d.ts +9 -0
  17. package/dist/react/3d/ZenSpace3DCesium.js +186 -0
  18. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
  19. package/dist/react/3d/ZenSpace3DShaders.d.ts +78 -0
  20. package/dist/react/3d/ZenSpace3DShaders.js +94 -0
  21. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
  22. package/dist/react/3d/ZenSpace3DTypes.d.ts +614 -0
  23. package/dist/react/3d/ZenSpace3DUtils.d.ts +183 -0
  24. package/dist/react/3d/ZenSpace3DUtils.js +213 -0
  25. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
  26. package/dist/react/3d/index.d.ts +23 -0
  27. package/dist/react/3d/threeLoader.d.ts +22 -0
  28. package/dist/react/3d/threeLoader.js +18 -0
  29. package/dist/react/3d/threeLoader.js.map +1 -0
  30. package/dist/react/astro/ClassificationBanner.d.ts +25 -0
  31. package/dist/react/astro/ClassificationBanner.js +83 -0
  32. package/dist/react/astro/ClassificationBanner.js.map +1 -0
  33. package/dist/react/astro/GlobalStatusBar.d.ts +42 -0
  34. package/dist/react/astro/GlobalStatusBar.js +165 -0
  35. package/dist/react/astro/GlobalStatusBar.js.map +1 -0
  36. package/dist/react/astro/MissionClock.d.ts +169 -0
  37. package/dist/react/astro/MissionClock.js +411 -0
  38. package/dist/react/astro/MissionClock.js.map +1 -0
  39. package/dist/react/astro/MonitoringIcon.d.ts +60 -0
  40. package/dist/react/astro/MonitoringIcon.js +369 -0
  41. package/dist/react/astro/MonitoringIcon.js.map +1 -0
  42. package/dist/react/astro/Notification.d.ts +42 -0
  43. package/dist/react/astro/Notification.js +156 -0
  44. package/dist/react/astro/Notification.js.map +1 -0
  45. package/dist/react/astro/Progress.d.ts +39 -0
  46. package/dist/react/astro/Progress.js +149 -0
  47. package/dist/react/astro/Progress.js.map +1 -0
  48. package/dist/react/astro/SimulationControls.d.ts +136 -0
  49. package/dist/react/astro/SimulationControls.js +668 -0
  50. package/dist/react/astro/SimulationControls.js.map +1 -0
  51. package/dist/react/astro/StatusIndicator.d.ts +34 -0
  52. package/dist/react/astro/StatusIndicator.js +189 -0
  53. package/dist/react/astro/StatusIndicator.js.map +1 -0
  54. package/dist/react/astro/UnifiedTimeline.d.ts +106 -0
  55. package/dist/react/astro/UnifiedTimeline.js +1768 -0
  56. package/dist/react/astro/UnifiedTimeline.js.map +1 -0
  57. package/dist/react/astro/index.d.ts +63 -0
  58. package/dist/react/cards/AccessCard.d.ts +37 -0
  59. package/dist/react/cards/AccessCard.js +410 -0
  60. package/dist/react/cards/AccessCard.js.map +1 -0
  61. package/dist/react/cards/OrbitCard.d.ts +31 -0
  62. package/dist/react/cards/OrbitCard.js +372 -0
  63. package/dist/react/cards/OrbitCard.js.map +1 -0
  64. package/dist/react/cards/SpacecraftCard.d.ts +54 -0
  65. package/dist/react/cards/SpacecraftCard.js +941 -0
  66. package/dist/react/cards/SpacecraftCard.js.map +1 -0
  67. package/dist/react/cards/TelemetryCard.d.ts +40 -0
  68. package/dist/react/cards/TelemetryCard.js +742 -0
  69. package/dist/react/cards/TelemetryCard.js.map +1 -0
  70. package/dist/react/cards/TelemetryStreamCard.d.ts +59 -0
  71. package/dist/react/cards/TelemetryStreamCard.js +309 -0
  72. package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
  73. package/dist/react/cards/index.d.ts +13 -0
  74. package/dist/react/charts/GroundTrackMap.d.ts +112 -0
  75. package/dist/react/charts/GroundTrackMap.js +1123 -0
  76. package/dist/react/charts/GroundTrackMap.js.map +1 -0
  77. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +26 -0
  78. package/dist/react/charts/GroundTrackMapLeaflet.js +571 -0
  79. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -0
  80. package/dist/react/charts/groundTrackMapLeafletTiles.d.ts +22 -0
  81. package/dist/react/charts/groundTrackMapLeafletTiles.js +11 -0
  82. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -0
  83. package/dist/react/charts/groundTrackMapLeafletUtils.d.ts +24 -0
  84. package/dist/react/charts/groundTrackMapLeafletUtils.js +109 -0
  85. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -0
  86. package/dist/react/charts/index.d.ts +10 -0
  87. package/dist/react/charts/unified/AstroChart.d.ts +24 -0
  88. package/dist/react/charts/unified/AstroChart.js +1405 -0
  89. package/dist/react/charts/unified/AstroChart.js.map +1 -0
  90. package/dist/react/charts/unified/PowerOverviewChart.d.ts +73 -0
  91. package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
  92. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
  93. package/dist/react/charts/unified/domain.d.ts +845 -0
  94. package/dist/react/charts/unified/domain.js +3168 -0
  95. package/dist/react/charts/unified/domain.js.map +1 -0
  96. package/dist/react/charts/unified/generators.d.ts +276 -0
  97. package/dist/react/charts/unified/generators.js +518 -0
  98. package/dist/react/charts/unified/generators.js.map +1 -0
  99. package/dist/react/charts/unified/index.d.ts +55 -0
  100. package/dist/react/charts/unified/presets.d.ts +290 -0
  101. package/dist/react/charts/unified/presets.js +999 -0
  102. package/dist/react/charts/unified/presets.js.map +1 -0
  103. package/dist/react/charts/unified/sync.d.ts +69 -0
  104. package/dist/react/charts/unified/sync.js +219 -0
  105. package/dist/react/charts/unified/sync.js.map +1 -0
  106. package/dist/react/charts/unified/theme.d.ts +447 -0
  107. package/dist/react/charts/unified/theme.js +562 -0
  108. package/dist/react/charts/unified/theme.js.map +1 -0
  109. package/dist/react/charts/unified/types.d.ts +826 -0
  110. package/dist/react/charts/unified/useChartStream.d.ts +58 -0
  111. package/dist/react/charts/unified/useChartStream.js +226 -0
  112. package/dist/react/charts/unified/useChartStream.js.map +1 -0
  113. package/dist/react/chatgpt/AppCard.d.ts +59 -0
  114. package/dist/react/chatgpt/AppCard.js +306 -0
  115. package/dist/react/chatgpt/AppCard.js.map +1 -0
  116. package/dist/react/chatgpt/ChatGPTCard.d.ts +6 -0
  117. package/dist/react/chatgpt/index.d.ts +167 -0
  118. package/dist/react/chatgpt/index.js +166 -0
  119. package/dist/react/chatgpt/index.js.map +1 -0
  120. package/dist/react/context/DisplaySettingsContext.d.ts +107 -0
  121. package/dist/react/context/DisplaySettingsContext.js +169 -0
  122. package/dist/react/context/DisplaySettingsContext.js.map +1 -0
  123. package/dist/react/context/index.d.ts +5 -0
  124. package/dist/react/core/ActivityPlanner.d.ts +45 -0
  125. package/dist/react/core/ActivityPlanner.js +532 -0
  126. package/dist/react/core/ActivityPlanner.js.map +1 -0
  127. package/dist/react/core/AppBar.d.ts +71 -0
  128. package/dist/react/core/AppBar.js +817 -0
  129. package/dist/react/core/AppBar.js.map +1 -0
  130. package/dist/react/core/AstroIcon.d.ts +84 -0
  131. package/dist/react/core/AstroIcon.js +1243 -0
  132. package/dist/react/core/AstroIcon.js.map +1 -0
  133. package/dist/react/core/Badge.d.ts +27 -0
  134. package/dist/react/core/Badge.js +134 -0
  135. package/dist/react/core/Badge.js.map +1 -0
  136. package/dist/react/core/Button.d.ts +26 -0
  137. package/dist/react/core/Button.js +306 -0
  138. package/dist/react/core/Button.js.map +1 -0
  139. package/dist/react/core/CardHeader.d.ts +34 -0
  140. package/dist/react/core/CardHeader.js +316 -0
  141. package/dist/react/core/CardHeader.js.map +1 -0
  142. package/dist/react/core/ChatPanel.d.ts +627 -0
  143. package/dist/react/core/ChatPanel.js +1144 -0
  144. package/dist/react/core/ChatPanel.js.map +1 -0
  145. package/dist/react/core/Checkbox.d.ts +26 -0
  146. package/dist/react/core/Checkbox.js +130 -0
  147. package/dist/react/core/Checkbox.js.map +1 -0
  148. package/dist/react/core/ColorPickerPanel.d.ts +25 -0
  149. package/dist/react/core/ColorPickerPanel.js +293 -0
  150. package/dist/react/core/ColorPickerPanel.js.map +1 -0
  151. package/dist/react/core/CommandBuilder.d.ts +74 -0
  152. package/dist/react/core/CommandBuilder.js +518 -0
  153. package/dist/react/core/CommandBuilder.js.map +1 -0
  154. package/dist/react/core/ConfirmDialog.d.ts +45 -0
  155. package/dist/react/core/ConfirmDialog.js +315 -0
  156. package/dist/react/core/ConfirmDialog.js.map +1 -0
  157. package/dist/react/core/ConnectionForm.d.ts +57 -0
  158. package/dist/react/core/ConnectionForm.js +496 -0
  159. package/dist/react/core/ConnectionForm.js.map +1 -0
  160. package/dist/react/core/Container.d.ts +51 -0
  161. package/dist/react/core/Container.js +670 -0
  162. package/dist/react/core/Container.js.map +1 -0
  163. package/dist/react/core/CopyButton.d.ts +39 -0
  164. package/dist/react/core/CopyButton.js +105 -0
  165. package/dist/react/core/CopyButton.js.map +1 -0
  166. package/dist/react/core/DataTable.d.ts +113 -0
  167. package/dist/react/core/DataTable.js +446 -0
  168. package/dist/react/core/DataTable.js.map +1 -0
  169. package/dist/react/core/DataValue.d.ts +64 -0
  170. package/dist/react/core/DataValue.js +545 -0
  171. package/dist/react/core/DataValue.js.map +1 -0
  172. package/dist/react/core/Dialog.d.ts +32 -0
  173. package/dist/react/core/Dialog.js +201 -0
  174. package/dist/react/core/Dialog.js.map +1 -0
  175. package/dist/react/core/FileExplorer.d.ts +65 -0
  176. package/dist/react/core/FileExplorer.js +520 -0
  177. package/dist/react/core/FileExplorer.js.map +1 -0
  178. package/dist/react/core/GlassCard.d.ts +129 -0
  179. package/dist/react/core/GlassCard.js +375 -0
  180. package/dist/react/core/GlassCard.js.map +1 -0
  181. package/dist/react/core/HeaderIconWithStatus.d.ts +39 -0
  182. package/dist/react/core/HeaderIconWithStatus.js +157 -0
  183. package/dist/react/core/HeaderIconWithStatus.js.map +1 -0
  184. package/dist/react/core/HexViewer.d.ts +143 -0
  185. package/dist/react/core/HexViewer.js +1106 -0
  186. package/dist/react/core/HexViewer.js.map +1 -0
  187. package/dist/react/core/Icon.d.ts +32 -0
  188. package/dist/react/core/Icon.js +142 -0
  189. package/dist/react/core/Icon.js.map +1 -0
  190. package/dist/react/core/ImageGallery.d.ts +41 -0
  191. package/dist/react/core/ImageGallery.js +320 -0
  192. package/dist/react/core/ImageGallery.js.map +1 -0
  193. package/dist/react/core/Input.d.ts +38 -0
  194. package/dist/react/core/Input.js +288 -0
  195. package/dist/react/core/Input.js.map +1 -0
  196. package/dist/react/core/LimitsBar.d.ts +51 -0
  197. package/dist/react/core/LimitsBar.js +200 -0
  198. package/dist/react/core/LimitsBar.js.map +1 -0
  199. package/dist/react/core/LogViewer.d.ts +61 -0
  200. package/dist/react/core/LogViewer.js +599 -0
  201. package/dist/react/core/LogViewer.js.map +1 -0
  202. package/dist/react/core/MessageStream.d.ts +58 -0
  203. package/dist/react/core/MessageStream.js +455 -0
  204. package/dist/react/core/MessageStream.js.map +1 -0
  205. package/dist/react/core/MissionCalendar.d.ts +81 -0
  206. package/dist/react/core/MissionCalendar.js +1049 -0
  207. package/dist/react/core/MissionCalendar.js.map +1 -0
  208. package/dist/react/core/NumberInput.d.ts +85 -0
  209. package/dist/react/core/NumberInput.js +507 -0
  210. package/dist/react/core/NumberInput.js.map +1 -0
  211. package/dist/react/core/PacketViewer.d.ts +73 -0
  212. package/dist/react/core/PacketViewer.js +431 -0
  213. package/dist/react/core/PacketViewer.js.map +1 -0
  214. package/dist/react/core/Pagination.d.ts +30 -0
  215. package/dist/react/core/Pagination.js +190 -0
  216. package/dist/react/core/Pagination.js.map +1 -0
  217. package/dist/react/core/PinInput.d.ts +41 -0
  218. package/dist/react/core/PinInput.js +210 -0
  219. package/dist/react/core/PinInput.js.map +1 -0
  220. package/dist/react/core/Popover.d.ts +55 -0
  221. package/dist/react/core/Popover.js +288 -0
  222. package/dist/react/core/Popover.js.map +1 -0
  223. package/dist/react/core/Select.d.ts +42 -0
  224. package/dist/react/core/Select.js +303 -0
  225. package/dist/react/core/Select.js.map +1 -0
  226. package/dist/react/core/SideNav.d.ts +103 -0
  227. package/dist/react/core/SideNav.js +551 -0
  228. package/dist/react/core/SideNav.js.map +1 -0
  229. package/dist/react/core/SidePanel.d.ts +33 -0
  230. package/dist/react/core/SidePanel.js +199 -0
  231. package/dist/react/core/SidePanel.js.map +1 -0
  232. package/dist/react/core/Tabs.d.ts +47 -0
  233. package/dist/react/core/Tabs.js +129 -0
  234. package/dist/react/core/Tabs.js.map +1 -0
  235. package/dist/react/core/Toast.d.ts +56 -0
  236. package/dist/react/core/Toast.js +229 -0
  237. package/dist/react/core/Toast.js.map +1 -0
  238. package/dist/react/core/Toggle.d.ts +22 -0
  239. package/dist/react/core/Toggle.js +151 -0
  240. package/dist/react/core/Toggle.js.map +1 -0
  241. package/dist/react/core/Tooltip.d.ts +19 -0
  242. package/dist/react/core/Tooltip.js +179 -0
  243. package/dist/react/core/Tooltip.js.map +1 -0
  244. package/dist/react/core/Typography.d.ts +127 -0
  245. package/dist/react/core/Typography.js +187 -0
  246. package/dist/react/core/Typography.js.map +1 -0
  247. package/dist/react/core/index.d.ts +108 -0
  248. package/dist/react/core/layout/Box.d.ts +77 -0
  249. package/dist/react/core/layout/Box.js +126 -0
  250. package/dist/react/core/layout/Box.js.map +1 -0
  251. package/dist/react/core/layout/Center.d.ts +20 -0
  252. package/dist/react/core/layout/Center.js +34 -0
  253. package/dist/react/core/layout/Center.js.map +1 -0
  254. package/dist/react/core/layout/Divider.d.ts +16 -0
  255. package/dist/react/core/layout/Divider.js +108 -0
  256. package/dist/react/core/layout/Divider.js.map +1 -0
  257. package/dist/react/core/layout/Flex.d.ts +30 -0
  258. package/dist/react/core/layout/Flex.js +128 -0
  259. package/dist/react/core/layout/Flex.js.map +1 -0
  260. package/dist/react/core/layout/Grid.d.ts +36 -0
  261. package/dist/react/core/layout/Grid.js +142 -0
  262. package/dist/react/core/layout/Grid.js.map +1 -0
  263. package/dist/react/core/layout/Spacer.d.ts +8 -0
  264. package/dist/react/core/layout/Spacer.js +31 -0
  265. package/dist/react/core/layout/Spacer.js.map +1 -0
  266. package/dist/react/core/layout/Stack.d.ts +54 -0
  267. package/dist/react/core/layout/Stack.js +74 -0
  268. package/dist/react/core/layout/Stack.js.map +1 -0
  269. package/dist/react/core/layout/index.d.ts +38 -0
  270. package/dist/react/core/layout/responsive.d.ts +23 -0
  271. package/dist/react/core/layout/responsive.js +26 -0
  272. package/dist/react/core/layout/responsive.js.map +1 -0
  273. package/dist/react/core/layout/useBreakpoint.d.ts +77 -0
  274. package/dist/react/core/layout/useBreakpoint.js +73 -0
  275. package/dist/react/core/layout/useBreakpoint.js.map +1 -0
  276. package/dist/react/core/propertyConfig.d.ts +443 -0
  277. package/dist/react/core/propertyConfig.js +399 -0
  278. package/dist/react/core/propertyConfig.js.map +1 -0
  279. package/dist/react/hooks/index.d.ts +21 -0
  280. package/dist/react/hooks/useAccessWindows.d.ts +66 -0
  281. package/dist/react/hooks/useCompactMode.d.ts +82 -0
  282. package/dist/react/hooks/useCompactMode.js +62 -0
  283. package/dist/react/hooks/useCompactMode.js.map +1 -0
  284. package/dist/react/hooks/useLiveSelection.d.ts +57 -0
  285. package/dist/react/hooks/useSimulationPlayback.d.ts +97 -0
  286. package/dist/react/hooks/useSimulationTime.d.ts +61 -0
  287. package/dist/react/hooks/useSpacecraftPosition.d.ts +50 -0
  288. package/dist/react/hooks/useSpacecraftPosition.js +89 -0
  289. package/dist/react/hooks/useSpacecraftPosition.js.map +1 -0
  290. package/dist/react/hooks/useTelemetry.d.ts +55 -0
  291. package/dist/react/hooks/useTelemetry.js +73 -0
  292. package/dist/react/hooks/useTelemetry.js.map +1 -0
  293. package/dist/react/hooks/useZendirSession.d.ts +109 -0
  294. package/dist/react/hooks/useZendirSession.js +148 -0
  295. package/dist/react/hooks/useZendirSession.js.map +1 -0
  296. package/dist/react/index.d.ts +74 -0
  297. package/dist/react/shared/ErrorBoundary.d.ts +63 -0
  298. package/dist/react/shared/ErrorBoundary.js +142 -0
  299. package/dist/react/shared/ErrorBoundary.js.map +1 -0
  300. package/dist/react/shared/Skeleton.d.ts +110 -0
  301. package/dist/react/shared/Skeleton.js +324 -0
  302. package/dist/react/shared/Skeleton.js.map +1 -0
  303. package/dist/react/shared/index.d.ts +12 -0
  304. package/dist/react/theme/ThemeProvider.d.ts +385 -0
  305. package/dist/react/theme/ThemeProvider.js +1096 -0
  306. package/dist/react/theme/ThemeProvider.js.map +1 -0
  307. package/dist/react/theme/astro-tokens.d.ts +153 -0
  308. package/dist/react/theme/cardAccent.d.ts +75 -0
  309. package/dist/react/theme/cardAccent.js +137 -0
  310. package/dist/react/theme/cardAccent.js.map +1 -0
  311. package/dist/react/theme/config.d.ts +39 -0
  312. package/dist/react/theme/index.d.ts +9 -0
  313. package/dist/react/types.d.ts +360 -0
  314. package/dist/react/types.js +58 -0
  315. package/dist/react/types.js.map +1 -0
  316. package/dist/react/utils/index.d.ts +247 -0
  317. package/dist/react/utils/index.js +423 -0
  318. package/dist/react/utils/index.js.map +1 -0
  319. package/dist/react/visualizations/EclipseTimerCard.d.ts +17 -0
  320. package/dist/react/visualizations/EclipseTimerCard.js +250 -0
  321. package/dist/react/visualizations/EclipseTimerCard.js.map +1 -0
  322. package/dist/react/visualizations/LinkBudgetCard.d.ts +50 -0
  323. package/dist/react/visualizations/LinkBudgetCard.js +444 -0
  324. package/dist/react/visualizations/LinkBudgetCard.js.map +1 -0
  325. package/dist/react/visualizations/NavBallCard.d.ts +17 -0
  326. package/dist/react/visualizations/NavBallCard.js +243 -0
  327. package/dist/react/visualizations/NavBallCard.js.map +1 -0
  328. package/dist/react/visualizations/PropulsionCard.d.ts +37 -0
  329. package/dist/react/visualizations/PropulsionCard.js +298 -0
  330. package/dist/react/visualizations/PropulsionCard.js.map +1 -0
  331. package/dist/react/visualizations/SensorFootprintCard.d.ts +33 -0
  332. package/dist/react/visualizations/SensorFootprintCard.js +326 -0
  333. package/dist/react/visualizations/SensorFootprintCard.js.map +1 -0
  334. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +38 -0
  335. package/dist/react/visualizations/ThermalHeatmapCard.js +372 -0
  336. package/dist/react/visualizations/ThermalHeatmapCard.js.map +1 -0
  337. package/dist/react/visualizations/index.d.ts +17 -0
  338. package/dist/react.d.ts +1 -0
  339. package/dist/react.js +421 -0
  340. package/dist/react.js.map +1 -0
  341. package/dist/shaders/atmosphere.frag.js +5 -0
  342. package/dist/shaders/atmosphere.frag.js.map +1 -0
  343. package/dist/shaders/atmosphere.vert.js +5 -0
  344. package/dist/shaders/atmosphere.vert.js.map +1 -0
  345. package/dist/shaders/stars.frag.js +5 -0
  346. package/dist/shaders/stars.frag.js.map +1 -0
  347. package/dist/shaders/stars.vert.js +5 -0
  348. package/dist/shaders/stars.vert.js.map +1 -0
  349. package/dist/style.css +143 -0
  350. package/dist/tokens/index.d.ts +296 -0
  351. package/dist/tokens/index.js +263 -0
  352. package/dist/tokens/index.js.map +1 -0
  353. package/dist/tokens/tokens.css +155 -0
  354. package/dist/types/index.d.ts +23 -0
  355. package/dist/types.d.ts +1 -0
  356. package/dist/types.js +2 -0
  357. package/dist/types.js.map +1 -0
  358. package/package.json +220 -0
  359. package/sdk-stub.js +22 -0
@@ -0,0 +1,1144 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import React, { memo, useState, useRef, useEffect, useCallback } from "react";
3
+ import { safeAccentText } from "../utils/index.js";
4
+ import { useTheme } from "../theme/ThemeProvider.js";
5
+ function parseYamlLite(text) {
6
+ const lines = [];
7
+ for (const raw of text.split("\n")) {
8
+ const content = raw.trimEnd();
9
+ if (content.trim() === "" || content.trim().startsWith("#")) continue;
10
+ lines.push({ indent: content.search(/\S/), text: content.trim() });
11
+ }
12
+ let pos = 0;
13
+ const peek = () => pos < lines.length ? lines[pos] : null;
14
+ const advance = () => lines[pos++];
15
+ function scalar(s) {
16
+ const v = s.trim();
17
+ if (v === "" || v === "null" || v === "~") return null;
18
+ if (v === "true") return true;
19
+ if (v === "false") return false;
20
+ if (/^-?\d+(\.\d+)?([eE][+-]?\d+)?$/.test(v)) return Number(v);
21
+ if (v.startsWith('"') && v.endsWith('"') || v.startsWith("'") && v.endsWith("'"))
22
+ return v.slice(1, -1);
23
+ if (v.startsWith("[") && v.endsWith("]") || v.startsWith("{") && v.endsWith("}")) {
24
+ try {
25
+ return JSON.parse(v);
26
+ } catch {
27
+ }
28
+ }
29
+ return v;
30
+ }
31
+ function parseValue(minIndent) {
32
+ const line = peek();
33
+ if (!line || line.indent < minIndent) return void 0;
34
+ const actualIndent = line.indent;
35
+ if (line.text.startsWith("- ")) return parseSequence(actualIndent);
36
+ return parseMapping(actualIndent);
37
+ }
38
+ function parseSequence(level) {
39
+ const arr = [];
40
+ while (peek() && peek().indent === level && peek().text.startsWith("- ")) {
41
+ const line = advance();
42
+ const after = line.text.slice(2).trim();
43
+ if (!after) {
44
+ const val = parseValue(level + 1);
45
+ arr.push(val ?? null);
46
+ continue;
47
+ }
48
+ const colonIdx = after.indexOf(":");
49
+ if (colonIdx > 0 && !/^['"]/.test(after)) {
50
+ const obj = {};
51
+ const k = after.slice(0, colonIdx).trim();
52
+ const v = after.slice(colonIdx + 1).trim();
53
+ obj[k] = v ? scalar(v) : parseValue(level + 3) ?? null;
54
+ const siblingIndent = level + 2;
55
+ while (peek() && peek().indent >= siblingIndent) {
56
+ if (peek().indent === siblingIndent && !peek().text.startsWith("- ")) {
57
+ const next = advance();
58
+ const ci = next.text.indexOf(":");
59
+ if (ci > 0) {
60
+ const nk = next.text.slice(0, ci).trim();
61
+ const nv = next.text.slice(ci + 1).trim();
62
+ obj[nk] = nv ? scalar(nv) : parseValue(siblingIndent + 1) ?? null;
63
+ }
64
+ } else if (peek().indent > siblingIndent) {
65
+ advance();
66
+ } else {
67
+ break;
68
+ }
69
+ }
70
+ arr.push(obj);
71
+ } else {
72
+ arr.push(scalar(after));
73
+ }
74
+ }
75
+ return arr;
76
+ }
77
+ function parseMapping(level) {
78
+ const obj = {};
79
+ while (peek() && peek().indent === level && !peek().text.startsWith("- ")) {
80
+ const line = advance();
81
+ const colonIdx = line.text.indexOf(":");
82
+ if (colonIdx <= 0) continue;
83
+ const k = line.text.slice(0, colonIdx).trim();
84
+ const v = line.text.slice(colonIdx + 1).trim();
85
+ obj[k] = v ? scalar(v) : parseValue(level + 1) ?? null;
86
+ }
87
+ return obj;
88
+ }
89
+ try {
90
+ return parseValue(0) ?? {};
91
+ } catch {
92
+ return {};
93
+ }
94
+ }
95
+ function sanitizeBlocks(blocks) {
96
+ if (!Array.isArray(blocks)) return void 0;
97
+ return blocks.filter((b) => b != null && typeof b === "object" && typeof b.type === "string").map((b) => {
98
+ const block = { ...b };
99
+ switch (block.type) {
100
+ case "telemetry":
101
+ if (!Array.isArray(block.items)) block.items = [];
102
+ break;
103
+ case "table":
104
+ if (!Array.isArray(block.columns)) block.columns = [];
105
+ if (!Array.isArray(block.rows)) block.rows = [];
106
+ break;
107
+ case "actions":
108
+ if (!Array.isArray(block.buttons)) block.buttons = [];
109
+ break;
110
+ case "choice":
111
+ if (!Array.isArray(block.options)) block.options = [];
112
+ if (typeof block.id !== "string") block.id = `choice-${Date.now()}`;
113
+ break;
114
+ case "confirm":
115
+ if (typeof block.id !== "string") block.id = `confirm-${Date.now()}`;
116
+ if (typeof block.title !== "string") block.title = "";
117
+ break;
118
+ case "command":
119
+ if (typeof block.command !== "string") block.command = "";
120
+ break;
121
+ case "kv":
122
+ if (!Array.isArray(block.pairs)) block.pairs = [];
123
+ break;
124
+ case "alert":
125
+ if (typeof block.title !== "string") block.title = "";
126
+ if (typeof block.status !== "string") block.status = "normal";
127
+ break;
128
+ case "progress":
129
+ if (typeof block.label !== "string") block.label = "";
130
+ if (typeof block.value !== "number") block.value = 0;
131
+ break;
132
+ }
133
+ return block;
134
+ });
135
+ }
136
+ function generateId(custom) {
137
+ if (custom) return custom();
138
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
139
+ return `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
140
+ }
141
+ function parseRaw(raw, format, yamlParser) {
142
+ const tryJSON = (s) => {
143
+ try {
144
+ const parsed = JSON.parse(s);
145
+ if (parsed && typeof parsed === "object" && typeof parsed.content === "string") return parsed;
146
+ return null;
147
+ } catch {
148
+ return null;
149
+ }
150
+ };
151
+ const tryYAML = (s) => {
152
+ try {
153
+ const parser = yamlParser ?? parseYamlLite;
154
+ const parsed = parser(s);
155
+ if (parsed && typeof parsed === "object" && typeof parsed.content === "string")
156
+ return parsed;
157
+ return null;
158
+ } catch {
159
+ return null;
160
+ }
161
+ };
162
+ if (format === "json") return tryJSON(raw);
163
+ if (format === "yaml") return tryYAML(raw);
164
+ return tryJSON(raw) ?? tryYAML(raw);
165
+ }
166
+ function parseChatResponse(raw, format = "auto", options) {
167
+ const id = generateId(options == null ? void 0 : options.idGenerator);
168
+ const base = {
169
+ id,
170
+ role: "assistant",
171
+ timestamp: Date.now()
172
+ };
173
+ const payload = parseRaw(raw, format, options == null ? void 0 : options.yamlParser);
174
+ if (payload) {
175
+ return {
176
+ ...base,
177
+ content: payload.content ?? "",
178
+ severity: payload.severity,
179
+ blocks: sanitizeBlocks(payload.blocks)
180
+ };
181
+ }
182
+ return { ...base, content: raw };
183
+ }
184
+ function createChatResponseParser(options = {}) {
185
+ return (raw, format) => {
186
+ return parseChatResponse(raw, format ?? options.defaultFormat ?? "auto", options);
187
+ };
188
+ }
189
+ function parseMcpToolResult(toolName, result, options) {
190
+ var _a, _b;
191
+ const id = generateId(options == null ? void 0 : options.idGenerator);
192
+ const timestamp = Date.now();
193
+ if (result.isError) {
194
+ const errorText = ((_a = result.content) == null ? void 0 : _a.filter((c) => c.type === "text").map((c) => c.text).join("\n")) || `Tool "${toolName}" failed`;
195
+ return {
196
+ id,
197
+ role: "assistant",
198
+ timestamp,
199
+ severity: "critical",
200
+ content: errorText,
201
+ blocks: [{ type: "alert", status: "critical", title: `MCP Tool Error: ${toolName}`, detail: errorText }]
202
+ };
203
+ }
204
+ const textParts = ((_b = result.content) == null ? void 0 : _b.filter((c) => c.type === "text").map((c) => c.text ?? "")) ?? [];
205
+ const rawText = textParts.join("\n");
206
+ if (rawText.trim()) {
207
+ const payload = parseRaw(rawText, "auto");
208
+ if (payload && payload.content) {
209
+ return {
210
+ id,
211
+ role: "assistant",
212
+ timestamp,
213
+ content: payload.content,
214
+ severity: payload.severity,
215
+ blocks: sanitizeBlocks(payload.blocks)
216
+ };
217
+ }
218
+ }
219
+ return {
220
+ id,
221
+ role: "assistant",
222
+ timestamp,
223
+ content: rawText || `Tool \`${toolName}\` completed successfully.`,
224
+ blocks: [{
225
+ type: "kv",
226
+ title: "MCP Tool Call",
227
+ pairs: [
228
+ { key: "Tool", value: toolName, mono: true },
229
+ ...result._meta ? [{ key: "Meta", value: JSON.stringify(result._meta), mono: true }] : []
230
+ ]
231
+ }]
232
+ };
233
+ }
234
+ const CHAT_RESPONSE_MCP_TOOL = {
235
+ name: "respond_to_operator",
236
+ description: "Respond to the spacecraft operator with text content and optional structured UI blocks (alerts, telemetry, progress, tables, choices, confirmations, commands, key-value metadata). Use the Astro UX 6-level status system: normal, standby, caution, serious, critical, off.",
237
+ inputSchema: {
238
+ type: "object",
239
+ required: ["content"],
240
+ properties: {
241
+ content: { type: "string", description: "Plain-text or markdown response shown to the operator." },
242
+ severity: { type: "string", enum: ["normal", "standby", "caution", "serious", "critical", "off"] },
243
+ blocks: {
244
+ type: "array",
245
+ description: "Structured UI blocks rendered below the text content.",
246
+ items: {
247
+ type: "object",
248
+ required: ["type"],
249
+ properties: {
250
+ type: { type: "string", enum: ["alert", "telemetry", "progress", "table", "choice", "confirm", "command", "kv"] },
251
+ status: { type: "string", enum: ["normal", "standby", "caution", "serious", "critical", "off"] },
252
+ title: { type: "string" },
253
+ detail: { type: "string" },
254
+ label: { type: "string" },
255
+ value: { type: "number" },
256
+ id: { type: "string" },
257
+ command: { type: "string" },
258
+ executable: { type: "boolean" },
259
+ items: { type: "array", items: { type: "object", properties: { label: { type: "string" }, value: {}, unit: { type: "string" }, status: { type: "string" } } } },
260
+ columns: { type: "array", items: { type: "string" } },
261
+ rows: { type: "array", items: { type: "array" } },
262
+ options: { type: "array", items: { type: "object", properties: { id: { type: "string" }, label: { type: "string" }, description: { type: "string" }, status: { type: "string" } } } },
263
+ pairs: { type: "array", items: { type: "object", properties: { key: { type: "string" }, value: {}, mono: { type: "boolean" } } } }
264
+ }
265
+ }
266
+ }
267
+ }
268
+ }
269
+ };
270
+ const CHAT_RESPONSE_TOOL_SCHEMA = {
271
+ name: "respond_to_operator",
272
+ description: "Respond to the spacecraft operator with text content and optional structured UI blocks (alerts, telemetry, progress, tables, choices, confirmations, commands, key-value metadata). Use the Astro UX 6-level status system: normal, standby, caution, serious, critical, off.",
273
+ parameters: {
274
+ type: "object",
275
+ required: ["content"],
276
+ properties: {
277
+ content: {
278
+ type: "string",
279
+ description: "Plain-text or markdown response shown to the operator."
280
+ },
281
+ severity: {
282
+ type: "string",
283
+ enum: ["normal", "standby", "caution", "serious", "critical", "off"],
284
+ description: "Overall message severity. Drives the accent color and icon."
285
+ },
286
+ blocks: {
287
+ type: "array",
288
+ description: "Structured UI blocks rendered below the text content.",
289
+ items: {
290
+ type: "object",
291
+ required: ["type"],
292
+ properties: {
293
+ type: {
294
+ type: "string",
295
+ enum: ["alert", "telemetry", "progress", "table", "choice", "confirm", "command", "kv"]
296
+ },
297
+ status: { type: "string", enum: ["normal", "standby", "caution", "serious", "critical", "off"] },
298
+ title: { type: "string" },
299
+ detail: { type: "string" },
300
+ items: {
301
+ type: "array",
302
+ items: {
303
+ type: "object",
304
+ properties: {
305
+ label: { type: "string" },
306
+ value: {},
307
+ unit: { type: "string" },
308
+ status: { type: "string", enum: ["normal", "standby", "caution", "serious", "critical", "off"] }
309
+ }
310
+ }
311
+ },
312
+ label: { type: "string" },
313
+ value: { type: "number" },
314
+ max: { type: "number" },
315
+ columns: { type: "array", items: { type: "string" } },
316
+ rows: { type: "array", items: { type: "array" } },
317
+ id: { type: "string" },
318
+ multiple: { type: "boolean" },
319
+ options: {
320
+ type: "array",
321
+ items: {
322
+ type: "object",
323
+ properties: {
324
+ id: { type: "string" },
325
+ label: { type: "string" },
326
+ description: { type: "string" },
327
+ status: { type: "string", enum: ["normal", "standby", "caution", "serious", "critical", "off"] },
328
+ disabled: { type: "boolean" }
329
+ }
330
+ }
331
+ },
332
+ confirmLabel: { type: "string" },
333
+ cancelLabel: { type: "string" },
334
+ language: { type: "string" },
335
+ command: { type: "string" },
336
+ executable: { type: "boolean" },
337
+ pairs: {
338
+ type: "array",
339
+ items: {
340
+ type: "object",
341
+ properties: {
342
+ key: { type: "string" },
343
+ value: {},
344
+ mono: { type: "boolean" }
345
+ }
346
+ }
347
+ }
348
+ }
349
+ }
350
+ }
351
+ }
352
+ }
353
+ };
354
+ const CHAT_RESPONSE_JSON_PROMPT = `When reporting telemetry, status, or alerts, respond with a JSON object:
355
+
356
+ {
357
+ "content": "Plain text explanation (supports **markdown**).",
358
+ "severity": "normal" | "standby" | "caution" | "serious" | "critical" | "off",
359
+ "blocks": [
360
+ { "type": "alert", "status": "caution", "title": "Alert Title", "detail": "Description" },
361
+ { "type": "telemetry", "title": "Subsystem", "items": [{ "label": "Temp", "value": 72, "unit": "°C", "status": "normal" }] },
362
+ { "type": "progress", "label": "Operation", "value": 75, "max": 100, "status": "normal" },
363
+ { "type": "table", "title": "Data", "columns": ["Col1", "Col2"], "rows": [["val1", "val2"]] },
364
+ { "type": "choice", "id": "unique-id", "title": "Pick one", "options": [{ "id": "opt1", "label": "Option 1" }] },
365
+ { "type": "confirm", "id": "unique-id", "status": "caution", "title": "Confirm action" },
366
+ { "type": "command", "id": "cmd-id", "command": "CMD SAT-001 EXECUTE", "executable": true },
367
+ { "type": "kv", "title": "Context", "pairs": [{ "key": "Spacecraft", "value": "SAT-001" }] }
368
+ ]
369
+ }
370
+
371
+ Status levels (Astro UX): normal (nominal), standby (idle), caution (approaching limit), serious (at limit), critical (exceeding limit), off (no data).
372
+ Always include "content". Only include "blocks" when structured data helps the operator.`;
373
+ const CHAT_RESPONSE_YAML_PROMPT = `Respond in YAML format (not JSON). Use this structure:
374
+
375
+ content: Your plain-text or markdown response here.
376
+ severity: normal
377
+ blocks:
378
+ - type: alert
379
+ status: caution
380
+ title: Alert Title
381
+ detail: Optional detail
382
+ - type: telemetry
383
+ title: Subsystem
384
+ items:
385
+ - label: Parameter
386
+ value: 42.5
387
+ unit: "°C"
388
+ status: normal
389
+ - type: progress
390
+ label: Operation
391
+ value: 75
392
+ max: 100
393
+ status: normal
394
+ - type: choice
395
+ id: unique-id
396
+ title: Pick one
397
+ options:
398
+ - id: opt1
399
+ label: Option 1
400
+ status: normal
401
+ - type: command
402
+ id: cmd-id
403
+ language: CCSDS-TC
404
+ command: CMD SAT-001 EXECUTE
405
+ executable: true
406
+ - type: kv
407
+ title: Context
408
+ pairs:
409
+ - key: Spacecraft
410
+ value: SAT-001
411
+
412
+ Status levels (Astro UX): normal, standby, caution, serious, critical, off.
413
+ Always include "content". Only include "blocks" when structured data helps the operator.`;
414
+ const CHAT_STATUS_RULES_PROMPT = `Assign status levels using these thresholds:
415
+ - Battery: normal >50%, standby 30-50%, caution 20-30%, serious 10-20%, critical <10%
416
+ - Temperature: normal <70°C, caution 70-80°C, serious 80-85°C, critical >85°C
417
+ - Signal: normal >-80 dBm, caution -80 to -90, serious -90 to -95, critical <-95 dBm
418
+ - Memory/Storage: normal <70%, caution 70-85%, serious 85-95%, critical >95%
419
+
420
+ General rules:
421
+ - "normal" → Operating within nominal parameters
422
+ - "standby" → Idle, waiting, or scheduled
423
+ - "caution" → Approaching a limit
424
+ - "serious" → At or exceeding a soft limit
425
+ - "critical" → Exceeding hard limit, loss of signal, or failure
426
+ - "off" → Powered down, no data`;
427
+ function StatusShape({ status, size = 10, color }) {
428
+ const glow = `${color}50`;
429
+ switch (status) {
430
+ case "caution":
431
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style: { filter: `drop-shadow(0 0 3px ${glow})` }, children: /* @__PURE__ */ jsx("rect", { x: "1", y: "1", width: "10", height: "10", fill: color }) });
432
+ case "serious":
433
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style: { filter: `drop-shadow(0 0 3px ${glow})` }, children: /* @__PURE__ */ jsx("polygon", { points: "6,1 11,6 6,11 1,6", fill: color }) });
434
+ case "critical":
435
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style: { filter: `drop-shadow(0 0 3px ${glow})` }, children: /* @__PURE__ */ jsx("polygon", { points: "6,11 1,2 11,2", fill: color }) });
436
+ case "standby":
437
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style: { filter: `drop-shadow(0 0 3px ${glow})` }, children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "3.5", fill: "none", stroke: color, strokeWidth: "2" }) });
438
+ case "off":
439
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style: { filter: `drop-shadow(0 0 3px ${glow})` }, children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "3", fill: color }) });
440
+ default:
441
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style: { filter: `drop-shadow(0 0 3px ${glow})` }, children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "5", fill: color }) });
442
+ }
443
+ }
444
+ function AlertBlock({ block }) {
445
+ const { tokens } = useTheme();
446
+ const color = tokens.colors.status[block.status];
447
+ return /* @__PURE__ */ jsxs("div", { style: {
448
+ display: "flex",
449
+ alignItems: "flex-start",
450
+ gap: 10,
451
+ padding: "10px 14px",
452
+ backgroundColor: `${color}12`,
453
+ border: `1px solid ${color}30`,
454
+ borderLeft: `3px solid ${color}`,
455
+ borderRadius: tokens.borderRadius.md,
456
+ marginTop: 8
457
+ }, children: [
458
+ /* @__PURE__ */ jsx("div", { style: { marginTop: 2, flexShrink: 0 }, children: /* @__PURE__ */ jsx(StatusShape, { status: block.status, size: 12, color }) }),
459
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
460
+ /* @__PURE__ */ jsx("div", { style: { fontSize: tokens.typography.fontSize.sm, fontWeight: 600, color: tokens.colors.text.primary }, children: block.title }),
461
+ block.detail && /* @__PURE__ */ jsx("div", { style: { fontSize: tokens.typography.fontSize.xs, color: tokens.colors.text.secondary, marginTop: 2, lineHeight: 1.5 }, children: block.detail })
462
+ ] })
463
+ ] });
464
+ }
465
+ function TelemetryBlock({ block }) {
466
+ const { tokens } = useTheme();
467
+ return /* @__PURE__ */ jsxs("div", { style: {
468
+ marginTop: 8,
469
+ border: `1px solid ${tokens.colors.border.muted}`,
470
+ borderRadius: tokens.borderRadius.md,
471
+ overflow: "hidden"
472
+ }, children: [
473
+ block.title && /* @__PURE__ */ jsx("div", { style: {
474
+ padding: "6px 12px",
475
+ fontSize: tokens.typography.fontSize.xxs,
476
+ fontWeight: 600,
477
+ color: tokens.colors.text.secondary,
478
+ textTransform: "uppercase",
479
+ letterSpacing: "0.05em",
480
+ backgroundColor: `${tokens.colors.background.elevated}80`,
481
+ borderBottom: `1px solid ${tokens.colors.border.muted}`
482
+ }, children: block.title }),
483
+ /* @__PURE__ */ jsx("div", { style: { padding: "8px 12px", display: "flex", flexDirection: "column", gap: 6 }, children: (block.items ?? []).map((item, i) => {
484
+ const itemColor = item.status ? tokens.colors.status[item.status] : tokens.colors.text.secondary;
485
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, fontSize: tokens.typography.fontSize.sm }, children: [
486
+ /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6, color: tokens.colors.text.secondary }, children: [
487
+ item.status && /* @__PURE__ */ jsx(StatusShape, { status: item.status, size: 8, color: tokens.colors.status[item.status] }),
488
+ item.label
489
+ ] }),
490
+ /* @__PURE__ */ jsxs("span", { style: {
491
+ fontFamily: tokens.typography.fontFamily.mono,
492
+ fontVariantNumeric: "tabular-nums",
493
+ color: itemColor,
494
+ fontWeight: 500
495
+ }, children: [
496
+ item.value,
497
+ item.unit ? ` ${item.unit}` : ""
498
+ ] })
499
+ ] }, i);
500
+ }) })
501
+ ] });
502
+ }
503
+ function ProgressBlock({ block }) {
504
+ const { tokens } = useTheme();
505
+ const max = block.max ?? 100;
506
+ const pct = Math.min(100, Math.max(0, block.value / max * 100));
507
+ const effectiveStatus = block.status ?? (pct >= 75 ? "normal" : pct >= 50 ? "standby" : pct >= 25 ? "caution" : pct > 0 ? "serious" : "off");
508
+ const color = tokens.colors.status[effectiveStatus];
509
+ return /* @__PURE__ */ jsxs("div", { style: { marginTop: 8 }, children: [
510
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: 4, fontSize: tokens.typography.fontSize.xs, color: tokens.colors.text.secondary }, children: [
511
+ /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
512
+ /* @__PURE__ */ jsx(StatusShape, { status: effectiveStatus, size: 8, color }),
513
+ block.label
514
+ ] }),
515
+ /* @__PURE__ */ jsxs("span", { style: { fontFamily: tokens.typography.fontFamily.mono, color: tokens.colors.text.primary }, children: [
516
+ pct.toFixed(0),
517
+ "%"
518
+ ] })
519
+ ] }),
520
+ /* @__PURE__ */ jsx("div", { style: { height: 6, backgroundColor: tokens.colors.border.muted, borderRadius: 3, overflow: "hidden" }, children: /* @__PURE__ */ jsx("div", { style: { height: "100%", width: `${pct}%`, backgroundColor: color, borderRadius: 3, transition: "width 300ms", boxShadow: `0 0 6px ${color}40` } }) })
521
+ ] });
522
+ }
523
+ function TableBlock({ block }) {
524
+ const { tokens } = useTheme();
525
+ return /* @__PURE__ */ jsxs("div", { style: { marginTop: 8, border: `1px solid ${tokens.colors.border.muted}`, borderRadius: tokens.borderRadius.md, overflow: "hidden" }, children: [
526
+ block.title && /* @__PURE__ */ jsx("div", { style: {
527
+ padding: "6px 12px",
528
+ fontSize: tokens.typography.fontSize.xxs,
529
+ fontWeight: 600,
530
+ color: tokens.colors.text.secondary,
531
+ textTransform: "uppercase",
532
+ letterSpacing: "0.05em",
533
+ backgroundColor: `${tokens.colors.background.elevated}80`,
534
+ borderBottom: `1px solid ${tokens.colors.border.muted}`
535
+ }, children: block.title }),
536
+ /* @__PURE__ */ jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: tokens.typography.fontSize.xs }, children: [
537
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: (block.columns ?? []).map((col, i) => /* @__PURE__ */ jsx("th", { style: {
538
+ padding: "6px 12px",
539
+ textAlign: "left",
540
+ fontWeight: 600,
541
+ color: tokens.colors.text.secondary,
542
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
543
+ whiteSpace: "nowrap"
544
+ }, children: col }, i)) }) }),
545
+ /* @__PURE__ */ jsx("tbody", { children: (block.rows ?? []).map((row, ri) => /* @__PURE__ */ jsx("tr", { children: (row ?? []).map((cell, ci) => /* @__PURE__ */ jsx("td", { style: {
546
+ padding: "5px 12px",
547
+ color: tokens.colors.text.primary,
548
+ fontFamily: typeof cell === "number" ? tokens.typography.fontFamily.mono : void 0,
549
+ fontVariantNumeric: typeof cell === "number" ? "tabular-nums" : void 0,
550
+ borderBottom: ri < (block.rows ?? []).length - 1 ? `1px solid ${tokens.colors.border.muted}30` : "none",
551
+ whiteSpace: "nowrap"
552
+ }, children: cell }, ci)) }, ri)) })
553
+ ] }) })
554
+ ] });
555
+ }
556
+ function ActionsBlock({ block }) {
557
+ const { tokens } = useTheme();
558
+ return /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 8, marginTop: 8, flexWrap: "wrap" }, children: (block.buttons ?? []).map((btn, i) => {
559
+ const isCritical = btn.variant === "critical";
560
+ const isPrimary = btn.variant === "primary" || !btn.variant && i === 0;
561
+ const baseColor = isCritical ? tokens.colors.status.critical : tokens.colors.accent.primary;
562
+ const textColor = isCritical ? tokens.colors.status.critical : safeAccentText(tokens.colors.accent.primary);
563
+ return /* @__PURE__ */ jsx("button", { onClick: btn.onClick, style: {
564
+ fontSize: tokens.typography.fontSize.xxs,
565
+ padding: "4px 14px",
566
+ borderRadius: tokens.borderRadius.sm,
567
+ border: `1px solid ${baseColor}${isPrimary ? "" : "40"}`,
568
+ backgroundColor: isPrimary ? `${baseColor}20` : "transparent",
569
+ color: textColor,
570
+ cursor: "pointer",
571
+ fontFamily: tokens.typography.fontFamily.primary,
572
+ fontWeight: 500,
573
+ transition: "all 150ms"
574
+ }, children: btn.label }, i);
575
+ }) });
576
+ }
577
+ function ChoiceBlock({ block, messageId, onEvent }) {
578
+ const { tokens } = useTheme();
579
+ const [localSelected, setLocalSelected] = useState(new Set(block.selected ?? []));
580
+ const isSubmitted = block.submitted;
581
+ const toggle = (optId) => {
582
+ if (isSubmitted) return;
583
+ setLocalSelected((prev) => {
584
+ const next = new Set(prev);
585
+ if (block.multiple) {
586
+ next.has(optId) ? next.delete(optId) : next.add(optId);
587
+ } else {
588
+ next.clear();
589
+ next.add(optId);
590
+ }
591
+ return next;
592
+ });
593
+ };
594
+ const submit = () => {
595
+ if (localSelected.size === 0 || isSubmitted) return;
596
+ onEvent == null ? void 0 : onEvent({ blockId: block.id, messageId, action: "select", value: Array.from(localSelected) });
597
+ };
598
+ return /* @__PURE__ */ jsxs("div", { style: { marginTop: 8 }, children: [
599
+ block.title && /* @__PURE__ */ jsxs("div", { style: { fontSize: tokens.typography.fontSize.xs, fontWeight: 600, color: tokens.colors.text.secondary, marginBottom: 6 }, children: [
600
+ block.title,
601
+ block.multiple ? " (select multiple)" : ""
602
+ ] }),
603
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: (block.options ?? []).map((opt) => {
604
+ const isSelected = localSelected.has(opt.id);
605
+ const optColor = opt.status ? tokens.colors.status[opt.status] : tokens.colors.accent.primary;
606
+ const isDisabled = opt.disabled || isSubmitted;
607
+ return /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => toggle(opt.id), disabled: isDisabled, style: {
608
+ display: "flex",
609
+ alignItems: "center",
610
+ gap: 10,
611
+ padding: "8px 12px",
612
+ borderRadius: tokens.borderRadius.md,
613
+ cursor: isDisabled ? "default" : "pointer",
614
+ border: `1px solid ${isSelected ? optColor : tokens.colors.border.muted}`,
615
+ backgroundColor: isSelected ? `${optColor}15` : "transparent",
616
+ transition: "all 150ms",
617
+ textAlign: "left",
618
+ fontFamily: tokens.typography.fontFamily.primary,
619
+ opacity: isDisabled && !isSelected ? 0.5 : 1
620
+ }, children: [
621
+ /* @__PURE__ */ jsx("div", { style: {
622
+ width: 16,
623
+ height: 16,
624
+ flexShrink: 0,
625
+ borderRadius: block.multiple ? 3 : "50%",
626
+ border: `2px solid ${isSelected ? optColor : tokens.colors.border.muted}`,
627
+ backgroundColor: isSelected ? optColor : "transparent",
628
+ display: "flex",
629
+ alignItems: "center",
630
+ justifyContent: "center",
631
+ transition: "all 150ms"
632
+ }, children: isSelected && /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: 10, height: 10, fill: "none", stroke: tokens.colors.text.inverse, strokeWidth: 2, children: /* @__PURE__ */ jsx("polyline", { points: "2,6 5,9 10,3" }) }) }),
633
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
634
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
635
+ opt.status && /* @__PURE__ */ jsx(StatusShape, { status: opt.status, size: 8, color: tokens.colors.status[opt.status] }),
636
+ /* @__PURE__ */ jsx("span", { style: { fontSize: tokens.typography.fontSize.sm, color: tokens.colors.text.primary, fontWeight: 500 }, children: opt.label })
637
+ ] }),
638
+ opt.description && /* @__PURE__ */ jsx("div", { style: { fontSize: tokens.typography.fontSize.xs, color: tokens.colors.text.tertiary, marginTop: 1 }, children: opt.description })
639
+ ] })
640
+ ] }, opt.id);
641
+ }) }),
642
+ !isSubmitted && onEvent && /* @__PURE__ */ jsx("button", { type: "button", onClick: submit, disabled: localSelected.size === 0, style: {
643
+ marginTop: 8,
644
+ padding: "5px 18px",
645
+ fontSize: tokens.typography.fontSize.xs,
646
+ fontWeight: 600,
647
+ borderRadius: tokens.borderRadius.sm,
648
+ border: `1px solid ${tokens.colors.accent.primary}`,
649
+ backgroundColor: localSelected.size > 0 ? `${tokens.colors.accent.primary}20` : "transparent",
650
+ color: localSelected.size > 0 ? safeAccentText(tokens.colors.accent.primary) : tokens.colors.text.tertiary,
651
+ cursor: localSelected.size > 0 ? "pointer" : "not-allowed",
652
+ fontFamily: tokens.typography.fontFamily.primary,
653
+ transition: "all 150ms"
654
+ }, children: "Confirm Selection" }),
655
+ isSubmitted && /* @__PURE__ */ jsx("div", { style: { marginTop: 6, fontSize: tokens.typography.fontSize.xs, color: tokens.colors.text.tertiary, fontStyle: "italic" }, children: "Selection submitted" })
656
+ ] });
657
+ }
658
+ function ConfirmBlock({ block, messageId, onEvent }) {
659
+ const { tokens } = useTheme();
660
+ const status = block.status ?? "caution";
661
+ const color = tokens.colors.status[status];
662
+ const resolved = block.resolved;
663
+ return /* @__PURE__ */ jsxs("div", { style: {
664
+ marginTop: 8,
665
+ padding: "12px 14px",
666
+ backgroundColor: `${color}10`,
667
+ border: `1px solid ${color}30`,
668
+ borderLeft: `3px solid ${color}`,
669
+ borderRadius: tokens.borderRadius.md
670
+ }, children: [
671
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }, children: [
672
+ /* @__PURE__ */ jsx(StatusShape, { status, size: 12, color }),
673
+ /* @__PURE__ */ jsx("span", { style: { fontSize: tokens.typography.fontSize.sm, fontWeight: 600, color: tokens.colors.text.primary }, children: block.title })
674
+ ] }),
675
+ block.detail && /* @__PURE__ */ jsx("div", { style: { fontSize: tokens.typography.fontSize.xs, color: tokens.colors.text.secondary, marginBottom: 8, lineHeight: 1.5 }, children: block.detail }),
676
+ !resolved && onEvent ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8 }, children: [
677
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onEvent({ blockId: block.id, messageId, action: "confirm" }), style: {
678
+ padding: "5px 16px",
679
+ fontSize: tokens.typography.fontSize.xs,
680
+ fontWeight: 600,
681
+ borderRadius: tokens.borderRadius.sm,
682
+ cursor: "pointer",
683
+ border: `1px solid ${color}`,
684
+ backgroundColor: `${color}20`,
685
+ color,
686
+ fontFamily: tokens.typography.fontFamily.primary,
687
+ transition: "all 150ms"
688
+ }, children: block.confirmLabel ?? "Confirm" }),
689
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onEvent({ blockId: block.id, messageId, action: "cancel" }), style: {
690
+ padding: "5px 16px",
691
+ fontSize: tokens.typography.fontSize.xs,
692
+ fontWeight: 500,
693
+ borderRadius: tokens.borderRadius.sm,
694
+ cursor: "pointer",
695
+ border: `1px solid ${tokens.colors.border.muted}`,
696
+ backgroundColor: "transparent",
697
+ color: tokens.colors.text.secondary,
698
+ fontFamily: tokens.typography.fontFamily.primary,
699
+ transition: "all 150ms"
700
+ }, children: block.cancelLabel ?? "Cancel" })
701
+ ] }) : resolved ? /* @__PURE__ */ jsx("div", { style: {
702
+ fontSize: tokens.typography.fontSize.xs,
703
+ fontWeight: 500,
704
+ color: resolved === "confirmed" ? tokens.colors.status.normal : tokens.colors.text.tertiary,
705
+ fontStyle: "italic"
706
+ }, children: resolved === "confirmed" ? "✓ Confirmed" : "✗ Cancelled" }) : null
707
+ ] });
708
+ }
709
+ function CommandBlock({ block, messageId, onEvent }) {
710
+ const { tokens } = useTheme();
711
+ const [copied, setCopied] = useState(false);
712
+ const handleCopy = () => {
713
+ var _a;
714
+ (_a = navigator.clipboard) == null ? void 0 : _a.writeText(block.command).then(() => {
715
+ setCopied(true);
716
+ setTimeout(() => setCopied(false), 2e3);
717
+ });
718
+ if (block.id) onEvent == null ? void 0 : onEvent({ blockId: block.id, messageId, action: "copy", value: block.command });
719
+ };
720
+ const handleExecute = () => {
721
+ if (block.id) onEvent == null ? void 0 : onEvent({ blockId: block.id, messageId, action: "execute", value: block.command });
722
+ };
723
+ return /* @__PURE__ */ jsxs("div", { style: { marginTop: 8, borderRadius: tokens.borderRadius.md, overflow: "hidden", border: `1px solid ${tokens.colors.border.muted}` }, children: [
724
+ block.label && /* @__PURE__ */ jsx("div", { style: {
725
+ padding: "5px 12px",
726
+ fontSize: tokens.typography.fontSize.xxs,
727
+ fontWeight: 600,
728
+ color: tokens.colors.text.tertiary,
729
+ textTransform: "uppercase",
730
+ letterSpacing: "0.05em",
731
+ backgroundColor: `${tokens.colors.background.elevated}80`,
732
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
733
+ display: "flex",
734
+ alignItems: "center",
735
+ justifyContent: "space-between"
736
+ }, children: /* @__PURE__ */ jsxs("span", { children: [
737
+ block.label,
738
+ block.language ? ` · ${block.language}` : ""
739
+ ] }) }),
740
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
741
+ /* @__PURE__ */ jsx("pre", { style: {
742
+ margin: 0,
743
+ padding: "10px 12px",
744
+ paddingRight: 80,
745
+ fontSize: tokens.typography.fontSize.xs,
746
+ fontFamily: tokens.typography.fontFamily.mono,
747
+ backgroundColor: `${tokens.colors.background.base}80`,
748
+ color: tokens.colors.text.primary,
749
+ overflowX: "auto",
750
+ lineHeight: 1.5
751
+ }, children: block.command }),
752
+ /* @__PURE__ */ jsxs("div", { style: { position: "absolute", top: 6, right: 8, display: "flex", gap: 4 }, children: [
753
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: handleCopy, style: {
754
+ padding: "2px 8px",
755
+ fontSize: tokens.typography.fontSize.micro,
756
+ borderRadius: tokens.borderRadius.sm,
757
+ border: `1px solid ${tokens.colors.border.muted}`,
758
+ backgroundColor: tokens.colors.background.elevated,
759
+ color: copied ? tokens.colors.status.normal : tokens.colors.text.tertiary,
760
+ cursor: "pointer",
761
+ fontFamily: tokens.typography.fontFamily.primary,
762
+ fontWeight: 500
763
+ }, children: copied ? "✓ Copied" : "Copy" }),
764
+ block.executable && onEvent && block.id && /* @__PURE__ */ jsx("button", { type: "button", onClick: handleExecute, style: {
765
+ padding: "2px 8px",
766
+ fontSize: tokens.typography.fontSize.micro,
767
+ borderRadius: tokens.borderRadius.sm,
768
+ border: `1px solid ${tokens.colors.accent.primary}60`,
769
+ backgroundColor: `${tokens.colors.accent.primary}15`,
770
+ color: safeAccentText(tokens.colors.accent.primary),
771
+ cursor: "pointer",
772
+ fontFamily: tokens.typography.fontFamily.primary,
773
+ fontWeight: 600
774
+ }, children: "Run" })
775
+ ] })
776
+ ] })
777
+ ] });
778
+ }
779
+ function KVBlock({ block }) {
780
+ const { tokens } = useTheme();
781
+ return /* @__PURE__ */ jsxs("div", { style: {
782
+ marginTop: 8,
783
+ padding: "8px 12px",
784
+ backgroundColor: `${tokens.colors.background.elevated}40`,
785
+ borderRadius: tokens.borderRadius.md,
786
+ border: `1px solid ${tokens.colors.border.muted}`
787
+ }, children: [
788
+ block.title && /* @__PURE__ */ jsx("div", { style: {
789
+ fontSize: tokens.typography.fontSize.xxs,
790
+ fontWeight: 600,
791
+ color: tokens.colors.text.tertiary,
792
+ textTransform: "uppercase",
793
+ letterSpacing: "0.05em",
794
+ marginBottom: 6
795
+ }, children: block.title }),
796
+ /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "auto 1fr", gap: "3px 16px", fontSize: tokens.typography.fontSize.xs }, children: (block.pairs ?? []).map((p, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
797
+ /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.text.tertiary, whiteSpace: "nowrap" }, children: p.key }),
798
+ /* @__PURE__ */ jsx("span", { style: {
799
+ color: tokens.colors.text.primary,
800
+ fontFamily: p.mono ? tokens.typography.fontFamily.mono : void 0,
801
+ fontVariantNumeric: p.mono ? "tabular-nums" : void 0
802
+ }, children: p.value })
803
+ ] }, i)) })
804
+ ] });
805
+ }
806
+ function renderBlock(block, index, messageId, onEvent) {
807
+ switch (block.type) {
808
+ case "alert":
809
+ return /* @__PURE__ */ jsx(AlertBlock, { block }, index);
810
+ case "telemetry":
811
+ return /* @__PURE__ */ jsx(TelemetryBlock, { block }, index);
812
+ case "progress":
813
+ return /* @__PURE__ */ jsx(ProgressBlock, { block }, index);
814
+ case "table":
815
+ return /* @__PURE__ */ jsx(TableBlock, { block }, index);
816
+ case "actions":
817
+ return /* @__PURE__ */ jsx(ActionsBlock, { block }, index);
818
+ case "choice":
819
+ return /* @__PURE__ */ jsx(ChoiceBlock, { block, messageId, onEvent }, index);
820
+ case "confirm":
821
+ return /* @__PURE__ */ jsx(ConfirmBlock, { block, messageId, onEvent }, index);
822
+ case "command":
823
+ return /* @__PURE__ */ jsx(CommandBlock, { block, messageId, onEvent }, index);
824
+ case "kv":
825
+ return /* @__PURE__ */ jsx(KVBlock, { block }, index);
826
+ default:
827
+ return null;
828
+ }
829
+ }
830
+ const ChatPanel = memo(function ChatPanel2({
831
+ messages = [],
832
+ onSend,
833
+ loading = false,
834
+ placeholder = "Type a message...",
835
+ title,
836
+ subtitle,
837
+ disabled = false,
838
+ showTimestamps = true,
839
+ height = "100%",
840
+ onClear,
841
+ onBlockEvent,
842
+ style
843
+ }) {
844
+ const { tokens } = useTheme();
845
+ const [input, setInput] = useState("");
846
+ const messagesEndRef = useRef(null);
847
+ const inputRef = useRef(null);
848
+ useEffect(() => {
849
+ var _a;
850
+ (_a = messagesEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
851
+ }, [messages, loading]);
852
+ const handleSend = useCallback(() => {
853
+ const text = input.trim();
854
+ if (!text || disabled) return;
855
+ onSend(text);
856
+ setInput("");
857
+ if (inputRef.current) inputRef.current.style.height = "auto";
858
+ }, [input, onSend, disabled]);
859
+ const handleKeyDown = useCallback((e) => {
860
+ if (e.key === "Enter" && !e.shiftKey) {
861
+ e.preventDefault();
862
+ handleSend();
863
+ }
864
+ }, [handleSend]);
865
+ const handleInput = useCallback((e) => {
866
+ setInput(e.target.value);
867
+ const el = e.target;
868
+ el.style.height = "auto";
869
+ el.style.height = `${Math.min(el.scrollHeight, 120)}px`;
870
+ }, []);
871
+ const formatTime = (ts) => {
872
+ if (!ts) return "";
873
+ return new Date(ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
874
+ };
875
+ const renderContent = (text) => {
876
+ const parts = [];
877
+ const lines = text.split("\n");
878
+ let inCode = false;
879
+ let codeBlock = [];
880
+ lines.forEach((line, i) => {
881
+ if (line.startsWith("```")) {
882
+ if (inCode) {
883
+ parts.push(
884
+ /* @__PURE__ */ jsx("pre", { style: {
885
+ backgroundColor: `${tokens.colors.background.base}80`,
886
+ padding: `${tokens.spacing.xs} ${tokens.spacing.sm}`,
887
+ borderRadius: tokens.borderRadius.sm,
888
+ fontSize: tokens.typography.fontSize.xs,
889
+ fontFamily: tokens.typography.fontFamily.mono,
890
+ overflowX: "auto",
891
+ margin: `${tokens.spacing.xs} 0`,
892
+ border: `1px solid ${tokens.colors.border.muted}`
893
+ }, children: codeBlock.join("\n") }, `code-${i}`)
894
+ );
895
+ codeBlock = [];
896
+ inCode = false;
897
+ } else {
898
+ inCode = true;
899
+ }
900
+ return;
901
+ }
902
+ if (inCode) {
903
+ codeBlock.push(line);
904
+ return;
905
+ }
906
+ let processed = line;
907
+ if (line.includes("**")) {
908
+ const segments = line.split(/\*\*(.*?)\*\*/g);
909
+ processed = segments.map((seg, j) => j % 2 === 1 ? /* @__PURE__ */ jsx("strong", { children: seg }, j) : seg);
910
+ }
911
+ if (typeof processed === "string" && processed.includes("`")) {
912
+ const segments = processed.split(/`(.*?)`/g);
913
+ processed = segments.map(
914
+ (seg, j) => j % 2 === 1 ? /* @__PURE__ */ jsx("code", { style: {
915
+ backgroundColor: `${tokens.colors.background.base}80`,
916
+ padding: "1px 4px",
917
+ borderRadius: "3px",
918
+ fontSize: "0.9em",
919
+ fontFamily: tokens.typography.fontFamily.mono
920
+ }, children: seg }, j) : seg
921
+ );
922
+ }
923
+ parts.push(/* @__PURE__ */ jsxs(React.Fragment, { children: [
924
+ processed,
925
+ i < lines.length - 1 && /* @__PURE__ */ jsx("br", {})
926
+ ] }, `line-${i}`));
927
+ });
928
+ return parts;
929
+ };
930
+ const TypingDots = () => /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", padding: tokens.spacing.xs }, children: [
931
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx("div", { style: {
932
+ width: 6,
933
+ height: 6,
934
+ borderRadius: "50%",
935
+ backgroundColor: tokens.colors.accent.primary,
936
+ opacity: 0.6,
937
+ animation: `zendir-typing 1.2s ease-in-out ${i * 0.2}s infinite`
938
+ } }, i)),
939
+ /* @__PURE__ */ jsx("style", { children: `@keyframes zendir-typing { 0%,60%,100%{opacity:.3;transform:translateY(0)} 30%{opacity:1;transform:translateY(-3px)} }` })
940
+ ] });
941
+ return /* @__PURE__ */ jsxs("div", { style: {
942
+ display: "flex",
943
+ flexDirection: "column",
944
+ height: typeof height === "number" ? `${height}px` : height,
945
+ fontFamily: tokens.typography.fontFamily.primary,
946
+ backgroundColor: tokens.colors.background.base,
947
+ borderRadius: tokens.borderRadius.lg,
948
+ border: `1px solid ${tokens.colors.border.muted}`,
949
+ overflow: "hidden",
950
+ ...style
951
+ }, children: [
952
+ (title || onClear) && /* @__PURE__ */ jsxs("div", { style: {
953
+ display: "flex",
954
+ alignItems: "center",
955
+ justifyContent: "space-between",
956
+ padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
957
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
958
+ backgroundColor: tokens.colors.background.surface
959
+ }, children: [
960
+ /* @__PURE__ */ jsxs("div", { children: [
961
+ title && /* @__PURE__ */ jsx("div", { style: { fontSize: tokens.typography.fontSize.sm, fontWeight: 600, color: tokens.colors.text.primary }, children: title }),
962
+ subtitle && /* @__PURE__ */ jsx("div", { style: { fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.text.tertiary }, children: subtitle })
963
+ ] }),
964
+ onClear && messages.length > 0 && /* @__PURE__ */ jsx("button", { onClick: onClear, style: {
965
+ fontSize: tokens.typography.fontSize.xxs,
966
+ color: tokens.colors.text.tertiary,
967
+ backgroundColor: "transparent",
968
+ border: "none",
969
+ cursor: "pointer",
970
+ padding: "4px 8px",
971
+ borderRadius: tokens.borderRadius.sm,
972
+ fontFamily: tokens.typography.fontFamily.primary
973
+ }, children: "Clear" })
974
+ ] }),
975
+ /* @__PURE__ */ jsxs(
976
+ "div",
977
+ {
978
+ role: "log",
979
+ "aria-live": "polite",
980
+ "aria-label": "Chat messages",
981
+ style: {
982
+ flex: 1,
983
+ overflow: "auto",
984
+ padding: tokens.spacing.md,
985
+ display: "flex",
986
+ flexDirection: "column",
987
+ gap: tokens.spacing.sm
988
+ },
989
+ children: [
990
+ messages.length === 0 && /* @__PURE__ */ jsx("div", { style: {
991
+ display: "flex",
992
+ alignItems: "center",
993
+ justifyContent: "center",
994
+ flex: 1,
995
+ color: tokens.colors.text.tertiary,
996
+ fontSize: tokens.typography.fontSize.sm
997
+ }, children: "No messages yet" }),
998
+ messages.map((msg) => {
999
+ const isUser = msg.role === "user";
1000
+ const isSystem = msg.role === "system";
1001
+ const severity = msg.severity;
1002
+ const severityColor = severity ? tokens.colors.status[severity] : void 0;
1003
+ const systemBg = severityColor ? `${severityColor}12` : `${tokens.colors.status.caution}10`;
1004
+ const systemBorder = severityColor ? `${severityColor}30` : `${tokens.colors.status.caution}20`;
1005
+ const systemAccent = severityColor || void 0;
1006
+ return /* @__PURE__ */ jsxs("div", { style: {
1007
+ display: "flex",
1008
+ flexDirection: "column",
1009
+ alignItems: isUser ? "flex-end" : "flex-start",
1010
+ maxWidth: isSystem ? "100%" : "85%",
1011
+ alignSelf: isUser ? "flex-end" : "flex-start"
1012
+ }, children: [
1013
+ /* @__PURE__ */ jsxs("div", { style: {
1014
+ padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
1015
+ borderRadius: tokens.borderRadius.md,
1016
+ backgroundColor: isUser ? `${tokens.colors.accent.primary}20` : isSystem ? systemBg : tokens.colors.background.surface,
1017
+ border: `1px solid ${isUser ? `${tokens.colors.accent.primary}30` : isSystem ? systemBorder : tokens.colors.border.muted}`,
1018
+ borderLeft: isSystem && systemAccent ? `3px solid ${systemAccent}` : void 0,
1019
+ fontSize: tokens.typography.fontSize.sm,
1020
+ color: tokens.colors.text.primary,
1021
+ lineHeight: 1.6,
1022
+ width: isSystem ? "100%" : "auto",
1023
+ opacity: msg.status === "sending" ? 0.7 : 1
1024
+ }, children: [
1025
+ isSystem && severity && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }, children: [
1026
+ /* @__PURE__ */ jsx(StatusShape, { status: severity, size: 10, color: severityColor }),
1027
+ /* @__PURE__ */ jsx("span", { style: {
1028
+ fontSize: tokens.typography.fontSize.xxs,
1029
+ fontWeight: 600,
1030
+ color: severityColor,
1031
+ textTransform: "uppercase",
1032
+ letterSpacing: "0.04em"
1033
+ }, children: severity })
1034
+ ] }),
1035
+ renderContent(msg.content),
1036
+ Array.isArray(msg.blocks) && msg.blocks.map((block, i) => block ? renderBlock(block, i, msg.id, onBlockEvent) : null),
1037
+ msg.actions && msg.actions.length > 0 && /* @__PURE__ */ jsx("div", { style: {
1038
+ display: "flex",
1039
+ gap: tokens.spacing.xs,
1040
+ marginTop: tokens.spacing.xs,
1041
+ paddingTop: tokens.spacing.xs,
1042
+ borderTop: `1px solid ${tokens.colors.border.muted}`
1043
+ }, children: msg.actions.map((action, i) => /* @__PURE__ */ jsx("button", { onClick: action.onClick, style: {
1044
+ fontSize: tokens.typography.fontSize.xxs,
1045
+ padding: "2px 10px",
1046
+ borderRadius: tokens.borderRadius.sm,
1047
+ border: `1px solid ${tokens.colors.accent.primary}40`,
1048
+ backgroundColor: `${tokens.colors.accent.primary}10`,
1049
+ color: safeAccentText(tokens.colors.accent.primary),
1050
+ cursor: "pointer",
1051
+ fontFamily: tokens.typography.fontFamily.primary
1052
+ }, children: action.label }, i)) })
1053
+ ] }),
1054
+ showTimestamps && msg.timestamp && /* @__PURE__ */ jsxs("div", { style: {
1055
+ fontSize: tokens.typography.fontSize.micro,
1056
+ color: tokens.colors.text.tertiary,
1057
+ marginTop: "2px",
1058
+ paddingLeft: tokens.spacing.xs,
1059
+ paddingRight: tokens.spacing.xs,
1060
+ display: "flex",
1061
+ alignItems: "center",
1062
+ gap: "4px"
1063
+ }, children: [
1064
+ formatTime(msg.timestamp),
1065
+ msg.status === "error" && /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.status.critical }, children: "• Failed" })
1066
+ ] })
1067
+ ] }, msg.id);
1068
+ }),
1069
+ loading && /* @__PURE__ */ jsx("div", { style: {
1070
+ alignSelf: "flex-start",
1071
+ padding: `${tokens.spacing.xs} ${tokens.spacing.md}`,
1072
+ borderRadius: tokens.borderRadius.md,
1073
+ backgroundColor: tokens.colors.background.surface,
1074
+ border: `1px solid ${tokens.colors.border.muted}`
1075
+ }, children: /* @__PURE__ */ jsx(TypingDots, {}) }),
1076
+ /* @__PURE__ */ jsx("div", { ref: messagesEndRef })
1077
+ ]
1078
+ }
1079
+ ),
1080
+ /* @__PURE__ */ jsxs("div", { style: {
1081
+ display: "flex",
1082
+ alignItems: "flex-end",
1083
+ gap: tokens.spacing.sm,
1084
+ padding: tokens.spacing.md,
1085
+ borderTop: `1px solid ${tokens.colors.border.muted}`,
1086
+ backgroundColor: tokens.colors.background.surface
1087
+ }, children: [
1088
+ /* @__PURE__ */ jsx(
1089
+ "textarea",
1090
+ {
1091
+ ref: inputRef,
1092
+ value: input,
1093
+ onChange: handleInput,
1094
+ onKeyDown: handleKeyDown,
1095
+ placeholder,
1096
+ disabled,
1097
+ "aria-label": "Message input",
1098
+ rows: 1,
1099
+ style: {
1100
+ flex: 1,
1101
+ resize: "none",
1102
+ border: `1px solid ${tokens.colors.border.muted}`,
1103
+ borderRadius: tokens.borderRadius.md,
1104
+ padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
1105
+ fontSize: tokens.typography.fontSize.sm,
1106
+ fontFamily: tokens.typography.fontFamily.primary,
1107
+ color: tokens.colors.text.primary,
1108
+ backgroundColor: tokens.colors.background.base,
1109
+ outline: "none",
1110
+ transition: tokens.animation.fast,
1111
+ maxHeight: 120,
1112
+ lineHeight: 1.5
1113
+ }
1114
+ }
1115
+ ),
1116
+ /* @__PURE__ */ jsx("button", { onClick: handleSend, disabled: disabled || !input.trim(), "aria-label": "Send message", style: {
1117
+ display: "flex",
1118
+ alignItems: "center",
1119
+ justifyContent: "center",
1120
+ width: 44,
1121
+ height: 44,
1122
+ borderRadius: tokens.borderRadius.md,
1123
+ border: "none",
1124
+ backgroundColor: input.trim() ? tokens.colors.accent.primary : `${tokens.colors.accent.primary}20`,
1125
+ color: input.trim() ? tokens.colors.text.inverse : tokens.colors.text.tertiary,
1126
+ cursor: input.trim() && !disabled ? "pointer" : "not-allowed",
1127
+ transition: tokens.animation.fast,
1128
+ flexShrink: 0
1129
+ }, children: /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" }) }) })
1130
+ ] })
1131
+ ] });
1132
+ });
1133
+ export {
1134
+ CHAT_RESPONSE_JSON_PROMPT,
1135
+ CHAT_RESPONSE_MCP_TOOL,
1136
+ CHAT_RESPONSE_TOOL_SCHEMA,
1137
+ CHAT_RESPONSE_YAML_PROMPT,
1138
+ CHAT_STATUS_RULES_PROMPT,
1139
+ ChatPanel,
1140
+ createChatResponseParser,
1141
+ parseChatResponse,
1142
+ parseMcpToolResult
1143
+ };
1144
+ //# sourceMappingURL=ChatPanel.js.map