@agimon-ai/doompi-web-components 0.0.1-alpha.45 → 0.0.1-alpha.47

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 (464) hide show
  1. package/dist/doompi-core/dist/src/extensions/webPlugin.d.mts +2 -0
  2. package/dist/doompi-core/dist/src/web/models/globalStore.d.mts +1 -0
  3. package/dist/doompi-core/dist/src/web/models/sessionStore.d.mts +1 -0
  4. package/dist/doompi-core/dist/src/web/models/workspaceStore.d.mts +1 -0
  5. package/dist/doompi-core/dist/src/web/schemas/template.d.mts +1 -0
  6. package/dist/doompi-core/dist/src/web/types/extensionFile.d.mts +2 -0
  7. package/dist/doompi-core/dist/src/web/types/mcpWidget.d.mts +16 -0
  8. package/dist/doompi-core/dist/src/web/types/mcpWidget.d.mts.map +1 -0
  9. package/dist/doompi-core/dist/src/web/types/template.d.mts +1 -0
  10. package/dist/doompi-core/dist/src/web/types/webPlugin.d.mts +2 -0
  11. package/dist/doompi-core/dist/web.d.mts +10 -0
  12. package/dist/doompi-web-components/src/components/Accordion.d.mts.map +1 -0
  13. package/dist/doompi-web-components/src/components/Accordion.mjs.map +1 -0
  14. package/dist/doompi-web-components/src/components/AnsiText.d.mts.map +1 -0
  15. package/dist/doompi-web-components/src/components/AnsiText.mjs.map +1 -0
  16. package/dist/doompi-web-components/src/components/Avatar.d.mts.map +1 -0
  17. package/dist/doompi-web-components/src/components/Avatar.mjs.map +1 -0
  18. package/dist/doompi-web-components/src/components/Badge.d.mts.map +1 -0
  19. package/dist/doompi-web-components/src/components/Badge.mjs.map +1 -0
  20. package/dist/doompi-web-components/src/components/Breadcrumb.d.mts.map +1 -0
  21. package/dist/doompi-web-components/src/components/Breadcrumb.mjs.map +1 -0
  22. package/dist/doompi-web-components/src/components/Button.d.mts.map +1 -0
  23. package/dist/doompi-web-components/src/components/Button.mjs.map +1 -0
  24. package/dist/doompi-web-components/src/components/Checkbox.d.mts.map +1 -0
  25. package/dist/doompi-web-components/src/components/Checkbox.mjs.map +1 -0
  26. package/dist/doompi-web-components/src/components/CodeBlock.mjs.map +1 -0
  27. package/dist/doompi-web-components/src/components/CodeEditor.d.mts.map +1 -0
  28. package/dist/doompi-web-components/src/components/CodeEditor.mjs.map +1 -0
  29. package/dist/doompi-web-components/src/components/CodeEditorView.mjs.map +1 -0
  30. package/dist/doompi-web-components/src/components/Collapsible.d.mts.map +1 -0
  31. package/dist/doompi-web-components/src/components/Collapsible.mjs.map +1 -0
  32. package/dist/doompi-web-components/src/components/Command.d.mts.map +1 -0
  33. package/dist/doompi-web-components/src/components/Command.mjs.map +1 -0
  34. package/dist/doompi-web-components/src/components/CopyButton.mjs.map +1 -0
  35. package/dist/doompi-web-components/src/components/Dialog.d.mts.map +1 -0
  36. package/dist/doompi-web-components/src/components/Dialog.mjs.map +1 -0
  37. package/dist/doompi-web-components/src/components/Dot.d.mts.map +1 -0
  38. package/dist/doompi-web-components/src/components/Dot.mjs.map +1 -0
  39. package/dist/doompi-web-components/src/components/Drawer.d.mts.map +1 -0
  40. package/dist/doompi-web-components/src/components/Drawer.mjs.map +1 -0
  41. package/dist/doompi-web-components/src/components/DropdownMenu.d.mts.map +1 -0
  42. package/dist/doompi-web-components/src/components/DropdownMenu.mjs.map +1 -0
  43. package/dist/doompi-web-components/src/components/EmptyState.d.mts.map +1 -0
  44. package/dist/doompi-web-components/src/components/EmptyState.mjs.map +1 -0
  45. package/dist/doompi-web-components/src/components/HashlineLines.d.mts.map +1 -0
  46. package/dist/doompi-web-components/src/components/HashlineLines.mjs.map +1 -0
  47. package/dist/doompi-web-components/src/components/Input.d.mts.map +1 -0
  48. package/dist/doompi-web-components/src/components/Input.mjs.map +1 -0
  49. package/dist/doompi-web-components/src/components/Kbd.d.mts.map +1 -0
  50. package/dist/doompi-web-components/src/components/Kbd.mjs.map +1 -0
  51. package/dist/doompi-web-components/src/components/Label.d.mts.map +1 -0
  52. package/dist/doompi-web-components/src/components/Label.mjs.map +1 -0
  53. package/dist/doompi-web-components/src/components/Markdown.d.mts.map +1 -0
  54. package/dist/doompi-web-components/src/components/Markdown.mjs.map +1 -0
  55. package/dist/doompi-web-components/src/components/McpApp.d.mts +18 -0
  56. package/dist/doompi-web-components/src/components/McpApp.d.mts.map +1 -0
  57. package/dist/doompi-web-components/src/components/McpApp.mjs +2 -0
  58. package/dist/doompi-web-components/src/components/McpApp.mjs.map +1 -0
  59. package/dist/doompi-web-components/src/components/McpToolWidget.d.mts +14 -0
  60. package/dist/doompi-web-components/src/components/McpToolWidget.d.mts.map +1 -0
  61. package/dist/doompi-web-components/src/components/McpToolWidget.mjs +3 -0
  62. package/dist/doompi-web-components/src/components/McpToolWidget.mjs.map +1 -0
  63. package/dist/doompi-web-components/src/components/MediaPreview.d.mts.map +1 -0
  64. package/dist/doompi-web-components/src/components/MediaPreview.mjs.map +1 -0
  65. package/dist/doompi-web-components/src/components/MermaidDiagram.mjs.map +1 -0
  66. package/dist/doompi-web-components/src/components/MessageItem.d.mts.map +1 -0
  67. package/dist/doompi-web-components/src/components/MessageItem.mjs.map +1 -0
  68. package/dist/doompi-web-components/src/components/MessageLines.d.mts.map +1 -0
  69. package/dist/doompi-web-components/src/components/MessageLines.mjs.map +1 -0
  70. package/dist/doompi-web-components/src/components/OptionList.d.mts.map +1 -0
  71. package/dist/doompi-web-components/src/components/OptionList.mjs.map +1 -0
  72. package/dist/doompi-web-components/src/components/Panel.d.mts.map +1 -0
  73. package/dist/doompi-web-components/src/components/Panel.mjs.map +1 -0
  74. package/dist/doompi-web-components/src/components/PdfPreview.d.mts.map +1 -0
  75. package/dist/doompi-web-components/src/components/PdfPreview.mjs.map +1 -0
  76. package/dist/doompi-web-components/src/components/Popover.d.mts.map +1 -0
  77. package/dist/doompi-web-components/src/components/Popover.mjs.map +1 -0
  78. package/dist/doompi-web-components/src/components/Progress.d.mts.map +1 -0
  79. package/dist/doompi-web-components/src/components/Progress.mjs.map +1 -0
  80. package/dist/doompi-web-components/src/components/RadioGroup.d.mts.map +1 -0
  81. package/dist/doompi-web-components/src/components/RadioGroup.mjs.map +1 -0
  82. package/dist/doompi-web-components/src/components/ScrollArea.d.mts.map +1 -0
  83. package/dist/doompi-web-components/src/components/ScrollArea.mjs.map +1 -0
  84. package/dist/doompi-web-components/src/components/SectionLabel.d.mts.map +1 -0
  85. package/dist/doompi-web-components/src/components/SectionLabel.mjs.map +1 -0
  86. package/dist/doompi-web-components/src/components/Select.d.mts.map +1 -0
  87. package/dist/doompi-web-components/src/components/Select.mjs.map +1 -0
  88. package/dist/doompi-web-components/src/components/Separator.d.mts.map +1 -0
  89. package/dist/doompi-web-components/src/components/Separator.mjs.map +1 -0
  90. package/dist/doompi-web-components/src/components/Sheet.d.mts.map +1 -0
  91. package/dist/doompi-web-components/src/components/Sheet.mjs.map +1 -0
  92. package/dist/doompi-web-components/src/components/Skeleton.d.mts.map +1 -0
  93. package/dist/doompi-web-components/src/components/Skeleton.mjs.map +1 -0
  94. package/dist/doompi-web-components/src/components/Spinner.d.mts.map +1 -0
  95. package/dist/doompi-web-components/src/components/Spinner.mjs.map +1 -0
  96. package/dist/doompi-web-components/src/components/StatusBadge.d.mts.map +1 -0
  97. package/dist/doompi-web-components/src/components/StatusBadge.mjs.map +1 -0
  98. package/dist/doompi-web-components/src/components/StreamCursor.d.mts.map +1 -0
  99. package/dist/doompi-web-components/src/components/StreamCursor.mjs.map +1 -0
  100. package/dist/doompi-web-components/src/components/Switch.d.mts.map +1 -0
  101. package/dist/doompi-web-components/src/components/Switch.mjs.map +1 -0
  102. package/dist/doompi-web-components/src/components/SyntaxText.d.mts.map +1 -0
  103. package/dist/doompi-web-components/src/components/SyntaxText.mjs.map +1 -0
  104. package/dist/doompi-web-components/src/components/Tabs.d.mts.map +1 -0
  105. package/dist/doompi-web-components/src/components/Tabs.mjs.map +1 -0
  106. package/dist/doompi-web-components/src/components/TerminalView.d.mts.map +1 -0
  107. package/dist/doompi-web-components/src/components/TerminalView.mjs.map +1 -0
  108. package/dist/doompi-web-components/src/components/Textarea.d.mts.map +1 -0
  109. package/dist/doompi-web-components/src/components/Textarea.mjs.map +1 -0
  110. package/dist/doompi-web-components/src/components/Toast.d.mts.map +1 -0
  111. package/dist/doompi-web-components/src/components/Toast.mjs.map +1 -0
  112. package/dist/doompi-web-components/src/components/ToolPathLink.d.mts.map +1 -0
  113. package/dist/doompi-web-components/src/components/ToolPathLink.mjs.map +1 -0
  114. package/dist/doompi-web-components/src/components/Tooltip.d.mts.map +1 -0
  115. package/dist/doompi-web-components/src/components/Tooltip.mjs.map +1 -0
  116. package/dist/doompi-web-components/src/lib/ansiSpans.d.mts.map +1 -0
  117. package/dist/doompi-web-components/src/lib/ansiSpans.mjs.map +1 -0
  118. package/dist/doompi-web-components/src/lib/cn.d.mts.map +1 -0
  119. package/dist/doompi-web-components/src/lib/cn.mjs.map +1 -0
  120. package/dist/doompi-web-components/src/lib/collapse.d.mts.map +1 -0
  121. package/dist/doompi-web-components/src/lib/collapse.mjs.map +1 -0
  122. package/dist/doompi-web-components/src/lib/editorController.mjs.map +1 -0
  123. package/dist/doompi-web-components/src/lib/editorLanguage.d.mts.map +1 -0
  124. package/dist/doompi-web-components/src/lib/editorLanguage.mjs.map +1 -0
  125. package/dist/doompi-web-components/src/lib/editorTheme.d.mts.map +1 -0
  126. package/dist/doompi-web-components/src/lib/editorTheme.mjs.map +1 -0
  127. package/dist/doompi-web-components/src/lib/fenceGrammar.mjs.map +1 -0
  128. package/dist/doompi-web-components/src/lib/hashlineHighlight.d.mts.map +1 -0
  129. package/dist/doompi-web-components/src/lib/hashlineHighlight.mjs.map +1 -0
  130. package/dist/doompi-web-components/src/lib/hashlineView.d.mts.map +1 -0
  131. package/dist/doompi-web-components/src/lib/hashlineView.mjs.map +1 -0
  132. package/dist/doompi-web-components/src/lib/media.d.mts.map +1 -0
  133. package/dist/doompi-web-components/src/lib/media.mjs.map +1 -0
  134. package/dist/doompi-web-components/src/lib/mediaPlayback.mjs.map +1 -0
  135. package/dist/doompi-web-components/src/lib/mermaidDiagram.mjs.map +1 -0
  136. package/dist/doompi-web-components/src/lib/optionList.d.mts.map +1 -0
  137. package/dist/doompi-web-components/src/lib/optionList.mjs.map +1 -0
  138. package/dist/doompi-web-components/src/lib/syntaxHighlight.d.mts.map +1 -0
  139. package/dist/doompi-web-components/src/lib/syntaxHighlight.mjs.map +1 -0
  140. package/dist/doompi-web-components/src/lib/tone.d.mts.map +1 -0
  141. package/dist/doompi-web-components/src/lib/tone.mjs.map +1 -0
  142. package/dist/doompi-web-components/src/theme/apply.d.mts.map +1 -0
  143. package/dist/doompi-web-components/src/theme/apply.mjs.map +1 -0
  144. package/dist/doompi-web-components/src/theme/builtinThemes.d.mts.map +1 -0
  145. package/dist/doompi-web-components/src/theme/builtinThemes.mjs.map +1 -0
  146. package/dist/doompi-web-components/src/theme/derive.d.mts.map +1 -0
  147. package/dist/doompi-web-components/src/theme/derive.mjs.map +1 -0
  148. package/dist/doompi-web-components/src/theme/parse.d.mts.map +1 -0
  149. package/dist/doompi-web-components/src/theme/parse.mjs.map +1 -0
  150. package/dist/doompi-web-components/src/theme/piTheme.d.mts.map +1 -0
  151. package/dist/doompi-web-components/src/theme/piTheme.mjs.map +1 -0
  152. package/dist/doompi-web-components/src/theme/preference.d.mts.map +1 -0
  153. package/dist/doompi-web-components/src/theme/preference.mjs.map +1 -0
  154. package/dist/doompi-web-components/src/types/editor.d.mts.map +1 -0
  155. package/dist/doompi-web-components/src/types/editor.mjs.map +1 -0
  156. package/dist/doompi-web-components/src/types/theme.d.mts.map +1 -0
  157. package/dist/doompi-web-components/src/types/theme.mjs.map +1 -0
  158. package/dist/doompi-web-components/src/types/tone.d.mts.map +1 -0
  159. package/dist/doompi-web-components/src/types/tone.mjs.map +1 -0
  160. package/dist/doompi-web-components/themes/doom-nord-dark.mjs.map +1 -0
  161. package/dist/doompi-web-components/themes/doom-one-dark.mjs.map +1 -0
  162. package/dist/doompi-web-components/themes/doom-one-light.mjs.map +1 -0
  163. package/dist/index.cjs +1 -1
  164. package/dist/index.d.mts +61 -60
  165. package/dist/index.mjs +1 -1
  166. package/dist/mcpWidget.cjs +1 -0
  167. package/dist/mcpWidget.d.mts +3 -0
  168. package/dist/mcpWidget.mjs +1 -0
  169. package/dist/src/components/McpApp.cjs +2 -0
  170. package/dist/src/components/McpApp.cjs.map +1 -0
  171. package/dist/src/components/McpToolWidget.cjs +3 -0
  172. package/dist/src/components/McpToolWidget.cjs.map +1 -0
  173. package/dist/theme.d.mts +7 -7
  174. package/dist/theme.mjs +1 -1
  175. package/package.json +11 -4
  176. package/styles/mcp.css +22 -0
  177. package/dist/src/components/Accordion.d.mts.map +0 -1
  178. package/dist/src/components/Accordion.mjs.map +0 -1
  179. package/dist/src/components/AnsiText.d.mts.map +0 -1
  180. package/dist/src/components/AnsiText.mjs.map +0 -1
  181. package/dist/src/components/Avatar.d.mts.map +0 -1
  182. package/dist/src/components/Avatar.mjs.map +0 -1
  183. package/dist/src/components/Badge.d.mts.map +0 -1
  184. package/dist/src/components/Badge.mjs.map +0 -1
  185. package/dist/src/components/Breadcrumb.d.mts.map +0 -1
  186. package/dist/src/components/Breadcrumb.mjs.map +0 -1
  187. package/dist/src/components/Button.d.mts.map +0 -1
  188. package/dist/src/components/Button.mjs.map +0 -1
  189. package/dist/src/components/Checkbox.d.mts.map +0 -1
  190. package/dist/src/components/Checkbox.mjs.map +0 -1
  191. package/dist/src/components/CodeBlock.mjs.map +0 -1
  192. package/dist/src/components/CodeEditor.d.mts.map +0 -1
  193. package/dist/src/components/CodeEditor.mjs.map +0 -1
  194. package/dist/src/components/CodeEditorView.mjs.map +0 -1
  195. package/dist/src/components/Collapsible.d.mts.map +0 -1
  196. package/dist/src/components/Collapsible.mjs.map +0 -1
  197. package/dist/src/components/Command.d.mts.map +0 -1
  198. package/dist/src/components/Command.mjs.map +0 -1
  199. package/dist/src/components/CopyButton.mjs.map +0 -1
  200. package/dist/src/components/Dialog.d.mts.map +0 -1
  201. package/dist/src/components/Dialog.mjs.map +0 -1
  202. package/dist/src/components/Dot.d.mts.map +0 -1
  203. package/dist/src/components/Dot.mjs.map +0 -1
  204. package/dist/src/components/Drawer.d.mts.map +0 -1
  205. package/dist/src/components/Drawer.mjs.map +0 -1
  206. package/dist/src/components/DropdownMenu.d.mts.map +0 -1
  207. package/dist/src/components/DropdownMenu.mjs.map +0 -1
  208. package/dist/src/components/EmptyState.d.mts.map +0 -1
  209. package/dist/src/components/EmptyState.mjs.map +0 -1
  210. package/dist/src/components/HashlineLines.d.mts.map +0 -1
  211. package/dist/src/components/HashlineLines.mjs.map +0 -1
  212. package/dist/src/components/Input.d.mts.map +0 -1
  213. package/dist/src/components/Input.mjs.map +0 -1
  214. package/dist/src/components/Kbd.d.mts.map +0 -1
  215. package/dist/src/components/Kbd.mjs.map +0 -1
  216. package/dist/src/components/Label.d.mts.map +0 -1
  217. package/dist/src/components/Label.mjs.map +0 -1
  218. package/dist/src/components/Markdown.d.mts.map +0 -1
  219. package/dist/src/components/Markdown.mjs.map +0 -1
  220. package/dist/src/components/MediaPreview.d.mts.map +0 -1
  221. package/dist/src/components/MediaPreview.mjs.map +0 -1
  222. package/dist/src/components/MermaidDiagram.mjs.map +0 -1
  223. package/dist/src/components/MessageItem.d.mts.map +0 -1
  224. package/dist/src/components/MessageItem.mjs.map +0 -1
  225. package/dist/src/components/MessageLines.d.mts.map +0 -1
  226. package/dist/src/components/MessageLines.mjs.map +0 -1
  227. package/dist/src/components/OptionList.d.mts.map +0 -1
  228. package/dist/src/components/OptionList.mjs.map +0 -1
  229. package/dist/src/components/Panel.d.mts.map +0 -1
  230. package/dist/src/components/Panel.mjs.map +0 -1
  231. package/dist/src/components/PdfPreview.d.mts.map +0 -1
  232. package/dist/src/components/PdfPreview.mjs.map +0 -1
  233. package/dist/src/components/Popover.d.mts.map +0 -1
  234. package/dist/src/components/Popover.mjs.map +0 -1
  235. package/dist/src/components/Progress.d.mts.map +0 -1
  236. package/dist/src/components/Progress.mjs.map +0 -1
  237. package/dist/src/components/RadioGroup.d.mts.map +0 -1
  238. package/dist/src/components/RadioGroup.mjs.map +0 -1
  239. package/dist/src/components/ScrollArea.d.mts.map +0 -1
  240. package/dist/src/components/ScrollArea.mjs.map +0 -1
  241. package/dist/src/components/SectionLabel.d.mts.map +0 -1
  242. package/dist/src/components/SectionLabel.mjs.map +0 -1
  243. package/dist/src/components/Select.d.mts.map +0 -1
  244. package/dist/src/components/Select.mjs.map +0 -1
  245. package/dist/src/components/Separator.d.mts.map +0 -1
  246. package/dist/src/components/Separator.mjs.map +0 -1
  247. package/dist/src/components/Sheet.d.mts.map +0 -1
  248. package/dist/src/components/Sheet.mjs.map +0 -1
  249. package/dist/src/components/Skeleton.d.mts.map +0 -1
  250. package/dist/src/components/Skeleton.mjs.map +0 -1
  251. package/dist/src/components/Spinner.d.mts.map +0 -1
  252. package/dist/src/components/Spinner.mjs.map +0 -1
  253. package/dist/src/components/StatusBadge.d.mts.map +0 -1
  254. package/dist/src/components/StatusBadge.mjs.map +0 -1
  255. package/dist/src/components/StreamCursor.d.mts.map +0 -1
  256. package/dist/src/components/StreamCursor.mjs.map +0 -1
  257. package/dist/src/components/Switch.d.mts.map +0 -1
  258. package/dist/src/components/Switch.mjs.map +0 -1
  259. package/dist/src/components/SyntaxText.d.mts.map +0 -1
  260. package/dist/src/components/SyntaxText.mjs.map +0 -1
  261. package/dist/src/components/Tabs.d.mts.map +0 -1
  262. package/dist/src/components/Tabs.mjs.map +0 -1
  263. package/dist/src/components/TerminalView.d.mts.map +0 -1
  264. package/dist/src/components/TerminalView.mjs.map +0 -1
  265. package/dist/src/components/Textarea.d.mts.map +0 -1
  266. package/dist/src/components/Textarea.mjs.map +0 -1
  267. package/dist/src/components/Toast.d.mts.map +0 -1
  268. package/dist/src/components/Toast.mjs.map +0 -1
  269. package/dist/src/components/ToolPathLink.d.mts.map +0 -1
  270. package/dist/src/components/ToolPathLink.mjs.map +0 -1
  271. package/dist/src/components/Tooltip.d.mts.map +0 -1
  272. package/dist/src/components/Tooltip.mjs.map +0 -1
  273. package/dist/src/lib/ansiSpans.d.mts.map +0 -1
  274. package/dist/src/lib/ansiSpans.mjs.map +0 -1
  275. package/dist/src/lib/cn.d.mts.map +0 -1
  276. package/dist/src/lib/cn.mjs.map +0 -1
  277. package/dist/src/lib/collapse.d.mts.map +0 -1
  278. package/dist/src/lib/collapse.mjs.map +0 -1
  279. package/dist/src/lib/editorController.mjs.map +0 -1
  280. package/dist/src/lib/editorLanguage.d.mts.map +0 -1
  281. package/dist/src/lib/editorLanguage.mjs.map +0 -1
  282. package/dist/src/lib/editorTheme.d.mts.map +0 -1
  283. package/dist/src/lib/editorTheme.mjs.map +0 -1
  284. package/dist/src/lib/fenceGrammar.mjs.map +0 -1
  285. package/dist/src/lib/hashlineHighlight.d.mts.map +0 -1
  286. package/dist/src/lib/hashlineHighlight.mjs.map +0 -1
  287. package/dist/src/lib/hashlineView.d.mts.map +0 -1
  288. package/dist/src/lib/hashlineView.mjs.map +0 -1
  289. package/dist/src/lib/media.d.mts.map +0 -1
  290. package/dist/src/lib/media.mjs.map +0 -1
  291. package/dist/src/lib/mediaPlayback.mjs.map +0 -1
  292. package/dist/src/lib/mermaidDiagram.mjs.map +0 -1
  293. package/dist/src/lib/optionList.d.mts.map +0 -1
  294. package/dist/src/lib/optionList.mjs.map +0 -1
  295. package/dist/src/lib/syntaxHighlight.d.mts.map +0 -1
  296. package/dist/src/lib/syntaxHighlight.mjs.map +0 -1
  297. package/dist/src/lib/tone.d.mts.map +0 -1
  298. package/dist/src/lib/tone.mjs.map +0 -1
  299. package/dist/src/theme/apply.d.mts.map +0 -1
  300. package/dist/src/theme/apply.mjs.map +0 -1
  301. package/dist/src/theme/builtinThemes.d.mts.map +0 -1
  302. package/dist/src/theme/builtinThemes.mjs.map +0 -1
  303. package/dist/src/theme/derive.d.mts.map +0 -1
  304. package/dist/src/theme/derive.mjs.map +0 -1
  305. package/dist/src/theme/parse.d.mts.map +0 -1
  306. package/dist/src/theme/parse.mjs.map +0 -1
  307. package/dist/src/theme/piTheme.d.mts.map +0 -1
  308. package/dist/src/theme/piTheme.mjs.map +0 -1
  309. package/dist/src/theme/preference.d.mts.map +0 -1
  310. package/dist/src/theme/preference.mjs.map +0 -1
  311. package/dist/src/types/editor.d.mts.map +0 -1
  312. package/dist/src/types/editor.mjs.map +0 -1
  313. package/dist/src/types/theme.d.mts.map +0 -1
  314. package/dist/src/types/theme.mjs.map +0 -1
  315. package/dist/src/types/tone.d.mts.map +0 -1
  316. package/dist/src/types/tone.mjs.map +0 -1
  317. package/dist/themes/doom-nord-dark.mjs.map +0 -1
  318. package/dist/themes/doom-one-dark.mjs.map +0 -1
  319. package/dist/themes/doom-one-light.mjs.map +0 -1
  320. /package/dist/{src → doompi-web-components/src}/components/Accordion.d.mts +0 -0
  321. /package/dist/{src → doompi-web-components/src}/components/Accordion.mjs +0 -0
  322. /package/dist/{src → doompi-web-components/src}/components/AnsiText.d.mts +0 -0
  323. /package/dist/{src → doompi-web-components/src}/components/AnsiText.mjs +0 -0
  324. /package/dist/{src → doompi-web-components/src}/components/Avatar.d.mts +0 -0
  325. /package/dist/{src → doompi-web-components/src}/components/Avatar.mjs +0 -0
  326. /package/dist/{src → doompi-web-components/src}/components/Badge.d.mts +0 -0
  327. /package/dist/{src → doompi-web-components/src}/components/Badge.mjs +0 -0
  328. /package/dist/{src → doompi-web-components/src}/components/Breadcrumb.d.mts +0 -0
  329. /package/dist/{src → doompi-web-components/src}/components/Breadcrumb.mjs +0 -0
  330. /package/dist/{src → doompi-web-components/src}/components/Button.d.mts +0 -0
  331. /package/dist/{src → doompi-web-components/src}/components/Button.mjs +0 -0
  332. /package/dist/{src → doompi-web-components/src}/components/Checkbox.d.mts +0 -0
  333. /package/dist/{src → doompi-web-components/src}/components/Checkbox.mjs +0 -0
  334. /package/dist/{src → doompi-web-components/src}/components/CodeBlock.mjs +0 -0
  335. /package/dist/{src → doompi-web-components/src}/components/CodeEditor.d.mts +0 -0
  336. /package/dist/{src → doompi-web-components/src}/components/CodeEditor.mjs +0 -0
  337. /package/dist/{src → doompi-web-components/src}/components/CodeEditorView.mjs +0 -0
  338. /package/dist/{src → doompi-web-components/src}/components/Collapsible.d.mts +0 -0
  339. /package/dist/{src → doompi-web-components/src}/components/Collapsible.mjs +0 -0
  340. /package/dist/{src → doompi-web-components/src}/components/Command.d.mts +0 -0
  341. /package/dist/{src → doompi-web-components/src}/components/Command.mjs +0 -0
  342. /package/dist/{src → doompi-web-components/src}/components/CopyButton.mjs +0 -0
  343. /package/dist/{src → doompi-web-components/src}/components/Dialog.d.mts +0 -0
  344. /package/dist/{src → doompi-web-components/src}/components/Dialog.mjs +0 -0
  345. /package/dist/{src → doompi-web-components/src}/components/Dot.d.mts +0 -0
  346. /package/dist/{src → doompi-web-components/src}/components/Dot.mjs +0 -0
  347. /package/dist/{src → doompi-web-components/src}/components/Drawer.d.mts +0 -0
  348. /package/dist/{src → doompi-web-components/src}/components/Drawer.mjs +0 -0
  349. /package/dist/{src → doompi-web-components/src}/components/DropdownMenu.d.mts +0 -0
  350. /package/dist/{src → doompi-web-components/src}/components/DropdownMenu.mjs +0 -0
  351. /package/dist/{src → doompi-web-components/src}/components/EmptyState.d.mts +0 -0
  352. /package/dist/{src → doompi-web-components/src}/components/EmptyState.mjs +0 -0
  353. /package/dist/{src → doompi-web-components/src}/components/HashlineLines.d.mts +0 -0
  354. /package/dist/{src → doompi-web-components/src}/components/HashlineLines.mjs +0 -0
  355. /package/dist/{src → doompi-web-components/src}/components/Input.d.mts +0 -0
  356. /package/dist/{src → doompi-web-components/src}/components/Input.mjs +0 -0
  357. /package/dist/{src → doompi-web-components/src}/components/Kbd.d.mts +0 -0
  358. /package/dist/{src → doompi-web-components/src}/components/Kbd.mjs +0 -0
  359. /package/dist/{src → doompi-web-components/src}/components/Label.d.mts +0 -0
  360. /package/dist/{src → doompi-web-components/src}/components/Label.mjs +0 -0
  361. /package/dist/{src → doompi-web-components/src}/components/Markdown.d.mts +0 -0
  362. /package/dist/{src → doompi-web-components/src}/components/Markdown.mjs +0 -0
  363. /package/dist/{src → doompi-web-components/src}/components/MediaPreview.d.mts +0 -0
  364. /package/dist/{src → doompi-web-components/src}/components/MediaPreview.mjs +0 -0
  365. /package/dist/{src → doompi-web-components/src}/components/MermaidDiagram.mjs +0 -0
  366. /package/dist/{src → doompi-web-components/src}/components/MessageItem.d.mts +0 -0
  367. /package/dist/{src → doompi-web-components/src}/components/MessageItem.mjs +0 -0
  368. /package/dist/{src → doompi-web-components/src}/components/MessageLines.d.mts +0 -0
  369. /package/dist/{src → doompi-web-components/src}/components/MessageLines.mjs +0 -0
  370. /package/dist/{src → doompi-web-components/src}/components/OptionList.d.mts +0 -0
  371. /package/dist/{src → doompi-web-components/src}/components/OptionList.mjs +0 -0
  372. /package/dist/{src → doompi-web-components/src}/components/Panel.d.mts +0 -0
  373. /package/dist/{src → doompi-web-components/src}/components/Panel.mjs +0 -0
  374. /package/dist/{src → doompi-web-components/src}/components/PdfPreview.d.mts +0 -0
  375. /package/dist/{src → doompi-web-components/src}/components/PdfPreview.mjs +0 -0
  376. /package/dist/{src → doompi-web-components/src}/components/Popover.d.mts +0 -0
  377. /package/dist/{src → doompi-web-components/src}/components/Popover.mjs +0 -0
  378. /package/dist/{src → doompi-web-components/src}/components/Progress.d.mts +0 -0
  379. /package/dist/{src → doompi-web-components/src}/components/Progress.mjs +0 -0
  380. /package/dist/{src → doompi-web-components/src}/components/RadioGroup.d.mts +0 -0
  381. /package/dist/{src → doompi-web-components/src}/components/RadioGroup.mjs +0 -0
  382. /package/dist/{src → doompi-web-components/src}/components/ScrollArea.d.mts +0 -0
  383. /package/dist/{src → doompi-web-components/src}/components/ScrollArea.mjs +0 -0
  384. /package/dist/{src → doompi-web-components/src}/components/SectionLabel.d.mts +0 -0
  385. /package/dist/{src → doompi-web-components/src}/components/SectionLabel.mjs +0 -0
  386. /package/dist/{src → doompi-web-components/src}/components/Select.d.mts +0 -0
  387. /package/dist/{src → doompi-web-components/src}/components/Select.mjs +0 -0
  388. /package/dist/{src → doompi-web-components/src}/components/Separator.d.mts +0 -0
  389. /package/dist/{src → doompi-web-components/src}/components/Separator.mjs +0 -0
  390. /package/dist/{src → doompi-web-components/src}/components/Sheet.d.mts +0 -0
  391. /package/dist/{src → doompi-web-components/src}/components/Sheet.mjs +0 -0
  392. /package/dist/{src → doompi-web-components/src}/components/Skeleton.d.mts +0 -0
  393. /package/dist/{src → doompi-web-components/src}/components/Skeleton.mjs +0 -0
  394. /package/dist/{src → doompi-web-components/src}/components/Spinner.d.mts +0 -0
  395. /package/dist/{src → doompi-web-components/src}/components/Spinner.mjs +0 -0
  396. /package/dist/{src → doompi-web-components/src}/components/StatusBadge.d.mts +0 -0
  397. /package/dist/{src → doompi-web-components/src}/components/StatusBadge.mjs +0 -0
  398. /package/dist/{src → doompi-web-components/src}/components/StreamCursor.d.mts +0 -0
  399. /package/dist/{src → doompi-web-components/src}/components/StreamCursor.mjs +0 -0
  400. /package/dist/{src → doompi-web-components/src}/components/Switch.d.mts +0 -0
  401. /package/dist/{src → doompi-web-components/src}/components/Switch.mjs +0 -0
  402. /package/dist/{src → doompi-web-components/src}/components/SyntaxText.d.mts +0 -0
  403. /package/dist/{src → doompi-web-components/src}/components/SyntaxText.mjs +0 -0
  404. /package/dist/{src → doompi-web-components/src}/components/Tabs.d.mts +0 -0
  405. /package/dist/{src → doompi-web-components/src}/components/Tabs.mjs +0 -0
  406. /package/dist/{src → doompi-web-components/src}/components/TerminalView.d.mts +0 -0
  407. /package/dist/{src → doompi-web-components/src}/components/TerminalView.mjs +0 -0
  408. /package/dist/{src → doompi-web-components/src}/components/Textarea.d.mts +0 -0
  409. /package/dist/{src → doompi-web-components/src}/components/Textarea.mjs +0 -0
  410. /package/dist/{src → doompi-web-components/src}/components/Toast.d.mts +0 -0
  411. /package/dist/{src → doompi-web-components/src}/components/Toast.mjs +0 -0
  412. /package/dist/{src → doompi-web-components/src}/components/ToolPathLink.d.mts +0 -0
  413. /package/dist/{src → doompi-web-components/src}/components/ToolPathLink.mjs +0 -0
  414. /package/dist/{src → doompi-web-components/src}/components/Tooltip.d.mts +0 -0
  415. /package/dist/{src → doompi-web-components/src}/components/Tooltip.mjs +0 -0
  416. /package/dist/{src → doompi-web-components/src}/icons/icons.d.mts +0 -0
  417. /package/dist/{src → doompi-web-components/src}/icons/icons.mjs +0 -0
  418. /package/dist/{src → doompi-web-components/src}/lib/ansiSpans.d.mts +0 -0
  419. /package/dist/{src → doompi-web-components/src}/lib/ansiSpans.mjs +0 -0
  420. /package/dist/{src → doompi-web-components/src}/lib/cn.d.mts +0 -0
  421. /package/dist/{src → doompi-web-components/src}/lib/cn.mjs +0 -0
  422. /package/dist/{src → doompi-web-components/src}/lib/collapse.d.mts +0 -0
  423. /package/dist/{src → doompi-web-components/src}/lib/collapse.mjs +0 -0
  424. /package/dist/{src → doompi-web-components/src}/lib/editorController.mjs +0 -0
  425. /package/dist/{src → doompi-web-components/src}/lib/editorLanguage.d.mts +0 -0
  426. /package/dist/{src → doompi-web-components/src}/lib/editorLanguage.mjs +0 -0
  427. /package/dist/{src → doompi-web-components/src}/lib/editorTheme.d.mts +0 -0
  428. /package/dist/{src → doompi-web-components/src}/lib/editorTheme.mjs +0 -0
  429. /package/dist/{src → doompi-web-components/src}/lib/fenceGrammar.mjs +0 -0
  430. /package/dist/{src → doompi-web-components/src}/lib/hashlineHighlight.d.mts +0 -0
  431. /package/dist/{src → doompi-web-components/src}/lib/hashlineHighlight.mjs +0 -0
  432. /package/dist/{src → doompi-web-components/src}/lib/hashlineView.d.mts +0 -0
  433. /package/dist/{src → doompi-web-components/src}/lib/hashlineView.mjs +0 -0
  434. /package/dist/{src → doompi-web-components/src}/lib/media.d.mts +0 -0
  435. /package/dist/{src → doompi-web-components/src}/lib/media.mjs +0 -0
  436. /package/dist/{src → doompi-web-components/src}/lib/mediaPlayback.mjs +0 -0
  437. /package/dist/{src → doompi-web-components/src}/lib/mermaidDiagram.mjs +0 -0
  438. /package/dist/{src → doompi-web-components/src}/lib/optionList.d.mts +0 -0
  439. /package/dist/{src → doompi-web-components/src}/lib/optionList.mjs +0 -0
  440. /package/dist/{src → doompi-web-components/src}/lib/syntaxHighlight.d.mts +0 -0
  441. /package/dist/{src → doompi-web-components/src}/lib/syntaxHighlight.mjs +0 -0
  442. /package/dist/{src → doompi-web-components/src}/lib/tone.d.mts +0 -0
  443. /package/dist/{src → doompi-web-components/src}/lib/tone.mjs +0 -0
  444. /package/dist/{src → doompi-web-components/src}/theme/apply.d.mts +0 -0
  445. /package/dist/{src → doompi-web-components/src}/theme/apply.mjs +0 -0
  446. /package/dist/{src → doompi-web-components/src}/theme/builtinThemes.d.mts +0 -0
  447. /package/dist/{src → doompi-web-components/src}/theme/builtinThemes.mjs +0 -0
  448. /package/dist/{src → doompi-web-components/src}/theme/derive.d.mts +0 -0
  449. /package/dist/{src → doompi-web-components/src}/theme/derive.mjs +0 -0
  450. /package/dist/{src → doompi-web-components/src}/theme/parse.d.mts +0 -0
  451. /package/dist/{src → doompi-web-components/src}/theme/parse.mjs +0 -0
  452. /package/dist/{src → doompi-web-components/src}/theme/piTheme.d.mts +0 -0
  453. /package/dist/{src → doompi-web-components/src}/theme/piTheme.mjs +0 -0
  454. /package/dist/{src → doompi-web-components/src}/theme/preference.d.mts +0 -0
  455. /package/dist/{src → doompi-web-components/src}/theme/preference.mjs +0 -0
  456. /package/dist/{src → doompi-web-components/src}/types/editor.d.mts +0 -0
  457. /package/dist/{src → doompi-web-components/src}/types/editor.mjs +0 -0
  458. /package/dist/{src → doompi-web-components/src}/types/theme.d.mts +0 -0
  459. /package/dist/{src → doompi-web-components/src}/types/theme.mjs +0 -0
  460. /package/dist/{src → doompi-web-components/src}/types/tone.d.mts +0 -0
  461. /package/dist/{src → doompi-web-components/src}/types/tone.mjs +0 -0
  462. /package/dist/{themes → doompi-web-components/themes}/doom-nord-dark.mjs +0 -0
  463. /package/dist/{themes → doompi-web-components/themes}/doom-one-dark.mjs +0 -0
  464. /package/dist/{themes → doompi-web-components/themes}/doom-one-light.mjs +0 -0
@@ -0,0 +1,2 @@
1
+ import "../web/types/webPlugin.mjs";
2
+ import "../web/types/extensionFile.mjs";
@@ -0,0 +1 @@
1
+ import "../types/webPlugin.mjs";
@@ -0,0 +1 @@
1
+ import "../types/webPlugin.mjs";
@@ -0,0 +1 @@
1
+ import "../types/webPlugin.mjs";
@@ -0,0 +1 @@
1
+ import "../types/template.mjs";
@@ -0,0 +1,2 @@
1
+ import "./template.mjs";
2
+ import "./webPlugin.mjs";
@@ -0,0 +1,16 @@
1
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
+ //#region ../doompi-core/dist/src/web/types/mcpWidget.d.mts
3
+ //#region src/web/types/mcpWidget.d.ts
4
+ /** The MCP host supplies invocation data. Widgets never receive host services or credentials. */
5
+ export interface DoomMcpWidgetProps {
6
+ readonly toolName: string;
7
+ readonly args: Readonly<Record<string, unknown>>;
8
+ readonly result: CallToolResult | null;
9
+ readonly phase: 'connecting' | 'preparing' | 'running' | 'result' | 'cancelled' | 'error';
10
+ readonly error?: string;
11
+ /** Only available when this tool explicitly allows app calls and the host supports them. */
12
+ readonly refresh?: () => Promise<CallToolResult>;
13
+ }
14
+ //#endregion
15
+ //#endregion
16
+ //# sourceMappingURL=mcpWidget.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpWidget.d.mts","names":[],"sources":["../../../../../../../doompi-core/dist/src/web/types/mcpWidget.d.mts"],"mappings":";;;;iBAGiB;WACN;WACA,MAAM,SAAS;WACf,QAAQ;WACR;WACA;;WAEA,gBAAgB,QAAQ"}
@@ -0,0 +1 @@
1
+ import { ComponentType, ReactNode } from "react";
@@ -0,0 +1,2 @@
1
+ import "./template.mjs";
2
+ import { ComponentType, ReactNode } from "react";
@@ -0,0 +1,10 @@
1
+ import { DoomMcpWidgetProps } from "./src/web/types/mcpWidget.mjs";
2
+ import "./src/web/types/template.mjs";
3
+ import "./src/web/types/webPlugin.mjs";
4
+ import "./src/web/types/extensionFile.mjs";
5
+ import "./src/extensions/webPlugin.mjs";
6
+ import "./src/web/models/globalStore.mjs";
7
+ import "./src/web/models/sessionStore.mjs";
8
+ import "./src/web/models/workspaceStore.mjs";
9
+ import "./src/web/schemas/template.mjs";
10
+ export type { DoomMcpWidgetProps };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.d.mts","names":[],"sources":["../../../../src/components/Accordion.tsx"],"mappings":";;;;iBAOgB,YAAU,OAAO,sBAAsB,UAAmB,wBAAK,IAAA;wBAI/D,gBAAgB,cAAc,SAAS,sBAAsB,UAAmB,wBAAK,IAAA;wBAUrF,mBAAmB,WAAW,aAAa,SAAS,sBAAsB,UAAmB,2BAAQ,IAAA;wBAkBrG,mBAAmB,cAAc,SAAS,sBAAsB,UAAmB,2BAAQ,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.mjs","names":["Accordion","AccordionPrimitive"],"sources":["../../../../src/components/Accordion.tsx"],"sourcesContent":["import { Accordion as AccordionPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { ChevronDownIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\n\n/** Several collapsibles that know about each other; pass type=\"single\" for one open at a time. */\nexport function Accordion(props: ComponentProps<typeof AccordionPrimitive.Root>) {\n return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />;\n}\n\nexport function AccordionItem({ className, ...props }: ComponentProps<typeof AccordionPrimitive.Item>) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn('border-b border-doom-border-soft last:border-b-0', className)}\n {...props}\n />\n );\n}\n\nexport function AccordionTrigger({ className, children, ...props }: ComponentProps<typeof AccordionPrimitive.Trigger>) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n 'flex flex-1 cursor-pointer items-center justify-between gap-2 py-2 text-left text-sm text-doom-hi outline-none transition-colors hover:text-doom-blue focus-visible:text-doom-blue [&[data-state=open]>svg]:rotate-180',\n className,\n )}\n {...props}\n >\n {children}\n <ChevronDownIcon className=\"h-3 w-3 shrink-0 text-doom-faint transition-transform\" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nexport function AccordionContent({ className, ...props }: ComponentProps<typeof AccordionPrimitive.Content>) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className={cn('overflow-hidden pb-2 text-sm text-doom-dim', className)}\n {...props}\n />\n );\n}\n"],"mappings":"+KAOA,SAAgBA,EAAU,EAAuD,CAC/E,MAAO,kBAACC,EAAmB,KAApB,CAAyB,YAAU,YAAY,GAAI,CAAQ,CAAA,CACpE,CAEA,SAAgB,EAAc,CAAE,YAAW,GAAG,GAAyD,CACrG,MACE,kBAACA,EAAmB,KAApB,CACE,YAAU,iBACV,UAAW,EAAG,mDAAoD,CAAS,EAC3E,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAiB,CAAE,YAAW,WAAU,GAAG,GAA4D,CACrH,MACE,kBAACA,EAAmB,OAApB,CAA2B,UAAU,OACnC,SAAA,kBAACA,EAAmB,QAApB,CACE,YAAU,oBACV,UAAW,EACT,yNACA,CACF,EACA,GAAI,EANN,SAAA,CAQG,EACD,kBAAC,EAAD,CAAiB,UAAU,uDAAyD,CAAA,CAC1D,GACH,CAAA,CAE/B,CAEA,SAAgB,EAAiB,CAAE,YAAW,GAAG,GAA4D,CAC3G,MACE,kBAACA,EAAmB,QAApB,CACE,YAAU,oBACV,UAAW,EAAG,6CAA8C,CAAS,EACrE,GAAI,CACL,CAAA,CAEL"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnsiText.d.mts","names":[],"sources":["../../../../src/components/AnsiText.tsx"],"mappings":";;iBAmDiB,sBAAsB,KAAK;;EAE1C;;;wBAIc,WAAW,MAAM,cAAc,SAAS,gCAAa,IAAA;iBASpD,sBAAsB,KAAK;;EAE1C;;;wBAIc,WAAW,SAAS,SAAS,gCAAa,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnsiText.mjs","names":["Fragment"],"sources":["../../../../src/components/AnsiText.tsx"],"sourcesContent":["import { type ComponentProps, Fragment, useMemo } from 'react';\n\nimport { type AnsiSpan, ansiSpans } from '../lib/ansiSpans';\nimport { cn } from '../lib/cn';\n\n/**\n * Terminal output with the colours it was written in.\n *\n * Both readers of terminal text render it the same way, so the mapping from a\n * span's attributes to classes lives here rather than in each of them: a\n * captured workflow screen is a line at a time, and a runner log is a block.\n * Parsing is synchronous and cheap; text with no escapes in it takes a path\n * that allocates nothing.\n *\n * DESIGN PATTERNS:\n * - Named colours arrive as theme classes from `ansiSpans`; only 256-colour\n * and truecolour, which no token stands for, come through as a style.\n * - One element per line, so wrapping and selection behave as they do in a pre.\n *\n * AVOID:\n * - Carrying attributes across lines. A captured screen and a bounded log tail\n * both start mid-stream.\n */\n\nfunction spanClassName(span: AnsiSpan): string {\n return cn(\n span.className,\n span.bold === true && 'font-bold',\n span.faint === true && 'opacity-60',\n span.italic === true && 'italic',\n span.underline === true && 'underline',\n span.inverse === true && 'bg-doom-text text-doom-deep',\n );\n}\n\nfunction AnsiSpans({ spans }: { spans: readonly AnsiSpan[] }) {\n return (\n <>\n {spans.map((span, index) => (\n <span\n key={index}\n className={spanClassName(span)}\n style={span.color === undefined ? undefined : { color: span.color }}\n >\n {span.text}\n </span>\n ))}\n </>\n );\n}\n\nexport interface AnsiLineProps extends Omit<ComponentProps<'span'>, 'children'> {\n /** One line of terminal output, escapes and all. */\n line: string;\n}\n\n/** One line, for a caller that already lays out a screen row by row. */\nexport function AnsiLine({ line, className, ...props }: AnsiLineProps) {\n const spans = useMemo(() => ansiSpans(line), [line]);\n return (\n <span data-slot=\"ansi-line\" className={className} {...props}>\n <AnsiSpans spans={spans} />\n </span>\n );\n}\n\nexport interface AnsiTextProps extends Omit<ComponentProps<'pre'>, 'children'> {\n /** Terminal output, newline separated, escapes and all. */\n text: string;\n}\n\n/** A block of terminal output: a log tail, or anything else that arrives whole. */\nexport function AnsiText({ text, ...props }: AnsiTextProps) {\n const lines = useMemo(() => text.split('\\n').map((line) => ansiSpans(line)), [text]);\n return (\n <pre data-slot=\"ansi-text\" {...props}>\n {lines.map((spans, index) => (\n <Fragment key={index}>\n {index > 0 ? '\\n' : null}\n <AnsiSpans spans={spans} />\n </Fragment>\n ))}\n </pre>\n );\n}\n"],"mappings":"kMAwBA,SAAS,EAAc,EAAwB,CAC7C,OAAO,EACL,EAAK,UACL,EAAK,OAAS,IAAQ,YACtB,EAAK,QAAU,IAAQ,aACvB,EAAK,SAAW,IAAQ,SACxB,EAAK,YAAc,IAAQ,YAC3B,EAAK,UAAY,IAAQ,6BAC3B,CACF,CAEA,SAAS,EAAU,CAAE,SAAyC,CAC5D,MACE,kBAAA,EAAA,CAAA,SACG,EAAM,KAAK,EAAM,IAChB,kBAAC,OAAD,CAEE,UAAW,EAAc,CAAI,EAC7B,MAAO,EAAK,QAAU,IAAA,GAAY,IAAA,GAAY,CAAE,MAAO,EAAK,KAAM,EAEjE,SAAA,EAAK,IACF,EALC,CAKD,CACP,CACD,CAAA,CAEN,CAQA,SAAgB,EAAS,CAAE,OAAM,YAAW,GAAG,GAAwB,CACrE,IAAM,EAAQ,MAAc,EAAU,CAAI,EAAG,CAAC,CAAI,CAAC,EACnD,MACE,kBAAC,OAAD,CAAM,YAAU,YAAuB,YAAW,GAAI,EACpD,SAAA,kBAAC,EAAD,CAAkB,OAAQ,CAAA,CACtB,CAAA,CAEV,CAQA,SAAgB,EAAS,CAAE,OAAM,GAAG,GAAwB,CAC1D,IAAM,EAAQ,MAAc,EAAK,MAAM;CAAI,CAAC,CAAC,IAAK,GAAS,EAAU,CAAI,CAAC,EAAG,CAAC,CAAI,CAAC,EACnF,MACE,kBAAC,MAAD,CAAK,YAAU,YAAY,GAAI,EAC5B,SAAA,EAAM,KAAK,EAAO,IACjB,kBAACA,EAAD,CAAA,SAAA,CACG,EAAQ,EAAI;EAAO,KACpB,kBAAC,EAAD,CAAkB,OAAQ,CAAA,CAClB,CAAA,EAHK,CAGL,CACX,CACE,CAAA,CAET"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Avatar.d.mts","names":[],"sources":["../../../../src/components/Avatar.tsx"],"mappings":";;;;iBAMgB,WAAS,cAAc,SAAS,sBAAsB,OAAgB,wBAAK,IAAA;wBAU3E,cAAc,cAAc,SAAS,sBAAsB,OAAgB,yBAAM,IAAA;wBAUjF,iBAAiB,cAAc,SAAS,sBAAsB,OAAgB,4BAAS,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Avatar.mjs","names":["Avatar","AvatarPrimitive"],"sources":["../../../../src/components/Avatar.tsx"],"sourcesContent":["import { Avatar as AvatarPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A face or an initial; Radix only shows the fallback once the image has actually failed. */\nexport function Avatar({ className, ...props }: ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn('relative flex h-6 w-6 shrink-0 overflow-hidden rounded-full bg-doom-deep', className)}\n {...props}\n />\n );\n}\n\nexport function AvatarImage({ className, ...props }: ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn('h-full w-full object-cover', className)}\n {...props}\n />\n );\n}\n\nexport function AvatarFallback({ className, ...props }: ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn('flex h-full w-full items-center justify-center text-xs font-bold text-doom-dim', className)}\n {...props}\n />\n );\n}\n"],"mappings":"6GAMA,SAAgBA,EAAO,CAAE,YAAW,GAAG,GAAsD,CAC3F,MACE,kBAACC,EAAgB,KAAjB,CACE,YAAU,SACV,UAAW,EAAG,2EAA4E,CAAS,EACnG,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAuD,CACjG,MACE,kBAACA,EAAgB,MAAjB,CACE,YAAU,eACV,UAAW,EAAG,6BAA8B,CAAS,EACrD,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAe,CAAE,YAAW,GAAG,GAA0D,CACvG,MACE,kBAACA,EAAgB,SAAjB,CACE,YAAU,kBACV,UAAW,EAAG,iFAAkF,CAAS,EACzG,GAAI,CACL,CAAA,CAEL"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Badge.d.mts","names":[],"sources":["../../../../src/components/Badge.tsx"],"mappings":";;;;qBAOa,gBAAa;;;6CAuBxB;YAEU,YAAY;iBAEP,mBAAmB,wBAAwB,oBAAoB;;EAE9E;;;wBAIc,QAAQ,WAAW,MAAM,MAAM,YAAoB,SAAS,6BAAU,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Badge.mjs","names":[],"sources":["../../../../src/components/Badge.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport type { ChipTone } from '../types/tone';\n\nexport const badgeVariants = cva('inline-flex items-center gap-1.5 whitespace-nowrap rounded border font-mono', {\n variants: {\n tone: {\n neutral: 'border-doom-border text-doom-dim',\n blue: 'border-doom-blue/40 text-doom-blue',\n green: 'border-doom-green/40 text-doom-green',\n yellow: 'border-doom-yellow/40 text-doom-yellow',\n red: 'border-doom-red/40 text-doom-red',\n magenta: 'border-doom-magenta/40 text-doom-magenta',\n violet: 'border-doom-violet/40 text-doom-violet',\n cyan: 'border-doom-cyan/40 text-doom-cyan',\n orange: 'border-doom-orange/40 text-doom-orange',\n teal: 'border-doom-teal/40 text-doom-teal',\n } satisfies Record<ChipTone, string>,\n /** The same rungs Button names, so a chip can sit beside a button of any size. */\n size: {\n xs: 'px-1.5 py-0.5 text-2xs font-bold',\n sm: 'px-2 py-0.5 text-xs',\n md: 'px-2.5 py-1 text-sm',\n lg: 'px-3 py-1.5 text-base',\n },\n },\n defaultVariants: { tone: 'neutral', size: 'sm' },\n});\n\nexport type BadgeTone = ChipTone;\n\nexport interface BadgeProps extends ComponentProps<'span'>, VariantProps<typeof badgeVariants> {\n /** Render the child element instead of a <span>, so a link can look like a chip. */\n asChild?: boolean;\n}\n\n/** An outlined chip in one of the accent tones; the Chip the cockpit mockup draws. */\nexport function Badge({ className, tone, size, asChild = false, ...props }: BadgeProps) {\n const Component = asChild ? Slot.Root : 'span';\n return <Component data-slot=\"badge\" className={cn(badgeVariants({ tone, size }), className)} {...props} />;\n}\n"],"mappings":"0JAOA,MAAa,EAAgB,EAAI,8EAA+E,CAC9G,SAAU,CACR,KAAM,CACJ,QAAS,mCACT,KAAM,qCACN,MAAO,uCACP,OAAQ,yCACR,IAAK,mCACL,QAAS,2CACT,OAAQ,yCACR,KAAM,qCACN,OAAQ,yCACR,KAAM,oCACR,EAEA,KAAM,CACJ,GAAI,mCACJ,GAAI,sBACJ,GAAI,sBACJ,GAAI,uBACN,CACF,EACA,gBAAiB,CAAE,KAAM,UAAW,KAAM,IAAK,CACjD,CAAC,EAUD,SAAgB,EAAM,CAAE,YAAW,OAAM,OAAM,UAAU,GAAO,GAAG,GAAqB,CACtF,IAAM,EAAY,EAAU,EAAK,KAAO,OACxC,MAAO,kBAAC,EAAD,CAAW,YAAU,QAAQ,UAAW,EAAG,EAAc,CAAE,OAAM,MAAK,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CAC3G"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Breadcrumb.d.mts","names":[],"sources":["../../../../src/components/Breadcrumb.tsx"],"mappings":";;qBAIa;;;;;;;;;wBAUG,mBAAmB,cAAc;iBAShC;;EAEf;;EAEA;;EAEA;EACA;;;;;;;;;;;;;;wBAec,aAAa,MAAM,MAAM,0BAA0B,UAAU,kCAAe,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Breadcrumb.mjs","names":[],"sources":["../../../../src/components/Breadcrumb.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './Tooltip';\n\n/** The marker a collapsed run of segments is shown as. */\nexport const BREADCRUMB_ELLIPSIS = '…';\n\n/**\n * A path as breadcrumb segments, with the middle collapsed when it is deeper\n * than `keep` allows.\n *\n * The first segment and the last few are what place a leaf; the ones between\n * are what a reader skims past, so those are the ones that go. The leaf is\n * always the final segment and is never collapsed.\n */\nexport function breadcrumbSegments(path: string, keep = 4): string[] {\n const segments = path.split('/').filter((segment) => segment !== '');\n if (segments.length === 0) return [path];\n const limit = Math.max(3, keep);\n if (segments.length <= limit) return segments;\n // Keep room for the first segment, the collapse marker, and the leaf.\n return [segments[0] ?? '', BREADCRUMB_ELLIPSIS, ...segments.slice(segments.length - (limit - 2))];\n}\n\nexport interface BreadcrumbProps {\n /** The path to show, separated by forward slashes. */\n path: string;\n /** How many segments survive, with a minimum of three to retain the leaf. */\n keep?: number;\n /** Marks the trail so a test can find it. */\n 'data-testid'?: string;\n className?: string;\n}\n\n/**\n * A slash-separated path, shortened to fit and readable in full on hover.\n *\n * Two things shorten it, because they solve different problems. Collapsing the\n * middle keeps a deep path legible at any width, and truncation handles what is\n * left when the container is narrower than even that. Either one hides\n * something, so the whole path is always one hover away, wrapped rather than\n * clipped: a tooltip that truncates too would defeat the point of having one.\n *\n * The leaf carries the emphasis. A reader scanning a header is looking for the\n * file, and the directories are context for it.\n */\nexport function Breadcrumb({ path, keep, className, 'data-testid': testId }: BreadcrumbProps) {\n const segments = breadcrumbSegments(path, keep);\n const lastIndex = segments.length - 1;\n\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n data-slot=\"breadcrumb\"\n data-testid={testId}\n title={undefined}\n className={cn('flex min-w-0 items-baseline gap-1 truncate font-mono text-sm', className)}\n >\n {segments.map((segment, index) => (\n // Segments repeat in a path (src/app/src), so the index is what\n // keeps two of the same name apart.\n <span key={`${segment}-${String(index)}`} className=\"flex min-w-0 items-baseline gap-1\">\n {index > 0 ? <span className=\"shrink-0 text-doom-faint\">/</span> : null}\n <span\n className={\n index === lastIndex ? 'truncate font-bold text-doom-hi' : 'min-w-0 truncate text-doom-faint'\n }\n >\n {segment}\n </span>\n </span>\n ))}\n </span>\n </TooltipTrigger>\n <TooltipContent className=\"max-w-[32rem] break-all whitespace-normal\">{path}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n"],"mappings":"0LAIA,MAAa,EAAsB,IAUnC,SAAgB,EAAmB,EAAc,EAAO,EAAa,CACnE,IAAM,EAAW,EAAK,MAAM,GAAG,CAAC,CAAC,OAAQ,GAAY,IAAY,EAAE,EACnE,GAAI,EAAS,SAAW,EAAG,MAAO,CAAC,CAAI,EACvC,IAAM,EAAQ,KAAK,IAAI,EAAG,CAAI,EAG9B,OAFI,EAAS,QAAU,EAAc,EAE9B,CAAC,EAAS,IAAM,OAAyB,GAAG,EAAS,MAAM,EAAS,QAAU,EAAQ,EAAE,CAAC,CAClG,CAwBA,SAAgB,EAAW,CAAE,OAAM,OAAM,YAAW,cAAe,GAA2B,CAC5F,IAAM,EAAW,EAAmB,EAAM,CAAI,EACxC,EAAY,EAAS,OAAS,EAEpC,MACE,kBAAC,EAAD,CAAA,SACE,kBAAC,EAAD,CAAA,SAAA,CACE,kBAAC,EAAD,CAAgB,QAAA,GACd,SAAA,kBAAC,OAAD,CACE,YAAU,aACV,cAAa,EACb,MAAO,IAAA,GACP,UAAW,EAAG,+DAAgE,CAAS,EAEtF,SAAA,EAAS,KAAK,EAAS,IAGtB,kBAAC,OAAD,CAA0C,UAAU,oCAApD,SAAA,CACG,EAAQ,EAAI,kBAAC,OAAD,CAAM,UAAU,2BAA2B,SAAA,GAAO,CAAA,EAAI,KACnE,kBAAC,OAAD,CACE,UACE,IAAU,EAAY,kCAAoC,mCAG3D,SAAA,CACG,CAAA,CACF,CATK,EAAA,GAAG,EAAQ,GAAG,OAAO,CAAK,GAS/B,CACP,CACG,CAAA,CACQ,CAAA,EAChB,kBAAC,EAAD,CAAgB,UAAU,4CAA6C,SAAA,CAAqB,CAAA,CACrF,CAAA,CAAA,CACM,CAAA,CAErB"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.d.mts","names":[],"sources":["../../../../src/components/Button.tsx"],"mappings":";;;qBAOa,iBAAc;;;6CAgC1B;YAEW,gBAAgB,YAAY,oBAAoB;YAChD,aAAa,YAAY,oBAAoB;iBAExC,oBAAoB,0BAA0B,oBAAoB;;EAEjF;;;;;EAKA;;EAEA;;;wBAIc,SACd,WACA,SACA,MACA,SACA,SACA,cACA,UACA,MACA,aACG,SACF,8BAAW,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.mjs","names":[],"sources":["../../../../src/components/Button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Spinner } from './Spinner';\n\nexport const buttonVariants = cva(\n 'inline-flex min-h-6 min-w-6 shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n primary: 'bg-doom-blue font-bold text-doom-rail hover:brightness-110',\n outline: 'border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi',\n ghost: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n subtle: 'bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi',\n danger: 'bg-doom-red font-bold text-doom-rail hover:brightness-110',\n 'danger-outline': 'border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110',\n success: 'bg-doom-green font-bold text-doom-rail hover:brightness-110',\n link: 'text-doom-blue hover:underline',\n },\n size: {\n xs: 'h-6 rounded px-1.5 text-2xs',\n sm: 'h-7 px-2.5 text-xs',\n md: 'h-8 px-3 text-sm',\n lg: 'h-9 px-3.5 text-base',\n icon: 'h-6 w-6 rounded p-0',\n 'icon-md': 'h-8 w-8 p-0',\n /**\n * A whole card that is one click target: a session in the rail, a run\n * in a panel. It keeps the button's focus ring and cursor and gives up\n * the button's single-line box, which is what a card-shaped <button>\n * would otherwise have to restate.\n */\n card: 'h-auto w-full flex-col items-stretch justify-start gap-1 px-[11px] py-2.5 text-left whitespace-normal',\n },\n },\n defaultVariants: { variant: 'outline', size: 'md' },\n },\n);\n\nexport type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>['variant']>;\nexport type ButtonSize = NonNullable<VariantProps<typeof buttonVariants>['size']>;\n\nexport interface ButtonProps extends ComponentProps<'button'>, VariantProps<typeof buttonVariants> {\n /** Render the child element instead of a <button>, passing the classes down (shadcn's asChild). */\n asChild?: boolean;\n /**\n * Work is in flight: the button shows a spinner and stops accepting clicks.\n * Ignored under asChild, where the child owns its own content.\n */\n loading?: boolean;\n /** What the spinner announces while loading; omit it and the wait is silent. */\n loadingLabel?: string;\n}\n\n/** The one button: every variant is a theme token, so it recolours with the theme. */\nexport function Button({\n className,\n variant,\n size,\n asChild = false,\n loading = false,\n loadingLabel,\n disabled,\n type,\n children,\n ...props\n}: ButtonProps) {\n const Component = asChild ? Slot.Root : 'button';\n const busy = !asChild && loading;\n return (\n <Component\n data-slot=\"button\"\n type={asChild ? undefined : (type ?? 'button')}\n aria-busy={busy ? true : undefined}\n disabled={asChild ? undefined : (disabled ?? busy)}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n >\n {/* Slot takes exactly one child, so asChild hands its element straight through. */}\n {asChild ? (\n children\n ) : (\n <>\n {busy ? <Spinner label={loadingLabel} /> : null}\n {children}\n </>\n )}\n </Component>\n );\n}\n"],"mappings":"0NAOA,MAAa,EAAiB,EAC5B,yVACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,6DACT,QAAS,uFACT,MAAO,uDACP,OAAQ,oEACR,OAAQ,4DACR,iBAAkB,4FAClB,QAAS,8DACT,KAAM,gCACR,EACA,KAAM,CACJ,GAAI,8BACJ,GAAI,qBACJ,GAAI,mBACJ,GAAI,uBACJ,KAAM,sBACN,UAAW,cAOX,KAAM,uGACR,CACF,EACA,gBAAiB,CAAE,QAAS,UAAW,KAAM,IAAK,CACpD,CACF,EAkBA,SAAgB,EAAO,CACrB,YACA,UACA,OACA,UAAU,GACV,UAAU,GACV,eACA,WACA,OACA,WACA,GAAG,GACW,CACd,IAAM,EAAY,EAAU,EAAK,KAAO,SAClC,EAAO,CAAC,GAAW,EACzB,MACE,kBAAC,EAAD,CACE,YAAU,SACV,KAAM,EAAU,IAAA,GAAa,GAAQ,SACrC,YAAW,EAAO,GAAO,IAAA,GACzB,SAAU,EAAU,IAAA,GAAa,GAAY,EAC7C,UAAW,EAAG,EAAe,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EAC1D,GAAI,EAGH,SAAA,EACC,EAEA,kBAAA,EAAA,CAAA,SAAA,CACG,EAAO,kBAAC,EAAD,CAAS,MAAO,CAAe,CAAA,EAAI,KAC1C,CACD,CAAA,CAAA,CAEK,CAAA,CAEf"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.d.mts","names":[],"sources":["../../../../src/components/Checkbox.tsx"],"mappings":";;;;iBAOgB,aAAW,cAAc,SAAS,sBAAsB,SAAkB,wBAAK,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.mjs","names":["Checkbox","CheckboxPrimitive"],"sources":["../../../../src/components/Checkbox.tsx"],"sourcesContent":["import { Checkbox as CheckboxPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CheckIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\n\n/** A box that is on, off, or indeterminate; the tick is the accent on the deep well. */\nexport function Checkbox({ className, ...props }: ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'flex h-3.5 w-3.5 shrink-0 cursor-pointer items-center justify-center rounded-sm border border-doom-border bg-doom-deep outline-none transition-colors focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 data-[state=checked]:border-doom-blue data-[state=indeterminate]:border-doom-blue',\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator data-slot=\"checkbox-indicator\" className=\"text-doom-blue\">\n <CheckIcon className=\"h-2.5 w-2.5\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n"],"mappings":"8JAOA,SAAgBA,EAAS,CAAE,YAAW,GAAG,GAAwD,CAC/F,MACE,kBAACC,EAAkB,KAAnB,CACE,YAAU,WACV,UAAW,EACT,gVACA,CACF,EACA,GAAI,EAEJ,SAAA,kBAACA,EAAkB,UAAnB,CAA6B,YAAU,qBAAqB,UAAU,iBACpE,SAAA,kBAAC,EAAD,CAAW,UAAU,aAAe,CAAA,CACT,CAAA,CACP,CAAA,CAE5B"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeBlock.mjs","names":[],"sources":["../../../../src/components/CodeBlock.tsx"],"sourcesContent":["import { fenceGrammarOf, fenceLanguageOf, MERMAID_LANGUAGE } from '../lib/fenceGrammar';\nimport { CopyButton } from './CopyButton';\nimport { MermaidDiagram } from './MermaidDiagram';\nimport { SyntaxText } from './SyntaxText';\n\n/**\n * A fenced code block: coloured, copyable, and a picture when it is mermaid.\n *\n * DESIGN PATTERNS:\n * - The fence's own word picks the grammar, and an unknown word means plain\n * text rather than a guess at the wrong language.\n * - Colour and the diagram both arrive asynchronously, so the block always has\n * the source on screen from the first frame of a streaming reply.\n *\n * AVOID:\n * - Reading the language anywhere but the fence. A block in a message has no\n * path, and guessing from the body colours prose as code.\n */\n\nexport interface CodeBlockProps {\n /** The block's source, without the fence lines. */\n text: string;\n /** The `language-*` class react-markdown puts on the inner <code>. */\n className?: string | undefined;\n}\n\nexport function CodeBlock({ text, className }: CodeBlockProps) {\n const language = fenceLanguageOf(className);\n const body =\n language === MERMAID_LANGUAGE ? (\n <MermaidDiagram code={text} />\n ) : (\n <SyntaxText\n text={text}\n grammar={fenceGrammarOf(language)}\n className=\"overflow-x-auto text-sm leading-relaxed text-doom-text\"\n />\n );\n return (\n <div\n data-slot=\"code-block\"\n data-language={language ?? ''}\n className=\"relative rounded border border-doom-border bg-doom-deep p-2.5\"\n >\n {body}\n <CopyButton text={text} className=\"absolute top-1.5 right-1.5\" />\n </div>\n );\n}\n"],"mappings":"kRA0BA,SAAgB,EAAU,CAAE,OAAM,aAA6B,CAC7D,IAAM,EAAW,EAAgB,CAAS,EACpC,EACJ,IAAA,UACE,kBAAC,EAAD,CAAgB,KAAM,CAAO,CAAA,EAE7B,kBAAC,EAAD,CACQ,OACN,QAAS,EAAe,CAAQ,EAChC,UAAU,wDACX,CAAA,EAEL,MACE,kBAAC,MAAD,CACE,YAAU,aACV,gBAAe,GAAY,GAC3B,UAAU,gEAHZ,SAAA,CAKG,EACD,kBAAC,EAAD,CAAkB,OAAM,UAAU,4BAA8B,CAAA,CAC7D,GAET"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeEditor.d.mts","names":[],"sources":["../../../../src/components/CodeEditor.tsx"],"mappings":";;wBAkBgB,aAAa,cAAc,SAAS,kCAAe,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeEditor.mjs","names":[],"sources":["../../../../src/components/CodeEditor.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\n\nimport { cn } from '../lib/cn';\nimport type { CodeEditorProps } from '../types/editor';\nimport { Skeleton } from './Skeleton';\n\n/**\n * A code editor: line numbers, syntax colour, folding, undo, and a search\n * panel on the usual keys.\n *\n * The editor arrives as its own chunk. The cockpit is one bundle that every\n * session downloads, most of them without ever opening a file, and it is read\n * over a tunnel as often as over localhost; an editor nobody opened has no\n * business in that first load. What this module holds is the boundary, so the\n * cost is paid on the first render that asks for an editor and never again.\n */\nconst CodeEditorView = lazy(async () => ({ default: (await import('./CodeEditorView')).CodeEditorView }));\n\nexport function CodeEditor({ className, ...props }: CodeEditorProps) {\n return (\n <Suspense fallback={<Skeleton className={cn('min-h-0', className)} />}>\n <CodeEditorView className={className} {...props} />\n </Suspense>\n );\n}\n"],"mappings":"gKAgBA,MAAM,EAAiB,EAAK,UAAa,CAAE,SAAU,MAAM,OAAO,wBAAA,CAAqB,cAAe,EAAE,EAExG,SAAgB,EAAW,CAAE,YAAW,GAAG,GAA0B,CACnE,MACE,kBAAC,EAAD,CAAU,SAAU,kBAAC,EAAD,CAAU,UAAW,EAAG,UAAW,CAAS,CAAI,CAAA,EAClE,SAAA,kBAAC,EAAD,CAA2B,YAAW,GAAI,CAAQ,CAAA,CAC1C,CAAA,CAEd"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeEditorView.mjs","names":[],"sources":["../../../../src/components/CodeEditorView.tsx"],"sourcesContent":["import { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands';\nimport {\n bracketMatching,\n foldGutter,\n foldKeymap,\n HighlightStyle,\n indentOnInput,\n syntaxHighlighting,\n} from '@codemirror/language';\nimport { highlightSelectionMatches, search, searchKeymap } from '@codemirror/search';\nimport { Compartment, EditorState, StateEffect, StateField } from '@codemirror/state';\nimport {\n Decoration,\n type DecorationSet,\n drawSelection,\n EditorView,\n highlightActiveLine,\n highlightActiveLineGutter,\n keymap,\n lineNumbers,\n rectangularSelection,\n WidgetType,\n} from '@codemirror/view';\nimport { tags } from '@lezer/highlight';\nimport { useEffect, useImperativeHandle, useLayoutEffect, useRef } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { boundedEditorEdits, boundedEditorRanges } from '../lib/editorController';\nimport { grammarKeyOf, loadGrammar } from '../lib/editorLanguage';\nimport { DOOM_EDITOR_STYLES, DOOM_SYNTAX_STYLES } from '../lib/editorTheme';\nimport type { CodeEditorProps, EditorSelectionRange, EditorViewportRectangle } from '../types/editor';\n\nfunction selectionRange(editor: { readonly state: EditorState }, from: number, to: number): EditorSelectionRange {\n const start = Math.min(from, to);\n const end = Math.max(from, to);\n return {\n text: editor.state.sliceDoc(start, end),\n from: start,\n to: end,\n startLine: editor.state.doc.lineAt(start).number,\n endLine: editor.state.doc.lineAt(end).number,\n };\n}\n\nexport function resolveEditorViewportRegion(\n editor: {\n readonly state: EditorState;\n posAtCoords(coords: { x: number; y: number }): number | null;\n },\n rectangle: EditorViewportRectangle,\n): EditorSelectionRange | null {\n const start = editor.posAtCoords({ x: rectangle.left, y: rectangle.top });\n const end = editor.posAtCoords({ x: rectangle.right, y: rectangle.bottom });\n if (start === null || end === null) return null;\n return selectionRange(editor, start, end);\n}\n/**\n * The editor itself, mounted on a real CodeMirror view.\n *\n * Nothing imports this module directly: `CodeEditor` reaches it through a lazy\n * import so the whole editor, and every grammar under it, stays out of the\n * cockpit's first load. Behaviour lives here rather than in that wrapper so\n * the split costs one file and no indirection.\n *\n * The three things a caller can change after mount each sit in their own\n * compartment. Reconfiguring one is a transaction; rebuilding the editor would\n * throw away the undo history, the scroll position and the cursor, which is\n * what a reader loses if a parent re-render is allowed to remount this.\n */\n\n/** Not a colour or a layout choice: how CodeMirror is told to draw the doom palette. */\nconst DOOM_THEME = EditorView.theme(DOOM_EDITOR_STYLES);\n\nconst DOOM_HIGHLIGHT = HighlightStyle.define([\n { tag: tags.comment, ...DOOM_SYNTAX_STYLES.comment },\n { tag: tags.keyword, ...DOOM_SYNTAX_STYLES.keyword },\n { tag: [tags.atom, tags.bool, tags.null, tags.self], ...DOOM_SYNTAX_STYLES.constant },\n { tag: tags.number, ...DOOM_SYNTAX_STYLES.literal },\n { tag: [tags.string, tags.special(tags.string), tags.character], ...DOOM_SYNTAX_STYLES.string },\n { tag: tags.regexp, ...DOOM_SYNTAX_STYLES.regexp },\n { tag: tags.operator, ...DOOM_SYNTAX_STYLES.operator },\n { tag: tags.punctuation, ...DOOM_SYNTAX_STYLES.punctuation },\n { tag: tags.variableName, ...DOOM_SYNTAX_STYLES.variable },\n { tag: tags.propertyName, ...DOOM_SYNTAX_STYLES.property },\n { tag: [tags.function(tags.variableName), tags.function(tags.propertyName)], ...DOOM_SYNTAX_STYLES.callable },\n { tag: [tags.typeName, tags.className, tags.namespace], ...DOOM_SYNTAX_STYLES.type },\n { tag: tags.tagName, ...DOOM_SYNTAX_STYLES.tag },\n { tag: tags.attributeName, ...DOOM_SYNTAX_STYLES.attribute },\n { tag: [tags.meta, tags.processingInstruction], ...DOOM_SYNTAX_STYLES.meta },\n { tag: tags.heading, ...DOOM_SYNTAX_STYLES.heading },\n { tag: [tags.link, tags.url], ...DOOM_SYNTAX_STYLES.link },\n { tag: tags.emphasis, ...DOOM_SYNTAX_STYLES.emphasis },\n { tag: tags.strong, ...DOOM_SYNTAX_STYLES.strong },\n { tag: tags.strikethrough, ...DOOM_SYNTAX_STYLES.strikethrough },\n { tag: tags.invalid, ...DOOM_SYNTAX_STYLES.invalid },\n]);\n\nconst setClosedDecorations = StateEffect.define<DecorationSet>();\nconst closedDecorations = StateField.define<DecorationSet>({\n create: () => Decoration.none,\n update: (decorations, transaction) => {\n let next = decorations.map(transaction.changes);\n for (const effect of transaction.effects) {\n if (effect.is(setClosedDecorations)) next = effect.value;\n }\n return next;\n },\n provide: (field) => EditorView.decorations.from(field),\n});\n\nconst setMarkedDecorations = StateEffect.define<DecorationSet>();\nconst markedDecorations = StateField.define<DecorationSet>({\n create: () => Decoration.none,\n update: (decorations, transaction) => {\n let next = decorations.map(transaction.changes);\n for (const effect of transaction.effects) {\n if (effect.is(setMarkedDecorations)) next = effect.value;\n }\n return next;\n },\n provide: (field) => EditorView.decorations.from(field),\n});\n\nclass MarkedRangeLabel extends WidgetType {\n constructor(private readonly label: string) {\n super();\n }\n\n eq(other: MarkedRangeLabel): boolean {\n return other.label === this.label;\n }\n\n toDOM(): HTMLElement {\n const label = document.createElement('span');\n label.className = 'cm-marked-region-label';\n label.dataset.authorRegionLabel = this.label;\n label.textContent = this.label;\n return label;\n }\n}\n\nconst MARKED_REGION_THEME = EditorView.baseTheme({\n '.cm-marked-region': {\n backgroundColor: 'var(--doom-tint-yellow)',\n borderBottom: '1px solid var(--doom-edge-yellow)',\n },\n '.cm-marked-region-label': {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: '16px',\n height: '16px',\n marginRight: '4px',\n borderRadius: '999px',\n backgroundColor: 'var(--doom-yellow)',\n color: 'var(--doom-deep)',\n fontSize: '9px',\n fontWeight: '700',\n lineHeight: '1',\n verticalAlign: 'text-bottom',\n },\n});\n\n/** Everything that never changes for the life of an editor. */\nconst FIXED_EXTENSIONS = [\n lineNumbers(),\n highlightActiveLineGutter(),\n foldGutter(),\n highlightActiveLine(),\n drawSelection(),\n rectangularSelection(),\n indentOnInput(),\n bracketMatching(),\n history(),\n search({ top: true }),\n highlightSelectionMatches(),\n // Tab indents rather than leaving the editor. That trades a keyboard user's\n // escape route for the behaviour every other editor has, so it is last in\n // the keymap and Escape then Tab still moves focus out.\n keymap.of([...defaultKeymap, ...historyKeymap, ...searchKeymap, ...foldKeymap, indentWithTab]),\n syntaxHighlighting(DOOM_HIGHLIGHT),\n closedDecorations,\n markedDecorations,\n MARKED_REGION_THEME,\n DOOM_THEME,\n];\n\nexport function CodeEditorView({\n value,\n path,\n readOnly = false,\n lineWrapping = true,\n className,\n onChange,\n onSelect,\n controllerRef,\n 'data-testid': testId,\n}: CodeEditorProps) {\n const host = useRef<HTMLDivElement>(null);\n const view = useRef<EditorView | null>(null);\n // The callbacks are new objects on every parent render. Reading them through\n // a ref is what lets the editor be built once and still call the current\n // pair, rather than being rebuilt whenever the parent re-renders.\n const handlers = useRef({ onChange, onSelect });\n // The document is seeded once from the value of the first render; the sync effect\n // below owns every later change.\n const initialValue = useRef(value);\n const compartments = useRef({\n language: new Compartment(),\n readOnly: new Compartment(),\n wrapping: new Compartment(),\n });\n\n useEffect(() => {\n handlers.current = { onChange, onSelect };\n });\n\n useLayoutEffect(() => {\n const parent = host.current;\n if (parent === null) return;\n const { language, readOnly: readOnlyPart, wrapping } = compartments.current;\n const editor = new EditorView({\n parent,\n state: EditorState.create({\n // The initial document only; every later change arrives as a\n // transaction from the effect below.\n doc: initialValue.current,\n extensions: [\n ...FIXED_EXTENSIONS,\n language.of([]),\n readOnlyPart.of([]),\n wrapping.of([]),\n EditorView.updateListener.of((update) => {\n if (update.docChanged) handlers.current.onChange?.(update.state.doc.toString());\n if (!update.selectionSet && !update.docChanged) return;\n const report = handlers.current.onSelect;\n if (report === undefined) return;\n const range = update.state.selection.main;\n report(selectionRange(update.view, range.from, range.to));\n }),\n ],\n }),\n });\n view.current = editor;\n return () => {\n editor.destroy();\n view.current = null;\n };\n // Built once.\n }, []);\n\n useImperativeHandle(\n controllerRef,\n () => ({\n focus: () => view.current?.focus(),\n revealAndSelect: (range) => {\n const editor = view.current;\n if (editor === null) return;\n const [bounded] = boundedEditorRanges(editor.state.doc.length, [range]);\n if (bounded === undefined) return;\n editor.dispatch({\n selection: { anchor: bounded.from, head: bounded.to },\n effects: EditorView.scrollIntoView(bounded.from, { y: 'center' }),\n });\n },\n applyEdits: (edits) => {\n const editor = view.current;\n if (editor === null || edits.length === 0) return;\n editor.dispatch({ changes: boundedEditorEdits(editor.state.doc.length, edits) });\n },\n setClosedRanges: (ranges) => {\n const editor = view.current;\n if (editor === null) return;\n const bounded = boundedEditorRanges(editor.state.doc.length, ranges);\n const decorations = bounded.map((range) =>\n range.from === range.to\n ? Decoration.line({ attributes: { class: 'cm-closed-tone', 'data-tone': 'closed' } }).range(\n editor.state.doc.lineAt(range.from).from,\n )\n : Decoration.mark({ class: 'cm-closed-tone', attributes: { 'data-tone': 'closed' } }).range(\n range.from,\n range.to,\n ),\n );\n editor.dispatch({ effects: setClosedDecorations.of(Decoration.set(decorations)) });\n },\n setMarkedRanges: (ranges) => {\n const editor = view.current;\n if (editor === null) return;\n const decorations = ranges.flatMap((range) => {\n const [bounded] = boundedEditorRanges(editor.state.doc.length, [range]);\n if (bounded === undefined || bounded.from === bounded.to) return [];\n return [\n Decoration.widget({ widget: new MarkedRangeLabel(range.label), side: -1 }).range(bounded.from),\n Decoration.mark({\n class: 'cm-marked-region',\n attributes: { 'data-author-region': range.label },\n }).range(bounded.from, bounded.to),\n ];\n });\n editor.dispatch({ effects: setMarkedDecorations.of(Decoration.set(decorations, true)) });\n },\n resolveViewportRegion: (rectangle) => {\n const editor = view.current;\n return editor === null ? null : resolveEditorViewportRegion(editor, rectangle);\n },\n }),\n [],\n );\n\n useEffect(() => {\n const editor = view.current;\n // A caller that echoes onChange back into `value` would otherwise replace\n // the document on every keystroke and drop the cursor to the end.\n if (editor === null || editor.state.doc.toString() === value) return;\n editor.dispatch({ changes: { from: 0, to: editor.state.doc.length, insert: value } });\n }, [value]);\n\n useEffect(() => {\n view.current?.dispatch({\n effects: compartments.current.readOnly.reconfigure([\n EditorState.readOnly.of(readOnly),\n EditorView.editable.of(!readOnly),\n ]),\n });\n }, [readOnly]);\n\n useEffect(() => {\n view.current?.dispatch({\n effects: compartments.current.wrapping.reconfigure(lineWrapping ? EditorView.lineWrapping : []),\n });\n }, [lineWrapping]);\n\n useEffect(() => {\n const key = path === undefined ? undefined : grammarKeyOf(path);\n const { language } = compartments.current;\n if (key === undefined) {\n view.current?.dispatch({ effects: language.reconfigure([]) });\n return;\n }\n let cancelled = false;\n void loadGrammar(key)\n .then((grammar) => {\n if (!cancelled) view.current?.dispatch({ effects: language.reconfigure(grammar) });\n })\n .catch(() => {\n // A grammar is a separate chunk over the network, and the cockpit is\n // often read through a tunnel. Losing it costs syntax colour, not the\n // file, so fall back to plain text rather than failing the pane.\n if (!cancelled) view.current?.dispatch({ effects: language.reconfigure([]) });\n });\n return () => {\n cancelled = true;\n };\n }, [path]);\n\n return <div ref={host} data-testid={testId} className={cn('min-h-0 overflow-hidden', className)} />;\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collapsible.d.mts","names":[],"sources":["../../../../src/components/Collapsible.tsx"],"mappings":";;;;iBAMgB,cAAY,OAAO,sBAAsB,YAAqB,wBAAK,IAAA;wBAInE,mBAAmB,OAAO,sBAAsB,YAAqB,sCAAmB,IAAA;wBAIxF,qBACd,cACG,SACF,sBAAsB,YAAqB,sCAAmB,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collapsible.mjs","names":["Collapsible","CollapsiblePrimitive"],"sources":["../../../../src/components/Collapsible.tsx"],"sourcesContent":["import { Collapsible as CollapsiblePrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A section that folds; Radix keeps the trigger's aria-expanded in step with the content. */\nexport function Collapsible(props: ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nexport function CollapsibleTrigger(props: ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return <CollapsiblePrimitive.CollapsibleTrigger data-slot=\"collapsible-trigger\" {...props} />;\n}\n\nexport function CollapsibleContent({\n className,\n ...props\n}: ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return (\n <CollapsiblePrimitive.CollapsibleContent\n data-slot=\"collapsible-content\"\n className={cn('overflow-hidden', className)}\n {...props}\n />\n );\n}\n"],"mappings":"kHAMA,SAAgBA,EAAY,EAAyD,CACnF,MAAO,kBAACC,EAAqB,KAAtB,CAA2B,YAAU,cAAc,GAAI,CAAQ,CAAA,CACxE,CAEA,SAAgB,EAAmB,EAAuE,CACxG,MAAO,kBAACA,EAAqB,mBAAtB,CAAyC,YAAU,sBAAsB,GAAI,CAAQ,CAAA,CAC9F,CAEA,SAAgB,EAAmB,CACjC,YACA,GAAG,GAC8D,CACjE,MACE,kBAACA,EAAqB,mBAAtB,CACE,YAAU,sBACV,UAAW,EAAG,kBAAmB,CAAS,EAC1C,GAAI,CACL,CAAA,CAEL"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Command.d.mts","names":[],"sources":["../../../../src/components/Command.tsx"],"mappings":";;;;;;;;;;;;;;iBAiBiB,2BAA2B,KAAK;EAC/C;EACA,eAAe;;EAEf,OAAO;EACP;;wBAGc,gBACd,MACA,cACA,OACA,cACA,WACA,UACA,UACG,SACF,qCAAkB,IAAA;;wBAYL,gBAAgB,cAAc,SAAS,wCAAqB,IAAA;;wBAW5D,eAAe,cAAc,SAAS,6BAAU,IAAA;;wBAchD,cAAc,cAAc,SAAS,wCAAqB,IAAA;;wBAY1D,eAAe,cAAc,SAAS,wCAAqB,IAAA;wBAI3D,oBAAoB,cAAc,SAAS,wCAAqB,IAAA;;wBAWhE,cAAc,YAAwB,SAAS,iCAAc,IAAA;;wBAK7D,iBAAiB,OAAO,yCAAsB,IAAA;;wBAK9C,eAAe,cAAc,SAAS,wCAAqB,IAAA;;wBAW3D,gBAAgB,cAAc,SAAS,wCAAqB,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Command.mjs","names":[],"sources":["../../../../src/components/Command.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Dialog, DialogContent, type DialogContentProps, DialogTitle } from './Dialog';\nimport { Input, type InputProps } from './Input';\nimport { OptionLabel, OptionRow, type OptionRowProps } from './OptionList';\n\n/**\n * The command palette's frame, its search strip, its rows, and its hint.\n *\n * It has no Radix counterpart and it deliberately does no filtering: the\n * surface that opens a palette already knows how to rank its own commands,\n * and a matcher baked in here would be a second, worse one. Built on Dialog,\n * Input, and the option row so a palette and a select popover cannot drift\n * apart, rather than on a new dependency.\n */\n\nexport interface CommandDialogProps extends Omit<DialogContentProps, 'title'> {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Names the dialog for assistive tech; visually hidden unless the palette draws its own heading. */\n title: ReactNode;\n titleVisible?: boolean;\n}\n\nexport function CommandDialog({\n open,\n onOpenChange,\n title,\n titleVisible = false,\n className,\n children,\n width = 'lg',\n ...props\n}: CommandDialogProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent data-slot=\"command-dialog\" width={width} className={cn('max-h-[70vh]', className)} {...props}>\n <DialogTitle className={titleVisible ? undefined : 'sr-only'}>{title}</DialogTitle>\n {children}\n </DialogContent>\n </Dialog>\n );\n}\n\n/** The strip the search field sits in. */\nexport function CommandHeader({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"command-header\"\n className={cn('flex shrink-0 items-center gap-2 border-b border-doom-border px-3 py-2.5', className)}\n {...props}\n />\n );\n}\n\n/** The search field: bare, because the header already draws the surface. */\nexport function CommandInput({ className, ...props }: InputProps) {\n return (\n <Input\n data-slot=\"command-input\"\n variant=\"bare\"\n autoFocus\n autoComplete=\"off\"\n className={cn('flex-1', className)}\n {...props}\n />\n );\n}\n\n/** The scrolling body. It is the listbox, so its rows are the options. */\nexport function CommandList({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n role=\"listbox\"\n data-slot=\"command-list\"\n className={cn('flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto p-1.5', className)}\n {...props}\n />\n );\n}\n\n/** A labelled run of rows. */\nexport function CommandGroup({ className, ...props }: ComponentProps<'div'>) {\n return <div data-slot=\"command-group\" className={cn('flex flex-col gap-0.5', className)} {...props} />;\n}\n\nexport function CommandGroupLabel({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"command-group-label\"\n className={cn('px-2 pt-2 pb-1 text-2xs font-bold tracking-wider text-doom-faint uppercase', className)}\n {...props}\n />\n );\n}\n\n/** One command. Compact by default, since a palette shows many at once. */\nexport function CommandItem({ density = 'compact', ...props }: OptionRowProps) {\n return <OptionRow data-slot=\"command-item\" density={density} {...props} />;\n}\n\n/** A command's name, taking the width the row has left. */\nexport function CommandItemLabel(props: ComponentProps<'span'>) {\n return <OptionLabel data-slot=\"command-item-label\" density=\"compact\" {...props} />;\n}\n\n/** What the palette says when nothing matches. */\nexport function CommandEmpty({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"command-empty\"\n className={cn('px-2 py-6 text-center text-sm text-doom-faint', className)}\n {...props}\n />\n );\n}\n\n/** The hint strip along the bottom: what the keys do. */\nexport function CommandFooter({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"command-footer\"\n className={cn(\n 'flex min-h-[30px] shrink-0 items-center justify-between gap-3 border-t border-doom-border-soft bg-doom-deep px-3 text-2xs text-doom-faint',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"iQAyBA,SAAgB,EAAc,CAC5B,OACA,eACA,QACA,eAAe,GACf,YACA,WACA,QAAQ,KACR,GAAG,GACkB,CACrB,MACE,kBAAC,EAAD,CAAc,OAAoB,eAChC,SAAA,kBAAC,EAAD,CAAe,YAAU,iBAAwB,QAAO,UAAW,EAAG,eAAgB,CAAS,EAAG,GAAI,EAAtG,SAAA,CACE,kBAAC,EAAD,CAAa,UAAW,EAAe,IAAA,GAAY,UAAY,SAAA,CAAmB,CAAA,EACjF,CACY,GACT,CAAA,CAEZ,CAGA,SAAgB,EAAc,CAAE,YAAW,GAAG,GAAgC,CAC5E,MACE,kBAAC,MAAD,CACE,YAAU,iBACV,UAAW,EAAG,2EAA4E,CAAS,EACnG,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAa,CAAE,YAAW,GAAG,GAAqB,CAChE,MACE,kBAAC,EAAD,CACE,YAAU,gBACV,QAAQ,OACR,UAAA,GACA,aAAa,MACb,UAAW,EAAG,SAAU,CAAS,EACjC,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAgC,CAC1E,MACE,kBAAC,MAAD,CACE,KAAK,UACL,YAAU,eACV,UAAW,EAAG,6DAA8D,CAAS,EACrF,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAa,CAAE,YAAW,GAAG,GAAgC,CAC3E,MAAO,kBAAC,MAAD,CAAK,YAAU,gBAAgB,UAAW,EAAG,wBAAyB,CAAS,EAAG,GAAI,CAAQ,CAAA,CACvG,CAEA,SAAgB,EAAkB,CAAE,YAAW,GAAG,GAAgC,CAChF,MACE,kBAAC,MAAD,CACE,YAAU,sBACV,UAAW,EAAG,6EAA8E,CAAS,EACrG,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAY,CAAE,UAAU,UAAW,GAAG,GAAyB,CAC7E,MAAO,kBAAC,EAAD,CAAW,YAAU,eAAwB,UAAS,GAAI,CAAQ,CAAA,CAC3E,CAGA,SAAgB,EAAiB,EAA+B,CAC9D,MAAO,kBAAC,EAAD,CAAa,YAAU,qBAAqB,QAAQ,UAAU,GAAI,CAAQ,CAAA,CACnF,CAGA,SAAgB,EAAa,CAAE,YAAW,GAAG,GAAgC,CAC3E,MACE,kBAAC,MAAD,CACE,YAAU,gBACV,UAAW,EAAG,gDAAiD,CAAS,EACxE,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAc,CAAE,YAAW,GAAG,GAAgC,CAC5E,MACE,kBAAC,MAAD,CACE,YAAU,iBACV,UAAW,EACT,4IACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyButton.mjs","names":[],"sources":["../../../../src/components/CopyButton.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\n\nimport { CheckIcon, CopyIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\n\n/**\n * Puts a piece of text on the clipboard and says so.\n *\n * DESIGN PATTERNS:\n * - Always visible, dimmed. Half the cockpit's surfaces are touched rather\n * than pointed at, and a control revealed by hover does not exist there.\n * - A refused clipboard is a state, not a crash: the label says the browser\n * blocked it and the text is still there to select by hand.\n */\n\n/** How long the control stays acknowledged before returning to its icon. */\nconst FEEDBACK_MS = 1500;\n\ntype CopyState = 'idle' | 'copied' | 'failed';\n\nconst LABELS: Readonly<Record<CopyState, string>> = {\n idle: 'copy',\n copied: 'copied',\n failed: 'copying was blocked by the browser',\n};\n\nexport interface CopyButtonProps {\n /** What lands on the clipboard. */\n text: string;\n className?: string | undefined;\n}\n\nexport function CopyButton({ text, className }: CopyButtonProps) {\n const [state, setState] = useState<CopyState>('idle');\n\n useEffect(() => {\n if (state === 'idle') return;\n const timer = setTimeout(() => setState('idle'), FEEDBACK_MS);\n return () => clearTimeout(timer);\n }, [state]);\n\n const copy = useCallback(() => {\n void navigator.clipboard.writeText(text).then(\n () => setState('copied'),\n () => setState('failed'),\n );\n }, [text]);\n\n const label = LABELS[state];\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"copy-button\"\n data-state={state}\n title={label}\n aria-label={label}\n onClick={copy}\n className={cn('opacity-60 hover:opacity-100', className)}\n >\n {state === 'copied' ? <CheckIcon className=\"size-3 text-doom-green\" /> : <CopyIcon className=\"size-3\" />}\n </Button>\n );\n}\n"],"mappings":"+OAiBA,MAIM,EAA8C,CAClD,KAAM,OACN,OAAQ,SACR,OAAQ,oCACV,EAQA,SAAgB,EAAW,CAAE,OAAM,aAA8B,CAC/D,GAAM,CAAC,EAAO,GAAY,EAAoB,MAAM,EAEpD,MAAgB,CACd,GAAI,IAAU,OAAQ,OACtB,IAAM,EAAQ,eAAiB,EAAS,MAAM,EAAG,IAAW,EAC5D,UAAa,aAAa,CAAK,CACjC,EAAG,CAAC,CAAK,CAAC,EAEV,IAAM,EAAO,MAAkB,CAC7B,UAAe,UAAU,UAAU,CAAI,CAAC,CAAC,SACjC,EAAS,QAAQ,MACjB,EAAS,QAAQ,CACzB,CACF,EAAG,CAAC,CAAI,CAAC,EAEH,EAAQ,EAAO,GACrB,MACE,kBAAC,EAAD,CACE,KAAK,SACL,QAAQ,QACR,KAAK,OACL,cAAY,cACZ,aAAY,EACZ,MAAO,EACP,aAAY,EACZ,QAAS,EACT,UAAW,EAAG,+BAAgC,CAAS,EAEtD,SAAA,IAAU,SAAW,kBAAC,EAAD,CAAW,UAAU,wBAA0B,CAAA,EAAI,kBAAC,EAAD,CAAU,UAAU,QAAU,CAAA,CACjG,CAAA,CAEZ"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dialog.d.mts","names":[],"sources":["../../../../src/components/Dialog.tsx"],"mappings":";;;;;;;;iBAagB,SAAO,OAAO,sBAAsB,OAAgB,wBAAK,IAAA;wBASzD,cAAc,OAAO,sBAAsB,OAAgB,2BAAQ,IAAA;wBAQnE,YAAY,OAAO,sBAAsB,OAAgB,yBAAM,IAAA;iBA+B9D,2BAA2B,sBAAsB,OAAgB;;EAEhF;;wBAKc,gBAAgB,WAAW,UAAU,UAAiB,SAAS,qCAAkB,IAAA;iBAmBhF,0BAA0B;;;;;;;EAOzC;;EAEA;;wBAGc,eACd,WACA,aACA,YACA,aACG,SACF,oCAAiB,IAAA;wBAsBJ,cAAc,cAAc,SAAS,sBAAsB,OAAgB,yBAAM,IAAA;wBAUjF,oBAAoB,cAAc,SAAS,sBAAsB,OAAgB,+BAAY,IAAA;wBAU7F,aAAa,cAAc,SAAS,wCAAqB,IAAA;qBAU5D,uBAAoB;;6CAc/B;iBAEe,0BAA0B,uBAAuB,oBAAoB;wBAEtE,eAAe,WAAW,YAAY,SAAS,oCAAiB,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dialog.mjs","names":["Dialog","DialogPrimitive"],"sources":["../../../../src/components/Dialog.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport { createContext, type ComponentProps, useContext } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\n\nconst DialogOpenChangeContext = createContext<((open: boolean) => void) | undefined>(undefined);\n/**\n * shadcn's Dialog on Radix: focus trap, Escape, outside click, scroll lock,\n * and focus restored to the trigger on close. The frame is the Doom panel.\n */\nexport function Dialog(props: ComponentProps<typeof DialogPrimitive.Root>) {\n const onOpenChange = props.onOpenChange === undefined ? undefined : (open: boolean) => props.onOpenChange?.(open);\n return (\n <DialogOpenChangeContext.Provider value={onOpenChange}>\n <DialogPrimitive.Root data-slot=\"dialog\" {...props} onOpenChange={onOpenChange} />\n </DialogOpenChangeContext.Provider>\n );\n}\n\nexport function DialogTrigger(props: ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nexport function DialogPortal(props: ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nexport function DialogClose(props: ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nexport function DialogOverlay({\n className,\n onPointerDownCapture,\n ...props\n}: ComponentProps<typeof DialogPrimitive.Overlay>) {\n const onOpenChange = useContext(DialogOpenChangeContext);\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn('fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade', className)}\n onPointerDownCapture={(event) => {\n onPointerDownCapture?.(event);\n if (event.defaultPrevented || onOpenChange === undefined) return;\n const dialogContent = event.currentTarget.nextElementSibling;\n const openSelectTrigger = dialogContent?.querySelector('[data-slot=\"select-trigger\"][data-state=\"open\"]');\n if (openSelectTrigger === null || openSelectTrigger === undefined) return;\n\n // Radix's parent outside listener can lag one render behind a nested\n // modal Select. Own this backdrop press so the complete stack closes.\n event.stopPropagation();\n onOpenChange(false);\n }}\n {...props}\n />\n );\n}\n\nexport interface DialogContentProps extends ComponentProps<typeof DialogPrimitive.Content> {\n /** Width preset; `className` may still override. */\n width?: 'sm' | 'md' | 'lg';\n}\n\nconst CONTENT_WIDTH = { sm: 'w-[360px]', md: 'w-[480px]', lg: 'w-[620px]' } as const;\n\nexport function DialogContent({ className, children, width = 'md', ...props }: DialogContentProps) {\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n 'fixed top-1/2 left-1/2 z-50 flex max-h-[calc(100dvh-24px)] max-w-[calc(100vw-24px)] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-lg border border-doom-border bg-doom-panel font-mono shadow-2xl outline-none data-[state=open]:animate-doom-pop',\n CONTENT_WIDTH[width],\n className,\n )}\n {...props}\n >\n {children}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nexport interface DialogHeaderProps extends ComponentProps<'div'> {\n /**\n * Show the close control at the right of the strip. Off by default: most\n * headers already put something there (a spinner, a method label) and every\n * dialog closes on Escape, so an X that fights the existing content is worse\n * than none. Turn it on for a dialog whose only way out is the mouse.\n */\n dismissible?: boolean;\n /** What the close control announces. */\n closeLabel?: string;\n}\n\nexport function DialogHeader({\n className,\n dismissible = false,\n closeLabel = 'close',\n children,\n ...props\n}: DialogHeaderProps) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\n 'flex min-w-0 items-center justify-between gap-3 border-b border-doom-border px-3 py-3 sm:px-4',\n className,\n )}\n {...props}\n >\n {children}\n {dismissible ? (\n <DialogPrimitive.Close asChild>\n <Button variant=\"ghost\" size=\"icon\" aria-label={closeLabel} className=\"text-doom-faint hover:text-doom-hi\">\n <CloseIcon className=\"h-3 w-3\" />\n </Button>\n </DialogPrimitive.Close>\n ) : null}\n </div>\n );\n}\n\nexport function DialogTitle({ className, ...props }: ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn('text-sm font-bold tracking-wide text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function DialogDescription({ className, ...props }: ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function DialogBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"dialog-body\"\n className={cn('flex min-h-0 flex-col gap-3 overflow-y-auto px-3 py-3 sm:px-4 sm:py-4', className)}\n {...props}\n />\n );\n}\n\nexport const dialogFooterVariants = cva('flex shrink-0 items-center gap-2', {\n variants: {\n variant: {\n /** Buttons alone, sitting inside the body's padding. */\n plain: 'justify-end',\n /**\n * The full-width strip: a hint on the left, the buttons on the right,\n * recessed and ruled off from the body. The same shape PopoverFooter\n * draws, because a dialog and a popover promise their keys the same way.\n */\n bar: 'min-h-[34px] flex-wrap justify-between border-t border-doom-border-soft bg-doom-deep px-3 py-1.5 sm:flex-nowrap sm:px-4 sm:py-0',\n },\n },\n defaultVariants: { variant: 'plain' },\n});\n\nexport interface DialogFooterProps extends ComponentProps<'div'>, VariantProps<typeof dialogFooterVariants> {}\n\nexport function DialogFooter({ className, variant, ...props }: DialogFooterProps) {\n return <div data-slot=\"dialog-footer\" className={cn(dialogFooterVariants({ variant }), className)} {...props} />;\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dot.d.mts","names":[],"sources":["../../../../src/components/Dot.tsx"],"mappings":";;;;qBAMa,cAAW;;;;6CA2BtB;YAEU,UAAU;iBAEL,iBAAiB,wBAAwB,oBAAoB;;wBAG9D,MAAM,WAAW,MAAM,MAAM,UAAU,SAAS,2BAAQ,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dot.mjs","names":[],"sources":["../../../../src/components/Dot.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport type { DotTone as Tone } from '../types/tone';\n\nexport const dotVariants = cva('inline-block shrink-0 rounded-full', {\n variants: {\n tone: {\n neutral: 'bg-doom-faint',\n muted: 'bg-doom-faint/40',\n blue: 'bg-doom-blue',\n green: 'bg-doom-green',\n yellow: 'bg-doom-yellow',\n red: 'bg-doom-red',\n magenta: 'bg-doom-magenta',\n violet: 'bg-doom-violet',\n cyan: 'bg-doom-cyan',\n orange: 'bg-doom-orange',\n teal: 'bg-doom-teal',\n } satisfies Record<Tone, string>,\n size: {\n xs: 'h-1 w-1',\n sm: 'h-1.5 w-1.5',\n md: 'h-2 w-2',\n lg: 'h-2.5 w-2.5',\n },\n pulse: {\n true: 'animate-pulse',\n false: '',\n },\n },\n defaultVariants: { tone: 'neutral', size: 'sm', pulse: false },\n});\n\nexport type DotTone = Tone;\n\nexport interface DotProps extends ComponentProps<'span'>, VariantProps<typeof dotVariants> {}\n\n/** The status dot: a colour and, while something is live, a pulse. */\nexport function Dot({ className, tone, size, pulse, ...props }: DotProps) {\n return <span data-slot=\"dot\" aria-hidden className={cn(dotVariants({ tone, size, pulse }), className)} {...props} />;\n}\n"],"mappings":"0HAMA,MAAa,EAAc,EAAI,qCAAsC,CACnE,SAAU,CACR,KAAM,CACJ,QAAS,gBACT,MAAO,mBACP,KAAM,eACN,MAAO,gBACP,OAAQ,iBACR,IAAK,cACL,QAAS,kBACT,OAAQ,iBACR,KAAM,eACN,OAAQ,iBACR,KAAM,cACR,EACA,KAAM,CACJ,GAAI,UACJ,GAAI,cACJ,GAAI,UACJ,GAAI,aACN,EACA,MAAO,CACL,KAAM,gBACN,MAAO,EACT,CACF,EACA,gBAAiB,CAAE,KAAM,UAAW,KAAM,KAAM,MAAO,EAAM,CAC/D,CAAC,EAOD,SAAgB,EAAI,CAAE,YAAW,OAAM,OAAM,QAAO,GAAG,GAAmB,CACxE,MAAO,kBAAC,OAAD,CAAM,YAAU,MAAM,cAAA,GAAY,UAAW,EAAG,EAAY,CAAE,OAAM,OAAM,OAAM,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CACrH"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.d.mts","names":[],"sources":["../../../../src/components/Drawer.tsx"],"mappings":";;iBAMiB;EACf;EACA,eAAe;EACf;EACA;EACA,UAAU;EACV;EACA;EACA;EACA;;;wBAIc,SACd,MACA,cACA,MACA,OACA,UACA,WACA,2BACe,QACf,kBACC,8BAAW,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.mjs","names":["Dialog","DialogPrimitive"],"sources":["../../../../src/components/Drawer.tsx"],"sourcesContent":["import { Dialog as DialogPrimitive } from 'radix-ui';\nimport { type ReactNode, useRef } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Dialog, DialogHeader, DialogOverlay, DialogPortal, DialogTitle } from './Dialog';\n\nexport interface DrawerProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n side: 'left' | 'right';\n title: string;\n children: ReactNode;\n className?: string;\n showHeader?: boolean;\n 'data-testid'?: string;\n backdropTestId?: string;\n}\n\n/** A controlled side panel with a focus trap and restoration for external header buttons. */\nexport function Drawer({\n open,\n onOpenChange,\n side,\n title,\n children,\n className,\n showHeader = true,\n 'data-testid': testId,\n backdropTestId,\n}: DrawerProps) {\n const opener = useRef<HTMLElement | null>(null);\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogPortal>\n <DialogOverlay data-testid={backdropTestId} />\n <DialogPrimitive.Content\n aria-describedby={undefined}\n data-testid={testId}\n className={cn(\n 'fixed inset-y-0 z-50 flex w-[min(300px,calc(100vw-48px))] flex-col overflow-y-auto border-doom-border bg-doom-rail outline-none',\n side === 'left' ? 'left-0 border-r' : 'right-0 border-l',\n className,\n )}\n onOpenAutoFocus={() => {\n opener.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n }}\n onCloseAutoFocus={(event) => {\n event.preventDefault();\n if (opener.current?.isConnected) opener.current.focus();\n }}\n >\n {showHeader ? (\n <DialogHeader dismissible closeLabel={`hide ${title.toLowerCase()}`}>\n <DialogTitle>{title}</DialogTitle>\n </DialogHeader>\n ) : (\n <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n )}\n {children}\n </DialogPrimitive.Content>\n </DialogPortal>\n </Dialog>\n );\n}\n"],"mappings":"oQAmBA,SAAgB,EAAO,CACrB,OACA,eACA,OACA,QACA,WACA,YACA,aAAa,GACb,cAAe,EACf,kBACc,CACd,IAAM,EAAS,EAA2B,IAAI,EAC9C,MACE,kBAACA,EAAD,CAAc,OAAoB,eAChC,SAAA,kBAAC,EAAD,CAAA,SAAA,CACE,kBAAC,EAAD,CAAe,cAAa,CAAiB,CAAA,EAC7C,kBAACC,EAAgB,QAAjB,CACE,mBAAkB,IAAA,GAClB,cAAa,EACb,UAAW,EACT,kIACA,IAAS,OAAS,kBAAoB,mBACtC,CACF,EACA,oBAAuB,CACrB,EAAO,QAAU,SAAS,yBAAyB,YAAc,SAAS,cAAgB,IAC5F,EACA,iBAAmB,GAAU,CAC3B,EAAM,eAAe,EACjB,EAAO,SAAS,aAAa,EAAO,QAAQ,MAAM,CACxD,EAdF,SAAA,CAgBG,EACC,kBAAC,EAAD,CAAc,YAAA,GAAY,WAAY,QAAQ,EAAM,YAAY,IAC9D,SAAA,kBAAC,EAAD,CAAA,SAAc,CAAmB,CAAA,CACrB,CAAA,EAEd,kBAAC,EAAD,CAAa,UAAU,UAAW,SAAA,CAAmB,CAAA,EAEtD,CACsB,CACb,CAAA,CAAA,CAAA,CAAA,CACR,CAAA,CAEZ"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropdownMenu.d.mts","names":[],"sources":["../../../../src/components/DropdownMenu.tsx"],"mappings":";;;;;iBAQgB,eAAa,OAAO,sBAAsB,aAAsB,wBAAK,IAAA;wBAIrE,oBAAoB,OAAO,sBAAsB,aAAsB,2BAAQ,IAAA;;wBAK/E,kBAAkB,OAAO,sBAAsB,aAAsB,yBAAM,IAAA;wBAQ3E,sBACd,WACA,OACA,eACG,SACF,sBAAsB,aAAsB,2BAAQ,IAAA;qBAc1C,2BAAwB;;;6CAapC;iBAEgB,8BACP,sBAAsB,aAAsB,OAAO,oBAAoB;wBAEjE,mBAAmB,WAAW,SAAS,aAAa,SAAS,wCAAqB,IAAA;iBAoBjF,sCACP,sBAAsB,aAAsB,eAAe,oBAAoB;;wBAGzE,2BAA2B,WAAW,SAAS,aAAa,SAAS,gDAA6B,IAAA;;wBAgBlG,uBAAuB,OAAO,sBAAsB,aAAsB,8BAAW,IAAA;iBAIpF,mCACP,sBAAsB,aAAsB,YAAY,oBAAoB;wBAEtE,wBAAwB,WAAW,SAAS,aAAa,SAAS,6CAA0B,IAAA;wBAe5F,gBAAgB,OAAO,sBAAsB,aAAsB,uBAAI,IAAA;;wBAKvE,yBACd,WACA,aACG,SACF,sBAAsB,aAAsB,8BAAW,IAAA;wBAa1C,yBACd,WACA,eACG,SACF,sBAAsB,aAAsB,8BAAW,IAAA;wBAa1C,oBAAoB,cAAc,SAAS,sBAAsB,aAAsB,yBAAM,IAAA;;wBAW7F,uBAAuB,cAAc,SAAS,yCAAsB,IAAA;wBAUpE,wBAAwB,cAAc,SAAS,sBAAsB,aAAsB,6BAAU,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropdownMenu.mjs","names":["DropdownMenu","DropdownMenuPrimitive"],"sources":["../../../../src/components/DropdownMenu.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { CheckIcon, ChevronRightIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\n\n/** shadcn's DropdownMenu on Radix: roving focus, typeahead, outside click, Escape. */\nexport function DropdownMenu(props: ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nexport function DropdownMenuTrigger(props: ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\n/** A run of items under one label, so the separator between groups is structural. */\nexport function DropdownMenuGroup(props: ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\n/** The surface every menu and submenu wears. */\nconst CONTENT_CLASS =\n 'z-50 flex min-w-[120px] flex-col overflow-hidden rounded border border-doom-border bg-doom-panel py-1 font-mono shadow-xl outline-none data-[state=open]:animate-doom-rise';\n\nexport function DropdownMenuContent({\n className,\n align = 'end',\n sideOffset = 4,\n ...props\n}: ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(CONTENT_CLASS, className)}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nexport const dropdownMenuItemVariants = cva(\n 'flex w-full cursor-pointer items-center gap-2 px-2.5 py-1.5 text-left text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-40 data-[highlighted]:bg-doom-deep',\n {\n variants: {\n variant: {\n default: 'text-doom-hi',\n destructive: 'text-doom-red',\n },\n /** A row that carries a check or bullet keeps a gutter for it, so labels line up whether or not one is set. */\n indented: { true: 'pl-7', false: '' },\n },\n defaultVariants: { variant: 'default', indented: false },\n },\n);\n\nexport interface DropdownMenuItemProps\n extends ComponentProps<typeof DropdownMenuPrimitive.Item>, VariantProps<typeof dropdownMenuItemVariants> {}\n\nexport function DropdownMenuItem({ className, variant, indented, ...props }: DropdownMenuItemProps) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-variant={variant ?? 'default'}\n className={cn(dropdownMenuItemVariants({ variant, indented }), className)}\n {...props}\n />\n );\n}\n\n/** The check or bullet a selectable row shows when it is set; it sits in the row's gutter. */\nfunction ItemIndicator({ children }: { children: ReactNode }) {\n return (\n <span className=\"pointer-events-none absolute left-2.5 flex h-3 w-3 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>{children}</DropdownMenuPrimitive.ItemIndicator>\n </span>\n );\n}\n\nexport interface DropdownMenuCheckboxItemProps\n extends ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>, VariantProps<typeof dropdownMenuItemVariants> {}\n\n/** A row that toggles: the check lives in the gutter so the label never shifts. */\nexport function DropdownMenuCheckboxItem({ className, variant, children, ...props }: DropdownMenuCheckboxItemProps) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn('relative', dropdownMenuItemVariants({ variant, indented: true }), className)}\n {...props}\n >\n <ItemIndicator>\n <CheckIcon className=\"h-3 w-3 text-doom-blue\" />\n </ItemIndicator>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\n/** The exclusive-choice group; pair it with DropdownMenuRadioItem. */\nexport function DropdownMenuRadioGroup(props: ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nexport interface DropdownMenuRadioItemProps\n extends ComponentProps<typeof DropdownMenuPrimitive.RadioItem>, VariantProps<typeof dropdownMenuItemVariants> {}\n\nexport function DropdownMenuRadioItem({ className, variant, children, ...props }: DropdownMenuRadioItemProps) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn('relative', dropdownMenuItemVariants({ variant, indented: true }), className)}\n {...props}\n >\n <ItemIndicator>\n <span className=\"h-1.5 w-1.5 rounded-full bg-doom-blue\" />\n </ItemIndicator>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nexport function DropdownMenuSub(props: ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\n/** The row that opens a submenu; the chevron is part of the row, not the caller's job. */\nexport function DropdownMenuSubTrigger({\n className,\n children,\n ...props\n}: ComponentProps<typeof DropdownMenuPrimitive.SubTrigger>) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n className={cn(dropdownMenuItemVariants(), 'data-[state=open]:bg-doom-deep', className)}\n {...props}\n >\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n <ChevronRightIcon className=\"h-3 w-3 shrink-0 text-doom-faint\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nexport function DropdownMenuSubContent({\n className,\n sideOffset = 2,\n ...props\n}: ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n sideOffset={sideOffset}\n className={cn(CONTENT_CLASS, className)}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nexport function DropdownMenuLabel({ className, ...props }: ComponentProps<typeof DropdownMenuPrimitive.Label>) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n className={cn('px-2.5 py-1 text-2xs font-bold tracking-wider text-doom-faint uppercase', className)}\n {...props}\n />\n );\n}\n\n/** The keystroke printed at the right of a row; the row supplies the gap. */\nexport function DropdownMenuShortcut({ className, ...props }: ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn('ml-auto shrink-0 text-xs tracking-wide text-doom-faint', className)}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuSeparator({ className, ...props }: ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn('my-1 h-px bg-doom-border-soft', className)}\n {...props}\n />\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmptyState.d.mts","names":[],"sources":["../../../../src/components/EmptyState.tsx"],"mappings":";;iBAKiB,wBAAwB,KAAK;EAC5C,OAAO;EACP,cAAc;;EAEd,WAAW;;;;;EAKX;;;wBAIc,aAAa,OAAO,aAAa,UAAU,WAAW,YAAoB,SAAS,kCAAe,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmptyState.mjs","names":[],"sources":["../../../../src/components/EmptyState.tsx"],"sourcesContent":["import { Slot } from 'radix-ui';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../lib/cn';\n\nexport interface EmptyStateProps extends Omit<ComponentProps<'div'>, 'title'> {\n title: ReactNode;\n description?: ReactNode;\n /** Optional calls to action under the copy. */\n children?: ReactNode;\n /**\n * Render the child element instead of a <div>, so an empty row inside a\n * list stays an <li> and the list keeps its semantics.\n */\n asChild?: boolean;\n}\n\n/** The centred \"nothing here yet\" card every empty panel shares. */\nexport function EmptyState({ title, description, children, className, asChild = false, ...props }: EmptyStateProps) {\n const Component = asChild ? Slot.Root : 'div';\n return (\n <Component\n data-slot=\"empty-state\"\n className={cn('flex min-w-0 flex-1 items-center justify-center px-3 py-4 sm:px-4', className)}\n {...props}\n >\n <div className=\"flex min-w-0 w-full max-w-[520px] flex-col items-center gap-3 text-center\">\n <span className=\"text-base font-bold text-doom-hi\">{title}</span>\n {description ? <span className=\"text-sm leading-relaxed text-doom-dim\">{description}</span> : null}\n {children}\n </div>\n </Component>\n );\n}\n"],"mappings":"qHAkBA,SAAgB,EAAW,CAAE,QAAO,cAAa,WAAU,YAAW,UAAU,GAAO,GAAG,GAA0B,CAClH,IAAM,EAAY,EAAU,EAAK,KAAO,MACxC,MACE,kBAAC,EAAD,CACE,YAAU,cACV,UAAW,EAAG,oEAAqE,CAAS,EAC5F,GAAI,EAEJ,SAAA,kBAAC,MAAD,CAAK,UAAU,4EAAf,SAAA,CACE,kBAAC,OAAD,CAAM,UAAU,mCAAoC,SAAA,CAAY,CAAA,EAC/D,EAAc,kBAAC,OAAD,CAAM,UAAU,wCAAyC,SAAA,CAAkB,CAAA,EAAI,KAC7F,CACE,GACI,CAAA,CAEf"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HashlineLines.d.mts","names":[],"sources":["../../../../src/components/HashlineLines.tsx"],"mappings":";;;;;;;;;;;;;iBAkBiB,2BAA2B;EAC1C,gBAAgB;;EAEhB;;EAEA;;wBA4Cc,gBAAgB,WAAW,OAAO,QAAQ,SAAS,SAAS,qCAAkB,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HashlineLines.mjs","names":[],"sources":["../../../../src/components/HashlineLines.tsx"],"sourcesContent":["import { type ComponentProps, useEffect, useMemo, useState } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { type HashlineGroup, hashlineGroups, hashlineGroupsKey } from '../lib/hashlineHighlight';\nimport type { PresentedLine } from '../lib/hashlineView';\nimport { detectGrammar, highlightToLines, type SyntaxSpan } from '../lib/syntaxHighlight';\nimport { SyntaxLine } from './SyntaxText';\n\n/**\n * The anchored body shared by hashline results: a file heading per group, a\n * right-aligned line-number gutter, and a `>>` marker on grep matches. The\n * gutter width is a style, not a class, because it follows the widest number.\n *\n * The anchored lines are coloured with the editor's grammars when the body\n * names a file, or when `path` names one for a result that does not. Colour\n * arrives a frame or two late and never blocks the text: an unhighlighted body\n * is the same body without the colours.\n */\nexport interface HashlineLinesProps extends ComponentProps<'div'> {\n lines: readonly PresentedLine[];\n /** Width of the line-number column, in characters, from `hashlineBody`. */\n gutter: number;\n /** The file a body of bare anchored lines came from, for highlighting. */\n path?: string | undefined;\n}\n\nconst NO_SPANS: ReadonlyMap<number, readonly SyntaxSpan[]> = new Map();\n\n/**\n * Spans per presented-line index, once every file's run has parsed. The result\n * is stored with the body it belongs to, so a body that has changed since\n * reads as plain rather than wearing the previous body's colours.\n */\nfunction useHashlineSpans(groups: readonly HashlineGroup[]): ReadonlyMap<number, readonly SyntaxSpan[]> {\n const key = hashlineGroupsKey(groups);\n const [done, setDone] = useState<{ key: string; spans: ReadonlyMap<number, readonly SyntaxSpan[]> } | undefined>(\n undefined,\n );\n\n useEffect(() => {\n let live = true;\n const next = new Map<number, readonly SyntaxSpan[]>();\n const work = groups.map(async (group) => {\n const grammar = detectGrammar({ path: group.path, text: group.text });\n if (grammar === undefined) return;\n const highlighted = await highlightToLines(group.text, grammar);\n if (highlighted === undefined) return;\n for (const [offset, index] of group.indices.entries()) {\n const line = highlighted[offset];\n if (line !== undefined) next.set(index, line);\n }\n });\n // One state write for the whole body, so a many-file grep result does not\n // repaint once per file. A grammar that fails to load leaves its run plain.\n void Promise.allSettled(work).then(() => {\n if (live && next.size > 0) setDone({ key, spans: next });\n });\n return () => {\n live = false;\n };\n // The groups are rebuilt every render; their key is what actually changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key]);\n\n return done?.key === key ? done.spans : NO_SPANS;\n}\n\nexport function HashlineLines({ className, lines, gutter, path, ...props }: HashlineLinesProps) {\n const groups = useMemo(() => hashlineGroups(lines, path), [lines, path]);\n const spans = useHashlineSpans(groups);\n // Bound to a name rather than written inline: this file ships as a scaffold\n // template too, and an inline style object opens with the same two braces\n // Liquid reads as an output tag, which fails to render.\n const gutterStyle = { width: `${gutter}ch` };\n return (\n <div data-slot=\"hashline-lines\" className={cn('flex flex-col font-mono', className)} {...props}>\n {lines.map((line, index) => {\n if (line.type === 'file') {\n return (\n <span key={index} className=\"mt-1 truncate text-doom-faint first:mt-0\">\n {line.path}\n </span>\n );\n }\n if (line.type === 'plain') {\n return (\n <span key={index} className=\"whitespace-pre-wrap break-words text-doom-dim\">\n {line.text}\n </span>\n );\n }\n const { value } = line;\n return (\n <span key={index} className=\"flex gap-2\">\n {value.marker !== undefined ? (\n <span className={`w-4 shrink-0 ${value.marker === 'match' ? 'text-doom-blue' : 'text-doom-faint'}`}>\n {value.marker === 'match' ? '>>' : ''}\n </span>\n ) : null}\n <span className=\"shrink-0 text-right text-doom-faint\" style={gutterStyle}>\n {value.line}\n </span>\n <SyntaxLine\n spans={spans.get(index)}\n text={value.content}\n className={`min-w-0 whitespace-pre-wrap break-words ${value.marker === 'match' ? 'text-doom-hi' : 'text-doom-text'}`}\n />\n </span>\n );\n })}\n </div>\n );\n}\n"],"mappings":"sWA0BA,MAAM,kBAAuD,IAAI,IAOjE,SAAS,EAAiB,EAA8E,CACtG,IAAM,EAAM,EAAkB,CAAM,EAC9B,CAAC,EAAM,GAAW,EACtB,IAAA,EACF,EA2BA,OAzBA,MAAgB,CACd,IAAI,EAAO,GACL,kBAAO,IAAI,IACX,EAAO,EAAO,IAAI,KAAO,IAAU,CACvC,IAAM,EAAU,EAAc,CAAE,KAAM,EAAM,KAAM,KAAM,EAAM,IAAK,CAAC,EACpE,GAAI,IAAY,IAAA,GAAW,OAC3B,IAAM,EAAc,MAAM,EAAiB,EAAM,KAAM,CAAO,EAC1D,OAAgB,IAAA,GACpB,IAAK,GAAM,CAAC,EAAQ,KAAU,EAAM,QAAQ,QAAQ,EAAG,CACrD,IAAM,EAAO,EAAY,GACrB,IAAS,IAAA,IAAW,EAAK,IAAI,EAAO,CAAI,CAC9C,CACF,CAAC,EAMD,OAHA,QAAa,WAAW,CAAI,CAAC,CAAC,SAAW,CACnC,GAAQ,EAAK,KAAO,GAAG,EAAQ,CAAE,MAAK,MAAO,CAAK,CAAC,CACzD,CAAC,MACY,CACX,EAAO,EACT,CAGF,EAAG,CAAC,CAAG,CAAC,EAED,GAAM,MAAQ,EAAM,EAAK,MAAQ,CAC1C,CAEA,SAAgB,EAAc,CAAE,YAAW,QAAO,SAAQ,OAAM,GAAG,GAA6B,CAE9F,IAAM,EAAQ,EADC,MAAc,EAAe,EAAO,CAAI,EAAG,CAAC,EAAO,CAAI,CAClC,CAAC,EAI/B,EAAc,CAAE,MAAO,GAAG,EAAO,GAAI,EAC3C,MACE,kBAAC,MAAD,CAAK,YAAU,iBAAiB,UAAW,EAAG,0BAA2B,CAAS,EAAG,GAAI,EACtF,SAAA,EAAM,KAAK,EAAM,IAAU,CAC1B,GAAI,EAAK,OAAS,OAChB,MACE,kBAAC,OAAD,CAAkB,UAAU,2CACzB,SAAA,EAAK,IACF,EAFK,CAEL,EAGV,GAAI,EAAK,OAAS,QAChB,MACE,kBAAC,OAAD,CAAkB,UAAU,gDACzB,SAAA,EAAK,IACF,EAFK,CAEL,EAGV,GAAM,CAAE,SAAU,EAClB,MACE,kBAAC,OAAD,CAAkB,UAAU,aAA5B,SAAA,CACG,EAAM,SAAW,IAAA,GAId,KAHF,kBAAC,OAAD,CAAM,UAAW,gBAAgB,EAAM,SAAW,QAAU,iBAAmB,oBAC5E,SAAA,EAAM,SAAW,QAAU,KAAO,EAC/B,CAAA,EAER,kBAAC,OAAD,CAAM,UAAU,sCAAsC,MAAO,EAC1D,SAAA,EAAM,IACH,CAAA,EACN,kBAAC,EAAD,CACE,MAAO,EAAM,IAAI,CAAK,EACtB,KAAM,EAAM,QACZ,UAAW,2CAA2C,EAAM,SAAW,QAAU,eAAiB,kBACnG,CAAA,CACG,CAdK,EAAA,CAcL,CAEV,CAAC,CACE,CAAA,CAET"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.d.mts","names":[],"sources":["../../../../src/components/Input.tsx"],"mappings":";;;;;;;;qBAUa,gBAAa;;;6CAwBzB;YAEW,eAAe,YAAY,oBAAoB;YAC/C,YAAY,YAAY,oBAAoB;iBAEvC,mBAAmB,KAAK,kCAAkC,oBAAoB;;wBAG/E,QAAQ,WAAW,MAAM,SAAS,SAAS,SAAS,6BAAU,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.mjs","names":[],"sources":["../../../../src/components/Input.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The shape both fields wear, so a single-line and a multi-line field in the\n * same form agree on their well, their type ramp, and their invalid state.\n * Textarea builds on it rather than restating it.\n */\nexport const fieldVariants = cva(\n 'min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red',\n {\n variants: {\n variant: {\n default: 'rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60',\n /** No well: a composer or a palette search that draws its own surface. */\n bare: 'border-0 bg-transparent',\n },\n /** The same rungs Button names, so a field and the button beside it line up. */\n size: {\n xs: 'min-h-6 px-1.5 py-0.5 text-2xs',\n sm: 'min-h-7 px-2 py-1 text-xs',\n md: 'min-h-8 px-2.5 py-1.5 text-sm',\n lg: 'min-h-9 px-3 py-1.5 text-base',\n },\n },\n compoundVariants: [\n // A bare field sits inside a surface that already has its own padding,\n // so it keeps the size's type ramp and gives up the size's box.\n { variant: 'bare', class: 'min-h-0 p-0' },\n ],\n defaultVariants: { variant: 'default', size: 'md' },\n },\n);\n\nexport type FieldVariant = NonNullable<VariantProps<typeof fieldVariants>['variant']>;\nexport type FieldSize = NonNullable<VariantProps<typeof fieldVariants>['size']>;\n\nexport interface InputProps extends Omit<ComponentProps<'input'>, 'size'>, VariantProps<typeof fieldVariants> {}\n\n/** The one text field: deep well, quiet border, accent border on focus, red edge when invalid. */\nexport function Input({ className, type, variant, size, ...props }: InputProps) {\n return (\n <input\n type={type ?? 'text'}\n data-slot=\"input\"\n spellCheck={false}\n className={cn(fieldVariants({ variant, size }), className)}\n {...props}\n />\n );\n}\n"],"mappings":"0HAUA,MAAa,EAAgB,EAC3B,2JACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,6FAET,KAAM,yBACR,EAEA,KAAM,CACJ,GAAI,iCACJ,GAAI,4BACJ,GAAI,gCACJ,GAAI,+BACN,CACF,EACA,iBAAkB,CAGhB,CAAE,QAAS,OAAQ,MAAO,aAAc,CAC1C,EACA,gBAAiB,CAAE,QAAS,UAAW,KAAM,IAAK,CACpD,CACF,EAQA,SAAgB,EAAM,CAAE,YAAW,OAAM,UAAS,OAAM,GAAG,GAAqB,CAC9E,MACE,kBAAC,QAAD,CACE,KAAM,GAAQ,OACd,YAAU,QACV,WAAY,GACZ,UAAW,EAAG,EAAc,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EACzD,GAAI,CACL,CAAA,CAEL"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Kbd.d.mts","names":[],"sources":["../../../../src/components/Kbd.tsx"],"mappings":";;;wBAKgB,MAAM,cAAc,SAAS,wCAAqB,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Kbd.mjs","names":[],"sources":["../../../../src/components/Kbd.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A key or key path, drawn as the leader hints draw them. */\nexport function Kbd({ className, ...props }: ComponentProps<'kbd'>) {\n return (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n 'inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-2xs font-bold text-doom-faint',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"2EAKA,SAAgB,EAAI,CAAE,YAAW,GAAG,GAAgC,CAClE,MACE,kBAAC,MAAD,CACE,YAAU,MACV,UAAW,EACT,2GACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Label.d.mts","names":[],"sources":["../../../../src/components/Label.tsx"],"mappings":";;;;iBAMgB,UAAQ,cAAc,SAAS,sBAAsB,MAAe,wBAAK,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Label.mjs","names":["Label","LabelPrimitive"],"sources":["../../../../src/components/Label.tsx"],"sourcesContent":["import { Label as LabelPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A field's name: clicking it focuses the control, which a bare span never does. */\nexport function Label({ className, ...props }: ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'flex items-center gap-1.5 text-xs text-doom-faint select-none has-[+:disabled]:opacity-50',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"4GAMA,SAAgBA,EAAM,CAAE,YAAW,GAAG,GAAqD,CACzF,MACE,kBAACC,EAAe,KAAhB,CACE,YAAU,QACV,UAAW,EACT,4FACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Markdown.d.mts","names":[],"sources":["../../../../src/components/Markdown.tsx"],"mappings":";;;;;;;;;YAkBY,mBAAmB,cAAc;;wBAiI7B,WAAW,MAAM;EAAgB;EAAc,aAAa;oBAAiB,IAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Markdown.mjs","names":[],"sources":["../../../../src/components/Markdown.tsx"],"sourcesContent":["import { createContext, type ComponentProps, isValidElement, type ReactNode, useContext } 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\nconst CODE_CLASS = 'rounded bg-doom-deep px-1 py-px font-mono text-sm 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\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-bold 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 h1: ({ children }) => <h1 className=\"text-lg font-bold text-doom-hi\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"text-base font-bold text-doom-hi\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"text-base font-bold text-doom-hi\">{children}</h3>,\n h4: ({ children }) => <h4 className=\"text-base font-bold text-doom-text\">{children}</h4>,\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 text-sm\">{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-bold text-doom-hi\">{children}</th>\n ),\n td: ({ children }) => <td className=\"border border-doom-border px-2 py-1 align-top\">{children}</td>,\n img: ({ src, alt }) => (\n <img src={src} alt={alt ?? ''} className=\"max-h-[480px] max-w-full rounded border border-doom-border\" />\n ),\n};\n\n/** GitHub-flavored Markdown using the cockpit's safe, shared presentation. */\nexport function Markdown({ text, onFileLink }: { text: string; onFileLink?: FileLinkHandler }) {\n return (\n <FileLinkContext.Provider value={onFileLink}>\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 </FileLinkContext.Provider>\n );\n}\n"],"mappings":"sNAMA,MAAM,EAAiB,CAAC,CAAS,EAE3B,EAAa,oEAkBb,EAAkB,EAA2C,IAAA,EAAS,EAE5E,SAAS,EAAK,CAAE,YAAW,WAAU,GAAG,GAAgC,CACtE,IAAM,EAAa,EAAW,CAAe,EAGvC,EAAQ,OAAO,GAAa,UAAY,CAAC,EAAS,SAAS;CAAI,EAAI,EAAW,IAAA,GAC9E,EAAO,IAAU,IAAA,IAAa,IAAc,IAAA,GAAY,IAAA,GAAY,IAAa,CAAK,EAc5F,OAbI,IAAS,IAAA,IAAa,IAAU,IAAA,GAEhC,kBAAC,SAAD,CACE,KAAK,SACL,cAAY,qBACZ,MAAO,QAAQ,IACf,QAAS,EACT,UAAW,GAAG,EAAW,mHAExB,SAAA,CACK,CAAA,EAIV,kBAAC,OAAD,CACE,GAAI,EACJ,UAAW,GAAG,GAAa,GAAG,GAAG,EAAW,0DAE3C,UACG,CAAA,CAEV,CAEA,SAAS,EAAK,CAAE,OAAM,YAAiC,CACrD,IAAM,EAAa,EAAW,CAAe,EACzC,EAAO,EACX,GAAI,CACF,EAAO,IAAS,IAAA,GAAY,IAAA,GAAY,mBAAmB,CAAI,CACjE,MAAQ,CACN,EAAO,IAAA,EACT,CAEA,IAAM,EADS,IAAS,IAAA,IAAa,IAAS,IAAM,CAAC,oCAAoC,KAAK,CAAI,EAC5E,IAAa,EAAO,EAAI,EAAI,IAAA,GAalD,OAZI,IAAS,IAAA,GAaX,kBAAC,IAAD,CAAS,OAAM,OAAO,SAAS,IAAI,aAAa,UAAU,mDACvD,UACA,CAAA,EAbD,kBAAC,SAAD,CACE,KAAK,SACL,cAAY,qBACZ,MAAO,QAAQ,IACf,QAAS,EACT,UAAU,mDAET,UACK,CAAA,CAOd,CAGA,SAAS,EAAO,EAA6B,CAG3C,OAFI,OAAO,GAAa,SAAiB,EACrC,MAAM,QAAQ,CAAQ,EAAU,EAAS,IAAK,GAAU,EAAO,CAAkB,CAAC,CAAC,CAAC,KAAK,EAAE,EACxF,EACT,CAWA,SAAS,EAAI,CAAE,YAAmC,CAChD,IAAM,EAAO,EAA6D,CAAQ,EAAI,EAAW,IAAA,GAQjG,OAPI,IAAS,IAAA,GAET,kBAAC,MAAD,CAAK,UAAU,+FACZ,UACE,CAAA,EAGF,kBAAC,EAAD,CAAW,KAAM,EAAO,EAAK,MAAM,QAAQ,CAAC,CAAC,QAAQ,MAAO,EAAE,EAAG,UAAW,EAAK,MAAM,SAAY,CAAA,CAC5G,CACA,MAAM,EAAyB,CAC7B,GAAI,CAAE,cAAe,kBAAC,IAAD,CAAG,UAAU,kCAAmC,UAAY,CAAA,EACjF,QAAS,CAAE,cAAe,kBAAC,SAAD,CAAQ,UAAU,yBAA0B,UAAiB,CAAA,EACvF,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,SAAU,UAAa,CAAA,EAC3D,KAAM,CAAE,cAAe,kBAAC,MAAD,CAAK,UAAU,6BAA8B,UAAc,CAAA,EAClF,EAAG,EACH,KAAM,EACN,IAAK,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,EACpF,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,iCAAkC,UAAa,CAAA,EACnF,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,mCAAoC,UAAa,CAAA,EACrF,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,mCAAoC,UAAa,CAAA,EACrF,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,qCAAsC,UAAa,CAAA,EACvF,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,0BAA2B,UAAgB,CAAA,CACzD,CAAA,EAEP,IAAK,CAAE,cACL,kBAAC,KAAD,CAAI,UAAU,oFAAqF,UAAa,CAAA,EAElH,IAAK,CAAE,cAAe,kBAAC,KAAD,CAAI,UAAU,gDAAiD,UAAa,CAAA,EAClG,KAAM,CAAE,MAAK,SACX,kBAAC,MAAD,CAAU,MAAK,IAAK,GAAO,GAAI,UAAU,4DAA8D,CAAA,CAE3G,EAGA,SAAgB,EAAS,CAAE,OAAM,cAA8D,CAC7F,MACE,kBAAC,EAAgB,SAAjB,CAA0B,MAAO,EAC/B,SAAA,kBAAC,MAAD,CAAK,UAAU,8BACb,SAAA,kBAAC,EAAD,CAAe,cAAe,EAAgB,WAAY,EACvD,SAAA,CACY,CAAA,CACZ,CAAA,CACmB,CAAA,CAE9B"}
@@ -0,0 +1,18 @@
1
+ import { DoomMcpWidgetProps } from "../../../doompi-core/dist/src/web/types/mcpWidget.mjs";
2
+ import "../../../doompi-core/dist/web.mjs";
3
+ import { ComponentType } from "react";
4
+ //#region src/components/McpApp.d.ts
5
+ interface View {
6
+ readonly widget?: string;
7
+ readonly props: DoomMcpWidgetProps;
8
+ readonly failure?: string;
9
+ }
10
+ /** The root only dispatches. Tool-specific presentation belongs to the contributing package. */
11
+ export declare function McpApp({ widgets, view }: {
12
+ widgets: Readonly<Record<string, ComponentType<DoomMcpWidgetProps>>>;
13
+ view: View;
14
+ }): import("react").JSX.Element;
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>;
17
+ //#endregion
18
+ //# sourceMappingURL=McpApp.d.mts.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ import{jsx as e}from"react/jsx-runtime";import{Component as t}from"react";import{App as n,applyDocumentTheme as r,applyHostStyleVariables as i}from"@modelcontextprotocol/ext-apps";import{createRoot as a}from"react-dom/client";var o=class extends t{state={failed:!1};static getDerivedStateFromError(){return{failed:!0}}render(){return this.state.failed?/* @__PURE__ */ e(`p`,{role:`status`,children:`The tool widget could not be rendered.`}):this.props.children}};function s({widgets:t,view:n}){let r=n.widget!==void 0&&Object.hasOwn(t,n.widget)?t[n.widget]:void 0;return n.failure?/* @__PURE__ */ e(`p`,{role:`status`,children:n.failure}):r===void 0?/* @__PURE__ */ e(`p`,{role:`status`,children:n.widget===void 0?`Waiting for tool information...`:`No widget is available for this tool.`}):/* @__PURE__ */ e(o,{children:/* @__PURE__ */ e(r,{...n.props})},n.widget)}async function c(t){let o=document.getElementById(`root`);if(o===null)throw Error(`Missing MCP app root`);let c=a(o),l=new n({name:`doompi-tools`,version:`1.0.0`},{},{autoResize:!0}),u=!1,d=!1,f=!1,p=!1,m={props:{toolName:``,args:{},result:null,phase:`connecting`}},h=()=>{u||c.render(/* @__PURE__ */ e(s,{widgets:t,view:m}))},g=e=>{d=!0,m={...m,failure:e},h()},_=(e,t)=>{if(typeof e==`string`&&e.length>0){if(m.props.toolName&&m.props.toolName!==e)return g(`The tool changed. Reopen this widget from the conversation.`),!1;m={...m,props:{...m.props,toolName:e}}}if(typeof t==`string`){if(m.widget!==void 0&&m.widget!==t)return g(`The widget changed. Refresh the MCP connection.`),!1;m={...m,widget:t}}return!0},v=()=>{let e=m.props.toolName,t=f&&p&&!!l.getHostCapabilities()?.serverTools&&e.length>0;m={...m,props:{...m.props,refresh:t?async()=>{if(u||e!==m.props.toolName||!p)throw Error(`This widget is no longer active.`);return l.callServerTool({name:e,arguments:{...m.props.args}})}:void 0}}},y=e=>{if(u||e===void 0)return;e.theme&&(r(e.theme),document.documentElement.classList.toggle(`dark`,e.theme===`dark`),document.documentElement.dataset.theme=e.theme),e.styles?.variables&&i(e.styles.variables);let t=e.toolInfo?.tool;if(t){if(!_(t.name,t._meta?.[`doompi/widget`]))return;let e=t._meta?.ui;p=Array.isArray(e?.visibility)&&e.visibility.includes(`app`)}v(),h()};l.ontoolinputpartial=({arguments:e})=>{u||d||(m={...m,props:{...m.props,args:e??{},phase:`preparing`}},h())},l.ontoolinput=({arguments:e})=>{u||d||(m={...m,props:{...m.props,args:e??{},phase:`running`}},h())},l.ontoolresult=e=>{u||d||_(e._meta?.[`doompi/toolName`],e._meta?.[`doompi/widget`])&&(d=!0,m={...m,props:{...m.props,result:e,phase:`result`}},v(),h())},l.ontoolcancelled=()=>{u||d||(d=!0,m={...m,props:{...m.props,phase:`cancelled`,result:null}},h())},l.onhostcontextchanged=y;let b=()=>{u||(m={...m,failure:`Tool view closed.`},h(),u=!0,window.removeEventListener(`pagehide`,b),setTimeout(()=>{l.close().catch(()=>{})},0))};l.onteardown=()=>(b(),{}),window.addEventListener(`pagehide`,b,{once:!0}),h();try{if(await l.connect(),u)return;f=!0,y(l.getHostContext())}catch{u||g(`Could not connect to the app host. Reopen this widget in an MCP Apps-compatible client.`)}}export{s as McpApp,c as mountMcpApp};
2
+ //# sourceMappingURL=McpApp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpApp.mjs","names":[],"sources":["../../../../src/components/McpApp.tsx"],"sourcesContent":["import type { DoomMcpWidgetProps } from '@agimon-ai/doompi-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: 'doompi-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?.['doompi/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?.['doompi/toolName'], result._meta?.['doompi/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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"}
@@ -0,0 +1,14 @@
1
+ import { DoomMcpWidgetProps } from "../../../doompi-core/dist/src/web/types/mcpWidget.mjs";
2
+ import { ReactNode } from "react";
3
+ //#region src/components/McpToolWidget.d.ts
4
+ /** Presentational primitives only. Each package chooses its own fields and result presentation. */
5
+ export declare function McpToolFrame({ title, phase, result, error, children }: Pick<DoomMcpWidgetProps, 'phase' | 'result' | 'error'> & {
6
+ title: string;
7
+ children?: ReactNode;
8
+ }): import("react").JSX.Element;
9
+ export declare function McpToolFields({ fields }: {
10
+ fields: readonly (readonly [string, unknown])[];
11
+ }): import("react").JSX.Element | null;
12
+ export declare function McpToolOutput({ result }: Pick<DoomMcpWidgetProps, 'result'>): import("react").JSX.Element | null;
13
+ //#endregion
14
+ //# sourceMappingURL=McpToolWidget.d.mts.map
@@ -0,0 +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"}
@@ -0,0 +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};
3
+ //# sourceMappingURL=McpToolWidget.mjs.map