@adea-ai/ui 0.140.0 → 0.142.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/composites/appearance-editor/appearance-editor.js +2 -2
- package/dist/components/composites/appearance-editor/appearance-editor.js.map +1 -1
- package/dist/components/composites/catalog-browser/catalog-browser-group.js +1 -1
- package/dist/components/composites/chain-of-thought/chain-of-thought.d.ts +56 -0
- package/dist/components/composites/chain-of-thought/chain-of-thought.d.ts.map +1 -0
- package/dist/components/composites/chain-of-thought/chain-of-thought.js +117 -0
- package/dist/components/composites/chain-of-thought/chain-of-thought.js.map +1 -0
- package/dist/components/composites/chain-of-thought/index.d.ts +2 -0
- package/dist/components/composites/chain-of-thought/index.d.ts.map +1 -0
- package/dist/components/composites/chain-of-thought/index.js +2 -0
- package/dist/components/composites/chat/chat.d.ts +67 -0
- package/dist/components/composites/chat/chat.d.ts.map +1 -0
- package/dist/components/composites/chat/chat.js +179 -0
- package/dist/components/composites/chat/chat.js.map +1 -0
- package/dist/components/composites/chat/index.d.ts +2 -0
- package/dist/components/composites/chat/index.d.ts.map +1 -0
- package/dist/components/composites/chat/index.js +2 -0
- package/dist/components/composites/checkpoint/checkpoint-model.d.ts +34 -0
- package/dist/components/composites/checkpoint/checkpoint-model.d.ts.map +1 -0
- package/dist/components/composites/checkpoint/checkpoint-model.js +48 -0
- package/dist/components/composites/checkpoint/checkpoint-model.js.map +1 -0
- package/dist/components/composites/checkpoint/checkpoint.d.ts +48 -0
- package/dist/components/composites/checkpoint/checkpoint.d.ts.map +1 -0
- package/dist/components/composites/checkpoint/checkpoint.js +160 -0
- package/dist/components/composites/checkpoint/checkpoint.js.map +1 -0
- package/dist/components/composites/checkpoint/index.d.ts +3 -0
- package/dist/components/composites/checkpoint/index.d.ts.map +1 -0
- package/dist/components/composites/checkpoint/index.js +3 -0
- package/dist/components/composites/confirmation/confirmation-model.d.ts +45 -0
- package/dist/components/composites/confirmation/confirmation-model.d.ts.map +1 -0
- package/dist/components/composites/confirmation/confirmation-model.js +51 -0
- package/dist/components/composites/confirmation/confirmation-model.js.map +1 -0
- package/dist/components/composites/confirmation/confirmation.d.ts +72 -0
- package/dist/components/composites/confirmation/confirmation.d.ts.map +1 -0
- package/dist/components/composites/confirmation/confirmation.js +300 -0
- package/dist/components/composites/confirmation/confirmation.js.map +1 -0
- package/dist/components/composites/confirmation/index.d.ts +3 -0
- package/dist/components/composites/confirmation/index.d.ts.map +1 -0
- package/dist/components/composites/confirmation/index.js +3 -0
- package/dist/components/composites/context/context-model.d.ts +69 -0
- package/dist/components/composites/context/context-model.d.ts.map +1 -0
- package/dist/components/composites/context/context-model.js +122 -0
- package/dist/components/composites/context/context-model.js.map +1 -0
- package/dist/components/composites/context/context.d.ts +38 -0
- package/dist/components/composites/context/context.d.ts.map +1 -0
- package/dist/components/composites/context/context.js +234 -0
- package/dist/components/composites/context/context.js.map +1 -0
- package/dist/components/composites/context/index.d.ts +3 -0
- package/dist/components/composites/context/index.d.ts.map +1 -0
- package/dist/components/composites/context/index.js +3 -0
- package/dist/components/composites/file-tree/build-file-tree.d.ts +138 -0
- package/dist/components/composites/file-tree/build-file-tree.d.ts.map +1 -0
- package/dist/components/composites/file-tree/build-file-tree.js +325 -0
- package/dist/components/composites/file-tree/build-file-tree.js.map +1 -0
- package/dist/components/composites/file-tree/file-tree.d.ts +74 -0
- package/dist/components/composites/file-tree/file-tree.d.ts.map +1 -0
- package/dist/components/composites/file-tree/file-tree.js +389 -0
- package/dist/components/composites/file-tree/file-tree.js.map +1 -0
- package/dist/components/composites/file-tree/index.d.ts +3 -0
- package/dist/components/composites/file-tree/index.d.ts.map +1 -0
- package/dist/components/composites/file-tree/index.js +3 -0
- package/dist/components/composites/inline-citation/citation.d.ts +37 -0
- package/dist/components/composites/inline-citation/citation.d.ts.map +1 -0
- package/dist/components/composites/inline-citation/citation.js +52 -0
- package/dist/components/composites/inline-citation/citation.js.map +1 -0
- package/dist/components/composites/inline-citation/index.d.ts +3 -0
- package/dist/components/composites/inline-citation/index.d.ts.map +1 -0
- package/dist/components/composites/inline-citation/index.js +3 -0
- package/dist/components/composites/inline-citation/inline-citation.d.ts +64 -0
- package/dist/components/composites/inline-citation/inline-citation.d.ts.map +1 -0
- package/dist/components/composites/inline-citation/inline-citation.js +272 -0
- package/dist/components/composites/inline-citation/inline-citation.js.map +1 -0
- package/dist/components/composites/message-scroller/index.d.ts +3 -0
- package/dist/components/composites/message-scroller/index.d.ts.map +1 -0
- package/dist/components/composites/message-scroller/index.js +3 -0
- package/dist/components/composites/message-scroller/message-scroller.d.ts +55 -0
- package/dist/components/composites/message-scroller/message-scroller.d.ts.map +1 -0
- package/dist/components/composites/message-scroller/message-scroller.js +201 -0
- package/dist/components/composites/message-scroller/message-scroller.js.map +1 -0
- package/dist/components/composites/message-scroller/scroll-anchor.d.ts +66 -0
- package/dist/components/composites/message-scroller/scroll-anchor.d.ts.map +1 -0
- package/dist/components/composites/message-scroller/scroll-anchor.js +122 -0
- package/dist/components/composites/message-scroller/scroll-anchor.js.map +1 -0
- package/dist/components/composites/model-selector/index.d.ts +3 -0
- package/dist/components/composites/model-selector/index.d.ts.map +1 -0
- package/dist/components/composites/model-selector/index.js +3 -0
- package/dist/components/composites/model-selector/model-selector.d.ts +55 -0
- package/dist/components/composites/model-selector/model-selector.d.ts.map +1 -0
- package/dist/components/composites/model-selector/model-selector.js +490 -0
- package/dist/components/composites/model-selector/model-selector.js.map +1 -0
- package/dist/components/composites/model-selector/models.d.ts +51 -0
- package/dist/components/composites/model-selector/models.d.ts.map +1 -0
- package/dist/components/composites/model-selector/models.js +71 -0
- package/dist/components/composites/model-selector/models.js.map +1 -0
- package/dist/components/composites/plan/index.d.ts +2 -0
- package/dist/components/composites/plan/index.d.ts.map +1 -0
- package/dist/components/composites/plan/index.js +2 -0
- package/dist/components/composites/plan/plan.d.ts +61 -0
- package/dist/components/composites/plan/plan.d.ts.map +1 -0
- package/dist/components/composites/plan/plan.js +130 -0
- package/dist/components/composites/plan/plan.js.map +1 -0
- package/dist/components/composites/queue/index.d.ts +2 -0
- package/dist/components/composites/queue/index.d.ts.map +1 -0
- package/dist/components/composites/queue/index.js +2 -0
- package/dist/components/composites/queue/queue.d.ts +77 -0
- package/dist/components/composites/queue/queue.d.ts.map +1 -0
- package/dist/components/composites/queue/queue.js +271 -0
- package/dist/components/composites/queue/queue.js.map +1 -0
- package/dist/components/composites/reasoning/index.d.ts +2 -0
- package/dist/components/composites/reasoning/index.d.ts.map +1 -0
- package/dist/components/composites/reasoning/index.js +2 -0
- package/dist/components/composites/reasoning/reasoning.d.ts +62 -0
- package/dist/components/composites/reasoning/reasoning.d.ts.map +1 -0
- package/dist/components/composites/reasoning/reasoning.js +156 -0
- package/dist/components/composites/reasoning/reasoning.js.map +1 -0
- package/dist/components/composites/sources/index.d.ts +3 -0
- package/dist/components/composites/sources/index.d.ts.map +1 -0
- package/dist/components/composites/sources/index.js +3 -0
- package/dist/components/composites/sources/source.d.ts +46 -0
- package/dist/components/composites/sources/source.d.ts.map +1 -0
- package/dist/components/composites/sources/source.js +74 -0
- package/dist/components/composites/sources/source.js.map +1 -0
- package/dist/components/composites/sources/sources.d.ts +45 -0
- package/dist/components/composites/sources/sources.d.ts.map +1 -0
- package/dist/components/composites/sources/sources.js +175 -0
- package/dist/components/composites/sources/sources.js.map +1 -0
- package/dist/components/composites/stack-trace/index.d.ts +3 -0
- package/dist/components/composites/stack-trace/index.d.ts.map +1 -0
- package/dist/components/composites/stack-trace/index.js +3 -0
- package/dist/components/composites/stack-trace/parse-stack-trace.d.ts +118 -0
- package/dist/components/composites/stack-trace/parse-stack-trace.d.ts.map +1 -0
- package/dist/components/composites/stack-trace/parse-stack-trace.js +376 -0
- package/dist/components/composites/stack-trace/parse-stack-trace.js.map +1 -0
- package/dist/components/composites/stack-trace/stack-trace.d.ts +63 -0
- package/dist/components/composites/stack-trace/stack-trace.d.ts.map +1 -0
- package/dist/components/composites/stack-trace/stack-trace.js +491 -0
- package/dist/components/composites/stack-trace/stack-trace.js.map +1 -0
- package/dist/components/composites/subagent/index.d.ts +2 -0
- package/dist/components/composites/subagent/index.d.ts.map +1 -0
- package/dist/components/composites/subagent/index.js +2 -0
- package/dist/components/composites/subagent/subagent.d.ts +55 -0
- package/dist/components/composites/subagent/subagent.d.ts.map +1 -0
- package/dist/components/composites/subagent/subagent.js +138 -0
- package/dist/components/composites/subagent/subagent.js.map +1 -0
- package/dist/components/composites/suggestion/index.d.ts +2 -0
- package/dist/components/composites/suggestion/index.d.ts.map +1 -0
- package/dist/components/composites/suggestion/index.js +2 -0
- package/dist/components/composites/suggestion/suggestion.d.ts +37 -0
- package/dist/components/composites/suggestion/suggestion.d.ts.map +1 -0
- package/dist/components/composites/suggestion/suggestion.js +100 -0
- package/dist/components/composites/suggestion/suggestion.js.map +1 -0
- package/dist/components/composites/task/index.d.ts +2 -0
- package/dist/components/composites/task/index.d.ts.map +1 -0
- package/dist/components/composites/task/index.js +2 -0
- package/dist/components/composites/task/task.d.ts +96 -0
- package/dist/components/composites/task/task.d.ts.map +1 -0
- package/dist/components/composites/task/task.js +311 -0
- package/dist/components/composites/task/task.js.map +1 -0
- package/dist/components/composites/terminal/ansi.d.ts +101 -0
- package/dist/components/composites/terminal/ansi.d.ts.map +1 -0
- package/dist/components/composites/terminal/ansi.js +544 -0
- package/dist/components/composites/terminal/ansi.js.map +1 -0
- package/dist/components/composites/terminal/index.d.ts +4 -0
- package/dist/components/composites/terminal/index.d.ts.map +1 -0
- package/dist/components/composites/terminal/index.js +4 -0
- package/dist/components/composites/terminal/terminal-model.d.ts +63 -0
- package/dist/components/composites/terminal/terminal-model.d.ts.map +1 -0
- package/dist/components/composites/terminal/terminal-model.js +69 -0
- package/dist/components/composites/terminal/terminal-model.js.map +1 -0
- package/dist/components/composites/terminal/terminal.d.ts +88 -0
- package/dist/components/composites/terminal/terminal.d.ts.map +1 -0
- package/dist/components/composites/terminal/terminal.js +500 -0
- package/dist/components/composites/terminal/terminal.js.map +1 -0
- package/dist/components/composites/test-results/index.d.ts +3 -0
- package/dist/components/composites/test-results/index.d.ts.map +1 -0
- package/dist/components/composites/test-results/index.js +3 -0
- package/dist/components/composites/test-results/test-results-model.d.ts +154 -0
- package/dist/components/composites/test-results/test-results-model.d.ts.map +1 -0
- package/dist/components/composites/test-results/test-results-model.js +252 -0
- package/dist/components/composites/test-results/test-results-model.js.map +1 -0
- package/dist/components/composites/test-results/test-results.d.ts +60 -0
- package/dist/components/composites/test-results/test-results.d.ts.map +1 -0
- package/dist/components/composites/test-results/test-results.js +631 -0
- package/dist/components/composites/test-results/test-results.js.map +1 -0
- package/dist/components/composites/tool/format-tool-value.d.ts +37 -0
- package/dist/components/composites/tool/format-tool-value.d.ts.map +1 -0
- package/dist/components/composites/tool/format-tool-value.js +135 -0
- package/dist/components/composites/tool/format-tool-value.js.map +1 -0
- package/dist/components/composites/tool/index.d.ts +3 -0
- package/dist/components/composites/tool/index.d.ts.map +1 -0
- package/dist/components/composites/tool/index.js +3 -0
- package/dist/components/composites/tool/tool.d.ts +69 -0
- package/dist/components/composites/tool/tool.d.ts.map +1 -0
- package/dist/components/composites/tool/tool.js +214 -0
- package/dist/components/composites/tool/tool.js.map +1 -0
- package/dist/components/composites/update-dialog/update-dialog.js +1 -1
- package/dist/components/conversation/conversation-surface.d.ts +7 -0
- package/dist/components/conversation/conversation-surface.d.ts.map +1 -1
- package/dist/components/conversation/conversation-surface.js +2 -0
- package/dist/components/conversation/conversation-surface.js.map +1 -1
- package/dist/components/conversation/scroll-follow-core.d.ts +24 -0
- package/dist/components/conversation/scroll-follow-core.d.ts.map +1 -1
- package/dist/components/conversation/scroll-follow-core.js +23 -1
- package/dist/components/conversation/scroll-follow-core.js.map +1 -1
- package/dist/components/conversation/scroll-follow.d.ts +3 -0
- package/dist/components/conversation/scroll-follow.d.ts.map +1 -1
- package/dist/components/conversation/scroll-follow.js +80 -1
- package/dist/components/conversation/scroll-follow.js.map +1 -1
- package/dist/components/ui/attachment/attachment.d.ts +58 -0
- package/dist/components/ui/attachment/attachment.d.ts.map +1 -0
- package/dist/components/ui/attachment/attachment.js +279 -0
- package/dist/components/ui/attachment/attachment.js.map +1 -0
- package/dist/components/ui/attachment/index.d.ts +2 -0
- package/dist/components/ui/attachment/index.d.ts.map +1 -0
- package/dist/components/ui/attachment/index.js +2 -0
- package/dist/components/ui/badge/badge.d.ts +1 -1
- package/dist/components/ui/bubble/bubble.d.ts +33 -0
- package/dist/components/ui/bubble/bubble.d.ts.map +1 -0
- package/dist/components/ui/bubble/bubble.js +95 -0
- package/dist/components/ui/bubble/bubble.js.map +1 -0
- package/dist/components/ui/bubble/index.d.ts +2 -0
- package/dist/components/ui/bubble/index.d.ts.map +1 -0
- package/dist/components/ui/bubble/index.js +2 -0
- package/dist/components/ui/button/button.d.ts +1 -1
- package/dist/components/ui/code-block/code-block.d.ts +56 -3
- package/dist/components/ui/code-block/code-block.d.ts.map +1 -1
- package/dist/components/ui/code-block/code-block.js +231 -50
- package/dist/components/ui/code-block/code-block.js.map +1 -1
- package/dist/components/ui/code-block/index.d.ts +1 -1
- package/dist/components/ui/code-block/index.d.ts.map +1 -1
- package/dist/components/ui/code-block/index.js +2 -2
- package/dist/components/ui/field/number-field.d.ts +21 -4
- package/dist/components/ui/field/number-field.d.ts.map +1 -1
- package/dist/components/ui/field/number-field.js +22 -11
- package/dist/components/ui/field/number-field.js.map +1 -1
- package/dist/components/ui/marker/index.d.ts +2 -0
- package/dist/components/ui/marker/index.d.ts.map +1 -0
- package/dist/components/ui/marker/index.js +2 -0
- package/dist/components/ui/marker/marker.d.ts +35 -0
- package/dist/components/ui/marker/marker.d.ts.map +1 -0
- package/dist/components/ui/marker/marker.js +123 -0
- package/dist/components/ui/marker/marker.js.map +1 -0
- package/dist/components/ui/message/cite-ranges.d.ts +42 -0
- package/dist/components/ui/message/cite-ranges.d.ts.map +1 -0
- package/dist/components/ui/message/cite-ranges.js +105 -0
- package/dist/components/ui/message/cite-ranges.js.map +1 -0
- package/dist/components/ui/message/index.d.ts +4 -0
- package/dist/components/ui/message/index.d.ts.map +1 -0
- package/dist/components/ui/message/index.js +4 -0
- package/dist/components/ui/message/message.d.ts +95 -0
- package/dist/components/ui/message/message.d.ts.map +1 -0
- package/dist/components/ui/message/message.js +443 -0
- package/dist/components/ui/message/message.js.map +1 -0
- package/dist/components/ui/message/parse-message-text.d.ts +93 -0
- package/dist/components/ui/message/parse-message-text.d.ts.map +1 -0
- package/dist/components/ui/message/parse-message-text.js +365 -0
- package/dist/components/ui/message/parse-message-text.js.map +1 -0
- package/dist/components/ui/questionnaire/index.d.ts +2 -0
- package/dist/components/ui/questionnaire/index.d.ts.map +1 -0
- package/dist/components/ui/questionnaire/index.js +2 -0
- package/dist/components/ui/questionnaire/questionnaire.d.ts +83 -0
- package/dist/components/ui/questionnaire/questionnaire.d.ts.map +1 -0
- package/dist/components/ui/questionnaire/questionnaire.js +470 -0
- package/dist/components/ui/questionnaire/questionnaire.js.map +1 -0
- package/dist/components/ui/status-chip/status-chip.d.ts +1 -1
- package/dist/components/ui/switch/switch.js +11 -11
- package/dist/components/ui/switch/switch.js.map +1 -1
- package/dist/components/ui/trace/index.d.ts +2 -0
- package/dist/components/ui/trace/index.d.ts.map +1 -0
- package/dist/components/ui/trace/index.js +2 -0
- package/dist/components/ui/trace/trace.d.ts +72 -0
- package/dist/components/ui/trace/trace.d.ts.map +1 -0
- package/dist/components/ui/trace/trace.js +340 -0
- package/dist/components/ui/trace/trace.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -5
- package/dist/r/attachment.json +25 -0
- package/dist/r/bubble.json +22 -0
- package/dist/r/chain-of-thought.json +26 -0
- package/dist/r/chat.json +24 -0
- package/dist/r/checkpoint.json +35 -0
- package/dist/r/confirmation.json +34 -0
- package/dist/r/context.json +33 -0
- package/dist/r/file-tree.json +32 -0
- package/dist/r/inline-citation.json +35 -0
- package/dist/r/marker.json +22 -0
- package/dist/r/message-scroller.json +31 -0
- package/dist/r/message.json +33 -0
- package/dist/r/model-selector.json +34 -0
- package/dist/r/plan.json +26 -0
- package/dist/r/questionnaire.json +28 -0
- package/dist/r/queue.json +26 -0
- package/dist/r/reasoning.json +26 -0
- package/dist/r/registry.json +811 -52
- package/dist/r/sources.json +32 -0
- package/dist/r/src/components/composites/chain-of-thought/chain-of-thought.tsx +141 -0
- package/dist/r/src/components/composites/chain-of-thought/index.ts +11 -0
- package/dist/r/src/components/composites/chat/chat.tsx +190 -0
- package/dist/r/src/components/composites/chat/index.ts +11 -0
- package/dist/r/src/components/composites/checkpoint/checkpoint-model.ts +71 -0
- package/dist/r/src/components/composites/checkpoint/checkpoint.tsx +214 -0
- package/dist/r/src/components/composites/checkpoint/index.ts +8 -0
- package/dist/r/src/components/composites/confirmation/confirmation-model.ts +83 -0
- package/dist/r/src/components/composites/confirmation/confirmation.tsx +311 -0
- package/dist/r/src/components/composites/confirmation/index.ts +9 -0
- package/dist/r/src/components/composites/context/context-model.ts +168 -0
- package/dist/r/src/components/composites/context/context.tsx +187 -0
- package/dist/r/src/components/composites/context/index.ts +18 -0
- package/dist/r/src/components/composites/file-tree/build-file-tree.ts +456 -0
- package/dist/r/src/components/composites/file-tree/file-tree.tsx +405 -0
- package/dist/r/src/components/composites/file-tree/index.ts +25 -0
- package/dist/r/src/components/composites/inline-citation/citation.ts +78 -0
- package/dist/r/src/components/composites/inline-citation/index.ts +9 -0
- package/dist/r/src/components/composites/inline-citation/inline-citation.tsx +285 -0
- package/dist/r/src/components/composites/message-scroller/index.ts +2 -0
- package/dist/r/src/components/composites/message-scroller/message-scroller.tsx +301 -0
- package/dist/r/src/components/composites/message-scroller/scroll-anchor.ts +170 -0
- package/dist/r/src/components/composites/model-selector/index.ts +14 -0
- package/dist/r/src/components/composites/model-selector/model-selector.tsx +420 -0
- package/dist/r/src/components/composites/model-selector/models.ts +103 -0
- package/dist/r/src/components/composites/plan/index.ts +1 -0
- package/dist/r/src/components/composites/plan/plan.tsx +155 -0
- package/dist/r/src/components/composites/queue/index.ts +10 -0
- package/dist/r/src/components/composites/queue/queue.tsx +264 -0
- package/dist/r/src/components/composites/reasoning/index.ts +1 -0
- package/dist/r/src/components/composites/reasoning/reasoning.tsx +176 -0
- package/dist/r/src/components/composites/sources/index.ts +11 -0
- package/dist/r/src/components/composites/sources/source.ts +116 -0
- package/dist/r/src/components/composites/sources/sources.tsx +163 -0
- package/dist/r/src/components/composites/stack-trace/index.ts +19 -0
- package/dist/r/src/components/composites/stack-trace/parse-stack-trace.ts +507 -0
- package/dist/r/src/components/composites/stack-trace/stack-trace.tsx +395 -0
- package/dist/r/src/components/composites/subagent/index.ts +1 -0
- package/dist/r/src/components/composites/subagent/subagent.tsx +159 -0
- package/dist/r/src/components/composites/suggestion/index.ts +1 -0
- package/dist/r/src/components/composites/suggestion/suggestion.tsx +140 -0
- package/dist/r/src/components/composites/task/index.ts +14 -0
- package/dist/r/src/components/composites/task/task.tsx +317 -0
- package/dist/r/src/components/composites/terminal/ansi.ts +674 -0
- package/dist/r/src/components/composites/terminal/index.ts +20 -0
- package/dist/r/src/components/composites/terminal/terminal-model.ts +111 -0
- package/dist/r/src/components/composites/terminal/terminal.tsx +574 -0
- package/dist/r/src/components/composites/test-results/index.ts +20 -0
- package/dist/r/src/components/composites/test-results/test-results-model.ts +368 -0
- package/dist/r/src/components/composites/test-results/test-results.tsx +586 -0
- package/dist/r/src/components/composites/tool/format-tool-value.ts +221 -0
- package/dist/r/src/components/composites/tool/index.ts +2 -0
- package/dist/r/src/components/composites/tool/tool.tsx +228 -0
- package/dist/r/src/components/conversation/conversation-surface.tsx +9 -0
- package/dist/r/src/components/conversation/scroll-follow-core.ts +31 -0
- package/dist/r/src/components/conversation/scroll-follow.ts +92 -0
- package/dist/r/src/components/ui/attachment/attachment.tsx +282 -0
- package/dist/r/src/components/ui/attachment/index.ts +10 -0
- package/dist/r/src/components/ui/bubble/bubble.tsx +86 -0
- package/dist/r/src/components/ui/bubble/index.ts +1 -0
- package/dist/r/src/components/ui/code-block/code-block.tsx +256 -26
- package/dist/r/src/components/ui/code-block/index.ts +9 -1
- package/dist/r/src/components/ui/field/number-field.tsx +51 -14
- package/dist/r/src/components/ui/marker/index.ts +1 -0
- package/dist/r/src/components/ui/marker/marker.tsx +90 -0
- package/dist/r/src/components/ui/message/cite-ranges.ts +144 -0
- package/dist/r/src/components/ui/message/index.ts +23 -0
- package/dist/r/src/components/ui/message/message.tsx +434 -0
- package/dist/r/src/components/ui/message/parse-message-text.ts +450 -0
- package/dist/r/src/components/ui/questionnaire/index.ts +10 -0
- package/dist/r/src/components/ui/questionnaire/questionnaire.tsx +446 -0
- package/dist/r/src/components/ui/trace/index.ts +9 -0
- package/dist/r/src/components/ui/trace/trace.tsx +334 -0
- package/dist/r/src/styles/base.css +34 -0
- package/dist/r/stack-trace.json +32 -0
- package/dist/r/subagent.json +27 -0
- package/dist/r/suggestion.json +24 -0
- package/dist/r/task.json +28 -0
- package/dist/r/terminal.json +35 -0
- package/dist/r/test-results.json +33 -0
- package/dist/r/tool.json +31 -0
- package/dist/r/trace.json +25 -0
- package/package.json +6 -3
- package/registry.json +811 -52
- package/src/components/composites/chain-of-thought/chain-of-thought.tsx +141 -0
- package/src/components/composites/chain-of-thought/index.ts +11 -0
- package/src/components/composites/chat/chat.tsx +190 -0
- package/src/components/composites/chat/index.ts +11 -0
- package/src/components/composites/checkpoint/checkpoint-model.ts +71 -0
- package/src/components/composites/checkpoint/checkpoint.tsx +214 -0
- package/src/components/composites/checkpoint/index.ts +8 -0
- package/src/components/composites/confirmation/confirmation-model.ts +83 -0
- package/src/components/composites/confirmation/confirmation.tsx +311 -0
- package/src/components/composites/confirmation/index.ts +9 -0
- package/src/components/composites/context/context-model.ts +168 -0
- package/src/components/composites/context/context.tsx +187 -0
- package/src/components/composites/context/index.ts +18 -0
- package/src/components/composites/file-tree/build-file-tree.ts +456 -0
- package/src/components/composites/file-tree/file-tree.tsx +405 -0
- package/src/components/composites/file-tree/index.ts +25 -0
- package/src/components/composites/inline-citation/citation.ts +78 -0
- package/src/components/composites/inline-citation/index.ts +9 -0
- package/src/components/composites/inline-citation/inline-citation.tsx +285 -0
- package/src/components/composites/message-scroller/index.ts +2 -0
- package/src/components/composites/message-scroller/message-scroller.tsx +301 -0
- package/src/components/composites/message-scroller/scroll-anchor.ts +170 -0
- package/src/components/composites/model-selector/index.ts +14 -0
- package/src/components/composites/model-selector/model-selector.tsx +420 -0
- package/src/components/composites/model-selector/models.ts +103 -0
- package/src/components/composites/plan/index.ts +1 -0
- package/src/components/composites/plan/plan.tsx +155 -0
- package/src/components/composites/queue/index.ts +10 -0
- package/src/components/composites/queue/queue.tsx +264 -0
- package/src/components/composites/reasoning/index.ts +1 -0
- package/src/components/composites/reasoning/reasoning.tsx +176 -0
- package/src/components/composites/sources/index.ts +11 -0
- package/src/components/composites/sources/source.ts +116 -0
- package/src/components/composites/sources/sources.tsx +163 -0
- package/src/components/composites/stack-trace/index.ts +19 -0
- package/src/components/composites/stack-trace/parse-stack-trace.ts +507 -0
- package/src/components/composites/stack-trace/stack-trace.tsx +395 -0
- package/src/components/composites/subagent/index.ts +1 -0
- package/src/components/composites/subagent/subagent.tsx +159 -0
- package/src/components/composites/suggestion/index.ts +1 -0
- package/src/components/composites/suggestion/suggestion.tsx +140 -0
- package/src/components/composites/task/index.ts +14 -0
- package/src/components/composites/task/task.tsx +317 -0
- package/src/components/composites/terminal/ansi.ts +674 -0
- package/src/components/composites/terminal/index.ts +20 -0
- package/src/components/composites/terminal/terminal-model.ts +111 -0
- package/src/components/composites/terminal/terminal.tsx +574 -0
- package/src/components/composites/test-results/index.ts +20 -0
- package/src/components/composites/test-results/test-results-model.ts +368 -0
- package/src/components/composites/test-results/test-results.tsx +586 -0
- package/src/components/composites/tool/format-tool-value.ts +221 -0
- package/src/components/composites/tool/index.ts +2 -0
- package/src/components/composites/tool/tool.tsx +228 -0
- package/src/components/conversation/conversation-surface.tsx +9 -0
- package/src/components/conversation/scroll-follow-core.ts +31 -0
- package/src/components/conversation/scroll-follow.ts +92 -0
- package/src/components/ui/attachment/attachment.tsx +282 -0
- package/src/components/ui/attachment/index.ts +10 -0
- package/src/components/ui/bubble/bubble.tsx +86 -0
- package/src/components/ui/bubble/index.ts +1 -0
- package/src/components/ui/code-block/code-block.tsx +256 -26
- package/src/components/ui/code-block/index.ts +9 -1
- package/src/components/ui/field/number-field.tsx +51 -14
- package/src/components/ui/marker/index.ts +1 -0
- package/src/components/ui/marker/marker.tsx +90 -0
- package/src/components/ui/message/cite-ranges.ts +144 -0
- package/src/components/ui/message/index.ts +23 -0
- package/src/components/ui/message/message.tsx +434 -0
- package/src/components/ui/message/parse-message-text.ts +450 -0
- package/src/components/ui/questionnaire/index.ts +10 -0
- package/src/components/ui/questionnaire/questionnaire.tsx +446 -0
- package/src/components/ui/trace/index.ts +9 -0
- package/src/components/ui/trace/trace.tsx +334 -0
- package/src/index.ts +26 -0
- package/src/styles/base.css +34 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Brain } from 'lucide-solid'
|
|
2
|
+
import { createEffect, createSignal, on, splitProps, type JSX } from 'solid-js'
|
|
3
|
+
import { MessageText } from '../../ui/message'
|
|
4
|
+
import { ScrollArea } from '../../ui/scroll-area'
|
|
5
|
+
import { TraceDetail, TraceLine, type TraceLineProps } from '../../ui/trace'
|
|
6
|
+
|
|
7
|
+
// A function child runs once, when the content mounts (see `deferred` in `tool.tsx`).
|
|
8
|
+
const deferred = (render: () => JSX.Element) => render as unknown as JSX.Element
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Reasoning.
|
|
12
|
+
*
|
|
13
|
+
* The agent's thinking, as a `TraceLine`: a title that says what state it is in,
|
|
14
|
+
* and a body that is the text the host chose to show. Reach for `ChainOfThought`
|
|
15
|
+
* when the thinking is a sequence of discrete steps with their own status, and
|
|
16
|
+
* for a plain `MessageText` when the text is simply part of the answer.
|
|
17
|
+
*
|
|
18
|
+
* ## It shows what it is given, and nothing else
|
|
19
|
+
*
|
|
20
|
+
* `text` is whatever the host has decided is user-visible — a provider's reasoning
|
|
21
|
+
* summary, a model's visible scratchpad. This component never implies there is
|
|
22
|
+
* more behind it: no "show full reasoning" control, no placeholder body, no
|
|
23
|
+
* ellipsis standing in for hidden content. With no `text` and no `streaming` the
|
|
24
|
+
* line is a plain, non-expandable line titled "Reasoning", because there is
|
|
25
|
+
* nothing to open.
|
|
26
|
+
*
|
|
27
|
+
* ## The title is the state
|
|
28
|
+
*
|
|
29
|
+
* - `streaming` — "Thinking…", with the running mark and shimmer.
|
|
30
|
+
* - finished with a `duration` (seconds) — "Thought for 4s".
|
|
31
|
+
* - finished without one — "Reasoning". A duration the host did not measure is
|
|
32
|
+
* not invented.
|
|
33
|
+
*
|
|
34
|
+
* ## Open while it is arriving, closed once it is done
|
|
35
|
+
*
|
|
36
|
+
* While streaming the body is open so the reader can follow along; when the
|
|
37
|
+
* stream ends it folds away so the settled transcript stays one quiet column. The
|
|
38
|
+
* reader's own toggle wins in both directions and is remembered until the next
|
|
39
|
+
* stream begins, so someone who closed it mid-stream is not re-opened and
|
|
40
|
+
* someone who opened it afterwards is not folded. Pass `open` and `onOpenChange`
|
|
41
|
+
* to own the state instead.
|
|
42
|
+
*
|
|
43
|
+
* ## Bounded, and stable while it grows
|
|
44
|
+
*
|
|
45
|
+
* The body is `MessageText`, so the text is untrusted and rendered as text (see
|
|
46
|
+
* its doc comment), and earlier paragraphs keep their DOM while the last one
|
|
47
|
+
* grows. The scroller is capped; while streaming it follows the newest text only
|
|
48
|
+
* if the reader has not scrolled up, so reading the start of a long thought is
|
|
49
|
+
* not interrupted by the end of it.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/** `4` → `4s`, `65` → `1m 5s`. Nothing for a value that is not a finite duration. */
|
|
53
|
+
export function formatDuration(seconds: number | undefined): string | undefined {
|
|
54
|
+
if (seconds === undefined || !Number.isFinite(seconds) || seconds < 0) return undefined
|
|
55
|
+
const total = Math.round(seconds)
|
|
56
|
+
if (total === 0) return '<1s'
|
|
57
|
+
if (total < 60) return `${total}s`
|
|
58
|
+
const hours = Math.floor(total / 3600)
|
|
59
|
+
const minutes = Math.floor((total % 3600) / 60)
|
|
60
|
+
const rest = total % 60
|
|
61
|
+
if (hours > 0) return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`
|
|
62
|
+
return rest > 0 ? `${minutes}m ${rest}s` : `${minutes}m`
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The line's title for a state. Exported so a host can say the same thing elsewhere. */
|
|
66
|
+
export function reasoningTitle(state: { streaming?: boolean; duration?: number }): string {
|
|
67
|
+
if (state.streaming) return 'Thinking…'
|
|
68
|
+
const duration = formatDuration(state.duration)
|
|
69
|
+
return duration ? `Thought for ${duration}` : 'Reasoning'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Within this many pixels of the end counts as "following". */
|
|
73
|
+
const FOLLOW_SLOP = 16
|
|
74
|
+
|
|
75
|
+
export type ReasoningProps = Omit<
|
|
76
|
+
TraceLineProps,
|
|
77
|
+
| 'title'
|
|
78
|
+
| 'description'
|
|
79
|
+
| 'status'
|
|
80
|
+
| 'statusLabel'
|
|
81
|
+
| 'defaultOpen'
|
|
82
|
+
| 'children'
|
|
83
|
+
| 'href'
|
|
84
|
+
| 'onSelect'
|
|
85
|
+
| 'selectHaspopup'
|
|
86
|
+
> & {
|
|
87
|
+
/** The reasoning the host marked as user-visible. Untrusted text. */
|
|
88
|
+
text?: string
|
|
89
|
+
/** True while text may still arrive. */
|
|
90
|
+
streaming?: boolean
|
|
91
|
+
/** Seconds the thinking took, if the host measured it. */
|
|
92
|
+
duration?: number
|
|
93
|
+
/** Replaces the state-derived title, e.g. for another language. */
|
|
94
|
+
title?: JSX.Element
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function ReasoningBody(props: { text: string; streaming?: boolean }) {
|
|
98
|
+
let scroller: HTMLDivElement | undefined
|
|
99
|
+
let following = true
|
|
100
|
+
|
|
101
|
+
createEffect(() => {
|
|
102
|
+
// Read for the dependency: new text is the event that may need following.
|
|
103
|
+
void props.text
|
|
104
|
+
if (props.streaming && following && scroller) scroller.scrollTop = scroller.scrollHeight
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<TraceDetail>
|
|
109
|
+
<ScrollArea
|
|
110
|
+
ref={(element) => (scroller = element)}
|
|
111
|
+
role="region"
|
|
112
|
+
aria-label="Reasoning text"
|
|
113
|
+
class="max-h-72"
|
|
114
|
+
onScroll={(event) => {
|
|
115
|
+
const element = event.currentTarget
|
|
116
|
+
following = element.scrollHeight - element.scrollTop - element.clientHeight <= FOLLOW_SLOP
|
|
117
|
+
}}
|
|
118
|
+
>
|
|
119
|
+
<MessageText
|
|
120
|
+
text={props.text}
|
|
121
|
+
streaming={props.streaming}
|
|
122
|
+
codeBlockProps={{ maxHeight: '16rem', wrap: true }}
|
|
123
|
+
/>
|
|
124
|
+
</ScrollArea>
|
|
125
|
+
</TraceDetail>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function Reasoning(props: ReasoningProps) {
|
|
130
|
+
const [local, rest] = splitProps(props, [
|
|
131
|
+
'text',
|
|
132
|
+
'streaming',
|
|
133
|
+
'duration',
|
|
134
|
+
'title',
|
|
135
|
+
'icon',
|
|
136
|
+
'open',
|
|
137
|
+
'onOpenChange',
|
|
138
|
+
])
|
|
139
|
+
// `undefined` means "the reader has not decided", which is what lets the stream
|
|
140
|
+
// open and close the line on its own.
|
|
141
|
+
const [chosen, setChosen] = createSignal<boolean>()
|
|
142
|
+
const open = () => local.open ?? chosen() ?? local.streaming === true
|
|
143
|
+
const hasBody = () => (local.text ?? '').trim() !== '' || local.streaming === true
|
|
144
|
+
|
|
145
|
+
createEffect(
|
|
146
|
+
on(
|
|
147
|
+
() => local.streaming,
|
|
148
|
+
(streaming) => {
|
|
149
|
+
if (streaming) setChosen(undefined)
|
|
150
|
+
},
|
|
151
|
+
{ defer: true }
|
|
152
|
+
)
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
// A function child runs only when the content mounts, so a folded line parses nothing.
|
|
156
|
+
const body = () => <ReasoningBody text={local.text ?? ''} streaming={local.streaming} />
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<TraceLine
|
|
160
|
+
icon={local.icon ?? <Brain />}
|
|
161
|
+
title={
|
|
162
|
+
local.title ?? reasoningTitle({ streaming: local.streaming, duration: local.duration })
|
|
163
|
+
}
|
|
164
|
+
status={local.streaming ? 'running' : undefined}
|
|
165
|
+
statusLabel="In progress"
|
|
166
|
+
open={open()}
|
|
167
|
+
onOpenChange={(value) => {
|
|
168
|
+
setChosen(value)
|
|
169
|
+
local.onOpenChange?.(value)
|
|
170
|
+
}}
|
|
171
|
+
{...rest}
|
|
172
|
+
>
|
|
173
|
+
{hasBody() ? deferred(body) : undefined}
|
|
174
|
+
</TraceLine>
|
|
175
|
+
)
|
|
176
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { safeHref } from '../../ui/message/parse-message-text'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What a reply drew on.
|
|
5
|
+
*
|
|
6
|
+
* Every field except `title` is optional because a source is only as much as the
|
|
7
|
+
* host knew: a search result has a snippet, a file has no URL, a tool result has
|
|
8
|
+
* neither. Nothing is inferred from what is missing, and two entries that share a
|
|
9
|
+
* URL stay two entries — the host may have cited two passages of one page, and a
|
|
10
|
+
* list that quietly merged them would also renumber every citation after it.
|
|
11
|
+
*/
|
|
12
|
+
export type Source = Readonly<{
|
|
13
|
+
/** A stable key for streaming updates. Falls back to position. */
|
|
14
|
+
id?: string
|
|
15
|
+
title: string
|
|
16
|
+
url?: string
|
|
17
|
+
snippet?: string
|
|
18
|
+
}>
|
|
19
|
+
|
|
20
|
+
/** Titles and snippets come from the open web; these keep one of them from owning the layout. */
|
|
21
|
+
export const SOURCE_TITLE_LIMIT = 160
|
|
22
|
+
export const SOURCE_SNIPPET_LIMIT = 480
|
|
23
|
+
|
|
24
|
+
// C0 controls other than tab and newline, DEL, and the bidirectional marks,
|
|
25
|
+
// overrides and isolates: the last group is how a title can be made to read as a
|
|
26
|
+
// different string than the one that is stored. Tested by code point rather than
|
|
27
|
+
// by a regular expression so no control or invisible character appears in this file.
|
|
28
|
+
function isHidden(code: number): boolean {
|
|
29
|
+
return (
|
|
30
|
+
code <= 0x08 ||
|
|
31
|
+
code === 0x0b ||
|
|
32
|
+
code === 0x0c ||
|
|
33
|
+
(code >= 0x0e && code <= 0x1f) ||
|
|
34
|
+
code === 0x7f ||
|
|
35
|
+
code === 0x200e ||
|
|
36
|
+
code === 0x200f ||
|
|
37
|
+
(code >= 0x202a && code <= 0x202e) ||
|
|
38
|
+
(code >= 0x2066 && code <= 0x2069)
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function stripHidden(value: string): string {
|
|
43
|
+
let out = ''
|
|
44
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
45
|
+
if (!isHidden(value.charCodeAt(index))) out += value.charAt(index)
|
|
46
|
+
}
|
|
47
|
+
return out
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Untrusted text, made safe to lay out: hidden and direction-overriding
|
|
52
|
+
* characters removed, runs of whitespace (including newlines) collapsed to one
|
|
53
|
+
* space, and clipped to `limit` with an ellipsis. It is still only ever rendered
|
|
54
|
+
* as a text node — this is about length and spoofing, not escaping.
|
|
55
|
+
*/
|
|
56
|
+
export function boundText(value: string, limit: number): string {
|
|
57
|
+
// Clip before the regex passes so a multi-megabyte value costs a slice, not a scan.
|
|
58
|
+
const head = value.length > limit * 4 ? value.slice(0, limit * 4) : value
|
|
59
|
+
const clean = stripHidden(head).replace(/\s+/g, ' ').trim()
|
|
60
|
+
if (clean.length <= limit) return clean
|
|
61
|
+
const clipped = clean.slice(0, limit)
|
|
62
|
+
// Never end on half of a surrogate pair: it renders as a replacement glyph.
|
|
63
|
+
const last = clipped.charCodeAt(clipped.length - 1)
|
|
64
|
+
const whole = last >= 0xd800 && last <= 0xdbff ? clipped.slice(0, -1) : clipped
|
|
65
|
+
return `${whole.trimEnd()}…`
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A URL a link may point at: `http:`, `https:` or `mailto:`, no embedded
|
|
70
|
+
* credentials. `safeHref` (the message parser's own gate) already refuses other
|
|
71
|
+
* schemes, whitespace and control characters and over-long values; credentials are
|
|
72
|
+
* refused here as well because `https://trusted.example@evil.example/` shows a
|
|
73
|
+
* host that is not the one the link goes to.
|
|
74
|
+
*/
|
|
75
|
+
export function safeSourceUrl(value: string | undefined): string | undefined {
|
|
76
|
+
if (value === undefined) return undefined
|
|
77
|
+
const href = safeHref(value)
|
|
78
|
+
if (href === undefined) return undefined
|
|
79
|
+
try {
|
|
80
|
+
const url = new URL(href)
|
|
81
|
+
if (url.username !== '' || url.password !== '') return undefined
|
|
82
|
+
} catch {
|
|
83
|
+
return undefined
|
|
84
|
+
}
|
|
85
|
+
return href
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The host to show beside a title, taken from the parsed URL (so an
|
|
90
|
+
* internationalised name appears in its `xn--` form and a look-alike cannot pass
|
|
91
|
+
* for the real one). A mailto source shows its address. Undefined when the URL is
|
|
92
|
+
* absent or unsafe: nothing is guessed.
|
|
93
|
+
*/
|
|
94
|
+
export function sourceHost(value: string | undefined): string | undefined {
|
|
95
|
+
const href = safeSourceUrl(value)
|
|
96
|
+
if (href === undefined) return undefined
|
|
97
|
+
try {
|
|
98
|
+
const url = new URL(href)
|
|
99
|
+
if (url.protocol === 'mailto:') {
|
|
100
|
+
return boundText(decodeURIComponent(url.pathname), 80) || undefined
|
|
101
|
+
}
|
|
102
|
+
return url.hostname || undefined
|
|
103
|
+
} catch {
|
|
104
|
+
return undefined
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** The line a collapsed list shows. One source is singular; the count is the list's length. */
|
|
109
|
+
export function sourcesLabel(count: number): string {
|
|
110
|
+
return `Used ${count} ${count === 1 ? 'source' : 'sources'}`
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** What to call a source: its title, else its host, else an honest placeholder. */
|
|
114
|
+
export function sourceTitle(source: Source): string {
|
|
115
|
+
return boundText(source.title, SOURCE_TITLE_LIMIT) || sourceHost(source.url) || 'Untitled source'
|
|
116
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { BookOpen } from 'lucide-solid'
|
|
2
|
+
import { createSignal, For, Show, splitProps } from 'solid-js'
|
|
3
|
+
import { Button } from '../../ui/button'
|
|
4
|
+
import { TextLink } from '../../ui/text-link'
|
|
5
|
+
import { Trace, TraceDetail, TraceLine, type TraceProps } from '../../ui/trace'
|
|
6
|
+
import {
|
|
7
|
+
SOURCE_SNIPPET_LIMIT,
|
|
8
|
+
boundText,
|
|
9
|
+
safeSourceUrl,
|
|
10
|
+
sourceHost,
|
|
11
|
+
sourceTitle,
|
|
12
|
+
sourcesLabel,
|
|
13
|
+
type Source,
|
|
14
|
+
} from './source'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Sources.
|
|
18
|
+
*
|
|
19
|
+
* The links a reply used, as one `Trace` line — "Used 4 sources" — that expands
|
|
20
|
+
* into the list. It lives under the answer with the rest of the agent's activity
|
|
21
|
+
* rather than as a card of its own, because a reader who wants to check a claim
|
|
22
|
+
* will open it and one who does not should not have to scroll past it. For a
|
|
23
|
+
* marker inside a sentence use `InlineCitation`, which points at the same
|
|
24
|
+
* `Source` shape; the two are numbered the same way (position in this list).
|
|
25
|
+
*
|
|
26
|
+
* ## What it will and will not say
|
|
27
|
+
*
|
|
28
|
+
* - **No sources, no line.** An empty list renders nothing: "Used 0 sources" is a
|
|
29
|
+
* claim about an answer that may simply not have been grounded.
|
|
30
|
+
* - **A row is a link only with a safe address.** `http:`, `https:` and `mailto:`
|
|
31
|
+
* without embedded credentials (`safeSourceUrl`). Any other address is not
|
|
32
|
+
* linked and not printed — the row says the address was not linked, so the
|
|
33
|
+
* reader knows something was withheld instead of finding a dead title.
|
|
34
|
+
* - **The host is read from the parsed URL**, never from the title, so a title
|
|
35
|
+
* that reads "docs.example.com" cannot make a link to somewhere else look like it.
|
|
36
|
+
* - **Nothing is merged.** Two entries that share a URL are two rows, with their
|
|
37
|
+
* own numbers; the host may have cited two passages and the citations point at
|
|
38
|
+
* positions.
|
|
39
|
+
* - **Hostile and long values are bounded.** Titles, hosts and snippets are
|
|
40
|
+
* clipped and stripped of direction overrides (`boundText`), and are only ever
|
|
41
|
+
* text nodes.
|
|
42
|
+
* - **A long list is shown in pages.** Past `initialVisible` the rest is behind a
|
|
43
|
+
* button that names how many there are, so a 200-source answer is not 200 rows
|
|
44
|
+
* the moment it opens. The button stays in place and toggles, so focus is never
|
|
45
|
+
* left on a control that has just disappeared.
|
|
46
|
+
*/
|
|
47
|
+
export type SourcesProps = Omit<TraceProps, 'children'> & {
|
|
48
|
+
sources: readonly Source[]
|
|
49
|
+
/** Replaces the default "Used N sources" for another language or a different verb. */
|
|
50
|
+
label?: string
|
|
51
|
+
open?: boolean
|
|
52
|
+
defaultOpen?: boolean
|
|
53
|
+
onOpenChange?: (open: boolean) => void
|
|
54
|
+
/** Rows shown before the "Show all" button. Default 25. */
|
|
55
|
+
initialVisible?: number
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const DEFAULT_VISIBLE = 25
|
|
59
|
+
|
|
60
|
+
export function Sources(props: SourcesProps) {
|
|
61
|
+
const [local, rest] = splitProps(props, [
|
|
62
|
+
'sources',
|
|
63
|
+
'label',
|
|
64
|
+
'open',
|
|
65
|
+
'defaultOpen',
|
|
66
|
+
'onOpenChange',
|
|
67
|
+
'initialVisible',
|
|
68
|
+
])
|
|
69
|
+
const [expanded, setExpanded] = createSignal(false)
|
|
70
|
+
const limit = () => Math.max(1, Math.floor(local.initialVisible ?? DEFAULT_VISIBLE))
|
|
71
|
+
const hidden = () => Math.max(0, local.sources.length - limit())
|
|
72
|
+
const visible = () => (expanded() ? local.sources : local.sources.slice(0, limit()))
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<Show when={local.sources.length > 0}>
|
|
76
|
+
<Trace aria-label="Sources" data-slot="sources" {...rest}>
|
|
77
|
+
<TraceLine
|
|
78
|
+
icon={<BookOpen />}
|
|
79
|
+
title={local.label ?? sourcesLabel(local.sources.length)}
|
|
80
|
+
open={local.open}
|
|
81
|
+
defaultOpen={local.defaultOpen}
|
|
82
|
+
onOpenChange={local.onOpenChange}
|
|
83
|
+
>
|
|
84
|
+
<TraceDetail>
|
|
85
|
+
<ol class="m-0 flex list-none flex-col gap-2 p-0" aria-label="Sources used">
|
|
86
|
+
<For each={visible()}>
|
|
87
|
+
{(source, index) => <SourceRow source={source} position={index() + 1} />}
|
|
88
|
+
</For>
|
|
89
|
+
</ol>
|
|
90
|
+
<Show when={hidden() > 0}>
|
|
91
|
+
<Button
|
|
92
|
+
type="button"
|
|
93
|
+
variant="ghost"
|
|
94
|
+
size="xs"
|
|
95
|
+
class="mt-1"
|
|
96
|
+
aria-expanded={expanded()}
|
|
97
|
+
onClick={() => setExpanded((value) => !value)}
|
|
98
|
+
>
|
|
99
|
+
{expanded() ? 'Show fewer sources' : `Show all ${local.sources.length} sources`}
|
|
100
|
+
</Button>
|
|
101
|
+
</Show>
|
|
102
|
+
</TraceDetail>
|
|
103
|
+
</TraceLine>
|
|
104
|
+
</Trace>
|
|
105
|
+
</Show>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function SourceRow(props: { source: Source; position: number }) {
|
|
110
|
+
const href = () => safeSourceUrl(props.source.url)
|
|
111
|
+
const host = () => sourceHost(props.source.url)
|
|
112
|
+
const title = () => sourceTitle(props.source)
|
|
113
|
+
const snippet = () =>
|
|
114
|
+
props.source.snippet ? boundText(props.source.snippet, SOURCE_SNIPPET_LIMIT) : ''
|
|
115
|
+
// An address was supplied but is not one we link: say so rather than go silent.
|
|
116
|
+
const withheld = () => props.source.url !== undefined && props.source.url !== '' && !href()
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<li data-slot="source" class="flex min-w-0 items-baseline gap-2">
|
|
120
|
+
<span
|
|
121
|
+
aria-hidden="true"
|
|
122
|
+
class="w-5 shrink-0 text-end text-xs text-muted-foreground tabular-nums"
|
|
123
|
+
>
|
|
124
|
+
{props.position}
|
|
125
|
+
</span>
|
|
126
|
+
<div class="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
127
|
+
<Show
|
|
128
|
+
when={href()}
|
|
129
|
+
fallback={
|
|
130
|
+
<span class="text-sm text-foreground [overflow-wrap:anywhere]">
|
|
131
|
+
<span class="visually-hidden">Source {props.position}: </span>
|
|
132
|
+
{title()}
|
|
133
|
+
</span>
|
|
134
|
+
}
|
|
135
|
+
>
|
|
136
|
+
{(url) => (
|
|
137
|
+
<TextLink
|
|
138
|
+
href={url()}
|
|
139
|
+
target="_blank"
|
|
140
|
+
rel="noreferrer noopener"
|
|
141
|
+
class="w-fit max-w-full text-sm [overflow-wrap:anywhere]"
|
|
142
|
+
>
|
|
143
|
+
<span class="visually-hidden">Source {props.position}: </span>
|
|
144
|
+
{title()}
|
|
145
|
+
<span class="visually-hidden"> (opens in a new tab)</span>
|
|
146
|
+
</TextLink>
|
|
147
|
+
)}
|
|
148
|
+
</Show>
|
|
149
|
+
<Show when={host() || withheld()}>
|
|
150
|
+
<span class="text-xs text-muted-foreground [overflow-wrap:anywhere]">
|
|
151
|
+
{host()}
|
|
152
|
+
<Show when={withheld()}>{host() ? ' · ' : ''}Address not linked</Show>
|
|
153
|
+
</span>
|
|
154
|
+
</Show>
|
|
155
|
+
<Show when={snippet()}>
|
|
156
|
+
<p class="m-0 line-clamp-3 text-xs text-muted-foreground [overflow-wrap:anywhere]">
|
|
157
|
+
{snippet()}
|
|
158
|
+
</p>
|
|
159
|
+
</Show>
|
|
160
|
+
</div>
|
|
161
|
+
</li>
|
|
162
|
+
)
|
|
163
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { StackTrace, STACK_TRACE_MAX_BLOCKS, type StackTraceProps } from './stack-trace'
|
|
2
|
+
export {
|
|
3
|
+
classifyFrame,
|
|
4
|
+
dedentLines,
|
|
5
|
+
describeFrameGroup,
|
|
6
|
+
frameLocation,
|
|
7
|
+
groupStackEntries,
|
|
8
|
+
parseStackTrace,
|
|
9
|
+
splitLocation,
|
|
10
|
+
STACK_MAX_LINES,
|
|
11
|
+
type ParsedStackTrace,
|
|
12
|
+
type ParseStackTraceOptions,
|
|
13
|
+
type StackBlock,
|
|
14
|
+
type StackEntry,
|
|
15
|
+
type StackFrame,
|
|
16
|
+
type StackFrameKind,
|
|
17
|
+
type StackTraceFormat,
|
|
18
|
+
type StackTraceHeader,
|
|
19
|
+
} from './parse-stack-trace'
|