@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 @@
|
|
|
1
|
+
{"version":3,"file":"chat.js","names":["CircleAlert","Info","TriangleAlert","Show","splitProps","ComponentProps","JSX","Dynamic","cn","cva","VariantProps","ChatProps","header","Element","notices","composer","Chat","props","local","rest","_el$","_tmpl$","_el$2","firstChild","_el$3","nextSibling","_el$4","_el$5","_$spread","_$mergeProps","class","_$insert","children","ChatHeaderProps","Omit","title","subtitle","status","actions","ChatHeader","_el$6","_tmpl$4","_el$7","_el$8","_$createComponent","when","_el$9","_tmpl$2","_el$0","_tmpl$3","chatNoticeVariants","variants","tone","info","warning","danger","defaultVariants","ChatNoticeProps","description","action","live","ChatNotice","Glyph","_el$1","_tmpl$7","_el$10","_el$11","_el$12","role","_$memo","undefined","component","_el$13","_tmpl$5","_el$14","_tmpl$6","_$effect","_$className","ChatEmptyProps","suggestions","ChatEmpty","_el$15","_tmpl$9","_el$16","_el$17","_el$18","_tmpl$8","_$mergeProps","_$createComponent","_$memo","_$className"],"sources":["../../../../src/components/composites/chat/chat.tsx"],"sourcesContent":["import { CircleAlert, Info, TriangleAlert } from 'lucide-solid'\nimport { Show, splitProps, type ComponentProps, type JSX } from 'solid-js'\nimport { Dynamic } from 'solid-js/web'\nimport { cn } from '#lib/utils'\nimport { cva, type VariantProps } from '#lib/variants'\n\n/**\n * Chat.\n *\n * The frame a conversation lives in: a header, a strip for things the reader\n * must know before reading anything else, the thread, and the composer. It is a\n * layout and nothing more — the thread is a `MessageScroller`, the input is a\n * composer, and what happens in between is the host's — which is why it takes\n * slots instead of data.\n *\n * ## Why notices have their own row\n *\n * \"The connection dropped\", \"this transcript has a gap\", \"this session is\n * read-only\" are about the whole conversation, not about a turn, and they must\n * not scroll away with the turns. They sit between the header and the thread in\n * their own grid track, so a notice appearing never steals the thread's row and\n * collapses to zero height when there are none. Each notice states its cause in\n * words and carries its own remedy (`action`); one that reports a *change*\n * (`live`) is announced, one that describes a standing condition is not.\n *\n * ## Layout\n *\n * `h-full min-h-0`, so the thread scrolls inside the frame rather than the page\n * growing, and a `min-w-0` track, so a long unbroken token in a turn cannot widen\n * the whole conversation. Nothing here sets a width: the reading column is the\n * turn's, and the composer sets its own measure.\n */\nexport type ChatProps = ComponentProps<'section'> & {\n header?: JSX.Element\n /** `ChatNotice`s. The row collapses when this is empty. */\n notices?: JSX.Element\n /** The composer. */\n composer?: JSX.Element\n}\n\nexport function Chat(props: ChatProps) {\n const [local, rest] = splitProps(props, ['class', 'header', 'notices', 'composer', 'children'])\n return (\n <section\n data-slot=\"chat\"\n class={cn(\n 'grid h-full min-h-0 min-w-0 grid-cols-[minmax(0,1fr)] grid-rows-[auto_auto_minmax(0,1fr)_auto] bg-background text-foreground',\n local.class\n )}\n {...rest}\n >\n <div class=\"row-start-1 min-w-0\">{local.header}</div>\n <div class=\"row-start-2 flex min-w-0 flex-col\">{local.notices}</div>\n <div class=\"row-start-3 flex min-h-0 min-w-0 flex-col\">{local.children}</div>\n <div class=\"row-start-4 min-w-0\">{local.composer}</div>\n </section>\n )\n}\n\nexport type ChatHeaderProps = Omit<ComponentProps<'header'>, 'title'> & {\n title: JSX.Element\n /** One line under the title: identity, scope, generation. */\n subtitle?: JSX.Element\n /** The conversation's state in words (a `StatusChip`). */\n status?: JSX.Element\n /** Host actions: rename, archive, hand off. */\n actions?: JSX.Element\n}\n\nexport function ChatHeader(props: ChatHeaderProps) {\n const [local, rest] = splitProps(props, ['class', 'title', 'subtitle', 'status', 'actions'])\n return (\n <header\n data-slot=\"chat-header\"\n class={cn(\n 'flex min-h-topbar min-w-0 items-center gap-3 border-b border-border px-4 py-2',\n local.class\n )}\n {...rest}\n >\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <h2 class=\"m-0 truncate text-sm font-semibold tracking-tight\">{local.title}</h2>\n <Show when={local.subtitle}>\n <p class=\"m-0 truncate text-xs text-muted-foreground\">{local.subtitle}</p>\n </Show>\n </div>\n <Show when={local.status}>{local.status}</Show>\n <Show when={local.actions}>\n <div class=\"flex shrink-0 items-center gap-1\">{local.actions}</div>\n </Show>\n </header>\n )\n}\n\nexport const chatNoticeVariants = cva(\n 'flex min-w-0 items-start gap-2.5 border-b px-4 py-2 text-sm',\n {\n variants: {\n tone: {\n info: 'border-border bg-muted/40',\n warning: 'border-warning/30 bg-warning-subtle',\n danger: 'border-destructive/30 bg-destructive-subtle',\n },\n },\n defaultVariants: { tone: 'info' },\n }\n)\n\nexport type ChatNoticeProps = Omit<ComponentProps<'div'>, 'title'> &\n VariantProps<typeof chatNoticeVariants> & {\n title: JSX.Element\n description?: JSX.Element\n /** The remedy: Reconnect, Jump to terminal. */\n action?: JSX.Element\n /** Announce it. Use for a change (connection lost), not a standing condition. */\n live?: 'polite' | 'assertive'\n }\n\nexport function ChatNotice(props: ChatNoticeProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'tone',\n 'title',\n 'description',\n 'action',\n 'live',\n ])\n const Glyph = () =>\n local.tone === 'danger' ? CircleAlert : local.tone === 'warning' ? TriangleAlert : Info\n return (\n <div\n data-slot=\"chat-notice\"\n role={local.live === 'assertive' ? 'alert' : local.live === 'polite' ? 'status' : undefined}\n class={cn(chatNoticeVariants({ tone: local.tone }), local.class)}\n {...rest}\n >\n <span\n aria-hidden=\"true\"\n class={cn('mt-0.5 shrink-0 [&_svg]:size-4', {\n 'text-muted-foreground': (local.tone ?? 'info') === 'info',\n 'text-warning': local.tone === 'warning',\n 'text-destructive': local.tone === 'danger',\n })}\n >\n <Dynamic component={Glyph()} />\n </span>\n <div class=\"min-w-0 flex-1\">\n <p class=\"m-0 font-medium [overflow-wrap:anywhere]\">{local.title}</p>\n <Show when={local.description}>\n <p class=\"m-0 text-xs text-muted-foreground [overflow-wrap:anywhere]\">\n {local.description}\n </p>\n </Show>\n </div>\n <Show when={local.action}>\n <div class=\"flex shrink-0 items-center gap-1.5\">{local.action}</div>\n </Show>\n </div>\n )\n}\n\nexport type ChatEmptyProps = Omit<ComponentProps<'div'>, 'title'> & {\n title: JSX.Element\n description?: JSX.Element\n /** Prompt chips (`Suggestions`), shown only when the host has real ones. */\n suggestions?: JSX.Element\n}\n\n/** A conversation with no turns yet. Centred in the thread, never in a card. */\nexport function ChatEmpty(props: ChatEmptyProps) {\n const [local, rest] = splitProps(props, ['class', 'title', 'description', 'suggestions'])\n return (\n <div\n data-slot=\"chat-empty\"\n class={cn(\n 'mx-auto flex min-h-full w-full max-w-xl flex-col items-center justify-center gap-4 px-6 py-10 text-center',\n local.class\n )}\n {...rest}\n >\n <div class=\"flex flex-col gap-1\">\n <h3 class=\"m-0 text-base font-semibold tracking-tight text-balance\">{local.title}</h3>\n <Show when={local.description}>\n <p class=\"m-0 text-sm text-muted-foreground text-balance\">{local.description}</p>\n </Show>\n </div>\n <Show when={local.suggestions}>{local.suggestions}</Show>\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/chat/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,SAAS,EACT,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,SAAS,GACf,MAAM,QAAQ,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a restore stands. `idle` is the resting state of a checkpoint that has
|
|
3
|
+
* not been restored from; the other three are only ever set because something
|
|
4
|
+
* happened — the host passes them, or the component sets them from the promise
|
|
5
|
+
* `onRestore` returned.
|
|
6
|
+
*/
|
|
7
|
+
export type CheckpointState = 'idle' | 'restoring' | 'restored' | 'failed';
|
|
8
|
+
/** The checkpoint's name as drawn; a blank label is the honest generic word. */
|
|
9
|
+
export declare function checkpointLabel(label: string | undefined): string;
|
|
10
|
+
/**
|
|
11
|
+
* The sentence for the status region. `idle` says nothing, because a
|
|
12
|
+
* checkpoint that has not been touched makes no statement. A failure carries the
|
|
13
|
+
* host's text when there is one.
|
|
14
|
+
*/
|
|
15
|
+
export declare function checkpointStatus(state: CheckpointState, error?: string, disabledReason?: string): string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* The confirmation dialog's words. The host's `consequence` is what actually
|
|
18
|
+
* names what will change, so it is used verbatim (bounded); without one the dialog
|
|
19
|
+
* says only what a restore always means and does not guess at the rest.
|
|
20
|
+
*/
|
|
21
|
+
export declare function restoreDialogCopy(label: string | undefined, consequence: string | undefined): {
|
|
22
|
+
title: string;
|
|
23
|
+
description: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Whether the Restore control exists, and whether it can be used. It exists only
|
|
27
|
+
* when the host passed a handler — a checkpoint that cannot be restored must not
|
|
28
|
+
* look as if it can — and goes once the restore has succeeded.
|
|
29
|
+
*/
|
|
30
|
+
export declare function restoreControl(hasHandler: boolean, state: CheckpointState, disabledReason: string | undefined): {
|
|
31
|
+
visible: boolean;
|
|
32
|
+
disabled: boolean;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=checkpoint-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-model.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/checkpoint/checkpoint-model.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAA;AAE1E,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,EACtB,KAAK,CAAC,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,GAAG,SAAS,CAapB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAOxC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,eAAe,EACtB,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAKzC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { boundText } from "../sources/source.js";
|
|
2
|
+
//#region src/components/composites/checkpoint/checkpoint-model.ts
|
|
3
|
+
/** The checkpoint's name as drawn; a blank label is the honest generic word. */
|
|
4
|
+
function checkpointLabel(label) {
|
|
5
|
+
return (label ? boundText(label, 80) : "") || "Checkpoint";
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The sentence for the status region. `idle` says nothing, because a
|
|
9
|
+
* checkpoint that has not been touched makes no statement. A failure carries the
|
|
10
|
+
* host's text when there is one.
|
|
11
|
+
*/
|
|
12
|
+
function checkpointStatus(state, error, disabledReason) {
|
|
13
|
+
switch (state) {
|
|
14
|
+
case "restoring": return "Restoring…";
|
|
15
|
+
case "restored": return "Restored";
|
|
16
|
+
case "failed": {
|
|
17
|
+
const detail = error ? boundText(error, 240) : "";
|
|
18
|
+
return detail ? `Restore failed: ${detail}` : "Restore failed";
|
|
19
|
+
}
|
|
20
|
+
case "idle": return disabledReason ? boundText(disabledReason, 240) : void 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The confirmation dialog's words. The host's `consequence` is what actually
|
|
25
|
+
* names what will change, so it is used verbatim (bounded); without one the dialog
|
|
26
|
+
* says only what a restore always means and does not guess at the rest.
|
|
27
|
+
*/
|
|
28
|
+
function restoreDialogCopy(label, consequence) {
|
|
29
|
+
return {
|
|
30
|
+
title: `Restore to “${checkpointLabel(label)}”?`,
|
|
31
|
+
description: consequence ? boundText(consequence, 400) : "Restoring returns to this checkpoint."
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Whether the Restore control exists, and whether it can be used. It exists only
|
|
36
|
+
* when the host passed a handler — a checkpoint that cannot be restored must not
|
|
37
|
+
* look as if it can — and goes once the restore has succeeded.
|
|
38
|
+
*/
|
|
39
|
+
function restoreControl(hasHandler, state, disabledReason) {
|
|
40
|
+
return {
|
|
41
|
+
visible: hasHandler && state !== "restored",
|
|
42
|
+
disabled: state === "restoring" || disabledReason !== void 0
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { checkpointLabel, checkpointStatus, restoreControl, restoreDialogCopy };
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=checkpoint-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-model.js","names":[],"sources":["../../../../src/components/composites/checkpoint/checkpoint-model.ts"],"sourcesContent":["import { boundText } from '../sources/source'\n\n/**\n * Where a restore stands. `idle` is the resting state of a checkpoint that has\n * not been restored from; the other three are only ever set because something\n * happened — the host passes them, or the component sets them from the promise\n * `onRestore` returned.\n */\nexport type CheckpointState = 'idle' | 'restoring' | 'restored' | 'failed'\n\n/** The checkpoint's name as drawn; a blank label is the honest generic word. */\nexport function checkpointLabel(label: string | undefined): string {\n return (label ? boundText(label, 80) : '') || 'Checkpoint'\n}\n\n/**\n * The sentence for the status region. `idle` says nothing, because a\n * checkpoint that has not been touched makes no statement. A failure carries the\n * host's text when there is one.\n */\nexport function checkpointStatus(\n state: CheckpointState,\n error?: string,\n disabledReason?: string\n): string | undefined {\n switch (state) {\n case 'restoring':\n return 'Restoring…'\n case 'restored':\n return 'Restored'\n case 'failed': {\n const detail = error ? boundText(error, 240) : ''\n return detail ? `Restore failed: ${detail}` : 'Restore failed'\n }\n case 'idle':\n return disabledReason ? boundText(disabledReason, 240) : undefined\n }\n}\n\n/**\n * The confirmation dialog's words. The host's `consequence` is what actually\n * names what will change, so it is used verbatim (bounded); without one the dialog\n * says only what a restore always means and does not guess at the rest.\n */\nexport function restoreDialogCopy(\n label: string | undefined,\n consequence: string | undefined\n): { title: string; description: string } {\n return {\n title: `Restore to “${checkpointLabel(label)}”?`,\n description: consequence\n ? boundText(consequence, 400)\n : 'Restoring returns to this checkpoint.',\n }\n}\n\n/**\n * Whether the Restore control exists, and whether it can be used. It exists only\n * when the host passed a handler — a checkpoint that cannot be restored must not\n * look as if it can — and goes once the restore has succeeded.\n */\nexport function restoreControl(\n hasHandler: boolean,\n state: CheckpointState,\n disabledReason: string | undefined\n): { visible: boolean; disabled: boolean } {\n return {\n visible: hasHandler && state !== 'restored',\n disabled: state === 'restoring' || disabledReason !== undefined,\n }\n}\n"],"mappings":";;;AAWA,SAAgB,gBAAgB,OAAmC;CACjE,QAAQ,QAAQ,UAAU,OAAO,EAAE,IAAI,OAAO;AAChD;;;;;;AAOA,SAAgB,iBACd,OACA,OACA,gBACoB;CACpB,QAAQ,OAAR;EACE,KAAK,aACH,OAAO;EACT,KAAK,YACH,OAAO;EACT,KAAK,UAAU;GACb,MAAM,SAAS,QAAQ,UAAU,OAAO,GAAG,IAAI;GAC/C,OAAO,SAAS,mBAAmB,WAAW;EAChD;EACA,KAAK,QACH,OAAO,iBAAiB,UAAU,gBAAgB,GAAG,IAAI,KAAA;CAC7D;AACF;;;;;;AAOA,SAAgB,kBACd,OACA,aACwC;CACxC,OAAO;EACL,OAAO,eAAe,gBAAgB,KAAK,EAAE;EAC7C,aAAa,cACT,UAAU,aAAa,GAAG,IAC1B;CACN;AACF;;;;;;AAOA,SAAgB,eACd,YACA,OACA,gBACyC;CACzC,OAAO;EACL,SAAS,cAAc,UAAU;EACjC,UAAU,UAAU,eAAe,mBAAmB,KAAA;CACxD;AACF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ComponentProps } from 'solid-js';
|
|
2
|
+
import { type CheckpointState } from './checkpoint-model';
|
|
3
|
+
/**
|
|
4
|
+
* Checkpoint.
|
|
5
|
+
*
|
|
6
|
+
* A point in the conversation the host can name: a divider in the transcript with
|
|
7
|
+
* a label and a time. It always renders — as a `Marker`, the quietest thing in the
|
|
8
|
+
* column — and it is honest about what it is:
|
|
9
|
+
*
|
|
10
|
+
* - **Without `onRestore` it is only a marker.** Not a disabled button, not a
|
|
11
|
+
* greyed-out "Restore": nothing. Whether a checkpoint can be returned to is a
|
|
12
|
+
* fact about the host's storage and permissions, and a control that implies it
|
|
13
|
+
* can would be a claim nobody made.
|
|
14
|
+
* - **With `onRestore` it offers Restore, and Restore asks first.** An
|
|
15
|
+
* `AlertDialog` (Escape and the scrim do nothing; every exit is a named choice)
|
|
16
|
+
* states what will change in the host's own words (`consequence`) before the
|
|
17
|
+
* handler is called. A restore throws work away; the confirmation is the point.
|
|
18
|
+
*
|
|
19
|
+
* ## States
|
|
20
|
+
*
|
|
21
|
+
* `idle` → `restoring` → `restored`, or `failed` with `error`. Pass `state` to
|
|
22
|
+
* drive it from the host; omit it and the component follows the promise
|
|
23
|
+
* `onRestore` returns. The status sentence is a live region that exists from the
|
|
24
|
+
* start, so a change is announced. While restoring, the control stays focusable
|
|
25
|
+
* (`aria-disabled`, not `disabled`) so focus is not dropped when the dialog hands
|
|
26
|
+
* it back; once restored the control goes and focus moves to the status line.
|
|
27
|
+
*
|
|
28
|
+
* A restore that cannot happen now takes `disabledReason`, shown in words under
|
|
29
|
+
* the divider; the host decides, the component explains.
|
|
30
|
+
*/
|
|
31
|
+
export type CheckpointProps = Omit<ComponentProps<'div'>, 'children' | 'onError'> & {
|
|
32
|
+
/** The checkpoint's name. Defaults to "Checkpoint". */
|
|
33
|
+
label?: string;
|
|
34
|
+
/** When it was taken, already formatted for the reader. */
|
|
35
|
+
time?: string;
|
|
36
|
+
state?: CheckpointState;
|
|
37
|
+
/** Supplying this is what makes the checkpoint restorable. */
|
|
38
|
+
onRestore?: () => void | Promise<void>;
|
|
39
|
+
/** What restoring will change, in the host's words. Shown in the confirmation. */
|
|
40
|
+
consequence?: string;
|
|
41
|
+
restoreLabel?: string;
|
|
42
|
+
/** Why Restore cannot be used right now. */
|
|
43
|
+
disabledReason?: string;
|
|
44
|
+
/** Why a restore failed. */
|
|
45
|
+
error?: string;
|
|
46
|
+
};
|
|
47
|
+
export declare function Checkpoint(props: CheckpointProps): import("solid-js").JSX.Element;
|
|
48
|
+
//# sourceMappingURL=checkpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/checkpoint/checkpoint.tsx"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AAkBjB,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAClF,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,kCAoIhD"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "../../ui/alert-dialog/alert-dialog.js";
|
|
3
|
+
import { Button } from "../../ui/button/button.js";
|
|
4
|
+
import { Spinner } from "../../ui/spinner/spinner.js";
|
|
5
|
+
import { Marker } from "../../ui/marker/marker.js";
|
|
6
|
+
import { boundText } from "../sources/source.js";
|
|
7
|
+
import { settleDecision } from "../confirmation/confirmation-model.js";
|
|
8
|
+
import { checkpointLabel, checkpointStatus, restoreControl, restoreDialogCopy } from "./checkpoint-model.js";
|
|
9
|
+
import { className, createComponent, effect, insert, memo, mergeProps, setAttribute, spread, template, use } from "solid-js/web";
|
|
10
|
+
import { Flag } from "lucide-solid";
|
|
11
|
+
import { Show, createEffect, createMemo, createSignal, createUniqueId, on, splitProps } from "solid-js";
|
|
12
|
+
//#region src/components/composites/checkpoint/checkpoint.tsx
|
|
13
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div data-slot=checkpoint><p role=status tabindex=-1>`);
|
|
14
|
+
function Checkpoint(props) {
|
|
15
|
+
const [local, rest] = splitProps(props, [
|
|
16
|
+
"class",
|
|
17
|
+
"label",
|
|
18
|
+
"time",
|
|
19
|
+
"state",
|
|
20
|
+
"onRestore",
|
|
21
|
+
"consequence",
|
|
22
|
+
"restoreLabel",
|
|
23
|
+
"disabledReason",
|
|
24
|
+
"error"
|
|
25
|
+
]);
|
|
26
|
+
const reasonId = `${createUniqueId()}-status`;
|
|
27
|
+
const [followed, setFollowed] = createSignal("idle");
|
|
28
|
+
const [failure, setFailure] = createSignal(void 0);
|
|
29
|
+
const [confirming, setConfirming] = createSignal(false);
|
|
30
|
+
let inflight = false;
|
|
31
|
+
let root;
|
|
32
|
+
let status;
|
|
33
|
+
const state = () => local.state ?? followed();
|
|
34
|
+
const error = () => local.error ?? failure();
|
|
35
|
+
const control = () => restoreControl(local.onRestore !== void 0, state(), local.disabledReason);
|
|
36
|
+
const copy = () => restoreDialogCopy(local.label, local.consequence);
|
|
37
|
+
const statusText = () => checkpointStatus(state(), error(), local.disabledReason);
|
|
38
|
+
const restore = async () => {
|
|
39
|
+
if (inflight || control().disabled) return;
|
|
40
|
+
inflight = true;
|
|
41
|
+
setFailure(void 0);
|
|
42
|
+
setFollowed("restoring");
|
|
43
|
+
const result = await settleDecision(local.onRestore);
|
|
44
|
+
inflight = false;
|
|
45
|
+
if (result.ok) setFollowed("restored");
|
|
46
|
+
else {
|
|
47
|
+
setFailure(result.message);
|
|
48
|
+
setFollowed("failed");
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
createEffect(on(() => state() === "restored", (restored) => {
|
|
52
|
+
if (!restored) return;
|
|
53
|
+
const active = document.activeElement;
|
|
54
|
+
if (active === null || active === document.body || root?.contains(active)) status?.focus();
|
|
55
|
+
}, { defer: true }));
|
|
56
|
+
const restoreAction = createMemo(() => createComponent(Show, {
|
|
57
|
+
get when() {
|
|
58
|
+
return control().visible;
|
|
59
|
+
},
|
|
60
|
+
get children() {
|
|
61
|
+
return createComponent(AlertDialog, {
|
|
62
|
+
get open() {
|
|
63
|
+
return confirming();
|
|
64
|
+
},
|
|
65
|
+
onOpenChange: (open) => setConfirming(open && !control().disabled),
|
|
66
|
+
get children() {
|
|
67
|
+
return [createComponent(AlertDialogTrigger, {
|
|
68
|
+
as: Button,
|
|
69
|
+
variant: "ghost",
|
|
70
|
+
size: "2xs",
|
|
71
|
+
get ["aria-disabled"]() {
|
|
72
|
+
return control().disabled || void 0;
|
|
73
|
+
},
|
|
74
|
+
get ["aria-describedby"]() {
|
|
75
|
+
return statusText() ? reasonId : void 0;
|
|
76
|
+
},
|
|
77
|
+
get children() {
|
|
78
|
+
return [createComponent(Show, {
|
|
79
|
+
get when() {
|
|
80
|
+
return state() === "restoring";
|
|
81
|
+
},
|
|
82
|
+
get children() {
|
|
83
|
+
return createComponent(Spinner, {
|
|
84
|
+
size: "xs",
|
|
85
|
+
label: false
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}), memo(() => memo(() => state() === "restoring")() ? "Restoring…" : local.restoreLabel ?? (state() === "failed" ? "Try again" : "Restore"))];
|
|
89
|
+
}
|
|
90
|
+
}), createComponent(AlertDialogContent, { get children() {
|
|
91
|
+
return [createComponent(AlertDialogHeader, { get children() {
|
|
92
|
+
return [createComponent(AlertDialogTitle, { get children() {
|
|
93
|
+
return copy().title;
|
|
94
|
+
} }), createComponent(AlertDialogDescription, {
|
|
95
|
+
"class": "[overflow-wrap:anywhere]",
|
|
96
|
+
get children() {
|
|
97
|
+
return copy().description;
|
|
98
|
+
}
|
|
99
|
+
})];
|
|
100
|
+
} }), createComponent(AlertDialogFooter, { get children() {
|
|
101
|
+
return [createComponent(AlertDialogCancel, {
|
|
102
|
+
as: Button,
|
|
103
|
+
variant: "ghost",
|
|
104
|
+
children: "Do not restore"
|
|
105
|
+
}), createComponent(AlertDialogAction, {
|
|
106
|
+
as: Button,
|
|
107
|
+
onClick: () => void restore(),
|
|
108
|
+
get children() {
|
|
109
|
+
return local.restoreLabel ?? "Restore";
|
|
110
|
+
}
|
|
111
|
+
})];
|
|
112
|
+
} })];
|
|
113
|
+
} })];
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}));
|
|
118
|
+
return (() => {
|
|
119
|
+
var _el$ = _tmpl$(), _el$2 = _el$.firstChild;
|
|
120
|
+
use((element) => root = element, _el$);
|
|
121
|
+
spread(_el$, mergeProps({
|
|
122
|
+
get ["data-state"]() {
|
|
123
|
+
return state();
|
|
124
|
+
},
|
|
125
|
+
get ["class"]() {
|
|
126
|
+
return local.class;
|
|
127
|
+
}
|
|
128
|
+
}, rest), false, true);
|
|
129
|
+
insert(_el$, createComponent(Marker, {
|
|
130
|
+
variant: "rule",
|
|
131
|
+
get icon() {
|
|
132
|
+
return createComponent(Flag, {});
|
|
133
|
+
},
|
|
134
|
+
get tone() {
|
|
135
|
+
return state() === "failed" ? "danger" : "neutral";
|
|
136
|
+
},
|
|
137
|
+
get label() {
|
|
138
|
+
return checkpointLabel(local.label);
|
|
139
|
+
},
|
|
140
|
+
get description() {
|
|
141
|
+
return memo(() => !!local.time)() ? boundText(local.time, 60) : void 0;
|
|
142
|
+
},
|
|
143
|
+
get action() {
|
|
144
|
+
return restoreAction();
|
|
145
|
+
}
|
|
146
|
+
}), _el$2);
|
|
147
|
+
use((element) => status = element, _el$2);
|
|
148
|
+
setAttribute(_el$2, "id", reasonId);
|
|
149
|
+
insert(_el$2, statusText);
|
|
150
|
+
effect(() => className(_el$2, cn("m-0 text-center text-xs outline-none [overflow-wrap:anywhere]", {
|
|
151
|
+
"text-destructive": state() === "failed",
|
|
152
|
+
"text-muted-foreground": state() !== "failed"
|
|
153
|
+
})));
|
|
154
|
+
return _el$;
|
|
155
|
+
})();
|
|
156
|
+
}
|
|
157
|
+
//#endregion
|
|
158
|
+
export { Checkpoint };
|
|
159
|
+
|
|
160
|
+
//# sourceMappingURL=checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.js","names":["Flag","createEffect","createMemo","createSignal","createUniqueId","on","Show","splitProps","ComponentProps","cn","Button","AlertDialog","AlertDialogAction","AlertDialogCancel","AlertDialogContent","AlertDialogDescription","AlertDialogFooter","AlertDialogHeader","AlertDialogTitle","AlertDialogTrigger","Marker","Spinner","settleDecision","boundText","checkpointLabel","checkpointStatus","restoreControl","restoreDialogCopy","CheckpointState","CheckpointProps","Omit","label","time","state","onRestore","Promise","consequence","restoreLabel","disabledReason","error","Checkpoint","props","local","rest","uid","reasonId","followed","setFollowed","failure","setFailure","undefined","confirming","setConfirming","inflight","root","HTMLDivElement","status","HTMLParagraphElement","control","copy","statusText","restore","disabled","result","ok","message","restored","active","document","activeElement","body","contains","focus","defer","restoreAction","_$createComponent","when","visible","children","open","onOpenChange","as","variant","size","aria-disabled","aria-describedby","_$memo","title","description","onClick","_el$","_tmpl$","_el$2","firstChild","_$use","element","_$spread","_$mergeProps","data-state","class","_$insert","icon","tone","action","_$setAttribute","_$effect","_$className","_$createComponent","_$memo","_$mergeProps","_$className"],"sources":["../../../../src/components/composites/checkpoint/checkpoint.tsx"],"sourcesContent":["import { Flag } from 'lucide-solid'\nimport {\n createEffect,\n createMemo,\n createSignal,\n createUniqueId,\n on,\n Show,\n splitProps,\n type ComponentProps,\n} from 'solid-js'\nimport { cn } from '#lib/utils'\nimport { Button } from '../../ui/button'\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from '../../ui/alert-dialog'\nimport { Marker } from '../../ui/marker'\nimport { Spinner } from '../../ui/spinner'\nimport { settleDecision } from '../confirmation/confirmation-model'\nimport { boundText } from '../sources/source'\nimport {\n checkpointLabel,\n checkpointStatus,\n restoreControl,\n restoreDialogCopy,\n type CheckpointState,\n} from './checkpoint-model'\n\n/**\n * Checkpoint.\n *\n * A point in the conversation the host can name: a divider in the transcript with\n * a label and a time. It always renders — as a `Marker`, the quietest thing in the\n * column — and it is honest about what it is:\n *\n * - **Without `onRestore` it is only a marker.** Not a disabled button, not a\n * greyed-out \"Restore\": nothing. Whether a checkpoint can be returned to is a\n * fact about the host's storage and permissions, and a control that implies it\n * can would be a claim nobody made.\n * - **With `onRestore` it offers Restore, and Restore asks first.** An\n * `AlertDialog` (Escape and the scrim do nothing; every exit is a named choice)\n * states what will change in the host's own words (`consequence`) before the\n * handler is called. A restore throws work away; the confirmation is the point.\n *\n * ## States\n *\n * `idle` → `restoring` → `restored`, or `failed` with `error`. Pass `state` to\n * drive it from the host; omit it and the component follows the promise\n * `onRestore` returns. The status sentence is a live region that exists from the\n * start, so a change is announced. While restoring, the control stays focusable\n * (`aria-disabled`, not `disabled`) so focus is not dropped when the dialog hands\n * it back; once restored the control goes and focus moves to the status line.\n *\n * A restore that cannot happen now takes `disabledReason`, shown in words under\n * the divider; the host decides, the component explains.\n */\nexport type CheckpointProps = Omit<ComponentProps<'div'>, 'children' | 'onError'> & {\n /** The checkpoint's name. Defaults to \"Checkpoint\". */\n label?: string\n /** When it was taken, already formatted for the reader. */\n time?: string\n state?: CheckpointState\n /** Supplying this is what makes the checkpoint restorable. */\n onRestore?: () => void | Promise<void>\n /** What restoring will change, in the host's words. Shown in the confirmation. */\n consequence?: string\n restoreLabel?: string\n /** Why Restore cannot be used right now. */\n disabledReason?: string\n /** Why a restore failed. */\n error?: string\n}\n\nexport function Checkpoint(props: CheckpointProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'label',\n 'time',\n 'state',\n 'onRestore',\n 'consequence',\n 'restoreLabel',\n 'disabledReason',\n 'error',\n ])\n const uid = createUniqueId()\n const reasonId = `${uid}-status`\n const [followed, setFollowed] = createSignal<CheckpointState>('idle')\n const [failure, setFailure] = createSignal<string | undefined>(undefined)\n const [confirming, setConfirming] = createSignal(false)\n let inflight = false\n let root: HTMLDivElement | undefined\n let status: HTMLParagraphElement | undefined\n\n const state = (): CheckpointState => local.state ?? followed()\n const error = () => local.error ?? failure()\n const control = () => restoreControl(local.onRestore !== undefined, state(), local.disabledReason)\n const copy = () => restoreDialogCopy(local.label, local.consequence)\n const statusText = () => checkpointStatus(state(), error(), local.disabledReason)\n\n const restore = async () => {\n if (inflight || control().disabled) return\n inflight = true\n setFailure(undefined)\n setFollowed('restoring')\n const result = await settleDecision(local.onRestore)\n inflight = false\n if (result.ok) {\n setFollowed('restored')\n } else {\n setFailure(result.message)\n setFollowed('failed')\n }\n }\n\n // The control is replaced by the status line on success; do not strand focus.\n createEffect(\n on(\n () => state() === 'restored',\n (restored) => {\n if (!restored) return\n const active = document.activeElement\n if (active === null || active === document.body || root?.contains(active)) {\n status?.focus()\n }\n },\n { defer: true }\n )\n )\n\n // Built once. `Marker` reads `action` twice (to test it, then to draw it), and a\n // JSX prop re-creates its component on every read: a second AlertDialog root\n // would portal a second, invisible-to-the-tree dialog when this one opens.\n const restoreAction = createMemo(() => (\n <Show when={control().visible}>\n <AlertDialog\n open={confirming()}\n onOpenChange={(open) => setConfirming(open && !control().disabled)}\n >\n <AlertDialogTrigger\n as={Button}\n variant=\"ghost\"\n size=\"2xs\"\n aria-disabled={control().disabled || undefined}\n aria-describedby={statusText() ? reasonId : undefined}\n >\n <Show when={state() === 'restoring'}>\n <Spinner size=\"xs\" label={false} />\n </Show>\n {state() === 'restoring'\n ? 'Restoring…'\n : (local.restoreLabel ?? (state() === 'failed' ? 'Try again' : 'Restore'))}\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{copy().title}</AlertDialogTitle>\n <AlertDialogDescription class=\"[overflow-wrap:anywhere]\">\n {copy().description}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel as={Button} variant=\"ghost\">\n Do not restore\n </AlertDialogCancel>\n <AlertDialogAction as={Button} onClick={() => void restore()}>\n {local.restoreLabel ?? 'Restore'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </Show>\n ))\n\n return (\n <div\n ref={(element) => (root = element)}\n data-slot=\"checkpoint\"\n data-state={state()}\n class={local.class}\n {...rest}\n >\n <Marker\n variant=\"rule\"\n icon={<Flag />}\n tone={state() === 'failed' ? 'danger' : 'neutral'}\n label={checkpointLabel(local.label)}\n description={local.time ? boundText(local.time, 60) : undefined}\n action={restoreAction()}\n />\n {/* Always present, so a state change is a change to a live region rather than\n the arrival of one. Empty while idle, which takes no space. */}\n <p\n id={reasonId}\n ref={(element) => (status = element)}\n role=\"status\"\n tabindex=\"-1\"\n class={cn('m-0 text-center text-xs outline-none [overflow-wrap:anywhere]', {\n 'text-destructive': state() === 'failed',\n 'text-muted-foreground': state() !== 'failed',\n })}\n >\n {statusText()}\n </p>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;AAiFA,SAAgBwC,WAAWC,OAAwB;CACjD,MAAM,CAACC,OAAOC,QAAQpC,WAAWkC,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAAO,CACR;CAED,MAAMI,WAAW,GADLzC,eACQwC,EAAG;CACvB,MAAM,CAACE,UAAUC,eAAe5C,aAA8B,MAAM;CACpE,MAAM,CAAC6C,SAASC,cAAc9C,aAAiC+C,KAAAA,CAAS;CACxE,MAAM,CAACC,YAAYC,iBAAiBjD,aAAa,KAAK;CACtD,IAAIkD,WAAW;CACf,IAAIC;CACJ,IAAIE;CAEJ,MAAMvB,cAA+BS,MAAMT,SAASa,SAAS;CAC7D,MAAMP,cAAcG,MAAMH,SAASS,QAAQ;CAC3C,MAAMU,gBAAgBhC,eAAegB,MAAMR,cAAcgB,KAAAA,GAAWjB,MAAM,GAAGS,MAAMJ,cAAc;CACjG,MAAMqB,aAAahC,kBAAkBe,MAAMX,OAAOW,MAAMN,WAAW;CACnE,MAAMwB,mBAAmBnC,iBAAiBQ,MAAM,GAAGM,MAAM,GAAGG,MAAMJ,cAAc;CAEhF,MAAMuB,UAAU,YAAY;EAC1B,IAAIR,YAAYK,QAAQ,CAAC,CAACI,UAAU;EACpCT,WAAW;EACXJ,WAAWC,KAAAA,CAAS;EACpBH,YAAY,WAAW;EACvB,MAAMgB,SAAS,MAAMzC,eAAeoB,MAAMR,SAAS;EACnDmB,WAAW;EACX,IAAIU,OAAOC,IACTjB,YAAY,UAAU;OACjB;GACLE,WAAWc,OAAOE,OAAO;GACzBlB,YAAY,QAAQ;EACtB;CACF;CAGA9C,aACEI,SACQ4B,MAAM,MAAM,aACjBiC,aAAa;EACZ,IAAI,CAACA,UAAU;EACf,MAAMC,SAASC,SAASC;EACxB,IAAIF,WAAW,QAAQA,WAAWC,SAASE,QAAQhB,MAAMiB,SAASJ,MAAM,GACtEX,QAAQgB,MAAM;CAElB,GACA,EAAEC,OAAO,KAAK,CAChB,CACF;CAKA,MAAMC,gBAAgBxE,iBAAWyE,gBAC9BrE,MAAI;EAAA,IAACsE,OAAI;GAAA,OAAElB,QAAQ,CAAC,CAACmB;EAAO;EAAA,IAAAC,WAAA;GAAA,OAAAH,gBAC1BhE,aAAW;IAAA,IACVoE,OAAI;KAAA,OAAE5B,WAAW;IAAC;IAClB6B,eAAeD,SAAS3B,cAAc2B,QAAQ,CAACrB,QAAQ,CAAC,CAACI,QAAQ;IAAC,IAAAgB,WAAA;KAAA,OAAA,CAAAH,gBAEjExD,oBAAkB;MACjB8D,IAAIvE;MACJwE,SAAO;MACPC,MAAI;MAAA,KAAA,mBAAA;OAAA,OACWzB,QAAQ,CAAC,CAACI,YAAYZ,KAAAA;MAAS;MAAA,KAAA,sBAAA;OAAA,OAC5BU,WAAW,IAAIf,WAAWK,KAAAA;MAAS;MAAA,IAAA4B,WAAA;OAAA,OAAA,CAAAH,gBAEpDrE,MAAI;QAAA,IAACsE,OAAI;SAAA,OAAE3C,MAAM,MAAM;QAAW;QAAA,IAAA6C,WAAA;SAAA,OAAAH,gBAChCtD,SAAO;UAAC8D,MAAI;UAAMpD,OAAO;SAAK,CAAA;QAAA;OAAA,CAAA,GAAAuD,WAEhCA,WAAArD,MAAM,MAAM,WAAW,CAAA,CAAA,IACpB,eACCS,MAAML,iBAAiBJ,MAAM,MAAM,WAAW,cAAc,UAAW,CAAA;MAAA;KAAA,CAAA,GAAA0C,gBAE7E7D,oBAAkB,EAAA,IAAAgE,WAAA;MAAA,OAAA,CAAAH,gBAChB1D,mBAAiB,EAAA,IAAA6D,WAAA;OAAA,OAAA,CAAAH,gBACfzD,kBAAgB,EAAA,IAAA4D,WAAA;QAAA,OAAEnB,KAAK,CAAC,CAAC4B;OAAK,EAAA,CAAA,GAAAZ,gBAC9B5D,wBAAsB;QAAA,SAAA;QAAA,IAAA+D,WAAA;SAAA,OACpBnB,KAAK,CAAC,CAAC6B;QAAW;OAAA,CAAA,CAAA;MAAA,EAAA,CAAA,GAAAb,gBAGtB3D,mBAAiB,EAAA,IAAA8D,WAAA;OAAA,OAAA,CAAAH,gBACf9D,mBAAiB;QAACoE,IAAIvE;QAAQwE,SAAO;QAAAJ,UAAA;OAAA,CAAA,GAAAH,gBAGrC/D,mBAAiB;QAACqE,IAAIvE;QAAQ+E,eAAe,KAAK5B,QAAQ;QAAC,IAAAiB,WAAA;SAAA,OACzDpC,MAAML,gBAAgB;QAAS;OAAA,CAAA,CAAA;MAAA,EAAA,CAAA,CAAA;KAAA,EAAA,CAAA,CAAA;IAAA;GAAA,CAAA;EAAA;CAAA,CAAA,CAM3C;CAED,cAAA;EAAA,IAAAqD,OAAAC,OAAA,GAAAC,QAAAF,KAAAG;EAAAC,KAEUC,YAAazC,OAAOyC,SAAQL,IAAA;EAAAM,OAAAN,MAAAO,WAAA;GAAA,KAAA,gBAAA;IAAA,OAEtBhE,MAAM;GAAC;GAAA,KAAA,WAAA;IAAA,OACZS,MAAMyD;GAAK;EAAA,GACdxD,IAAI,GAAA,OAAA,IAAA;EAAAyD,OAAAV,MAAAf,gBAEPvD,QAAM;GACL8D,SAAO;GAAA,IACPmB,OAAI;IAAA,OAAA1B,gBAAG3E,MAAI,CAAA,CAAA;GAAA;GAAA,IACXsG,OAAI;IAAA,OAAErE,MAAM,MAAM,WAAW,WAAW;GAAS;GAAA,IACjDF,QAAK;IAAA,OAAEP,gBAAgBkB,MAAMX,KAAK;GAAC;GAAA,IACnCyD,cAAW;IAAA,OAAEF,WAAA,CAAA,CAAA5C,MAAMV,IAAI,CAAA,CAAA,IAAGT,UAAUmB,MAAMV,MAAM,EAAE,IAAIkB,KAAAA;GAAS;GAAA,IAC/DqD,SAAM;IAAA,OAAE7B,cAAc;GAAC;EAAA,CAAA,GAAAkB,KAAA;EAAAE,KAMjBC,YAAavC,SAASuC,SAAQH,KAAA;EAAAY,aAAAZ,OAAA,MADhC/C,QAAQ;EAAAuD,OAAAR,OASXhC,UAAU;EAAA6C,aAAAC,UAAAd,OALJnF,GAAG,iEAAiE;GACzE,oBAAoBwB,MAAM,MAAM;GAChC,yBAAyBA,MAAM,MAAM;EACvC,CAAC,CAAC,CAAA;EAAA,OAAAyD;CAAA,EAAA,CAAA;AAMV"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/checkpoint/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a request for approval stands.
|
|
3
|
+
*
|
|
4
|
+
* - `requested`: waiting on the reader. The only state with live buttons.
|
|
5
|
+
* - `approved` / `denied`: settled; the record of the answer.
|
|
6
|
+
* - `expired`: nobody can answer it any more (the run moved on, a timeout).
|
|
7
|
+
* - `unavailable`: it is still open, but this client cannot answer it right now
|
|
8
|
+
* (offline, no authority, another client holds it). The buttons stay visible and
|
|
9
|
+
* disabled so the reader can see what was asked and why they cannot answer.
|
|
10
|
+
*/
|
|
11
|
+
export type ConfirmationState = 'requested' | 'approved' | 'denied' | 'expired' | 'unavailable';
|
|
12
|
+
/** Whether the choice is still open, which is exactly when the buttons are drawn. */
|
|
13
|
+
export declare function isAwaitingAnswer(state: ConfirmationState): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The one line that replaces the buttons once the request settles. Who and when
|
|
16
|
+
* appear only if the host supplied them: "Approved" is a fact the state gives,
|
|
17
|
+
* "by Ana" is a fact only the host knows.
|
|
18
|
+
*/
|
|
19
|
+
export declare function confirmationOutcome(state: ConfirmationState, by?: string, at?: string): string | undefined;
|
|
20
|
+
export type DecisionResult = {
|
|
21
|
+
ok: true;
|
|
22
|
+
} | {
|
|
23
|
+
ok: false;
|
|
24
|
+
message: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Run a host handler that may be synchronous, asynchronous, or throw, and report
|
|
28
|
+
* the outcome as data. A rejection's own message is shown (bounded) because the
|
|
29
|
+
* host usually knows why; a non-Error rejection gets a plain sentence instead of
|
|
30
|
+
* "[object Object]".
|
|
31
|
+
*/
|
|
32
|
+
export declare function settleDecision(handler: (() => void | Promise<void>) | undefined): Promise<DecisionResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Why a choice is not available, in words. A host `disabledReason` outranks the
|
|
35
|
+
* built-in sentence for a missing handler, and a request that is `unavailable`
|
|
36
|
+
* without a reason still says so rather than showing dead buttons.
|
|
37
|
+
*/
|
|
38
|
+
export declare function decisionReason(options: {
|
|
39
|
+
state: ConfirmationState;
|
|
40
|
+
disabledReason?: string;
|
|
41
|
+
hasHandler: boolean;
|
|
42
|
+
unavailableFallback: string;
|
|
43
|
+
missingFallback: string;
|
|
44
|
+
}): string | undefined;
|
|
45
|
+
//# sourceMappingURL=confirmation-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmation-model.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/confirmation/confirmation-model.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAA;AAE/F,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAElE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,iBAAiB,EACxB,EAAE,CAAC,EAAE,MAAM,EACX,EAAE,CAAC,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAapB;AAED,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAI1E;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,GAChD,OAAO,CAAC,cAAc,CAAC,CAQzB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,KAAK,EAAE,iBAAiB,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,OAAO,CAAA;IACnB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,eAAe,EAAE,MAAM,CAAA;CACxB,GAAG,MAAM,GAAG,SAAS,CAMrB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { boundText } from "../sources/source.js";
|
|
2
|
+
//#region src/components/composites/confirmation/confirmation-model.ts
|
|
3
|
+
/** Whether the choice is still open, which is exactly when the buttons are drawn. */
|
|
4
|
+
function isAwaitingAnswer(state) {
|
|
5
|
+
return state === "requested" || state === "unavailable";
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The one line that replaces the buttons once the request settles. Who and when
|
|
9
|
+
* appear only if the host supplied them: "Approved" is a fact the state gives,
|
|
10
|
+
* "by Ana" is a fact only the host knows.
|
|
11
|
+
*/
|
|
12
|
+
function confirmationOutcome(state, by, at) {
|
|
13
|
+
const base = state === "approved" ? "Approved" : state === "denied" ? "Denied" : state === "expired" ? "Expired without an answer" : void 0;
|
|
14
|
+
if (base === void 0) return void 0;
|
|
15
|
+
const who = by ? boundText(by, 60) : "";
|
|
16
|
+
const when = at ? boundText(at, 40) : "";
|
|
17
|
+
return `${base}${who ? ` by ${who}` : ""}${when ? ` at ${when}` : ""}`;
|
|
18
|
+
}
|
|
19
|
+
var DEFAULT_FAILURE = "Your answer could not be sent. Try again.";
|
|
20
|
+
/**
|
|
21
|
+
* Run a host handler that may be synchronous, asynchronous, or throw, and report
|
|
22
|
+
* the outcome as data. A rejection's own message is shown (bounded) because the
|
|
23
|
+
* host usually knows why; a non-Error rejection gets a plain sentence instead of
|
|
24
|
+
* "[object Object]".
|
|
25
|
+
*/
|
|
26
|
+
async function settleDecision(handler) {
|
|
27
|
+
try {
|
|
28
|
+
await handler?.();
|
|
29
|
+
return { ok: true };
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return {
|
|
32
|
+
ok: false,
|
|
33
|
+
message: (error instanceof Error ? boundText(error.message, 200) : "") || DEFAULT_FAILURE
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Why a choice is not available, in words. A host `disabledReason` outranks the
|
|
39
|
+
* built-in sentence for a missing handler, and a request that is `unavailable`
|
|
40
|
+
* without a reason still says so rather than showing dead buttons.
|
|
41
|
+
*/
|
|
42
|
+
function decisionReason(options) {
|
|
43
|
+
const hostReason = options.disabledReason ? boundText(options.disabledReason, 240) : "";
|
|
44
|
+
if (hostReason) return hostReason;
|
|
45
|
+
if (options.state === "unavailable") return options.unavailableFallback;
|
|
46
|
+
if (!options.hasHandler) return options.missingFallback;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { confirmationOutcome, decisionReason, isAwaitingAnswer, settleDecision };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=confirmation-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmation-model.js","names":[],"sources":["../../../../src/components/composites/confirmation/confirmation-model.ts"],"sourcesContent":["import { boundText } from '../sources/source'\n\n/**\n * Where a request for approval stands.\n *\n * - `requested`: waiting on the reader. The only state with live buttons.\n * - `approved` / `denied`: settled; the record of the answer.\n * - `expired`: nobody can answer it any more (the run moved on, a timeout).\n * - `unavailable`: it is still open, but this client cannot answer it right now\n * (offline, no authority, another client holds it). The buttons stay visible and\n * disabled so the reader can see what was asked and why they cannot answer.\n */\nexport type ConfirmationState = 'requested' | 'approved' | 'denied' | 'expired' | 'unavailable'\n\n/** Whether the choice is still open, which is exactly when the buttons are drawn. */\nexport function isAwaitingAnswer(state: ConfirmationState): boolean {\n return state === 'requested' || state === 'unavailable'\n}\n\n/**\n * The one line that replaces the buttons once the request settles. Who and when\n * appear only if the host supplied them: \"Approved\" is a fact the state gives,\n * \"by Ana\" is a fact only the host knows.\n */\nexport function confirmationOutcome(\n state: ConfirmationState,\n by?: string,\n at?: string\n): string | undefined {\n const base =\n state === 'approved'\n ? 'Approved'\n : state === 'denied'\n ? 'Denied'\n : state === 'expired'\n ? 'Expired without an answer'\n : undefined\n if (base === undefined) return undefined\n const who = by ? boundText(by, 60) : ''\n const when = at ? boundText(at, 40) : ''\n return `${base}${who ? ` by ${who}` : ''}${when ? ` at ${when}` : ''}`\n}\n\nexport type DecisionResult = { ok: true } | { ok: false; message: string }\n\nconst DEFAULT_FAILURE = 'Your answer could not be sent. Try again.'\n\n/**\n * Run a host handler that may be synchronous, asynchronous, or throw, and report\n * the outcome as data. A rejection's own message is shown (bounded) because the\n * host usually knows why; a non-Error rejection gets a plain sentence instead of\n * \"[object Object]\".\n */\nexport async function settleDecision(\n handler: (() => void | Promise<void>) | undefined\n): Promise<DecisionResult> {\n try {\n await handler?.()\n return { ok: true }\n } catch (error) {\n const message = error instanceof Error ? boundText(error.message, 200) : ''\n return { ok: false, message: message || DEFAULT_FAILURE }\n }\n}\n\n/**\n * Why a choice is not available, in words. A host `disabledReason` outranks the\n * built-in sentence for a missing handler, and a request that is `unavailable`\n * without a reason still says so rather than showing dead buttons.\n */\nexport function decisionReason(options: {\n state: ConfirmationState\n disabledReason?: string\n hasHandler: boolean\n unavailableFallback: string\n missingFallback: string\n}): string | undefined {\n const hostReason = options.disabledReason ? boundText(options.disabledReason, 240) : ''\n if (hostReason) return hostReason\n if (options.state === 'unavailable') return options.unavailableFallback\n if (!options.hasHandler) return options.missingFallback\n return undefined\n}\n"],"mappings":";;;AAeA,SAAgB,iBAAiB,OAAmC;CAClE,OAAO,UAAU,eAAe,UAAU;AAC5C;;;;;;AAOA,SAAgB,oBACd,OACA,IACA,IACoB;CACpB,MAAM,OACJ,UAAU,aACN,aACA,UAAU,WACR,WACA,UAAU,YACR,8BACA,KAAA;CACV,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,MAAM,MAAM,KAAK,UAAU,IAAI,EAAE,IAAI;CACrC,MAAM,OAAO,KAAK,UAAU,IAAI,EAAE,IAAI;CACtC,OAAO,GAAG,OAAO,MAAM,OAAO,QAAQ,KAAK,OAAO,OAAO,SAAS;AACpE;AAIA,IAAM,kBAAkB;;;;;;;AAQxB,eAAsB,eACpB,SACyB;CACzB,IAAI;EACF,MAAM,UAAU;EAChB,OAAO,EAAE,IAAI,KAAK;CACpB,SAAS,OAAO;EAEd,OAAO;GAAE,IAAI;GAAO,UADJ,iBAAiB,QAAQ,UAAU,MAAM,SAAS,GAAG,IAAI,OACjC;EAAgB;CAC1D;AACF;;;;;;AAOA,SAAgB,eAAe,SAMR;CACrB,MAAM,aAAa,QAAQ,iBAAiB,UAAU,QAAQ,gBAAgB,GAAG,IAAI;CACrF,IAAI,YAAY,OAAO;CACvB,IAAI,QAAQ,UAAU,eAAe,OAAO,QAAQ;CACpD,IAAI,CAAC,QAAQ,YAAY,OAAO,QAAQ;AAE1C"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type ComponentProps, type JSX } from 'solid-js';
|
|
2
|
+
import { type ConfirmationState } from './confirmation-model';
|
|
3
|
+
/**
|
|
4
|
+
* Confirmation.
|
|
5
|
+
*
|
|
6
|
+
* The agent has stopped a tool and will not continue until the person approves or
|
|
7
|
+
* denies it. Like `Questionnaire`, this is one of the two elements in a transcript
|
|
8
|
+
* the reader *must* act on, so it is allowed a card surface — and the border is
|
|
9
|
+
* the focus ring's colour only while it is waiting. Once answered it drops to a
|
|
10
|
+
* hairline and a one-line record, because a settled decision should read as
|
|
11
|
+
* history, not as something still asking.
|
|
12
|
+
*
|
|
13
|
+
* ## It shows what is being approved, and nothing else
|
|
14
|
+
*
|
|
15
|
+
* `title` and `description` say what the tool wants to do; `details` is the
|
|
16
|
+
* evidence, rendered as `CodeBlock size="sm"` (a command, a request) or
|
|
17
|
+
* `DiffBlock` (a patch). Details are text: never interpreted, and a long one
|
|
18
|
+
* scrolls inside its block. Approve and Deny exist only while the request is
|
|
19
|
+
* open; afterwards they are replaced by the outcome, with *who* and *when* only if
|
|
20
|
+
* the host supplied them.
|
|
21
|
+
*
|
|
22
|
+
* ## The host owns authority
|
|
23
|
+
*
|
|
24
|
+
* Whether this client may answer is not decided here. No handler, or a host
|
|
25
|
+
* `disabledReason`, or the `unavailable` state, leaves the buttons visible and
|
|
26
|
+
* disabled with the reason beside them in words — never hidden, because a reader
|
|
27
|
+
* who cannot see the choice cannot tell whether the agent is waiting on them.
|
|
28
|
+
*
|
|
29
|
+
* ## Answering is a round trip
|
|
30
|
+
*
|
|
31
|
+
* `onApprove` / `onDeny` may return a promise. While one is pending both buttons
|
|
32
|
+
* refuse input (a synchronous guard as well as the signal, so a double click in
|
|
33
|
+
* one tick cannot submit twice) and the pressed one shows a spinner. A failure
|
|
34
|
+
* shows `error` (or the rejection's own message) and re-enables the buttons. The
|
|
35
|
+
* buttons use `aria-disabled` rather than `disabled`: a native disabled button
|
|
36
|
+
* drops focus, and the reader's place would be lost mid-decision. When the state
|
|
37
|
+
* settles, focus moves to the outcome line if it was in the card, so a keyboard
|
|
38
|
+
* user is not stranded on a control that no longer exists.
|
|
39
|
+
*/
|
|
40
|
+
export type ConfirmationDetails = Readonly<{
|
|
41
|
+
kind: 'code';
|
|
42
|
+
code: string;
|
|
43
|
+
language?: string;
|
|
44
|
+
title?: string;
|
|
45
|
+
}> | Readonly<{
|
|
46
|
+
kind: 'diff';
|
|
47
|
+
patch: string;
|
|
48
|
+
title?: string;
|
|
49
|
+
}>;
|
|
50
|
+
export type ConfirmationProps = Omit<ComponentProps<'section'>, 'title' | 'onError'> & {
|
|
51
|
+
state?: ConfirmationState;
|
|
52
|
+
/** What the tool wants to do, as a short sentence. */
|
|
53
|
+
title: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
details?: ConfirmationDetails;
|
|
56
|
+
onApprove?: () => void | Promise<void>;
|
|
57
|
+
onDeny?: () => void | Promise<void>;
|
|
58
|
+
approveLabel?: string;
|
|
59
|
+
denyLabel?: string;
|
|
60
|
+
/** Why the choice cannot be made right now; shown in words beside the buttons. */
|
|
61
|
+
disabledReason?: string;
|
|
62
|
+
/** A failed answer, in words. Overrides the rejection's own message. */
|
|
63
|
+
error?: string;
|
|
64
|
+
/** Who answered, once settled. Omit if unknown; nothing is assumed. */
|
|
65
|
+
resolvedBy?: string;
|
|
66
|
+
/** When it was answered, already formatted for the reader. Omit if unknown. */
|
|
67
|
+
resolvedAt?: string;
|
|
68
|
+
/** Extra content between the details and the buttons. */
|
|
69
|
+
children?: JSX.Element;
|
|
70
|
+
};
|
|
71
|
+
export declare function Confirmation(props: ConfirmationProps): JSX.Element;
|
|
72
|
+
//# sourceMappingURL=confirmation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmation.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/confirmation/confirmation.tsx"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,GAAG,EACT,MAAM,UAAU,CAAA;AAOjB,OAAO,EAKL,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAA;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,MAAM,mBAAmB,GAC3B,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC3E,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAE7D,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC,GAAG;IACrF,KAAK,CAAC,EAAE,iBAAiB,CAAA;IACzB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB,CAAA;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,eAiLpD"}
|