@agimon-ai/po-web-components 0.0.0-alpha.2 → 0.0.0-alpha.21

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 (511) hide show
  1. package/LICENSE +191 -1
  2. package/README.md +7 -7
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.mts +3 -2
  5. package/dist/index.mjs +1 -1
  6. package/dist/node_modules/.pnpm/{@modelcontextprotocol_server@2.2.0/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-CfX6zgs1.d.mts → @modelcontextprotocol_server@2.3.1/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-D4NN8WsG.d.mts} +5 -6
  7. package/dist/node_modules/.pnpm/@modelcontextprotocol_server@2.3.1/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-D4NN8WsG.d.mts.map +1 -0
  8. package/dist/node_modules/.pnpm/@modelcontextprotocol_server@2.3.1/node_modules/@modelcontextprotocol/server/dist/index.d.mts +2 -0
  9. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/compat.d.mts +8 -0
  10. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/compat.d.mts.map +1 -0
  11. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/errors.d.mts +21 -0
  12. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/errors.d.mts.map +1 -0
  13. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/parse.d.mts +15 -0
  14. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/parse.d.mts.map +1 -0
  15. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/schemas.d.mts +169 -0
  16. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/schemas.d.mts.map +1 -0
  17. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/api.d.mts +38 -0
  18. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/api.d.mts.map +1 -0
  19. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/checks.d.mts +63 -0
  20. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/checks.d.mts.map +1 -0
  21. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/core.d.mts +50 -0
  22. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/core.d.mts.map +1 -0
  23. package/dist/node_modules/.pnpm/{zod@4.6.5 → zod@4.6.6}/node_modules/zod/v4/core/errors.d.mts +3 -87
  24. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/errors.d.mts.map +1 -0
  25. package/dist/node_modules/.pnpm/{zod@4.6.5 → zod@4.6.6}/node_modules/zod/v4/core/json-schema.d.mts +1 -26
  26. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/json-schema.d.mts.map +1 -0
  27. package/dist/node_modules/.pnpm/{zod@4.6.5 → zod@4.6.6}/node_modules/zod/v4/core/registries.d.mts +3 -7
  28. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/registries.d.mts.map +1 -0
  29. package/dist/node_modules/.pnpm/{zod@4.6.5 → zod@4.6.6}/node_modules/zod/v4/core/schemas.d.mts +10 -405
  30. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/schemas.d.mts.map +1 -0
  31. package/dist/node_modules/.pnpm/{zod@4.6.5 → zod@4.6.6}/node_modules/zod/v4/core/standard-schema.d.mts +1 -1
  32. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/standard-schema.d.mts.map +1 -0
  33. package/dist/node_modules/.pnpm/{zod@4.6.5 → zod@4.6.6}/node_modules/zod/v4/core/to-json-schema.d.mts +4 -33
  34. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/to-json-schema.d.mts.map +1 -0
  35. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/util.d.mts +38 -0
  36. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/util.d.mts.map +1 -0
  37. package/dist/node_modules/.pnpm/{zod@4.6.5 → zod@4.6.6}/node_modules/zod/v4/core/versions.d.mts +1 -1
  38. package/dist/node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/core/versions.d.mts.map +1 -0
  39. package/dist/packages/core/po-core/dist/mcpWidget.d.mts +2 -2
  40. package/dist/packages/core/po-core/dist/src/web/types/mcpWidget.d.mts +3 -3
  41. package/dist/packages/core/po-core/dist/web.d.mts +2 -2
  42. package/dist/packages/core/po-web-components/src/components/Accordion.mjs +1 -1
  43. package/dist/packages/core/po-web-components/src/components/Accordion.mjs.map +1 -1
  44. package/dist/packages/core/po-web-components/src/components/AgentAvatar.d.mts +14 -0
  45. package/dist/packages/core/po-web-components/src/components/AgentAvatar.d.mts.map +1 -0
  46. package/dist/packages/core/po-web-components/src/components/AgentAvatar.mjs +2 -0
  47. package/dist/packages/core/po-web-components/src/components/AgentAvatar.mjs.map +1 -0
  48. package/dist/packages/core/po-web-components/src/components/AnsiText.mjs +1 -1
  49. package/dist/packages/core/po-web-components/src/components/AnsiText.mjs.map +1 -1
  50. package/dist/packages/core/po-web-components/src/components/Avatar.mjs +1 -1
  51. package/dist/packages/core/po-web-components/src/components/Avatar.mjs.map +1 -1
  52. package/dist/packages/core/po-web-components/src/components/Badge.mjs +1 -1
  53. package/dist/packages/core/po-web-components/src/components/Badge.mjs.map +1 -1
  54. package/dist/packages/core/po-web-components/src/components/Breadcrumb.mjs +1 -1
  55. package/dist/packages/core/po-web-components/src/components/Breadcrumb.mjs.map +1 -1
  56. package/dist/packages/core/po-web-components/src/components/Button.d.mts.map +1 -1
  57. package/dist/packages/core/po-web-components/src/components/Button.mjs +1 -1
  58. package/dist/packages/core/po-web-components/src/components/Button.mjs.map +1 -1
  59. package/dist/packages/core/po-web-components/src/components/Checkbox.mjs +1 -1
  60. package/dist/packages/core/po-web-components/src/components/Checkbox.mjs.map +1 -1
  61. package/dist/packages/core/po-web-components/src/components/CodeBlock.mjs +1 -1
  62. package/dist/packages/core/po-web-components/src/components/CodeBlock.mjs.map +1 -1
  63. package/dist/packages/core/po-web-components/src/components/CodeEditorView.mjs +1 -1
  64. package/dist/packages/core/po-web-components/src/components/CodeEditorView.mjs.map +1 -1
  65. package/dist/packages/core/po-web-components/src/components/Command.mjs +1 -1
  66. package/dist/packages/core/po-web-components/src/components/Command.mjs.map +1 -1
  67. package/dist/packages/core/po-web-components/src/components/CopyButton.mjs +1 -1
  68. package/dist/packages/core/po-web-components/src/components/CopyButton.mjs.map +1 -1
  69. package/dist/packages/core/po-web-components/src/components/Dialog.d.mts +1 -1
  70. package/dist/packages/core/po-web-components/src/components/Dialog.mjs +1 -1
  71. package/dist/packages/core/po-web-components/src/components/Dialog.mjs.map +1 -1
  72. package/dist/packages/core/po-web-components/src/components/DiffView.mjs +1 -1
  73. package/dist/packages/core/po-web-components/src/components/DiffView.mjs.map +1 -1
  74. package/dist/packages/core/po-web-components/src/components/Dot.mjs +1 -1
  75. package/dist/packages/core/po-web-components/src/components/Dot.mjs.map +1 -1
  76. package/dist/packages/core/po-web-components/src/components/Drawer.mjs +1 -1
  77. package/dist/packages/core/po-web-components/src/components/Drawer.mjs.map +1 -1
  78. package/dist/packages/core/po-web-components/src/components/DropdownMenu.mjs +1 -1
  79. package/dist/packages/core/po-web-components/src/components/DropdownMenu.mjs.map +1 -1
  80. package/dist/packages/core/po-web-components/src/components/EmptyState.mjs +1 -1
  81. package/dist/packages/core/po-web-components/src/components/EmptyState.mjs.map +1 -1
  82. package/dist/packages/core/po-web-components/src/components/HashlineLines.mjs +1 -1
  83. package/dist/packages/core/po-web-components/src/components/HashlineLines.mjs.map +1 -1
  84. package/dist/packages/core/po-web-components/src/components/Input.mjs +1 -1
  85. package/dist/packages/core/po-web-components/src/components/Input.mjs.map +1 -1
  86. package/dist/packages/core/po-web-components/src/components/Kbd.mjs +1 -1
  87. package/dist/packages/core/po-web-components/src/components/Kbd.mjs.map +1 -1
  88. package/dist/packages/core/po-web-components/src/components/Label.mjs +1 -1
  89. package/dist/packages/core/po-web-components/src/components/Label.mjs.map +1 -1
  90. package/dist/packages/core/po-web-components/src/components/Markdown.d.mts +1 -0
  91. package/dist/packages/core/po-web-components/src/components/Markdown.d.mts.map +1 -1
  92. package/dist/packages/core/po-web-components/src/components/Markdown.mjs +2 -2
  93. package/dist/packages/core/po-web-components/src/components/Markdown.mjs.map +1 -1
  94. package/dist/packages/core/po-web-components/src/components/McpApp.d.mts +5 -4
  95. package/dist/packages/core/po-web-components/src/components/McpApp.d.mts.map +1 -1
  96. package/dist/packages/core/po-web-components/src/components/McpApp.mjs.map +1 -1
  97. package/dist/packages/core/po-web-components/src/components/McpToolWidget.d.mts +3 -3
  98. package/dist/packages/core/po-web-components/src/components/McpToolWidget.d.mts.map +1 -1
  99. package/dist/packages/core/po-web-components/src/components/McpToolWidget.mjs +2 -2
  100. package/dist/packages/core/po-web-components/src/components/McpToolWidget.mjs.map +1 -1
  101. package/dist/packages/core/po-web-components/src/components/MediaPreview.mjs +1 -1
  102. package/dist/packages/core/po-web-components/src/components/MediaPreview.mjs.map +1 -1
  103. package/dist/packages/core/po-web-components/src/components/MermaidDiagram.mjs +1 -1
  104. package/dist/packages/core/po-web-components/src/components/MermaidDiagram.mjs.map +1 -1
  105. package/dist/packages/core/po-web-components/src/components/MessageItem.mjs +1 -1
  106. package/dist/packages/core/po-web-components/src/components/MessageItem.mjs.map +1 -1
  107. package/dist/packages/core/po-web-components/src/components/MessageLines.mjs +1 -1
  108. package/dist/packages/core/po-web-components/src/components/MessageLines.mjs.map +1 -1
  109. package/dist/packages/core/po-web-components/src/components/OptionList.mjs +1 -1
  110. package/dist/packages/core/po-web-components/src/components/OptionList.mjs.map +1 -1
  111. package/dist/packages/core/po-web-components/src/components/Panel.mjs +1 -1
  112. package/dist/packages/core/po-web-components/src/components/Panel.mjs.map +1 -1
  113. package/dist/packages/core/po-web-components/src/components/PdfPreview.mjs +1 -1
  114. package/dist/packages/core/po-web-components/src/components/PdfPreview.mjs.map +1 -1
  115. package/dist/packages/core/po-web-components/src/components/Picker.mjs +1 -1
  116. package/dist/packages/core/po-web-components/src/components/Picker.mjs.map +1 -1
  117. package/dist/packages/core/po-web-components/src/components/Popover.mjs +1 -1
  118. package/dist/packages/core/po-web-components/src/components/Popover.mjs.map +1 -1
  119. package/dist/packages/core/po-web-components/src/components/Progress.mjs +1 -1
  120. package/dist/packages/core/po-web-components/src/components/Progress.mjs.map +1 -1
  121. package/dist/packages/core/po-web-components/src/components/RadioGroup.mjs +1 -1
  122. package/dist/packages/core/po-web-components/src/components/RadioGroup.mjs.map +1 -1
  123. package/dist/packages/core/po-web-components/src/components/ReviewCommentDraft.mjs +1 -1
  124. package/dist/packages/core/po-web-components/src/components/ReviewCommentDraft.mjs.map +1 -1
  125. package/dist/packages/core/po-web-components/src/components/ScrollArea.mjs +1 -1
  126. package/dist/packages/core/po-web-components/src/components/ScrollArea.mjs.map +1 -1
  127. package/dist/packages/core/po-web-components/src/components/SectionLabel.mjs +1 -1
  128. package/dist/packages/core/po-web-components/src/components/SectionLabel.mjs.map +1 -1
  129. package/dist/packages/core/po-web-components/src/components/Select.mjs +1 -1
  130. package/dist/packages/core/po-web-components/src/components/Select.mjs.map +1 -1
  131. package/dist/packages/core/po-web-components/src/components/Separator.mjs +1 -1
  132. package/dist/packages/core/po-web-components/src/components/Separator.mjs.map +1 -1
  133. package/dist/packages/core/po-web-components/src/components/Settings.mjs +1 -1
  134. package/dist/packages/core/po-web-components/src/components/Settings.mjs.map +1 -1
  135. package/dist/packages/core/po-web-components/src/components/Sheet.mjs +1 -1
  136. package/dist/packages/core/po-web-components/src/components/Sheet.mjs.map +1 -1
  137. package/dist/packages/core/po-web-components/src/components/Skeleton.mjs +1 -1
  138. package/dist/packages/core/po-web-components/src/components/Skeleton.mjs.map +1 -1
  139. package/dist/packages/core/po-web-components/src/components/StatusBadge.mjs +1 -1
  140. package/dist/packages/core/po-web-components/src/components/StatusBadge.mjs.map +1 -1
  141. package/dist/packages/core/po-web-components/src/components/StreamCursor.mjs +1 -1
  142. package/dist/packages/core/po-web-components/src/components/StreamCursor.mjs.map +1 -1
  143. package/dist/packages/core/po-web-components/src/components/Switch.mjs +1 -1
  144. package/dist/packages/core/po-web-components/src/components/Switch.mjs.map +1 -1
  145. package/dist/packages/core/po-web-components/src/components/Tabs.mjs +1 -1
  146. package/dist/packages/core/po-web-components/src/components/Tabs.mjs.map +1 -1
  147. package/dist/packages/core/po-web-components/src/components/Toast.mjs +1 -1
  148. package/dist/packages/core/po-web-components/src/components/Toast.mjs.map +1 -1
  149. package/dist/packages/core/po-web-components/src/components/ToolPathLink.mjs +1 -1
  150. package/dist/packages/core/po-web-components/src/components/ToolPathLink.mjs.map +1 -1
  151. package/dist/packages/core/po-web-components/src/components/Tooltip.mjs +1 -1
  152. package/dist/packages/core/po-web-components/src/components/Tooltip.mjs.map +1 -1
  153. package/dist/packages/core/po-web-components/src/icons/icons.d.mts +2 -2
  154. package/dist/packages/core/po-web-components/src/icons/icons.mjs +1 -1
  155. package/dist/packages/core/po-web-components/src/lib/ansiSpans.mjs +1 -1
  156. package/dist/packages/core/po-web-components/src/lib/ansiSpans.mjs.map +1 -1
  157. package/dist/packages/core/po-web-components/src/lib/editorTheme.d.mts +19 -19
  158. package/dist/packages/core/po-web-components/src/lib/editorTheme.d.mts.map +1 -1
  159. package/dist/packages/core/po-web-components/src/lib/editorTheme.mjs +1 -1
  160. package/dist/packages/core/po-web-components/src/lib/editorTheme.mjs.map +1 -1
  161. package/dist/packages/core/po-web-components/src/lib/hashlineHighlight.mjs +1 -1
  162. package/dist/packages/core/po-web-components/src/lib/hashlineHighlight.mjs.map +1 -1
  163. package/dist/packages/core/po-web-components/src/lib/hashlineView.mjs +1 -1
  164. package/dist/packages/core/po-web-components/src/lib/hashlineView.mjs.map +1 -1
  165. package/dist/packages/core/po-web-components/src/lib/syntaxHighlight.d.mts +2 -2
  166. package/dist/packages/core/po-web-components/src/lib/syntaxHighlight.mjs +1 -1
  167. package/dist/packages/core/po-web-components/src/lib/syntaxHighlight.mjs.map +1 -1
  168. package/dist/packages/core/po-web-components/src/theme/builtinThemes.d.mts +1 -1
  169. package/dist/packages/core/po-web-components/src/theme/builtinThemes.d.mts.map +1 -1
  170. package/dist/packages/core/po-web-components/src/theme/builtinThemes.mjs +1 -1
  171. package/dist/packages/core/po-web-components/src/theme/builtinThemes.mjs.map +1 -1
  172. package/dist/packages/core/po-web-components/src/theme/derive.mjs +1 -1
  173. package/dist/packages/core/po-web-components/src/theme/derive.mjs.map +1 -1
  174. package/dist/packages/core/po-web-components/src/theme/nativeTheme.d.mts +2 -2
  175. package/dist/packages/core/po-web-components/src/theme/nativeTheme.mjs +1 -1
  176. package/dist/packages/core/po-web-components/src/theme/nativeTheme.mjs.map +1 -1
  177. package/dist/packages/core/po-web-components/src/types/theme.d.mts +1 -1
  178. package/dist/packages/core/po-web-components/src/types/theme.d.mts.map +1 -1
  179. package/dist/packages/core/po-web-components/src/types/theme.mjs +1 -1
  180. package/dist/packages/core/po-web-components/src/types/theme.mjs.map +1 -1
  181. package/dist/packages/core/po-web-components/themes/po-nord-dark.mjs +2 -0
  182. package/dist/packages/core/po-web-components/themes/po-nord-dark.mjs.map +1 -0
  183. package/dist/packages/core/po-web-components/themes/po-one-light.mjs +2 -0
  184. package/dist/packages/core/po-web-components/themes/po-one-light.mjs.map +1 -0
  185. package/dist/src/components/Accordion.cjs +1 -1
  186. package/dist/src/components/Accordion.cjs.map +1 -1
  187. package/dist/src/components/AgentAvatar.cjs +2 -0
  188. package/dist/src/components/AgentAvatar.cjs.map +1 -0
  189. package/dist/src/components/AnsiText.cjs +1 -1
  190. package/dist/src/components/AnsiText.cjs.map +1 -1
  191. package/dist/src/components/Avatar.cjs +1 -1
  192. package/dist/src/components/Avatar.cjs.map +1 -1
  193. package/dist/src/components/Badge.cjs +1 -1
  194. package/dist/src/components/Badge.cjs.map +1 -1
  195. package/dist/src/components/Breadcrumb.cjs +1 -1
  196. package/dist/src/components/Breadcrumb.cjs.map +1 -1
  197. package/dist/src/components/Button.cjs +1 -1
  198. package/dist/src/components/Button.cjs.map +1 -1
  199. package/dist/src/components/Checkbox.cjs +1 -1
  200. package/dist/src/components/Checkbox.cjs.map +1 -1
  201. package/dist/src/components/CodeBlock.cjs +1 -1
  202. package/dist/src/components/CodeBlock.cjs.map +1 -1
  203. package/dist/src/components/CodeEditorView.cjs +1 -1
  204. package/dist/src/components/CodeEditorView.cjs.map +1 -1
  205. package/dist/src/components/Command.cjs +1 -1
  206. package/dist/src/components/Command.cjs.map +1 -1
  207. package/dist/src/components/CopyButton.cjs +1 -1
  208. package/dist/src/components/CopyButton.cjs.map +1 -1
  209. package/dist/src/components/Dialog.cjs +1 -1
  210. package/dist/src/components/Dialog.cjs.map +1 -1
  211. package/dist/src/components/DiffView.cjs +1 -1
  212. package/dist/src/components/DiffView.cjs.map +1 -1
  213. package/dist/src/components/Dot.cjs +1 -1
  214. package/dist/src/components/Dot.cjs.map +1 -1
  215. package/dist/src/components/Drawer.cjs +1 -1
  216. package/dist/src/components/Drawer.cjs.map +1 -1
  217. package/dist/src/components/DropdownMenu.cjs +1 -1
  218. package/dist/src/components/DropdownMenu.cjs.map +1 -1
  219. package/dist/src/components/EmptyState.cjs +1 -1
  220. package/dist/src/components/EmptyState.cjs.map +1 -1
  221. package/dist/src/components/HashlineLines.cjs +1 -1
  222. package/dist/src/components/HashlineLines.cjs.map +1 -1
  223. package/dist/src/components/Input.cjs +1 -1
  224. package/dist/src/components/Input.cjs.map +1 -1
  225. package/dist/src/components/Kbd.cjs +1 -1
  226. package/dist/src/components/Kbd.cjs.map +1 -1
  227. package/dist/src/components/Label.cjs +1 -1
  228. package/dist/src/components/Label.cjs.map +1 -1
  229. package/dist/src/components/Markdown.cjs +2 -2
  230. package/dist/src/components/Markdown.cjs.map +1 -1
  231. package/dist/src/components/McpApp.cjs.map +1 -1
  232. package/dist/src/components/McpToolWidget.cjs +2 -2
  233. package/dist/src/components/McpToolWidget.cjs.map +1 -1
  234. package/dist/src/components/MediaPreview.cjs +1 -1
  235. package/dist/src/components/MediaPreview.cjs.map +1 -1
  236. package/dist/src/components/MermaidDiagram.cjs +1 -1
  237. package/dist/src/components/MermaidDiagram.cjs.map +1 -1
  238. package/dist/src/components/MessageItem.cjs +1 -1
  239. package/dist/src/components/MessageItem.cjs.map +1 -1
  240. package/dist/src/components/MessageLines.cjs +1 -1
  241. package/dist/src/components/MessageLines.cjs.map +1 -1
  242. package/dist/src/components/OptionList.cjs +1 -1
  243. package/dist/src/components/OptionList.cjs.map +1 -1
  244. package/dist/src/components/Panel.cjs +1 -1
  245. package/dist/src/components/Panel.cjs.map +1 -1
  246. package/dist/src/components/PdfPreview.cjs +1 -1
  247. package/dist/src/components/PdfPreview.cjs.map +1 -1
  248. package/dist/src/components/Picker.cjs +1 -1
  249. package/dist/src/components/Picker.cjs.map +1 -1
  250. package/dist/src/components/Popover.cjs +1 -1
  251. package/dist/src/components/Popover.cjs.map +1 -1
  252. package/dist/src/components/Progress.cjs +1 -1
  253. package/dist/src/components/Progress.cjs.map +1 -1
  254. package/dist/src/components/RadioGroup.cjs +1 -1
  255. package/dist/src/components/RadioGroup.cjs.map +1 -1
  256. package/dist/src/components/ReviewCommentDraft.cjs +1 -1
  257. package/dist/src/components/ReviewCommentDraft.cjs.map +1 -1
  258. package/dist/src/components/ScrollArea.cjs +1 -1
  259. package/dist/src/components/ScrollArea.cjs.map +1 -1
  260. package/dist/src/components/SectionLabel.cjs +1 -1
  261. package/dist/src/components/SectionLabel.cjs.map +1 -1
  262. package/dist/src/components/Select.cjs +1 -1
  263. package/dist/src/components/Select.cjs.map +1 -1
  264. package/dist/src/components/Separator.cjs +1 -1
  265. package/dist/src/components/Separator.cjs.map +1 -1
  266. package/dist/src/components/Settings.cjs +1 -1
  267. package/dist/src/components/Settings.cjs.map +1 -1
  268. package/dist/src/components/Sheet.cjs +1 -1
  269. package/dist/src/components/Sheet.cjs.map +1 -1
  270. package/dist/src/components/Skeleton.cjs +1 -1
  271. package/dist/src/components/Skeleton.cjs.map +1 -1
  272. package/dist/src/components/StatusBadge.cjs +1 -1
  273. package/dist/src/components/StatusBadge.cjs.map +1 -1
  274. package/dist/src/components/StreamCursor.cjs +1 -1
  275. package/dist/src/components/StreamCursor.cjs.map +1 -1
  276. package/dist/src/components/Switch.cjs +1 -1
  277. package/dist/src/components/Switch.cjs.map +1 -1
  278. package/dist/src/components/Tabs.cjs +1 -1
  279. package/dist/src/components/Tabs.cjs.map +1 -1
  280. package/dist/src/components/Toast.cjs +1 -1
  281. package/dist/src/components/Toast.cjs.map +1 -1
  282. package/dist/src/components/ToolPathLink.cjs +1 -1
  283. package/dist/src/components/ToolPathLink.cjs.map +1 -1
  284. package/dist/src/components/Tooltip.cjs +1 -1
  285. package/dist/src/components/Tooltip.cjs.map +1 -1
  286. package/dist/src/icons/icons.cjs +1 -1
  287. package/dist/src/lib/ansiSpans.cjs +1 -1
  288. package/dist/src/lib/ansiSpans.cjs.map +1 -1
  289. package/dist/src/lib/editorTheme.cjs +1 -1
  290. package/dist/src/lib/editorTheme.cjs.map +1 -1
  291. package/dist/src/lib/hashlineHighlight.cjs +1 -1
  292. package/dist/src/lib/hashlineHighlight.cjs.map +1 -1
  293. package/dist/src/lib/hashlineView.cjs +1 -1
  294. package/dist/src/lib/hashlineView.cjs.map +1 -1
  295. package/dist/src/lib/syntaxHighlight.cjs +1 -1
  296. package/dist/src/lib/syntaxHighlight.cjs.map +1 -1
  297. package/dist/src/theme/builtinThemes.cjs +1 -1
  298. package/dist/src/theme/builtinThemes.cjs.map +1 -1
  299. package/dist/src/theme/derive.cjs +1 -1
  300. package/dist/src/theme/derive.cjs.map +1 -1
  301. package/dist/src/theme/nativeTheme.cjs +1 -1
  302. package/dist/src/theme/nativeTheme.cjs.map +1 -1
  303. package/dist/src/types/theme.cjs +1 -1
  304. package/dist/src/types/theme.cjs.map +1 -1
  305. package/dist/themes/po-nord-dark.cjs +2 -0
  306. package/dist/themes/po-nord-dark.cjs.map +1 -0
  307. package/dist/themes/po-one-light.cjs +2 -0
  308. package/dist/themes/po-one-light.cjs.map +1 -0
  309. package/package.json +18 -18
  310. package/styles/mcp.css +11 -11
  311. package/styles/preview.css +1 -1
  312. package/styles/theme.css +118 -119
  313. package/themes/{doom-nord-dark.json → po-nord-dark.json} +1 -1
  314. package/themes/{doom-one-light.json → po-one-light.json} +1 -1
  315. package/dist/_virtual/_rolldown/runtime.mjs +0 -1
  316. package/dist/node_modules/.pnpm/@modelcontextprotocol_server@2.2.0/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-CfX6zgs1.d.mts.map +0 -1
  317. package/dist/node_modules/.pnpm/@modelcontextprotocol_server@2.2.0/node_modules/@modelcontextprotocol/server/dist/index.d.mts +0 -2
  318. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/coerce.d.mts +0 -20
  319. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/coerce.d.mts.map +0 -1
  320. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/compat.d.mts +0 -50
  321. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/compat.d.mts.map +0 -1
  322. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/deep-partial.d.mts +0 -10
  323. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/deep-partial.d.mts.map +0 -1
  324. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/errors.d.mts +0 -33
  325. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/errors.d.mts.map +0 -1
  326. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.d.mts +0 -28
  327. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.d.mts.map +0 -1
  328. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/from-json-schema.d.mts +0 -14
  329. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/from-json-schema.d.mts.map +0 -1
  330. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/in-out.d.mts +0 -13
  331. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/in-out.d.mts.map +0 -1
  332. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/iso.d.mts +0 -13
  333. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/iso.d.mts.map +0 -1
  334. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/parse.d.mts +0 -54
  335. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/parse.d.mts.map +0 -1
  336. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/schemas.d.mts +0 -775
  337. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/schemas.d.mts.map +0 -1
  338. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/api.d.mts +0 -331
  339. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/api.d.mts.map +0 -1
  340. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/checks.d.mts +0 -296
  341. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/checks.d.mts.map +0 -1
  342. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/compile.d.mts +0 -67
  343. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/compile.d.mts.map +0 -1
  344. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/core.d.mts +0 -85
  345. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/core.d.mts.map +0 -1
  346. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/doc.d.mts +0 -18
  347. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/doc.d.mts.map +0 -1
  348. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/errors.d.mts.map +0 -1
  349. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/index.d.mts +0 -24
  350. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/index.d.mts.map +0 -1
  351. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/json-schema-generator.d.mts +0 -67
  352. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/json-schema-generator.d.mts.map +0 -1
  353. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/json-schema-processors.d.mts +0 -12
  354. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/json-schema-processors.d.mts.map +0 -1
  355. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/json-schema.d.mts.map +0 -1
  356. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/memoizer.d.mts +0 -18
  357. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/memoizer.d.mts.map +0 -1
  358. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/parse.d.mts +0 -54
  359. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/parse.d.mts.map +0 -1
  360. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/regexes.d.mts +0 -94
  361. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/regexes.d.mts.map +0 -1
  362. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/registries.d.mts.map +0 -1
  363. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/schemas.d.mts.map +0 -1
  364. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/standard-schema.d.mts.map +0 -1
  365. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/to-json-schema.d.mts.map +0 -1
  366. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/util.d.mts +0 -237
  367. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/util.d.mts.map +0 -1
  368. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/versions.d.mts.map +0 -1
  369. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/index.d.mts +0 -29
  370. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/index.d.mts.map +0 -1
  371. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ar.d.mts +0 -8
  372. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ar.d.mts.map +0 -1
  373. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/az.d.mts +0 -8
  374. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/az.d.mts.map +0 -1
  375. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/be.d.mts +0 -8
  376. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/be.d.mts.map +0 -1
  377. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/bg.d.mts +0 -8
  378. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/bg.d.mts.map +0 -1
  379. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/bn.d.mts +0 -8
  380. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/bn.d.mts.map +0 -1
  381. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ca.d.mts +0 -8
  382. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ca.d.mts.map +0 -1
  383. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ckb.d.mts +0 -8
  384. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ckb.d.mts.map +0 -1
  385. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/cs.d.mts +0 -8
  386. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/cs.d.mts.map +0 -1
  387. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/da.d.mts +0 -8
  388. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/da.d.mts.map +0 -1
  389. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/de.d.mts +0 -8
  390. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/de.d.mts.map +0 -1
  391. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/el.d.mts +0 -8
  392. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/el.d.mts.map +0 -1
  393. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/en.d.mts +0 -8
  394. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/en.d.mts.map +0 -1
  395. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/eo.d.mts +0 -8
  396. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/eo.d.mts.map +0 -1
  397. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/es.d.mts +0 -8
  398. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/es.d.mts.map +0 -1
  399. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/fa.d.mts +0 -8
  400. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/fa.d.mts.map +0 -1
  401. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/fi.d.mts +0 -8
  402. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/fi.d.mts.map +0 -1
  403. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/fr-CA.d.mts +0 -8
  404. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/fr-CA.d.mts.map +0 -1
  405. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/fr.d.mts +0 -8
  406. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/fr.d.mts.map +0 -1
  407. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/gu.d.mts +0 -8
  408. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/gu.d.mts.map +0 -1
  409. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/he.d.mts +0 -8
  410. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/he.d.mts.map +0 -1
  411. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/hi.d.mts +0 -8
  412. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/hi.d.mts.map +0 -1
  413. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/hr.d.mts +0 -8
  414. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/hr.d.mts.map +0 -1
  415. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/hu.d.mts +0 -8
  416. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/hu.d.mts.map +0 -1
  417. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/hy.d.mts +0 -8
  418. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/hy.d.mts.map +0 -1
  419. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/id.d.mts +0 -8
  420. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/id.d.mts.map +0 -1
  421. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/index.d.mts +0 -69
  422. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/index.d.mts.map +0 -1
  423. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/is.d.mts +0 -8
  424. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/is.d.mts.map +0 -1
  425. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/it.d.mts +0 -8
  426. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/it.d.mts.map +0 -1
  427. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ja.d.mts +0 -8
  428. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ja.d.mts.map +0 -1
  429. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ka.d.mts +0 -8
  430. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ka.d.mts.map +0 -1
  431. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/kh.d.mts +0 -8
  432. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/kh.d.mts.map +0 -1
  433. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/km.d.mts +0 -8
  434. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/km.d.mts.map +0 -1
  435. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/kn.d.mts +0 -8
  436. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/kn.d.mts.map +0 -1
  437. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ko.d.mts +0 -8
  438. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ko.d.mts.map +0 -1
  439. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/lt.d.mts +0 -8
  440. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/lt.d.mts.map +0 -1
  441. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/mk.d.mts +0 -8
  442. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/mk.d.mts.map +0 -1
  443. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ms.d.mts +0 -8
  444. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ms.d.mts.map +0 -1
  445. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ne.d.mts +0 -8
  446. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ne.d.mts.map +0 -1
  447. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/nl.d.mts +0 -8
  448. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/nl.d.mts.map +0 -1
  449. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/nn.d.mts +0 -8
  450. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/nn.d.mts.map +0 -1
  451. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/no.d.mts +0 -8
  452. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/no.d.mts.map +0 -1
  453. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ota.d.mts +0 -8
  454. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ota.d.mts.map +0 -1
  455. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/pl.d.mts +0 -8
  456. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/pl.d.mts.map +0 -1
  457. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ps.d.mts +0 -8
  458. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ps.d.mts.map +0 -1
  459. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/pt-BR.d.mts +0 -8
  460. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/pt-BR.d.mts.map +0 -1
  461. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/pt.d.mts +0 -8
  462. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/pt.d.mts.map +0 -1
  463. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ro.d.mts +0 -8
  464. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ro.d.mts.map +0 -1
  465. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ru.d.mts +0 -8
  466. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ru.d.mts.map +0 -1
  467. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/sk.d.mts +0 -8
  468. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/sk.d.mts.map +0 -1
  469. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/sl.d.mts +0 -8
  470. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/sl.d.mts.map +0 -1
  471. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/sv.d.mts +0 -8
  472. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/sv.d.mts.map +0 -1
  473. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ta.d.mts +0 -8
  474. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ta.d.mts.map +0 -1
  475. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/tg.d.mts +0 -8
  476. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/tg.d.mts.map +0 -1
  477. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/th.d.mts +0 -8
  478. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/th.d.mts.map +0 -1
  479. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/tk.d.mts +0 -8
  480. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/tk.d.mts.map +0 -1
  481. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/tr.d.mts +0 -8
  482. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/tr.d.mts.map +0 -1
  483. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ua.d.mts +0 -8
  484. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ua.d.mts.map +0 -1
  485. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/uk.d.mts +0 -8
  486. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/uk.d.mts.map +0 -1
  487. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ur.d.mts +0 -8
  488. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/ur.d.mts.map +0 -1
  489. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/uz.d.mts +0 -8
  490. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/uz.d.mts.map +0 -1
  491. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/vi.d.mts +0 -8
  492. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/vi.d.mts.map +0 -1
  493. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/yo.d.mts +0 -8
  494. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/yo.d.mts.map +0 -1
  495. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/zh-CN.d.mts +0 -8
  496. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/zh-CN.d.mts.map +0 -1
  497. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/zh-TW.d.mts +0 -8
  498. package/dist/node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/zh-TW.d.mts.map +0 -1
  499. package/dist/packages/core/po-web-components/themes/doom-nord-dark.mjs +0 -2
  500. package/dist/packages/core/po-web-components/themes/doom-nord-dark.mjs.map +0 -1
  501. package/dist/packages/core/po-web-components/themes/doom-one-dark.mjs +0 -2
  502. package/dist/packages/core/po-web-components/themes/doom-one-dark.mjs.map +0 -1
  503. package/dist/packages/core/po-web-components/themes/doom-one-light.mjs +0 -2
  504. package/dist/packages/core/po-web-components/themes/doom-one-light.mjs.map +0 -1
  505. package/dist/themes/doom-nord-dark.cjs +0 -2
  506. package/dist/themes/doom-nord-dark.cjs.map +0 -1
  507. package/dist/themes/doom-one-dark.cjs +0 -2
  508. package/dist/themes/doom-one-dark.cjs.map +0 -1
  509. package/dist/themes/doom-one-light.cjs +0 -2
  510. package/dist/themes/doom-one-light.cjs.map +0 -1
  511. package/themes/doom-one-dark.json +0 -30
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.mjs","names":["ReactMarkdown","remarkGfm","REMARK_PLUGINS","CODE_CLASS","FileLinkContext","createContext","ImageContext","Image","loader","useContext","path","src","loaded","setLoaded","useState","useEffect","active","asset","result","current","alt","Code","rest","onFileLink","label","children","open","className","Link","href","textOf","child","Pre","code","isValidElement","CodeBlock","COMPONENTS","Markdown","loadImage","text"],"sources":["../../../../../../src/components/Markdown.tsx"],"sourcesContent":["import {\n createContext,\n type ComponentProps,\n isValidElement,\n type ReactNode,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from './CodeBlock';\n\nconst REMARK_PLUGINS = [remarkGfm];\n\n// No size: inline code follows the prose it sits in, 15px in the conversation\n// and 13px in a compact transcript, so a path never reads smaller than its sentence.\nconst CODE_CLASS = 'rounded bg-doom-deep px-1 py-px font-mono text-doom-green';\n\n/**\n * What a piece of inline code opens, when the host knows.\n *\n * Returning undefined leaves the span as plain code, which is the answer for\n * everything a message quotes that is not a file: a class name, a flag, a\n * command. The caller decides what counts, because only it knows which files\n * the session has.\n */\nexport type FileLinkHandler = (text: string, explicit?: boolean) => (() => void) | undefined;\n\n/**\n * Passed by context rather than as a component prop so the component map stays\n * a module constant. Rebuilding that map per render gives react-markdown new\n * component identities, which remounts the whole rendered tree on every frame\n * of a streaming reply.\n */\nconst FileLinkContext = createContext<FileLinkHandler | undefined>(undefined);\n\ntype ImageLoader = (path: string) => Promise<{ url: string; dispose(): void }>;\nconst ImageContext = createContext<ImageLoader | undefined>(undefined);\n\nfunction Image({ src, alt }: ComponentProps<'img'>) {\n const loader = useContext(ImageContext);\n let path: string | undefined;\n if (typeof src === 'string' && src !== '' && !/^(?:[a-z][a-z\\d+.-]*:|\\/\\/|#|\\?)/i.test(src)) {\n try {\n path = decodeURIComponent(src.split(/[?#]/, 1)[0]!);\n } catch {\n // An invalid encoded filename is shown as unavailable, never fetched.\n path = '';\n }\n }\n const [loaded, setLoaded] = useState<{ path: string; loader: ImageLoader; url?: string; failed?: boolean }>();\n useEffect(() => {\n if (loader === undefined || path === undefined) return;\n let active = true;\n let asset: Awaited<ReturnType<ImageLoader>> | undefined;\n void Promise.resolve()\n .then(() => {\n if (active) setLoaded(undefined);\n if (path === '') throw new Error('Invalid image path.');\n return loader(path);\n })\n .then((result) => {\n if (!active) {\n result.dispose();\n return;\n }\n asset = result;\n setLoaded({ path, loader, url: result.url });\n })\n .catch(() => {\n if (active) setLoaded({ path, loader, failed: true });\n });\n return () => {\n active = false;\n asset?.dispose();\n };\n }, [path, loader]);\n const current = loaded?.path === path && loaded?.loader === loader ? loaded : undefined;\n if (loader !== undefined && path !== undefined && (current?.url === undefined || current.failed))\n return (\n <span role={current?.failed ? 'alert' : 'status'} title={path}>\n {alt || path || 'Image'} ({current?.failed ? 'unavailable' : 'loading...'})\n </span>\n );\n return (\n <img\n src={loader !== undefined && path !== undefined ? current?.url : src}\n alt={alt ?? ''}\n onError={loader !== undefined && path !== undefined ? () => setLoaded({ path, loader, failed: true }) : undefined}\n className=\"max-h-[480px] max-w-full rounded border border-doom-border\"\n />\n );\n}\n\nfunction Code({ className, children, ...rest }: ComponentProps<'code'>) {\n const onFileLink = useContext(FileLinkContext);\n // Only a single-line span with no language class is a candidate: a fenced\n // block is content, not a reference, and its own renderer owns it.\n const label = typeof children === 'string' && !children.includes('\\n') ? children : undefined;\n const open = label === undefined || className !== undefined ? undefined : onFileLink?.(label);\n if (open !== undefined && label !== undefined) {\n return (\n <button\n type=\"button\"\n data-testid=\"markdown-file-link\"\n title={`open ${label}`}\n onClick={open}\n className={`${CODE_CLASS} cursor-pointer underline decoration-doom-green/40 underline-offset-2 hover:text-doom-hi hover:decoration-doom-hi`}\n >\n {label}\n </button>\n );\n }\n return (\n <code\n {...rest}\n className={`${className ?? ''} ${CODE_CLASS} [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`}\n >\n {children}\n </code>\n );\n}\n\nfunction Link({ href, children }: ComponentProps<'a'>) {\n const onFileLink = useContext(FileLinkContext);\n let path = href;\n try {\n path = href === undefined ? undefined : decodeURIComponent(href);\n } catch {\n path = undefined;\n }\n const isFile = path !== undefined && path !== '' && !/^(?:[a-z][a-z\\d+.-]*:|\\/\\/|#|\\?)/i.test(path);\n const open = isFile ? onFileLink?.(path!, true) : undefined;\n if (open !== undefined)\n return (\n <button\n type=\"button\"\n data-testid=\"markdown-file-link\"\n title={`open ${path}`}\n onClick={open}\n className=\"text-doom-blue underline decoration-doom-blue/50\"\n >\n {children}\n </button>\n );\n return (\n <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"text-doom-blue underline decoration-doom-blue/50\">\n {children}\n </a>\n );\n}\n\n/** The text inside a fence, which react-markdown hands over as nested strings. */\nfunction textOf(children: ReactNode): string {\n if (typeof children === 'string') return children;\n if (Array.isArray(children)) return children.map((child) => textOf(child as ReactNode)).join('');\n return '';\n}\n\n/**\n * A fenced block, read off the <code> child that carries its language.\n *\n * The block is handed to `CodeBlock` whole rather than rendered as a styled\n * <pre> around inline code, because a fence is content with its own\n * presentation: it is coloured, it can be copied, and a mermaid fence is a\n * picture. A <pre> that came from raw HTML has no such child and keeps the\n * plain box.\n */\nfunction Pre({ children }: ComponentProps<'pre'>) {\n const code = isValidElement<{ className?: string; children?: ReactNode }>(children) ? children : undefined;\n if (code === undefined)\n return (\n <pre className=\"overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-sm leading-relaxed\">\n {children}\n </pre>\n );\n // Markdown ends every fence with a newline the author did not type.\n return <CodeBlock text={textOf(code.props.children).replace(/\\n$/, '')} className={code.props.className} />;\n}\nconst COMPONENTS: Components = {\n p: ({ children }) => <p className=\"whitespace-pre-wrap break-words\">{children}</p>,\n strong: ({ children }) => <strong className=\"font-semibold text-doom-hi\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n del: ({ children }) => <del className=\"text-doom-dim line-through\">{children}</del>,\n a: Link,\n code: Code,\n pre: Pre,\n ul: ({ children }) => <ul className=\"list-disc pl-5\">{children}</ul>,\n ol: ({ children }) => <ol className=\"list-decimal pl-5\">{children}</ol>,\n li: ({ children }) => <li className=\"whitespace-pre-wrap break-words\">{children}</li>,\n // Headings step up from the prose they sit in and never shrink below it, so a\n // reply's `##` reads as a heading in both the 15px conversation and a 13px\n // compact transcript. h4 to h6 keep the prose size and lean on weight alone.\n h1: ({ children }) => <h1 className=\"mt-2 text-2xl font-semibold text-doom-hi first:mt-0\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"mt-2 text-xl font-semibold text-doom-hi first:mt-0\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"mt-1 text-lg font-semibold text-doom-hi first:mt-0\">{children}</h3>,\n h4: ({ children }) => <h4 className=\"font-semibold text-doom-hi\">{children}</h4>,\n h5: ({ children }) => <h5 className=\"font-semibold text-doom-text\">{children}</h5>,\n h6: ({ children }) => <h6 className=\"font-semibold text-doom-dim\">{children}</h6>,\n blockquote: ({ children }) => (\n <blockquote className=\"border-l-2 border-doom-border pl-3 text-doom-dim\">{children}</blockquote>\n ),\n hr: () => <hr className=\"border-doom-border-soft\" />,\n table: ({ children }) => (\n <div className=\"overflow-x-auto\">\n <table className=\"border-collapse\">{children}</table>\n </div>\n ),\n th: ({ children }) => (\n <th className=\"border border-doom-border bg-doom-deep px-2 py-1 text-left font-semibold text-doom-hi\">\n {children}\n </th>\n ),\n td: ({ children }) => <td className=\"border border-doom-border px-2 py-1 align-top\">{children}</td>,\n img: Image,\n};\n\n/** GitHub-flavored Markdown using the cockpit's safe, shared presentation. */\nexport function Markdown({\n text,\n onFileLink,\n loadImage,\n}: {\n text: string;\n onFileLink?: FileLinkHandler;\n loadImage?: ImageLoader;\n}) {\n return (\n <FileLinkContext.Provider value={onFileLink}>\n <ImageContext.Provider value={loadImage}>\n <div className=\"flex min-w-0 flex-col gap-2\">\n <ReactMarkdown remarkPlugins={REMARK_PLUGINS} components={COMPONENTS}>\n {text}\n </ReactMarkdown>\n </div>\n </ImageContext.Provider>\n </FileLinkContext.Provider>\n );\n}\n"],"mappings":"6PAcA,MAAME,EAAiB,CAACD,CAAS,EAI3BE,EAAa,4DAkBbC,EAAkBC,EAA2C,IAAA,EAAS,EAGtEC,EAAeD,EAAuC,IAAA,EAAS,EAErE,SAASE,EAAM,CAAE,MAAK,OAA8B,CAClD,IAAMC,EAASC,EAAWH,CAAY,EAClCI,EACJ,GAAI,OAAOC,GAAQ,UAAYA,IAAQ,IAAM,CAAC,oCAAoC,KAAKA,CAAG,EACxF,GAAI,CACF,EAAO,mBAAmBA,EAAI,MAAM,OAAQ,CAAC,CAAC,CAAC,EAAG,CACpD,MAAQ,CAEN,EAAO,EACT,CAEF,GAAM,CAACC,EAAQC,GAAaC,EAAgF,EAC5GC,MAAgB,CACd,GAAIP,IAAW,IAAA,IAAaE,IAAS,IAAA,GAAW,OAChD,IAAIM,EAAS,GACTC,EAkBJ,OAjBA,QAAa,QAAQ,CAAC,CACnB,SAAW,CAEV,GADID,GAAQH,EAAU,IAAA,EAAS,EAC3BH,IAAS,GAAI,MAAU,MAAM,qBAAqB,EACtD,OAAOF,EAAOE,CAAI,CACpB,CAAC,CAAC,CACD,KAAM,GAAW,CAChB,GAAI,CAACM,EAAQ,CACXE,EAAO,QAAQ,EACf,MACF,CACA,EAAQA,EACRL,EAAU,CAAE,OAAM,SAAQ,IAAKK,EAAO,GAAI,CAAC,CAC7C,CAAC,CAAC,CACD,UAAY,CACPF,GAAQH,EAAU,CAAE,OAAM,SAAQ,OAAQ,EAAK,CAAC,CACtD,CAAC,MACU,CACX,EAAS,GACTI,GAAO,QAAQ,CACjB,CACF,EAAG,CAACP,EAAMF,CAAM,CAAC,EACjB,IAAMW,EAAUP,GAAQ,OAASF,GAAQE,GAAQ,SAAWJ,EAASI,EAAS,IAAA,GAO9E,OANIJ,IAAW,IAAA,IAAaE,IAAS,IAAA,KAAcS,GAAS,MAAQ,IAAA,IAAaA,EAAQ,QAErF,kBAAC,OAAD,CAAM,KAAMA,GAAS,OAAS,QAAU,SAAU,MAAOT,EAAzD,SAAA,CACGU,GAAOV,GAAQ,QAAQ,KAAGS,GAAS,OAAS,cAAgB,aAAa,GACtE,IAGR,kBAAC,MAAD,CACE,IAAKX,IAAW,IAAA,IAAaE,IAAS,IAAA,GAAYS,GAAS,IAAMR,EACjE,IAAKS,GAAO,GACZ,QAASZ,IAAW,IAAA,IAAaE,IAAS,IAAA,OAAkBG,EAAU,CAAE,OAAM,SAAQ,OAAQ,EAAK,CAAC,EAAI,IAAA,GACxG,UAAU,4DACX,CAAA,CAEL,CAEA,SAASQ,EAAK,CAAE,YAAW,WAAU,GAAGC,GAAgC,CACtE,IAAMC,EAAad,EAAWL,CAAe,EAGvCoB,EAAQ,OAAOC,GAAa,UAAY,CAACA,EAAS,SAAS;CAAI,EAAIA,EAAW,IAAA,GAC9EC,EAAOF,IAAU,IAAA,IAAaG,IAAc,IAAA,GAAY,IAAA,GAAYJ,IAAaC,CAAK,EAc5F,OAbIE,IAAS,IAAA,IAAaF,IAAU,IAAA,GAEhC,kBAAC,SAAD,CACE,KAAK,SACL,cAAY,qBACZ,MAAO,QAAQA,IACf,QAASE,EACT,UAAW,GAAGvB,EAAW,mHAExB,SAAAqB,CACK,CAAA,EAIV,kBAAC,OAAD,CACE,GAAIF,EACJ,UAAW,GAAGK,GAAa,GAAG,GAAGxB,EAAW,0DAE3C,UACG,CAAA,CAEV,CAEA,SAASyB,EAAK,CAAE,OAAM,YAAiC,CACrD,IAAML,EAAad,EAAWL,CAAe,EACzCM,EAAOmB,EACX,GAAI,CACF,EAAOA,IAAS,IAAA,GAAY,IAAA,GAAY,mBAAmBA,CAAI,CACjE,MAAQ,CACN,EAAO,IAAA,EACT,CAEA,IAAMH,EADShB,IAAS,IAAA,IAAaA,IAAS,IAAM,CAAC,oCAAoC,KAAKA,CAAI,EAC5Ea,IAAab,EAAO,EAAI,EAAI,IAAA,GAalD,OAZIgB,IAAS,IAAA,GAaX,kBAAC,IAAD,CAAS,OAAM,OAAO,SAAS,IAAI,aAAa,UAAU,mDACvD,UACA,CAAA,EAbD,kBAAC,SAAD,CACE,KAAK,SACL,cAAY,qBACZ,MAAO,QAAQhB,IACf,QAASgB,EACT,UAAU,mDAET,UACK,CAAA,CAOd,CAGA,SAASI,EAAO,EAA6B,CAG3C,OAFI,OAAOL,GAAa,SAAiBA,EACrC,MAAM,QAAQA,CAAQ,EAAUA,EAAS,IAAK,GAAUK,EAAOC,CAAkB,CAAC,CAAC,CAAC,KAAK,EAAE,EACxF,EACT,CAWA,SAASC,EAAI,CAAE,YAAmC,CAChD,IAAMC,EAAOC,EAA6DT,CAAQ,EAAIA,EAAW,IAAA,GAQjG,OAPIQ,IAAS,IAAA,GAET,kBAAC,MAAD,CAAK,UAAU,+FACZ,UACE,CAAA,EAGF,kBAACE,EAAD,CAAW,KAAML,EAAOG,EAAK,MAAM,QAAQ,CAAC,CAAC,QAAQ,MAAO,EAAE,EAAG,UAAWA,EAAK,MAAM,SAAY,CAAA,CAC5G,CACA,MAAMG,EAAyB,CAC7B,GAAI,CAAE,cAAe,kBAAC,IAAD,CAAG,UAAU,kCAAmC,UAAY,CAAA,EACjF,QAAS,CAAE,cAAe,kBAAC,SAAD,CAAQ,UAAU,6BAA8B,UAAiB,CAAA,EAC3F,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,SAAU,UAAa,CAAA,EAC3D,KAAM,CAAE,cAAe,kBAAC,MAAD,CAAK,UAAU,6BAA8B,UAAc,CAAA,EAClF,EAAGR,EACH,KAAMP,EACN,IAAKW,EACL,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,iBAAkB,UAAa,CAAA,EACnE,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,oBAAqB,UAAa,CAAA,EACtE,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,kCAAmC,UAAa,CAAA,EAIpF,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,sDAAuD,UAAa,CAAA,EACxG,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,qDAAsD,UAAa,CAAA,EACvG,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,qDAAsD,UAAa,CAAA,EACvG,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,6BAA8B,UAAa,CAAA,EAC/E,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,+BAAgC,UAAa,CAAA,EACjF,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,8BAA+B,UAAa,CAAA,EAChF,YAAa,CAAE,cACb,kBAAC,aAAD,CAAY,UAAU,mDAAoD,UAAqB,CAAA,EAEjG,OAAU,kBAAC,KAAD,CAAI,UAAU,yBAA2B,CAAA,EACnD,OAAQ,CAAE,cACR,kBAAC,MAAD,CAAK,UAAU,kBACb,SAAA,kBAAC,QAAD,CAAO,UAAU,kBAAmB,UAAgB,CAAA,CACjD,CAAA,EAEP,IAAK,CAAE,cACL,kBAAC,KAAD,CAAI,UAAU,wFACX,UACC,CAAA,EAEN,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,gDAAiD,UAAa,CAAA,EAClG,IAAKzB,CACP,EAGA,SAAgB8B,EAAS,CACvB,OACA,aACA,aAKC,CACD,MACE,kBAACjC,EAAgB,SAAjB,CAA0B,MAAOmB,EAC/B,SAAA,kBAACjB,EAAa,SAAd,CAAuB,MAAOgC,EAC5B,SAAA,kBAAC,MAAD,CAAK,UAAU,8BACb,SAAA,kBAACtC,EAAD,CAAe,cAAeE,EAAgB,WAAYkC,EACvD,SAAAG,CACY,CAAA,CACZ,CAAA,CACgB,CAAA,CACC,CAAA,CAE9B"}
1
+ {"version":3,"file":"Markdown.mjs","names":["ReactMarkdown","remarkGfm","REMARK_PLUGINS","CODE_CLASS","FileLinkContext","createContext","ImageContext","Image","loader","useContext","path","src","loaded","setLoaded","useState","useEffect","active","asset","result","current","alt","Code","rest","onFileLink","label","children","open","className","Link","href","textOf","child","Pre","code","isValidElement","CodeBlock","COMPONENTS","Markdown","loadImage","text"],"sources":["../../../../../../src/components/Markdown.tsx"],"sourcesContent":["import {\n createContext,\n type ComponentProps,\n isValidElement,\n type ReactNode,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from './CodeBlock';\n\nconst REMARK_PLUGINS = [remarkGfm];\n\n// No size: inline code follows the prose it sits in, 15px in the conversation\n// and 13px in a compact transcript, so a path never reads smaller than its sentence.\nconst CODE_CLASS = 'rounded bg-po-deep px-1 py-px font-mono text-po-green';\n\n/**\n * What a piece of inline code opens, when the host knows.\n *\n * Returning undefined leaves the span as plain code, which is the answer for\n * everything a message quotes that is not a file: a class name, a flag, a\n * command. The caller decides what counts, because only it knows which files\n * the session has.\n */\nexport type FileLinkHandler = (text: string, explicit?: boolean) => (() => void) | undefined;\n\n/**\n * Passed by context rather than as a component prop so the component map stays\n * a module constant. Rebuilding that map per render gives react-markdown new\n * component identities, which remounts the whole rendered tree on every frame\n * of a streaming reply.\n */\nconst FileLinkContext = createContext<FileLinkHandler | undefined>(undefined);\n\ntype ImageLoader = (path: string) => Promise<{ url: string; dispose(): void }>;\nconst ImageContext = createContext<ImageLoader | undefined>(undefined);\n\nfunction Image({ src, alt }: ComponentProps<'img'>) {\n const loader = useContext(ImageContext);\n let path: string | undefined;\n if (typeof src === 'string' && src !== '' && !/^(?:[a-z][a-z\\d+.-]*:|\\/\\/|#|\\?)/i.test(src)) {\n try {\n path = decodeURIComponent(src.split(/[?#]/, 1)[0]!);\n } catch {\n // An invalid encoded filename is shown as unavailable, never fetched.\n path = '';\n }\n }\n const [loaded, setLoaded] = useState<{ path: string; loader: ImageLoader; url?: string; failed?: boolean }>();\n useEffect(() => {\n if (loader === undefined || path === undefined) return;\n let active = true;\n let asset: Awaited<ReturnType<ImageLoader>> | undefined;\n void Promise.resolve()\n .then(() => {\n if (active) setLoaded(undefined);\n if (path === '') throw new Error('Invalid image path.');\n return loader(path);\n })\n .then((result) => {\n if (!active) {\n result.dispose();\n return;\n }\n asset = result;\n setLoaded({ path, loader, url: result.url });\n })\n .catch(() => {\n if (active) setLoaded({ path, loader, failed: true });\n });\n return () => {\n active = false;\n asset?.dispose();\n };\n }, [path, loader]);\n const current = loaded?.path === path && loaded?.loader === loader ? loaded : undefined;\n if (loader !== undefined && path !== undefined && (current?.url === undefined || current.failed))\n return (\n <span role={current?.failed ? 'alert' : 'status'} title={path}>\n {alt || path || 'Image'} ({current?.failed ? 'unavailable' : 'loading...'})\n </span>\n );\n return (\n <img\n src={loader !== undefined && path !== undefined ? current?.url : src}\n alt={alt ?? ''}\n onError={loader !== undefined && path !== undefined ? () => setLoaded({ path, loader, failed: true }) : undefined}\n className=\"max-h-[480px] max-w-full rounded border border-po-border\"\n />\n );\n}\n\nfunction Code({ className, children, ...rest }: ComponentProps<'code'>) {\n const onFileLink = useContext(FileLinkContext);\n // Only a single-line span with no language class is a candidate: a fenced\n // block is content, not a reference, and its own renderer owns it.\n const label = typeof children === 'string' && !children.includes('\\n') ? children : undefined;\n const open = label === undefined || className !== undefined ? undefined : onFileLink?.(label);\n if (open !== undefined && label !== undefined) {\n return (\n <button\n type=\"button\"\n data-testid=\"markdown-file-link\"\n title={`open ${label}`}\n onClick={open}\n className={`${CODE_CLASS} cursor-pointer underline decoration-po-green/40 underline-offset-2 hover:text-po-hi hover:decoration-po-hi`}\n >\n {label}\n </button>\n );\n }\n return (\n <code\n {...rest}\n className={`${className ?? ''} ${CODE_CLASS} [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-po-hi`}\n >\n {children}\n </code>\n );\n}\n\nfunction Link({ href, children }: ComponentProps<'a'>) {\n const onFileLink = useContext(FileLinkContext);\n let path = href;\n try {\n path = href === undefined ? undefined : decodeURIComponent(href);\n } catch {\n path = undefined;\n }\n const isFile = path !== undefined && path !== '' && !/^(?:[a-z][a-z\\d+.-]*:|\\/\\/|#|\\?)/i.test(path);\n const open = isFile ? onFileLink?.(path!, true) : undefined;\n if (open !== undefined)\n return (\n <button\n type=\"button\"\n data-testid=\"markdown-file-link\"\n title={`open ${path}`}\n onClick={open}\n className=\"text-po-blue underline decoration-po-blue/50\"\n >\n {children}\n </button>\n );\n return (\n <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"text-po-blue underline decoration-po-blue/50\">\n {children}\n </a>\n );\n}\n\n/** The text inside a fence, which react-markdown hands over as nested strings. */\nfunction textOf(children: ReactNode): string {\n if (typeof children === 'string') return children;\n if (Array.isArray(children)) return children.map((child) => textOf(child as ReactNode)).join('');\n return '';\n}\n\n/**\n * A fenced block, read off the <code> child that carries its language.\n *\n * The block is handed to `CodeBlock` whole rather than rendered as a styled\n * <pre> around inline code, because a fence is content with its own\n * presentation: it is coloured, it can be copied, and a mermaid fence is a\n * picture. A <pre> that came from raw HTML has no such child and keeps the\n * plain box.\n */\nfunction Pre({ children }: ComponentProps<'pre'>) {\n const code = isValidElement<{ className?: string; children?: ReactNode }>(children) ? children : undefined;\n if (code === undefined)\n return (\n <pre className=\"overflow-x-auto rounded border border-po-border bg-po-deep p-2.5 text-sm leading-relaxed\">\n {children}\n </pre>\n );\n // Markdown ends every fence with a newline the author did not type.\n return <CodeBlock text={textOf(code.props.children).replace(/\\n$/, '')} className={code.props.className} />;\n}\nconst COMPONENTS: Components = {\n p: ({ children }) => <p className=\"whitespace-pre-wrap break-words\">{children}</p>,\n strong: ({ children }) => <strong className=\"font-semibold text-po-hi\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n del: ({ children }) => <del className=\"text-po-dim line-through\">{children}</del>,\n a: Link,\n code: Code,\n pre: Pre,\n ul: ({ children }) => <ul className=\"list-disc pl-5\">{children}</ul>,\n ol: ({ children }) => <ol className=\"list-decimal pl-5\">{children}</ol>,\n li: ({ children }) => <li className=\"whitespace-pre-wrap break-words\">{children}</li>,\n // Headings step up from the prose they sit in and never shrink below it, so a\n // reply's `##` reads as a heading in both the 15px conversation and a 13px\n // compact transcript. h4 to h6 keep the prose size and lean on weight alone.\n h1: ({ children }) => <h1 className=\"mt-2 text-2xl font-semibold text-po-hi first:mt-0\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"mt-2 text-xl font-semibold text-po-hi first:mt-0\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"mt-1 text-lg font-semibold text-po-hi first:mt-0\">{children}</h3>,\n h4: ({ children }) => <h4 className=\"font-semibold text-po-hi\">{children}</h4>,\n h5: ({ children }) => <h5 className=\"font-semibold text-po-text\">{children}</h5>,\n h6: ({ children }) => <h6 className=\"font-semibold text-po-dim\">{children}</h6>,\n blockquote: ({ children }) => (\n <blockquote className=\"border-l-2 border-po-border pl-3 text-po-dim\">{children}</blockquote>\n ),\n hr: () => <hr className=\"border-po-border-soft\" />,\n table: ({ children }) => (\n <div className=\"overflow-x-auto\">\n <table className=\"border-collapse\">{children}</table>\n </div>\n ),\n th: ({ children }) => (\n <th className=\"border border-po-border bg-po-deep px-2 py-1 text-left font-semibold text-po-hi\">{children}</th>\n ),\n td: ({ children }) => <td className=\"border border-po-border px-2 py-1 align-top\">{children}</td>,\n img: Image,\n};\n\n/** GitHub-flavored Markdown using the cockpit's safe, shared presentation. */\nexport function Markdown({\n text,\n onFileLink,\n loadImage,\n}: {\n text: string;\n onFileLink?: FileLinkHandler;\n loadImage?: ImageLoader;\n}) {\n return (\n <FileLinkContext.Provider value={onFileLink}>\n <ImageContext.Provider value={loadImage}>\n <div className=\"flex min-w-0 flex-col gap-2\">\n <ReactMarkdown remarkPlugins={REMARK_PLUGINS} components={COMPONENTS}>\n {text}\n </ReactMarkdown>\n </div>\n </ImageContext.Provider>\n </FileLinkContext.Provider>\n );\n}\n"],"mappings":"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"}
@@ -1,18 +1,19 @@
1
- import { DoomMcpWidgetProps } from "../../../po-core/dist/src/web/types/mcpWidget.mjs";
1
+ import { PoMcpWidgetProps } from "../../../po-core/dist/src/web/types/mcpWidget.mjs";
2
2
  import "../../../po-core/dist/web.mjs";
3
3
  import { ComponentType } from "react";
4
4
  //#region src/components/McpApp.d.ts
5
5
  interface View {
6
6
  readonly widget?: string;
7
- readonly props: DoomMcpWidgetProps;
7
+ readonly props: PoMcpWidgetProps;
8
8
  readonly failure?: string;
9
9
  }
10
10
  /** The root only dispatches. Tool-specific presentation belongs to the contributing package. */
11
11
  export declare function McpApp({ widgets, view }: {
12
- widgets: Readonly<Record<string, ComponentType<DoomMcpWidgetProps>>>;
12
+ widgets: Readonly<Record<string, ComponentType<PoMcpWidgetProps>>>;
13
13
  view: View;
14
14
  }): import("react").JSX.Element;
15
15
  /** Mounts one independently sandboxed invocation of the sync-generated widget registry. */
16
- export declare function mountMcpApp(widgets: Readonly<Record<string, ComponentType<DoomMcpWidgetProps>>>): Promise<void>;
16
+ export declare function mountMcpApp(widgets: Readonly<Record<string, ComponentType<PoMcpWidgetProps>>>): Promise<void>;
17
17
  //#endregion
18
+ export {};
18
19
  //# sourceMappingURL=McpApp.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"McpApp.d.mts","names":[],"sources":["../../../../../../src/components/McpApp.tsx"],"mappings":";;;;UAUU;WACC;WACA,OAAO;WACP;;;wBAgBK,SACd,SACA;EAEA,SAAS,SAAS,eAAe,cAAc;EAC/C,MAAM;oBACP,IAAA;;wBAiBqB,YAAY,SAAS,SAAS,eAAe,cAAc,wBAAwB"}
1
+ {"version":3,"file":"McpApp.d.mts","names":[],"sources":["../../../../../../src/components/McpApp.tsx"],"mappings":";;;;UAUU;WACC;WACA,OAAO;WACP;;;wBAgBK,SACd,SACA;EAEA,SAAS,SAAS,eAAe,cAAc;EAC/C,MAAM;oBACP,IAAA;;wBAiBqB,YAAY,SAAS,SAAS,eAAe,cAAc,sBAAsB"}
@@ -1 +1 @@
1
- {"version":3,"file":"McpApp.mjs","names":["WidgetBoundary","Component","McpApp","Widget","view","widgets","mountMcpApp","element","root","createRoot","app","App","disposed","terminal","connected","appVisible","render","fail","message","identify","name","widget","updateRefresh","enabled","applyContext","context","applyDocumentTheme","applyHostStyleVariables","tool","ui","args","result","dispose"],"sources":["../../../../../../src/components/McpApp.tsx"],"sourcesContent":["import type { DoomMcpWidgetProps } from '@agimon-ai/po-core/web';\nimport {\n App,\n applyDocumentTheme,\n applyHostStyleVariables,\n type McpUiHostContext,\n} from '@modelcontextprotocol/ext-apps';\nimport { Component, type ComponentType, type ReactNode } from 'react';\nimport { createRoot } from 'react-dom/client';\n\ninterface View {\n readonly widget?: string;\n readonly props: DoomMcpWidgetProps;\n readonly failure?: string;\n}\n\nclass WidgetBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false };\n\n static getDerivedStateFromError() {\n return { failed: true };\n }\n\n render() {\n return this.state.failed ? <p role=\"status\">The tool widget could not be rendered.</p> : this.props.children;\n }\n}\n\n/** The root only dispatches. Tool-specific presentation belongs to the contributing package. */\nexport function McpApp({\n widgets,\n view,\n}: {\n widgets: Readonly<Record<string, ComponentType<DoomMcpWidgetProps>>>;\n view: View;\n}) {\n const Widget = view.widget !== undefined && Object.hasOwn(widgets, view.widget) ? widgets[view.widget] : undefined;\n if (view.failure) return <p role=\"status\">{view.failure}</p>;\n if (Widget === undefined)\n return (\n <p role=\"status\">\n {view.widget === undefined ? 'Waiting for tool information...' : 'No widget is available for this tool.'}\n </p>\n );\n return (\n <WidgetBoundary key={view.widget}>\n <Widget {...view.props} />\n </WidgetBoundary>\n );\n}\n\n/** Mounts one independently sandboxed invocation of the sync-generated widget registry. */\nexport async function mountMcpApp(widgets: Readonly<Record<string, ComponentType<DoomMcpWidgetProps>>>): Promise<void> {\n const element = document.getElementById('root');\n if (element === null) throw new Error('Missing MCP app root');\n const root = createRoot(element);\n const app = new App({ name: 'po-tools', version: '1.0.0' }, {}, { autoResize: true });\n let disposed = false;\n let terminal = false;\n let connected = false;\n let appVisible = false;\n let view: View = { props: { toolName: '', args: {}, result: null, phase: 'connecting' } };\n\n const render = (): void => {\n if (!disposed) root.render(<McpApp widgets={widgets} view={view} />);\n };\n const fail = (message: string): void => {\n terminal = true;\n view = { ...view, failure: message };\n render();\n };\n const identify = (name: unknown, widget: unknown): boolean => {\n if (typeof name === 'string' && name.length > 0) {\n if (view.props.toolName && view.props.toolName !== name) {\n fail('The tool changed. Reopen this widget from the conversation.');\n return false;\n }\n view = { ...view, props: { ...view.props, toolName: name } };\n }\n if (typeof widget === 'string') {\n if (view.widget !== undefined && view.widget !== widget) {\n fail('The widget changed. Refresh the MCP connection.');\n return false;\n }\n view = { ...view, widget };\n }\n return true;\n };\n const updateRefresh = (): void => {\n const name = view.props.toolName;\n const enabled = connected && appVisible && !!app.getHostCapabilities()?.serverTools && name.length > 0;\n view = {\n ...view,\n props: {\n ...view.props,\n refresh: enabled\n ? async () => {\n if (disposed || name !== view.props.toolName || !appVisible)\n throw new Error('This widget is no longer active.');\n return app.callServerTool({ name, arguments: { ...view.props.args } });\n }\n : undefined,\n },\n };\n };\n const applyContext = (context: McpUiHostContext | undefined): void => {\n if (disposed || context === undefined) return;\n if (context.theme) {\n applyDocumentTheme(context.theme);\n document.documentElement.classList.toggle('dark', context.theme === 'dark');\n document.documentElement.dataset.theme = context.theme;\n }\n if (context.styles?.variables) applyHostStyleVariables(context.styles.variables);\n const tool = context.toolInfo?.tool;\n if (tool) {\n if (!identify(tool.name, tool._meta?.['po/widget'])) return;\n const ui = tool._meta?.ui as { visibility?: unknown } | undefined;\n appVisible = Array.isArray(ui?.visibility) && ui.visibility.includes('app');\n }\n updateRefresh();\n render();\n };\n\n app.ontoolinputpartial = ({ arguments: args }) => {\n if (disposed || terminal) return;\n view = { ...view, props: { ...view.props, args: args ?? {}, phase: 'preparing' } };\n render();\n };\n app.ontoolinput = ({ arguments: args }) => {\n if (disposed || terminal) return;\n view = { ...view, props: { ...view.props, args: args ?? {}, phase: 'running' } };\n render();\n };\n app.ontoolresult = (result) => {\n if (disposed || terminal) return;\n if (!identify(result._meta?.['po/toolName'], result._meta?.['po/widget'])) return;\n terminal = true;\n view = { ...view, props: { ...view.props, result, phase: 'result' } };\n updateRefresh();\n render();\n };\n app.ontoolcancelled = () => {\n if (disposed || terminal) return;\n terminal = true;\n view = { ...view, props: { ...view.props, phase: 'cancelled', result: null } };\n render();\n };\n app.onhostcontextchanged = applyContext;\n\n const dispose = (): void => {\n if (disposed) return;\n view = { ...view, failure: 'Tool view closed.' };\n render();\n disposed = true;\n window.removeEventListener('pagehide', dispose);\n setTimeout(() => {\n void app.close().catch(() => {});\n }, 0);\n };\n\n app.onteardown = () => {\n dispose();\n return {};\n };\n window.addEventListener('pagehide', dispose, { once: true });\n render();\n\n try {\n await app.connect();\n if (disposed) return;\n connected = true;\n applyContext(app.getHostContext());\n } catch {\n if (!disposed) fail('Could not connect to the app host. Reopen this widget in an MCP Apps-compatible client.');\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"McpApp.mjs","names":["WidgetBoundary","Component","McpApp","Widget","view","widgets","mountMcpApp","element","root","createRoot","app","App","disposed","terminal","connected","appVisible","render","fail","message","identify","name","widget","updateRefresh","enabled","applyContext","context","applyDocumentTheme","applyHostStyleVariables","tool","ui","args","result","dispose"],"sources":["../../../../../../src/components/McpApp.tsx"],"sourcesContent":["import type { PoMcpWidgetProps } from '@agimon-ai/po-core/web';\nimport {\n App,\n applyDocumentTheme,\n applyHostStyleVariables,\n type McpUiHostContext,\n} from '@modelcontextprotocol/ext-apps';\nimport { Component, type ComponentType, type ReactNode } from 'react';\nimport { createRoot } from 'react-dom/client';\n\ninterface View {\n readonly widget?: string;\n readonly props: PoMcpWidgetProps;\n readonly failure?: string;\n}\n\nclass WidgetBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false };\n\n static getDerivedStateFromError() {\n return { failed: true };\n }\n\n render() {\n return this.state.failed ? <p role=\"status\">The tool widget could not be rendered.</p> : this.props.children;\n }\n}\n\n/** The root only dispatches. Tool-specific presentation belongs to the contributing package. */\nexport function McpApp({\n widgets,\n view,\n}: {\n widgets: Readonly<Record<string, ComponentType<PoMcpWidgetProps>>>;\n view: View;\n}) {\n const Widget = view.widget !== undefined && Object.hasOwn(widgets, view.widget) ? widgets[view.widget] : undefined;\n if (view.failure) return <p role=\"status\">{view.failure}</p>;\n if (Widget === undefined)\n return (\n <p role=\"status\">\n {view.widget === undefined ? 'Waiting for tool information...' : 'No widget is available for this tool.'}\n </p>\n );\n return (\n <WidgetBoundary key={view.widget}>\n <Widget {...view.props} />\n </WidgetBoundary>\n );\n}\n\n/** Mounts one independently sandboxed invocation of the sync-generated widget registry. */\nexport async function mountMcpApp(widgets: Readonly<Record<string, ComponentType<PoMcpWidgetProps>>>): Promise<void> {\n const element = document.getElementById('root');\n if (element === null) throw new Error('Missing MCP app root');\n const root = createRoot(element);\n const app = new App({ name: 'po-tools', version: '1.0.0' }, {}, { autoResize: true });\n let disposed = false;\n let terminal = false;\n let connected = false;\n let appVisible = false;\n let view: View = { props: { toolName: '', args: {}, result: null, phase: 'connecting' } };\n\n const render = (): void => {\n if (!disposed) root.render(<McpApp widgets={widgets} view={view} />);\n };\n const fail = (message: string): void => {\n terminal = true;\n view = { ...view, failure: message };\n render();\n };\n const identify = (name: unknown, widget: unknown): boolean => {\n if (typeof name === 'string' && name.length > 0) {\n if (view.props.toolName && view.props.toolName !== name) {\n fail('The tool changed. Reopen this widget from the conversation.');\n return false;\n }\n view = { ...view, props: { ...view.props, toolName: name } };\n }\n if (typeof widget === 'string') {\n if (view.widget !== undefined && view.widget !== widget) {\n fail('The widget changed. Refresh the MCP connection.');\n return false;\n }\n view = { ...view, widget };\n }\n return true;\n };\n const updateRefresh = (): void => {\n const name = view.props.toolName;\n const enabled = connected && appVisible && !!app.getHostCapabilities()?.serverTools && name.length > 0;\n view = {\n ...view,\n props: {\n ...view.props,\n refresh: enabled\n ? async () => {\n if (disposed || name !== view.props.toolName || !appVisible)\n throw new Error('This widget is no longer active.');\n return app.callServerTool({ name, arguments: { ...view.props.args } });\n }\n : undefined,\n },\n };\n };\n const applyContext = (context: McpUiHostContext | undefined): void => {\n if (disposed || context === undefined) return;\n if (context.theme) {\n applyDocumentTheme(context.theme);\n document.documentElement.classList.toggle('dark', context.theme === 'dark');\n document.documentElement.dataset.theme = context.theme;\n }\n if (context.styles?.variables) applyHostStyleVariables(context.styles.variables);\n const tool = context.toolInfo?.tool;\n if (tool) {\n if (!identify(tool.name, tool._meta?.['po/widget'])) return;\n const ui = tool._meta?.ui as { visibility?: unknown } | undefined;\n appVisible = Array.isArray(ui?.visibility) && ui.visibility.includes('app');\n }\n updateRefresh();\n render();\n };\n\n app.ontoolinputpartial = ({ arguments: args }) => {\n if (disposed || terminal) return;\n view = { ...view, props: { ...view.props, args: args ?? {}, phase: 'preparing' } };\n render();\n };\n app.ontoolinput = ({ arguments: args }) => {\n if (disposed || terminal) return;\n view = { ...view, props: { ...view.props, args: args ?? {}, phase: 'running' } };\n render();\n };\n app.ontoolresult = (result) => {\n if (disposed || terminal) return;\n if (!identify(result._meta?.['po/toolName'], result._meta?.['po/widget'])) return;\n terminal = true;\n view = { ...view, props: { ...view.props, result, phase: 'result' } };\n updateRefresh();\n render();\n };\n app.ontoolcancelled = () => {\n if (disposed || terminal) return;\n terminal = true;\n view = { ...view, props: { ...view.props, phase: 'cancelled', result: null } };\n render();\n };\n app.onhostcontextchanged = applyContext;\n\n const dispose = (): void => {\n if (disposed) return;\n view = { ...view, failure: 'Tool view closed.' };\n render();\n disposed = true;\n window.removeEventListener('pagehide', dispose);\n setTimeout(() => {\n void app.close().catch(() => {});\n }, 0);\n };\n\n app.onteardown = () => {\n dispose();\n return {};\n };\n window.addEventListener('pagehide', dispose, { once: true });\n render();\n\n try {\n await app.connect();\n if (disposed) return;\n connected = true;\n applyContext(app.getHostContext());\n } catch {\n if (!disposed) fail('Could not connect to the app host. Reopen this widget in an MCP Apps-compatible client.');\n }\n}\n"],"mappings":"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"}
@@ -1,15 +1,15 @@
1
- import { DoomMcpWidgetProps } from "../../../po-core/dist/src/web/types/mcpWidget.mjs";
1
+ import { PoMcpWidgetProps } from "../../../po-core/dist/src/web/types/mcpWidget.mjs";
2
2
  import "../../../po-core/dist/mcpWidget.mjs";
3
3
  import { ReactNode } from "react";
4
4
  //#region src/components/McpToolWidget.d.ts
5
5
  /** Presentational primitives only. Each package chooses its own fields and result presentation. */
6
- export declare function McpToolFrame({ title, phase, result, error, children }: Pick<DoomMcpWidgetProps, 'phase' | 'result' | 'error'> & {
6
+ export declare function McpToolFrame({ title, phase, result, error, children }: Pick<PoMcpWidgetProps, 'phase' | 'result' | 'error'> & {
7
7
  title: string;
8
8
  children?: ReactNode;
9
9
  }): import("react").JSX.Element;
10
10
  export declare function McpToolFields({ fields }: {
11
11
  fields: readonly (readonly [string, unknown])[];
12
12
  }): import("react").JSX.Element | null;
13
- export declare function McpToolOutput({ result }: Pick<DoomMcpWidgetProps, 'result'>): import("react").JSX.Element | null;
13
+ export declare function McpToolOutput({ result }: Pick<PoMcpWidgetProps, 'result'>): import("react").JSX.Element | null;
14
14
  //#endregion
15
15
  //# sourceMappingURL=McpToolWidget.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"McpToolWidget.d.mts","names":[],"sources":["../../../../../../src/components/McpToolWidget.tsx"],"mappings":";;;;;wBAIgB,eACd,OACA,OACA,QACA,OACA,YACC,KAAK;EAAsD;EAAe,WAAW;oBAAW,IAAA;wBAqCnF,gBAAgB;EAAY;oBAAiD,IAAA;wBAkB7E,gBAAgB,UAAU,KAAK,gDAA6B,IAAA"}
1
+ {"version":3,"file":"McpToolWidget.d.mts","names":[],"sources":["../../../../../../src/components/McpToolWidget.tsx"],"mappings":";;;;;wBAIgB,eACd,OACA,OACA,QACA,OACA,YACC,KAAK;EAAoD;EAAe,WAAW;oBAAW,IAAA;wBAqCjF,gBAAgB;EAAY;oBAAiD,IAAA;wBAkB7E,gBAAgB,UAAU,KAAK,8CAA2B,IAAA"}
@@ -1,3 +1,3 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";function n({title:n,phase:r,result:i,error:a,children:o}){let s=r===`error`||i?.isError===!0;return/* @__PURE__ */ t(`section`,{className:`min-w-0 rounded-md border border-doom-border bg-doom-bg p-4 text-base text-doom-text`,children:[/* @__PURE__ */ e(`h1`,{className:`m-0 break-words text-lg font-semibold`,children:n}),/* @__PURE__ */ e(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,className:s?`my-2 text-doom-red`:`my-2 text-doom-dim`,children:a??(s?`Tool failed`:r===`result`?`Result received`:r===`cancelled`?`Tool cancelled`:r===`running`?`Running tool...`:r===`preparing`?`Preparing tool...`:`Connecting to host...`)}),o]})}function r(e){if(typeof e==`string`)return e.length>500?`${e.slice(0,500)}...`:e;if(typeof e==`number`&&Number.isFinite(e)||typeof e==`boolean`)return String(e);if(Array.isArray(e)&&e.every(e=>typeof e==`string`))return r(e.join(`, `))}function i({fields:n}){let i=n.flatMap(([e,t])=>{let n=r(t);return n===void 0||n===``?[]:[{label:e,text:n}]});return i.length===0?null:/* @__PURE__ */ e(`dl`,{"aria-label":`Tool details`,className:`my-3 flex min-w-0 flex-col gap-2`,children:i.map(({label:n,text:r})=>/* @__PURE__ */ t(`div`,{className:`flex min-w-0 flex-wrap gap-x-3 gap-y-1`,children:[/* @__PURE__ */ e(`dt`,{className:`text-sm text-doom-dim`,children:n}),/* @__PURE__ */ e(`dd`,{className:`m-0 min-w-0 whitespace-pre-wrap break-all text-sm`,children:r})]},n))})}function a({result:n}){if(n===null)return null;let r=8e3,i=``,a=!1,o=0;for(let e of n.content??[]){if(e.type!==`text`){o+=1;continue}let t=`${i?`
2
- `:``}${e.text}`,n=Math.max(0,r-i.length);a||=t.length>n,i+=t.slice(0,n)}if(!i&&n.structuredContent){let e=JSON.stringify(n.structuredContent,null,2);i=e.slice(0,r),a=e.length>r}return/* @__PURE__ */ t(`details`,{open:!0,className:`min-w-0 rounded-md border border-doom-border-soft`,children:[/* @__PURE__ */ e(`summary`,{className:`cursor-pointer bg-doom-panel p-3 text-sm focus-visible:outline`,children:`Tool output`}),/* @__PURE__ */ e(`pre`,{tabIndex:0,"aria-label":`Tool output preview`,className:`m-0 max-h-72 overflow-auto whitespace-pre-wrap break-all p-3 font-mono text-sm`,children:i||(o?`Non-text result returned to the agent.`:`No text output.`)}),a||o?/* @__PURE__ */ t(`p`,{className:`m-0 border-t border-doom-border-soft p-3 text-sm text-doom-dim`,children:[a?`Preview truncated. Full output remains in the tool result. `:``,o?`${o} non-text content item(s) returned to the agent.`:``]}):null]})}export{i as McpToolFields,n as McpToolFrame,a as McpToolOutput};
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";function n({title:n,phase:r,result:i,error:a,children:o}){let s=r===`error`||i?.isError===!0;return/* @__PURE__ */ t(`section`,{className:`min-w-0 rounded-md border border-po-border bg-po-bg p-4 text-base text-po-text`,children:[/* @__PURE__ */ e(`h1`,{className:`m-0 break-words text-lg font-semibold`,children:n}),/* @__PURE__ */ e(`p`,{role:`status`,"aria-live":`polite`,"aria-atomic":`true`,className:s?`my-2 text-po-red`:`my-2 text-po-dim`,children:a??(s?`Tool failed`:r===`result`?`Result received`:r===`cancelled`?`Tool cancelled`:r===`running`?`Running tool...`:r===`preparing`?`Preparing tool...`:`Connecting to host...`)}),o]})}function r(e){if(typeof e==`string`)return e.length>500?`${e.slice(0,500)}...`:e;if(typeof e==`number`&&Number.isFinite(e)||typeof e==`boolean`)return String(e);if(Array.isArray(e)&&e.every(e=>typeof e==`string`))return r(e.join(`, `))}function i({fields:n}){let i=n.flatMap(([e,t])=>{let n=r(t);return n===void 0||n===``?[]:[{label:e,text:n}]});return i.length===0?null:/* @__PURE__ */ e(`dl`,{"aria-label":`Tool details`,className:`my-3 flex min-w-0 flex-col gap-2`,children:i.map(({label:n,text:r})=>/* @__PURE__ */ t(`div`,{className:`flex min-w-0 flex-wrap gap-x-3 gap-y-1`,children:[/* @__PURE__ */ e(`dt`,{className:`text-sm text-po-dim`,children:n}),/* @__PURE__ */ e(`dd`,{className:`m-0 min-w-0 whitespace-pre-wrap break-all text-sm`,children:r})]},n))})}function a({result:n}){if(n===null)return null;let r=8e3,i=``,a=!1,o=0;for(let e of n.content??[]){if(e.type!==`text`){o+=1;continue}let t=`${i?`
2
+ `:``}${e.text}`,n=Math.max(0,r-i.length);a||=t.length>n,i+=t.slice(0,n)}if(!i&&n.structuredContent){let e=JSON.stringify(n.structuredContent,null,2);i=e.slice(0,r),a=e.length>r}return/* @__PURE__ */ t(`details`,{open:!0,className:`min-w-0 rounded-md border border-po-border-soft`,children:[/* @__PURE__ */ e(`summary`,{className:`cursor-pointer bg-po-panel p-3 text-sm focus-visible:outline`,children:`Tool output`}),/* @__PURE__ */ e(`pre`,{tabIndex:0,"aria-label":`Tool output preview`,className:`m-0 max-h-72 overflow-auto whitespace-pre-wrap break-all p-3 font-mono text-sm`,children:i||(o?`Non-text result returned to the agent.`:`No text output.`)}),a||o?/* @__PURE__ */ t(`p`,{className:`m-0 border-t border-po-border-soft p-3 text-sm text-po-dim`,children:[a?`Preview truncated. Full output remains in the tool result. `:``,o?`${o} non-text content item(s) returned to the agent.`:``]}):null]})}export{i as McpToolFields,n as McpToolFrame,a as McpToolOutput};
3
3
  //# sourceMappingURL=McpToolWidget.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"McpToolWidget.mjs","names":["McpToolFrame","failed","phase","result","title","error","children","fieldText","value","item","McpToolFields","values","fields","label","text","McpToolOutput","limit","truncated","nonText","block","part","remaining"],"sources":["../../../../../../src/components/McpToolWidget.tsx"],"sourcesContent":["import type { DoomMcpWidgetProps } from '@agimon-ai/po-core/mcpWidget';\nimport type { ReactNode } from 'react';\n\n/** Presentational primitives only. Each package chooses its own fields and result presentation. */\nexport function McpToolFrame({\n title,\n phase,\n result,\n error,\n children,\n}: Pick<DoomMcpWidgetProps, 'phase' | 'result' | 'error'> & { title: string; children?: ReactNode }) {\n const failed = phase === 'error' || result?.isError === true;\n const status = failed\n ? 'Tool failed'\n : phase === 'result'\n ? 'Result received'\n : phase === 'cancelled'\n ? 'Tool cancelled'\n : phase === 'running'\n ? 'Running tool...'\n : phase === 'preparing'\n ? 'Preparing tool...'\n : 'Connecting to host...';\n return (\n <section className=\"min-w-0 rounded-md border border-doom-border bg-doom-bg p-4 text-base text-doom-text\">\n <h1 className=\"m-0 break-words text-lg font-semibold\">{title}</h1>\n <p\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={failed ? 'my-2 text-doom-red' : 'my-2 text-doom-dim'}\n >\n {error ?? status}\n </p>\n {children}\n </section>\n );\n}\n\nfunction fieldText(value: unknown): string | undefined {\n if (typeof value === 'string') return value.length > 500 ? `${value.slice(0, 500)}...` : value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n if (typeof value === 'boolean') return String(value);\n if (Array.isArray(value) && value.every((item) => typeof item === 'string')) return fieldText(value.join(', '));\n return undefined;\n}\n\nexport function McpToolFields({ fields }: { fields: readonly (readonly [string, unknown])[] }) {\n const values = fields.flatMap(([label, value]) => {\n const text = fieldText(value);\n return text === undefined || text === '' ? [] : [{ label, text }];\n });\n if (values.length === 0) return null;\n return (\n <dl aria-label=\"Tool details\" className=\"my-3 flex min-w-0 flex-col gap-2\">\n {values.map(({ label, text }) => (\n <div key={label} className=\"flex min-w-0 flex-wrap gap-x-3 gap-y-1\">\n <dt className=\"text-sm text-doom-dim\">{label}</dt>\n <dd className=\"m-0 min-w-0 whitespace-pre-wrap break-all text-sm\">{text}</dd>\n </div>\n ))}\n </dl>\n );\n}\n\nexport function McpToolOutput({ result }: Pick<DoomMcpWidgetProps, 'result'>) {\n if (result === null) return null;\n const limit = 8000;\n let text = '';\n let truncated = false;\n let nonText = 0;\n for (const block of result.content ?? []) {\n if (block.type !== 'text') {\n nonText += 1;\n continue;\n }\n const part = `${text ? '\\n' : ''}${block.text}`;\n const remaining = Math.max(0, limit - text.length);\n truncated ||= part.length > remaining;\n text += part.slice(0, remaining);\n }\n if (!text && result.structuredContent) {\n const value = JSON.stringify(result.structuredContent, null, 2);\n text = value.slice(0, limit);\n truncated = value.length > limit;\n }\n return (\n <details open className=\"min-w-0 rounded-md border border-doom-border-soft\">\n <summary className=\"cursor-pointer bg-doom-panel p-3 text-sm focus-visible:outline\">Tool output</summary>\n <pre\n tabIndex={0}\n aria-label=\"Tool output preview\"\n className=\"m-0 max-h-72 overflow-auto whitespace-pre-wrap break-all p-3 font-mono text-sm\"\n >\n {text || (nonText ? 'Non-text result returned to the agent.' : 'No text output.')}\n </pre>\n {truncated || nonText ? (\n <p className=\"m-0 border-t border-doom-border-soft p-3 text-sm text-doom-dim\">\n {truncated ? 'Preview truncated. Full output remains in the tool result. ' : ''}\n {nonText ? `${nonText} non-text content item(s) returned to the agent.` : ''}\n </p>\n ) : null}\n </details>\n );\n}\n"],"mappings":"kDAIA,SAAgBA,EAAa,CAC3B,QACA,QACA,SACA,QACA,YACmG,CACnG,IAAMC,EAASC,IAAU,SAAWC,GAAQ,UAAY,GAYxD,MACE,kBAAC,UAAD,CAAS,UAAU,uFAAnB,SAAA,CACE,kBAAC,KAAD,CAAI,UAAU,wCAAyC,SAAAC,CAAU,CAAA,EACjE,kBAAC,IAAD,CACE,KAAK,SACL,YAAU,SACV,cAAY,OACZ,UAAWH,EAAS,qBAAuB,qBAE1C,SAAAI,IApBQJ,EACX,cACAC,IAAU,SACR,kBACAA,IAAU,YACR,iBACAA,IAAU,UACR,kBACAA,IAAU,YACR,oBACA,wBAWL,CAAA,EACFI,CACM,GAEb,CAEA,SAASC,EAAU,EAAoC,CACrD,GAAI,OAAOC,GAAU,SAAU,OAAOA,EAAM,OAAS,IAAM,GAAGA,EAAM,MAAM,EAAG,GAAG,EAAE,KAAOA,EAEzF,GADI,OAAOA,GAAU,UAAY,OAAO,SAASA,CAAK,GAClD,OAAOA,GAAU,UAAW,OAAO,OAAOA,CAAK,EACnD,GAAI,MAAM,QAAQA,CAAK,GAAKA,EAAM,MAAO,GAAS,OAAOC,GAAS,QAAQ,EAAG,OAAOF,EAAUC,EAAM,KAAK,IAAI,CAAC,CAEhH,CAEA,SAAgBE,EAAc,CAAE,UAA+D,CAC7F,IAAMC,EAASC,EAAO,SAAS,CAACC,EAAOL,KAAW,CAChD,IAAMM,EAAOP,EAAUC,CAAK,EAC5B,OAAOM,IAAS,IAAA,IAAaA,IAAS,GAAK,CAAC,EAAI,CAAC,CAAE,QAAO,MAAK,CAAC,CAClE,CAAC,EAED,OADIH,EAAO,SAAW,EAAU,KAE9B,kBAAC,KAAD,CAAI,aAAW,eAAe,UAAU,mCACrC,SAAAA,EAAO,KAAK,CAAE,QAAO,UACpB,kBAAC,MAAD,CAAiB,UAAU,yCAA3B,SAAA,CACE,kBAAC,KAAD,CAAI,UAAU,wBAAyB,SAAAE,CAAU,CAAA,EACjD,kBAAC,KAAD,CAAI,UAAU,oDAAqD,SAAAC,CAAS,CAAA,CACzE,CAHK,EAAAD,CAGL,CACN,CACC,CAAA,CAER,CAEA,SAAgBE,EAAc,CAAE,UAA8C,CAC5E,GAAIZ,IAAW,KAAM,OAAO,KAC5B,IAAMa,EAAQ,IACVF,EAAO,GACPG,EAAY,GACZC,EAAU,EACd,IAAK,IAAMC,KAAShB,EAAO,SAAW,CAAC,EAAG,CACxC,GAAIgB,EAAM,OAAS,OAAQ,CACzB,GAAW,EACX,QACF,CACA,IAAMC,EAAO,GAAGN,EAAO;EAAO,KAAKK,EAAM,OACnCE,EAAY,KAAK,IAAI,EAAGL,EAAQF,EAAK,MAAM,EACjD,IAAcM,EAAK,OAASC,EAC5B,GAAQD,EAAK,MAAM,EAAGC,CAAS,CACjC,CACA,GAAI,CAACP,GAAQX,EAAO,kBAAmB,CACrC,IAAMK,EAAQ,KAAK,UAAUL,EAAO,kBAAmB,KAAM,CAAC,EAC9D,EAAOK,EAAM,MAAM,EAAGQ,CAAK,EAC3B,EAAYR,EAAM,OAASQ,CAC7B,CACA,MACE,kBAAC,UAAD,CAAS,KAAA,GAAK,UAAU,oDAAxB,SAAA,CACE,kBAAC,UAAD,CAAS,UAAU,iEAAiE,SAAA,aAAoB,CAAA,EACxG,kBAAC,MAAD,CACE,SAAU,EACV,aAAW,sBACX,UAAU,iFAET,SAAAF,IAASI,EAAU,yCAA2C,kBAC5D,CAAA,EACJD,GAAaC,EACZ,kBAAC,IAAD,CAAG,UAAU,iEAAb,SAAA,CACGD,EAAY,8DAAgE,GAC5EC,EAAU,GAAGA,EAAQ,kDAAoD,EACzE,CACD,CAAA,EAAA,IACG,GAEb"}
1
+ {"version":3,"file":"McpToolWidget.mjs","names":["McpToolFrame","failed","phase","result","title","error","children","fieldText","value","item","McpToolFields","values","fields","label","text","McpToolOutput","limit","truncated","nonText","block","part","remaining"],"sources":["../../../../../../src/components/McpToolWidget.tsx"],"sourcesContent":["import type { PoMcpWidgetProps } from '@agimon-ai/po-core/mcpWidget';\nimport type { ReactNode } from 'react';\n\n/** Presentational primitives only. Each package chooses its own fields and result presentation. */\nexport function McpToolFrame({\n title,\n phase,\n result,\n error,\n children,\n}: Pick<PoMcpWidgetProps, 'phase' | 'result' | 'error'> & { title: string; children?: ReactNode }) {\n const failed = phase === 'error' || result?.isError === true;\n const status = failed\n ? 'Tool failed'\n : phase === 'result'\n ? 'Result received'\n : phase === 'cancelled'\n ? 'Tool cancelled'\n : phase === 'running'\n ? 'Running tool...'\n : phase === 'preparing'\n ? 'Preparing tool...'\n : 'Connecting to host...';\n return (\n <section className=\"min-w-0 rounded-md border border-po-border bg-po-bg p-4 text-base text-po-text\">\n <h1 className=\"m-0 break-words text-lg font-semibold\">{title}</h1>\n <p\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={failed ? 'my-2 text-po-red' : 'my-2 text-po-dim'}\n >\n {error ?? status}\n </p>\n {children}\n </section>\n );\n}\n\nfunction fieldText(value: unknown): string | undefined {\n if (typeof value === 'string') return value.length > 500 ? `${value.slice(0, 500)}...` : value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n if (typeof value === 'boolean') return String(value);\n if (Array.isArray(value) && value.every((item) => typeof item === 'string')) return fieldText(value.join(', '));\n return undefined;\n}\n\nexport function McpToolFields({ fields }: { fields: readonly (readonly [string, unknown])[] }) {\n const values = fields.flatMap(([label, value]) => {\n const text = fieldText(value);\n return text === undefined || text === '' ? [] : [{ label, text }];\n });\n if (values.length === 0) return null;\n return (\n <dl aria-label=\"Tool details\" className=\"my-3 flex min-w-0 flex-col gap-2\">\n {values.map(({ label, text }) => (\n <div key={label} className=\"flex min-w-0 flex-wrap gap-x-3 gap-y-1\">\n <dt className=\"text-sm text-po-dim\">{label}</dt>\n <dd className=\"m-0 min-w-0 whitespace-pre-wrap break-all text-sm\">{text}</dd>\n </div>\n ))}\n </dl>\n );\n}\n\nexport function McpToolOutput({ result }: Pick<PoMcpWidgetProps, 'result'>) {\n if (result === null) return null;\n const limit = 8000;\n let text = '';\n let truncated = false;\n let nonText = 0;\n for (const block of result.content ?? []) {\n if (block.type !== 'text') {\n nonText += 1;\n continue;\n }\n const part = `${text ? '\\n' : ''}${block.text}`;\n const remaining = Math.max(0, limit - text.length);\n truncated ||= part.length > remaining;\n text += part.slice(0, remaining);\n }\n if (!text && result.structuredContent) {\n const value = JSON.stringify(result.structuredContent, null, 2);\n text = value.slice(0, limit);\n truncated = value.length > limit;\n }\n return (\n <details open className=\"min-w-0 rounded-md border border-po-border-soft\">\n <summary className=\"cursor-pointer bg-po-panel p-3 text-sm focus-visible:outline\">Tool output</summary>\n <pre\n tabIndex={0}\n aria-label=\"Tool output preview\"\n className=\"m-0 max-h-72 overflow-auto whitespace-pre-wrap break-all p-3 font-mono text-sm\"\n >\n {text || (nonText ? 'Non-text result returned to the agent.' : 'No text output.')}\n </pre>\n {truncated || nonText ? (\n <p className=\"m-0 border-t border-po-border-soft p-3 text-sm text-po-dim\">\n {truncated ? 'Preview truncated. Full output remains in the tool result. ' : ''}\n {nonText ? `${nonText} non-text content item(s) returned to the agent.` : ''}\n </p>\n ) : null}\n </details>\n );\n}\n"],"mappings":"kDAIA,SAAgBA,EAAa,CAC3B,QACA,QACA,SACA,QACA,YACiG,CACjG,IAAMC,EAASC,IAAU,SAAWC,GAAQ,UAAY,GAYxD,MACE,kBAAC,UAAD,CAAS,UAAU,iFAAnB,SAAA,CACE,kBAAC,KAAD,CAAI,UAAU,wCAAyC,SAAAC,CAAU,CAAA,EACjE,kBAAC,IAAD,CACE,KAAK,SACL,YAAU,SACV,cAAY,OACZ,UAAWH,EAAS,mBAAqB,mBAExC,SAAAI,IApBQJ,EACX,cACAC,IAAU,SACR,kBACAA,IAAU,YACR,iBACAA,IAAU,UACR,kBACAA,IAAU,YACR,oBACA,wBAWL,CAAA,EACFI,CACM,GAEb,CAEA,SAASC,EAAU,EAAoC,CACrD,GAAI,OAAOC,GAAU,SAAU,OAAOA,EAAM,OAAS,IAAM,GAAGA,EAAM,MAAM,EAAG,GAAG,EAAE,KAAOA,EAEzF,GADI,OAAOA,GAAU,UAAY,OAAO,SAASA,CAAK,GAClD,OAAOA,GAAU,UAAW,OAAO,OAAOA,CAAK,EACnD,GAAI,MAAM,QAAQA,CAAK,GAAKA,EAAM,MAAO,GAAS,OAAOC,GAAS,QAAQ,EAAG,OAAOF,EAAUC,EAAM,KAAK,IAAI,CAAC,CAEhH,CAEA,SAAgBE,EAAc,CAAE,UAA+D,CAC7F,IAAMC,EAASC,EAAO,SAAS,CAACC,EAAOL,KAAW,CAChD,IAAMM,EAAOP,EAAUC,CAAK,EAC5B,OAAOM,IAAS,IAAA,IAAaA,IAAS,GAAK,CAAC,EAAI,CAAC,CAAE,QAAO,MAAK,CAAC,CAClE,CAAC,EAED,OADIH,EAAO,SAAW,EAAU,KAE9B,kBAAC,KAAD,CAAI,aAAW,eAAe,UAAU,mCACrC,SAAAA,EAAO,KAAK,CAAE,QAAO,UACpB,kBAAC,MAAD,CAAiB,UAAU,yCAA3B,SAAA,CACE,kBAAC,KAAD,CAAI,UAAU,sBAAuB,SAAAE,CAAU,CAAA,EAC/C,kBAAC,KAAD,CAAI,UAAU,oDAAqD,SAAAC,CAAS,CAAA,CACzE,CAHK,EAAAD,CAGL,CACN,CACC,CAAA,CAER,CAEA,SAAgBE,EAAc,CAAE,UAA4C,CAC1E,GAAIZ,IAAW,KAAM,OAAO,KAC5B,IAAMa,EAAQ,IACVF,EAAO,GACPG,EAAY,GACZC,EAAU,EACd,IAAK,IAAMC,KAAShB,EAAO,SAAW,CAAC,EAAG,CACxC,GAAIgB,EAAM,OAAS,OAAQ,CACzB,GAAW,EACX,QACF,CACA,IAAMC,EAAO,GAAGN,EAAO;EAAO,KAAKK,EAAM,OACnCE,EAAY,KAAK,IAAI,EAAGL,EAAQF,EAAK,MAAM,EACjD,IAAcM,EAAK,OAASC,EAC5B,GAAQD,EAAK,MAAM,EAAGC,CAAS,CACjC,CACA,GAAI,CAACP,GAAQX,EAAO,kBAAmB,CACrC,IAAMK,EAAQ,KAAK,UAAUL,EAAO,kBAAmB,KAAM,CAAC,EAC9D,EAAOK,EAAM,MAAM,EAAGQ,CAAK,EAC3B,EAAYR,EAAM,OAASQ,CAC7B,CACA,MACE,kBAAC,UAAD,CAAS,KAAA,GAAK,UAAU,kDAAxB,SAAA,CACE,kBAAC,UAAD,CAAS,UAAU,+DAA+D,SAAA,aAAoB,CAAA,EACtG,kBAAC,MAAD,CACE,SAAU,EACV,aAAW,sBACX,UAAU,iFAET,SAAAF,IAASI,EAAU,yCAA2C,kBAC5D,CAAA,EACJD,GAAaC,EACZ,kBAAC,IAAD,CAAG,UAAU,6DAAb,SAAA,CACGD,EAAY,8DAAgE,GAC5EC,EAAU,GAAGA,EAAQ,kDAAoD,EACzE,CACD,CAAA,EAAA,IACG,GAEb"}
@@ -1,2 +1,2 @@
1
- import{FileIcon as e}from"../icons/icons.mjs";import{cn as t}from"../lib/cn.mjs";import{Badge as n}from"./Badge.mjs";import{mediaKindOf as r}from"../lib/media.mjs";import{boundedMediaTime as i}from"../lib/mediaPlayback.mjs";import{PdfPreview as a}from"./PdfPreview.mjs";import{jsx as o,jsxs as s}from"react/jsx-runtime";import{useEffect as c,useImperativeHandle as l,useRef as u}from"react";const d=`max-w-full rounded border border-doom-border bg-doom-deep`;function f(e){return{playing:!e.paused&&!e.ended,currentTime:e.currentTime,duration:Number.isFinite(e.duration)?e.duration:0}}function p(e,t={current:void 0}){return{play:async()=>{let t=e.current;t!==null&&await t.play()},pause:()=>e.current?.pause(),seek:t=>{let n=e.current;n!==null&&(n.currentTime=i(t,n.duration))},getState:()=>{let t=e.current;return t===null?{playing:!1,currentTime:0,duration:0}:f(t)},isFrameReady:()=>{let n=e.current;return n!==null&&!n.seeking&&n.readyState>=2&&(n.requestVideoFrameCallback===void 0||t.current!==void 0)},getIntrinsicSize:()=>{let t=e.current;return t===null||t.videoWidth<=0||t.videoHeight<=0?null:{width:t.videoWidth,height:t.videoHeight}},captureFrame:async(n=`image/png`,r)=>{let i=e.current;if(i===null||i.videoWidth<=0||i.videoHeight<=0||i.seeking)return null;let a=t.current===void 0?void 0:{...t.current},o=a?.mediaTime??i.currentTime,s=document.createElement(`canvas`);s.width=i.videoWidth,s.height=i.videoHeight;let c=s.getContext(`2d`);if(c===null)return null;c.drawImage(i,0,0,s.width,s.height);let l=await new Promise(e=>s.toBlob(e,n,r));return l===null?null:{blob:l,width:s.width,height:s.height,timeSeconds:o,...a===void 0?{}:{metadata:a}}}}}function m({src:e,className:n,testId:r,controllerRef:i,onPlaybackStateChange:a,videoControls:s=!0}){let m=u(null),h=u(void 0),g=()=>{let e=m.current;e!==null&&a?.(f(e))},_=u(g);return c(()=>{_.current=g}),l(i,()=>p(m,h),[]),c(()=>{let e=m.current;if(e===null||e.requestVideoFrameCallback===void 0)return;let t=0,n=(r,i)=>{h.current={mediaTime:i.mediaTime,...Number.isFinite(i.presentedFrames)?{presentedFrames:i.presentedFrames}:{}},_.current(),t=e.requestVideoFrameCallback(n)};return t=e.requestVideoFrameCallback(n),()=>e.cancelVideoFrameCallback(t)},[]),/* @__PURE__ */ o(`video`,{ref:m,src:e,controls:s,playsInline:!0,preload:`metadata`,"data-testid":r,"data-kind":`video`,className:t(d,`max-h-[36rem]`,n),onPlay:g,onPause:g,onTimeUpdate:g,onDurationChange:g,onEnded:g,onLoadedMetadata:g,onLoadedData:g,onSeeking:()=>{h.current=void 0,g()},onSeeked:g,children:/* @__PURE__ */ o(`track`,{kind:`captions`})})}function h({src:i,path:c,kind:l,contentType:u,className:f,controllerRef:p,pdfControllerRef:h,onPlaybackStateChange:g,videoControls:_,"data-testid":v}){let y=l??r(c),b=c.split(`/`).at(-1)??c;if(y===`image`){let e=/^image\/(?:avif|bmp|gif|jpeg|png|webp)$/i.test(u??``),n=/* @__PURE__ */ o(`img`,{src:i,alt:c,className:t(d,`max-h-[36rem]`,f)});return e?/* @__PURE__ */ o(`a`,{href:i,target:`_blank`,rel:`noreferrer`,"data-testid":v,"data-kind":y,children:n}):/* @__PURE__ */ o(`span`,{"data-testid":v,"data-kind":y,children:n})}return y===`video`?/* @__PURE__ */ o(m,{src:i,className:f,controllerRef:p,onPlaybackStateChange:g,testId:v,videoControls:_}):y===`pdf`?/* @__PURE__ */ o(a,{src:i,path:c,controllerRef:h,"data-testid":v,className:f}):/* @__PURE__ */ o(n,{asChild:!0,size:`md`,"data-testid":v,"data-kind":y,className:t(`self-start bg-doom-panel text-doom-text hover:border-doom-blue/50`,f),children:/* @__PURE__ */ s(`a`,{href:i,download:b,children:[/* @__PURE__ */ o(e,{className:`h-3 w-3 shrink-0 text-doom-faint`}),`download `,b]})})}export{h as MediaPreview,f as mediaPlaybackState,p as mediaPreviewController};
1
+ import{FileIcon as e}from"../icons/icons.mjs";import{cn as t}from"../lib/cn.mjs";import{Badge as n}from"./Badge.mjs";import{mediaKindOf as r}from"../lib/media.mjs";import{boundedMediaTime as i}from"../lib/mediaPlayback.mjs";import{PdfPreview as a}from"./PdfPreview.mjs";import{jsx as o,jsxs as s}from"react/jsx-runtime";import{useEffect as c,useImperativeHandle as l,useRef as u}from"react";const d=`max-w-full rounded border border-po-border bg-po-deep`;function f(e){return{playing:!e.paused&&!e.ended,currentTime:e.currentTime,duration:Number.isFinite(e.duration)?e.duration:0}}function p(e,t={current:void 0}){return{play:async()=>{let t=e.current;t!==null&&await t.play()},pause:()=>e.current?.pause(),seek:t=>{let n=e.current;n!==null&&(n.currentTime=i(t,n.duration))},getState:()=>{let t=e.current;return t===null?{playing:!1,currentTime:0,duration:0}:f(t)},isFrameReady:()=>{let n=e.current;return n!==null&&!n.seeking&&n.readyState>=2&&(n.requestVideoFrameCallback===void 0||t.current!==void 0)},getIntrinsicSize:()=>{let t=e.current;return t===null||t.videoWidth<=0||t.videoHeight<=0?null:{width:t.videoWidth,height:t.videoHeight}},captureFrame:async(n=`image/png`,r)=>{let i=e.current;if(i===null||i.videoWidth<=0||i.videoHeight<=0||i.seeking)return null;let a=t.current===void 0?void 0:{...t.current},o=a?.mediaTime??i.currentTime,s=document.createElement(`canvas`);s.width=i.videoWidth,s.height=i.videoHeight;let c=s.getContext(`2d`);if(c===null)return null;c.drawImage(i,0,0,s.width,s.height);let l=await new Promise(e=>s.toBlob(e,n,r));return l===null?null:{blob:l,width:s.width,height:s.height,timeSeconds:o,...a===void 0?{}:{metadata:a}}}}}function m({src:e,className:n,testId:r,controllerRef:i,onPlaybackStateChange:a,videoControls:s=!0}){let m=u(null),h=u(void 0),g=()=>{let e=m.current;e!==null&&a?.(f(e))},_=u(g);return c(()=>{_.current=g}),l(i,()=>p(m,h),[]),c(()=>{let e=m.current;if(e===null||e.requestVideoFrameCallback===void 0)return;let t=0,n=(r,i)=>{h.current={mediaTime:i.mediaTime,...Number.isFinite(i.presentedFrames)?{presentedFrames:i.presentedFrames}:{}},_.current(),t=e.requestVideoFrameCallback(n)};return t=e.requestVideoFrameCallback(n),()=>e.cancelVideoFrameCallback(t)},[]),/* @__PURE__ */ o(`video`,{ref:m,src:e,controls:s,playsInline:!0,preload:`metadata`,"data-testid":r,"data-kind":`video`,className:t(d,`max-h-[36rem]`,n),onPlay:g,onPause:g,onTimeUpdate:g,onDurationChange:g,onEnded:g,onLoadedMetadata:g,onLoadedData:g,onSeeking:()=>{h.current=void 0,g()},onSeeked:g,children:/* @__PURE__ */ o(`track`,{kind:`captions`})})}function h({src:i,path:c,kind:l,contentType:u,className:f,controllerRef:p,pdfControllerRef:h,onPlaybackStateChange:g,videoControls:_,"data-testid":v}){let y=l??r(c),b=c.split(`/`).at(-1)??c;if(y===`image`){let e=/^image\/(?:avif|bmp|gif|jpeg|png|webp)$/i.test(u??``),n=/* @__PURE__ */ o(`img`,{src:i,alt:c,className:t(d,`max-h-[36rem]`,f)});return e?/* @__PURE__ */ o(`a`,{href:i,target:`_blank`,rel:`noreferrer`,"data-testid":v,"data-kind":y,children:n}):/* @__PURE__ */ o(`span`,{"data-testid":v,"data-kind":y,children:n})}return y===`video`?/* @__PURE__ */ o(m,{src:i,className:f,controllerRef:p,onPlaybackStateChange:g,testId:v,videoControls:_}):y===`pdf`?/* @__PURE__ */ o(a,{src:i,path:c,controllerRef:h,"data-testid":v,className:f}):/* @__PURE__ */ o(n,{asChild:!0,size:`md`,"data-testid":v,"data-kind":y,className:t(`self-start bg-po-panel text-po-text hover:border-po-blue/50`,f),children:/* @__PURE__ */ s(`a`,{href:i,download:b,children:[/* @__PURE__ */ o(e,{className:`h-3 w-3 shrink-0 text-po-faint`}),`download `,b]})})}export{h as MediaPreview,f as mediaPlaybackState,p as mediaPreviewController};
2
2
  //# sourceMappingURL=MediaPreview.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MediaPreview.mjs","names":["FRAME","mediaPlaybackState","video","mediaPreviewController","videoRef","boundedMediaTime","seconds","frameMetadataRef","metadata","timeSeconds","canvas","context","blob","resolve","type","quality","VideoPreview","useRef","reportState","onPlaybackStateChange","reportStateRef","useEffect","useImperativeHandle","controllerRef","request","report","videoControls","testId","cn","className","MediaPreview","resolved","kind","mediaKindOf","path","name","raster","contentType","image","src","PdfPreview","pdfControllerRef","Badge","FileIcon"],"sources":["../../../../../../src/components/MediaPreview.tsx"],"sourcesContent":["import { useEffect, useImperativeHandle, useRef } from 'react';\n\nimport { FileIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { mediaKindOf } from '../lib/media';\nimport { boundedMediaTime } from '../lib/mediaPlayback';\nimport type { MediaKind } from '../types/editor';\nimport { Badge } from './Badge';\nimport { PdfPreview, type PdfPreviewController } from './PdfPreview';\n/**\n * A file the browser can show but not edit.\n *\n * It renders bytes a server is already serving, so the caller supplies the\n * URL and this decides only which element reads it. Everything the browser\n * cannot render is a download rather than a converted approximation: a `.docx`\n * turned into HTML is a different document, and offering to edit that one\n * would be offering to overwrite the real one with it.\n */\n\nexport interface MediaPlaybackState {\n playing: boolean;\n currentTime: number;\n duration: number;\n}\n\nexport interface MediaIntrinsicSize {\n width: number;\n height: number;\n}\n\nexport interface MediaFrameMetadata {\n mediaTime: number;\n presentedFrames?: number;\n}\n\nexport interface MediaFrameCapture {\n blob: Blob;\n width: number;\n height: number;\n timeSeconds: number;\n metadata?: MediaFrameMetadata;\n}\n\nexport interface MediaPreviewController {\n play: () => Promise<void>;\n pause: () => void;\n seek: (seconds: number) => void;\n getState: () => MediaPlaybackState;\n isFrameReady: () => boolean;\n getIntrinsicSize: () => MediaIntrinsicSize | null;\n captureFrame: (type?: 'image/png' | 'image/jpeg', quality?: number) => Promise<MediaFrameCapture | null>;\n}\n\nexport interface MediaPreviewProps {\n /** Where the bytes are served from. */\n src: string;\n /** The file's path, used for the accessible name and the download name. */\n path: string;\n /** Overrides the kind inferred from the path, for a server that knows better. */\n kind?: MediaKind;\n /** The fetched MIME type, required before opening image bytes as a document. */\n contentType?: string;\n className?: string;\n videoControls?: boolean;\n 'data-testid'?: string;\n /** Video-only controller. It is assigned while the video element is mounted. */\n controllerRef?: import('react').Ref<MediaPreviewController>;\n /** PDF-only page and geometry controller. */\n pdfControllerRef?: import('react').Ref<PdfPreviewController>;\n /** Reports browser playback state changes for video previews. */\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nconst FRAME = 'max-w-full rounded border border-doom-border bg-doom-deep';\n\ninterface VideoPreviewProps {\n src: string;\n className?: string;\n testId?: string;\n videoControls?: boolean;\n controllerRef?: import('react').Ref<MediaPreviewController>;\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nexport function mediaPlaybackState(video: HTMLVideoElement): MediaPlaybackState {\n return {\n playing: !video.paused && !video.ended,\n currentTime: video.currentTime,\n duration: Number.isFinite(video.duration) ? video.duration : 0,\n };\n}\n\nexport function mediaPreviewController(\n videoRef: { readonly current: HTMLVideoElement | null },\n frameMetadataRef: { readonly current: MediaFrameMetadata | undefined } = { current: undefined },\n): MediaPreviewController {\n return {\n play: async () => {\n const video = videoRef.current;\n if (video !== null) await video.play();\n },\n pause: () => videoRef.current?.pause(),\n seek: (seconds) => {\n const video = videoRef.current;\n if (video !== null) video.currentTime = boundedMediaTime(seconds, video.duration);\n },\n getState: () => {\n const video = videoRef.current;\n return video === null ? { playing: false, currentTime: 0, duration: 0 } : mediaPlaybackState(video);\n },\n isFrameReady: () => {\n const video = videoRef.current;\n return (\n video !== null &&\n !video.seeking &&\n video.readyState >= 2 &&\n (video.requestVideoFrameCallback === undefined || frameMetadataRef.current !== undefined)\n );\n },\n getIntrinsicSize: () => {\n const video = videoRef.current;\n return video === null || video.videoWidth <= 0 || video.videoHeight <= 0\n ? null\n : { width: video.videoWidth, height: video.videoHeight };\n },\n captureFrame: async (type = 'image/png', quality) => {\n const video = videoRef.current;\n if (video === null || video.videoWidth <= 0 || video.videoHeight <= 0 || video.seeking) return null;\n const metadata = frameMetadataRef.current === undefined ? undefined : { ...frameMetadataRef.current };\n const timeSeconds = metadata?.mediaTime ?? video.currentTime;\n const canvas = document.createElement('canvas');\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n const context = canvas.getContext('2d');\n if (context === null) return null;\n context.drawImage(video, 0, 0, canvas.width, canvas.height);\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (blob === null) return null;\n return {\n blob,\n width: canvas.width,\n height: canvas.height,\n timeSeconds,\n ...(metadata === undefined ? {} : { metadata }),\n };\n },\n };\n}\n\nfunction VideoPreview({\n src,\n className,\n testId,\n controllerRef,\n onPlaybackStateChange,\n videoControls = true,\n}: VideoPreviewProps) {\n const videoRef = useRef<HTMLVideoElement>(null);\n const frameMetadataRef = useRef<MediaFrameMetadata | undefined>(undefined);\n const reportState = () => {\n const video = videoRef.current;\n if (video !== null) onPlaybackStateChange?.(mediaPlaybackState(video));\n };\n const reportStateRef = useRef(reportState);\n useEffect(() => {\n reportStateRef.current = reportState;\n });\n useImperativeHandle(controllerRef, () => mediaPreviewController(videoRef, frameMetadataRef), []);\n useEffect(() => {\n const video = videoRef.current;\n if (video === null || video.requestVideoFrameCallback === undefined) return;\n let request = 0;\n const report: VideoFrameRequestCallback = (_now, metadata) => {\n frameMetadataRef.current = {\n mediaTime: metadata.mediaTime,\n ...(Number.isFinite(metadata.presentedFrames) ? { presentedFrames: metadata.presentedFrames } : {}),\n };\n reportStateRef.current();\n request = video.requestVideoFrameCallback(report);\n };\n request = video.requestVideoFrameCallback(report);\n return () => video.cancelVideoFrameCallback(request);\n }, []);\n return (\n <video\n ref={videoRef}\n src={src}\n controls={videoControls}\n playsInline\n preload=\"metadata\"\n data-testid={testId}\n data-kind=\"video\"\n className={cn(FRAME, 'max-h-[36rem]', className)}\n onPlay={reportState}\n onPause={reportState}\n onTimeUpdate={reportState}\n onDurationChange={reportState}\n onEnded={reportState}\n onLoadedMetadata={reportState}\n onLoadedData={reportState}\n onSeeking={() => {\n frameMetadataRef.current = undefined;\n reportState();\n }}\n onSeeked={reportState}\n >\n <track kind=\"captions\" />\n </video>\n );\n}\n\nexport function MediaPreview({\n src,\n path,\n kind,\n contentType,\n className,\n controllerRef,\n pdfControllerRef,\n onPlaybackStateChange,\n videoControls,\n 'data-testid': testId,\n}: MediaPreviewProps) {\n const resolved = kind ?? mediaKindOf(path);\n const name = path.split('/').at(-1) ?? path;\n\n if (resolved === 'image') {\n // A symlink's target determines the MIME type, so the path cannot establish SVG safety.\n const raster = /^image\\/(?:avif|bmp|gif|jpeg|png|webp)$/i.test(contentType ?? '');\n const image = <img src={src} alt={path} className={cn(FRAME, 'max-h-[36rem]', className)} />;\n return raster ? (\n <a href={src} target=\"_blank\" rel=\"noreferrer\" data-testid={testId} data-kind={resolved}>\n {image}\n </a>\n ) : (\n <span data-testid={testId} data-kind={resolved}>\n {image}\n </span>\n );\n }\n if (resolved === 'video') {\n return (\n <VideoPreview\n src={src}\n className={className}\n controllerRef={controllerRef}\n onPlaybackStateChange={onPlaybackStateChange}\n testId={testId}\n videoControls={videoControls}\n />\n );\n }\n if (resolved === 'pdf') {\n return (\n <PdfPreview src={src} path={path} controllerRef={pdfControllerRef} data-testid={testId} className={className} />\n );\n }\n return (\n <Badge\n asChild\n size=\"md\"\n data-testid={testId}\n data-kind={resolved}\n className={cn('self-start bg-doom-panel text-doom-text hover:border-doom-blue/50', className)}\n >\n <a href={src} download={name}>\n <FileIcon className=\"h-3 w-3 shrink-0 text-doom-faint\" />\n download {name}\n </a>\n </Badge>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MediaPreview.mjs","names":["FRAME","mediaPlaybackState","video","mediaPreviewController","videoRef","boundedMediaTime","seconds","frameMetadataRef","metadata","timeSeconds","canvas","context","blob","resolve","type","quality","VideoPreview","useRef","reportState","onPlaybackStateChange","reportStateRef","useEffect","useImperativeHandle","controllerRef","request","report","videoControls","testId","cn","className","MediaPreview","resolved","kind","mediaKindOf","path","name","raster","contentType","image","src","PdfPreview","pdfControllerRef","Badge","FileIcon"],"sources":["../../../../../../src/components/MediaPreview.tsx"],"sourcesContent":["import { useEffect, useImperativeHandle, useRef } from 'react';\n\nimport { FileIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { mediaKindOf } from '../lib/media';\nimport { boundedMediaTime } from '../lib/mediaPlayback';\nimport type { MediaKind } from '../types/editor';\nimport { Badge } from './Badge';\nimport { PdfPreview, type PdfPreviewController } from './PdfPreview';\n/**\n * A file the browser can show but not edit.\n *\n * It renders bytes a server is already serving, so the caller supplies the\n * URL and this decides only which element reads it. Everything the browser\n * cannot render is a download rather than a converted approximation: a `.docx`\n * turned into HTML is a different document, and offering to edit that one\n * would be offering to overwrite the real one with it.\n */\n\nexport interface MediaPlaybackState {\n playing: boolean;\n currentTime: number;\n duration: number;\n}\n\nexport interface MediaIntrinsicSize {\n width: number;\n height: number;\n}\n\nexport interface MediaFrameMetadata {\n mediaTime: number;\n presentedFrames?: number;\n}\n\nexport interface MediaFrameCapture {\n blob: Blob;\n width: number;\n height: number;\n timeSeconds: number;\n metadata?: MediaFrameMetadata;\n}\n\nexport interface MediaPreviewController {\n play: () => Promise<void>;\n pause: () => void;\n seek: (seconds: number) => void;\n getState: () => MediaPlaybackState;\n isFrameReady: () => boolean;\n getIntrinsicSize: () => MediaIntrinsicSize | null;\n captureFrame: (type?: 'image/png' | 'image/jpeg', quality?: number) => Promise<MediaFrameCapture | null>;\n}\n\nexport interface MediaPreviewProps {\n /** Where the bytes are served from. */\n src: string;\n /** The file's path, used for the accessible name and the download name. */\n path: string;\n /** Overrides the kind inferred from the path, for a server that knows better. */\n kind?: MediaKind;\n /** The fetched MIME type, required before opening image bytes as a document. */\n contentType?: string;\n className?: string;\n videoControls?: boolean;\n 'data-testid'?: string;\n /** Video-only controller. It is assigned while the video element is mounted. */\n controllerRef?: import('react').Ref<MediaPreviewController>;\n /** PDF-only page and geometry controller. */\n pdfControllerRef?: import('react').Ref<PdfPreviewController>;\n /** Reports browser playback state changes for video previews. */\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nconst FRAME = 'max-w-full rounded border border-po-border bg-po-deep';\n\ninterface VideoPreviewProps {\n src: string;\n className?: string;\n testId?: string;\n videoControls?: boolean;\n controllerRef?: import('react').Ref<MediaPreviewController>;\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nexport function mediaPlaybackState(video: HTMLVideoElement): MediaPlaybackState {\n return {\n playing: !video.paused && !video.ended,\n currentTime: video.currentTime,\n duration: Number.isFinite(video.duration) ? video.duration : 0,\n };\n}\n\nexport function mediaPreviewController(\n videoRef: { readonly current: HTMLVideoElement | null },\n frameMetadataRef: { readonly current: MediaFrameMetadata | undefined } = { current: undefined },\n): MediaPreviewController {\n return {\n play: async () => {\n const video = videoRef.current;\n if (video !== null) await video.play();\n },\n pause: () => videoRef.current?.pause(),\n seek: (seconds) => {\n const video = videoRef.current;\n if (video !== null) video.currentTime = boundedMediaTime(seconds, video.duration);\n },\n getState: () => {\n const video = videoRef.current;\n return video === null ? { playing: false, currentTime: 0, duration: 0 } : mediaPlaybackState(video);\n },\n isFrameReady: () => {\n const video = videoRef.current;\n return (\n video !== null &&\n !video.seeking &&\n video.readyState >= 2 &&\n (video.requestVideoFrameCallback === undefined || frameMetadataRef.current !== undefined)\n );\n },\n getIntrinsicSize: () => {\n const video = videoRef.current;\n return video === null || video.videoWidth <= 0 || video.videoHeight <= 0\n ? null\n : { width: video.videoWidth, height: video.videoHeight };\n },\n captureFrame: async (type = 'image/png', quality) => {\n const video = videoRef.current;\n if (video === null || video.videoWidth <= 0 || video.videoHeight <= 0 || video.seeking) return null;\n const metadata = frameMetadataRef.current === undefined ? undefined : { ...frameMetadataRef.current };\n const timeSeconds = metadata?.mediaTime ?? video.currentTime;\n const canvas = document.createElement('canvas');\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n const context = canvas.getContext('2d');\n if (context === null) return null;\n context.drawImage(video, 0, 0, canvas.width, canvas.height);\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (blob === null) return null;\n return {\n blob,\n width: canvas.width,\n height: canvas.height,\n timeSeconds,\n ...(metadata === undefined ? {} : { metadata }),\n };\n },\n };\n}\n\nfunction VideoPreview({\n src,\n className,\n testId,\n controllerRef,\n onPlaybackStateChange,\n videoControls = true,\n}: VideoPreviewProps) {\n const videoRef = useRef<HTMLVideoElement>(null);\n const frameMetadataRef = useRef<MediaFrameMetadata | undefined>(undefined);\n const reportState = () => {\n const video = videoRef.current;\n if (video !== null) onPlaybackStateChange?.(mediaPlaybackState(video));\n };\n const reportStateRef = useRef(reportState);\n useEffect(() => {\n reportStateRef.current = reportState;\n });\n useImperativeHandle(controllerRef, () => mediaPreviewController(videoRef, frameMetadataRef), []);\n useEffect(() => {\n const video = videoRef.current;\n if (video === null || video.requestVideoFrameCallback === undefined) return;\n let request = 0;\n const report: VideoFrameRequestCallback = (_now, metadata) => {\n frameMetadataRef.current = {\n mediaTime: metadata.mediaTime,\n ...(Number.isFinite(metadata.presentedFrames) ? { presentedFrames: metadata.presentedFrames } : {}),\n };\n reportStateRef.current();\n request = video.requestVideoFrameCallback(report);\n };\n request = video.requestVideoFrameCallback(report);\n return () => video.cancelVideoFrameCallback(request);\n }, []);\n return (\n <video\n ref={videoRef}\n src={src}\n controls={videoControls}\n playsInline\n preload=\"metadata\"\n data-testid={testId}\n data-kind=\"video\"\n className={cn(FRAME, 'max-h-[36rem]', className)}\n onPlay={reportState}\n onPause={reportState}\n onTimeUpdate={reportState}\n onDurationChange={reportState}\n onEnded={reportState}\n onLoadedMetadata={reportState}\n onLoadedData={reportState}\n onSeeking={() => {\n frameMetadataRef.current = undefined;\n reportState();\n }}\n onSeeked={reportState}\n >\n <track kind=\"captions\" />\n </video>\n );\n}\n\nexport function MediaPreview({\n src,\n path,\n kind,\n contentType,\n className,\n controllerRef,\n pdfControllerRef,\n onPlaybackStateChange,\n videoControls,\n 'data-testid': testId,\n}: MediaPreviewProps) {\n const resolved = kind ?? mediaKindOf(path);\n const name = path.split('/').at(-1) ?? path;\n\n if (resolved === 'image') {\n // A symlink's target determines the MIME type, so the path cannot establish SVG safety.\n const raster = /^image\\/(?:avif|bmp|gif|jpeg|png|webp)$/i.test(contentType ?? '');\n const image = <img src={src} alt={path} className={cn(FRAME, 'max-h-[36rem]', className)} />;\n return raster ? (\n <a href={src} target=\"_blank\" rel=\"noreferrer\" data-testid={testId} data-kind={resolved}>\n {image}\n </a>\n ) : (\n <span data-testid={testId} data-kind={resolved}>\n {image}\n </span>\n );\n }\n if (resolved === 'video') {\n return (\n <VideoPreview\n src={src}\n className={className}\n controllerRef={controllerRef}\n onPlaybackStateChange={onPlaybackStateChange}\n testId={testId}\n videoControls={videoControls}\n />\n );\n }\n if (resolved === 'pdf') {\n return (\n <PdfPreview src={src} path={path} controllerRef={pdfControllerRef} data-testid={testId} className={className} />\n );\n }\n return (\n <Badge\n asChild\n size=\"md\"\n data-testid={testId}\n data-kind={resolved}\n className={cn('self-start bg-po-panel text-po-text hover:border-po-blue/50', className)}\n >\n <a href={src} download={name}>\n <FileIcon className=\"h-3 w-3 shrink-0 text-po-faint\" />\n download {name}\n </a>\n </Badge>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{renderMermaid as e}from"../lib/mermaidDiagram.mjs";import{SyntaxText as t}from"./SyntaxText.mjs";import{jsx as n}from"react/jsx-runtime";import{useEffect as r,useId as i,useState as a}from"react";function o({code:o}){let s=`mermaid-${i().replaceAll(/[^a-zA-Z0-9]/g,``)}`,[c,l]=a(void 0);return r(()=>{let t=!0;return e(s,o).then(e=>{t&&l({source:o,svg:e})},()=>void 0),()=>{t=!1}},[o,s]),c?.source===o?/* @__PURE__ */ n(`div`,{"data-testid":`mermaid-diagram`,dangerouslySetInnerHTML:{__html:c.svg},className:`flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full`}):/* @__PURE__ */ n(t,{text:o,className:`text-doom-text`})}export{o as MermaidDiagram};
1
+ import{renderMermaid as e}from"../lib/mermaidDiagram.mjs";import{SyntaxText as t}from"./SyntaxText.mjs";import{jsx as n}from"react/jsx-runtime";import{useEffect as r,useId as i,useState as a}from"react";function o({code:o}){let s=`mermaid-${i().replaceAll(/[^a-zA-Z0-9]/g,``)}`,[c,l]=a(void 0);return r(()=>{let t=!0;return e(s,o).then(e=>{t&&l({source:o,svg:e})},()=>void 0),()=>{t=!1}},[o,s]),c?.source===o?/* @__PURE__ */ n(`div`,{"data-testid":`mermaid-diagram`,dangerouslySetInnerHTML:{__html:c.svg},className:`flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full`}):/* @__PURE__ */ n(t,{text:o,className:`text-po-text`})}export{o as MermaidDiagram};
2
2
  //# sourceMappingURL=MermaidDiagram.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MermaidDiagram.mjs","names":["MermaidDiagram","id","useId","drawn","setDrawn","useState","useEffect","live","renderMermaid","code","SyntaxText"],"sources":["../../../../../../src/components/MermaidDiagram.tsx"],"sourcesContent":["import { useEffect, useId, useState } from 'react';\n\nimport { renderMermaid } from '../lib/mermaidDiagram';\nimport { SyntaxText } from './SyntaxText';\n\n/**\n * A mermaid fence, drawn.\n *\n * DESIGN PATTERNS:\n * - The source is the fallback, never a spinner or an error box. A diagram\n * that has not loaded yet, a diagram that fails to parse and a diagram in a\n * half-streamed message all show the text the author wrote, which stays\n * useful on its own.\n * - The rendered markup is stored with the source it came from, so a message\n * that grows never paints the previous frame's picture over new text.\n *\n * AVOID:\n * - Rendering at module scope or during render: mermaid measures text in the\n * document, so it only runs in an effect, in a browser.\n */\n\ninterface Drawn {\n source: string;\n svg: string;\n}\n\nexport function MermaidDiagram({ code }: { code: string }) {\n // Mermaid puts the id in the DOM and in the SVG's own ids, so React's\n // colon-wrapped value has to lose its punctuation first.\n const id = `mermaid-${useId().replaceAll(/[^a-zA-Z0-9]/g, '')}`;\n const [drawn, setDrawn] = useState<Drawn | undefined>(undefined);\n\n useEffect(() => {\n let live = true;\n void renderMermaid(id, code).then(\n (svg) => {\n if (live) setDrawn({ source: code, svg });\n },\n // Invalid syntax and a chunk that will not load are the same outcome\n // here: the block keeps showing its source.\n () => undefined,\n );\n return () => {\n live = false;\n };\n }, [code, id]);\n\n if (drawn?.source !== code) return <SyntaxText text={code} className=\"text-doom-text\" />;\n return (\n <div\n data-testid=\"mermaid-diagram\"\n // Mermaid sanitises its own output under the strict security level set\n // in lib/mermaidDiagram.ts; this is the only way it hands back a figure.\n dangerouslySetInnerHTML={{ __html: drawn.svg }}\n className=\"flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full\"\n />\n );\n}\n"],"mappings":"2MA0BA,SAAgBA,EAAe,CAAE,QAA0B,CAGzD,IAAMC,EAAK,WAAWC,EAAM,CAAC,CAAC,WAAW,gBAAiB,EAAE,IACtD,CAACC,EAAOC,GAAYC,EAA4B,IAAA,EAAS,EAkB/D,OAhBAC,MAAgB,CACd,IAAIC,EAAO,GASX,OARAC,EAAmBP,EAAIQ,CAAI,CAAC,CAAC,KAC1B,GAAQ,CACHF,GAAMH,EAAS,CAAE,OAAQK,EAAM,KAAI,CAAC,CAC1C,MAGM,IAAA,EACR,MACa,CACX,EAAO,EACT,CACF,EAAG,CAACA,EAAMR,CAAE,CAAC,EAETE,GAAO,SAAWM,EAEpB,kBAAC,MAAD,CACE,cAAY,kBAGZ,wBAAyB,CAAE,OAAQN,EAAM,GAAI,EAC7C,UAAU,uEACX,CAAA,EARgC,kBAACO,EAAD,CAAY,KAAMD,EAAM,UAAU,gBAAkB,CAAA,CAUzF"}
1
+ {"version":3,"file":"MermaidDiagram.mjs","names":["MermaidDiagram","id","useId","drawn","setDrawn","useState","useEffect","live","renderMermaid","code","SyntaxText"],"sources":["../../../../../../src/components/MermaidDiagram.tsx"],"sourcesContent":["import { useEffect, useId, useState } from 'react';\n\nimport { renderMermaid } from '../lib/mermaidDiagram';\nimport { SyntaxText } from './SyntaxText';\n\n/**\n * A mermaid fence, drawn.\n *\n * DESIGN PATTERNS:\n * - The source is the fallback, never a spinner or an error box. A diagram\n * that has not loaded yet, a diagram that fails to parse and a diagram in a\n * half-streamed message all show the text the author wrote, which stays\n * useful on its own.\n * - The rendered markup is stored with the source it came from, so a message\n * that grows never paints the previous frame's picture over new text.\n *\n * AVOID:\n * - Rendering at module scope or during render: mermaid measures text in the\n * document, so it only runs in an effect, in a browser.\n */\n\ninterface Drawn {\n source: string;\n svg: string;\n}\n\nexport function MermaidDiagram({ code }: { code: string }) {\n // Mermaid puts the id in the DOM and in the SVG's own ids, so React's\n // colon-wrapped value has to lose its punctuation first.\n const id = `mermaid-${useId().replaceAll(/[^a-zA-Z0-9]/g, '')}`;\n const [drawn, setDrawn] = useState<Drawn | undefined>(undefined);\n\n useEffect(() => {\n let live = true;\n void renderMermaid(id, code).then(\n (svg) => {\n if (live) setDrawn({ source: code, svg });\n },\n // Invalid syntax and a chunk that will not load are the same outcome\n // here: the block keeps showing its source.\n () => undefined,\n );\n return () => {\n live = false;\n };\n }, [code, id]);\n\n if (drawn?.source !== code) return <SyntaxText text={code} className=\"text-po-text\" />;\n return (\n <div\n data-testid=\"mermaid-diagram\"\n // Mermaid sanitises its own output under the strict security level set\n // in lib/mermaidDiagram.ts; this is the only way it hands back a figure.\n dangerouslySetInnerHTML={{ __html: drawn.svg }}\n className=\"flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full\"\n />\n );\n}\n"],"mappings":"2MA0BA,SAAgBA,EAAe,CAAE,QAA0B,CAGzD,IAAMC,EAAK,WAAWC,EAAM,CAAC,CAAC,WAAW,gBAAiB,EAAE,IACtD,CAACC,EAAOC,GAAYC,EAA4B,IAAA,EAAS,EAkB/D,OAhBAC,MAAgB,CACd,IAAIC,EAAO,GASX,OARAC,EAAmBP,EAAIQ,CAAI,CAAC,CAAC,KAC1B,GAAQ,CACHF,GAAMH,EAAS,CAAE,OAAQK,EAAM,KAAI,CAAC,CAC1C,MAGM,IAAA,EACR,MACa,CACX,EAAO,EACT,CACF,EAAG,CAACA,EAAMR,CAAE,CAAC,EAETE,GAAO,SAAWM,EAEpB,kBAAC,MAAD,CACE,cAAY,kBAGZ,wBAAyB,CAAE,OAAQN,EAAM,GAAI,EAC7C,UAAU,uEACX,CAAA,EARgC,kBAACO,EAAD,CAAY,KAAMD,EAAM,UAAU,cAAgB,CAAA,CAUvF"}
@@ -1,2 +1,2 @@
1
- import{AlertIcon as e,CheckIcon as t,ChevronDownIcon as n,ChevronUpIcon as r,LoaderIcon as i,WrenchIcon as a}from"../icons/icons.mjs";import{cn as o}from"../lib/cn.mjs";import{Button as s}from"./Button.mjs";import{STATUS_EDGE as c,StatusBadge as l}from"./StatusBadge.mjs";import{Fragment as u,jsx as d,jsxs as f}from"react/jsx-runtime";import{createContext as p,useContext as m,useState as h}from"react";import{cva as g}from"class-variance-authority";const _=p(null),v=p({tone:`neutral`,expandable:!1,expanded:!1,toggle:()=>void 0});function y(){return m(v)}const b=p(null),x=g(`overflow-hidden rounded-lg border transition-colors`,{variants:{tone:{...c,ok:`border-doom-border-soft`}},defaultVariants:{tone:`neutral`}}),S=g(`overflow-hidden border-l-2 transition-colors`,{variants:{tone:{...c,ok:`border-transparent`,neutral:`border-transparent`}},defaultVariants:{tone:`neutral`}});function C({title:e,children:t}){return/* @__PURE__ */ f(u,{children:[/* @__PURE__ */ d(`span`,{"aria-hidden":!0,className:`grid size-9 shrink-0 place-items-center rounded-full bg-doom-rail text-doom-dim max-sm:hidden`,children:/* @__PURE__ */ d(a,{className:`size-4`})}),/* @__PURE__ */ f(`div`,{className:`flex min-w-0 flex-1 flex-col`,children:[/* @__PURE__ */ d(`span`,{className:`text-sm text-doom-dim`,children:`Tool call`}),/* @__PURE__ */ f(`div`,{className:`flex min-w-0 items-center gap-2 text-base`,children:[/* @__PURE__ */ d(`span`,{className:`shrink-0 font-semibold text-doom-hi`,children:e}),/* @__PURE__ */ d(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:t})]})]})]})}function w({className:e,tone:t,expandable:n=!1,defaultExpanded:r=!1,expanded:i,onExpandedChange:a,children:s,...c}){let[l,u]=h(r),f=m(b),p=m(_),g=f!==null,y=i??l,C={tone:t??`neutral`,headerAccessory:p,expandable:n,expanded:y,toggle:()=>{let e=!y;i===void 0&&u(e),a?.(e)}};return/* @__PURE__ */ d(v.Provider,{value:C,children:/* @__PURE__ */ d(_,{value:null,children:/* @__PURE__ */ d(`div`,{"data-slot":`message-item`,"data-expanded":y,"data-grouped":g,className:o(g?S({tone:t}):x({tone:t}),e),...c,children:typeof s==`function`?s(C):s})})})}function T({className:e,tone:t,title:n,summary:r,badge:i,children:a,...s}){let c=i===void 0?D[t??`neutral`]:i;return/* @__PURE__ */ d(b.Provider,{value:{tone:t??`neutral`},children:/* @__PURE__ */ f(`div`,{"data-slot":`message-item-group`,className:o(x({tone:t}),e),...s,children:[/* @__PURE__ */ f(`div`,{className:`flex min-h-11 items-center gap-3 border-doom-border-soft border-b px-4 py-3 text-sm text-doom-dim`,children:[/* @__PURE__ */ d(C,{title:n,children:/* @__PURE__ */ d(`span`,{className:`min-w-0 flex-1 truncate text-doom-faint`,children:r})}),c!==null&&c!==``?/* @__PURE__ */ d(k,{tone:t??`neutral`,children:c}):null]}),/* @__PURE__ */ d(`div`,{className:`flex flex-col divide-y divide-doom-border-soft`,children:a})]})})}function E(e){return e.running?`running`:e.isError?`error`:`ok`}const D={neutral:``,running:`Running`,ok:`Completed`,error:`Failed`,info:`Info`,accent:`Note`},O={running:/* @__PURE__ */ d(i,{"aria-hidden":!0,className:`size-3 animate-spin`}),ok:/* @__PURE__ */ d(t,{"aria-hidden":!0,className:`size-3`}),error:/* @__PURE__ */ d(e,{"aria-hidden":!0,className:`size-3`})};function k({tone:e,children:t,...n}){return/* @__PURE__ */ f(l,{tone:e,size:`md`,className:`gap-1 font-semibold`,...n,children:[O[e],t]})}const A=/* @__PURE__ */ new Set([`ok`,`neutral`]);function j({className:e,title:t,badge:i,children:a,...c}){let{headerAccessory:l,tone:u,expandable:p,expanded:h,toggle:g}=y(),_=m(b),v=_!==null&&A.has(u)?null:D[u],x=i===void 0?v:i;return/* @__PURE__ */ f(`div`,{"data-slot":`message-item-header`,className:o(`flex min-h-11 items-center gap-3 px-4 py-3 text-sm text-doom-dim`,e),...c,children:[_===null?/* @__PURE__ */ d(C,{title:t,children:a}):/* @__PURE__ */ d(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:a}),l,x!==null&&x!==``?/* @__PURE__ */ d(k,{tone:u,"data-testid":`tool-status`,children:x}):null,p?/* @__PURE__ */ d(s,{variant:`ghost`,size:`icon`,"data-testid":`tool-expand`,"aria-expanded":h,"aria-label":h?`collapse`:`expand`,onClick:g,className:`text-doom-dim hover:text-doom-blue`,children:d(h?r:n,{className:`size-4`})}):null]})}function M({className:e,...t}){return/* @__PURE__ */ d(`div`,{"data-slot":`message-item-body`,className:o(`border-t border-doom-border-soft px-4 py-3 text-base text-doom-dim`,e),...t})}const N={neutral:`…`,running:`◐`,ok:`✓`,error:`✗`,info:`●`,accent:`●`},P=g(`shrink-0`,{variants:{tone:{neutral:`text-doom-faint`,running:`text-doom-yellow`,ok:`text-doom-green`,error:`text-doom-red`,info:`text-doom-blue`,accent:`text-doom-magenta`}},defaultVariants:{tone:`neutral`}});function F({className:e,tone:t,glyph:n,expands:r=!1,children:i,...a}){let{toggle:s}=y(),c=/* @__PURE__ */ f(u,{children:[/* @__PURE__ */ d(`span`,{className:P({tone:t}),children:n??N[t??`neutral`]}),/* @__PURE__ */ d(`span`,{children:i})]});return r?/* @__PURE__ */ d(`button`,{type:`button`,"data-slot":`message-item-status`,"data-testid":`tool-more`,onClick:s,className:o(`flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue`,e),children:c}):/* @__PURE__ */ d(`span`,{"data-slot":`message-item-status`,className:o(`flex items-center gap-1.5 text-doom-faint`,e),...a,children:c})}export{w as MessageItem,M as MessageItemBody,T as MessageItemGroup,j as MessageItemHeader,_ as MessageItemHeaderAccessoryContext,F as MessageItemStatus,N as STATUS_GLYPH,D as STATUS_LABEL,S as messageItemRowVariants,P as messageItemStatusVariants,x as messageItemVariants,E as toolTone,y as useMessageItem};
1
+ import{AlertIcon as e,CheckIcon as t,ChevronDownIcon as n,ChevronUpIcon as r,LoaderIcon as i,WrenchIcon as a}from"../icons/icons.mjs";import{cn as o}from"../lib/cn.mjs";import{Button as s}from"./Button.mjs";import{STATUS_EDGE as c,StatusBadge as l}from"./StatusBadge.mjs";import{Fragment as u,jsx as d,jsxs as f}from"react/jsx-runtime";import{createContext as p,useContext as m,useState as h}from"react";import{cva as g}from"class-variance-authority";const _=p(null),v=p({tone:`neutral`,expandable:!1,expanded:!1,toggle:()=>void 0});function y(){return m(v)}const b=p(null),x=g(`overflow-hidden rounded-lg border transition-colors`,{variants:{tone:{...c,ok:`border-po-border-soft`}},defaultVariants:{tone:`neutral`}}),S=g(`overflow-hidden border-l-2 transition-colors`,{variants:{tone:{...c,ok:`border-transparent`,neutral:`border-transparent`}},defaultVariants:{tone:`neutral`}});function C({title:e,children:t}){return/* @__PURE__ */ f(u,{children:[/* @__PURE__ */ d(`span`,{"aria-hidden":!0,className:`grid size-9 shrink-0 place-items-center rounded-full bg-po-rail text-po-dim max-sm:hidden`,children:/* @__PURE__ */ d(a,{className:`size-4`})}),/* @__PURE__ */ f(`div`,{className:`flex min-w-0 flex-1 flex-col`,children:[/* @__PURE__ */ d(`span`,{className:`text-sm text-po-dim`,children:`Tool call`}),/* @__PURE__ */ f(`div`,{className:`flex min-w-0 items-center gap-2 text-base`,children:[/* @__PURE__ */ d(`span`,{className:`shrink-0 font-semibold text-po-hi`,children:e}),/* @__PURE__ */ d(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:t})]})]})]})}function w({className:e,tone:t,expandable:n=!1,defaultExpanded:r=!1,expanded:i,onExpandedChange:a,children:s,...c}){let[l,u]=h(r),f=m(b),p=m(_),g=f!==null,y=i??l,C={tone:t??`neutral`,headerAccessory:p,expandable:n,expanded:y,toggle:()=>{let e=!y;i===void 0&&u(e),a?.(e)}};return/* @__PURE__ */ d(v.Provider,{value:C,children:/* @__PURE__ */ d(_,{value:null,children:/* @__PURE__ */ d(`div`,{"data-slot":`message-item`,"data-expanded":y,"data-grouped":g,className:o(g?S({tone:t}):x({tone:t}),e),...c,children:typeof s==`function`?s(C):s})})})}function T({className:e,tone:t,title:n,summary:r,badge:i,children:a,...s}){let c=i===void 0?D[t??`neutral`]:i;return/* @__PURE__ */ d(b.Provider,{value:{tone:t??`neutral`},children:/* @__PURE__ */ f(`div`,{"data-slot":`message-item-group`,className:o(x({tone:t}),e),...s,children:[/* @__PURE__ */ f(`div`,{className:`flex min-h-11 items-center gap-3 border-po-border-soft border-b px-4 py-3 text-sm text-po-dim`,children:[/* @__PURE__ */ d(C,{title:n,children:/* @__PURE__ */ d(`span`,{className:`min-w-0 flex-1 truncate text-po-faint`,children:r})}),c!==null&&c!==``?/* @__PURE__ */ d(k,{tone:t??`neutral`,children:c}):null]}),/* @__PURE__ */ d(`div`,{className:`flex flex-col divide-y divide-po-border-soft`,children:a})]})})}function E(e){return e.running?`running`:e.isError?`error`:`ok`}const D={neutral:``,running:`Running`,ok:`Completed`,error:`Failed`,info:`Info`,accent:`Note`},O={running:/* @__PURE__ */ d(i,{"aria-hidden":!0,className:`size-3 animate-spin`}),ok:/* @__PURE__ */ d(t,{"aria-hidden":!0,className:`size-3`}),error:/* @__PURE__ */ d(e,{"aria-hidden":!0,className:`size-3`})};function k({tone:e,children:t,...n}){return/* @__PURE__ */ f(l,{tone:e,size:`md`,className:`gap-1 font-semibold`,...n,children:[O[e],t]})}const A=/* @__PURE__ */ new Set([`ok`,`neutral`]);function j({className:e,title:t,badge:i,children:a,...c}){let{headerAccessory:l,tone:u,expandable:p,expanded:h,toggle:g}=y(),_=m(b),v=_!==null&&A.has(u)?null:D[u],x=i===void 0?v:i;return/* @__PURE__ */ f(`div`,{"data-slot":`message-item-header`,className:o(`flex min-h-11 items-center gap-3 px-4 py-3 text-sm text-po-dim`,e),...c,children:[_===null?/* @__PURE__ */ d(C,{title:t,children:a}):/* @__PURE__ */ d(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:a}),l,x!==null&&x!==``?/* @__PURE__ */ d(k,{tone:u,"data-testid":`tool-status`,children:x}):null,p?/* @__PURE__ */ d(s,{variant:`ghost`,size:`icon`,"data-testid":`tool-expand`,"aria-expanded":h,"aria-label":h?`collapse`:`expand`,onClick:g,className:`text-po-dim hover:text-po-blue`,children:d(h?r:n,{className:`size-4`})}):null]})}function M({className:e,...t}){return/* @__PURE__ */ d(`div`,{"data-slot":`message-item-body`,className:o(`border-t border-po-border-soft px-4 py-3 text-base text-po-dim`,e),...t})}const N={neutral:`…`,running:`◐`,ok:`✓`,error:`✗`,info:`●`,accent:`●`},P=g(`shrink-0`,{variants:{tone:{neutral:`text-po-faint`,running:`text-po-yellow`,ok:`text-po-green`,error:`text-po-red`,info:`text-po-blue`,accent:`text-po-magenta`}},defaultVariants:{tone:`neutral`}});function F({className:e,tone:t,glyph:n,expands:r=!1,children:i,...a}){let{toggle:s}=y(),c=/* @__PURE__ */ f(u,{children:[/* @__PURE__ */ d(`span`,{className:P({tone:t}),children:n??N[t??`neutral`]}),/* @__PURE__ */ d(`span`,{children:i})]});return r?/* @__PURE__ */ d(`button`,{type:`button`,"data-slot":`message-item-status`,"data-testid":`tool-more`,onClick:s,className:o(`flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-po-faint hover:text-po-blue`,e),children:c}):/* @__PURE__ */ d(`span`,{"data-slot":`message-item-status`,className:o(`flex items-center gap-1.5 text-po-faint`,e),...a,children:c})}export{w as MessageItem,M as MessageItemBody,T as MessageItemGroup,j as MessageItemHeader,_ as MessageItemHeaderAccessoryContext,F as MessageItemStatus,N as STATUS_GLYPH,D as STATUS_LABEL,S as messageItemRowVariants,P as messageItemStatusVariants,x as messageItemVariants,E as toolTone,y as useMessageItem};
2
2
  //# sourceMappingURL=MessageItem.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageItem.mjs","names":["MessageItemHeaderAccessoryContext","createContext","MessageItemContext","useMessageItem","useContext","MessageItemGroupContext","messageItemVariants","cva","STATUS_EDGE","messageItemRowVariants","ToolCallLead","Fragment","WrenchIcon","title","MessageItem","props","own","setOwn","useState","defaultExpanded","group","headerAccessory","grouped","current","expanded","state","tone","next","onExpandedChange","cn","className","children","MessageItemGroup","label","badge","STATUS_LABEL","summary","OutcomeBadge","toolTone","OUTCOME_ICON","LoaderIcon","CheckIcon","AlertIcon","StatusBadge","SILENT_IN_GROUP","MessageItemHeader","defaultLabel","expandable","Button","toggle","jsx","ChevronUpIcon","ChevronDownIcon","MessageItemBody","STATUS_GLYPH","messageItemStatusVariants","MessageItemStatus","content","glyph","expands"],"sources":["../../../../../../src/components/MessageItem.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { type ComponentProps, createContext, type ReactNode, useContext, useState } from 'react';\n\nimport { AlertIcon, CheckIcon, ChevronDownIcon, ChevronUpIcon, LoaderIcon, WrenchIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\nimport { STATUS_EDGE, StatusBadge, type StatusTone } from './StatusBadge';\n\n/**\n * The message item: the timeline card a tool call, a run, or a notice sits\n * in. The item owns its outcome tone and its expand state; the header, body,\n * and status parts read both from it, so a card composes the parts and never\n * threads `expanded` by hand. A tool message in a web plugin is built from\n * this, and so is the cockpit's own fallback item, which is what keeps them\n * looking alike.\n */\n\n/** The next item captures this accessory for its header, without passing it to nested items. */\nexport const MessageItemHeaderAccessoryContext = createContext<ReactNode>(null);\n\nexport interface MessageItemState {\n tone: StatusTone;\n headerAccessory?: ReactNode;\n /** Whether the header offers the toggle; an item that hides nothing offers none. */\n expandable: boolean;\n expanded: boolean;\n toggle: () => void;\n}\n\nconst MessageItemContext = createContext<MessageItemState>({\n tone: 'neutral',\n expandable: false,\n expanded: false,\n toggle: () => undefined,\n});\n\n/** The enclosing item's state, for a part that lives deeper than the item's render prop. */\nexport function useMessageItem(): MessageItemState {\n return useContext(MessageItemContext);\n}\n\n/**\n * The group an item is a row of, or null for an item that is a card of its\n * own. A row drops the frame the group already draws and keeps its tone as an\n * edge down its left side, and it stops repeating what the group's header has\n * said once: the tool's name, and an outcome the whole run shares.\n */\nconst MessageItemGroupContext = createContext<{ tone: StatusTone } | null>(null);\n\n/**\n * The frame, wearing the edge STATUS_EDGE names for the tone, so the two never drift apart.\n * A settled OK is the calm default and keeps the soft border; only work in flight or a failure colours the edge.\n */\nexport const messageItemVariants = cva('overflow-hidden rounded-lg border transition-colors', {\n variants: { tone: { ...STATUS_EDGE, ok: 'border-doom-border-soft' } },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The same tone as a row: no card, one coloured edge, and the group's separators between rows. A settled row keeps a quiet edge. */\nexport const messageItemRowVariants = cva('overflow-hidden border-l-2 transition-colors', {\n variants: { tone: { ...STATUS_EDGE, ok: 'border-transparent', neutral: 'border-transparent' } },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The card's lead: the tool chip, the \"Tool call\" caption, then the name and its summary on one line. */\nfunction ToolCallLead({ title, children }: { title: ReactNode; children?: ReactNode }) {\n return (\n <>\n <span\n aria-hidden\n className=\"grid size-9 shrink-0 place-items-center rounded-full bg-doom-rail text-doom-dim max-sm:hidden\"\n >\n <WrenchIcon className=\"size-4\" />\n </span>\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"text-sm text-doom-dim\">Tool call</span>\n <div className=\"flex min-w-0 items-center gap-2 text-base\">\n <span className=\"shrink-0 font-semibold text-doom-hi\">{title}</span>\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n </div>\n </div>\n </>\n );\n}\n\nexport interface MessageItemProps\n extends Omit<ComponentProps<'div'>, 'children'>, VariantProps<typeof messageItemVariants> {\n /** Whether the header offers the expand toggle. A toggle that reveals nothing reads as broken, so the card decides. */\n expandable?: boolean;\n defaultExpanded?: boolean;\n /** Controlled mode; pair with onExpandedChange. Omit it and the item keeps its own state. */\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n /** Plain content, or a function of the item's state for a card that picks its lines by `expanded`. */\n children?: ReactNode | ((state: MessageItemState) => ReactNode);\n}\n\nexport function MessageItem({\n className,\n tone,\n expandable = false,\n defaultExpanded = false,\n expanded,\n onExpandedChange,\n children,\n ...props\n}: MessageItemProps) {\n const [own, setOwn] = useState(defaultExpanded);\n const group = useContext(MessageItemGroupContext);\n const headerAccessory = useContext(MessageItemHeaderAccessoryContext);\n const grouped = group !== null;\n const current = expanded ?? own;\n const state: MessageItemState = {\n tone: tone ?? 'neutral',\n headerAccessory,\n expandable,\n expanded: current,\n toggle: () => {\n const next = !current;\n if (expanded === undefined) setOwn(next);\n onExpandedChange?.(next);\n },\n };\n return (\n <MessageItemContext.Provider value={state}>\n <MessageItemHeaderAccessoryContext value={null}>\n <div\n data-slot=\"message-item\"\n data-expanded={current}\n data-grouped={grouped}\n className={cn(grouped ? messageItemRowVariants({ tone }) : messageItemVariants({ tone }), className)}\n {...props}\n >\n {typeof children === 'function' ? children(state) : children}\n </div>\n </MessageItemHeaderAccessoryContext>\n </MessageItemContext.Provider>\n );\n}\n\nexport interface MessageItemGroupProps\n extends Omit<ComponentProps<'div'>, 'title'>, VariantProps<typeof messageItemVariants> {\n /** The bold label at the left of the group header: the tool the run belongs to. */\n title: ReactNode;\n /** The line beside it, such as how many calls the group holds. */\n summary?: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n children?: ReactNode;\n}\n\n/**\n * One frame around a run of items that belong together.\n *\n * A transcript that calls the same tool five times in a row is five identical\n * frames, five gutter labels and five gaps, and the repetition reads louder\n * than the commands do. The group draws the frame once and each item inside it\n * becomes a row: same header, same expand, no card of its own. The tone still\n * belongs to the row, as an edge, so a failure in the middle of a run is not\n * flattened into the group's own outcome.\n */\nexport function MessageItemGroup({\n className,\n tone,\n title,\n summary,\n badge,\n children,\n ...props\n}: MessageItemGroupProps) {\n const label = badge === undefined ? STATUS_LABEL[tone ?? 'neutral'] : badge;\n return (\n <MessageItemGroupContext.Provider value={{ tone: tone ?? 'neutral' }}>\n <div data-slot=\"message-item-group\" className={cn(messageItemVariants({ tone }), className)} {...props}>\n <div className=\"flex min-h-11 items-center gap-3 border-doom-border-soft border-b px-4 py-3 text-sm text-doom-dim\">\n <ToolCallLead title={title}>\n <span className=\"min-w-0 flex-1 truncate text-doom-faint\">{summary}</span>\n </ToolCallLead>\n {label !== null && label !== '' ? <OutcomeBadge tone={tone ?? 'neutral'}>{label}</OutcomeBadge> : null}\n </div>\n <div className=\"flex flex-col divide-y divide-doom-border-soft\">{children}</div>\n </div>\n </MessageItemGroupContext.Provider>\n );\n}\n\n/** The tone a tool call's item wears: running while the tool runs, then its outcome. */\nexport function toolTone(state: { running: boolean; isError: boolean }): StatusTone {\n return state.running ? 'running' : state.isError ? 'error' : 'ok';\n}\n\n/** The badge text a tone reads as when the header is not told otherwise; empty hides the badge. */\nexport const STATUS_LABEL: Readonly<Record<StatusTone, string>> = {\n neutral: '',\n running: 'Running',\n ok: 'Completed',\n error: 'Failed',\n info: 'Info',\n accent: 'Note',\n};\n\nconst OUTCOME_ICON: Partial<Record<StatusTone, ReactNode>> = {\n running: <LoaderIcon aria-hidden className=\"size-3 animate-spin\" />,\n ok: <CheckIcon aria-hidden className=\"size-3\" />,\n error: <AlertIcon aria-hidden className=\"size-3\" />,\n};\n\n/** The sentence-case outcome pill, led by the tone's icon. */\nfunction OutcomeBadge({ tone, children, ...props }: ComponentProps<typeof StatusBadge> & { tone: StatusTone }) {\n return (\n <StatusBadge tone={tone} size=\"md\" className=\"gap-1 font-semibold\" {...props}>\n {OUTCOME_ICON[tone]}\n {children}\n </StatusBadge>\n );\n}\n\nexport interface MessageItemHeaderProps extends Omit<ComponentProps<'div'>, 'title'> {\n /** The bold label at the left: the tool name. */\n title: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n /** The summary beside the title; it gets the remaining width. */\n children?: ReactNode;\n}\n\n/** Inside a group these two are the quiet outcome: the group's header has already said it. */\nconst SILENT_IN_GROUP: ReadonlySet<StatusTone> = new Set<StatusTone>(['ok', 'neutral']);\n\n/**\n * The title row: label, summary, the tone's badge, and the expand toggle when\n * the item is expandable.\n *\n * A row inside a group says less. The group's header has already named the\n * tool and stated the run's outcome, so the row drops its title and speaks up\n * only when something went wrong or is still going: five OK badges down a run\n * of five are noise, and the one ERROR among them is the point.\n */\nexport function MessageItemHeader({ className, title, badge, children, ...props }: MessageItemHeaderProps) {\n const { headerAccessory, tone, expandable, expanded, toggle } = useMessageItem();\n const group = useContext(MessageItemGroupContext);\n const defaultLabel = group !== null && SILENT_IN_GROUP.has(tone) ? null : STATUS_LABEL[tone];\n const label = badge === undefined ? defaultLabel : badge;\n return (\n <div\n data-slot=\"message-item-header\"\n className={cn('flex min-h-11 items-center gap-3 px-4 py-3 text-sm text-doom-dim', className)}\n {...props}\n >\n {group === null ? (\n <ToolCallLead title={title}>{children}</ToolCallLead>\n ) : (\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n )}\n {headerAccessory}\n {label !== null && label !== '' ? (\n <OutcomeBadge tone={tone} data-testid=\"tool-status\">\n {label}\n </OutcomeBadge>\n ) : null}\n {expandable ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"tool-expand\"\n aria-expanded={expanded}\n aria-label={expanded ? 'collapse' : 'expand'}\n onClick={toggle}\n className=\"text-doom-dim hover:text-doom-blue\"\n >\n {expanded ? <ChevronUpIcon className=\"size-4\" /> : <ChevronDownIcon className=\"size-4\" />}\n </Button>\n ) : null}\n </div>\n );\n}\n\n/** The body under the header, on the card's own surface. */\nexport function MessageItemBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"message-item-body\"\n className={cn('border-t border-doom-border-soft px-4 py-3 text-base text-doom-dim', className)}\n {...props}\n />\n );\n}\n\n/** The glyph a tone reads as in a status line. */\nexport const STATUS_GLYPH: Readonly<Record<StatusTone, string>> = {\n neutral: '…',\n running: '◐',\n ok: '✓',\n error: '✗',\n info: '●',\n accent: '●',\n};\n\nexport const messageItemStatusVariants = cva('shrink-0', {\n variants: {\n tone: {\n neutral: 'text-doom-faint',\n running: 'text-doom-yellow',\n ok: 'text-doom-green',\n error: 'text-doom-red',\n info: 'text-doom-blue',\n accent: 'text-doom-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemStatusProps extends ComponentProps<'span'>, VariantProps<typeof messageItemStatusVariants> {\n /** Replaces the tone's glyph. */\n glyph?: string;\n /** Renders as a button that expands the item: the \"N more line(s)\" hint. Only className carries over. */\n expands?: boolean;\n}\n\n/** The one-line status under a body: `◐ running`, `✗ failed`, `✓ done`, or the hint that more is hidden. */\nexport function MessageItemStatus({\n className,\n tone,\n glyph,\n expands = false,\n children,\n ...props\n}: MessageItemStatusProps) {\n const { toggle } = useMessageItem();\n const content = (\n <>\n <span className={messageItemStatusVariants({ tone })}>{glyph ?? STATUS_GLYPH[tone ?? 'neutral']}</span>\n <span>{children}</span>\n </>\n );\n if (expands) {\n return (\n <button\n type=\"button\"\n data-slot=\"message-item-status\"\n data-testid=\"tool-more\"\n onClick={toggle}\n className={cn(\n 'flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue',\n className,\n )}\n >\n {content}\n </button>\n );\n }\n return (\n <span\n data-slot=\"message-item-status\"\n className={cn('flex items-center gap-1.5 text-doom-faint', className)}\n {...props}\n >\n {content}\n </span>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MessageItem.mjs","names":["MessageItemHeaderAccessoryContext","createContext","MessageItemContext","useMessageItem","useContext","MessageItemGroupContext","messageItemVariants","cva","STATUS_EDGE","messageItemRowVariants","ToolCallLead","Fragment","WrenchIcon","title","MessageItem","props","own","setOwn","useState","defaultExpanded","group","headerAccessory","grouped","current","expanded","state","tone","next","onExpandedChange","cn","className","children","MessageItemGroup","label","badge","STATUS_LABEL","summary","OutcomeBadge","toolTone","OUTCOME_ICON","LoaderIcon","CheckIcon","AlertIcon","StatusBadge","SILENT_IN_GROUP","MessageItemHeader","defaultLabel","expandable","Button","toggle","jsx","ChevronUpIcon","ChevronDownIcon","MessageItemBody","STATUS_GLYPH","messageItemStatusVariants","MessageItemStatus","content","glyph","expands"],"sources":["../../../../../../src/components/MessageItem.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { type ComponentProps, createContext, type ReactNode, useContext, useState } from 'react';\n\nimport { AlertIcon, CheckIcon, ChevronDownIcon, ChevronUpIcon, LoaderIcon, WrenchIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\nimport { STATUS_EDGE, StatusBadge, type StatusTone } from './StatusBadge';\n\n/**\n * The message item: the timeline card a tool call, a run, or a notice sits\n * in. The item owns its outcome tone and its expand state; the header, body,\n * and status parts read both from it, so a card composes the parts and never\n * threads `expanded` by hand. A tool message in a web plugin is built from\n * this, and so is the cockpit's own fallback item, which is what keeps them\n * looking alike.\n */\n\n/** The next item captures this accessory for its header, without passing it to nested items. */\nexport const MessageItemHeaderAccessoryContext = createContext<ReactNode>(null);\n\nexport interface MessageItemState {\n tone: StatusTone;\n headerAccessory?: ReactNode;\n /** Whether the header offers the toggle; an item that hides nothing offers none. */\n expandable: boolean;\n expanded: boolean;\n toggle: () => void;\n}\n\nconst MessageItemContext = createContext<MessageItemState>({\n tone: 'neutral',\n expandable: false,\n expanded: false,\n toggle: () => undefined,\n});\n\n/** The enclosing item's state, for a part that lives deeper than the item's render prop. */\nexport function useMessageItem(): MessageItemState {\n return useContext(MessageItemContext);\n}\n\n/**\n * The group an item is a row of, or null for an item that is a card of its\n * own. A row drops the frame the group already draws and keeps its tone as an\n * edge down its left side, and it stops repeating what the group's header has\n * said once: the tool's name, and an outcome the whole run shares.\n */\nconst MessageItemGroupContext = createContext<{ tone: StatusTone } | null>(null);\n\n/**\n * The frame, wearing the edge STATUS_EDGE names for the tone, so the two never drift apart.\n * A settled OK is the calm default and keeps the soft border; only work in flight or a failure colours the edge.\n */\nexport const messageItemVariants = cva('overflow-hidden rounded-lg border transition-colors', {\n variants: { tone: { ...STATUS_EDGE, ok: 'border-po-border-soft' } },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The same tone as a row: no card, one coloured edge, and the group's separators between rows. A settled row keeps a quiet edge. */\nexport const messageItemRowVariants = cva('overflow-hidden border-l-2 transition-colors', {\n variants: { tone: { ...STATUS_EDGE, ok: 'border-transparent', neutral: 'border-transparent' } },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The card's lead: the tool chip, the \"Tool call\" caption, then the name and its summary on one line. */\nfunction ToolCallLead({ title, children }: { title: ReactNode; children?: ReactNode }) {\n return (\n <>\n <span\n aria-hidden\n className=\"grid size-9 shrink-0 place-items-center rounded-full bg-po-rail text-po-dim max-sm:hidden\"\n >\n <WrenchIcon className=\"size-4\" />\n </span>\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"text-sm text-po-dim\">Tool call</span>\n <div className=\"flex min-w-0 items-center gap-2 text-base\">\n <span className=\"shrink-0 font-semibold text-po-hi\">{title}</span>\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n </div>\n </div>\n </>\n );\n}\n\nexport interface MessageItemProps\n extends Omit<ComponentProps<'div'>, 'children'>, VariantProps<typeof messageItemVariants> {\n /** Whether the header offers the expand toggle. A toggle that reveals nothing reads as broken, so the card decides. */\n expandable?: boolean;\n defaultExpanded?: boolean;\n /** Controlled mode; pair with onExpandedChange. Omit it and the item keeps its own state. */\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n /** Plain content, or a function of the item's state for a card that picks its lines by `expanded`. */\n children?: ReactNode | ((state: MessageItemState) => ReactNode);\n}\n\nexport function MessageItem({\n className,\n tone,\n expandable = false,\n defaultExpanded = false,\n expanded,\n onExpandedChange,\n children,\n ...props\n}: MessageItemProps) {\n const [own, setOwn] = useState(defaultExpanded);\n const group = useContext(MessageItemGroupContext);\n const headerAccessory = useContext(MessageItemHeaderAccessoryContext);\n const grouped = group !== null;\n const current = expanded ?? own;\n const state: MessageItemState = {\n tone: tone ?? 'neutral',\n headerAccessory,\n expandable,\n expanded: current,\n toggle: () => {\n const next = !current;\n if (expanded === undefined) setOwn(next);\n onExpandedChange?.(next);\n },\n };\n return (\n <MessageItemContext.Provider value={state}>\n <MessageItemHeaderAccessoryContext value={null}>\n <div\n data-slot=\"message-item\"\n data-expanded={current}\n data-grouped={grouped}\n className={cn(grouped ? messageItemRowVariants({ tone }) : messageItemVariants({ tone }), className)}\n {...props}\n >\n {typeof children === 'function' ? children(state) : children}\n </div>\n </MessageItemHeaderAccessoryContext>\n </MessageItemContext.Provider>\n );\n}\n\nexport interface MessageItemGroupProps\n extends Omit<ComponentProps<'div'>, 'title'>, VariantProps<typeof messageItemVariants> {\n /** The bold label at the left of the group header: the tool the run belongs to. */\n title: ReactNode;\n /** The line beside it, such as how many calls the group holds. */\n summary?: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n children?: ReactNode;\n}\n\n/**\n * One frame around a run of items that belong together.\n *\n * A transcript that calls the same tool five times in a row is five identical\n * frames, five gutter labels and five gaps, and the repetition reads louder\n * than the commands do. The group draws the frame once and each item inside it\n * becomes a row: same header, same expand, no card of its own. The tone still\n * belongs to the row, as an edge, so a failure in the middle of a run is not\n * flattened into the group's own outcome.\n */\nexport function MessageItemGroup({\n className,\n tone,\n title,\n summary,\n badge,\n children,\n ...props\n}: MessageItemGroupProps) {\n const label = badge === undefined ? STATUS_LABEL[tone ?? 'neutral'] : badge;\n return (\n <MessageItemGroupContext.Provider value={{ tone: tone ?? 'neutral' }}>\n <div data-slot=\"message-item-group\" className={cn(messageItemVariants({ tone }), className)} {...props}>\n <div className=\"flex min-h-11 items-center gap-3 border-po-border-soft border-b px-4 py-3 text-sm text-po-dim\">\n <ToolCallLead title={title}>\n <span className=\"min-w-0 flex-1 truncate text-po-faint\">{summary}</span>\n </ToolCallLead>\n {label !== null && label !== '' ? <OutcomeBadge tone={tone ?? 'neutral'}>{label}</OutcomeBadge> : null}\n </div>\n <div className=\"flex flex-col divide-y divide-po-border-soft\">{children}</div>\n </div>\n </MessageItemGroupContext.Provider>\n );\n}\n\n/** The tone a tool call's item wears: running while the tool runs, then its outcome. */\nexport function toolTone(state: { running: boolean; isError: boolean }): StatusTone {\n return state.running ? 'running' : state.isError ? 'error' : 'ok';\n}\n\n/** The badge text a tone reads as when the header is not told otherwise; empty hides the badge. */\nexport const STATUS_LABEL: Readonly<Record<StatusTone, string>> = {\n neutral: '',\n running: 'Running',\n ok: 'Completed',\n error: 'Failed',\n info: 'Info',\n accent: 'Note',\n};\n\nconst OUTCOME_ICON: Partial<Record<StatusTone, ReactNode>> = {\n running: <LoaderIcon aria-hidden className=\"size-3 animate-spin\" />,\n ok: <CheckIcon aria-hidden className=\"size-3\" />,\n error: <AlertIcon aria-hidden className=\"size-3\" />,\n};\n\n/** The sentence-case outcome pill, led by the tone's icon. */\nfunction OutcomeBadge({ tone, children, ...props }: ComponentProps<typeof StatusBadge> & { tone: StatusTone }) {\n return (\n <StatusBadge tone={tone} size=\"md\" className=\"gap-1 font-semibold\" {...props}>\n {OUTCOME_ICON[tone]}\n {children}\n </StatusBadge>\n );\n}\n\nexport interface MessageItemHeaderProps extends Omit<ComponentProps<'div'>, 'title'> {\n /** The bold label at the left: the tool name. */\n title: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n /** The summary beside the title; it gets the remaining width. */\n children?: ReactNode;\n}\n\n/** Inside a group these two are the quiet outcome: the group's header has already said it. */\nconst SILENT_IN_GROUP: ReadonlySet<StatusTone> = new Set<StatusTone>(['ok', 'neutral']);\n\n/**\n * The title row: label, summary, the tone's badge, and the expand toggle when\n * the item is expandable.\n *\n * A row inside a group says less. The group's header has already named the\n * tool and stated the run's outcome, so the row drops its title and speaks up\n * only when something went wrong or is still going: five OK badges down a run\n * of five are noise, and the one ERROR among them is the point.\n */\nexport function MessageItemHeader({ className, title, badge, children, ...props }: MessageItemHeaderProps) {\n const { headerAccessory, tone, expandable, expanded, toggle } = useMessageItem();\n const group = useContext(MessageItemGroupContext);\n const defaultLabel = group !== null && SILENT_IN_GROUP.has(tone) ? null : STATUS_LABEL[tone];\n const label = badge === undefined ? defaultLabel : badge;\n return (\n <div\n data-slot=\"message-item-header\"\n className={cn('flex min-h-11 items-center gap-3 px-4 py-3 text-sm text-po-dim', className)}\n {...props}\n >\n {group === null ? (\n <ToolCallLead title={title}>{children}</ToolCallLead>\n ) : (\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n )}\n {headerAccessory}\n {label !== null && label !== '' ? (\n <OutcomeBadge tone={tone} data-testid=\"tool-status\">\n {label}\n </OutcomeBadge>\n ) : null}\n {expandable ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"tool-expand\"\n aria-expanded={expanded}\n aria-label={expanded ? 'collapse' : 'expand'}\n onClick={toggle}\n className=\"text-po-dim hover:text-po-blue\"\n >\n {expanded ? <ChevronUpIcon className=\"size-4\" /> : <ChevronDownIcon className=\"size-4\" />}\n </Button>\n ) : null}\n </div>\n );\n}\n\n/** The body under the header, on the card's own surface. */\nexport function MessageItemBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"message-item-body\"\n className={cn('border-t border-po-border-soft px-4 py-3 text-base text-po-dim', className)}\n {...props}\n />\n );\n}\n\n/** The glyph a tone reads as in a status line. */\nexport const STATUS_GLYPH: Readonly<Record<StatusTone, string>> = {\n neutral: '…',\n running: '◐',\n ok: '✓',\n error: '✗',\n info: '●',\n accent: '●',\n};\n\nexport const messageItemStatusVariants = cva('shrink-0', {\n variants: {\n tone: {\n neutral: 'text-po-faint',\n running: 'text-po-yellow',\n ok: 'text-po-green',\n error: 'text-po-red',\n info: 'text-po-blue',\n accent: 'text-po-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemStatusProps extends ComponentProps<'span'>, VariantProps<typeof messageItemStatusVariants> {\n /** Replaces the tone's glyph. */\n glyph?: string;\n /** Renders as a button that expands the item: the \"N more line(s)\" hint. Only className carries over. */\n expands?: boolean;\n}\n\n/** The one-line status under a body: `◐ running`, `✗ failed`, `✓ done`, or the hint that more is hidden. */\nexport function MessageItemStatus({\n className,\n tone,\n glyph,\n expands = false,\n children,\n ...props\n}: MessageItemStatusProps) {\n const { toggle } = useMessageItem();\n const content = (\n <>\n <span className={messageItemStatusVariants({ tone })}>{glyph ?? STATUS_GLYPH[tone ?? 'neutral']}</span>\n <span>{children}</span>\n </>\n );\n if (expands) {\n return (\n <button\n type=\"button\"\n data-slot=\"message-item-status\"\n data-testid=\"tool-more\"\n onClick={toggle}\n className={cn(\n 'flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-po-faint hover:text-po-blue',\n className,\n )}\n >\n {content}\n </button>\n );\n }\n return (\n <span\n data-slot=\"message-item-status\"\n className={cn('flex items-center gap-1.5 text-po-faint', className)}\n {...props}\n >\n {content}\n </span>\n );\n}\n"],"mappings":"mcAkBA,MAAaA,EAAoCC,EAAyB,IAAI,EAWxEC,EAAqBD,EAAgC,CACzD,KAAM,UACN,WAAY,GACZ,SAAU,GACV,WAAc,IAAA,EAChB,CAAC,EAGD,SAAgBE,GAAmC,CACjD,OAAOC,EAAWF,CAAkB,CACtC,CAQA,MAAMG,EAA0BJ,EAA2C,IAAI,EAMlEK,EAAsBC,EAAI,sDAAuD,CAC5F,SAAU,CAAE,KAAM,CAAE,GAAGC,EAAa,GAAI,uBAAwB,CAAE,EAClE,gBAAiB,CAAE,KAAM,SAAU,CACrC,CAAC,EAGYC,EAAyBF,EAAI,+CAAgD,CACxF,SAAU,CAAE,KAAM,CAAE,GAAGC,EAAa,GAAI,qBAAsB,QAAS,oBAAqB,CAAE,EAC9F,gBAAiB,CAAE,KAAM,SAAU,CACrC,CAAC,EAGD,SAASE,EAAa,CAAE,QAAO,YAAwD,CACrF,MACE,kBAAAC,EAAA,CAAA,SAAA,CACE,kBAAC,OAAD,CACE,cAAA,GACA,UAAU,4FAEV,SAAA,kBAACC,EAAD,CAAY,UAAU,QAAU,CAAA,CAC5B,CAAA,EACN,kBAAC,MAAD,CAAK,UAAU,+BAAf,SAAA,CACE,kBAAC,OAAD,CAAM,UAAU,sBAAsB,SAAA,WAAe,CAAA,EACrD,kBAAC,MAAD,CAAK,UAAU,4CAAf,SAAA,CACE,kBAAC,OAAD,CAAM,UAAU,oCAAqC,SAAAC,CAAY,CAAA,EACjE,kBAAC,MAAD,CAAK,YAAU,uBAAuB,UAAU,yCAC7C,UACE,CAAA,CACF,CACF,CAAA,CAAA,CACL,CAAA,CAAA,CAAA,CAAA,CAEN,CAcA,SAAgBC,EAAY,CAC1B,YACA,OACA,aAAa,GACb,kBAAkB,GAClB,WACA,mBACA,WACA,GAAGC,GACgB,CACnB,GAAM,CAACC,EAAKC,GAAUC,EAASC,CAAe,EACxCC,EAAQhB,EAAWC,CAAuB,EAC1CgB,EAAkBjB,EAAWJ,CAAiC,EAC9DsB,EAAUF,IAAU,KACpBG,EAAUC,GAAYR,EACtBS,EAA0B,CAC9B,KAAMC,GAAQ,UACd,kBACA,aACA,SAAUH,EACV,WAAc,CACZ,IAAMI,EAAO,CAACJ,EACVC,IAAa,IAAA,IAAWP,EAAOU,CAAI,EACvCC,IAAmBD,CAAI,CACzB,CACF,EACA,MACE,kBAACzB,EAAmB,SAApB,CAA6B,MAAOuB,EAClC,SAAA,kBAACzB,EAAD,CAAmC,MAAO,KACxC,SAAA,kBAAC,MAAD,CACE,YAAU,eACV,gBAAeuB,EACf,eAAcD,EACd,UAAWO,EAAGP,EAAUb,EAAuB,CAAE,MAAK,CAAC,EAAIH,EAAoB,CAAE,MAAK,CAAC,EAAGwB,CAAS,EACnG,GAAIf,EAEH,SAAA,OAAOgB,GAAa,WAAaA,EAASN,CAAK,EAAIM,CACjD,CAAA,CAC4B,CAAA,CACR,CAAA,CAEjC,CAuBA,SAAgBC,EAAiB,CAC/B,YACA,OACA,QACA,UACA,QACA,WACA,GAAGjB,GACqB,CACxB,IAAMkB,EAAQC,IAAU,IAAA,GAAYC,EAAaT,GAAQ,WAAaQ,EACtE,MACE,kBAAC7B,EAAwB,SAAzB,CAAkC,MAAO,CAAE,KAAMqB,GAAQ,SAAU,EACjE,SAAA,kBAAC,MAAD,CAAK,YAAU,qBAAqB,UAAWG,EAAGvB,EAAoB,CAAE,MAAK,CAAC,EAAGwB,CAAS,EAAG,GAAIf,EAAjG,SAAA,CACE,kBAAC,MAAD,CAAK,UAAU,gGAAf,SAAA,CACE,kBAACL,EAAD,CAAqB,QACnB,SAAA,kBAAC,OAAD,CAAM,UAAU,wCAAyC,SAAA0B,CAAc,CAAA,CAC3D,CAAA,EACbH,IAAU,MAAQA,IAAU,GAAK,kBAACI,EAAD,CAAc,KAAMX,GAAQ,UAAY,SAAAO,CAAoB,CAAA,EAAI,IAC/F,CACL,CAAA,EAAA,kBAAC,MAAD,CAAK,UAAU,+CAAgD,UAAc,CAAA,CAC1E,GAC2B,CAAA,CAEtC,CAGA,SAAgBK,EAAS,EAA2D,CAClF,OAAOb,EAAM,QAAU,UAAYA,EAAM,QAAU,QAAU,IAC/D,CAGA,MAAaU,EAAqD,CAChE,QAAS,GACT,QAAS,UACT,GAAI,YACJ,MAAO,SACP,KAAM,OACN,OAAQ,MACV,EAEMI,EAAuD,CAC3D,QAAS,kBAACC,EAAD,CAAY,cAAA,GAAY,UAAU,qBAAuB,CAAA,EAClE,GAAI,kBAACC,EAAD,CAAW,cAAA,GAAY,UAAU,QAAU,CAAA,EAC/C,MAAO,kBAACC,EAAD,CAAW,cAAA,GAAY,UAAU,QAAU,CAAA,CACpD,EAGA,SAASL,EAAa,CAAE,OAAM,WAAU,GAAGtB,GAAoE,CAC7G,MACE,kBAAC4B,EAAD,CAAmB,OAAM,KAAK,KAAK,UAAU,sBAAsB,GAAI5B,EAAvE,SAAA,CACGwB,EAAab,GACbK,CACU,GAEjB,CAYA,MAAMa,kBAA2C,IAAI,IAAgB,CAAC,KAAM,SAAS,CAAC,EAWtF,SAAgBC,EAAkB,CAAE,YAAW,QAAO,QAAO,WAAU,GAAG9B,GAAiC,CACzG,GAAM,CAAE,kBAAiB,OAAM,aAAY,WAAU,UAAWZ,EAAe,EACzEiB,EAAQhB,EAAWC,CAAuB,EAC1CyC,EAAe1B,IAAU,MAAQwB,EAAgB,IAAIlB,CAAI,EAAI,KAAOS,EAAaT,GACjFO,EAAQC,IAAU,IAAA,GAAYY,EAAeZ,EACnD,MACE,kBAAC,MAAD,CACE,YAAU,sBACV,UAAWL,EAAG,iEAAkEC,CAAS,EACzF,GAAIf,EAHN,SAAA,CAKGK,IAAU,KACT,kBAACV,EAAD,CAAqB,QAAQ,UAAuB,CAAA,EAEpD,kBAAC,MAAD,CAAK,YAAU,uBAAuB,UAAU,yCAC7C,UACE,CAAA,EAENW,EACAY,IAAU,MAAQA,IAAU,GAC3B,kBAACI,EAAD,CAAoB,OAAM,cAAY,cACnC,SAAAJ,CACW,CAAA,EACZ,KACHc,EACC,kBAACC,EAAD,CACE,QAAQ,QACR,KAAK,OACL,cAAY,cACZ,gBAAexB,EACf,aAAYA,EAAW,WAAa,SACpC,QAASyB,EACT,UAAU,iCAET,SAAWC,EAAX1B,EAAY2B,EAAuCC,EAAxC,CAAe,UAAU,QAAU,CAAyC,CAClF,CAAA,EACN,IACD,GAET,CAGA,SAAgBC,EAAgB,CAAE,YAAW,GAAGtC,GAAgC,CAC9E,MACE,kBAAC,MAAD,CACE,YAAU,oBACV,UAAWc,EAAG,iEAAkEC,CAAS,EACzF,GAAIf,CACL,CAAA,CAEL,CAGA,MAAauC,EAAqD,CAChE,QAAS,IACT,QAAS,IACT,GAAI,IACJ,MAAO,IACP,KAAM,IACN,OAAQ,GACV,EAEaC,EAA4BhD,EAAI,WAAY,CACvD,SAAU,CACR,KAAM,CACJ,QAAS,gBACT,QAAS,iBACT,GAAI,gBACJ,MAAO,cACP,KAAM,eACN,OAAQ,iBACV,CACF,EACA,gBAAiB,CAAE,KAAM,SAAU,CACrC,CAAC,EAUD,SAAgBiD,EAAkB,CAChC,YACA,OACA,QACA,UAAU,GACV,WACA,GAAGzC,GACsB,CACzB,GAAM,CAAE,UAAWZ,EAAe,EAC5BsD,EACJ,kBAAA9C,EAAA,CAAA,SAAA,CACE,kBAAC,OAAD,CAAM,UAAW4C,EAA0B,CAAE,MAAK,CAAC,EAAI,SAAAG,GAASJ,EAAa5B,GAAQ,UAAiB,CAAA,EACtG,kBAAC,OAAD,CAAO,UAAe,CAAA,CACtB,CAAA,CAAA,EAkBJ,OAhBIiC,EAEA,kBAAC,SAAD,CACE,KAAK,SACL,YAAU,sBACV,cAAY,YACZ,QAASV,EACT,UAAWpB,EACT,4FACAC,CACF,EAEC,SAAA2B,CACK,CAAA,EAIV,kBAAC,OAAD,CACE,YAAU,sBACV,UAAW5B,EAAG,0CAA2CC,CAAS,EAClE,GAAIf,EAEH,SAAA0C,CACG,CAAA,CAEV"}
@@ -1,2 +1,2 @@
1
- import{cn as e}from"../lib/cn.mjs";import{jsx as t}from"react/jsx-runtime";import{cva as n}from"class-variance-authority";const r=n(`whitespace-pre-wrap break-words`,{variants:{tone:{hi:`text-doom-hi`,text:`text-doom-text`,dim:`text-doom-dim`,muted:`text-doom-faint`,success:`text-doom-green`,error:`text-doom-red`,warning:`text-doom-yellow`,accent:`text-doom-blue`},bold:{true:`font-bold`,false:``},indent:{true:`pl-4`,false:``}},defaultVariants:{tone:`dim`,bold:!1,indent:!1}});function i({className:n,lines:i,...a}){return/* @__PURE__ */ t(`div`,{"data-slot":`message-lines`,className:e(`flex flex-col gap-0.5`,n),...a,children:i.map((e,n)=>/* @__PURE__ */ t(`div`,{className:r({tone:e.tone,bold:e.bold===!0,indent:e.indent===!0}),children:e.text},`${String(n)}-${e.text}`))})}export{i as MessageLines,r as messageLineVariants};
1
+ import{cn as e}from"../lib/cn.mjs";import{jsx as t}from"react/jsx-runtime";import{cva as n}from"class-variance-authority";const r=n(`whitespace-pre-wrap break-words`,{variants:{tone:{hi:`text-po-hi`,text:`text-po-text`,dim:`text-po-dim`,muted:`text-po-faint`,success:`text-po-green`,error:`text-po-red`,warning:`text-po-yellow`,accent:`text-po-blue`},bold:{true:`font-bold`,false:``},indent:{true:`pl-4`,false:``}},defaultVariants:{tone:`dim`,bold:!1,indent:!1}});function i({className:n,lines:i,...a}){return/* @__PURE__ */ t(`div`,{"data-slot":`message-lines`,className:e(`flex flex-col gap-0.5`,n),...a,children:i.map((e,n)=>/* @__PURE__ */ t(`div`,{className:r({tone:e.tone,bold:e.bold===!0,indent:e.indent===!0}),children:e.text},`${String(n)}-${e.text}`))})}export{i as MessageLines,r as messageLineVariants};
2
2
  //# sourceMappingURL=MessageLines.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageLines.mjs","names":["messageLineVariants","cva","MessageLines","props","cn","className","lines","line","index"],"sources":["../../../../../../src/components/MessageLines.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport type { MessageLineTone as Tone } from '../types/tone';\n\n/** One line of a message body, with the tone the card's pure view logic chose for it. */\nexport type MessageLineTone = Tone;\n\nexport interface MessageLine {\n text: string;\n tone: MessageLineTone;\n bold?: boolean;\n indent?: boolean;\n}\n\nexport const messageLineVariants = cva('whitespace-pre-wrap break-words', {\n variants: {\n tone: {\n hi: 'text-doom-hi',\n text: 'text-doom-text',\n dim: 'text-doom-dim',\n muted: 'text-doom-faint',\n success: 'text-doom-green',\n error: 'text-doom-red',\n warning: 'text-doom-yellow',\n accent: 'text-doom-blue',\n } satisfies Record<Tone, string>,\n bold: { true: 'font-bold', false: '' },\n indent: { true: 'pl-4', false: '' },\n },\n defaultVariants: { tone: 'dim', bold: false, indent: false },\n});\n\nexport interface MessageLinesProps extends ComponentProps<'div'> {\n lines: readonly MessageLine[];\n}\n\n/** A body of toned lines: what a card's view helper computed, drawn one line per row. */\nexport function MessageLines({ className, lines, ...props }: MessageLinesProps) {\n return (\n <div data-slot=\"message-lines\" className={cn('flex flex-col gap-0.5', className)} {...props}>\n {lines.map((line, index) => (\n <div\n key={`${String(index)}-${line.text}`}\n className={messageLineVariants({ tone: line.tone, bold: line.bold === true, indent: line.indent === true })}\n >\n {line.text}\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":"0HAgBA,MAAaA,EAAsBC,EAAI,kCAAmC,CACxE,SAAU,CACR,KAAM,CACJ,GAAI,eACJ,KAAM,iBACN,IAAK,gBACL,MAAO,kBACP,QAAS,kBACT,MAAO,gBACP,QAAS,mBACT,OAAQ,gBACV,EACA,KAAM,CAAE,KAAM,YAAa,MAAO,EAAG,EACrC,OAAQ,CAAE,KAAM,OAAQ,MAAO,EAAG,CACpC,EACA,gBAAiB,CAAE,KAAM,MAAO,KAAM,GAAO,OAAQ,EAAM,CAC7D,CAAC,EAOD,SAAgBC,EAAa,CAAE,YAAW,QAAO,GAAGC,GAA4B,CAC9E,MACE,kBAAC,MAAD,CAAK,YAAU,gBAAgB,UAAWC,EAAG,wBAAyBC,CAAS,EAAG,GAAIF,EACnF,SAAAG,EAAM,KAAK,EAAM,IAChB,kBAAC,MAAD,CAEE,UAAWN,EAAoB,CAAE,KAAMO,EAAK,KAAM,KAAMA,EAAK,OAAS,GAAM,OAAQA,EAAK,SAAW,EAAK,CAAC,EAEzG,SAAAA,EAAK,IACH,EAJE,GAAG,OAAOC,CAAK,EAAE,GAAGD,EAAK,MAI3B,CACN,CACE,CAAA,CAET"}
1
+ {"version":3,"file":"MessageLines.mjs","names":["messageLineVariants","cva","MessageLines","props","cn","className","lines","line","index"],"sources":["../../../../../../src/components/MessageLines.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport type { MessageLineTone as Tone } from '../types/tone';\n\n/** One line of a message body, with the tone the card's pure view logic chose for it. */\nexport type MessageLineTone = Tone;\n\nexport interface MessageLine {\n text: string;\n tone: MessageLineTone;\n bold?: boolean;\n indent?: boolean;\n}\n\nexport const messageLineVariants = cva('whitespace-pre-wrap break-words', {\n variants: {\n tone: {\n hi: 'text-po-hi',\n text: 'text-po-text',\n dim: 'text-po-dim',\n muted: 'text-po-faint',\n success: 'text-po-green',\n error: 'text-po-red',\n warning: 'text-po-yellow',\n accent: 'text-po-blue',\n } satisfies Record<Tone, string>,\n bold: { true: 'font-bold', false: '' },\n indent: { true: 'pl-4', false: '' },\n },\n defaultVariants: { tone: 'dim', bold: false, indent: false },\n});\n\nexport interface MessageLinesProps extends ComponentProps<'div'> {\n lines: readonly MessageLine[];\n}\n\n/** A body of toned lines: what a card's view helper computed, drawn one line per row. */\nexport function MessageLines({ className, lines, ...props }: MessageLinesProps) {\n return (\n <div data-slot=\"message-lines\" className={cn('flex flex-col gap-0.5', className)} {...props}>\n {lines.map((line, index) => (\n <div\n key={`${String(index)}-${line.text}`}\n className={messageLineVariants({ tone: line.tone, bold: line.bold === true, indent: line.indent === true })}\n >\n {line.text}\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":"0HAgBA,MAAaA,EAAsBC,EAAI,kCAAmC,CACxE,SAAU,CACR,KAAM,CACJ,GAAI,aACJ,KAAM,eACN,IAAK,cACL,MAAO,gBACP,QAAS,gBACT,MAAO,cACP,QAAS,iBACT,OAAQ,cACV,EACA,KAAM,CAAE,KAAM,YAAa,MAAO,EAAG,EACrC,OAAQ,CAAE,KAAM,OAAQ,MAAO,EAAG,CACpC,EACA,gBAAiB,CAAE,KAAM,MAAO,KAAM,GAAO,OAAQ,EAAM,CAC7D,CAAC,EAOD,SAAgBC,EAAa,CAAE,YAAW,QAAO,GAAGC,GAA4B,CAC9E,MACE,kBAAC,MAAD,CAAK,YAAU,gBAAgB,UAAWC,EAAG,wBAAyBC,CAAS,EAAG,GAAIF,EACnF,SAAAG,EAAM,KAAK,EAAM,IAChB,kBAAC,MAAD,CAEE,UAAWN,EAAoB,CAAE,KAAMO,EAAK,KAAM,KAAMA,EAAK,OAAS,GAAM,OAAQA,EAAK,SAAW,EAAK,CAAC,EAEzG,SAAAA,EAAK,IACH,EAJE,GAAG,OAAOC,CAAK,EAAE,GAAGD,EAAK,MAI3B,CACN,CACE,CAAA,CAET"}
@@ -1,2 +1,2 @@
1
- import{cn as e}from"../lib/cn.mjs";import{optionMarker as t}from"../lib/optionList.mjs";import{jsx as n,jsxs as r}from"react/jsx-runtime";import{useEffect as i,useRef as a}from"react";import{cva as o}from"class-variance-authority";const s=o(`flex min-h-0 flex-1 flex-col overflow-y-auto`,{variants:{density:{compact:`gap-0.5 p-1.5`,comfortable:`gap-1.5`}},defaultVariants:{density:`comfortable`}}),c=o(`flex shrink-0 cursor-pointer items-center text-left outline-none`,{variants:{density:{compact:`gap-2.5 rounded-md px-2 py-[7px]`,comfortable:`min-h-[42px] gap-3 rounded-md border px-[11px] py-2 text-sm text-doom-text transition-colors`},active:{true:``,false:``}},compoundVariants:[{density:`compact`,active:!0,class:`bg-doom-tint-green`},{density:`comfortable`,active:!0,class:`border-doom-edge-green bg-doom-tint-green`},{density:`comfortable`,active:!1,class:`border-doom-border-soft`}],defaultVariants:{density:`comfortable`,active:!1}}),l=o(`flex shrink-0 items-center justify-center rounded-full font-semibold`,{variants:{density:{compact:`h-[15px] w-[15px] border border-doom-border text-2xs text-doom-faint`,comfortable:`h-[18px] w-[18px] bg-doom-deep text-xs text-doom-dim`}},defaultVariants:{density:`comfortable`}});function u({className:t,density:i,active:a,marker:o,children:s,...u}){return/* @__PURE__ */ r(`button`,{type:`button`,role:`option`,"data-slot":`option-row`,"aria-selected":a??!1,"data-cursor":a??!1,className:e(c({density:i,active:a}),t),...u,children:[o===void 0?null:/* @__PURE__ */ n(`span`,{className:l({density:i}),children:o}),s]})}function d({className:t,density:r,...i}){return/* @__PURE__ */ n(`span`,{"data-slot":`option-label`,className:e(`min-w-0 flex-1`,r===`compact`?`truncate text-sm text-doom-text`:`break-words`,t),...i})}function f({className:r,options:o,cursor:c,onCursorChange:l,onSelect:f,testIdPrefix:p,density:m=`comfortable`,...h}){let g=a(null);return i(()=>{g.current?.children[c]?.scrollIntoView({block:`nearest`})},[c]),/* @__PURE__ */ n(`div`,{ref:g,role:`listbox`,"aria-label":`options`,"data-slot":`option-list`,"data-testid":`${p}s`,className:e(s({density:m}),r),...h,children:o.map((e,r)=>/* @__PURE__ */ n(u,{density:m,active:r===c,marker:t(r),"data-testid":`${p}-${String(r)}`,title:e,onMouseEnter:()=>l(r),onClick:()=>f(e),children:/* @__PURE__ */ n(d,{density:m,children:e})},e))})}export{d as OptionLabel,f as OptionList,u as OptionRow,s as optionListVariants,l as optionMarkerVariants,c as optionRowVariants};
1
+ import{cn as e}from"../lib/cn.mjs";import{optionMarker as t}from"../lib/optionList.mjs";import{jsx as n,jsxs as r}from"react/jsx-runtime";import{useEffect as i,useRef as a}from"react";import{cva as o}from"class-variance-authority";const s=o(`flex min-h-0 flex-1 flex-col overflow-y-auto`,{variants:{density:{compact:`gap-0.5 p-1.5`,comfortable:`gap-1.5`}},defaultVariants:{density:`comfortable`}}),c=o(`flex shrink-0 cursor-pointer items-center text-left outline-none`,{variants:{density:{compact:`gap-2.5 rounded-md px-2 py-[7px]`,comfortable:`min-h-[42px] gap-3 rounded-md border px-[11px] py-2 text-sm text-po-text transition-colors`},active:{true:``,false:``}},compoundVariants:[{density:`compact`,active:!0,class:`bg-po-tint-green`},{density:`comfortable`,active:!0,class:`border-po-edge-green bg-po-tint-green`},{density:`comfortable`,active:!1,class:`border-po-border-soft`}],defaultVariants:{density:`comfortable`,active:!1}}),l=o(`flex shrink-0 items-center justify-center rounded-full font-semibold`,{variants:{density:{compact:`h-[15px] w-[15px] border border-po-border text-2xs text-po-faint`,comfortable:`h-[18px] w-[18px] bg-po-deep text-xs text-po-dim`}},defaultVariants:{density:`comfortable`}});function u({className:t,density:i,active:a,marker:o,children:s,...u}){return/* @__PURE__ */ r(`button`,{type:`button`,role:`option`,"data-slot":`option-row`,"aria-selected":a??!1,"data-cursor":a??!1,className:e(c({density:i,active:a}),t),...u,children:[o===void 0?null:/* @__PURE__ */ n(`span`,{className:l({density:i}),children:o}),s]})}function d({className:t,density:r,...i}){return/* @__PURE__ */ n(`span`,{"data-slot":`option-label`,className:e(`min-w-0 flex-1`,r===`compact`?`truncate text-sm text-po-text`:`break-words`,t),...i})}function f({className:r,options:o,cursor:c,onCursorChange:l,onSelect:f,testIdPrefix:p,density:m=`comfortable`,...h}){let g=a(null);return i(()=>{g.current?.children[c]?.scrollIntoView({block:`nearest`})},[c]),/* @__PURE__ */ n(`div`,{ref:g,role:`listbox`,"aria-label":`options`,"data-slot":`option-list`,"data-testid":`${p}s`,className:e(s({density:m}),r),...h,children:o.map((e,r)=>/* @__PURE__ */ n(u,{density:m,active:r===c,marker:t(r),"data-testid":`${p}-${String(r)}`,title:e,onMouseEnter:()=>l(r),onClick:()=>f(e),children:/* @__PURE__ */ n(d,{density:m,children:e})},e))})}export{d as OptionLabel,f as OptionList,u as OptionRow,s as optionListVariants,l as optionMarkerVariants,c as optionRowVariants};
2
2
  //# sourceMappingURL=OptionList.mjs.map