@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.
- package/dist/doompi-core/dist/src/extensions/webPlugin.d.mts +2 -0
- package/dist/doompi-core/dist/src/web/models/globalStore.d.mts +1 -0
- package/dist/doompi-core/dist/src/web/models/sessionStore.d.mts +1 -0
- package/dist/doompi-core/dist/src/web/models/workspaceStore.d.mts +1 -0
- package/dist/doompi-core/dist/src/web/schemas/template.d.mts +1 -0
- package/dist/doompi-core/dist/src/web/types/extensionFile.d.mts +2 -0
- package/dist/doompi-core/dist/src/web/types/mcpWidget.d.mts +16 -0
- package/dist/doompi-core/dist/src/web/types/mcpWidget.d.mts.map +1 -0
- package/dist/doompi-core/dist/src/web/types/template.d.mts +1 -0
- package/dist/doompi-core/dist/src/web/types/webPlugin.d.mts +2 -0
- package/dist/doompi-core/dist/web.d.mts +10 -0
- package/dist/doompi-web-components/src/components/Accordion.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Accordion.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/AnsiText.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/AnsiText.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Avatar.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Avatar.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Badge.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Badge.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Breadcrumb.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Breadcrumb.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Button.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Button.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Checkbox.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Checkbox.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/CodeBlock.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/CodeEditor.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/CodeEditor.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/CodeEditorView.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Collapsible.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Collapsible.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Command.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Command.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/CopyButton.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Dialog.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Dialog.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Dot.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Dot.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Drawer.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Drawer.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/DropdownMenu.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/DropdownMenu.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/EmptyState.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/EmptyState.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/HashlineLines.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/HashlineLines.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Input.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Input.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Kbd.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Kbd.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Label.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Label.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Markdown.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Markdown.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/McpApp.d.mts +18 -0
- package/dist/doompi-web-components/src/components/McpApp.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/McpApp.mjs +2 -0
- package/dist/doompi-web-components/src/components/McpApp.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/McpToolWidget.d.mts +14 -0
- package/dist/doompi-web-components/src/components/McpToolWidget.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/McpToolWidget.mjs +3 -0
- package/dist/doompi-web-components/src/components/McpToolWidget.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/MediaPreview.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/MediaPreview.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/MermaidDiagram.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/MessageItem.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/MessageItem.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/MessageLines.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/MessageLines.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/OptionList.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/OptionList.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Panel.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Panel.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/PdfPreview.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/PdfPreview.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Popover.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Popover.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Progress.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Progress.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/RadioGroup.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/RadioGroup.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/ScrollArea.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/ScrollArea.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/SectionLabel.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/SectionLabel.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Select.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Select.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Separator.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Separator.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Sheet.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Sheet.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Skeleton.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Skeleton.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Spinner.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Spinner.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/StatusBadge.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/StatusBadge.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/StreamCursor.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/StreamCursor.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Switch.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Switch.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/SyntaxText.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/SyntaxText.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Tabs.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Tabs.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/TerminalView.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/TerminalView.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Textarea.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Textarea.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Toast.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Toast.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/ToolPathLink.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/ToolPathLink.mjs.map +1 -0
- package/dist/doompi-web-components/src/components/Tooltip.d.mts.map +1 -0
- package/dist/doompi-web-components/src/components/Tooltip.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/ansiSpans.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/ansiSpans.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/cn.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/cn.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/collapse.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/collapse.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/editorController.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/editorLanguage.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/editorLanguage.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/editorTheme.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/editorTheme.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/fenceGrammar.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/hashlineHighlight.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/hashlineHighlight.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/hashlineView.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/hashlineView.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/media.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/media.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/mediaPlayback.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/mermaidDiagram.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/optionList.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/optionList.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/syntaxHighlight.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/syntaxHighlight.mjs.map +1 -0
- package/dist/doompi-web-components/src/lib/tone.d.mts.map +1 -0
- package/dist/doompi-web-components/src/lib/tone.mjs.map +1 -0
- package/dist/doompi-web-components/src/theme/apply.d.mts.map +1 -0
- package/dist/doompi-web-components/src/theme/apply.mjs.map +1 -0
- package/dist/doompi-web-components/src/theme/builtinThemes.d.mts.map +1 -0
- package/dist/doompi-web-components/src/theme/builtinThemes.mjs.map +1 -0
- package/dist/doompi-web-components/src/theme/derive.d.mts.map +1 -0
- package/dist/doompi-web-components/src/theme/derive.mjs.map +1 -0
- package/dist/doompi-web-components/src/theme/parse.d.mts.map +1 -0
- package/dist/doompi-web-components/src/theme/parse.mjs.map +1 -0
- package/dist/doompi-web-components/src/theme/piTheme.d.mts.map +1 -0
- package/dist/doompi-web-components/src/theme/piTheme.mjs.map +1 -0
- package/dist/doompi-web-components/src/theme/preference.d.mts.map +1 -0
- package/dist/doompi-web-components/src/theme/preference.mjs.map +1 -0
- package/dist/doompi-web-components/src/types/editor.d.mts.map +1 -0
- package/dist/doompi-web-components/src/types/editor.mjs.map +1 -0
- package/dist/doompi-web-components/src/types/theme.d.mts.map +1 -0
- package/dist/doompi-web-components/src/types/theme.mjs.map +1 -0
- package/dist/doompi-web-components/src/types/tone.d.mts.map +1 -0
- package/dist/doompi-web-components/src/types/tone.mjs.map +1 -0
- package/dist/doompi-web-components/themes/doom-nord-dark.mjs.map +1 -0
- package/dist/doompi-web-components/themes/doom-one-dark.mjs.map +1 -0
- package/dist/doompi-web-components/themes/doom-one-light.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.mts +61 -60
- package/dist/index.mjs +1 -1
- package/dist/mcpWidget.cjs +1 -0
- package/dist/mcpWidget.d.mts +3 -0
- package/dist/mcpWidget.mjs +1 -0
- package/dist/src/components/McpApp.cjs +2 -0
- package/dist/src/components/McpApp.cjs.map +1 -0
- package/dist/src/components/McpToolWidget.cjs +3 -0
- package/dist/src/components/McpToolWidget.cjs.map +1 -0
- package/dist/theme.d.mts +7 -7
- package/dist/theme.mjs +1 -1
- package/package.json +11 -4
- package/styles/mcp.css +22 -0
- package/dist/src/components/Accordion.d.mts.map +0 -1
- package/dist/src/components/Accordion.mjs.map +0 -1
- package/dist/src/components/AnsiText.d.mts.map +0 -1
- package/dist/src/components/AnsiText.mjs.map +0 -1
- package/dist/src/components/Avatar.d.mts.map +0 -1
- package/dist/src/components/Avatar.mjs.map +0 -1
- package/dist/src/components/Badge.d.mts.map +0 -1
- package/dist/src/components/Badge.mjs.map +0 -1
- package/dist/src/components/Breadcrumb.d.mts.map +0 -1
- package/dist/src/components/Breadcrumb.mjs.map +0 -1
- package/dist/src/components/Button.d.mts.map +0 -1
- package/dist/src/components/Button.mjs.map +0 -1
- package/dist/src/components/Checkbox.d.mts.map +0 -1
- package/dist/src/components/Checkbox.mjs.map +0 -1
- package/dist/src/components/CodeBlock.mjs.map +0 -1
- package/dist/src/components/CodeEditor.d.mts.map +0 -1
- package/dist/src/components/CodeEditor.mjs.map +0 -1
- package/dist/src/components/CodeEditorView.mjs.map +0 -1
- package/dist/src/components/Collapsible.d.mts.map +0 -1
- package/dist/src/components/Collapsible.mjs.map +0 -1
- package/dist/src/components/Command.d.mts.map +0 -1
- package/dist/src/components/Command.mjs.map +0 -1
- package/dist/src/components/CopyButton.mjs.map +0 -1
- package/dist/src/components/Dialog.d.mts.map +0 -1
- package/dist/src/components/Dialog.mjs.map +0 -1
- package/dist/src/components/Dot.d.mts.map +0 -1
- package/dist/src/components/Dot.mjs.map +0 -1
- package/dist/src/components/Drawer.d.mts.map +0 -1
- package/dist/src/components/Drawer.mjs.map +0 -1
- package/dist/src/components/DropdownMenu.d.mts.map +0 -1
- package/dist/src/components/DropdownMenu.mjs.map +0 -1
- package/dist/src/components/EmptyState.d.mts.map +0 -1
- package/dist/src/components/EmptyState.mjs.map +0 -1
- package/dist/src/components/HashlineLines.d.mts.map +0 -1
- package/dist/src/components/HashlineLines.mjs.map +0 -1
- package/dist/src/components/Input.d.mts.map +0 -1
- package/dist/src/components/Input.mjs.map +0 -1
- package/dist/src/components/Kbd.d.mts.map +0 -1
- package/dist/src/components/Kbd.mjs.map +0 -1
- package/dist/src/components/Label.d.mts.map +0 -1
- package/dist/src/components/Label.mjs.map +0 -1
- package/dist/src/components/Markdown.d.mts.map +0 -1
- package/dist/src/components/Markdown.mjs.map +0 -1
- package/dist/src/components/MediaPreview.d.mts.map +0 -1
- package/dist/src/components/MediaPreview.mjs.map +0 -1
- package/dist/src/components/MermaidDiagram.mjs.map +0 -1
- package/dist/src/components/MessageItem.d.mts.map +0 -1
- package/dist/src/components/MessageItem.mjs.map +0 -1
- package/dist/src/components/MessageLines.d.mts.map +0 -1
- package/dist/src/components/MessageLines.mjs.map +0 -1
- package/dist/src/components/OptionList.d.mts.map +0 -1
- package/dist/src/components/OptionList.mjs.map +0 -1
- package/dist/src/components/Panel.d.mts.map +0 -1
- package/dist/src/components/Panel.mjs.map +0 -1
- package/dist/src/components/PdfPreview.d.mts.map +0 -1
- package/dist/src/components/PdfPreview.mjs.map +0 -1
- package/dist/src/components/Popover.d.mts.map +0 -1
- package/dist/src/components/Popover.mjs.map +0 -1
- package/dist/src/components/Progress.d.mts.map +0 -1
- package/dist/src/components/Progress.mjs.map +0 -1
- package/dist/src/components/RadioGroup.d.mts.map +0 -1
- package/dist/src/components/RadioGroup.mjs.map +0 -1
- package/dist/src/components/ScrollArea.d.mts.map +0 -1
- package/dist/src/components/ScrollArea.mjs.map +0 -1
- package/dist/src/components/SectionLabel.d.mts.map +0 -1
- package/dist/src/components/SectionLabel.mjs.map +0 -1
- package/dist/src/components/Select.d.mts.map +0 -1
- package/dist/src/components/Select.mjs.map +0 -1
- package/dist/src/components/Separator.d.mts.map +0 -1
- package/dist/src/components/Separator.mjs.map +0 -1
- package/dist/src/components/Sheet.d.mts.map +0 -1
- package/dist/src/components/Sheet.mjs.map +0 -1
- package/dist/src/components/Skeleton.d.mts.map +0 -1
- package/dist/src/components/Skeleton.mjs.map +0 -1
- package/dist/src/components/Spinner.d.mts.map +0 -1
- package/dist/src/components/Spinner.mjs.map +0 -1
- package/dist/src/components/StatusBadge.d.mts.map +0 -1
- package/dist/src/components/StatusBadge.mjs.map +0 -1
- package/dist/src/components/StreamCursor.d.mts.map +0 -1
- package/dist/src/components/StreamCursor.mjs.map +0 -1
- package/dist/src/components/Switch.d.mts.map +0 -1
- package/dist/src/components/Switch.mjs.map +0 -1
- package/dist/src/components/SyntaxText.d.mts.map +0 -1
- package/dist/src/components/SyntaxText.mjs.map +0 -1
- package/dist/src/components/Tabs.d.mts.map +0 -1
- package/dist/src/components/Tabs.mjs.map +0 -1
- package/dist/src/components/TerminalView.d.mts.map +0 -1
- package/dist/src/components/TerminalView.mjs.map +0 -1
- package/dist/src/components/Textarea.d.mts.map +0 -1
- package/dist/src/components/Textarea.mjs.map +0 -1
- package/dist/src/components/Toast.d.mts.map +0 -1
- package/dist/src/components/Toast.mjs.map +0 -1
- package/dist/src/components/ToolPathLink.d.mts.map +0 -1
- package/dist/src/components/ToolPathLink.mjs.map +0 -1
- package/dist/src/components/Tooltip.d.mts.map +0 -1
- package/dist/src/components/Tooltip.mjs.map +0 -1
- package/dist/src/lib/ansiSpans.d.mts.map +0 -1
- package/dist/src/lib/ansiSpans.mjs.map +0 -1
- package/dist/src/lib/cn.d.mts.map +0 -1
- package/dist/src/lib/cn.mjs.map +0 -1
- package/dist/src/lib/collapse.d.mts.map +0 -1
- package/dist/src/lib/collapse.mjs.map +0 -1
- package/dist/src/lib/editorController.mjs.map +0 -1
- package/dist/src/lib/editorLanguage.d.mts.map +0 -1
- package/dist/src/lib/editorLanguage.mjs.map +0 -1
- package/dist/src/lib/editorTheme.d.mts.map +0 -1
- package/dist/src/lib/editorTheme.mjs.map +0 -1
- package/dist/src/lib/fenceGrammar.mjs.map +0 -1
- package/dist/src/lib/hashlineHighlight.d.mts.map +0 -1
- package/dist/src/lib/hashlineHighlight.mjs.map +0 -1
- package/dist/src/lib/hashlineView.d.mts.map +0 -1
- package/dist/src/lib/hashlineView.mjs.map +0 -1
- package/dist/src/lib/media.d.mts.map +0 -1
- package/dist/src/lib/media.mjs.map +0 -1
- package/dist/src/lib/mediaPlayback.mjs.map +0 -1
- package/dist/src/lib/mermaidDiagram.mjs.map +0 -1
- package/dist/src/lib/optionList.d.mts.map +0 -1
- package/dist/src/lib/optionList.mjs.map +0 -1
- package/dist/src/lib/syntaxHighlight.d.mts.map +0 -1
- package/dist/src/lib/syntaxHighlight.mjs.map +0 -1
- package/dist/src/lib/tone.d.mts.map +0 -1
- package/dist/src/lib/tone.mjs.map +0 -1
- package/dist/src/theme/apply.d.mts.map +0 -1
- package/dist/src/theme/apply.mjs.map +0 -1
- package/dist/src/theme/builtinThemes.d.mts.map +0 -1
- package/dist/src/theme/builtinThemes.mjs.map +0 -1
- package/dist/src/theme/derive.d.mts.map +0 -1
- package/dist/src/theme/derive.mjs.map +0 -1
- package/dist/src/theme/parse.d.mts.map +0 -1
- package/dist/src/theme/parse.mjs.map +0 -1
- package/dist/src/theme/piTheme.d.mts.map +0 -1
- package/dist/src/theme/piTheme.mjs.map +0 -1
- package/dist/src/theme/preference.d.mts.map +0 -1
- package/dist/src/theme/preference.mjs.map +0 -1
- package/dist/src/types/editor.d.mts.map +0 -1
- package/dist/src/types/editor.mjs.map +0 -1
- package/dist/src/types/theme.d.mts.map +0 -1
- package/dist/src/types/theme.mjs.map +0 -1
- package/dist/src/types/tone.d.mts.map +0 -1
- package/dist/src/types/tone.mjs.map +0 -1
- package/dist/themes/doom-nord-dark.mjs.map +0 -1
- package/dist/themes/doom-one-dark.mjs.map +0 -1
- package/dist/themes/doom-one-light.mjs.map +0 -1
- /package/dist/{src → doompi-web-components/src}/components/Accordion.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Accordion.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/AnsiText.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/AnsiText.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Avatar.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Avatar.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Badge.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Badge.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Breadcrumb.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Breadcrumb.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Button.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Button.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Checkbox.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Checkbox.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/CodeBlock.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/CodeEditor.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/CodeEditor.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/CodeEditorView.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Collapsible.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Collapsible.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Command.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Command.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/CopyButton.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Dialog.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Dialog.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Dot.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Dot.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Drawer.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Drawer.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/DropdownMenu.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/DropdownMenu.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/EmptyState.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/EmptyState.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/HashlineLines.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/HashlineLines.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Input.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Input.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Kbd.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Kbd.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Label.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Label.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Markdown.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Markdown.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/MediaPreview.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/MediaPreview.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/MermaidDiagram.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/MessageItem.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/MessageItem.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/MessageLines.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/MessageLines.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/OptionList.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/OptionList.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Panel.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Panel.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/PdfPreview.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/PdfPreview.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Popover.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Popover.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Progress.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Progress.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/RadioGroup.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/RadioGroup.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/ScrollArea.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/ScrollArea.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/SectionLabel.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/SectionLabel.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Select.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Select.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Separator.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Separator.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Sheet.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Sheet.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Skeleton.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Skeleton.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Spinner.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Spinner.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/StatusBadge.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/StatusBadge.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/StreamCursor.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/StreamCursor.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Switch.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Switch.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/SyntaxText.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/SyntaxText.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Tabs.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Tabs.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/TerminalView.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/TerminalView.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Textarea.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Textarea.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Toast.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Toast.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/ToolPathLink.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/ToolPathLink.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Tooltip.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/components/Tooltip.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/icons/icons.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/icons/icons.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/ansiSpans.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/ansiSpans.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/cn.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/cn.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/collapse.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/collapse.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/editorController.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/editorLanguage.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/editorLanguage.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/editorTheme.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/editorTheme.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/fenceGrammar.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/hashlineHighlight.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/hashlineHighlight.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/hashlineView.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/hashlineView.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/media.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/media.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/mediaPlayback.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/mermaidDiagram.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/optionList.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/optionList.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/syntaxHighlight.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/syntaxHighlight.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/tone.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/lib/tone.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/apply.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/apply.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/builtinThemes.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/builtinThemes.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/derive.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/derive.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/parse.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/parse.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/piTheme.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/piTheme.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/preference.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/theme/preference.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/types/editor.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/types/editor.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/types/theme.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/types/theme.mjs +0 -0
- /package/dist/{src → doompi-web-components/src}/types/tone.d.mts +0 -0
- /package/dist/{src → doompi-web-components/src}/types/tone.mjs +0 -0
- /package/dist/{themes → doompi-web-components/themes}/doom-nord-dark.mjs +0 -0
- /package/dist/{themes → doompi-web-components/themes}/doom-one-dark.mjs +0 -0
- /package/dist/{themes → doompi-web-components/themes}/doom-one-light.mjs +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpToolWidget.mjs","names":[],"sources":["../../../../src/components/McpToolWidget.tsx"],"sourcesContent":["import type { DoomMcpWidgetProps } from '@agimon-ai/doompi-core/mcpWidget';\nimport type { ReactNode } from 'react';\n\n/** Presentational primitives only. Each package chooses its own fields and result presentation. */\nexport function McpToolFrame({\n title,\n phase,\n result,\n error,\n children,\n}: Pick<DoomMcpWidgetProps, 'phase' | 'result' | 'error'> & { title: string; children?: ReactNode }) {\n const failed = phase === 'error' || result?.isError === true;\n const status = failed\n ? 'Tool failed'\n : phase === 'result'\n ? 'Result received'\n : phase === 'cancelled'\n ? 'Tool cancelled'\n : phase === 'running'\n ? 'Running tool...'\n : phase === 'preparing'\n ? 'Preparing tool...'\n : 'Connecting to host...';\n return (\n <section className=\"min-w-0 rounded-md border border-doom-border bg-doom-bg p-4 text-base text-doom-text\">\n <h1 className=\"m-0 break-words text-lg font-semibold\">{title}</h1>\n <p\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={failed ? 'my-2 text-doom-red' : 'my-2 text-doom-dim'}\n >\n {error ?? status}\n </p>\n {children}\n </section>\n );\n}\n\nfunction fieldText(value: unknown): string | undefined {\n if (typeof value === 'string') return value.length > 500 ? `${value.slice(0, 500)}...` : value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n if (typeof value === 'boolean') return String(value);\n if (Array.isArray(value) && value.every((item) => typeof item === 'string')) return fieldText(value.join(', '));\n return undefined;\n}\n\nexport function McpToolFields({ fields }: { fields: readonly (readonly [string, unknown])[] }) {\n const values = fields.flatMap(([label, value]) => {\n const text = fieldText(value);\n return text === undefined || text === '' ? [] : [{ label, text }];\n });\n if (values.length === 0) return null;\n return (\n <dl aria-label=\"Tool details\" className=\"my-3 flex min-w-0 flex-col gap-2\">\n {values.map(({ label, text }) => (\n <div key={label} className=\"flex min-w-0 flex-wrap gap-x-3 gap-y-1\">\n <dt className=\"text-sm text-doom-dim\">{label}</dt>\n <dd className=\"m-0 min-w-0 whitespace-pre-wrap break-all text-sm\">{text}</dd>\n </div>\n ))}\n </dl>\n );\n}\n\nexport function McpToolOutput({ result }: Pick<DoomMcpWidgetProps, 'result'>) {\n if (result === null) return null;\n const limit = 8000;\n let text = '';\n let truncated = false;\n let nonText = 0;\n for (const block of result.content ?? []) {\n if (block.type !== 'text') {\n nonText += 1;\n continue;\n }\n const part = `${text ? '\\n' : ''}${block.text}`;\n const remaining = Math.max(0, limit - text.length);\n truncated ||= part.length > remaining;\n text += part.slice(0, remaining);\n }\n if (!text && result.structuredContent) {\n const value = JSON.stringify(result.structuredContent, null, 2);\n text = value.slice(0, limit);\n truncated = value.length > limit;\n }\n return (\n <details open className=\"min-w-0 rounded-md border border-doom-border-soft\">\n <summary className=\"cursor-pointer bg-doom-panel p-3 text-sm focus-visible:outline\">Tool output</summary>\n <pre\n tabIndex={0}\n aria-label=\"Tool output preview\"\n className=\"m-0 max-h-72 overflow-auto whitespace-pre-wrap break-all p-3 font-mono text-sm\"\n >\n {text || (nonText ? 'Non-text result returned to the agent.' : 'No text output.')}\n </pre>\n {truncated || nonText ? (\n <p className=\"m-0 border-t border-doom-border-soft p-3 text-sm text-doom-dim\">\n {truncated ? 'Preview truncated. Full output remains in the tool result. ' : ''}\n {nonText ? `${nonText} non-text content item(s) returned to the agent.` : ''}\n </p>\n ) : null}\n </details>\n );\n}\n"],"mappings":"kDAIA,SAAgB,EAAa,CAC3B,QACA,QACA,SACA,QACA,YACmG,CACnG,IAAM,EAAS,IAAU,SAAW,GAAQ,UAAY,GAYxD,MACE,kBAAC,UAAD,CAAS,UAAU,uFAAnB,SAAA,CACE,kBAAC,KAAD,CAAI,UAAU,wCAAyC,SAAA,CAAU,CAAA,EACjE,kBAAC,IAAD,CACE,KAAK,SACL,YAAU,SACV,cAAY,OACZ,UAAW,EAAS,qBAAuB,qBAE1C,SAAA,IApBQ,EACX,cACA,IAAU,SACR,kBACA,IAAU,YACR,iBACA,IAAU,UACR,kBACA,IAAU,YACR,oBACA,wBAWL,CAAA,EACF,CACM,GAEb,CAEA,SAAS,EAAU,EAAoC,CACrD,GAAI,OAAO,GAAU,SAAU,OAAO,EAAM,OAAS,IAAM,GAAG,EAAM,MAAM,EAAG,GAAG,EAAE,KAAO,EAEzF,GADI,OAAO,GAAU,UAAY,OAAO,SAAS,CAAK,GAClD,OAAO,GAAU,UAAW,OAAO,OAAO,CAAK,EACnD,GAAI,MAAM,QAAQ,CAAK,GAAK,EAAM,MAAO,GAAS,OAAO,GAAS,QAAQ,EAAG,OAAO,EAAU,EAAM,KAAK,IAAI,CAAC,CAEhH,CAEA,SAAgB,EAAc,CAAE,UAA+D,CAC7F,IAAM,EAAS,EAAO,SAAS,CAAC,EAAO,KAAW,CAChD,IAAM,EAAO,EAAU,CAAK,EAC5B,OAAO,IAAS,IAAA,IAAa,IAAS,GAAK,CAAC,EAAI,CAAC,CAAE,QAAO,MAAK,CAAC,CAClE,CAAC,EAED,OADI,EAAO,SAAW,EAAU,KAE9B,kBAAC,KAAD,CAAI,aAAW,eAAe,UAAU,mCACrC,SAAA,EAAO,KAAK,CAAE,QAAO,UACpB,kBAAC,MAAD,CAAiB,UAAU,yCAA3B,SAAA,CACE,kBAAC,KAAD,CAAI,UAAU,wBAAyB,SAAA,CAAU,CAAA,EACjD,kBAAC,KAAD,CAAI,UAAU,oDAAqD,SAAA,CAAS,CAAA,CACzE,CAHK,EAAA,CAGL,CACN,CACC,CAAA,CAER,CAEA,SAAgB,EAAc,CAAE,UAA8C,CAC5E,GAAI,IAAW,KAAM,OAAO,KAC5B,IAAM,EAAQ,IACV,EAAO,GACP,EAAY,GACZ,EAAU,EACd,IAAK,IAAM,KAAS,EAAO,SAAW,CAAC,EAAG,CACxC,GAAI,EAAM,OAAS,OAAQ,CACzB,GAAW,EACX,QACF,CACA,IAAM,EAAO,GAAG,EAAO;EAAO,KAAK,EAAM,OACnC,EAAY,KAAK,IAAI,EAAG,EAAQ,EAAK,MAAM,EACjD,IAAc,EAAK,OAAS,EAC5B,GAAQ,EAAK,MAAM,EAAG,CAAS,CACjC,CACA,GAAI,CAAC,GAAQ,EAAO,kBAAmB,CACrC,IAAM,EAAQ,KAAK,UAAU,EAAO,kBAAmB,KAAM,CAAC,EAC9D,EAAO,EAAM,MAAM,EAAG,CAAK,EAC3B,EAAY,EAAM,OAAS,CAC7B,CACA,MACE,kBAAC,UAAD,CAAS,KAAA,GAAK,UAAU,oDAAxB,SAAA,CACE,kBAAC,UAAD,CAAS,UAAU,iEAAiE,SAAA,aAAoB,CAAA,EACxG,kBAAC,MAAD,CACE,SAAU,EACV,aAAW,sBACX,UAAU,iFAET,SAAA,IAAS,EAAU,yCAA2C,kBAC5D,CAAA,EACJ,GAAa,EACZ,kBAAC,IAAD,CAAG,UAAU,iEAAb,SAAA,CACG,EAAY,8DAAgE,GAC5E,EAAU,GAAG,EAAQ,kDAAoD,EACzE,CACD,CAAA,EAAA,IACG,GAEb"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaPreview.d.mts","names":[],"sources":["../../../../src/components/MediaPreview.tsx"],"mappings":";;;;;;;;;;;;iBAmBiB;EACf;EACA;EACA;;iBAGe;EACf;EACA;;iBAGe;EACf;EACA;;iBAGe;EACf,MAAM;EACN;EACA;EACA;EACA,WAAW;;iBAGI;EACf,YAAY;EACZ;EACA,OAAO;EACP,gBAAgB;EAChB;EACA,wBAAwB;EACxB,eAAe,mCAAmC,qBAAqB,QAAQ;;iBAGhE;;EAEf;;EAEA;;EAEA,OAAO;EACP;EACA;EACA;;EAEA,gCAAgC,IAAI;;EAEpC,mCAAmC,IAAI;;EAEvC,yBAAyB,OAAO;;wBA6IlB,eACd,KACA,MACA,MACA,WACA,eACA,kBACA,uBACA,8BACe,UACd,oCAAiB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaPreview.mjs","names":[],"sources":["../../../../src/components/MediaPreview.tsx"],"sourcesContent":["import { useEffect, useImperativeHandle, useRef } from 'react';\n\nimport { FileIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { mediaKindOf } from '../lib/media';\nimport { boundedMediaTime } from '../lib/mediaPlayback';\nimport type { MediaKind } from '../types/editor';\nimport { Badge } from './Badge';\nimport { PdfPreview, type PdfPreviewController } from './PdfPreview';\n/**\n * A file the browser can show but not edit.\n *\n * It renders bytes a server is already serving, so the caller supplies the\n * URL and this decides only which element reads it. Everything the browser\n * cannot render is a download rather than a converted approximation: a `.docx`\n * turned into HTML is a different document, and offering to edit that one\n * would be offering to overwrite the real one with it.\n */\n\nexport interface MediaPlaybackState {\n playing: boolean;\n currentTime: number;\n duration: number;\n}\n\nexport interface MediaIntrinsicSize {\n width: number;\n height: number;\n}\n\nexport interface MediaFrameMetadata {\n mediaTime: number;\n presentedFrames?: number;\n}\n\nexport interface MediaFrameCapture {\n blob: Blob;\n width: number;\n height: number;\n timeSeconds: number;\n metadata?: MediaFrameMetadata;\n}\n\nexport interface MediaPreviewController {\n play: () => Promise<void>;\n pause: () => void;\n seek: (seconds: number) => void;\n getState: () => MediaPlaybackState;\n isFrameReady: () => boolean;\n getIntrinsicSize: () => MediaIntrinsicSize | null;\n captureFrame: (type?: 'image/png' | 'image/jpeg', quality?: number) => Promise<MediaFrameCapture | null>;\n}\n\nexport interface MediaPreviewProps {\n /** Where the bytes are served from. */\n src: string;\n /** The file's path, used for the accessible name and the download name. */\n path: string;\n /** Overrides the kind inferred from the path, for a server that knows better. */\n kind?: MediaKind;\n className?: string;\n videoControls?: boolean;\n 'data-testid'?: string;\n /** Video-only controller. It is assigned while the video element is mounted. */\n controllerRef?: import('react').Ref<MediaPreviewController>;\n /** PDF-only page and geometry controller. */\n pdfControllerRef?: import('react').Ref<PdfPreviewController>;\n /** Reports browser playback state changes for video previews. */\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nconst FRAME = 'max-w-full rounded border border-doom-border bg-doom-deep';\n\ninterface VideoPreviewProps {\n src: string;\n className?: string;\n testId?: string;\n videoControls?: boolean;\n controllerRef?: import('react').Ref<MediaPreviewController>;\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nexport function mediaPlaybackState(video: HTMLVideoElement): MediaPlaybackState {\n return {\n playing: !video.paused && !video.ended,\n currentTime: video.currentTime,\n duration: Number.isFinite(video.duration) ? video.duration : 0,\n };\n}\n\nexport function mediaPreviewController(\n videoRef: { readonly current: HTMLVideoElement | null },\n frameMetadataRef: { readonly current: MediaFrameMetadata | undefined } = { current: undefined },\n): MediaPreviewController {\n return {\n play: async () => {\n const video = videoRef.current;\n if (video !== null) await video.play();\n },\n pause: () => videoRef.current?.pause(),\n seek: (seconds) => {\n const video = videoRef.current;\n if (video !== null) video.currentTime = boundedMediaTime(seconds, video.duration);\n },\n getState: () => {\n const video = videoRef.current;\n return video === null ? { playing: false, currentTime: 0, duration: 0 } : mediaPlaybackState(video);\n },\n isFrameReady: () => {\n const video = videoRef.current;\n return (\n video !== null &&\n !video.seeking &&\n video.readyState >= 2 &&\n (video.requestVideoFrameCallback === undefined || frameMetadataRef.current !== undefined)\n );\n },\n getIntrinsicSize: () => {\n const video = videoRef.current;\n return video === null || video.videoWidth <= 0 || video.videoHeight <= 0\n ? null\n : { width: video.videoWidth, height: video.videoHeight };\n },\n captureFrame: async (type = 'image/png', quality) => {\n const video = videoRef.current;\n if (video === null || video.videoWidth <= 0 || video.videoHeight <= 0 || video.seeking) return null;\n const metadata = frameMetadataRef.current === undefined ? undefined : { ...frameMetadataRef.current };\n const timeSeconds = metadata?.mediaTime ?? video.currentTime;\n const canvas = document.createElement('canvas');\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n const context = canvas.getContext('2d');\n if (context === null) return null;\n context.drawImage(video, 0, 0, canvas.width, canvas.height);\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (blob === null) return null;\n return {\n blob,\n width: canvas.width,\n height: canvas.height,\n timeSeconds,\n ...(metadata === undefined ? {} : { metadata }),\n };\n },\n };\n}\n\nfunction VideoPreview({\n src,\n className,\n testId,\n controllerRef,\n onPlaybackStateChange,\n videoControls = true,\n}: VideoPreviewProps) {\n const videoRef = useRef<HTMLVideoElement>(null);\n const frameMetadataRef = useRef<MediaFrameMetadata | undefined>(undefined);\n const reportState = () => {\n const video = videoRef.current;\n if (video !== null) onPlaybackStateChange?.(mediaPlaybackState(video));\n };\n const reportStateRef = useRef(reportState);\n useEffect(() => {\n reportStateRef.current = reportState;\n });\n useImperativeHandle(controllerRef, () => mediaPreviewController(videoRef, frameMetadataRef), []);\n useEffect(() => {\n const video = videoRef.current;\n if (video === null || video.requestVideoFrameCallback === undefined) return;\n let request = 0;\n const report: VideoFrameRequestCallback = (_now, metadata) => {\n frameMetadataRef.current = {\n mediaTime: metadata.mediaTime,\n ...(Number.isFinite(metadata.presentedFrames) ? { presentedFrames: metadata.presentedFrames } : {}),\n };\n reportStateRef.current();\n request = video.requestVideoFrameCallback(report);\n };\n request = video.requestVideoFrameCallback(report);\n return () => video.cancelVideoFrameCallback(request);\n }, []);\n return (\n <video\n ref={videoRef}\n src={src}\n controls={videoControls}\n playsInline\n preload=\"metadata\"\n data-testid={testId}\n data-kind=\"video\"\n className={cn(FRAME, 'max-h-[36rem]', className)}\n onPlay={reportState}\n onPause={reportState}\n onTimeUpdate={reportState}\n onDurationChange={reportState}\n onEnded={reportState}\n onLoadedMetadata={reportState}\n onLoadedData={reportState}\n onSeeking={() => {\n frameMetadataRef.current = undefined;\n reportState();\n }}\n onSeeked={reportState}\n >\n <track kind=\"captions\" />\n </video>\n );\n}\n\nexport function MediaPreview({\n src,\n path,\n kind,\n className,\n controllerRef,\n pdfControllerRef,\n onPlaybackStateChange,\n videoControls,\n 'data-testid': testId,\n}: MediaPreviewProps) {\n const resolved = kind ?? mediaKindOf(path);\n const name = path.split('/').at(-1) ?? path;\n\n if (resolved === 'image') {\n return (\n <a href={src} target=\"_blank\" rel=\"noreferrer\" data-testid={testId} data-kind={resolved}>\n <img src={src} alt={path} className={cn(FRAME, 'max-h-[36rem]', className)} />\n </a>\n );\n }\n if (resolved === 'video') {\n return (\n <VideoPreview\n src={src}\n className={className}\n controllerRef={controllerRef}\n onPlaybackStateChange={onPlaybackStateChange}\n testId={testId}\n videoControls={videoControls}\n />\n );\n }\n if (resolved === 'pdf') {\n return (\n <PdfPreview src={src} path={path} controllerRef={pdfControllerRef} data-testid={testId} className={className} />\n );\n }\n return (\n <Badge\n asChild\n size=\"md\"\n data-testid={testId}\n data-kind={resolved}\n className={cn('self-start bg-doom-panel text-doom-text hover:border-doom-blue/50', className)}\n >\n <a href={src} download={name}>\n <FileIcon className=\"h-3 w-3 shrink-0 text-doom-faint\" />\n download {name}\n </a>\n </Badge>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MermaidDiagram.mjs","names":[],"sources":["../../../../src/components/MermaidDiagram.tsx"],"sourcesContent":["import { useEffect, useId, useState } from 'react';\n\nimport { renderMermaid } from '../lib/mermaidDiagram';\nimport { SyntaxText } from './SyntaxText';\n\n/**\n * A mermaid fence, drawn.\n *\n * DESIGN PATTERNS:\n * - The source is the fallback, never a spinner or an error box. A diagram\n * that has not loaded yet, a diagram that fails to parse and a diagram in a\n * half-streamed message all show the text the author wrote, which stays\n * useful on its own.\n * - The rendered markup is stored with the source it came from, so a message\n * that grows never paints the previous frame's picture over new text.\n *\n * AVOID:\n * - Rendering at module scope or during render: mermaid measures text in the\n * document, so it only runs in an effect, in a browser.\n */\n\ninterface Drawn {\n source: string;\n svg: string;\n}\n\nexport function MermaidDiagram({ code }: { code: string }) {\n // Mermaid puts the id in the DOM and in the SVG's own ids, so React's\n // colon-wrapped value has to lose its punctuation first.\n const id = `mermaid-${useId().replaceAll(/[^a-zA-Z0-9]/g, '')}`;\n const [drawn, setDrawn] = useState<Drawn | undefined>(undefined);\n\n useEffect(() => {\n let live = true;\n void renderMermaid(id, code).then(\n (svg) => {\n if (live) setDrawn({ source: code, svg });\n },\n // Invalid syntax and a chunk that will not load are the same outcome\n // here: the block keeps showing its source.\n () => undefined,\n );\n return () => {\n live = false;\n };\n }, [code, id]);\n\n if (drawn?.source !== code) return <SyntaxText text={code} className=\"text-doom-text\" />;\n return (\n <div\n data-testid=\"mermaid-diagram\"\n // Mermaid sanitises its own output under the strict security level set\n // in lib/mermaidDiagram.ts; this is the only way it hands back a figure.\n dangerouslySetInnerHTML={{ __html: drawn.svg }}\n className=\"flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full\"\n />\n );\n}\n"],"mappings":"2MA0BA,SAAgB,EAAe,CAAE,QAA0B,CAGzD,IAAM,EAAK,WAAW,EAAM,CAAC,CAAC,WAAW,gBAAiB,EAAE,IACtD,CAAC,EAAO,GAAY,EAA4B,IAAA,EAAS,EAkB/D,OAhBA,MAAgB,CACd,IAAI,EAAO,GASX,OARA,EAAmB,EAAI,CAAI,CAAC,CAAC,KAC1B,GAAQ,CACH,GAAM,EAAS,CAAE,OAAQ,EAAM,KAAI,CAAC,CAC1C,MAGM,IAAA,EACR,MACa,CACX,EAAO,EACT,CACF,EAAG,CAAC,EAAM,CAAE,CAAC,EAET,GAAO,SAAW,EAEpB,kBAAC,MAAD,CACE,cAAY,kBAGZ,wBAAyB,CAAE,OAAQ,EAAM,GAAI,EAC7C,UAAU,uEACX,CAAA,EARgC,kBAAC,EAAD,CAAY,KAAM,EAAM,UAAU,gBAAkB,CAAA,CAUzF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageItem.d.mts","names":[],"sources":["../../../../src/components/MessageItem.tsx"],"mappings":";;;;;;;;;;;;iBAiBiB;EACf,MAAM;;EAEN;EACA;EACA;;;wBAWc,kBAAkB;;qBAarB,sBAAmB;;6CAG9B;;qBAGW,yBAAsB;;6CAGjC;iBAEe,yBACP,KAAK,oCAAoC,oBAAoB;;EAErE;EACA;;EAEA;EACA,oBAAoB;;EAEpB,WAAW,cAAc,OAAO,qBAAqB;;wBAGvC,cACd,WACA,MACA,YACA,iBACA,UACA,kBACA,aACG,SACF,mCAAgB,IAAA;iBA8BF,8BACP,KAAK,iCAAiC,oBAAoB;;EAElE,OAAO;;EAEP,UAAU;;EAEV,QAAQ;EACR,WAAW;;;;;;;;;;;;wBAaG,mBACd,WACA,MACA,OACA,SACA,OACA,aACG,SACF,wCAAqB,IAAA;;wBAiBR,SAAS;EAAS;EAAkB;IAAqB;;qBAK5D,cAAc,SAAS,OAAO;iBAS1B,+BAA+B,KAAK;;EAEnD,OAAO;;EAEP,QAAQ;;EAER,WAAW;;;;;;;;;;;wBAeG,oBAAoB,WAAW,OAAO,OAAO,aAAa,SAAS,yCAAsB,IAAA;;wBAsCzF,kBAAkB,cAAc,SAAS,wCAAqB,IAAA;;qBAWjE,cAAc,SAAS,OAAO;qBAS9B,4BAAyB;;6CAYpC;iBAEe,+BAA+B,wBAAwB,oBAAoB;;EAE1F;;EAEA;;;wBAIc,oBACd,WACA,MACA,OACA,SACA,aACG,SACF,yCAAsB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageItem.mjs","names":[],"sources":["../../../../src/components/MessageItem.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { type ComponentProps, createContext, type ReactNode, useContext, useState } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\nimport { STATUS_EDGE, StatusBadge, type StatusTone } from './StatusBadge';\n\n/**\n * The message item: the timeline card a tool call, a run, or a notice sits\n * in. The item owns its outcome tone and its expand state; the header, body,\n * and status parts read both from it, so a card composes the parts and never\n * threads `expanded` by hand. A tool message in a web plugin is built from\n * this, and so is the cockpit's own fallback item, which is what keeps them\n * looking alike.\n */\n\nexport interface MessageItemState {\n tone: StatusTone;\n /** Whether the header offers the toggle; an item that hides nothing offers none. */\n expandable: boolean;\n expanded: boolean;\n toggle: () => void;\n}\n\nconst MessageItemContext = createContext<MessageItemState>({\n tone: 'neutral',\n expandable: false,\n expanded: false,\n toggle: () => undefined,\n});\n\n/** The enclosing item's state, for a part that lives deeper than the item's render prop. */\nexport function useMessageItem(): MessageItemState {\n return useContext(MessageItemContext);\n}\n\n/**\n * The group an item is a row of, or null for an item that is a card of its\n * own. A row drops the frame the group already draws and keeps its tone as an\n * edge down its left side, and it stops repeating what the group's header has\n * said once: the tool's name, and an outcome the whole run shares.\n */\nconst MessageItemGroupContext = createContext<{ tone: StatusTone } | null>(null);\n\n/** The frame, wearing the edge STATUS_EDGE names for the tone, so the two never drift apart. */\nexport const messageItemVariants = cva('overflow-hidden rounded-md border bg-doom-panel transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The same tone as a row: no card, one coloured edge, and the group's separators between rows. */\nexport const messageItemRowVariants = cva('overflow-hidden border-l-2 transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemProps\n extends Omit<ComponentProps<'div'>, 'children'>, VariantProps<typeof messageItemVariants> {\n /** Whether the header offers the expand toggle. A toggle that reveals nothing reads as broken, so the card decides. */\n expandable?: boolean;\n defaultExpanded?: boolean;\n /** Controlled mode; pair with onExpandedChange. Omit it and the item keeps its own state. */\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n /** Plain content, or a function of the item's state for a card that picks its lines by `expanded`. */\n children?: ReactNode | ((state: MessageItemState) => ReactNode);\n}\n\nexport function MessageItem({\n className,\n tone,\n expandable = false,\n defaultExpanded = false,\n expanded,\n onExpandedChange,\n children,\n ...props\n}: MessageItemProps) {\n const [own, setOwn] = useState(defaultExpanded);\n const group = useContext(MessageItemGroupContext);\n const grouped = group !== null;\n const current = expanded ?? own;\n const state: MessageItemState = {\n tone: tone ?? 'neutral',\n expandable,\n expanded: current,\n toggle: () => {\n const next = !current;\n if (expanded === undefined) setOwn(next);\n onExpandedChange?.(next);\n },\n };\n return (\n <MessageItemContext.Provider value={state}>\n <div\n data-slot=\"message-item\"\n data-expanded={current}\n data-grouped={grouped}\n className={cn(grouped ? messageItemRowVariants({ tone }) : messageItemVariants({ tone }), className)}\n {...props}\n >\n {typeof children === 'function' ? children(state) : children}\n </div>\n </MessageItemContext.Provider>\n );\n}\n\nexport interface MessageItemGroupProps\n extends Omit<ComponentProps<'div'>, 'title'>, VariantProps<typeof messageItemVariants> {\n /** The bold label at the left of the group header: the tool the run belongs to. */\n title: ReactNode;\n /** The line beside it, such as how many calls the group holds. */\n summary?: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n children?: ReactNode;\n}\n\n/**\n * One frame around a run of items that belong together.\n *\n * A transcript that calls the same tool five times in a row is five identical\n * frames, five gutter labels and five gaps, and the repetition reads louder\n * than the commands do. The group draws the frame once and each item inside it\n * becomes a row: same header, same expand, no card of its own. The tone still\n * belongs to the row, as an edge, so a failure in the middle of a run is not\n * flattened into the group's own outcome.\n */\nexport function MessageItemGroup({\n className,\n tone,\n title,\n summary,\n badge,\n children,\n ...props\n}: MessageItemGroupProps) {\n const label = badge === undefined ? STATUS_LABEL[tone ?? 'neutral'] : badge;\n return (\n <MessageItemGroupContext.Provider value={{ tone: tone ?? 'neutral' }}>\n <div data-slot=\"message-item-group\" className={cn(messageItemVariants({ tone }), className)} {...props}>\n <div className=\"flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim\">\n <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span>\n <span className=\"min-w-0 flex-1 truncate text-doom-faint\">{summary}</span>\n {label !== null && label !== '' ? <StatusBadge tone={tone ?? 'neutral'}>{label}</StatusBadge> : null}\n </div>\n <div className=\"flex flex-col divide-y divide-doom-border-soft\">{children}</div>\n </div>\n </MessageItemGroupContext.Provider>\n );\n}\n\n/** The tone a tool call's item wears: running while the tool runs, then its outcome. */\nexport function toolTone(state: { running: boolean; isError: boolean }): StatusTone {\n return state.running ? 'running' : state.isError ? 'error' : 'ok';\n}\n\n/** The badge text a tone reads as when the header is not told otherwise; empty hides the badge. */\nexport const STATUS_LABEL: Readonly<Record<StatusTone, string>> = {\n neutral: '',\n running: 'RUNNING',\n ok: 'OK',\n error: 'ERROR',\n info: 'INFO',\n accent: 'NOTE',\n};\n\nexport interface MessageItemHeaderProps extends Omit<ComponentProps<'div'>, 'title'> {\n /** The bold label at the left: the tool name. */\n title: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n /** The summary beside the title; it gets the remaining width. */\n children?: ReactNode;\n}\n\n/** Inside a group these two are the quiet outcome: the group's header has already said it. */\nconst SILENT_IN_GROUP: ReadonlySet<StatusTone> = new Set<StatusTone>(['ok', 'neutral']);\n\n/**\n * The title row: label, summary, the tone's badge, and the expand toggle when\n * the item is expandable.\n *\n * A row inside a group says less. The group's header has already named the\n * tool and stated the run's outcome, so the row drops its title and speaks up\n * only when something went wrong or is still going: five OK badges down a run\n * of five are noise, and the one ERROR among them is the point.\n */\nexport function MessageItemHeader({ className, title, badge, children, ...props }: MessageItemHeaderProps) {\n const { tone, expandable, expanded, toggle } = useMessageItem();\n const group = useContext(MessageItemGroupContext);\n const defaultLabel = group !== null && SILENT_IN_GROUP.has(tone) ? null : STATUS_LABEL[tone];\n const label = badge === undefined ? defaultLabel : badge;\n return (\n <div\n data-slot=\"message-item-header\"\n className={cn('flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim', className)}\n {...props}\n >\n {group === null ? <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span> : null}\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n {label !== null && label !== '' ? (\n <StatusBadge tone={tone} data-testid=\"tool-status\">\n {label}\n </StatusBadge>\n ) : null}\n {expandable ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"tool-expand\"\n aria-expanded={expanded}\n aria-label={expanded ? 'collapse' : 'expand'}\n onClick={toggle}\n className=\"text-doom-faint hover:text-doom-blue\"\n >\n {expanded ? <ChevronUpIcon className=\"h-3 w-3\" /> : <ChevronDownIcon className=\"h-3 w-3\" />}\n </Button>\n ) : null}\n </div>\n );\n}\n\n/** The recessed body under the header. */\nexport function MessageItemBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"message-item-body\"\n className={cn('border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim', className)}\n {...props}\n />\n );\n}\n\n/** The glyph a tone reads as in a status line. */\nexport const STATUS_GLYPH: Readonly<Record<StatusTone, string>> = {\n neutral: '…',\n running: '◐',\n ok: '✓',\n error: '✗',\n info: '●',\n accent: '●',\n};\n\nexport const messageItemStatusVariants = cva('shrink-0', {\n variants: {\n tone: {\n neutral: 'text-doom-faint',\n running: 'text-doom-yellow',\n ok: 'text-doom-green',\n error: 'text-doom-red',\n info: 'text-doom-blue',\n accent: 'text-doom-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemStatusProps extends ComponentProps<'span'>, VariantProps<typeof messageItemStatusVariants> {\n /** Replaces the tone's glyph. */\n glyph?: string;\n /** Renders as a button that expands the item: the \"N more line(s)\" hint. Only className carries over. */\n expands?: boolean;\n}\n\n/** The one-line status under a body: `◐ running`, `✗ failed`, `✓ done`, or the hint that more is hidden. */\nexport function MessageItemStatus({\n className,\n tone,\n glyph,\n expands = false,\n children,\n ...props\n}: MessageItemStatusProps) {\n const { toggle } = useMessageItem();\n const content = (\n <>\n <span className={messageItemStatusVariants({ tone })}>{glyph ?? STATUS_GLYPH[tone ?? 'neutral']}</span>\n <span>{children}</span>\n </>\n );\n if (expands) {\n return (\n <button\n type=\"button\"\n data-slot=\"message-item-status\"\n data-testid=\"tool-more\"\n onClick={toggle}\n className={cn(\n 'flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue',\n className,\n )}\n >\n {content}\n </button>\n );\n }\n return (\n <span\n data-slot=\"message-item-status\"\n className={cn('flex items-center gap-1.5 text-doom-faint', className)}\n {...props}\n >\n {content}\n </span>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageLines.d.mts","names":[],"sources":["../../../../src/components/MessageLines.tsx"],"mappings":";;;;YAOY,kBAAkB;iBAEb;EACf;EACA,MAAM;EACN;EACA;;qBAGW,sBAAmB;;;;6CAgB9B;iBAEe,0BAA0B;EACzC,gBAAgB;;;wBAIF,eAAe,WAAW,UAAU,SAAS,oCAAiB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageLines.mjs","names":[],"sources":["../../../../src/components/MessageLines.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport type { MessageLineTone as Tone } from '../types/tone';\n\n/** One line of a message body, with the tone the card's pure view logic chose for it. */\nexport type MessageLineTone = Tone;\n\nexport interface MessageLine {\n text: string;\n tone: MessageLineTone;\n bold?: boolean;\n indent?: boolean;\n}\n\nexport const messageLineVariants = cva('whitespace-pre-wrap break-words', {\n variants: {\n tone: {\n hi: 'text-doom-hi',\n text: 'text-doom-text',\n dim: 'text-doom-dim',\n muted: 'text-doom-faint',\n success: 'text-doom-green',\n error: 'text-doom-red',\n warning: 'text-doom-yellow',\n accent: 'text-doom-blue',\n } satisfies Record<Tone, string>,\n bold: { true: 'font-bold', false: '' },\n indent: { true: 'pl-4', false: '' },\n },\n defaultVariants: { tone: 'dim', bold: false, indent: false },\n});\n\nexport interface MessageLinesProps extends ComponentProps<'div'> {\n lines: readonly MessageLine[];\n}\n\n/** A body of toned lines: what a card's view helper computed, drawn one line per row. */\nexport function MessageLines({ className, lines, ...props }: MessageLinesProps) {\n return (\n <div data-slot=\"message-lines\" className={cn('flex flex-col gap-0.5', className)} {...props}>\n {lines.map((line, index) => (\n <div\n key={`${String(index)}-${line.text}`}\n className={messageLineVariants({ tone: line.tone, bold: line.bold === true, indent: line.indent === true })}\n >\n {line.text}\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":"0HAgBA,MAAa,EAAsB,EAAI,kCAAmC,CACxE,SAAU,CACR,KAAM,CACJ,GAAI,eACJ,KAAM,iBACN,IAAK,gBACL,MAAO,kBACP,QAAS,kBACT,MAAO,gBACP,QAAS,mBACT,OAAQ,gBACV,EACA,KAAM,CAAE,KAAM,YAAa,MAAO,EAAG,EACrC,OAAQ,CAAE,KAAM,OAAQ,MAAO,EAAG,CACpC,EACA,gBAAiB,CAAE,KAAM,MAAO,KAAM,GAAO,OAAQ,EAAM,CAC7D,CAAC,EAOD,SAAgB,EAAa,CAAE,YAAW,QAAO,GAAG,GAA4B,CAC9E,MACE,kBAAC,MAAD,CAAK,YAAU,gBAAgB,UAAW,EAAG,wBAAyB,CAAS,EAAG,GAAI,EACnF,SAAA,EAAM,KAAK,EAAM,IAChB,kBAAC,MAAD,CAEE,UAAW,EAAoB,CAAE,KAAM,EAAK,KAAM,KAAM,EAAK,OAAS,GAAM,OAAQ,EAAK,SAAW,EAAK,CAAC,EAEzG,SAAA,EAAK,IACH,EAJE,GAAG,OAAO,CAAK,EAAE,GAAG,EAAK,MAI3B,CACN,CACE,CAAA,CAET"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OptionList.d.mts","names":[],"sources":["../../../../src/components/OptionList.tsx"],"mappings":";;;qBAMa,qBAAkB;;6CAM7B;qBAEW,oBAAiB;;;6CAc5B;qBAEW,uBAAoB;;6CAQ/B;iBAEe,uBAAuB,0BAA0B,oBAAoB;;EAEpF,SAAS;;;;;;;;;wBAUK,YAAY,WAAW,SAAS,QAAQ,QAAQ,aAAa,SAAS,iCAAc,IAAA;;wBAkBpF,cACd,WACA,YACG,SACF,yBAAyB,oBAAoB,sCAAmB,IAAA;iBAclD,wBACP,KAAK,oCAAoC,oBAAoB;EACrE;;EAEA;EACA,iBAAiB;EACjB,WAAW;;EAEX;;;;;;;;;;;;wBAac,aACd,WACA,SACA,QACA,gBACA,UACA,cACA,YACG,SACF,kCAAe,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OptionList.mjs","names":[],"sources":["../../../../src/components/OptionList.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { type ComponentProps, type ReactNode, useEffect, useRef } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { optionMarker } from '../lib/optionList';\n\nexport const optionListVariants = cva('flex min-h-0 flex-1 flex-col overflow-y-auto', {\n variants: {\n /** The compact rows of a bar popover, or the roomier rows of a modal. */\n density: { compact: 'gap-0.5 p-1.5', comfortable: 'gap-1.5' },\n },\n defaultVariants: { density: 'comfortable' },\n});\n\nexport const optionRowVariants = cva('flex shrink-0 cursor-pointer items-center text-left outline-none', {\n variants: {\n density: {\n compact: 'gap-2.5 rounded-md px-2 py-[7px]',\n comfortable: 'min-h-[42px] gap-3 rounded-md border px-[11px] py-2 text-sm text-doom-text transition-colors',\n },\n active: { true: '', false: '' },\n },\n compoundVariants: [\n { density: 'compact', active: true, class: 'bg-doom-tint-blue' },\n { density: 'comfortable', active: true, class: 'border-doom-edge-blue bg-doom-tint-blue' },\n { density: 'comfortable', active: false, class: 'border-doom-border-soft' },\n ],\n defaultVariants: { density: 'comfortable', active: false },\n});\n\nexport const optionMarkerVariants = cva('flex shrink-0 items-center justify-center rounded-full font-bold', {\n variants: {\n density: {\n compact: 'h-[15px] w-[15px] border border-doom-border text-2xs text-doom-faint',\n comfortable: 'h-[18px] w-[18px] bg-doom-deep text-xs text-doom-dim',\n },\n },\n defaultVariants: { density: 'comfortable' },\n});\n\nexport interface OptionRowProps extends ComponentProps<'button'>, VariantProps<typeof optionRowVariants> {\n /** The digit or bullet in the row's leading circle; omit it for a row with no shortcut. */\n marker?: ReactNode;\n}\n\n/**\n * One row of an option list, exported on its own so a surface with richer\n * rows than a plain string still wears the list's shape instead of restating\n * it. Children render straight into the row, so a row is free to hold a name\n * and a description side by side; OptionLabel is the single-string case.\n * `role=\"option\"` means a row belongs inside a `listbox`.\n */\nexport function OptionRow({ className, density, active, marker, children, ...props }: OptionRowProps) {\n return (\n <button\n type=\"button\"\n role=\"option\"\n data-slot=\"option-row\"\n aria-selected={active ?? false}\n data-cursor={active ?? false}\n className={cn(optionRowVariants({ density, active }), className)}\n {...props}\n >\n {marker === undefined ? null : <span className={optionMarkerVariants({ density })}>{marker}</span>}\n {children}\n </button>\n );\n}\n\n/** A row's single-string label: it takes the remaining width and clips or wraps by density. */\nexport function OptionLabel({\n className,\n density,\n ...props\n}: ComponentProps<'span'> & VariantProps<typeof optionListVariants>) {\n return (\n <span\n data-slot=\"option-label\"\n className={cn(\n 'min-w-0 flex-1',\n density === 'compact' ? 'truncate text-sm text-doom-text' : 'break-words',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport interface OptionListProps\n extends Omit<ComponentProps<'div'>, 'onSelect'>, VariantProps<typeof optionListVariants> {\n options: readonly string[];\n /** The highlighted row, owned by the surface so its own focused element can drive it. */\n cursor: number;\n onCursorChange: (cursor: number) => void;\n onSelect: (option: string) => void;\n /** Rows are `${testIdPrefix}-${index}`; the list itself is the plural, so a prefix query for a row never catches it. */\n testIdPrefix: string;\n}\n\n/**\n * The answers a select surface offers, wherever it is framed.\n *\n * The agent decides how many options there are, and a real one runs past\n * twenty, so the list cannot rely on the digit shortcuts alone. The cursor is\n * controlled rather than owned here because the surface around it is what the\n * overlay library focuses: keys arrive there, and taking focus away from it to\n * a list would fight the library for it and break the escape and outside-click\n * behaviour that focus carries. Pair it with handleOptionListKey.\n */\nexport function OptionList({\n className,\n options,\n cursor,\n onCursorChange,\n onSelect,\n testIdPrefix,\n density = 'comfortable',\n ...props\n}: OptionListProps) {\n const container = useRef<HTMLDivElement>(null);\n\n // Keep the highlighted row visible when the keyboard moves it past the edge.\n useEffect(() => {\n container.current?.children[cursor]?.scrollIntoView({ block: 'nearest' });\n }, [cursor]);\n\n return (\n <div\n ref={container}\n role=\"listbox\"\n aria-label=\"options\"\n data-slot=\"option-list\"\n data-testid={`${testIdPrefix}s`}\n className={cn(optionListVariants({ density }), className)}\n {...props}\n >\n {options.map((option, index) => (\n <OptionRow\n key={option}\n density={density}\n active={index === cursor}\n marker={optionMarker(index)}\n data-testid={`${testIdPrefix}-${String(index)}`}\n title={option}\n onMouseEnter={() => onCursorChange(index)}\n onClick={() => onSelect(option)}\n >\n <OptionLabel density={density}>{option}</OptionLabel>\n </OptionRow>\n ))}\n </div>\n );\n}\n"],"mappings":"uOAMA,MAAa,EAAqB,EAAI,+CAAgD,CACpF,SAAU,CAER,QAAS,CAAE,QAAS,gBAAiB,YAAa,SAAU,CAC9D,EACA,gBAAiB,CAAE,QAAS,aAAc,CAC5C,CAAC,EAEY,EAAoB,EAAI,mEAAoE,CACvG,SAAU,CACR,QAAS,CACP,QAAS,mCACT,YAAa,8FACf,EACA,OAAQ,CAAE,KAAM,GAAI,MAAO,EAAG,CAChC,EACA,iBAAkB,CAChB,CAAE,QAAS,UAAW,OAAQ,GAAM,MAAO,mBAAoB,EAC/D,CAAE,QAAS,cAAe,OAAQ,GAAM,MAAO,yCAA0C,EACzF,CAAE,QAAS,cAAe,OAAQ,GAAO,MAAO,yBAA0B,CAC5E,EACA,gBAAiB,CAAE,QAAS,cAAe,OAAQ,EAAM,CAC3D,CAAC,EAEY,EAAuB,EAAI,mEAAoE,CAC1G,SAAU,CACR,QAAS,CACP,QAAS,uEACT,YAAa,sDACf,CACF,EACA,gBAAiB,CAAE,QAAS,aAAc,CAC5C,CAAC,EAcD,SAAgB,EAAU,CAAE,YAAW,UAAS,SAAQ,SAAQ,WAAU,GAAG,GAAyB,CACpG,MACE,kBAAC,SAAD,CACE,KAAK,SACL,KAAK,SACL,YAAU,aACV,gBAAe,GAAU,GACzB,cAAa,GAAU,GACvB,UAAW,EAAG,EAAkB,CAAE,UAAS,QAAO,CAAC,EAAG,CAAS,EAC/D,GAAI,EAPN,SAAA,CASG,IAAW,IAAA,GAAY,KAAO,kBAAC,OAAD,CAAM,UAAW,EAAqB,CAAE,SAAQ,CAAC,EAAI,SAAA,CAAa,CAAA,EAChG,CACK,GAEZ,CAGA,SAAgB,EAAY,CAC1B,YACA,UACA,GAAG,GACgE,CACnE,MACE,kBAAC,OAAD,CACE,YAAU,eACV,UAAW,EACT,iBACA,IAAY,UAAY,kCAAoC,cAC5D,CACF,EACA,GAAI,CACL,CAAA,CAEL,CAuBA,SAAgB,EAAW,CACzB,YACA,UACA,SACA,iBACA,WACA,eACA,UAAU,cACV,GAAG,GACe,CAClB,IAAM,EAAY,EAAuB,IAAI,EAO7C,OAJA,MAAgB,CACd,EAAU,SAAS,SAAS,EAAO,EAAE,eAAe,CAAE,MAAO,SAAU,CAAC,CAC1E,EAAG,CAAC,CAAM,CAAC,EAGT,kBAAC,MAAD,CACE,IAAK,EACL,KAAK,UACL,aAAW,UACX,YAAU,cACV,cAAa,GAAG,EAAa,GAC7B,UAAW,EAAG,EAAmB,CAAE,SAAQ,CAAC,EAAG,CAAS,EACxD,GAAI,EAEH,SAAA,EAAQ,KAAK,EAAQ,IACpB,kBAAC,EAAD,CAEW,UACT,OAAQ,IAAU,EAClB,OAAQ,EAAa,CAAK,EAC1B,cAAa,GAAG,EAAa,GAAG,OAAO,CAAK,IAC5C,MAAO,EACP,iBAAoB,EAAe,CAAK,EACxC,YAAe,EAAS,CAAM,EAE9B,SAAA,kBAAC,EAAD,CAAsB,UAAU,SAAA,CAAoB,CAAA,CAC3C,EAVJ,CAUI,CACZ,CACE,CAAA,CAET"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Panel.d.mts","names":[],"sources":["../../../../src/components/Panel.tsx"],"mappings":";;iBAKiB,mBAAmB;;EAElC;;;wBAIc,QAAQ,WAAW,YAAoB,SAAS,6BAAU,IAAA;;wBAY1D,cAAc,cAAc,SAAS,wCAAqB,IAAA;;wBAO1D,YAAY,cAAc,SAAS,wCAAqB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Panel.mjs","names":[],"sources":["../../../../src/components/Panel.tsx"],"sourcesContent":["import { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\nexport interface PanelProps extends ComponentProps<'div'> {\n /** Render the child element instead of a <div>, so a list row can be a panel. */\n asChild?: boolean;\n}\n\n/** The bordered card surface: a tool card, a run card, a provider row. */\nexport function Panel({ className, asChild = false, ...props }: PanelProps) {\n const Component = asChild ? Slot.Root : 'div';\n return (\n <Component\n data-slot=\"panel\"\n className={cn('overflow-hidden rounded-md border border-doom-border bg-doom-panel', className)}\n {...props}\n />\n );\n}\n\n/** A panel's title row. */\nexport function PanelHeader({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div data-slot=\"panel-header\" className={cn('flex min-h-8 items-center gap-2 px-[11px]', className)} {...props} />\n );\n}\n\n/** A panel's recessed body: the deep well the header sits above. */\nexport function PanelBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"panel-body\"\n className={cn('border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim', className)}\n {...props}\n />\n );\n}\n"],"mappings":"2GAWA,SAAgB,EAAM,CAAE,YAAW,UAAU,GAAO,GAAG,GAAqB,CAC1E,IAAM,EAAY,EAAU,EAAK,KAAO,MACxC,MACE,kBAAC,EAAD,CACE,YAAU,QACV,UAAW,EAAG,qEAAsE,CAAS,EAC7F,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAgC,CAC1E,MACE,kBAAC,MAAD,CAAK,YAAU,eAAe,UAAW,EAAG,4CAA6C,CAAS,EAAG,GAAI,CAAQ,CAAA,CAErH,CAGA,SAAgB,EAAU,CAAE,YAAW,GAAG,GAAgC,CACxE,MACE,kBAAC,MAAD,CACE,YAAU,aACV,UAAW,EAAG,gFAAiF,CAAS,EACxG,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PdfPreview.d.mts","names":[],"sources":["../../../../src/components/PdfPreview.tsx"],"mappings":";iBAQiB;EACf;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;EACA;;iBAGe;EACf;EACA,MAAM;;iBAGS;EACf,gBAAgB;EAChB,UAAU;EACV,wBAAwB;IACtB;IACA;IACA;IACA;QACI;EACN,cAAc,mCAAmC,qBAAqB,QAAQ;;iBAG/D;EACf;EACA;EACA;EACA;EACA,gCAAgC,IAAI;;wBAUtB,yBACd,cACA;EAAU;EAAc;EAAa;EAAe;EAAgB;EAAe;GACnF;EAAa;EAAc;EAAa;EAAe;IACtD;;wBA0Ba,aAAa,KAAK,MAAM,WAAW,8BAA8B,UAAU,kCAAe,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PdfPreview.mjs","names":[],"sources":["../../../../src/components/PdfPreview.tsx"],"sourcesContent":["import type { PDFDocumentProxy, PDFPageProxy } from 'pdfjs-dist/webpack.mjs';\nimport { useEffect, useImperativeHandle, useRef, useState } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\n\ntype PdfLoadingTask = ReturnType<typeof import('pdfjs-dist/webpack.mjs').getDocument>;\n\nexport interface PdfNormalizedRectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface PdfPageState {\n page: number;\n pageCount: number;\n sourceWidth: number;\n sourceHeight: number;\n}\n\nexport interface PdfPageRegion {\n page: number;\n rect: PdfNormalizedRectangle;\n}\n\nexport interface PdfPreviewController {\n getState: () => PdfPageState;\n setPage: (page: number) => void;\n resolveViewportRegion: (rectangle: {\n left: number;\n top: number;\n right: number;\n bottom: number;\n }) => PdfPageRegion | null;\n capturePage: (type?: 'image/png' | 'image/jpeg', quality?: number) => Promise<Blob | null>;\n}\n\nexport interface PdfPreviewProps {\n src: string;\n path: string;\n className?: string;\n 'data-testid'?: string;\n controllerRef?: import('react').Ref<PdfPreviewController>;\n}\n\nconst EMPTY_STATE: PdfPageState = { page: 1, pageCount: 0, sourceWidth: 0, sourceHeight: 0 };\n\nfunction boundedPage(page: number, pageCount: number): number {\n if (!Number.isFinite(page) || pageCount <= 0) return 1;\n return Math.min(pageCount, Math.max(1, Math.trunc(page)));\n}\n\nexport function resolvePdfViewportRegion(\n page: number,\n bounds: { left: number; top: number; right: number; bottom: number; width: number; height: number },\n rectangle: { left: number; top: number; right: number; bottom: number },\n): PdfPageRegion | null {\n if (bounds.width <= 0 || bounds.height <= 0) return null;\n const left = Math.max(bounds.left, Math.min(bounds.right, rectangle.left));\n const right = Math.max(bounds.left, Math.min(bounds.right, rectangle.right));\n const top = Math.max(bounds.top, Math.min(bounds.bottom, rectangle.top));\n const bottom = Math.max(bounds.top, Math.min(bounds.bottom, rectangle.bottom));\n if (right <= left || bottom <= top) return null;\n return {\n page,\n rect: {\n x: (left - bounds.left) / bounds.width,\n y: (top - bounds.top) / bounds.height,\n width: (right - left) / bounds.width,\n height: (bottom - top) / bounds.height,\n },\n };\n}\nfunction canvasBlob(\n canvas: HTMLCanvasElement,\n type: 'image/png' | 'image/jpeg',\n quality?: number,\n): Promise<Blob | null> {\n return new Promise((resolve) => canvas.toBlob(resolve, type, quality));\n}\n\n/** A page-aware PDF canvas. Coordinates resolve against PDF page geometry rather than an opaque browser iframe. */\nexport function PdfPreview({ src, path, className, controllerRef, 'data-testid': testId }: PdfPreviewProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const documentRef = useRef<PDFDocumentProxy | null>(null);\n const renderTask = useRef<{ cancel(): void } | null>(null);\n const [page, setPage] = useState(1);\n const [pageState, setPageState] = useState<PdfPageState>(EMPTY_STATE);\n const [error, setError] = useState<string | undefined>();\n\n useEffect(() => {\n let disposed = false;\n let loading: PdfLoadingTask | undefined;\n // pdfjs is imported on demand: `pdfjs-dist/webpack.mjs` spins up its worker\n // at module scope, so a static import would make every consumer of this\n // package pay for the worker whether or not it ever shows a PDF.\n void import('pdfjs-dist/webpack.mjs')\n .then(({ getDocument }) => {\n if (disposed) return undefined;\n loading = getDocument({ url: src });\n return loading.promise.then((document) => {\n if (disposed) return;\n documentRef.current = document;\n setError(undefined);\n setPage(1);\n setPageState({ ...EMPTY_STATE, pageCount: document.numPages });\n });\n })\n .catch((reason: unknown) => {\n if (!disposed) setError(reason instanceof Error ? reason.message : String(reason));\n });\n return () => {\n disposed = true;\n void loading?.destroy();\n renderTask.current?.cancel();\n renderTask.current = null;\n documentRef.current = null;\n };\n }, [src]);\n\n useEffect(() => {\n const document = documentRef.current;\n const canvas = canvasRef.current;\n if (document === null || canvas === null) return;\n let disposed = false;\n void document\n .getPage(page)\n .then((pdfPage: PDFPageProxy) => {\n if (disposed) return;\n const source = pdfPage.getViewport({ scale: 1 });\n const viewport = pdfPage.getViewport({ scale: 1.5 });\n canvas.width = Math.ceil(viewport.width);\n canvas.height = Math.ceil(viewport.height);\n setPageState({ page, pageCount: document.numPages, sourceWidth: source.width, sourceHeight: source.height });\n const context = canvas.getContext('2d');\n if (context === null) return;\n const task = pdfPage.render({ canvas, canvasContext: context, viewport });\n renderTask.current = task;\n return task.promise;\n })\n .catch((reason: unknown) => {\n if (!disposed && (reason as { name?: unknown }).name !== 'RenderingCancelledException') {\n setError(reason instanceof Error ? reason.message : String(reason));\n }\n });\n return () => {\n disposed = true;\n renderTask.current?.cancel();\n renderTask.current = null;\n };\n }, [page, pageState.pageCount]);\n\n useImperativeHandle(\n controllerRef,\n () => ({\n getState: () => pageState,\n setPage: (next) => setPage(boundedPage(next, pageState.pageCount)),\n resolveViewportRegion: (rectangle) => {\n const canvas = canvasRef.current;\n if (canvas === null || pageState.pageCount === 0) return null;\n return resolvePdfViewportRegion(pageState.page, canvas.getBoundingClientRect(), rectangle);\n },\n capturePage: async (type = 'image/png', quality) => {\n const canvas = canvasRef.current;\n return canvas === null ? null : await canvasBlob(canvas, type, quality);\n },\n }),\n [pageState],\n );\n\n return (\n <section data-testid={testId} data-kind=\"pdf\" className={cn('flex min-h-0 flex-col gap-2', className)}>\n <div className=\"flex items-center justify-between gap-2 text-xs text-doom-faint\">\n <span>{path}</span>\n <div className=\"flex items-center gap-2\">\n <Button\n size=\"xs\"\n variant=\"ghost\"\n disabled={page <= 1}\n onClick={() => setPage((value) => Math.max(1, value - 1))}\n >\n previous\n </Button>\n <span data-testid={testId === undefined ? undefined : `${testId}-page`}>\n {pageState.pageCount === 0 ? 'loading' : `${page} / ${pageState.pageCount}`}\n </span>\n <Button\n size=\"xs\"\n variant=\"ghost\"\n disabled={pageState.pageCount === 0 || page >= pageState.pageCount}\n onClick={() => setPage((value) => boundedPage(value + 1, pageState.pageCount))}\n >\n next\n </Button>\n </div>\n </div>\n {error === undefined ? null : <output className=\"text-xs text-doom-red\">{error}</output>}\n <div className=\"min-h-0 overflow-auto rounded border border-doom-border bg-doom-deep\">\n <canvas ref={canvasRef} aria-label={path} className=\"mx-auto block max-w-full\" />\n </div>\n </section>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover.d.mts","names":[],"sources":["../../../../src/components/Popover.tsx"],"mappings":";;;;;;;iBASgB,UAAQ,OAAO,sBAAsB,QAAiB,wBAAK,IAAA;wBAI3D,eAAe,OAAO,sBAAsB,QAAiB,2BAAQ,IAAA;wBAIrE,cAAc,OAAO,sBAAsB,QAAiB,0BAAO,IAAA;;wBAKnE,aAAa,OAAO,sBAAsB,QAAiB,yBAAM,IAAA;wBAIjE,iBACd,WACA,OACA,eACG,SACF,sBAAsB,QAAiB,2BAAQ,IAAA;;wBAkBlC,gBAAgB,cAAc,SAAS,wCAAqB,IAAA;wBAa5D,gBAAgB,cAAc,SAAS,wCAAqB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover.mjs","names":["Popover","PopoverPrimitive"],"sources":["../../../../src/components/Popover.tsx"],"sourcesContent":["import { Popover as PopoverPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * shadcn's Popover on Radix: anchored to its trigger, closes on outside\n * click and Escape, and the trigger toggles it rather than reopening it.\n */\nexport function Popover(props: ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n}\n\nexport function PopoverTrigger(props: ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\n\nexport function PopoverAnchor(props: ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />;\n}\n\n/** Dismisses the popover from inside it: the row that acts and closes in one click. */\nexport function PopoverClose(props: ComponentProps<typeof PopoverPrimitive.Close>) {\n return <PopoverPrimitive.Close data-slot=\"popover-close\" {...props} />;\n}\n\nexport function PopoverContent({\n className,\n align = 'start',\n sideOffset = 6,\n ...props\n}: ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden rounded-lg border border-doom-border bg-doom-panel font-mono shadow-2xl outline-none data-[state=open]:animate-doom-rise',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n}\n\n/** The strip a popover's title sits in; tone colours the title. */\nexport function PopoverHeader({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"popover-header\"\n className={cn(\n 'flex h-[34px] shrink-0 items-center justify-between gap-3 border-b border-doom-border-soft bg-doom-deep px-3',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function PopoverFooter({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"popover-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":"8GASA,SAAgBA,EAAQ,EAAqD,CAC3E,MAAO,kBAACC,EAAiB,KAAlB,CAAuB,YAAU,UAAU,GAAI,CAAQ,CAAA,CAChE,CAEA,SAAgB,EAAe,EAAwD,CACrF,MAAO,kBAACA,EAAiB,QAAlB,CAA0B,YAAU,kBAAkB,GAAI,CAAQ,CAAA,CAC3E,CAEA,SAAgB,EAAc,EAAuD,CACnF,MAAO,kBAACA,EAAiB,OAAlB,CAAyB,YAAU,iBAAiB,GAAI,CAAQ,CAAA,CACzE,CAGA,SAAgB,EAAa,EAAsD,CACjF,MAAO,kBAACA,EAAiB,MAAlB,CAAwB,YAAU,gBAAgB,GAAI,CAAQ,CAAA,CACvE,CAEA,SAAgB,EAAe,CAC7B,YACA,QAAQ,QACR,aAAa,EACb,GAAG,GAC+C,CAClD,MACE,kBAACA,EAAiB,OAAlB,CAAA,SACE,kBAACA,EAAiB,QAAlB,CACE,YAAU,kBACH,QACK,aACZ,UAAW,EACT,uLACA,CACF,EACA,GAAI,CACL,CAAA,CACsB,CAAA,CAE7B,CAGA,SAAgB,EAAc,CAAE,YAAW,GAAG,GAAgC,CAC5E,MACE,kBAAC,MAAD,CACE,YAAU,iBACV,UAAW,EACT,+GACA,CACF,EACA,GAAI,CACL,CAAA,CAEL,CAEA,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":"Progress.d.mts","names":[],"sources":["../../../../src/components/Progress.tsx"],"mappings":";;;;iBAMgB,aAAW,WAAW,UAAU,SAAS,sBAAsB,SAAkB,wBAAK,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Progress.mjs","names":["Progress","ProgressPrimitive"],"sources":["../../../../src/components/Progress.tsx"],"sourcesContent":["import { Progress as ProgressPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A determinate bar; leave `value` undefined and Radix reports it as indeterminate. */\nexport function Progress({ className, value, ...props }: ComponentProps<typeof ProgressPrimitive.Root>) {\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n value={value}\n className={cn('relative h-1 w-full overflow-hidden rounded-full bg-doom-deep', className)}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className=\"h-full w-full flex-1 bg-doom-blue transition-transform\"\n style={{ transform: `translateX(-${String(100 - (value ?? 0))}%)` }}\n />\n </ProgressPrimitive.Root>\n );\n}\n"],"mappings":"+GAMA,SAAgBA,EAAS,CAAE,YAAW,QAAO,GAAG,GAAwD,CACtG,MACE,kBAACC,EAAkB,KAAnB,CACE,YAAU,WACH,QACP,UAAW,EAAG,gEAAiE,CAAS,EACxF,GAAI,EAEJ,SAAA,kBAACA,EAAkB,UAAnB,CACE,YAAU,qBACV,UAAU,yDACV,MAAO,CAAE,UAAW,eAAe,OAAO,KAAO,GAAS,EAAE,EAAE,GAAI,CACnE,CAAA,CACqB,CAAA,CAE5B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioGroup.d.mts","names":[],"sources":["../../../../src/components/RadioGroup.tsx"],"mappings":";;;;iBAMgB,eAAa,cAAc,SAAS,sBAAsB,WAAoB,wBAAK,IAAA;wBAMnF,iBAAiB,cAAc,SAAS,sBAAsB,WAAoB,wBAAK,IAAA;;;;;;wBAuBvF,iBAAiB,cAAc,SAAS,sBAAsB,WAAoB,wBAAK,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioGroup.mjs","names":["RadioGroup","RadioGroupPrimitive"],"sources":["../../../../src/components/RadioGroup.tsx"],"sourcesContent":["import { RadioGroup as RadioGroupPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** One choice out of several; Radix owns the arrow-key roving focus a native group has. */\nexport function RadioGroup({ className, ...props }: ComponentProps<typeof RadioGroupPrimitive.Root>) {\n return (\n <RadioGroupPrimitive.Root data-slot=\"radio-group\" className={cn('flex flex-col gap-2', className)} {...props} />\n );\n}\n\nexport function RadioGroupItem({ className, ...props }: ComponentProps<typeof RadioGroupPrimitive.Item>) {\n return (\n <RadioGroupPrimitive.Item\n data-slot=\"radio-group-item\"\n className={cn(\n 'flex h-3.5 w-3.5 shrink-0 cursor-pointer items-center justify-center rounded-full 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',\n className,\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator\n data-slot=\"radio-group-indicator\"\n className=\"block h-1.5 w-1.5 rounded-full bg-doom-blue\"\n />\n </RadioGroupPrimitive.Item>\n );\n}\n\n/**\n * A whole card that is one radio choice: the theme picker, where the target is\n * the preview rather than a dot. Radix keeps the roving focus and the checked\n * state; the card supplies the frame.\n */\nexport function RadioGroupCard({ className, ...props }: ComponentProps<typeof RadioGroupPrimitive.Item>) {\n return (\n <RadioGroupPrimitive.Item\n data-slot=\"radio-group-card\"\n className={cn(\n 'cursor-pointer rounded-md border border-doom-border bg-doom-panel p-2 text-left outline-none transition-colors hover:border-doom-blue/50 focus-visible:ring-2 focus-visible:ring-doom-blue/50 data-[state=checked]:border-doom-blue data-[state=checked]:bg-doom-tint-blue',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"iHAMA,SAAgBA,EAAW,CAAE,YAAW,GAAG,GAA0D,CACnG,MACE,kBAACC,EAAoB,KAArB,CAA0B,YAAU,cAAc,UAAW,EAAG,sBAAuB,CAAS,EAAG,GAAI,CAAQ,CAAA,CAEnH,CAEA,SAAgB,EAAe,CAAE,YAAW,GAAG,GAA0D,CACvG,MACE,kBAACA,EAAoB,KAArB,CACE,YAAU,mBACV,UAAW,EACT,sSACA,CACF,EACA,GAAI,EAEJ,SAAA,kBAACA,EAAoB,UAArB,CACE,YAAU,wBACV,UAAU,6CACX,CAAA,CACuB,CAAA,CAE9B,CAOA,SAAgB,EAAe,CAAE,YAAW,GAAG,GAA0D,CACvG,MACE,kBAACA,EAAoB,KAArB,CACE,YAAU,mBACV,UAAW,EACT,6QACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollArea.d.mts","names":[],"sources":["../../../../src/components/ScrollArea.tsx"],"mappings":";;;;;;;;iBAUgB,eAAa,WAAW,aAAa,SAAS,sBAAsB,WAAoB,wBAAK,IAAA;wBAY7F,YACd,WACA,gBACG,SACF,sBAAsB,WAAoB,uCAAoB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollArea.mjs","names":["ScrollArea","ScrollAreaPrimitive"],"sources":["../../../../src/components/ScrollArea.tsx"],"sourcesContent":["import { ScrollArea as ScrollAreaPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * A scroll container with a styled bar. The base stylesheet already themes\n * the native scrollbar, so reach for this only where the bar must overlay the\n * content or sit inside a rounded surface that clips it.\n */\nexport function ScrollArea({ className, children, ...props }: ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n return (\n <ScrollAreaPrimitive.Root data-slot=\"scroll-area\" className={cn('relative overflow-hidden', className)} {...props}>\n <ScrollAreaPrimitive.Viewport data-slot=\"scroll-area-viewport\" className=\"h-full w-full rounded-[inherit]\">\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nexport function ScrollBar({\n className,\n orientation = 'vertical',\n ...props\n}: ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n 'flex touch-none select-none',\n orientation === 'vertical' ? 'h-full w-2.5 p-px' : 'h-2.5 flex-col p-px',\n className,\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"relative flex-1 rounded-full bg-doom-border\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n}\n"],"mappings":"2HAUA,SAAgBA,EAAW,CAAE,YAAW,WAAU,GAAG,GAA0D,CAC7G,MACE,kBAACC,EAAoB,KAArB,CAA0B,YAAU,cAAc,UAAW,EAAG,2BAA4B,CAAS,EAAG,GAAI,EAA5G,SAAA,CACE,kBAACA,EAAoB,SAArB,CAA8B,YAAU,uBAAuB,UAAU,kCACtE,UAC2B,CAAA,EAC9B,kBAAC,EAAD,CAAY,CAAA,EACZ,kBAACA,EAAoB,OAArB,CAA6B,CAAA,CACL,GAE9B,CAEA,SAAgB,EAAU,CACxB,YACA,cAAc,WACd,GAAG,GAC8D,CACjE,MACE,kBAACA,EAAoB,oBAArB,CACE,YAAU,wBACG,cACb,UAAW,EACT,8BACA,IAAgB,WAAa,oBAAsB,sBACnD,CACF,EACA,GAAI,EAEJ,SAAA,kBAACA,EAAoB,gBAArB,CACE,YAAU,oBACV,UAAU,6CACX,CAAA,CACsC,CAAA,CAE7C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionLabel.d.mts","names":[],"sources":["../../../../src/components/SectionLabel.tsx"],"mappings":";;;wBAKgB,eAAe,cAAc,SAAS,yCAAsB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionLabel.mjs","names":[],"sources":["../../../../src/components/SectionLabel.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** The tiny tracked-out caps that head every cockpit section (SESSIONS, ACTIVITY, MINOR MODES). */\nexport function SectionLabel({ className, ...props }: ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"section-label\"\n className={cn('font-mono text-2xs font-bold tracking-widest text-doom-faint uppercase', className)}\n {...props}\n />\n );\n}\n"],"mappings":"2EAKA,SAAgB,EAAa,CAAE,YAAW,GAAG,GAAiC,CAC5E,MACE,kBAAC,OAAD,CACE,YAAU,gBACV,UAAW,EAAG,yEAA0E,CAAS,EACjG,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.mts","names":[],"sources":["../../../../src/components/Select.tsx"],"mappings":";;;;;;;;iBAWgB,SAAO,OAAO,sBAAsB,OAAgB,wBAAK,IAAA;wBAIzD,YAAY,OAAO,sBAAsB,OAAgB,yBAAM,IAAA;wBAI/D,YAAY,OAAO,sBAAsB,OAAgB,yBAAM,IAAA;wBAI/D,gBAAgB,WAAW,aAAa,SAAS,sBAAsB,OAAgB,2BAAQ,IAAA;wBAkB/F,gBACd,WACA,UACA,YACA,aACG,SACF,sBAAsB,OAAgB,2BAAQ,IAAA;wBAmBjC,cAAc,cAAc,SAAS,sBAAsB,OAAgB,yBAAM,IAAA;wBAUjF,aAAa,WAAW,aAAa,SAAS,sBAAsB,OAAgB,wBAAK,IAAA;wBAoBzF,kBAAkB,cAAc,SAAS,sBAAsB,OAAgB,6BAAU,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.mjs","names":["Select","SelectPrimitive"],"sources":["../../../../src/components/Select.tsx"],"sourcesContent":["import { Select as SelectPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CheckIcon, ChevronDownIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\n\n/**\n * A single choice from a list, on Radix rather than a native <select>: a\n * native one cannot be styled to the palette on every platform, and the\n * cockpit's model and mode pickers need the same surface a popover has.\n */\nexport function Select(props: ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nexport function SelectGroup(props: ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nexport function SelectValue(props: ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nexport function SelectTrigger({ className, children, ...props }: ComponentProps<typeof SelectPrimitive.Trigger>) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n className={cn(\n 'flex h-7 cursor-pointer items-center justify-between gap-2 rounded border border-doom-border bg-doom-deep px-2.5 font-mono text-sm text-doom-hi outline-none transition-colors hover:border-doom-blue/50 focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 data-[placeholder]:text-doom-faint',\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"h-3 w-3 shrink-0 text-doom-faint\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nexport function SelectContent({\n className,\n position = 'popper',\n sideOffset = 4,\n children,\n ...props\n}: ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n position={position}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 max-h-[320px] min-w-[var(--radix-select-trigger-width)] overflow-hidden rounded border border-doom-border bg-doom-panel font-mono shadow-xl outline-none data-[state=open]:animate-doom-rise',\n className,\n )}\n {...props}\n >\n <SelectPrimitive.Viewport className=\"p-1\">{children}</SelectPrimitive.Viewport>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nexport function SelectLabel({ className, ...props }: ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn('px-2 py-1 text-2xs font-bold tracking-wider text-doom-faint uppercase', className)}\n {...props}\n />\n );\n}\n\nexport function SelectItem({ className, children, ...props }: ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n 'relative flex cursor-pointer items-center gap-2 rounded-sm py-1.5 pr-2 pl-7 text-sm text-doom-hi outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-40 data-[highlighted]:bg-doom-deep',\n className,\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex h-3 w-3 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"h-3 w-3 text-doom-blue\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nexport function SelectSeparator({ className, ...props }: ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn('my-1 h-px bg-doom-border-soft', className)}\n {...props}\n />\n );\n}\n"],"mappings":"2LAWA,SAAgBA,EAAO,EAAoD,CACzE,MAAO,kBAACC,EAAgB,KAAjB,CAAsB,YAAU,SAAS,GAAI,CAAQ,CAAA,CAC9D,CAEA,SAAgB,EAAY,EAAqD,CAC/E,MAAO,kBAACA,EAAgB,MAAjB,CAAuB,YAAU,eAAe,GAAI,CAAQ,CAAA,CACrE,CAEA,SAAgB,EAAY,EAAqD,CAC/E,MAAO,kBAACA,EAAgB,MAAjB,CAAuB,YAAU,eAAe,GAAI,CAAQ,CAAA,CACrE,CAEA,SAAgB,EAAc,CAAE,YAAW,WAAU,GAAG,GAAyD,CAC/G,MACE,kBAACA,EAAgB,QAAjB,CACE,YAAU,iBACV,UAAW,EACT,oVACA,CACF,EACA,GAAI,EANN,SAAA,CAQG,EACD,kBAACA,EAAgB,KAAjB,CAAsB,QAAA,GACpB,SAAA,kBAAC,EAAD,CAAiB,UAAU,kCAAoC,CAAA,CAC3C,CAAA,CACC,GAE7B,CAEA,SAAgB,EAAc,CAC5B,YACA,WAAW,SACX,aAAa,EACb,WACA,GAAG,GAC8C,CACjD,MACE,kBAACA,EAAgB,OAAjB,CAAA,SACE,kBAACA,EAAgB,QAAjB,CACE,YAAU,iBACA,WACE,aACZ,UAAW,EACT,oMACA,CACF,EACA,GAAI,EAEJ,SAAA,kBAACA,EAAgB,SAAjB,CAA0B,UAAU,MAAO,UAAmC,CAAA,CACvD,CAAA,CACH,CAAA,CAE5B,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAuD,CACjG,MACE,kBAACA,EAAgB,MAAjB,CACE,YAAU,eACV,UAAW,EAAG,wEAAyE,CAAS,EAChG,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAW,CAAE,YAAW,WAAU,GAAG,GAAsD,CACzG,MACE,kBAACA,EAAgB,KAAjB,CACE,YAAU,cACV,UAAW,EACT,2NACA,CACF,EACA,GAAI,EANN,SAAA,CAQE,kBAAC,OAAD,CAAM,UAAU,+EACd,SAAA,kBAACA,EAAgB,cAAjB,CAAA,SACE,kBAAC,EAAD,CAAW,UAAU,wBAA0B,CAAA,CAClB,CAAA,CAC3B,CAAA,EACN,kBAACA,EAAgB,SAAjB,CAA2B,UAAmC,CAAA,CAC1C,GAE1B,CAEA,SAAgB,EAAgB,CAAE,YAAW,GAAG,GAA2D,CACzG,MACE,kBAACA,EAAgB,UAAjB,CACE,YAAU,mBACV,UAAW,EAAG,gCAAiC,CAAS,EACxD,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Separator.d.mts","names":[],"sources":["../../../../src/components/Separator.tsx"],"mappings":";;;;;;;;;iBAWgB,cACd,WACA,aACA,eACG,SACF,sBAAsB,UAAmB,wBAAK,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Separator.mjs","names":["Separator","SeparatorPrimitive"],"sources":["../../../../src/components/Separator.tsx"],"sourcesContent":["import { Separator as SeparatorPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * A hairline in the soft border colour. Radix decides the semantics: a\n * decorative rule is hidden from assistive tech, a meaningful one keeps its\n * separator role, and either way the element carries `data-orientation` so a\n * consumer can style around it the way it does every other primitive.\n */\nexport function Separator({\n className,\n orientation = 'horizontal',\n decorative = true,\n ...props\n}: ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n orientation={orientation}\n decorative={decorative}\n className={cn(\n 'shrink-0 bg-doom-border-soft',\n orientation === 'vertical' ? 'h-full w-px' : 'h-px w-full',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"gHAWA,SAAgBA,EAAU,CACxB,YACA,cAAc,aACd,aAAa,GACb,GAAG,GAC8C,CACjD,MACE,kBAACC,EAAmB,KAApB,CACE,YAAU,YACG,cACD,aACZ,UAAW,EACT,+BACA,IAAgB,WAAa,cAAgB,cAC7C,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sheet.d.mts","names":[],"sources":["../../../../src/components/Sheet.tsx"],"mappings":";;;;;;;;;;;wBAegB,MAAM,OAAO,sBAAsB,OAAe,wBAAK,IAAA;wBAIvD,aAAa,OAAO,sBAAsB,OAAe,2BAAQ,IAAA;wBAIjE,WAAW,OAAO,sBAAsB,OAAe,yBAAM,IAAA;wBAI7D,eAAe,cAAc,SAAS,sBAAsB,OAAe,2BAAQ,IAAA;iBAelF,0BAA0B,sBAAsB,OAAe;;EAE9E;;EAEA;;wBAKc,eAAe,WAAW,UAAU,MAAgB,UAAiB,SAAS,oCAAiB,IAAA;iBAqB9F,yBAAyB;;EAExC;;EAEA;;wBAGc,cACd,WACA,aACA,YACA,aACG,SACF,mCAAgB,IAAA;wBAwBH,aAAa,cAAc,SAAS,sBAAsB,OAAe,yBAAM,IAAA;wBAU/E,mBAAmB,cAAc,SAAS,sBAAsB,OAAe,+BAAY,IAAA;wBAU3F,YAAY,cAAc,SAAS,wCAAqB,IAAA;wBAUxD,cAAc,cAAc,SAAS,wCAAqB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sheet.mjs","names":["SheetPrimitive"],"sources":["../../../../src/components/Sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\n\n/**\n * A side panel on Radix's Dialog: an overlay that slides in from an edge,\n * with the focus trap, Escape, outside click and scroll lock a dialog has.\n *\n * It is the Dialog for content that reads as a column rather than a form: a\n * detail view beside what the reader was looking at. An inline aside cannot\n * do this, because it takes width from the surface underneath it.\n */\nexport function Sheet(props: ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\nexport function SheetTrigger(props: ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nexport function SheetClose(props: ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nexport function SheetOverlay({ className, ...props }: ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn('fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade', className)}\n {...props}\n />\n );\n}\n\nconst SIDE_POSITION = {\n right: 'inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right',\n left: 'inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left',\n} as const;\n\nexport interface SheetContentProps extends ComponentProps<typeof SheetPrimitive.Content> {\n /** Which edge it comes from. */\n side?: 'right' | 'left';\n /** Width preset; `className` may still override. */\n width?: 'sm' | 'md' | 'lg';\n}\n\nconst CONTENT_WIDTH = { sm: 'w-[360px]', md: 'w-[440px]', lg: 'w-[560px]' } as const;\n\nexport function SheetContent({ className, children, side = 'right', width = 'md', ...props }: SheetContentProps) {\n return (\n <SheetPrimitive.Portal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n 'fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none',\n SIDE_POSITION[side],\n CONTENT_WIDTH[width],\n className,\n )}\n {...props}\n >\n {children}\n </SheetPrimitive.Content>\n </SheetPrimitive.Portal>\n );\n}\n\nexport interface SheetHeaderProps extends ComponentProps<'div'> {\n /** Show the close control at the right of the strip. On by default: a sheet is dismissed, not answered. */\n dismissible?: boolean;\n /** What the close control announces. */\n closeLabel?: string;\n}\n\nexport function SheetHeader({\n className,\n dismissible = true,\n closeLabel = 'close',\n children,\n ...props\n}: SheetHeaderProps) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4', className)}\n {...props}\n >\n {children}\n {dismissible ? (\n <SheetPrimitive.Close asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={closeLabel}\n className=\"ml-auto text-doom-faint hover:text-doom-hi\"\n >\n <CloseIcon className=\"h-3 w-3\" />\n </Button>\n </SheetPrimitive.Close>\n ) : null}\n </div>\n );\n}\n\nexport function SheetTitle({ className, ...props }: ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn('truncate text-base font-bold text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function SheetDescription({ className, ...props }: ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function SheetBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-body\"\n className={cn('flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto px-4 py-3', className)}\n {...props}\n />\n );\n}\n\nexport function SheetFooter({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n 'flex min-h-[34px] shrink-0 flex-wrap items-center justify-between gap-2 border-t border-doom-border-soft bg-doom-deep px-4 py-1.5',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"4MAeA,SAAgB,EAAM,EAAmD,CACvE,MAAO,kBAACA,EAAe,KAAhB,CAAqB,YAAU,QAAQ,GAAI,CAAQ,CAAA,CAC5D,CAEA,SAAgB,EAAa,EAAsD,CACjF,MAAO,kBAACA,EAAe,QAAhB,CAAwB,YAAU,gBAAgB,GAAI,CAAQ,CAAA,CACvE,CAEA,SAAgB,EAAW,EAAoD,CAC7E,MAAO,kBAACA,EAAe,MAAhB,CAAsB,YAAU,cAAc,GAAI,CAAQ,CAAA,CACnE,CAEA,SAAgB,EAAa,CAAE,YAAW,GAAG,GAAwD,CACnG,MACE,kBAACA,EAAe,QAAhB,CACE,YAAU,gBACV,UAAW,EAAG,yEAA0E,CAAS,EACjG,GAAI,CACL,CAAA,CAEL,CAEA,MAAM,EAAgB,CACpB,MAAO,wEACP,KAAM,qEACR,EASM,EAAgB,CAAE,GAAI,YAAa,GAAI,YAAa,GAAI,WAAY,EAE1E,SAAgB,EAAa,CAAE,YAAW,WAAU,OAAO,QAAS,QAAQ,KAAM,GAAG,GAA4B,CAC/G,MACE,kBAACA,EAAe,OAAhB,CAAA,SAAA,CACE,kBAAC,EAAD,CAAe,CAAA,EACf,kBAACA,EAAe,QAAhB,CACE,YAAU,gBACV,YAAW,EACX,UAAW,EACT,sIACA,EAAc,GACd,EAAc,GACd,CACF,EACA,GAAI,EAEH,UACqB,CAAA,CACH,CAAA,CAAA,CAE3B,CASA,SAAgB,EAAY,CAC1B,YACA,cAAc,GACd,aAAa,QACb,WACA,GAAG,GACgB,CACnB,MACE,kBAAC,MAAD,CACE,YAAU,eACV,UAAW,EAAG,mFAAoF,CAAS,EAC3G,GAAI,EAHN,SAAA,CAKG,EACA,EACC,kBAACA,EAAe,MAAhB,CAAsB,QAAA,GACpB,SAAA,kBAAC,EAAD,CACE,QAAQ,QACR,KAAK,OACL,aAAY,EACZ,UAAU,6CAEV,SAAA,kBAAC,EAAD,CAAW,UAAU,SAAW,CAAA,CAC1B,CAAA,CACY,CAAA,EACpB,IACD,GAET,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,kBAACA,EAAe,MAAhB,CACE,YAAU,cACV,UAAW,EAAG,4CAA6C,CAAS,EACpE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAiB,CAAE,YAAW,GAAG,GAA4D,CAC3G,MACE,kBAACA,EAAe,YAAhB,CACE,YAAU,oBACV,UAAW,EAAG,wCAAyC,CAAS,EAChE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAU,CAAE,YAAW,GAAG,GAAgC,CACxE,MACE,kBAAC,MAAD,CACE,YAAU,aACV,UAAW,EAAG,+DAAgE,CAAS,EACvF,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAgC,CAC1E,MACE,kBAAC,MAAD,CACE,YAAU,eACV,UAAW,EACT,oIACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.d.mts","names":[],"sources":["../../../../src/components/Skeleton.tsx"],"mappings":";;;;;;;wBASgB,WAAW,cAAc,SAAS,wCAAqB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.mjs","names":[],"sources":["../../../../src/components/Skeleton.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The shape of content that has not arrived. It has no Radix counterpart; it\n * is a pulsing block, and it is aria-hidden because the live region that\n * announces the wait belongs to the surface, not to each placeholder.\n */\nexport function Skeleton({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"skeleton\"\n aria-hidden\n className={cn('animate-pulse rounded bg-doom-border-soft', className)}\n {...props}\n />\n );\n}\n"],"mappings":"2EASA,SAAgB,EAAS,CAAE,YAAW,GAAG,GAAgC,CACvE,MACE,kBAAC,MAAD,CACE,YAAU,WACV,cAAA,GACA,UAAW,EAAG,4CAA6C,CAAS,EACpE,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.d.mts","names":[],"sources":["../../../../src/components/Spinner.tsx"],"mappings":";;iBAKiB,qBAAqB;;;;;;EAMpC;;;wBAIc,UAAU,WAAW,UAAU,SAAS,+BAAY,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.mjs","names":[],"sources":["../../../../src/components/Spinner.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { LoaderIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\n\nexport interface SpinnerProps extends ComponentProps<'svg'> {\n /**\n * What the wait is for. Given one, the spinner announces itself as a live\n * status instead of staying silent, which is the difference between a\n * screen reader saying \"loading providers\" and saying nothing at all.\n */\n label?: string;\n}\n\n/** A turning loader in the current text colour; decorative unless it is given a label. */\nexport function Spinner({ className, label, ...props }: SpinnerProps) {\n const icon = (\n <LoaderIcon data-slot=\"spinner\" aria-hidden className={cn('h-3 w-3 animate-spin', className)} {...props} />\n );\n if (label === undefined) return icon;\n return (\n <output data-slot=\"spinner-status\" className=\"inline-flex items-center\">\n {icon}\n <span className=\"sr-only\">{label}</span>\n </output>\n );\n}\n"],"mappings":"qIAeA,SAAgB,EAAQ,CAAE,YAAW,QAAO,GAAG,GAAuB,CACpE,IAAM,EACJ,kBAAC,EAAD,CAAY,YAAU,UAAU,cAAA,GAAY,UAAW,EAAG,uBAAwB,CAAS,EAAG,GAAI,CAAQ,CAAA,EAG5G,OADI,IAAU,IAAA,GAAkB,EAE9B,kBAAC,SAAD,CAAQ,YAAU,iBAAiB,UAAU,2BAA7C,SAAA,CACG,EACD,kBAAC,OAAD,CAAM,UAAU,UAAW,SAAA,CAAY,CAAA,CACjC,GAEZ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBadge.d.mts","names":[],"sources":["../../../../src/components/StatusBadge.tsx"],"mappings":";;;;qBAOa,sBAAmB;;;6CAqB/B;YAEW,aAAa;;;;;;qBAOZ,aAAa,SAAS,OAAO;iBASzB,yBAAyB,wBAAwB,oBAAoB;;EAEpF;;;wBAIc,cAAc,WAAW,MAAM,MAAM,YAAoB,SAAS,mCAAgB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBadge.mjs","names":[],"sources":["../../../../src/components/StatusBadge.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 { StatusTone as Tone } from '../types/tone';\n\nexport const statusBadgeVariants = cva(\n 'inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-sm font-mono font-bold uppercase',\n {\n variants: {\n tone: {\n neutral: 'bg-doom-panel text-doom-faint',\n running: 'bg-doom-tint-yellow text-doom-yellow',\n ok: 'bg-doom-tint-green text-doom-green',\n error: 'bg-doom-tint-red text-doom-red',\n info: 'bg-doom-tint-blue text-doom-blue',\n accent: 'bg-doom-tint-magenta text-doom-magenta',\n } satisfies Record<Tone, string>,\n size: {\n xs: 'px-1.5 py-0.5 text-2xs',\n sm: 'px-[7px] py-[3px] text-xs',\n md: 'h-[21px] px-2 text-sm normal-case',\n lg: 'h-6 px-2.5 text-base normal-case',\n },\n },\n defaultVariants: { tone: 'neutral', size: 'sm' },\n },\n);\n\nexport type StatusTone = Tone;\n\n/**\n * The border a card wears for a status, the same tint family as the badge.\n * MessageItem builds its frame variants from this table, so a tone's edge is\n * named once and a card and its badge can never disagree about it.\n */\nexport const STATUS_EDGE: Readonly<Record<StatusTone, string>> = {\n neutral: 'border-doom-border',\n running: 'border-doom-edge-yellow',\n ok: 'border-doom-edge-green',\n error: 'border-doom-edge-red',\n info: 'border-doom-edge-blue',\n accent: 'border-doom-edge-magenta',\n};\n\nexport interface StatusBadgeProps extends ComponentProps<'span'>, VariantProps<typeof statusBadgeVariants> {\n /** Render the child element instead of a <span>, so a link can look like a pill. */\n asChild?: boolean;\n}\n\n/** The tinted outcome pill: RUNNING, OK, ERROR and their kin, as every run card draws it. */\nexport function StatusBadge({ className, tone, size, asChild = false, ...props }: StatusBadgeProps) {\n const Component = asChild ? Slot.Root : 'span';\n return (\n <Component data-slot=\"status-badge\" className={cn(statusBadgeVariants({ tone, size }), className)} {...props} />\n );\n}\n"],"mappings":"0JAOA,MAAa,EAAsB,EACjC,uGACA,CACE,SAAU,CACR,KAAM,CACJ,QAAS,gCACT,QAAS,uCACT,GAAI,qCACJ,MAAO,iCACP,KAAM,mCACN,OAAQ,wCACV,EACA,KAAM,CACJ,GAAI,yBACJ,GAAI,4BACJ,GAAI,oCACJ,GAAI,kCACN,CACF,EACA,gBAAiB,CAAE,KAAM,UAAW,KAAM,IAAK,CACjD,CACF,EASa,EAAoD,CAC/D,QAAS,qBACT,QAAS,0BACT,GAAI,yBACJ,MAAO,uBACP,KAAM,wBACN,OAAQ,0BACV,EAQA,SAAgB,EAAY,CAAE,YAAW,OAAM,OAAM,UAAU,GAAO,GAAG,GAA2B,CAClG,IAAM,EAAY,EAAU,EAAK,KAAO,OACxC,MACE,kBAAC,EAAD,CAAW,YAAU,eAAe,UAAW,EAAG,EAAoB,CAAE,OAAM,MAAK,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CAEnH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamCursor.d.mts","names":[],"sources":["../../../../src/components/StreamCursor.tsx"],"mappings":";;;wBAKgB,eAAe,cAAc,SAAS,yCAAsB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamCursor.mjs","names":[],"sources":["../../../../src/components/StreamCursor.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** The blinking block that marks text still arriving. */\nexport function StreamCursor({ className, ...props }: ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"stream-cursor\"\n aria-hidden\n className={cn('ml-0.5 inline-block h-3.5 w-2 translate-y-0.5 animate-doom-blink bg-doom-blue', className)}\n {...props}\n />\n );\n}\n"],"mappings":"2EAKA,SAAgB,EAAa,CAAE,YAAW,GAAG,GAAiC,CAC5E,MACE,kBAAC,OAAD,CACE,YAAU,gBACV,cAAA,GACA,UAAW,EAAG,gFAAiF,CAAS,EACxG,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Switch.d.mts","names":[],"sources":["../../../../src/components/Switch.tsx"],"mappings":";;;;iBAMgB,WAAS,cAAc,SAAS,sBAAsB,OAAgB,wBAAK,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Switch.mjs","names":["Switch","SwitchPrimitive"],"sources":["../../../../src/components/Switch.tsx"],"sourcesContent":["import { Switch as SwitchPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** An on/off track; use it where the change takes effect immediately, a checkbox where it needs a save. */\nexport function Switch({ className, ...props }: ComponentProps<typeof SwitchPrimitive.Root>) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n className={cn(\n 'inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full border border-doom-border bg-doom-deep p-px 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=checked]:bg-doom-tint-blue',\n className,\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className=\"block h-3 w-3 rounded-full bg-doom-faint transition-transform data-[state=checked]:translate-x-3 data-[state=checked]:bg-doom-blue\"\n />\n </SwitchPrimitive.Root>\n );\n}\n"],"mappings":"6GAMA,SAAgBA,EAAO,CAAE,YAAW,GAAG,GAAsD,CAC3F,MACE,kBAACC,EAAgB,KAAjB,CACE,YAAU,SACV,UAAW,EACT,sUACA,CACF,EACA,GAAI,EAEJ,SAAA,kBAACA,EAAgB,MAAjB,CACE,YAAU,eACV,UAAU,oIACX,CAAA,CACmB,CAAA,CAE1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyntaxText.d.mts","names":[],"sources":["../../../../src/components/SyntaxText.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;iBA8BiB;;EAEf;;EAEA,UAAU;;;;;;;;;;wBAWI,eAAe,cAAc,QAAO,cAAmB;iBAyBtD,wBAAwB,KAAK;;EAE5C,iBAAiB;EACjB;;;wBAIc,aAAa,OAAO,SAAS,SAAS,kCAAe,IAAA;iBAapD,wBAAwB,KAAK,oCAAoC;EAChF;;;wBAIc,aAAa,WAAW,MAAM,MAAM,YAAY,SAAS,kCAAe,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyntaxText.mjs","names":["Fragment"],"sources":["../../../../src/components/SyntaxText.tsx"],"sourcesContent":["import { type ComponentProps, Fragment, useEffect, useState } from 'react';\n\nimport { cn } from '../lib/cn';\nimport type { GrammarKey } from '../lib/editorLanguage';\nimport {\n detectGrammar,\n highlightToLines,\n type SyntaxLines,\n type SyntaxSpan,\n syntaxStyleOf,\n} from '../lib/syntaxHighlight';\n\n/**\n * Read-only code with the editor's colours.\n *\n * Two shapes over one hook, because the cards need both: `SyntaxText` for a\n * block of code that owns its own element, and `SyntaxLine` for a card that\n * already renders a line at a time next to a gutter. Highlighting is\n * asynchronous, so both show the plain text first and swap in spans once the\n * grammar has loaded; a result that never highlights simply stays plain.\n *\n * DESIGN PATTERNS:\n * - Plain text is the fallback, never a spinner: colour is decoration.\n * - The hook keys on the text, so a streaming result re-highlights as it grows.\n *\n * AVOID:\n * - Highlighting one line at a time. A line is not a parse unit; pass the whole\n * block to `useSyntaxLines` and render the line you want out of the result.\n */\n\nexport interface SyntaxQuery {\n /** The file the code came from, when the tool knows one. */\n path?: string | undefined;\n /** Skips detection when the caller already knows the grammar. */\n grammar?: GrammarKey | undefined;\n}\n\n/**\n * Colours `text`, or hands back undefined while that is still loading and for\n * anything with no grammar. Rendering the result is the caller's business.\n *\n * The finished spans are stored with the text they belong to, so text that has\n * changed since reads as plain during render rather than showing the previous\n * result's colours over the new lines.\n */\nexport function useSyntaxLines(text: string, query: SyntaxQuery = {}): SyntaxLines | undefined {\n const { path, grammar } = query;\n const key = grammar ?? detectGrammar({ path, text });\n const signature = `${key ?? ''}\\u0000${text}`;\n const [done, setDone] = useState<{ signature: string; lines: SyntaxLines } | undefined>(undefined);\n\n useEffect(() => {\n if (key === undefined) return;\n let live = true;\n void highlightToLines(text, key).then(\n (result) => {\n if (live && result !== undefined) setDone({ signature, lines: result });\n },\n // A grammar chunk that fails to load leaves the plain text in place: the\n // card stays readable and the network failure is the browser's to report.\n () => undefined,\n );\n return () => {\n live = false;\n };\n }, [text, key, signature]);\n\n return done?.signature === signature ? done.lines : undefined;\n}\n\nexport interface SyntaxLineProps extends Omit<ComponentProps<'span'>, 'children'> {\n /** The line's spans from `useSyntaxLines`, or undefined to show `text` plain. */\n spans?: readonly SyntaxSpan[] | undefined;\n text: string;\n}\n\n/** One line: coloured when its spans are in, the plain text until then. */\nexport function SyntaxLine({ spans, text, ...props }: SyntaxLineProps) {\n if (spans === undefined) return <span {...props}>{text}</span>;\n return (\n <span {...props}>\n {spans.map((span, index) => (\n <span key={index} style={syntaxStyleOf(span.token)}>\n {span.text}\n </span>\n ))}\n </span>\n );\n}\n\nexport interface SyntaxTextProps extends Omit<ComponentProps<'pre'>, 'children'>, SyntaxQuery {\n text: string;\n}\n\n/** A block of code, wrapped rather than clipped, coloured when a grammar is known. */\nexport function SyntaxText({ className, text, path, grammar, ...props }: SyntaxTextProps) {\n const lines = useSyntaxLines(text, { path, grammar });\n const plain = text.split('\\n');\n return (\n <pre\n data-slot=\"syntax-text\"\n data-highlighted={lines !== undefined}\n className={cn('whitespace-pre-wrap break-words [overflow-wrap:anywhere] font-mono', className)}\n {...props}\n >\n {(lines ?? plain).map((entry, index) => (\n <Fragment key={index}>\n {index > 0 ? '\\n' : null}\n <SyntaxLine\n spans={typeof entry === 'string' ? undefined : entry}\n text={typeof entry === 'string' ? entry : ''}\n />\n </Fragment>\n ))}\n </pre>\n );\n}\n"],"mappings":"uPA6CA,SAAgB,EAAe,EAAc,EAAqB,CAAC,EAA4B,CAC7F,GAAM,CAAE,OAAM,WAAY,EACpB,EAAM,GAAW,EAAc,CAAE,OAAM,MAAK,CAAC,EAC7C,EAAY,GAAG,GAAO,GAAG,QAAQ,IACjC,CAAC,EAAM,GAAW,EAAgE,IAAA,EAAS,EAkBjG,OAhBA,MAAgB,CACd,GAAI,IAAQ,IAAA,GAAW,OACvB,IAAI,EAAO,GASX,OARA,EAAsB,EAAM,CAAG,CAAC,CAAC,KAC9B,GAAW,CACN,GAAQ,IAAW,IAAA,IAAW,EAAQ,CAAE,YAAW,MAAO,CAAO,CAAC,CACxE,MAGM,IAAA,EACR,MACa,CACX,EAAO,EACT,CACF,EAAG,CAAC,EAAM,EAAK,CAAS,CAAC,EAElB,GAAM,YAAc,EAAY,EAAK,MAAQ,IAAA,EACtD,CASA,SAAgB,EAAW,CAAE,QAAO,OAAM,GAAG,GAA0B,CAErE,OADI,IAAU,IAAA,GAAkB,kBAAC,OAAD,CAAM,GAAI,EAAQ,SAAA,CAAW,CAAA,EAE3D,kBAAC,OAAD,CAAM,GAAI,EACP,SAAA,EAAM,KAAK,EAAM,IAChB,kBAAC,OAAD,CAAkB,MAAO,EAAc,EAAK,KAAK,EAC9C,SAAA,EAAK,IACF,EAFK,CAEL,CACP,CACG,CAAA,CAEV,CAOA,SAAgB,EAAW,CAAE,YAAW,OAAM,OAAM,UAAS,GAAG,GAA0B,CACxF,IAAM,EAAQ,EAAe,EAAM,CAAE,OAAM,SAAQ,CAAC,EAC9C,EAAQ,EAAK,MAAM;CAAI,EAC7B,MACE,kBAAC,MAAD,CACE,YAAU,cACV,mBAAkB,IAAU,IAAA,GAC5B,UAAW,EAAG,qEAAsE,CAAS,EAC7F,GAAI,EAEF,UAAA,GAAS,EAAA,CAAO,KAAK,EAAO,IAC5B,kBAACA,EAAD,CAAA,SAAA,CACG,EAAQ,EAAI;EAAO,KACpB,kBAAC,EAAD,CACE,MAAO,OAAO,GAAU,SAAW,IAAA,GAAY,EAC/C,KAAM,OAAO,GAAU,SAAW,EAAQ,EAC3C,CAAA,CACO,CAAA,EANK,CAML,CACX,CACE,CAAA,CAET"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.d.mts","names":[],"sources":["../../../../src/components/Tabs.tsx"],"mappings":";;;;;;;;;qBAYa,cAAW;;6CAWvB;;qBAGY,mBAAgB;;6CAQ5B;iBAEgB,oBAAoB,qBAAqB,oBAAoB;;EAE5E;;;;;;;wBAQc,SAAS,WAAW,QAAQ,YAAoB,SAAS,8BAAW,IAAA;;wBAapE,cACd,WACA,WACG,SACF,yBAAyB,oBAAoB,oCAAiB,IAAA;;iBAKjD,OAAK,OAAO,sBAAsB,KAAc,wBAAK,IAAA;wBAIrD,WAAW,cAAc,SAAS,sBAAsB,KAAc,wBAAK,IAAA;wBAI3E,cAAc,cAAc,SAAS,sBAAsB,KAAc,2BAAQ,IAAA;wBAcjF,cAAc,cAAc,SAAS,sBAAsB,KAAc,2BAAQ,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.mjs","names":["Tabs","TabsPrimitive"],"sources":["../../../../src/components/Tabs.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Tabs as TabsPrimitive } from 'radix-ui';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The look a tab wears, whether Radix drives it or a router link does. It is\n * exported because the cockpit's own tabs navigate routes rather than swap\n * panels, and a link that looks like a tab must not be a second implementation.\n */\nexport const tabVariants = cva(\n 'flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none',\n {\n variants: {\n active: {\n true: 'bg-doom-tint-blue font-bold text-doom-blue',\n false: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n },\n },\n defaultVariants: { active: false },\n },\n);\n\n/** The count a tab carries; it inverts on the active tab so it stays readable on the tint. */\nexport const tabBadgeVariants = cva(\n 'flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold',\n {\n variants: {\n active: { true: 'bg-doom-blue text-doom-rail', false: 'bg-doom-panel text-doom-dim' },\n },\n defaultVariants: { active: false },\n },\n);\n\nexport interface NavTabProps extends ComponentProps<'a'>, VariantProps<typeof tabVariants> {\n /** Render the child element instead of an <a>, so a router Link can be the tab. */\n asChild?: boolean;\n}\n\n/**\n * A tab that navigates. Radix Tabs owns panels and roving focus over content\n * it renders; a route-driven tab strip has neither, so it gets the styling and\n * leaves the semantics to the router.\n */\nexport function NavTab({ className, active, asChild = false, ...props }: NavTabProps) {\n const Component = asChild ? Slot.Root : 'a';\n return (\n <Component\n data-slot=\"nav-tab\"\n data-active={active ?? false}\n className={cn(tabVariants({ active }), className)}\n {...props}\n />\n );\n}\n\n/** The count beside a tab's label. */\nexport function NavTabBadge({\n className,\n active,\n ...props\n}: ComponentProps<'span'> & VariantProps<typeof tabBadgeVariants>) {\n return <span data-slot=\"nav-tab-badge\" className={cn(tabBadgeVariants({ active }), className)} {...props} />;\n}\n\n/** Radix Tabs, for a surface that swaps panels in place rather than navigating. */\nexport function Tabs(props: ComponentProps<typeof TabsPrimitive.Root>) {\n return <TabsPrimitive.Root data-slot=\"tabs\" {...props} />;\n}\n\nexport function TabsList({ className, ...props }: ComponentProps<typeof TabsPrimitive.List>) {\n return <TabsPrimitive.List data-slot=\"tabs-list\" className={cn('flex items-center gap-1', className)} {...props} />;\n}\n\nexport function TabsTrigger({ className, ...props }: ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n tabVariants({ active: false }),\n 'data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TabsContent({ className, ...props }: ComponentProps<typeof TabsPrimitive.Content>) {\n return <TabsPrimitive.Content data-slot=\"tabs-content\" className={cn('min-h-0 flex-1', className)} {...props} />;\n}\n"],"mappings":"oKAYA,MAAa,EAAc,EACzB,oHACA,CACE,SAAU,CACR,OAAQ,CACN,KAAM,6CACN,MAAO,sDACT,CACF,EACA,gBAAiB,CAAE,OAAQ,EAAM,CACnC,CACF,EAGa,EAAmB,EAC9B,8FACA,CACE,SAAU,CACR,OAAQ,CAAE,KAAM,8BAA+B,MAAO,6BAA8B,CACtF,EACA,gBAAiB,CAAE,OAAQ,EAAM,CACnC,CACF,EAYA,SAAgB,EAAO,CAAE,YAAW,SAAQ,UAAU,GAAO,GAAG,GAAsB,CACpF,IAAM,EAAY,EAAU,EAAK,KAAO,IACxC,MACE,kBAAC,EAAD,CACE,YAAU,UACV,cAAa,GAAU,GACvB,UAAW,EAAG,EAAY,CAAE,QAAO,CAAC,EAAG,CAAS,EAChD,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAY,CAC1B,YACA,SACA,GAAG,GAC8D,CACjE,MAAO,kBAAC,OAAD,CAAM,YAAU,gBAAgB,UAAW,EAAG,EAAiB,CAAE,QAAO,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CAC7G,CAGA,SAAgBA,EAAK,EAAkD,CACrE,MAAO,kBAACC,EAAc,KAAf,CAAoB,YAAU,OAAO,GAAI,CAAQ,CAAA,CAC1D,CAEA,SAAgB,EAAS,CAAE,YAAW,GAAG,GAAoD,CAC3F,MAAO,kBAACA,EAAc,KAAf,CAAoB,YAAU,YAAY,UAAW,EAAG,0BAA2B,CAAS,EAAG,GAAI,CAAQ,CAAA,CACpH,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAuD,CACjG,MACE,kBAACA,EAAc,QAAf,CACE,YAAU,eACV,UAAW,EACT,EAAY,CAAE,OAAQ,EAAM,CAAC,EAC7B,yGACA,CACF,EACA,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAuD,CACjG,MAAO,kBAACA,EAAc,QAAf,CAAuB,YAAU,eAAe,UAAW,EAAG,iBAAkB,CAAS,EAAG,GAAI,CAAQ,CAAA,CACjH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TerminalView.d.mts","names":[],"sources":["../../../../src/components/TerminalView.tsx"],"mappings":";;;;;;;;;;;;;;iBAkBiB;;EAEf,MAAM,MAAM;;EAEZ;;iBAGe,0BAA0B,KAAK;;EAE9C,UAAU;;EAEV;EACA,MAAM,MAAM,IAAI;EAChB;;wBAWc,eACd,QACA,SACA,KACA,UACA,cACG,SACF,oCAAiB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TerminalView.mjs","names":[],"sources":["../../../../src/components/TerminalView.tsx"],"sourcesContent":["import { type ComponentProps, useEffect, useImperativeHandle, useRef, useState } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { themeVariable } from '../types/theme';\n\n/**\n * A terminal emulator, for output that is a screen rather than a document.\n *\n * `AnsiText` beside it renders colour in text that happens to carry escapes.\n * This is the other thing: a full VT emulator that keeps a cursor, a grid and\n * an alternate screen, so a prompt, a progress bar or a full-screen program\n * behaves the way it would in a shell. Give it the bytes a pty produced and it\n * draws them; take its `onData` and you have what the reader typed.\n *\n * The emulator is loaded on mount rather than with the bundle. It is not a\n * small dependency, and most surfaces never show a terminal.\n */\n\nexport interface TerminalHandle {\n /** Writes pane bytes, escapes and all. */\n write(data: Uint8Array | string): void;\n /** Clears the screen and scrollback, for a stream that restarted. */\n reset(): void;\n}\n\nexport interface TerminalViewProps extends Omit<ComponentProps<'div'>, 'children' | 'onData' | 'ref'> {\n /** What the reader typed, already encoded the way a terminal sends it. */\n onData?: (text: string) => void;\n /** Called once the emulator is live, so a caller can start feeding it. */\n onReady?: () => void;\n ref?: React.Ref<TerminalHandle>;\n fontSize?: number;\n}\n\nconst DEFAULT_FONT_SIZE = 11;\nconst FONT_STACK = 'ui-monospace, SFMono-Regular, Menlo, monospace';\n\n/** Reads a theme token from the document, so the terminal follows the active theme. */\nfunction tokenColour(root: HTMLElement, token: Parameters<typeof themeVariable>[0]): string {\n return getComputedStyle(root).getPropertyValue(themeVariable(token)).trim();\n}\n\nexport function TerminalView({\n onData,\n onReady,\n ref,\n fontSize = DEFAULT_FONT_SIZE,\n className,\n ...props\n}: TerminalViewProps) {\n const mount = useRef<HTMLDivElement | null>(null);\n const handle = useRef<TerminalHandle | undefined>(undefined);\n const dataRef = useRef<((text: string) => void) | undefined>(onData);\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n dataRef.current = onData;\n });\n\n useImperativeHandle(ref, () => ({\n write: (data) => handle.current?.write(data),\n reset: () => handle.current?.reset(),\n }));\n\n useEffect(() => {\n const element = mount.current;\n if (element === null) return;\n let disposed = false;\n let dispose = (): void => undefined;\n\n void (async () => {\n const [{ Terminal }] = await Promise.all([import('@xterm/xterm'), import('@xterm/xterm/css/xterm.css')]);\n if (disposed) return;\n const terminal = new Terminal({\n cursorBlink: true,\n fontFamily: FONT_STACK,\n fontSize,\n allowTransparency: true,\n // Taken from the document's own custom properties rather than written\n // here, so a theme switch is the only place a colour is ever decided.\n theme: {\n background: tokenColour(element, 'deep'),\n foreground: tokenColour(element, 'dim'),\n cursor: tokenColour(element, 'hi'),\n selectionBackground: tokenColour(element, 'selected'),\n },\n });\n terminal.open(element);\n terminal.onData((text) => dataRef.current?.(text));\n handle.current = {\n write: (data) => terminal.write(data),\n reset: () => terminal.reset(),\n };\n setReady(true);\n onReady?.();\n\n dispose = () => {\n handle.current = undefined;\n terminal.dispose();\n };\n })();\n\n return () => {\n disposed = true;\n dispose();\n };\n // The emulator is built once for the life of the surface; later prop\n // changes reach it through the refs above rather than rebuilding it.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div\n ref={mount}\n data-slot=\"terminal-view\"\n data-ready={ready}\n className={cn('h-full min-w-0 w-full overflow-auto', className)}\n {...props}\n />\n );\n}\n"],"mappings":"mNAsCA,SAAS,EAAY,EAAmB,EAAoD,CAC1F,OAAO,iBAAiB,CAAI,CAAC,CAAC,iBAAiB,EAAc,CAAK,CAAC,CAAC,CAAC,KAAK,CAC5E,CAEA,SAAgB,EAAa,CAC3B,SACA,UACA,MACA,WAAW,GACX,YACA,GAAG,GACiB,CACpB,IAAM,EAAQ,EAA8B,IAAI,EAC1C,EAAS,EAAmC,IAAA,EAAS,EACrD,EAAU,EAA6C,CAAM,EAC7D,CAAC,EAAO,GAAY,EAAS,EAAK,EA0DxC,OAxDA,MAAgB,CACd,EAAQ,QAAU,CACpB,CAAC,EAED,EAAoB,OAAY,CAC9B,MAAQ,GAAS,EAAO,SAAS,MAAM,CAAI,EAC3C,UAAa,EAAO,SAAS,MAAM,CACrC,EAAE,EAEF,MAAgB,CACd,IAAM,EAAU,EAAM,QACtB,GAAI,IAAY,KAAM,OACtB,IAAI,EAAW,GACX,MAAsB,IAAA,GAkC1B,OAhCM,SAAY,CAChB,GAAM,CAAC,CAAE,aAAc,MAAM,QAAQ,IAAI,CAAC,OAAO,gBAAiB,OAAO,6BAA6B,CAAC,EACvG,GAAI,EAAU,OACd,IAAM,EAAW,IAAI,EAAS,CAC5B,YAAa,GACb,WAAY,iDACZ,WACA,kBAAmB,GAGnB,MAAO,CACL,WAAY,EAAY,EAAS,MAAM,EACvC,WAAY,EAAY,EAAS,KAAK,EACtC,OAAQ,EAAY,EAAS,IAAI,EACjC,oBAAqB,EAAY,EAAS,UAAU,CACtD,CACF,CAAC,EACD,EAAS,KAAK,CAAO,EACrB,EAAS,OAAQ,GAAS,EAAQ,UAAU,CAAI,CAAC,EACjD,EAAO,QAAU,CACf,MAAQ,GAAS,EAAS,MAAM,CAAI,EACpC,UAAa,EAAS,MAAM,CAC9B,EACA,EAAS,EAAI,EACb,IAAU,EAEV,MAAgB,CACd,EAAO,QAAU,IAAA,GACjB,EAAS,QAAQ,CACnB,CACF,EAAA,CAAG,MAEU,CACX,EAAW,GACX,EAAQ,CACV,CAIF,EAAG,CAAC,CAAC,EAGH,kBAAC,MAAD,CACE,IAAK,EACL,YAAU,gBACV,aAAY,EACZ,UAAW,EAAG,sCAAuC,CAAS,EAC9D,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Textarea.d.mts","names":[],"sources":["../../../../src/components/Textarea.tsx"],"mappings":";;;;iBAMiB,sBAAsB,KAAK,qCAAqC,oBAAoB;;wBAGrF,WAAW,WAAW,SAAS,SAAS,SAAS,gCAAa,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Textarea.mjs","names":[],"sources":["../../../../src/components/Textarea.tsx"],"sourcesContent":["import type { VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { fieldVariants } from './Input';\n\nexport interface TextareaProps extends Omit<ComponentProps<'textarea'>, 'size'>, VariantProps<typeof fieldVariants> {}\n\n/** The multi-line field, styled as the Input; `bare` drops the well for a composer that draws its own. */\nexport function Textarea({ className, variant, size, ...props }: TextareaProps) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn('resize-none', fieldVariants({ variant, size }), className)}\n {...props}\n />\n );\n}\n"],"mappings":"uHASA,SAAgB,EAAS,CAAE,YAAW,UAAS,OAAM,GAAG,GAAwB,CAC9E,MACE,kBAAC,WAAD,CACE,YAAU,WACV,UAAW,EAAG,cAAe,EAAc,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EACxE,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toast.d.mts","names":[],"sources":["../../../../src/components/Toast.tsx"],"mappings":";;;;;;;;;;wBAcgB,cAAc,OAAO,sBAAsB,MAAe,4BAAS,IAAA;wBAInE,gBAAgB,cAAc,SAAS,sBAAsB,MAAe,4BAAS,IAAA;qBAUxF,gBAAa;;6CAezB;iBAEgB,mBAAmB,sBAAsB,MAAe,OAAO,oBAAoB;iBAEpF,UAAQ,WAAW,SAAS,SAAS,6BAAU,IAAA;wBAI/C,aAAa,cAAc,SAAS,sBAAsB,MAAe,yBAAM,IAAA;wBAU/E,mBAAmB,cAAc,SAAS,sBAAsB,MAAe,+BAAY,IAAA;wBAU3F,YAAY,OAAO,sBAAsB,MAAe,0BAAO,IAAA;wBAI/D,aAAa,cAAc,SAAS,sBAAsB,MAAe,yBAAM,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toast.mjs","names":["ToastPrimitive","Toast"],"sources":["../../../../src/components/Toast.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Toast as ToastPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport type { StatusTone } from '../types/tone';\n\n/**\n * A transient notice. Radix owns the part that is easy to get wrong: it\n * announces through a live region, pauses its timer on hover and on window\n * blur, and restores focus when it leaves. Mount one ToastProvider and one\n * ToastViewport per page.\n */\nexport function ToastProvider(props: ComponentProps<typeof ToastPrimitive.Provider>) {\n return <ToastPrimitive.Provider {...props} />;\n}\n\nexport function ToastViewport({ className, ...props }: ComponentProps<typeof ToastPrimitive.Viewport>) {\n return (\n <ToastPrimitive.Viewport\n data-slot=\"toast-viewport\"\n className={cn('fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none', className)}\n {...props}\n />\n );\n}\n\nexport const toastVariants = cva(\n 'flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise',\n {\n variants: {\n tone: {\n neutral: 'border-doom-border',\n running: 'border-doom-edge-yellow',\n ok: 'border-doom-edge-green',\n error: 'border-doom-edge-red',\n info: 'border-doom-edge-blue',\n accent: 'border-doom-edge-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n },\n);\n\nexport interface ToastProps extends ComponentProps<typeof ToastPrimitive.Root>, VariantProps<typeof toastVariants> {}\n\nexport function Toast({ className, tone, ...props }: ToastProps) {\n return <ToastPrimitive.Root data-slot=\"toast\" className={cn(toastVariants({ tone }), className)} {...props} />;\n}\n\nexport function ToastTitle({ className, ...props }: ComponentProps<typeof ToastPrimitive.Title>) {\n return (\n <ToastPrimitive.Title\n data-slot=\"toast-title\"\n className={cn('text-sm font-bold text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function ToastDescription({ className, ...props }: ComponentProps<typeof ToastPrimitive.Description>) {\n return (\n <ToastPrimitive.Description\n data-slot=\"toast-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function ToastAction(props: ComponentProps<typeof ToastPrimitive.Action>) {\n return <ToastPrimitive.Action data-slot=\"toast-action\" {...props} />;\n}\n\nexport function ToastClose({ className, ...props }: ComponentProps<typeof ToastPrimitive.Close>) {\n return (\n <ToastPrimitive.Close\n data-slot=\"toast-close\"\n aria-label=\"dismiss\"\n className={cn(\n 'inline-flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded text-doom-faint transition-colors hover:text-doom-hi',\n className,\n )}\n {...props}\n >\n <CloseIcon className=\"h-3 w-3\" />\n </ToastPrimitive.Close>\n );\n}\n"],"mappings":"0MAcA,SAAgB,EAAc,EAAuD,CACnF,MAAO,kBAACA,EAAe,SAAhB,CAAyB,GAAI,CAAQ,CAAA,CAC9C,CAEA,SAAgB,EAAc,CAAE,YAAW,GAAG,GAAyD,CACrG,MACE,kBAACA,EAAe,SAAhB,CACE,YAAU,iBACV,UAAW,EAAG,oFAAqF,CAAS,EAC5G,GAAI,CACL,CAAA,CAEL,CAEA,MAAa,EAAgB,EAC3B,8HACA,CACE,SAAU,CACR,KAAM,CACJ,QAAS,qBACT,QAAS,0BACT,GAAI,yBACJ,MAAO,uBACP,KAAM,wBACN,OAAQ,0BACV,CACF,EACA,gBAAiB,CAAE,KAAM,SAAU,CACrC,CACF,EAIA,SAAgBC,EAAM,CAAE,YAAW,OAAM,GAAG,GAAqB,CAC/D,MAAO,kBAACD,EAAe,KAAhB,CAAqB,YAAU,QAAQ,UAAW,EAAG,EAAc,CAAE,MAAK,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CAC/G,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,kBAACA,EAAe,MAAhB,CACE,YAAU,cACV,UAAW,EAAG,iCAAkC,CAAS,EACzD,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAiB,CAAE,YAAW,GAAG,GAA4D,CAC3G,MACE,kBAACA,EAAe,YAAhB,CACE,YAAU,oBACV,UAAW,EAAG,wCAAyC,CAAS,EAChE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,EAAqD,CAC/E,MAAO,kBAACA,EAAe,OAAhB,CAAuB,YAAU,eAAe,GAAI,CAAQ,CAAA,CACrE,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,kBAACA,EAAe,MAAhB,CACE,YAAU,cACV,aAAW,UACX,UAAW,EACT,uIACA,CACF,EACA,GAAI,EAEJ,SAAA,kBAAC,EAAD,CAAW,UAAU,SAAW,CAAA,CACZ,CAAA,CAE1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolPathLink.d.mts","names":[],"sources":["../../../../src/components/ToolPathLink.tsx"],"mappings":";;;;;;;;;;;iBAaiB;EACf;;EAEA;EACA;;EAEA;;wBAGc,eACd,MACA,QACA,0BACe,WACZ,SACF,oCAAiB,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolPathLink.mjs","names":[],"sources":["../../../../src/components/ToolPathLink.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\n\n/**\n * The file path in a tool call's header, as a link when something can open it.\n *\n * A read, a write and an edit all put a path in the same place, and a reader\n * who wants to see that file should not have to go looking for it in a file\n * list. Whether the path can be opened is not this component's business: the\n * host resolves it against whatever plugin owns files, and hands the answer\n * down as `onOpen`. Without one the path stays exactly what it was, plain\n * text, because a link that opens nothing is worse than no link.\n */\n\nexport interface ToolPathLinkProps {\n path: string;\n /** Opens the file; omitted when nothing installed can show it. */\n onOpen?: () => void;\n className?: string;\n /** Defaults to `tool-path`, which is how a test finds the link inside a call header. */\n 'data-testid'?: string;\n}\n\nexport function ToolPathLink({\n path,\n onOpen,\n className,\n 'data-testid': testId = 'tool-path',\n ...props\n}: ToolPathLinkProps) {\n if (onOpen === undefined) {\n return (\n <span\n data-slot=\"tool-path\"\n data-testid={testId}\n className={cn('inline-block max-w-full min-w-0 truncate align-bottom text-doom-text', className)}\n {...props}\n >\n {path}\n </span>\n );\n }\n return (\n <button\n type=\"button\"\n data-slot=\"tool-path\"\n data-testid={testId}\n title={`open ${path}`}\n onClick={onOpen}\n className={cn(\n 'min-h-6 max-w-full min-w-0 cursor-pointer truncate text-left text-doom-text hover:text-doom-blue hover:underline',\n className,\n )}\n {...props}\n >\n {path}\n </button>\n );\n}\n"],"mappings":"2EAsBA,SAAgB,EAAa,CAC3B,OACA,SACA,YACA,cAAe,EAAS,YACxB,GAAG,GACiB,CAapB,OAZI,IAAW,IAAA,GAEX,kBAAC,OAAD,CACE,YAAU,YACV,cAAa,EACb,UAAW,EAAG,uEAAwE,CAAS,EAC/F,GAAI,EAEH,SAAA,CACG,CAAA,EAIR,kBAAC,SAAD,CACE,KAAK,SACL,YAAU,YACV,cAAa,EACb,MAAO,QAAQ,IACf,QAAS,EACT,UAAW,EACT,mHACA,CACF,EACA,GAAI,EAEH,SAAA,CACK,CAAA,CAEZ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tooltip.d.mts","names":[],"sources":["../../../../src/components/Tooltip.tsx"],"mappings":";;;;wBAMgB,kBAAkB,kBAAwB,SAAS,sBAAsB,QAAiB,4BAAS,IAAA;iBAInG,UAAQ,OAAO,sBAAsB,QAAiB,wBAAK,IAAA;wBAI3D,eAAe,OAAO,sBAAsB,QAAiB,2BAAQ,IAAA;wBAIrE,iBACd,WACA,YACA,aACG,SACF,sBAAsB,QAAiB,2BAAQ,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tooltip.mjs","names":["TooltipPrimitive","Tooltip"],"sources":["../../../../src/components/Tooltip.tsx"],"sourcesContent":["import { Tooltip as TooltipPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** Mount once near the root; every Tooltip below shares its delay. */\nexport function TooltipProvider({ delayDuration = 300, ...props }: ComponentProps<typeof TooltipPrimitive.Provider>) {\n return <TooltipPrimitive.Provider data-slot=\"tooltip-provider\" delayDuration={delayDuration} {...props} />;\n}\n\nexport function Tooltip(props: ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />;\n}\n\nexport function TooltipTrigger(props: ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nexport function TooltipContent({\n className,\n sideOffset = 4,\n children,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'z-50 rounded border border-doom-border bg-doom-deep px-2 py-1 font-mono text-xs text-doom-text shadow-lg data-[state=delayed-open]:animate-doom-fade',\n className,\n )}\n {...props}\n >\n {children}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n"],"mappings":"8GAMA,SAAgB,EAAgB,CAAE,gBAAgB,IAAK,GAAG,GAA2D,CACnH,MAAO,kBAACA,EAAiB,SAAlB,CAA2B,YAAU,mBAAkC,gBAAe,GAAI,CAAQ,CAAA,CAC3G,CAEA,SAAgBC,EAAQ,EAAqD,CAC3E,MAAO,kBAACD,EAAiB,KAAlB,CAAuB,YAAU,UAAU,GAAI,CAAQ,CAAA,CAChE,CAEA,SAAgB,EAAe,EAAwD,CACrF,MAAO,kBAACA,EAAiB,QAAlB,CAA0B,YAAU,kBAAkB,GAAI,CAAQ,CAAA,CAC3E,CAEA,SAAgB,EAAe,CAC7B,YACA,aAAa,EACb,WACA,GAAG,GAC+C,CAClD,MACE,kBAACA,EAAiB,OAAlB,CAAA,SACE,kBAACA,EAAiB,QAAlB,CACE,YAAU,kBACE,aACZ,UAAW,EACT,uJACA,CACF,EACA,GAAI,EAEH,UACuB,CAAA,CACH,CAAA,CAE7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ansiSpans.d.mts","names":[],"sources":["../../../../src/lib/ansiSpans.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;iBAyBiB;EACf;;EAEA;;EAEA;EACA;EACA;EACA;EACA;;EAEA;;;wBAqLc,UAAU,eAAe"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ansiSpans.mjs","names":[],"sources":["../../../../src/lib/ansiSpans.ts"],"sourcesContent":["/**\n * The escapes a captured terminal screen carries, turned into spans.\n *\n * WHY THIS EXISTS:\n * Two kinds of output reach the cockpit with a terminal's colour still in it.\n * A workflow captures a tmux pane with `-e`, and a runner's log file keeps the\n * palette on purpose, stripping only cursor moves and redraws. The browser has\n * no terminal, and the cockpit carries no terminal emulator, so the sequences\n * are read here and rendered as ordinary spans. It lives in the component\n * library because both readers need it and neither may import the other.\n *\n * WHAT IT UNDERSTANDS:\n * SGR (`ESC [ … m`) only: the eight base colours and their bright forms, 256\n * colour and truecolour, and bold, faint, italic, underline and inverse. Every\n * other sequence is dropped rather than printed, because a cursor move or a\n * clear that arrives as visible junk is worse than one that arrives as\n * nothing: the screen is a snapshot, and the next one repaints it anyway.\n *\n * The named colours become theme tokens rather than the child's own palette,\n * so a run's output sits in the cockpit's colours instead of fighting them.\n * Only 256-colour and truecolour, which name a colour no token can stand in\n * for, are rendered as themselves.\n */\n\n/** One run of text with the attributes in force when it was printed. */\nexport interface AnsiSpan {\n text: string;\n /** Theme class for a named colour, absent when the colour is the default. */\n className?: string;\n /** An exact colour the child asked for, as `rgb(r g b)`; only 256/truecolour set this. */\n color?: string;\n bold?: boolean;\n faint?: boolean;\n italic?: boolean;\n underline?: boolean;\n /** Foreground and background swapped, which a TUI uses for selection and cursors. */\n inverse?: boolean;\n}\n\n// oxlint-disable-next-line no-control-regex -- reading terminal escapes is the point\nconst ANSI_PATTERN = /\\x1b\\[([0-9;:]*)([A-Za-z])|\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)|\\x1b[()][A-Za-z0-9]|\\x1b[A-Za-z]/g;\nconst SGR_FINAL = 'm';\nconst RESET_CODE = 0;\nconst DEFAULT_FOREGROUND = 39;\nconst EXTENDED_FOREGROUND = 38;\nconst EXTENDED_BACKGROUND = 48;\nconst TRUECOLOR_SELECTOR = 2;\nconst PALETTE_SELECTOR = 5;\nconst BASE_FOREGROUND_START = 30;\nconst BASE_FOREGROUND_END = 37;\nconst BRIGHT_FOREGROUND_START = 90;\nconst BRIGHT_FOREGROUND_END = 97;\nconst BACKGROUND_START = 40;\nconst BACKGROUND_END = 49;\nconst BRIGHT_BACKGROUND_START = 100;\nconst BRIGHT_BACKGROUND_END = 107;\nconst RGB_CHANNELS = 3;\nconst PALETTE_SIZE = 256;\nconst PALETTE_CUBE_START = 16;\nconst PALETTE_GREY_START = 232;\nconst CUBE_SIDE = 6;\nconst CUBE_STEP = 40;\nconst CUBE_OFFSET = 55;\nconst GREY_STEP = 10;\nconst GREY_OFFSET = 8;\nconst MAX_CHANNEL = 255;\n\nconst BOLD = 1;\nconst FAINT = 2;\nconst ITALIC = 3;\nconst UNDERLINE = 4;\nconst INVERSE = 7;\nconst NOT_BOLD = 22;\nconst NOT_ITALIC = 23;\nconst NOT_UNDERLINE = 24;\nconst NOT_INVERSE = 27;\n\n/**\n * The eight terminal colours as theme tokens, listed as whole class strings so\n * the host's class scanner can see them.\n */\nconst FOREGROUND_CLASS: Readonly<Record<number, string>> = {\n 30: 'text-doom-faint',\n 31: 'text-doom-red',\n 32: 'text-doom-green',\n 33: 'text-doom-yellow',\n 34: 'text-doom-blue',\n 35: 'text-doom-magenta',\n 36: 'text-doom-cyan',\n 37: 'text-doom-text',\n 90: 'text-doom-dim',\n 91: 'text-doom-red',\n 92: 'text-doom-green',\n 93: 'text-doom-orange',\n 94: 'text-doom-blue',\n 95: 'text-doom-violet',\n 96: 'text-doom-cyan',\n 97: 'text-doom-hi',\n};\n\ninterface Attributes {\n className?: string;\n color?: string;\n bold: boolean;\n faint: boolean;\n italic: boolean;\n underline: boolean;\n inverse: boolean;\n}\n\nfunction blank(): Attributes {\n return { bold: false, faint: false, italic: false, underline: false, inverse: false };\n}\n\n/** One of the 256 palette entries as an exact colour, since no token stands for it. */\nfunction paletteColor(index: number): string | undefined {\n if (index < 0 || index >= PALETTE_SIZE) return undefined;\n if (index < PALETTE_CUBE_START) return undefined; // The first sixteen are the named ones.\n if (index >= PALETTE_GREY_START) {\n const level = (index - PALETTE_GREY_START) * GREY_STEP + GREY_OFFSET;\n return rgb(level, level, level);\n }\n const offset = index - PALETTE_CUBE_START;\n const channel = (value: number): number => (value === 0 ? 0 : value * CUBE_STEP + CUBE_OFFSET);\n return rgb(\n channel(Math.floor(offset / (CUBE_SIDE * CUBE_SIDE)) % CUBE_SIDE),\n channel(Math.floor(offset / CUBE_SIDE) % CUBE_SIDE),\n channel(offset % CUBE_SIDE),\n );\n}\n\nfunction rgb(red: number, green: number, blue: number): string {\n const clamp = (value: number): number => Math.max(0, Math.min(MAX_CHANNEL, Math.round(value)));\n return `rgb(${clamp(red)} ${clamp(green)} ${clamp(blue)})`;\n}\n\n/** Reads one extended-colour run (`38;5;n` or `38;2;r;g;b`), answering how many codes it ate. */\nfunction extendedColor(codes: readonly number[], index: number): { color?: string; consumed: number } {\n const selector = codes[index + 1];\n if (selector === TRUECOLOR_SELECTOR) {\n const [red, green, blue] = codes.slice(index + 2, index + 2 + RGB_CHANNELS);\n if (red === undefined || green === undefined || blue === undefined) return { consumed: codes.length };\n return { color: rgb(red, green, blue), consumed: 1 + 1 + RGB_CHANNELS };\n }\n if (selector === PALETTE_SELECTOR) {\n const entry = codes[index + 2];\n return { ...(entry === undefined ? {} : { color: paletteColor(entry) }), consumed: 3 };\n }\n return { consumed: 1 };\n}\n\nfunction applySgr(current: Attributes, parameters: string): Attributes {\n // An empty parameter list is a reset, which is what a bare `ESC[m` means.\n const codes = parameters === '' ? [RESET_CODE] : parameters.split(/[;:]/).map((part) => Number(part) || 0);\n let next = { ...current };\n for (let index = 0; index < codes.length; index += 1) {\n const code = codes[index] as number;\n if (code === RESET_CODE) {\n next = blank();\n } else if (code === BOLD) next.bold = true;\n else if (code === FAINT) next.faint = true;\n else if (code === ITALIC) next.italic = true;\n else if (code === UNDERLINE) next.underline = true;\n else if (code === INVERSE) next.inverse = true;\n else if (code === NOT_BOLD) {\n next.bold = false;\n next.faint = false;\n } else if (code === NOT_ITALIC) next.italic = false;\n else if (code === NOT_UNDERLINE) next.underline = false;\n else if (code === NOT_INVERSE) next.inverse = false;\n else if (code === DEFAULT_FOREGROUND) {\n delete next.className;\n delete next.color;\n } else if (code === EXTENDED_FOREGROUND) {\n const { color, consumed } = extendedColor(codes, index);\n delete next.className;\n if (color === undefined) delete next.color;\n else next.color = color;\n index += consumed - 1;\n } else if (code === EXTENDED_BACKGROUND) {\n // Backgrounds are dropped: a child painting its own background over the\n // cockpit's panel is what makes captured output unreadable in a theme.\n index += extendedColor(codes, index).consumed - 1;\n } else if (\n (code >= BASE_FOREGROUND_START && code <= BASE_FOREGROUND_END) ||\n (code >= BRIGHT_FOREGROUND_START && code <= BRIGHT_FOREGROUND_END)\n ) {\n const className = FOREGROUND_CLASS[code];\n delete next.color;\n if (className === undefined) delete next.className;\n else next.className = className;\n }\n // Background and everything else is read and dropped.\n else if (\n (code >= BACKGROUND_START && code <= BACKGROUND_END) ||\n (code >= BRIGHT_BACKGROUND_START && code <= BRIGHT_BACKGROUND_END)\n ) {\n next.inverse = false;\n }\n }\n return next;\n}\n\nfunction spanOf(text: string, attributes: Attributes): AnsiSpan {\n return {\n text,\n ...(attributes.className === undefined ? {} : { className: attributes.className }),\n ...(attributes.color === undefined ? {} : { color: attributes.color }),\n ...(attributes.bold ? { bold: true } : {}),\n ...(attributes.faint ? { faint: true } : {}),\n ...(attributes.italic ? { italic: true } : {}),\n ...(attributes.underline ? { underline: true } : {}),\n ...(attributes.inverse ? { inverse: true } : {}),\n };\n}\n\n/** One line of captured screen as spans, with every unreadable sequence dropped. */\nexport function ansiSpans(line: string): AnsiSpan[] {\n const spans: AnsiSpan[] = [];\n let attributes = blank();\n let cursor = 0;\n ANSI_PATTERN.lastIndex = 0;\n let match = ANSI_PATTERN.exec(line);\n while (match !== null) {\n if (match.index > cursor) spans.push(spanOf(line.slice(cursor, match.index), attributes));\n if (match[2] === SGR_FINAL) attributes = applySgr(attributes, match[1] ?? '');\n cursor = match.index + match[0].length;\n match = ANSI_PATTERN.exec(line);\n }\n if (cursor < line.length) spans.push(spanOf(line.slice(cursor), attributes));\n return spans;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.d.mts","names":[],"sources":["../../../../src/lib/cn.ts"],"mappings":";;;wBAIgB,MAAM,QAAQ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.mjs","names":[],"sources":["../../../../src/lib/cn.ts"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/** Merges class lists the shadcn way: conditional joins, then Tailwind conflict resolution. */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"qEAIA,SAAgB,EAAG,GAAG,EAA8B,CAClD,OAAO,EAAQ,EAAK,CAAM,CAAC,CAC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collapse.d.mts","names":[],"sources":["../../../../src/lib/collapse.ts"],"mappings":";iBAAiB,eAAe;EAC9B,OAAO;;EAEP;;;;;;;wBAQc,cAAc,GAAG,gBAAgB,KAAK,eAAe,oBAAoB,eAAe"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collapse.mjs","names":[],"sources":["../../../../src/lib/collapse.ts"],"sourcesContent":["export interface CollapsedLines<T> {\n shown: T[];\n /** How many lines the collapse holds back; 0 once expanded or when nothing was clipped. */\n hidden: number;\n}\n\n/**\n * The first `limit` lines until expanded. Head-only on purpose: a card that\n * shows the tail (a running command) keeps its own slice and reports the\n * count it hid.\n */\nexport function collapseLines<T>(lines: readonly T[], limit: number, expanded: boolean): CollapsedLines<T> {\n if (expanded || lines.length <= limit) return { shown: [...lines], hidden: 0 };\n return { shown: lines.slice(0, limit), hidden: lines.length - limit };\n}\n"],"mappings":"AAWA,SAAgB,EAAiB,EAAqB,EAAe,EAAsC,CAEzG,OADI,GAAY,EAAM,QAAU,EAAc,CAAE,MAAO,CAAC,GAAG,CAAK,EAAG,OAAQ,CAAE,EACtE,CAAE,MAAO,EAAM,MAAM,EAAG,CAAK,EAAG,OAAQ,EAAM,OAAS,CAAM,CACtE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editorController.mjs","names":[],"sources":["../../../../src/lib/editorController.ts"],"sourcesContent":["import type { EditorEdit, EditorTextRange } from '../types/editor';\n\n/** Validate and order offset ranges before they reach CodeMirror. */\nexport function boundedEditorRanges<T extends EditorTextRange>(\n documentLength: number,\n ranges: readonly T[],\n): readonly T[] {\n const ordered = [...ranges].sort((left, right) => left.from - right.from || left.to - right.to);\n let previousEnd = 0;\n\n for (const [index, range] of ordered.entries()) {\n if (!Number.isInteger(range.from) || !Number.isInteger(range.to)) {\n throw new RangeError('Editor ranges must use integer offsets');\n }\n if (range.from < 0 || range.to < range.from || range.to > documentLength) {\n throw new RangeError(`Editor range ${index} is outside the document`);\n }\n if (index > 0 && range.from < previousEnd) {\n throw new RangeError('Editor ranges must not overlap');\n }\n previousEnd = Math.max(previousEnd, range.to);\n }\n\n return ordered;\n}\n\n/** Convert caller edits to the bounded, ordered shape accepted by one transaction. */\nexport function boundedEditorEdits(documentLength: number, edits: readonly EditorEdit[]): readonly EditorEdit[] {\n return boundedEditorRanges(documentLength, edits);\n}\n"],"mappings":"AAGA,SAAgB,EACd,EACA,EACc,CACd,IAAM,EAAU,CAAC,GAAG,CAAM,CAAC,CAAC,MAAM,EAAM,IAAU,EAAK,KAAO,EAAM,MAAQ,EAAK,GAAK,EAAM,EAAE,EAC1F,EAAc,EAElB,IAAK,GAAM,CAAC,EAAO,KAAU,EAAQ,QAAQ,EAAG,CAC9C,GAAI,CAAC,OAAO,UAAU,EAAM,IAAI,GAAK,CAAC,OAAO,UAAU,EAAM,EAAE,EAC7D,MAAU,WAAW,wCAAwC,EAE/D,GAAI,EAAM,KAAO,GAAK,EAAM,GAAK,EAAM,MAAQ,EAAM,GAAK,EACxD,MAAU,WAAW,gBAAgB,EAAM,yBAAyB,EAEtE,GAAI,EAAQ,GAAK,EAAM,KAAO,EAC5B,MAAU,WAAW,gCAAgC,EAEvD,EAAc,KAAK,IAAI,EAAa,EAAM,EAAE,CAC9C,CAEA,OAAO,CACT,CAGA,SAAgB,EAAmB,EAAwB,EAAqD,CAC9G,OAAO,EAAoB,EAAgB,CAAK,CAClD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editorLanguage.d.mts","names":[],"sources":["../../../../src/lib/editorLanguage.ts"],"mappings":";;;;;;;;;;;;YAcY;;;;;;wBA6DI,aAAa,mBAAmB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editorLanguage.mjs","names":[],"sources":["../../../../src/lib/editorLanguage.ts"],"sourcesContent":["import type { StreamParser } from '@codemirror/language';\nimport type { Extension } from '@codemirror/state';\n\n/**\n * Which grammar a file gets, and how it arrives.\n *\n * The two halves are apart on purpose. Naming the grammar is a pure lookup a\n * caller can run before deciding anything, and loading it is a dynamic import\n * so a session that only ever opens Markdown never downloads the JavaScript\n * parser. Nothing here imports CodeMirror at runtime: every specifier below is\n * either a type, which erases, or inside an `import()` the bundler splits into\n * its own chunk.\n */\n\nexport type GrammarKey =\n | 'javascript'\n | 'jsx'\n | 'typescript'\n | 'tsx'\n | 'json'\n | 'markdown'\n | 'html'\n | 'css'\n | 'python'\n | 'yaml'\n | 'shell'\n | 'toml'\n | 'dockerfile';\n\n/** Keyed by lower-case extension without the dot. */\nconst GRAMMAR_BY_EXTENSION: Readonly<Record<string, GrammarKey>> = {\n cjs: 'javascript',\n js: 'javascript',\n mjs: 'javascript',\n jsx: 'jsx',\n cts: 'typescript',\n mts: 'typescript',\n ts: 'typescript',\n tsx: 'tsx',\n json: 'json',\n jsonc: 'json',\n markdown: 'markdown',\n md: 'markdown',\n htm: 'html',\n html: 'html',\n xhtml: 'html',\n css: 'css',\n py: 'python',\n pyi: 'python',\n yaml: 'yaml',\n yml: 'yaml',\n bash: 'shell',\n sh: 'shell',\n zsh: 'shell',\n toml: 'toml',\n};\n\n/** Files a project names rather than suffixes, matched on the whole lower-cased basename. */\nconst GRAMMAR_BY_FILENAME: Readonly<Record<string, GrammarKey>> = {\n '.bashrc': 'shell',\n '.zshrc': 'shell',\n containerfile: 'dockerfile',\n dockerfile: 'dockerfile',\n};\n\n/** The last segment of a path, lower-cased. */\nfunction basenameOf(filePath: string): string {\n return (filePath.split('/').at(-1) ?? '').toLowerCase();\n}\n\n/**\n * The grammar for a path, or undefined for a file the editor shows as plain\n * text. A name is tried whole before it is tried as a suffix, so\n * `Dockerfile.dev` is a Dockerfile and not a file with a `dev` extension.\n */\nexport function grammarKeyOf(filePath: string): GrammarKey | undefined {\n const name = basenameOf(filePath);\n const named = GRAMMAR_BY_FILENAME[name];\n if (named !== undefined) return named;\n const dot = name.lastIndexOf('.');\n if (dot < 1) return undefined;\n return GRAMMAR_BY_EXTENSION[name.slice(dot + 1)];\n}\n\n/** A legacy stream mode wrapped as a language; the modes predate Lezer and ship as tokenizers. */\nasync function streamMode(load: () => Promise<StreamParser<unknown>>): Promise<Extension> {\n const [{ StreamLanguage }, parser] = await Promise.all([import('@codemirror/language'), load()]);\n return StreamLanguage.define(parser);\n}\n\n/** Downloads one grammar. Each arm is its own chunk, so the cost is the languages actually opened. */\nexport async function loadGrammar(key: GrammarKey): Promise<Extension> {\n switch (key) {\n case 'javascript':\n return (await import('@codemirror/lang-javascript')).javascript();\n case 'jsx':\n return (await import('@codemirror/lang-javascript')).javascript({ jsx: true });\n case 'typescript':\n return (await import('@codemirror/lang-javascript')).javascript({ typescript: true });\n case 'tsx':\n return (await import('@codemirror/lang-javascript')).javascript({ jsx: true, typescript: true });\n case 'json':\n return (await import('@codemirror/lang-json')).json();\n case 'markdown':\n return (await import('@codemirror/lang-markdown')).markdown();\n case 'html':\n return (await import('@codemirror/lang-html')).html();\n case 'css':\n return (await import('@codemirror/lang-css')).css();\n case 'python':\n return (await import('@codemirror/lang-python')).python();\n case 'yaml':\n return (await import('@codemirror/lang-yaml')).yaml();\n case 'shell':\n return streamMode(async () => (await import('@codemirror/legacy-modes/mode/shell')).shell);\n case 'toml':\n return streamMode(async () => (await import('@codemirror/legacy-modes/mode/toml')).toml);\n case 'dockerfile':\n return streamMode(async () => (await import('@codemirror/legacy-modes/mode/dockerfile')).dockerFile);\n }\n}\n"],"mappings":"AA8BA,MAAM,EAA6D,CACjE,IAAK,aACL,GAAI,aACJ,IAAK,aACL,IAAK,MACL,IAAK,aACL,IAAK,aACL,GAAI,aACJ,IAAK,MACL,KAAM,OACN,MAAO,OACP,SAAU,WACV,GAAI,WACJ,IAAK,OACL,KAAM,OACN,MAAO,OACP,IAAK,MACL,GAAI,SACJ,IAAK,SACL,KAAM,OACN,IAAK,OACL,KAAM,QACN,GAAI,QACJ,IAAK,QACL,KAAM,MACR,EAGM,EAA4D,CAChE,UAAW,QACX,SAAU,QACV,cAAe,aACf,WAAY,YACd,EAGA,SAAS,EAAW,EAA0B,CAC5C,OAAQ,EAAS,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAK,GAAA,CAAI,YAAY,CACxD,CAOA,SAAgB,EAAa,EAA0C,CACrE,IAAM,EAAO,EAAW,CAAQ,EAC1B,EAAQ,EAAoB,GAClC,GAAI,IAAU,IAAA,GAAW,OAAO,EAChC,IAAM,EAAM,EAAK,YAAY,GAAG,EAC5B,OAAM,GACV,OAAO,EAAqB,EAAK,MAAM,EAAM,CAAC,EAChD,CAGA,eAAe,EAAW,EAAgE,CACxF,GAAM,CAAC,CAAE,kBAAkB,GAAU,MAAM,QAAQ,IAAI,CAAC,OAAO,wBAAyB,EAAK,CAAC,CAAC,EAC/F,OAAO,EAAe,OAAO,CAAM,CACrC,CAGA,eAAsB,EAAY,EAAqC,CACrE,OAAQ,EAAR,CACE,IAAK,aACH,OAAQ,MAAM,OAAO,+BAAA,CAAgC,WAAW,EAClE,IAAK,MACH,OAAQ,MAAM,OAAO,+BAAA,CAAgC,WAAW,CAAE,IAAK,EAAK,CAAC,EAC/E,IAAK,aACH,OAAQ,MAAM,OAAO,+BAAA,CAAgC,WAAW,CAAE,WAAY,EAAK,CAAC,EACtF,IAAK,MACH,OAAQ,MAAM,OAAO,+BAAA,CAAgC,WAAW,CAAE,IAAK,GAAM,WAAY,EAAK,CAAC,EACjG,IAAK,OACH,OAAQ,MAAM,OAAO,yBAAA,CAA0B,KAAK,EACtD,IAAK,WACH,OAAQ,MAAM,OAAO,6BAAA,CAA8B,SAAS,EAC9D,IAAK,OACH,OAAQ,MAAM,OAAO,yBAAA,CAA0B,KAAK,EACtD,IAAK,MACH,OAAQ,MAAM,OAAO,wBAAA,CAAyB,IAAI,EACpD,IAAK,SACH,OAAQ,MAAM,OAAO,2BAAA,CAA4B,OAAO,EAC1D,IAAK,OACH,OAAQ,MAAM,OAAO,yBAAA,CAA0B,KAAK,EACtD,IAAK,QACH,OAAO,EAAW,UAAa,MAAM,OAAO,uCAAA,CAAwC,KAAK,EAC3F,IAAK,OACH,OAAO,EAAW,UAAa,MAAM,OAAO,sCAAA,CAAuC,IAAI,EACzF,IAAK,aACH,OAAO,EAAW,UAAa,MAAM,OAAO,4CAAA,CAA6C,UAAU,CACvG,CACF"}
|