@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,586 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Check,
|
|
3
|
+
CircleCheck,
|
|
4
|
+
CircleMinus,
|
|
5
|
+
CircleX,
|
|
6
|
+
Copy,
|
|
7
|
+
FlaskConical,
|
|
8
|
+
LoaderCircle,
|
|
9
|
+
} from 'lucide-solid'
|
|
10
|
+
import {
|
|
11
|
+
createComputed,
|
|
12
|
+
createMemo,
|
|
13
|
+
createEffect,
|
|
14
|
+
createSignal,
|
|
15
|
+
For,
|
|
16
|
+
Show,
|
|
17
|
+
splitProps,
|
|
18
|
+
type Accessor,
|
|
19
|
+
type ComponentProps,
|
|
20
|
+
type JSX,
|
|
21
|
+
} from 'solid-js'
|
|
22
|
+
import { writeClipboardText } from '#lib/clipboard'
|
|
23
|
+
import { cn } from '#lib/utils'
|
|
24
|
+
import { Button } from '../../ui/button'
|
|
25
|
+
import { DiffBlock } from '../../ui/diff-block'
|
|
26
|
+
import { Trace, TraceDetail, TraceLine, type TraceStatus } from '../../ui/trace'
|
|
27
|
+
import { StackTrace, type StackTraceProps } from '../stack-trace'
|
|
28
|
+
import {
|
|
29
|
+
boundedEntries,
|
|
30
|
+
describeCount,
|
|
31
|
+
firstFailureRenderPath,
|
|
32
|
+
formatDuration,
|
|
33
|
+
listedCounts,
|
|
34
|
+
reconcileCounts,
|
|
35
|
+
sameFailure,
|
|
36
|
+
siblingKey,
|
|
37
|
+
suiteState,
|
|
38
|
+
type CountLine,
|
|
39
|
+
type TestCase,
|
|
40
|
+
type TestCaseStatus,
|
|
41
|
+
type TestOutcome,
|
|
42
|
+
type TestSuite,
|
|
43
|
+
type TestSummary,
|
|
44
|
+
type FirstFailureRenderPath,
|
|
45
|
+
} from './test-results-model'
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* TestResults.
|
|
49
|
+
*
|
|
50
|
+
* A test run: how it went in words and in a segmented bar, then the suites it
|
|
51
|
+
* ran as `Trace` lines, each opening onto its tests, and a failing test opening
|
|
52
|
+
* onto its message, diff and stack. It is for a run the host can structure; reach
|
|
53
|
+
* for `Terminal` when all there is to show is the command's output, and for
|
|
54
|
+
* `StackTrace` alone when one call failed outside a test.
|
|
55
|
+
*
|
|
56
|
+
* ## Counts are claims
|
|
57
|
+
*
|
|
58
|
+
* Nothing is computed that the host did not supply data for, and nothing the host
|
|
59
|
+
* supplied is quietly recomputed. `summary` is the host's own tally and is shown
|
|
60
|
+
* as given. If tests are listed and their number for an outcome does not match, the
|
|
61
|
+
* listed number is shown beside it — "40 passed (2 listed)" — which is also how a
|
|
62
|
+
* host that lists only its failures reads. Without a `summary` the counts shown are
|
|
63
|
+
* those of the tests listed, and the component says so; it does not present them as
|
|
64
|
+
* the run's totals. A suite is marked failed or passed only from the tests listed in
|
|
65
|
+
* it, and its spoken label says "listed" so it claims no more than that.
|
|
66
|
+
*
|
|
67
|
+
* ## Not colour-only
|
|
68
|
+
*
|
|
69
|
+
* The bar is decoration: every segment has a counterpart in the words beside it,
|
|
70
|
+
* each with its own shape (a cross, a tick, a dash). Segments are separated by a
|
|
71
|
+
* gap and never narrower than a visible sliver, so one failure in five thousand
|
|
72
|
+
* tests is still on the bar.
|
|
73
|
+
*
|
|
74
|
+
* ## Bounded
|
|
75
|
+
*
|
|
76
|
+
* Suites and tests are listed `listLimit` at a time with "show more", and a suite's
|
|
77
|
+
* tests are not rendered until it is open. The first failure in reading order opens
|
|
78
|
+
* when its row is visible; a failure beyond a "show more" boundary stays unmounted
|
|
79
|
+
* until its page is revealed. When a running result first reports a failure, its
|
|
80
|
+
* suite and test open once. Later updates preserve the user's disclosure choices.
|
|
81
|
+
*
|
|
82
|
+
* Failure details are text: the message is a `pre`, the diff goes to `DiffBlock`
|
|
83
|
+
* and the stack to `StackTrace`. If a stack already begins with the message, pass
|
|
84
|
+
* only the stack; nothing here de-duplicates what the host sends.
|
|
85
|
+
*/
|
|
86
|
+
export type TestResultsProps = Omit<ComponentProps<'section'>, 'children'> & {
|
|
87
|
+
suites: readonly TestSuite[]
|
|
88
|
+
/** The host's own counts. Shown as given; see the component comment. */
|
|
89
|
+
summary?: TestSummary
|
|
90
|
+
/** The run is still going. */
|
|
91
|
+
running?: boolean
|
|
92
|
+
/** Suites, or tests within a suite, listed before "show more". Default 50. */
|
|
93
|
+
listLimit?: number
|
|
94
|
+
/** Passed to each failure's `StackTrace`. */
|
|
95
|
+
onOpenFrame?: StackTraceProps['onOpenFrame']
|
|
96
|
+
/** The section's accessible name. Default "Test results". */
|
|
97
|
+
label?: string
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const TEST_RESULTS_LIST_LIMIT = 50
|
|
101
|
+
|
|
102
|
+
const OUTCOME_ICON: Readonly<Record<TestOutcome, () => JSX.Element>> = {
|
|
103
|
+
failed: () => <CircleX aria-hidden="true" class="size-3.5 text-destructive" />,
|
|
104
|
+
passed: () => <CircleCheck aria-hidden="true" class="size-3.5 text-success" />,
|
|
105
|
+
skipped: () => <CircleMinus aria-hidden="true" class="size-3.5 text-muted-foreground" />,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function CountReadout(props: { line: CountLine }) {
|
|
109
|
+
return (
|
|
110
|
+
<span class="flex items-center gap-1 whitespace-nowrap" data-outcome={props.line.outcome}>
|
|
111
|
+
{OUTCOME_ICON[props.line.outcome]()}
|
|
112
|
+
{describeCount(props.line)}
|
|
113
|
+
</span>
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Segments are drawn in this order so the bar reads the same in every run.
|
|
118
|
+
const SEGMENT_CLASS: Readonly<Record<TestOutcome, string>> = {
|
|
119
|
+
failed: 'bg-destructive',
|
|
120
|
+
passed: 'bg-success',
|
|
121
|
+
skipped: 'bg-muted-foreground/40',
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function SummaryBar(props: { lines: readonly CountLine[] }) {
|
|
125
|
+
const visible = () => props.lines.filter((line) => line.count > 0)
|
|
126
|
+
return (
|
|
127
|
+
<Show when={visible().length > 0}>
|
|
128
|
+
<div
|
|
129
|
+
aria-hidden="true"
|
|
130
|
+
data-slot="test-results-bar"
|
|
131
|
+
class="flex h-1.5 w-full gap-px overflow-hidden rounded-full bg-muted"
|
|
132
|
+
>
|
|
133
|
+
<For each={visible()}>
|
|
134
|
+
{(line) => (
|
|
135
|
+
<span
|
|
136
|
+
class={cn('min-w-1', SEGMENT_CLASS[line.outcome])}
|
|
137
|
+
style={{ flex: `${line.count} 1 0` }}
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
</For>
|
|
141
|
+
</div>
|
|
142
|
+
</Show>
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const TRACE_STATUS: Readonly<Record<TestCaseStatus, { status: TraceStatus; label: string }>> = {
|
|
147
|
+
passed: { status: 'success', label: 'Passed' },
|
|
148
|
+
failed: { status: 'error', label: 'Failed' },
|
|
149
|
+
skipped: { status: 'cancelled', label: 'Skipped' },
|
|
150
|
+
running: { status: 'running', label: 'Running' },
|
|
151
|
+
pending: { status: 'pending', label: 'Not run yet' },
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Keep keyboard focus through a reorder. Solid moves a keyed row's node instead
|
|
156
|
+
* of replacing it, and a browser blurs a focused element that is moved, so an
|
|
157
|
+
* immutable reorder would drop the reader's place onto the body even though the
|
|
158
|
+
* node and its open state survive. The focused element is noted just before the
|
|
159
|
+
* rows move and given focus back just after, but only when nothing else has taken
|
|
160
|
+
* focus meanwhile, and only inside a test run, so a reader who has moved on is
|
|
161
|
+
* never pulled back and an unrelated element is never refocused.
|
|
162
|
+
*/
|
|
163
|
+
function keepFocusThroughReorder(keys: Accessor<readonly string[]>) {
|
|
164
|
+
let noted: HTMLElement | undefined
|
|
165
|
+
createComputed(() => {
|
|
166
|
+
keys()
|
|
167
|
+
const active = typeof document === 'undefined' ? null : document.activeElement
|
|
168
|
+
noted =
|
|
169
|
+
active instanceof HTMLElement && active.closest('[data-slot="test-results"]')
|
|
170
|
+
? active
|
|
171
|
+
: undefined
|
|
172
|
+
})
|
|
173
|
+
createEffect(() => {
|
|
174
|
+
keys()
|
|
175
|
+
const element = noted
|
|
176
|
+
noted = undefined
|
|
177
|
+
if (!element || !element.isConnected) return
|
|
178
|
+
const active = document.activeElement
|
|
179
|
+
if (active === null || active === document.body) element.focus({ preventScroll: true })
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** A list that shows its first `limit` items and offers the rest. */
|
|
184
|
+
function Bounded<T>(props: {
|
|
185
|
+
items: readonly T[]
|
|
186
|
+
itemKey: (item: T, index: number) => string
|
|
187
|
+
limit: number
|
|
188
|
+
noun: string
|
|
189
|
+
children: (item: Accessor<T>, index: Accessor<number>, key: string) => JSX.Element
|
|
190
|
+
}) {
|
|
191
|
+
const [shown, setShown] = createSignal(props.limit)
|
|
192
|
+
const page = createMemo(() => boundedEntries(props.items, shown(), props.itemKey))
|
|
193
|
+
const visible = () => page().entries
|
|
194
|
+
const visibleKeys = createMemo(() => visible().map((entry) => entry.key))
|
|
195
|
+
keepFocusThroughReorder(visibleKeys)
|
|
196
|
+
const hidden = () => props.items.length - visible().length
|
|
197
|
+
return (
|
|
198
|
+
<>
|
|
199
|
+
<For each={visibleKeys()}>
|
|
200
|
+
{(key) => {
|
|
201
|
+
const entry = createMemo(() => page().byKey.get(key)!)
|
|
202
|
+
return props.children(
|
|
203
|
+
() => entry().item,
|
|
204
|
+
() => entry().index,
|
|
205
|
+
key
|
|
206
|
+
)
|
|
207
|
+
}}
|
|
208
|
+
</For>
|
|
209
|
+
<Show when={hidden() > 0}>
|
|
210
|
+
<li class="px-1.5 py-0.5">
|
|
211
|
+
<Button variant="ghost" size="2xs" onClick={() => setShown(shown() + props.limit)}>
|
|
212
|
+
Show {Math.min(hidden(), props.limit).toLocaleString()} more {props.noun} (
|
|
213
|
+
{hidden().toLocaleString()} hidden)
|
|
214
|
+
</Button>
|
|
215
|
+
</li>
|
|
216
|
+
</Show>
|
|
217
|
+
</>
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Characters of a failure message drawn before the rest is offered. */
|
|
222
|
+
export const TEST_RESULTS_MESSAGE_LIMIT = 4_000
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* A failed test's message, which a runner may print at any length: a captured
|
|
226
|
+
* log, a serialized object, a long assertion. It opens on its own for the first
|
|
227
|
+
* failure, so it is bounded where the diff and stack are already bounded: the
|
|
228
|
+
* body scrolls past a fixed height, only the first characters are drawn until the
|
|
229
|
+
* reader asks for the rest, and Copy writes all of it.
|
|
230
|
+
*/
|
|
231
|
+
function FailureMessage(props: { text: string; onCopy?: (ok: boolean) => void }) {
|
|
232
|
+
const [all, setAll] = createSignal(false)
|
|
233
|
+
const [copied, setCopied] = createSignal(false)
|
|
234
|
+
const [copyFailed, setCopyFailed] = createSignal(false)
|
|
235
|
+
const clipped = () => props.text.length > TEST_RESULTS_MESSAGE_LIMIT
|
|
236
|
+
const cut = () => {
|
|
237
|
+
// Never inside a surrogate pair, which would draw a replacement character.
|
|
238
|
+
const last = props.text.charCodeAt(TEST_RESULTS_MESSAGE_LIMIT - 1)
|
|
239
|
+
return last >= 0xd800 && last <= 0xdbff
|
|
240
|
+
? TEST_RESULTS_MESSAGE_LIMIT - 1
|
|
241
|
+
: TEST_RESULTS_MESSAGE_LIMIT
|
|
242
|
+
}
|
|
243
|
+
const shown = () => (clipped() && !all() ? props.text.slice(0, cut()) : props.text)
|
|
244
|
+
const copy = async () => {
|
|
245
|
+
let ok = true
|
|
246
|
+
try {
|
|
247
|
+
await writeClipboardText(props.text)
|
|
248
|
+
} catch {
|
|
249
|
+
ok = false
|
|
250
|
+
}
|
|
251
|
+
setCopied(ok)
|
|
252
|
+
setCopyFailed(!ok)
|
|
253
|
+
props.onCopy?.(ok)
|
|
254
|
+
if (ok) setTimeout(() => setCopied(false), 1500)
|
|
255
|
+
}
|
|
256
|
+
return (
|
|
257
|
+
<>
|
|
258
|
+
{/* A region that scrolls is a tab stop and needs a name. */}
|
|
259
|
+
<pre
|
|
260
|
+
data-slot="test-results-message"
|
|
261
|
+
tabindex="0"
|
|
262
|
+
role="group"
|
|
263
|
+
aria-label="Failure message"
|
|
264
|
+
class="m-0 max-h-64 overflow-auto font-code text-code whitespace-pre-wrap text-foreground [overflow-wrap:anywhere]"
|
|
265
|
+
>
|
|
266
|
+
{shown()}
|
|
267
|
+
</pre>
|
|
268
|
+
<Show when={clipped()}>
|
|
269
|
+
<div class="flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground">
|
|
270
|
+
<span class="italic">
|
|
271
|
+
<Show
|
|
272
|
+
when={!all()}
|
|
273
|
+
fallback={`All ${props.text.length.toLocaleString()} characters shown.`}
|
|
274
|
+
>
|
|
275
|
+
Showing the first {cut().toLocaleString()} of {props.text.length.toLocaleString()}{' '}
|
|
276
|
+
characters (copy has all of it).
|
|
277
|
+
</Show>
|
|
278
|
+
</span>
|
|
279
|
+
<Show when={!all()}>
|
|
280
|
+
<Button variant="ghost" size="2xs" onClick={() => setAll(true)}>
|
|
281
|
+
Show all {props.text.length.toLocaleString()} characters
|
|
282
|
+
</Button>
|
|
283
|
+
</Show>
|
|
284
|
+
<Button
|
|
285
|
+
variant="ghost"
|
|
286
|
+
size="2xs"
|
|
287
|
+
title={copyFailed() ? 'Copying is unavailable in this context' : undefined}
|
|
288
|
+
onClick={() => void copy()}
|
|
289
|
+
>
|
|
290
|
+
<Show when={copied()} fallback={<Copy aria-hidden="true" />}>
|
|
291
|
+
<Check aria-hidden="true" />
|
|
292
|
+
</Show>
|
|
293
|
+
{copied() ? 'Copied' : 'Copy message'}
|
|
294
|
+
</Button>
|
|
295
|
+
</div>
|
|
296
|
+
</Show>
|
|
297
|
+
</>
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function TestLine(props: {
|
|
302
|
+
test: Accessor<TestCase>
|
|
303
|
+
keyed: string
|
|
304
|
+
failure?: FirstFailureRenderPath
|
|
305
|
+
onOpenFrame?: TestResultsProps['onOpenFrame']
|
|
306
|
+
}) {
|
|
307
|
+
const test = () => props.test()
|
|
308
|
+
const state = () => (test().status ? TRACE_STATUS[test().status as TestCaseStatus] : undefined)
|
|
309
|
+
// Whether there is anything to disclose. Read once per change, so the disclosure
|
|
310
|
+
// exists while closed without anything below it being built.
|
|
311
|
+
const hasDetail = createMemo(() => Boolean(test().message || test().diff || test().stack))
|
|
312
|
+
// Only the last suite on the failure's path is given it, so a key among
|
|
313
|
+
// this suite's tests is enough to know the failure is this test.
|
|
314
|
+
const failureKey = createMemo(
|
|
315
|
+
() => (props.failure?.test === props.keyed ? props.failure : undefined),
|
|
316
|
+
undefined,
|
|
317
|
+
{ equals: sameFailure }
|
|
318
|
+
)
|
|
319
|
+
const [open, setOpen] = createSignal(failureKey() !== undefined)
|
|
320
|
+
let previousFailure = failureKey()
|
|
321
|
+
let collapsedFailure: FirstFailureRenderPath | undefined
|
|
322
|
+
|
|
323
|
+
createEffect(() => {
|
|
324
|
+
const currentFailure = failureKey()
|
|
325
|
+
if (
|
|
326
|
+
currentFailure &&
|
|
327
|
+
!sameFailure(currentFailure, previousFailure) &&
|
|
328
|
+
!sameFailure(currentFailure, collapsedFailure)
|
|
329
|
+
) {
|
|
330
|
+
setOpen(true)
|
|
331
|
+
}
|
|
332
|
+
previousFailure = currentFailure
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
const handleOpenChange = (next: boolean) => {
|
|
336
|
+
if (!next && failureKey()) collapsedFailure = failureKey()
|
|
337
|
+
else if (next) collapsedFailure = undefined
|
|
338
|
+
setOpen(next)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return (
|
|
342
|
+
<TraceLine
|
|
343
|
+
title={test().name}
|
|
344
|
+
status={state()?.status}
|
|
345
|
+
statusLabel={state()?.label}
|
|
346
|
+
meta={formatDuration(test().durationMs)}
|
|
347
|
+
open={open()}
|
|
348
|
+
onOpenChange={handleOpenChange}
|
|
349
|
+
>
|
|
350
|
+
{hasDetail() ? (
|
|
351
|
+
// A closed test builds nothing: the body is made when it is opened, so a diff or
|
|
352
|
+
// stack is not parsed for every test of an open suite.
|
|
353
|
+
<Show when={open()}>
|
|
354
|
+
<TraceDetail class="flex flex-col gap-2">
|
|
355
|
+
<Show when={test().message}>
|
|
356
|
+
<FailureMessage text={test().message!} />
|
|
357
|
+
</Show>
|
|
358
|
+
<Show when={test().diff}>
|
|
359
|
+
<DiffBlock patch={test().diff!} complete title="Expected and received" />
|
|
360
|
+
</Show>
|
|
361
|
+
<Show when={test().stack}>
|
|
362
|
+
<StackTrace text={test().stack!} onOpenFrame={props.onOpenFrame} />
|
|
363
|
+
</Show>
|
|
364
|
+
</TraceDetail>
|
|
365
|
+
</Show>
|
|
366
|
+
) : undefined}
|
|
367
|
+
</TraceLine>
|
|
368
|
+
)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function SuiteLine(props: {
|
|
372
|
+
suite: Accessor<TestSuite>
|
|
373
|
+
/** This suite's key among its siblings. */
|
|
374
|
+
keyed: string
|
|
375
|
+
/** How many suites enclose this one. */
|
|
376
|
+
depth: number
|
|
377
|
+
limit: number
|
|
378
|
+
/** The first failure, given only to suites on the way to it. */
|
|
379
|
+
failure?: FirstFailureRenderPath
|
|
380
|
+
onOpenFrame?: TestResultsProps['onOpenFrame']
|
|
381
|
+
}) {
|
|
382
|
+
const suite = () => props.suite()
|
|
383
|
+
const counts = createMemo(() => listedCounts([suite()]))
|
|
384
|
+
const state = createMemo(() => suiteState(counts()))
|
|
385
|
+
const children = () => (suite().tests?.length ?? 0) + (suite().suites?.length ?? 0) > 0
|
|
386
|
+
const [open, setOpen] = createSignal(state() === 'failed')
|
|
387
|
+
// The parent passes the failure down only while it is on the way to it, so
|
|
388
|
+
// one comparison at this suite's own depth settles whether it is on the path.
|
|
389
|
+
// Memoised: each level reads its parent's, so a bare function would re-run the
|
|
390
|
+
// whole chain above it on every read and cost exponential time in the depth.
|
|
391
|
+
const failure = createMemo(
|
|
392
|
+
() => (props.failure?.suites[props.depth] === props.keyed ? props.failure : undefined),
|
|
393
|
+
undefined,
|
|
394
|
+
{ equals: sameFailure }
|
|
395
|
+
)
|
|
396
|
+
const holdsFailure = createMemo(() => failure()?.suites.length === props.depth + 1)
|
|
397
|
+
let previousFailure = failure()
|
|
398
|
+
let collapsedFailure: FirstFailureRenderPath | undefined
|
|
399
|
+
|
|
400
|
+
createEffect(() => {
|
|
401
|
+
const currentFailure = failure()
|
|
402
|
+
if (
|
|
403
|
+
currentFailure &&
|
|
404
|
+
!sameFailure(currentFailure, previousFailure) &&
|
|
405
|
+
!sameFailure(currentFailure, collapsedFailure)
|
|
406
|
+
) {
|
|
407
|
+
setOpen(true)
|
|
408
|
+
}
|
|
409
|
+
previousFailure = currentFailure
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
const handleOpenChange = (next: boolean) => {
|
|
413
|
+
if (!next && failure()) collapsedFailure = failure()
|
|
414
|
+
else if (next) collapsedFailure = undefined
|
|
415
|
+
setOpen(next)
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const description = () => {
|
|
419
|
+
const parts = [
|
|
420
|
+
suite().file,
|
|
421
|
+
counts().failed > 0 ? `${counts().failed.toLocaleString()} failed` : undefined,
|
|
422
|
+
]
|
|
423
|
+
return parts.filter(Boolean).join(' · ') || undefined
|
|
424
|
+
}
|
|
425
|
+
return (
|
|
426
|
+
<TraceLine
|
|
427
|
+
icon={<FlaskConical />}
|
|
428
|
+
title={suite().name}
|
|
429
|
+
description={description()}
|
|
430
|
+
status={
|
|
431
|
+
state() === 'failed'
|
|
432
|
+
? 'error'
|
|
433
|
+
: state() === 'running'
|
|
434
|
+
? 'running'
|
|
435
|
+
: state() === 'passed'
|
|
436
|
+
? 'success'
|
|
437
|
+
: undefined
|
|
438
|
+
}
|
|
439
|
+
statusLabel={
|
|
440
|
+
state() === 'failed'
|
|
441
|
+
? 'Has failing tests'
|
|
442
|
+
: state() === 'passed'
|
|
443
|
+
? 'All listed tests passed'
|
|
444
|
+
: undefined
|
|
445
|
+
}
|
|
446
|
+
meta={formatDuration(suite().durationMs)}
|
|
447
|
+
open={open()}
|
|
448
|
+
onOpenChange={handleOpenChange}
|
|
449
|
+
>
|
|
450
|
+
{children() ? (
|
|
451
|
+
<div>
|
|
452
|
+
<Show when={open()}>
|
|
453
|
+
<Trace size="sm" aria-label={`${suite().name} tests`}>
|
|
454
|
+
<Bounded
|
|
455
|
+
items={suite().tests ?? []}
|
|
456
|
+
itemKey={siblingKey}
|
|
457
|
+
limit={props.limit}
|
|
458
|
+
noun="tests"
|
|
459
|
+
>
|
|
460
|
+
{(test, _index, key) => (
|
|
461
|
+
<TestLine
|
|
462
|
+
test={test}
|
|
463
|
+
keyed={key}
|
|
464
|
+
failure={holdsFailure() ? failure() : undefined}
|
|
465
|
+
onOpenFrame={props.onOpenFrame}
|
|
466
|
+
/>
|
|
467
|
+
)}
|
|
468
|
+
</Bounded>
|
|
469
|
+
<Bounded
|
|
470
|
+
items={suite().suites ?? []}
|
|
471
|
+
itemKey={siblingKey}
|
|
472
|
+
limit={props.limit}
|
|
473
|
+
noun="suites"
|
|
474
|
+
>
|
|
475
|
+
{(nested, _index, key) => (
|
|
476
|
+
<SuiteLine
|
|
477
|
+
suite={nested}
|
|
478
|
+
keyed={key}
|
|
479
|
+
depth={props.depth + 1}
|
|
480
|
+
limit={props.limit}
|
|
481
|
+
failure={failure()}
|
|
482
|
+
onOpenFrame={props.onOpenFrame}
|
|
483
|
+
/>
|
|
484
|
+
)}
|
|
485
|
+
</Bounded>
|
|
486
|
+
</Trace>
|
|
487
|
+
</Show>
|
|
488
|
+
</div>
|
|
489
|
+
) : undefined}
|
|
490
|
+
</TraceLine>
|
|
491
|
+
)
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export function TestResults(props: TestResultsProps) {
|
|
495
|
+
const [local, rest] = splitProps(props, [
|
|
496
|
+
'suites',
|
|
497
|
+
'summary',
|
|
498
|
+
'running',
|
|
499
|
+
'listLimit',
|
|
500
|
+
'onOpenFrame',
|
|
501
|
+
'label',
|
|
502
|
+
'class',
|
|
503
|
+
])
|
|
504
|
+
|
|
505
|
+
const listed = createMemo(() => listedCounts(local.suites))
|
|
506
|
+
const counts = createMemo(() => reconcileCounts(local.summary, listed()))
|
|
507
|
+
const limit = () => Math.max(1, Math.floor(local.listLimit ?? TEST_RESULTS_LIST_LIMIT))
|
|
508
|
+
const failure = createMemo(() => firstFailureRenderPath(local.suites), undefined, {
|
|
509
|
+
equals: sameFailure,
|
|
510
|
+
})
|
|
511
|
+
const duration = () => formatDuration(local.summary?.durationMs, 'long')
|
|
512
|
+
const nothing = () =>
|
|
513
|
+
counts().lines.length === 0 &&
|
|
514
|
+
counts().reportedTotal === undefined &&
|
|
515
|
+
local.suites.length === 0 &&
|
|
516
|
+
!local.running
|
|
517
|
+
|
|
518
|
+
return (
|
|
519
|
+
<section
|
|
520
|
+
data-slot="test-results"
|
|
521
|
+
aria-label={local.label ?? 'Test results'}
|
|
522
|
+
aria-busy={local.running || undefined}
|
|
523
|
+
class={cn('flex min-w-0 flex-col gap-2', local.class)}
|
|
524
|
+
{...rest}
|
|
525
|
+
>
|
|
526
|
+
<Show
|
|
527
|
+
when={!nothing()}
|
|
528
|
+
fallback={<p class="m-0 text-sm text-muted-foreground">No test results</p>}
|
|
529
|
+
>
|
|
530
|
+
<div class="flex flex-col gap-1.5">
|
|
531
|
+
<div class="flex flex-wrap items-center gap-x-3 gap-y-1 text-sm">
|
|
532
|
+
<Show when={local.running}>
|
|
533
|
+
<span class="flex items-center gap-1 text-info">
|
|
534
|
+
<LoaderCircle aria-hidden="true" class="size-3.5 motion-safe:animate-spin" />
|
|
535
|
+
Running
|
|
536
|
+
</span>
|
|
537
|
+
</Show>
|
|
538
|
+
<For each={counts().lines}>{(line) => <CountReadout line={line} />}</For>
|
|
539
|
+
<Show
|
|
540
|
+
when={
|
|
541
|
+
counts().lines.length === 0 &&
|
|
542
|
+
!counts().totalNote &&
|
|
543
|
+
counts().reportedTotal !== undefined
|
|
544
|
+
}
|
|
545
|
+
>
|
|
546
|
+
<span class="text-muted-foreground">
|
|
547
|
+
{counts().reportedTotal?.toLocaleString()} tests reported
|
|
548
|
+
</span>
|
|
549
|
+
</Show>
|
|
550
|
+
<Show when={counts().totalNote}>
|
|
551
|
+
{(note) => (
|
|
552
|
+
<span class="text-muted-foreground">
|
|
553
|
+
{note().reported.toLocaleString()} tests reported (
|
|
554
|
+
{note().listed.toLocaleString()} listed)
|
|
555
|
+
</span>
|
|
556
|
+
)}
|
|
557
|
+
</Show>
|
|
558
|
+
<Show when={duration()}>
|
|
559
|
+
<span class="text-muted-foreground">in {duration()}</span>
|
|
560
|
+
</Show>
|
|
561
|
+
</div>
|
|
562
|
+
<SummaryBar lines={counts().lines} />
|
|
563
|
+
<Show when={counts().basis === 'listed' && counts().lines.length > 0}>
|
|
564
|
+
<p class="m-0 text-xs text-muted-foreground">Counts are from the tests listed below.</p>
|
|
565
|
+
</Show>
|
|
566
|
+
</div>
|
|
567
|
+
<Show when={local.suites.length > 0}>
|
|
568
|
+
<Trace aria-label="Test suites">
|
|
569
|
+
<Bounded items={local.suites} itemKey={siblingKey} limit={limit()} noun="suites">
|
|
570
|
+
{(suite, _index, key) => (
|
|
571
|
+
<SuiteLine
|
|
572
|
+
suite={suite}
|
|
573
|
+
keyed={key}
|
|
574
|
+
depth={0}
|
|
575
|
+
limit={limit()}
|
|
576
|
+
failure={failure()}
|
|
577
|
+
onOpenFrame={local.onOpenFrame}
|
|
578
|
+
/>
|
|
579
|
+
)}
|
|
580
|
+
</Bounded>
|
|
581
|
+
</Trace>
|
|
582
|
+
</Show>
|
|
583
|
+
</Show>
|
|
584
|
+
</section>
|
|
585
|
+
)
|
|
586
|
+
}
|