@cueplusplus/ui 0.3.0 → 0.6.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/CHANGELOG.md +2263 -0
- package/dist/agent-runtime/_glyphs.js +43 -0
- package/dist/agent-runtime/branch-picker.d.ts +45 -0
- package/dist/agent-runtime/branch-picker.js +87 -0
- package/dist/agent-runtime/index.d.ts +4 -0
- package/dist/agent-runtime/index.js +4 -0
- package/dist/agent-runtime/tool-call-card.d.ts +69 -0
- package/dist/agent-runtime/tool-call-card.js +187 -0
- package/dist/agent-runtime/use-agent-thread.d.ts +164 -0
- package/dist/agent-runtime/use-agent-thread.js +251 -0
- package/dist/chat/index.d.ts +2 -2
- package/dist/chat/message-list.d.ts +6 -0
- package/dist/chat/message-list.js +35 -0
- package/dist/chrome/_drag.js +59 -0
- package/dist/chrome/_status-bar-item.js +85 -0
- package/dist/chrome/_status-bar.d.ts +15 -0
- package/dist/chrome/_status-bar.js +171 -0
- package/dist/chrome/app-shell.d.ts +120 -2
- package/dist/chrome/app-shell.js +107 -8
- package/dist/chrome/index.d.ts +4 -3
- package/dist/chrome/status-bar.d.ts +87 -4
- package/dist/chrome/status-bar.js +80 -16
- package/dist/chrome/title-bar.d.ts +11 -1
- package/dist/chrome/title-bar.js +1 -3
- package/dist/configurator/_export.js +3 -2
- package/dist/configurator/_overrides.d.ts +1 -1
- package/dist/configurator/token-editor.js +4 -1
- package/dist/date/_segments.js +52 -6
- package/dist/elements/activity-graph.d.ts +40 -0
- package/dist/elements/activity-graph.js +81 -0
- package/dist/elements/agent-card.d.ts +49 -0
- package/dist/elements/agent-card.js +91 -0
- package/dist/elements/agent-handoff.d.ts +24 -0
- package/dist/elements/agent-handoff.js +53 -0
- package/dist/elements/agent-mode-badge.d.ts +72 -0
- package/dist/elements/agent-mode-badge.js +110 -0
- package/dist/elements/agent-plan.d.ts +24 -0
- package/dist/elements/agent-plan.js +74 -0
- package/dist/elements/agent-status.d.ts +29 -0
- package/dist/elements/agent-status.js +46 -0
- package/dist/elements/agent-surface.d.ts +65 -0
- package/dist/elements/agent-surface.js +68 -0
- package/dist/elements/animated-number.d.ts +86 -0
- package/dist/elements/animated-number.js +118 -0
- package/dist/elements/approval-card.d.ts +40 -0
- package/dist/elements/approval-card.js +78 -0
- package/dist/elements/artifact-card.d.ts +30 -0
- package/dist/elements/artifact-card.js +58 -0
- package/dist/elements/background-inbox.d.ts +39 -0
- package/dist/elements/background-inbox.js +60 -0
- package/dist/elements/canvas-split.d.ts +77 -0
- package/dist/elements/canvas-split.js +138 -0
- package/dist/elements/chart.d.ts +41 -0
- package/dist/elements/chart.js +117 -0
- package/dist/elements/chat-panel.d.ts +46 -0
- package/dist/elements/chat-panel.js +104 -0
- package/dist/elements/checkpoint-history.d.ts +31 -0
- package/dist/elements/checkpoint-history.js +65 -0
- package/dist/elements/clamp.d.ts +90 -0
- package/dist/elements/clamp.js +109 -0
- package/dist/elements/code-diff.d.ts +42 -0
- package/dist/elements/code-diff.js +69 -0
- package/dist/elements/code-runner.d.ts +38 -0
- package/dist/elements/code-runner.js +84 -0
- package/dist/elements/command-palette.d.ts +48 -0
- package/dist/elements/command-palette.js +129 -0
- package/dist/elements/compaction-row.d.ts +63 -0
- package/dist/elements/compaction-row.js +110 -0
- package/dist/elements/comparison-card.d.ts +47 -0
- package/dist/elements/comparison-card.js +69 -0
- package/dist/elements/composer.d.ts +274 -0
- package/dist/elements/composer.js +505 -0
- package/dist/elements/computer-use.d.ts +40 -0
- package/dist/elements/computer-use.js +92 -0
- package/dist/elements/confidence-marker.d.ts +39 -0
- package/dist/elements/confidence-marker.js +64 -0
- package/dist/elements/connection-state.d.ts +29 -0
- package/dist/elements/connection-state.js +66 -0
- package/dist/elements/context-breakdown.d.ts +30 -0
- package/dist/elements/context-breakdown.js +86 -0
- package/dist/elements/context-usage.d.ts +99 -0
- package/dist/elements/context-usage.js +225 -0
- package/dist/elements/conversation-search.d.ts +48 -0
- package/dist/elements/conversation-search.js +88 -0
- package/dist/elements/cost-meter.d.ts +33 -0
- package/dist/elements/cost-meter.js +75 -0
- package/dist/elements/data-table.d.ts +31 -0
- package/dist/elements/data-table.js +67 -0
- package/dist/elements/day-separator.d.ts +34 -0
- package/dist/elements/day-separator.js +50 -0
- package/dist/elements/diagram.d.ts +34 -0
- package/dist/elements/diagram.js +75 -0
- package/dist/elements/document-reference.d.ts +37 -0
- package/dist/elements/document-reference.js +66 -0
- package/dist/elements/draft-restore.d.ts +27 -0
- package/dist/elements/draft-restore.js +54 -0
- package/dist/elements/edit-message.d.ts +36 -0
- package/dist/elements/edit-message.js +77 -0
- package/dist/elements/elements.css +459 -0
- package/dist/elements/elicitation-form.d.ts +48 -0
- package/dist/elements/elicitation-form.js +106 -0
- package/dist/elements/empty-state.d.ts +52 -0
- package/dist/elements/empty-state.js +98 -0
- package/dist/elements/end-of-turn-summary.d.ts +60 -0
- package/dist/elements/end-of-turn-summary.js +75 -0
- package/dist/elements/error-state.d.ts +29 -0
- package/dist/elements/error-state.js +55 -0
- package/dist/elements/feedback-dialog.d.ts +36 -0
- package/dist/elements/feedback-dialog.js +81 -0
- package/dist/elements/file-tree.d.ts +45 -0
- package/dist/elements/file-tree.js +84 -0
- package/dist/elements/flow-graph.d.ts +45 -0
- package/dist/elements/flow-graph.js +78 -0
- package/dist/elements/generative/chart.js +200 -0
- package/dist/elements/generative/faults.js +111 -0
- package/dist/elements/generative/icons.d.ts +41 -0
- package/dist/elements/generative/icons.js +190 -0
- package/dist/elements/generative/intrinsics.js +483 -0
- package/dist/elements/generative/spec.d.ts +110 -0
- package/dist/elements/generative/spec.js +366 -0
- package/dist/elements/generative.css +1145 -0
- package/dist/elements/generative.d.ts +144 -0
- package/dist/elements/generative.js +126 -0
- package/dist/elements/guardrail-notice.d.ts +29 -0
- package/dist/elements/guardrail-notice.js +63 -0
- package/dist/elements/image-generation.d.ts +18 -0
- package/dist/elements/image-generation.js +64 -0
- package/dist/elements/index.d.ts +116 -0
- package/dist/elements/index.js +115 -0
- package/dist/elements/inline-citation.d.ts +43 -0
- package/dist/elements/inline-citation.js +93 -0
- package/dist/elements/job-progress.d.ts +49 -0
- package/dist/elements/job-progress.js +74 -0
- package/dist/elements/launcher-bubble.d.ts +34 -0
- package/dist/elements/launcher-bubble.js +72 -0
- package/dist/elements/live-region-announcer.d.ts +130 -0
- package/dist/elements/live-region-announcer.js +230 -0
- package/dist/elements/loading-state.d.ts +27 -0
- package/dist/elements/loading-state.js +36 -0
- package/dist/elements/map-answer.d.ts +38 -0
- package/dist/elements/map-answer.js +93 -0
- package/dist/elements/markdown.d.ts +131 -0
- package/dist/elements/markdown.js +528 -0
- package/dist/elements/math-block.d.ts +51 -0
- package/dist/elements/math-block.js +70 -0
- package/dist/elements/mcp-server-panel.d.ts +41 -0
- package/dist/elements/mcp-server-panel.js +115 -0
- package/dist/elements/memory-chips.d.ts +30 -0
- package/dist/elements/memory-chips.js +43 -0
- package/dist/elements/message-actions.d.ts +38 -0
- package/dist/elements/message-actions.js +71 -0
- package/dist/elements/message-attachment.d.ts +48 -0
- package/dist/elements/message-attachment.js +63 -0
- package/dist/elements/message-branches.d.ts +25 -0
- package/dist/elements/message-branches.js +65 -0
- package/dist/elements/message-pair.d.ts +33 -0
- package/dist/elements/message-pair.js +65 -0
- package/dist/elements/message-queue.d.ts +31 -0
- package/dist/elements/message-queue.js +80 -0
- package/dist/elements/message-timing.d.ts +33 -0
- package/dist/elements/message-timing.js +37 -0
- package/dist/elements/mobile-composer.d.ts +44 -0
- package/dist/elements/mobile-composer.js +88 -0
- package/dist/elements/model-picker.d.ts +38 -0
- package/dist/elements/model-picker.js +69 -0
- package/dist/elements/number-ticker.d.ts +18 -0
- package/dist/elements/number-ticker.js +47 -0
- package/dist/elements/onboarding.d.ts +30 -0
- package/dist/elements/onboarding.js +75 -0
- package/dist/elements/permission-grant.d.ts +35 -0
- package/dist/elements/permission-grant.js +86 -0
- package/dist/elements/permission-scopes.d.ts +215 -0
- package/dist/elements/permission-scopes.js +249 -0
- package/dist/elements/prompt-library.d.ts +43 -0
- package/dist/elements/prompt-library.js +117 -0
- package/dist/elements/queue-dock.d.ts +101 -0
- package/dist/elements/queue-dock.js +132 -0
- package/dist/elements/quota-banner.d.ts +26 -0
- package/dist/elements/quota-banner.js +66 -0
- package/dist/elements/quote-reply.d.ts +44 -0
- package/dist/elements/quote-reply.js +79 -0
- package/dist/elements/range.d.ts +29 -0
- package/dist/elements/range.js +45 -0
- package/dist/elements/read-aloud.d.ts +45 -0
- package/dist/elements/read-aloud.js +75 -0
- package/dist/elements/reasoning-effort.d.ts +36 -0
- package/dist/elements/reasoning-effort.js +67 -0
- package/dist/elements/reasoning-panel.d.ts +46 -0
- package/dist/elements/reasoning-panel.js +75 -0
- package/dist/elements/recommendation-card.d.ts +45 -0
- package/dist/elements/recommendation-card.js +83 -0
- package/dist/elements/regenerate-menu.d.ts +45 -0
- package/dist/elements/regenerate-menu.js +51 -0
- package/dist/elements/replay.d.ts +217 -0
- package/dist/elements/replay.js +498 -0
- package/dist/elements/research-report.d.ts +38 -0
- package/dist/elements/research-report.js +69 -0
- package/dist/elements/retrieval-chunks.d.ts +43 -0
- package/dist/elements/retrieval-chunks.js +81 -0
- package/dist/elements/revert-dock.d.ts +159 -0
- package/dist/elements/revert-dock.js +327 -0
- package/dist/elements/reviewable-diff.d.ts +45 -0
- package/dist/elements/reviewable-diff.js +110 -0
- package/dist/elements/risk-badge.d.ts +52 -0
- package/dist/elements/risk-badge.js +91 -0
- package/dist/elements/schedule-card.d.ts +42 -0
- package/dist/elements/schedule-card.js +90 -0
- package/dist/elements/score-breakdown.d.ts +47 -0
- package/dist/elements/score-breakdown.js +82 -0
- package/dist/elements/scroll-anchor.d.ts +32 -0
- package/dist/elements/scroll-anchor.js +121 -0
- package/dist/elements/settings-panel.d.ts +52 -0
- package/dist/elements/settings-panel.js +107 -0
- package/dist/elements/shared-conversation.d.ts +39 -0
- package/dist/elements/shared-conversation.js +68 -0
- package/dist/elements/sources.d.ts +33 -0
- package/dist/elements/sources.js +61 -0
- package/dist/elements/speaker-identity.d.ts +32 -0
- package/dist/elements/speaker-identity.js +51 -0
- package/dist/elements/spec-sheet.d.ts +31 -0
- package/dist/elements/spec-sheet.js +45 -0
- package/dist/elements/stopped-run.d.ts +22 -0
- package/dist/elements/stopped-run.js +50 -0
- package/dist/elements/streaming-text.d.ts +31 -0
- package/dist/elements/streaming-text.js +45 -0
- package/dist/elements/subagent-list.d.ts +37 -0
- package/dist/elements/subagent-list.js +79 -0
- package/dist/elements/suggestions.d.ts +30 -0
- package/dist/elements/suggestions.js +36 -0
- package/dist/elements/surfaces.d.ts +85 -0
- package/dist/elements/surfaces.js +107 -0
- package/dist/elements/tail-status.d.ts +131 -0
- package/dist/elements/tail-status.js +94 -0
- package/dist/elements/terminal-block.d.ts +29 -0
- package/dist/elements/terminal-block.js +54 -0
- package/dist/elements/thinking-indicator.d.ts +18 -0
- package/dist/elements/thinking-indicator.js +36 -0
- package/dist/elements/thread-list.d.ts +35 -0
- package/dist/elements/thread-list.js +68 -0
- package/dist/elements/thread-search.d.ts +42 -0
- package/dist/elements/thread-search.js +99 -0
- package/dist/elements/timeline.d.ts +37 -0
- package/dist/elements/timeline.js +46 -0
- package/dist/elements/todo-list.d.ts +42 -0
- package/dist/elements/todo-list.js +59 -0
- package/dist/elements/tool-call.d.ts +41 -0
- package/dist/elements/tool-call.js +85 -0
- package/dist/elements/tool-error.d.ts +39 -0
- package/dist/elements/tool-error.js +76 -0
- package/dist/elements/tool-group.d.ts +45 -0
- package/dist/elements/tool-group.js +71 -0
- package/dist/elements/tool-timeline.d.ts +65 -0
- package/dist/elements/tool-timeline.js +88 -0
- package/dist/elements/trace-waterfall.d.ts +37 -0
- package/dist/elements/trace-waterfall.js +69 -0
- package/dist/elements/transcript-rules.d.ts +67 -0
- package/dist/elements/transcript-rules.js +95 -0
- package/dist/elements/turn-footer.d.ts +74 -0
- package/dist/elements/turn-footer.js +101 -0
- package/dist/elements/typing-indicator.d.ts +16 -0
- package/dist/elements/typing-indicator.js +51 -0
- package/dist/elements/verdict-row.d.ts +89 -0
- package/dist/elements/verdict-row.js +150 -0
- package/dist/elements/vocabulary.d.ts +612 -0
- package/dist/elements/vocabulary.js +611 -0
- package/dist/elements/voice-conversation.d.ts +49 -0
- package/dist/elements/voice-conversation.js +123 -0
- package/dist/elements/web-preview.d.ts +32 -0
- package/dist/elements/web-preview.js +66 -0
- package/dist/elements/web-search.d.ts +37 -0
- package/dist/elements/web-search.js +66 -0
- package/dist/elements/work-collapse.d.ts +103 -0
- package/dist/elements/work-collapse.js +131 -0
- package/dist/forms/_chassis.d.ts +104 -4
- package/dist/forms/_chassis.js +104 -4
- package/dist/forms/input-group.d.ts +8 -3
- package/dist/forms/input-group.js +8 -3
- package/dist/forms/number-field.d.ts +3 -2
- package/dist/forms/number-field.js +3 -2
- package/dist/icons/containers.d.ts +89 -0
- package/dist/icons/containers.js +295 -0
- package/dist/icons/index.d.ts +2 -0
- package/dist/index.d.ts +12 -6
- package/dist/index.js +5 -1
- package/dist/instruments/_data-row.js +118 -0
- package/dist/instruments/data-row.d.ts +94 -0
- package/dist/instruments/data-row.js +151 -0
- package/dist/instruments/data-tree.d.ts +126 -0
- package/dist/instruments/data-tree.js +303 -0
- package/dist/instruments/index.d.ts +5 -2
- package/dist/instruments/index.js +4 -1
- package/dist/instruments/ledger.d.ts +105 -0
- package/dist/instruments/ledger.js +114 -0
- package/dist/instruments/table.d.ts +70 -2
- package/dist/instruments/table.js +133 -39
- package/dist/instruments/two-step-button.js +25 -6
- package/dist/layout/sidebar.d.ts +19 -1
- package/dist/layout/sidebar.js +19 -1
- package/dist/primitives/button.js +11 -1
- package/dist/primitives/chip.d.ts +35 -9
- package/dist/primitives/chip.js +97 -11
- package/dist/system/agent-skin.d.ts +27 -0
- package/dist/system/agent-skin.js +20 -0
- package/dist/system/portal.d.ts +5 -3
- package/dist/system/portal.js +19 -5
- package/dist/system/theme-provider.js +54 -9
- package/dist/system/use-density.d.ts +9 -0
- package/dist/system/use-density.js +9 -0
- package/dist/system/use-isomorphic-layout-effect.js +19 -1
- package/dist/theming/_presets.d.ts +1 -1
- package/dist/theming/_presets.js +74 -11
- package/dist/theming/contrast.d.ts +16 -4
- package/dist/theming/contrast.js +33 -6
- package/dist/theming/create-theme.d.ts +6 -2
- package/dist/theming/create-theme.js +32 -5
- package/dist/theming/serialize.d.ts +10 -1
- package/dist/theming/serialize.js +62 -8
- package/manifest/components/activity-graph.json +88 -0
- package/manifest/components/agent-card.json +120 -0
- package/manifest/components/agent-handoff.json +87 -0
- package/manifest/components/agent-mode-badge.json +84 -0
- package/manifest/components/agent-plan.json +67 -0
- package/manifest/components/agent-status.json +73 -0
- package/manifest/components/agent-surface.json +78 -0
- package/manifest/components/alert-dialog.json +1 -1
- package/manifest/components/animated-number.json +67 -0
- package/manifest/components/app-shell.json +142 -9
- package/manifest/components/approval-card.json +106 -0
- package/manifest/components/artifact-card.json +81 -0
- package/manifest/components/audience-icon.json +52 -0
- package/manifest/components/autocomplete.json +2 -0
- package/manifest/components/background-inbox.json +71 -0
- package/manifest/components/branch-picker.json +124 -0
- package/manifest/components/button.json +1 -0
- package/manifest/components/canvas-split-body.json +62 -0
- package/manifest/components/canvas-split-document.json +54 -0
- package/manifest/components/canvas-split-header.json +83 -0
- package/manifest/components/canvas-split-line.json +62 -0
- package/manifest/components/canvas-split-message.json +62 -0
- package/manifest/components/canvas-split-thread.json +54 -0
- package/manifest/components/canvas-split.json +60 -0
- package/manifest/components/catalogue-icon.json +52 -0
- package/manifest/components/channel-beta-icon.json +52 -0
- package/manifest/components/channel-released-icon.json +52 -0
- package/manifest/components/chart.json +93 -0
- package/manifest/components/chat-empty-state.json +55 -0
- package/manifest/components/chat-panel-assistant-message.json +51 -0
- package/manifest/components/chat-panel-composer.json +66 -0
- package/manifest/components/chat-panel-messages.json +51 -0
- package/manifest/components/chat-panel-typing.json +51 -0
- package/manifest/components/chat-panel-user-message.json +51 -0
- package/manifest/components/chat-panel.json +57 -0
- package/manifest/components/checkpoint-history.json +80 -0
- package/manifest/components/chip.json +24 -12
- package/manifest/components/clamp.json +102 -0
- package/manifest/components/cli-tool-icon.json +52 -0
- package/manifest/components/code-diff.json +87 -0
- package/manifest/components/code-runner.json +97 -0
- package/manifest/components/color-field.json +2 -0
- package/manifest/components/color-picker.json +2 -0
- package/manifest/components/combobox.json +2 -0
- package/manifest/components/compaction-row.json +100 -0
- package/manifest/components/comparison-card.json +83 -0
- package/manifest/components/composer-actions.json +65 -0
- package/manifest/components/composer-attach-button.json +65 -0
- package/manifest/components/composer-attachment-chip.json +75 -0
- package/manifest/components/composer-attachments.json +60 -0
- package/manifest/components/composer-bar.json +73 -0
- package/manifest/components/composer-command-item.json +79 -0
- package/manifest/components/composer-context.json +67 -0
- package/manifest/components/composer-input.json +73 -0
- package/manifest/components/composer-menu-item.json +72 -0
- package/manifest/components/composer-menu.json +79 -0
- package/manifest/components/composer-model-item.json +75 -0
- package/manifest/components/composer-model-trigger.json +75 -0
- package/manifest/components/composer-person-item.json +79 -0
- package/manifest/components/composer-send.json +80 -0
- package/manifest/components/composer-toolbar.json +65 -0
- package/manifest/components/composer-voice-button.json +68 -0
- package/manifest/components/composer-voice.json +75 -0
- package/manifest/components/composer.json +2 -0
- package/manifest/components/computer-use.json +84 -0
- package/manifest/components/confidence-marker.json +74 -0
- package/manifest/components/connection-state.json +84 -0
- package/manifest/components/context-breakdown.json +65 -0
- package/manifest/components/context-usage.json +85 -0
- package/manifest/components/conversation-search.json +92 -0
- package/manifest/components/cost-meter.json +74 -0
- package/manifest/components/cue-portal-frame.json +1 -1
- package/manifest/components/data-row.json +203 -0
- package/manifest/components/data-tree.json +151 -0
- package/manifest/components/date-field.json +2 -0
- package/manifest/components/date-picker.json +2 -0
- package/manifest/components/date-range-picker.json +2 -0
- package/manifest/components/day-separator.json +58 -0
- package/manifest/components/delegation-card.json +1 -1
- package/manifest/components/density.json +1 -1
- package/manifest/components/diagram.json +100 -0
- package/manifest/components/document-reference.json +90 -0
- package/manifest/components/draft-restore.json +82 -0
- package/manifest/components/drawer.json +1 -1
- package/manifest/components/dropdown-menu.json +1 -1
- package/manifest/components/edit-message.json +105 -0
- package/manifest/components/elements-command-palette.json +100 -0
- package/manifest/components/elements-composer.json +71 -0
- package/manifest/components/elements-data-table.json +68 -0
- package/manifest/components/elements-timeline.json +69 -0
- package/manifest/components/elicitation-form.json +103 -0
- package/manifest/components/empty-state-composer.json +64 -0
- package/manifest/components/empty-state-greeting.json +49 -0
- package/manifest/components/empty-state-suggestion.json +57 -0
- package/manifest/components/empty-state-suggestions.json +49 -0
- package/manifest/components/end-of-turn-summary.json +77 -0
- package/manifest/components/env-var-input.json +2 -0
- package/manifest/components/error-state.json +80 -0
- package/manifest/components/feedback-dialog.json +107 -0
- package/manifest/components/file-tree.json +83 -0
- package/manifest/components/flow-graph.json +75 -0
- package/manifest/components/folder-icon.json +52 -0
- package/manifest/components/frac.json +59 -0
- package/manifest/components/generation-loader.json +64 -0
- package/manifest/components/generative-ui.json +93 -0
- package/manifest/components/guardrail-notice.json +91 -0
- package/manifest/components/hover-card.json +1 -1
- package/manifest/components/image-generation.json +67 -0
- package/manifest/components/info-tip.json +1 -1
- package/manifest/components/inline-citation.json +77 -0
- package/manifest/components/input-group.json +4 -2
- package/manifest/components/input.json +3 -1
- package/manifest/components/job-progress.json +96 -0
- package/manifest/components/launcher-bubble.json +105 -0
- package/manifest/components/ledger.json +187 -0
- package/manifest/components/live-region-announcer.json +79 -0
- package/manifest/components/map-answer.json +83 -0
- package/manifest/components/markdown-text.json +94 -0
- package/manifest/components/math-block.json +74 -0
- package/manifest/components/mcp-server-icon.json +52 -0
- package/manifest/components/mcp-server-panel.json +87 -0
- package/manifest/components/memory-chips.json +65 -0
- package/manifest/components/message-actions.json +99 -0
- package/manifest/components/message-attachments.json +63 -0
- package/manifest/components/message-branches.json +71 -0
- package/manifest/components/message-list.json +1 -1
- package/manifest/components/message-pair.json +86 -0
- package/manifest/components/message-queue.json +74 -0
- package/manifest/components/message-timing.json +62 -0
- package/manifest/components/mobile-composer.json +126 -0
- package/manifest/components/model-picker.json +76 -0
- package/manifest/components/multi-select.json +2 -0
- package/manifest/components/musical-time-input.json +2 -0
- package/manifest/components/node-card.json +1 -1
- package/manifest/components/node-handle.json +1 -1
- package/manifest/components/number-field.json +3 -1
- package/manifest/components/number-ticker.json +61 -0
- package/manifest/components/onboarding.json +84 -0
- package/manifest/components/otp-field.json +9 -7
- package/manifest/components/password-input.json +2 -0
- package/manifest/components/permission-grant.json +92 -0
- package/manifest/components/permission-scopes.json +139 -0
- package/manifest/components/popover.json +1 -1
- package/manifest/components/prompt-library.json +99 -0
- package/manifest/components/queue-dock.json +110 -0
- package/manifest/components/quota-banner.json +94 -0
- package/manifest/components/quote-reply.json +105 -0
- package/manifest/components/read-aloud.json +111 -0
- package/manifest/components/reasoning-effort.json +81 -0
- package/manifest/components/reasoning-panel.json +108 -0
- package/manifest/components/recommendation-card.json +107 -0
- package/manifest/components/regenerate-menu.json +89 -0
- package/manifest/components/replay-player.json +102 -0
- package/manifest/components/research-report.json +76 -0
- package/manifest/components/retrieval-chunks.json +84 -0
- package/manifest/components/revert-dock.json +150 -0
- package/manifest/components/reviewable-diff.json +93 -0
- package/manifest/components/risk-badge.json +74 -0
- package/manifest/components/schedule-card.json +101 -0
- package/manifest/components/score-breakdown.json +91 -0
- package/manifest/components/scroll-anchor.json +72 -0
- package/manifest/components/scroll-area.json +7 -7
- package/manifest/components/scrub-input.json +2 -0
- package/manifest/components/search-input.json +9 -7
- package/manifest/components/segmented-control.json +21 -21
- package/manifest/components/select.json +1 -0
- package/manifest/components/settings-panel.json +118 -0
- package/manifest/components/shared-conversation.json +89 -0
- package/manifest/components/shimmer-label.json +59 -0
- package/manifest/components/skill-icon.json +52 -0
- package/manifest/components/sources.json +83 -0
- package/manifest/components/speaker-identity.json +61 -0
- package/manifest/components/spec-sheet.json +80 -0
- package/manifest/components/stack-icon.json +52 -0
- package/manifest/components/stacks-matrix-icon.json +52 -0
- package/manifest/components/stat.json +1 -1
- package/manifest/components/status-bar.json +146 -12
- package/manifest/components/status-dot.json +1 -1
- package/manifest/components/stopped-run.json +81 -0
- package/manifest/components/streaming-text.json +71 -0
- package/manifest/components/sub.json +44 -0
- package/manifest/components/subagent-list.json +88 -0
- package/manifest/components/suggestions.json +84 -0
- package/manifest/components/sup.json +44 -0
- package/manifest/components/swap-label.json +71 -0
- package/manifest/components/table-scroll-region.json +6 -0
- package/manifest/components/table.json +88 -4
- package/manifest/components/tags-input.json +2 -0
- package/manifest/components/tail-status.json +109 -0
- package/manifest/components/terminal-block.json +91 -0
- package/manifest/components/textarea.json +3 -1
- package/manifest/components/theme-provider.json +2 -2
- package/manifest/components/thinking-indicator.json +63 -0
- package/manifest/components/thread-list.json +76 -0
- package/manifest/components/thread-search.json +90 -0
- package/manifest/components/threshold-rail.json +2 -2
- package/manifest/components/time-boundary.json +62 -0
- package/manifest/components/time-field.json +2 -0
- package/manifest/components/timeline.json +1 -1
- package/manifest/components/title-bar.json +1 -1
- package/manifest/components/todo-list.json +69 -0
- package/manifest/components/toggle-group.json +9 -7
- package/manifest/components/toggle.json +2 -0
- package/manifest/components/token-editor.json +1 -1
- package/manifest/components/tool-call-card.json +200 -0
- package/manifest/components/tool-call.json +119 -0
- package/manifest/components/tool-error.json +114 -0
- package/manifest/components/tool-group.json +83 -0
- package/manifest/components/tool-timeline.json +119 -0
- package/manifest/components/toolbar.json +7 -7
- package/manifest/components/tooltip.json +1 -1
- package/manifest/components/trace-waterfall.json +74 -0
- package/manifest/components/turn-footer.json +105 -0
- package/manifest/components/typing-indicator.json +53 -0
- package/manifest/components/unread-divider.json +55 -0
- package/manifest/components/usage-chart.json +1 -1
- package/manifest/components/verdict-row.json +91 -0
- package/manifest/components/voice-conversation.json +109 -0
- package/manifest/components/web-preview.json +87 -0
- package/manifest/components/web-search.json +92 -0
- package/manifest/components/work-collapse.json +102 -0
- package/manifest/manifest.json +2736 -60
- package/manifest/tokens.json +22 -1
- package/package.json +44 -2
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "LiveRegionAnnouncer",
|
|
3
|
+
"slug": "live-region-announcer",
|
|
4
|
+
"group": "elements",
|
|
5
|
+
"importPath": "@cueplusplus/ui/elements",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "One polite region, and a queue that makes it audible.\n\nThe element in this family with no visual design at all, and the one that\ndecides whether the rest of it can be used without a screen. An agent\ntranscript is a stream of state changes, and the naive wiring — an\n`aria-live` region bound to the current status — announces almost none of\nthem: polite announcements replace each other, so a region updated four times\na second speaks once and swallows the rest.\n\nSo this is a queue with four rules, all of them the reference's:\n\n- **Spacing.** One announcement every `spacing` milliseconds, so each is\n spoken instead of overwritten.\n- **Depth, oldest dropped.** A backlog behind a busy run is history; the\n newest five are what a reader needs.\n- **Paused while the page is hidden**, so a background tab does not read a\n run out over whatever the reader is actually doing, and paused on demand\n through `paused` while a modal has their attention. Both are in force from\n the first render rather than the first effect, so an announcer mounted into\n a hidden tab with a backlog does not spend a line of it learning where it\n is.\n- **The trailing space.** A screen reader ignores a live region set to the\n text it already holds; the same message twice is announced twice by\n appending a space to the second, which changes the string without changing\n a word of it.\n\nThe region itself is mounted empty and stays mounted. A live region added to\nthe document at the same moment as its text is a region most assistive\ntechnologies never announce, which is the most common way this fails in\npractice.\n\nWhat to say is the caller's: {@link ANNOUNCEMENTS } carries the nine\ntransitions the study found announced, as templates a console can extend or\ntranslate.\n\n**It is the surface's one speaker.** `TailStatus` is a `role=\"status\"` too,\nand a console that mounts both — which is the ordinary shape of an agent\nconsole — would have every state read out twice. So mounting this hands the\nspeaking to it: a `TailStatus` anywhere on the page notices (through\n{@link useAnnouncerPresent}) and renders as an ordinary row, keeping its words\non the screen and taking them out of the accessibility tree. Feed this the\ntransitions that row would have narrated, or set `announce` on the row to\ndecide the other way.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "messages",
|
|
12
|
+
"type": "readonly string[]",
|
|
13
|
+
"required": true,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "The log of things worth saying, oldest first. Everything that arrives at\nthe end of it after the announcer last looked is queued and read out in\norder.\n\nAn **append-only** list: the announcer remembers how much of it it has\nseen, so a list that is trimmed at the head loses the announcements that\nwere trimmed with it. Keep the run's log growing, or remount the announcer\nwith a new `key` when you start a new one."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "spacing",
|
|
19
|
+
"type": "number",
|
|
20
|
+
"required": false,
|
|
21
|
+
"defaultValue": "400",
|
|
22
|
+
"description": "Milliseconds between announcements. Defaults to `400`, the reference's own\nspacing, which is roughly how long a short phrase takes to speak.\n\nThis is the whole point of the component: a polite announcement that\narrives while another is being spoken replaces it, so an unspaced queue is\na queue most of which is never heard."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "depth",
|
|
26
|
+
"type": "number",
|
|
27
|
+
"required": false,
|
|
28
|
+
"defaultValue": "5",
|
|
29
|
+
"description": "How many announcements may wait at once. Defaults to `5`, and the **oldest**\nare dropped past it — five deep behind a busy run, the newest is the true\none and the backlog is history."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "paused",
|
|
33
|
+
"type": "boolean",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": "false",
|
|
36
|
+
"description": "Hold everything without dropping it: a modal is open, or the surface is\nbehind something a reader is working in. The queue drains from where it\nstopped when this goes back to `false`.\n\nA prop rather than an internal ref-count of open overlays, deliberately:\nthis library has its own portal and overlay contract, and an announcer with\na second opinion about what is on screen would be wrong exactly when it\nmattered."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "announceOnMount",
|
|
40
|
+
"type": "boolean",
|
|
41
|
+
"required": false,
|
|
42
|
+
"defaultValue": "false",
|
|
43
|
+
"description": "Announce the messages that are already in the list at mount. Defaults to\n`false` — the reference's \"skip the first observation\" guard, and the\nreason restoring a session does not read the whole transcript aloud.\n\nThe pause rules still hold over it: a backlog handed to an announcer that\nmounts into a hidden tab, or with `paused` already set, waits there rather\nthan spending its first line. Restoring a session into a background tab is\nthe case, and it is the one the rules exist for."
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"typeReferences": [
|
|
47
|
+
"Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\">"
|
|
48
|
+
],
|
|
49
|
+
"subcomponents": [],
|
|
50
|
+
"parts": [],
|
|
51
|
+
"variants": {},
|
|
52
|
+
"defaultVariants": {},
|
|
53
|
+
"tokensUsed": [],
|
|
54
|
+
"summary": "One polite region, and a queue that makes it audible.",
|
|
55
|
+
"examples": [
|
|
56
|
+
{
|
|
57
|
+
"title": "Usage",
|
|
58
|
+
"code": "import { ANNOUNCEMENTS, LiveRegionAnnouncer } from \"@cueplusplus/ui/elements\";\n\n// One per surface, mounted for the life of the transcript.\n<LiveRegionAnnouncer messages={log} paused={dialogOpen} />\n// Composed with the transcript's live row: the row draws, this one speaks.\n<>\n <TailStatus action={TAIL_ACTIONS.searchingCode} detail=\"composer.tsx\" />\n <LiveRegionAnnouncer messages={log} />\n</>\n// The log is a caller's append-only list of what happened.\nsetLog((was) => [...was, ANNOUNCEMENTS.working]);",
|
|
59
|
+
"language": "tsx"
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"status": "todo-docs",
|
|
63
|
+
"url": "/docs/components/live-region-announcer",
|
|
64
|
+
"mdUrl": "/docs/components/live-region-announcer.md",
|
|
65
|
+
"jsonUrl": "/r/components/live-region-announcer.json",
|
|
66
|
+
"specimens": [
|
|
67
|
+
{
|
|
68
|
+
"title": "LiveRegionAnnouncer",
|
|
69
|
+
"group": "elements",
|
|
70
|
+
"components": [
|
|
71
|
+
"LiveRegionAnnouncer"
|
|
72
|
+
],
|
|
73
|
+
"code": "<Specimens>\n <Specimen label=\"what a run says out loud\" wide>\n <div className=\"flex w-full max-w-md flex-col gap-(--cue-space-3)\">\n <LiveRegionAnnouncer messages={announced} />\n <Button\n size=\"sm\"\n className=\"self-start\"\n onClick={() =>\n setAnnounced((was) => [\n ...was,\n TRANSITIONS[was.length % TRANSITIONS.length] as string,\n ])\n }\n >\n Next transition\n </Button>\n <ol className=\"flex flex-col gap-(--cue-space-1) text-fg-muted text-(length:--cue-text-ui)\">\n {announced.length === 0 ? (\n <li className=\"text-fg-subtle\">Nothing announced yet.</li>\n ) : (\n announced.map((line, index) => (\n <li key={`${line}-${String(index)}`} className=\"truncate\">\n {line}\n </li>\n ))\n )}\n </ol>\n </div>\n </Specimen>\n <Specimen label=\"composed with the transcript's live row\" wide>\n {/*\n * The composition every agent console reaches for, and the one\n * that used to say everything twice: both of these are live\n * regions. Mounted together the row hands the speaking over — it\n * keeps its words on the screen and drops its `role=\"status\"`,\n * which is what `data-announces=\"false\"` on it says.\n */}\n <div className=\"flex w-full max-w-md flex-col gap-(--cue-space-3)\">\n <TailStatus\n action={announced.length === 0 ? TAIL_ACTIONS.thinking : TAIL_ACTIONS.running}\n detail=\"ola-patch --universe 3\"\n active={announced.length !== TRANSITIONS.length}\n />\n <LiveRegionAnnouncer messages={announced} />\n <p className=\"text-fg-subtle text-(length:--cue-text-ui)\">\n The row above is drawn, not announced: one region speaks for\n this surface and it is the queue.\n </p>\n </div>\n </Specimen>\n</Specimens>",
|
|
74
|
+
"note": "The element with no visual design at all, and the one that decides whether the rest of this family can be used without a screen. An agent transcript is a stream of state changes, and a live region wired straight to it announces almost none of them: polite announcements replace each other, so a region updated four times a second speaks once and swallows the rest. So it is a queue — 400ms of spacing, five deep with the oldest dropped, held while the page is hidden or a modal has the reader, and an identical sentence re-announced by appending a space, which changes the string without changing a word of it.",
|
|
75
|
+
"interaction": "press the button and nothing visible happens, which is the point — the list below is a mirror of what the region said, drawn only so the bench has something to look at. Press it twice quickly and the second announcement waits its 400ms rather than replacing the first; press it faster than five times and the oldest waiting one is dropped, because five deep behind a busy run the newest is the true one. The second specimen is the composition with TailStatus: that row is a role=status too, so mounting this takes the speaking off it — inspect the row and it carries data-announces=false and no role, which is how a console gets one voice instead of two."
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"todo": true
|
|
79
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "MapAnswer",
|
|
3
|
+
"slug": "map-answer",
|
|
4
|
+
"group": "elements",
|
|
5
|
+
"importPath": "@cueplusplus/ui/elements",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "A location answer: pins, a route between them, and the list they came from.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "pins",
|
|
12
|
+
"type": "readonly MapPin[]",
|
|
13
|
+
"required": true,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "Places in the answer, positioned as percentages so the element needs no tiles."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "activeId",
|
|
19
|
+
"type": "string",
|
|
20
|
+
"required": true,
|
|
21
|
+
"defaultValue": null,
|
|
22
|
+
"description": "Which pin is selected, in both the plot and the list."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "route",
|
|
26
|
+
"type": "boolean",
|
|
27
|
+
"required": false,
|
|
28
|
+
"defaultValue": null,
|
|
29
|
+
"description": "Draws a dashed path through the pins in order."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "onSelect",
|
|
33
|
+
"type": "((id: string) => void)",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": null,
|
|
36
|
+
"description": "Called when a pin or its list row is chosen. Both surfaces report the same id."
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"typeReferences": [
|
|
40
|
+
"Omit<\n ComponentProps<\"div\">,\n \"children\" | \"pins\" | \"activeId\" | \"route\" | \"onSelect\"\n> & {\n /** Places in the answer, positioned as percentages so the element needs no tiles. */\n pins: readonly MapPin[];\n /** Which pin is selected, in both the plot and the list. */\n activeId: string;\n /** Draws a dashed path through the pins in order. */\n route?: boolean;\n /** Called when a pin or its list row is chosen. Both surfaces report the same id. */\n onSelect?: (id: string) => void;\n}"
|
|
41
|
+
],
|
|
42
|
+
"subcomponents": [],
|
|
43
|
+
"parts": [],
|
|
44
|
+
"variants": {},
|
|
45
|
+
"defaultVariants": {},
|
|
46
|
+
"tokensUsed": [
|
|
47
|
+
"--cue-accent",
|
|
48
|
+
"--cue-bg",
|
|
49
|
+
"--cue-border",
|
|
50
|
+
"--cue-fg-muted",
|
|
51
|
+
"--cue-fg-subtle",
|
|
52
|
+
"--cue-radius-overlay",
|
|
53
|
+
"--cue-stream",
|
|
54
|
+
"--cue-surface-1",
|
|
55
|
+
"--cue-surface-3",
|
|
56
|
+
"--cue-text-body"
|
|
57
|
+
],
|
|
58
|
+
"summary": "A location answer: pins, a route between them, and the list they came from.",
|
|
59
|
+
"examples": [
|
|
60
|
+
{
|
|
61
|
+
"title": "Usage",
|
|
62
|
+
"code": "import { MapAnswer } from \"@cueplusplus/ui/elements\";\n\n<MapAnswer pins={pins} activeId=\"b\" route onSelect={setActive} />",
|
|
63
|
+
"language": "tsx"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"status": "todo-docs",
|
|
67
|
+
"url": "/docs/components/map-answer",
|
|
68
|
+
"mdUrl": "/docs/components/map-answer.md",
|
|
69
|
+
"jsonUrl": "/r/components/map-answer.json",
|
|
70
|
+
"specimens": [
|
|
71
|
+
{
|
|
72
|
+
"title": "MapAnswer",
|
|
73
|
+
"group": "elements-knowledge",
|
|
74
|
+
"components": [
|
|
75
|
+
"MapAnswer"
|
|
76
|
+
],
|
|
77
|
+
"code": "<Specimens>\n <Specimen label=\"three houses, routed\" wide>\n <MapAnswer pins={PINS} activeId={pin} route onSelect={setPin} />\n </Specimen>\n <Specimen label=\"no route\" wide>\n <MapAnswer pins={PINS.slice(0, 2)} activeId=\"studio\" />\n </Specimen>\n</Specimens>",
|
|
78
|
+
"note": "A location answer as a plan and a list at once: pins on a ruled ground, the same pins as rows underneath, and one selection driving both. The grid is drawn, not tiled — there is no map provider here, and `x`/`y` are percentages the caller decides.",
|
|
79
|
+
"interaction": "pin and row are both buttons for the same id, and both carry `aria-current`; the pin's own label is what a screen reader gets, since the plan itself is aria-hidden."
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"todo": true
|
|
83
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "MarkdownText",
|
|
3
|
+
"slug": "markdown-text",
|
|
4
|
+
"group": "elements",
|
|
5
|
+
"importPath": "@cueplusplus/ui/elements/markdown",
|
|
6
|
+
"peerDependencies": [
|
|
7
|
+
"react-markdown",
|
|
8
|
+
"rehype-sanitize"
|
|
9
|
+
],
|
|
10
|
+
"clientOnly": true,
|
|
11
|
+
"description": "Model output, rendered.\n\nThe one component in this library that turns a string into markup, and the\nonly one that has to be argued for rather than described. Everywhere else —\n`Message`, `AskBox`, every element in this group — text is text: a string\narrives from a model and is placed in the DOM as characters, because a\ncomponent that quietly parsed it would put every consumer of this library one\nprompt away from an injection. This one parses, so it states in full what it\nwill and will not do with what it is given.\n\n**Threat model.** The input is hostile. Assume the string was written by a\nmodel that was told to write it by a web page it fetched, a file it read, or\na tool result it did not verify — the practical shape of prompt injection is\nnot \"the model turned evil\", it is \"the model faithfully relayed an\nattacker's bytes\". Three things follow.\n\n- **No raw HTML, ever, and not by filtering it.** Markup in the source has no\n path to the DOM, and the first reason is an absence rather than a setting.\n `react-markdown` hands `remark-rehype` its own `allowDangerousHtml: true`\n and spreads it *over* whatever `remarkRehypeOptions` says, so the option\n cannot be turned off from here and `<img onerror=…>` does become a `raw`\n node. A `raw` node is a span of source text rather than an element, and the\n one thing that turns it into markup is `rehype-raw`. Nothing in this package\n depends on that plugin, and a test asserts it never will — so the string has\n no parser to reach. `rehype-sanitize` then drops the `raw` type outright,\n and react-markdown's own `skipHtml` removes whatever is left. Three gates,\n none of which is a deny-list of dangerous tags. A `<script>`, an\n `<iframe>`, an `<svg>` and an `onclick=` are all the same non-event: there\n is nothing in the tree for them to be.\n- **Attributes are enumerated, not filtered.** An element that is not in the\n schema renders nothing; an element that is renders only the attributes\n named beside it — `href`/`title` on a link, `src`/`alt`/`title` on an\n image, `language-…` on a `code`. No element in the subset accepts `id`,\n `style`, `srcset`, `formaction` or any `on*` handler, so none of them has\n an attribute to arrive on.\n- **URLs are allow-listed twice.** `http`, `https` and `mailto` on both\n `href` and `src`; a relative URL stays relative; everything else — a\n `javascript:` link, a `data:text/html` image, `vbscript:`, `blob:`,\n `file:`, `//host` — loses the attribute and leaves an inert element\n behind. Every link also carries `rel=\"noopener noreferrer nofollow\"`,\n which is not a prop: reverse tabnabbing, referrer leakage of a private\n console URL, and SEO laundering through a transcript are all things a\n caller should not be able to turn off by accident.\n\n**The subset.** Paragraphs, ATX and setext headings, bullet and ordered\nlists, block quotes, thematic breaks, fenced and indented code, inline code,\nemphasis, strong, strikethrough, links, images, and hard breaks. No GFM\nplugin is enabled, so no tables, task lists, footnotes or autolink literals —\nan explicit `<https://…>` autolink still works. Fenced blocks are plain text\nunless {@link MarkdownTextProps.renderCodeBlock} is given.\n\n**Streaming.** Pass `streaming` while the turn is arriving and the token the\nmodel is halfway through typing is hidden rather than rendered as\npunctuation: no asterisks flickering through every bold run, no half-written\nURL, no fence that opens a code block one frame and closes it the next. The\nwords appear as they arrive; only their formatting waits for the closing\ntoken.\n\n`react-markdown` and `rehype-sanitize` are optional peers of this subpath\nalone, which is why this component is not re-exported from\n`@cueplusplus/ui/elements`: a console that renders a transcript without\nmarkdown should install neither.",
|
|
12
|
+
"props": [
|
|
13
|
+
{
|
|
14
|
+
"name": "children",
|
|
15
|
+
"type": "string",
|
|
16
|
+
"required": true,
|
|
17
|
+
"defaultValue": null,
|
|
18
|
+
"description": "The markdown source. Untrusted model output is precisely what this prop is\nfor — see the component's own documentation for what is and is not\nrendered."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "streaming",
|
|
22
|
+
"type": "boolean",
|
|
23
|
+
"required": false,
|
|
24
|
+
"defaultValue": "false",
|
|
25
|
+
"description": "The turn is still arriving, so hide the token being typed.\n\nOff by default, because sealing is a small edit to the source and a\nsettled document should be rendered as written. Turn it on for the tail of\na stream and off again when the turn completes; the rendered output is\nidentical once nothing is half-written."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "target",
|
|
29
|
+
"type": "\"_self\" | \"_blank\"",
|
|
30
|
+
"required": false,
|
|
31
|
+
"defaultValue": "_blank",
|
|
32
|
+
"description": "Where a link opens. `_blank` by default: a transcript that navigates away\nloses the run. `rel` is not configurable — every link gets\n`noopener noreferrer nofollow` whatever this says."
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "headingLevel",
|
|
36
|
+
"type": "4 | 2 | 3",
|
|
37
|
+
"required": false,
|
|
38
|
+
"defaultValue": "2",
|
|
39
|
+
"description": "The heading level `#` renders at; `##` and below follow it, clamped at\n`h6`. Defaults to `2`, because model output is a passage inside a page\nthat already owns its `h1`."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "renderCodeBlock",
|
|
43
|
+
"type": "((block: MarkdownCodeBlock) => ReactNode)",
|
|
44
|
+
"required": false,
|
|
45
|
+
"defaultValue": null,
|
|
46
|
+
"description": "Render fenced code blocks with something other than plain text — a\nhighlighter, a copy button, a diff view.\n\nUnset, a block is a `<pre><code>` containing the model's characters and\nnothing else. That is the default on purpose: a highlighter is a second\nparser over the same untrusted string, usually one that emits HTML, and\nopting into it should be a line of code somebody wrote rather than a\nbehaviour they inherited."
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"typeReferences": [
|
|
50
|
+
"Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\">"
|
|
51
|
+
],
|
|
52
|
+
"subcomponents": [],
|
|
53
|
+
"parts": [],
|
|
54
|
+
"variants": {},
|
|
55
|
+
"defaultVariants": {},
|
|
56
|
+
"tokensUsed": [
|
|
57
|
+
"--cue-border",
|
|
58
|
+
"--cue-radius-control",
|
|
59
|
+
"--cue-space-1",
|
|
60
|
+
"--cue-space-2",
|
|
61
|
+
"--cue-space-3",
|
|
62
|
+
"--cue-space-5",
|
|
63
|
+
"--cue-text-body",
|
|
64
|
+
"--cue-text-emphasis",
|
|
65
|
+
"--cue-text-label",
|
|
66
|
+
"--cue-text-title",
|
|
67
|
+
"--cue-text-ui"
|
|
68
|
+
],
|
|
69
|
+
"summary": "Model output, rendered.",
|
|
70
|
+
"examples": [
|
|
71
|
+
{
|
|
72
|
+
"title": "Usage",
|
|
73
|
+
"code": "<Message agent=\"researcher\">\n <MarkdownText>{turn.text}</MarkdownText>\n</Message>\n<MarkdownText streaming={turn.status === \"running\"}>{turn.text}</MarkdownText>\n<MarkdownText renderCodeBlock={({ language, code }) => <Highlight lang={language} code={code} />}>\n {answer}\n</MarkdownText>",
|
|
74
|
+
"language": "tsx"
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
"status": "todo-docs",
|
|
78
|
+
"url": "/docs/components/markdown-text",
|
|
79
|
+
"mdUrl": "/docs/components/markdown-text.md",
|
|
80
|
+
"jsonUrl": "/r/components/markdown-text.json",
|
|
81
|
+
"specimens": [
|
|
82
|
+
{
|
|
83
|
+
"title": "MarkdownText",
|
|
84
|
+
"group": "elements-thread",
|
|
85
|
+
"components": [
|
|
86
|
+
"MarkdownText"
|
|
87
|
+
],
|
|
88
|
+
"code": "<Specimens>\n <Specimen label=\"settled\" wide>\n <MarkdownText>{MARKDOWN_ANSWER}</MarkdownText>\n </Specimen>\n <Specimen label=\"mid-stream\" wide>\n <MarkdownText streaming>{MARKDOWN_MID_STREAM}</MarkdownText>\n </Specimen>\n <Specimen label=\"mid-fence\" wide>\n <MarkdownText streaming>{MARKDOWN_MID_FENCE}</MarkdownText>\n </Specimen>\n</Specimens>",
|
|
89
|
+
"note": "The one component in the library that turns a string into markup, and the only one that has to be argued for. No raw HTML reaches the DOM — not filtered out, but never parsed: the img tag on the last line of the settled specimen is a real injection shape and renders as nothing. Links are http/https/mailto only and always carry rel='noopener noreferrer nofollow'; code blocks are plain text until a highlighter is passed. It ships from @cueplusplus/ui/elements/markdown so its parser and sanitizer stay off the elements barrel.",
|
|
90
|
+
"interaction": "none — it is a document, and it stays selectable, copyable text. Headings start at h2 by default so a turn never claims a page's title, and links are keyboard-reachable with the house focus ring."
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"todo": true
|
|
94
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "MathBlock",
|
|
3
|
+
"slug": "math-block",
|
|
4
|
+
"group": "elements",
|
|
5
|
+
"importPath": "@cueplusplus/ui/elements",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "Rendered expressions with the working shown, one step at a time.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "label",
|
|
12
|
+
"type": "string",
|
|
13
|
+
"required": false,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "Optional eyebrow above the working."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "steps",
|
|
19
|
+
"type": "readonly MathStep[]",
|
|
20
|
+
"required": true,
|
|
21
|
+
"defaultValue": null,
|
|
22
|
+
"description": "Each step is a node, so you compose expressions from the exported Frac, Sup, and\nSub helpers rather than passing a string to parse."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "visibleSteps",
|
|
26
|
+
"type": "number",
|
|
27
|
+
"required": true,
|
|
28
|
+
"defaultValue": null,
|
|
29
|
+
"description": "How much of the derivation has been shown."
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"typeReferences": [
|
|
33
|
+
"Omit<\n ComponentProps<\"div\">,\n \"children\" | \"label\" | \"steps\" | \"visibleSteps\"\n> & {\n /** Optional eyebrow above the working. */\n label?: string;\n /**\n * Each step is a node, so you compose expressions from the exported Frac, Sup, and\n * Sub helpers rather than passing a string to parse.\n */\n steps: readonly MathStep[];\n /** How much of the derivation has been shown. */\n visibleSteps: number;\n}"
|
|
34
|
+
],
|
|
35
|
+
"subcomponents": [],
|
|
36
|
+
"parts": [],
|
|
37
|
+
"variants": {},
|
|
38
|
+
"defaultVariants": {},
|
|
39
|
+
"tokensUsed": [
|
|
40
|
+
"--cue-border-strong",
|
|
41
|
+
"--cue-fg",
|
|
42
|
+
"--cue-fg-subtle",
|
|
43
|
+
"--cue-radius-overlay",
|
|
44
|
+
"--cue-text-emphasis"
|
|
45
|
+
],
|
|
46
|
+
"summary": "Rendered expressions with the working shown, one step at a time.",
|
|
47
|
+
"examples": [
|
|
48
|
+
{
|
|
49
|
+
"title": "Usage",
|
|
50
|
+
"code": "import { MathBlock, Frac, Sup } from \"@cueplusplus/ui/elements\";\n\n<MathBlock label=\"derivation\" steps={steps} visibleSteps={2} />",
|
|
51
|
+
"language": "tsx"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"status": "todo-docs",
|
|
55
|
+
"url": "/docs/components/math-block",
|
|
56
|
+
"mdUrl": "/docs/components/math-block.md",
|
|
57
|
+
"jsonUrl": "/r/components/math-block.json",
|
|
58
|
+
"specimens": [
|
|
59
|
+
{
|
|
60
|
+
"title": "MathBlock",
|
|
61
|
+
"group": "elements-knowledge",
|
|
62
|
+
"components": [
|
|
63
|
+
"MathBlock",
|
|
64
|
+
"Frac",
|
|
65
|
+
"Sub",
|
|
66
|
+
"Sup"
|
|
67
|
+
],
|
|
68
|
+
"code": "<Specimens>\n <Specimen label=\"worked through\" wide>\n <MathBlock label=\"illuminance at the deck\" steps={MATH} visibleSteps={MATH.length} />\n </Specimen>\n <Specimen label=\"first step only\" wide>\n <MathBlock steps={MATH} visibleSteps={1} />\n </Specimen>\n</Specimens>",
|
|
69
|
+
"note": "Maths with the working shown, a step at a time. The expressions are nodes rather than a string, so there is no parser and no KaTeX in the bundle — `Frac` stacks a numerator over a rule, `Sup` and `Sub` set an index upright inside the serif italic, and anything else is text.",
|
|
70
|
+
"interaction": "none. Each step's note says what justified it, which is what turns three lines of algebra into an explanation."
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"todo": true
|
|
74
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "McpServerIcon",
|
|
3
|
+
"slug": "mcp-server-icon",
|
|
4
|
+
"group": "icons",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": false,
|
|
8
|
+
"description": "An MCP server in the registry: a thing an agent connects *to*.\n\nTwo rack units with a status lamp each. It is drawn as hardware on purpose —\nan MCP server is the one entry in a catalogue of files that is a running\nprocess somewhere, with an address and a session, and a row that looked like\na document would hide the only fact about it that matters operationally.",
|
|
9
|
+
"props": [],
|
|
10
|
+
"typeReferences": [
|
|
11
|
+
"React.SVGProps<SVGSVGElement>"
|
|
12
|
+
],
|
|
13
|
+
"subcomponents": [],
|
|
14
|
+
"parts": [],
|
|
15
|
+
"variants": {},
|
|
16
|
+
"defaultVariants": {},
|
|
17
|
+
"tokensUsed": [
|
|
18
|
+
"--cue-danger",
|
|
19
|
+
"--cue-fg",
|
|
20
|
+
"--cue-icon-",
|
|
21
|
+
"--cue-icon-md",
|
|
22
|
+
"--cue-icon-sm"
|
|
23
|
+
],
|
|
24
|
+
"summary": "An MCP server in the registry: a thing an agent connects *to*.",
|
|
25
|
+
"examples": [],
|
|
26
|
+
"status": "todo-docs",
|
|
27
|
+
"url": "/docs/components/mcp-server-icon",
|
|
28
|
+
"mdUrl": "/docs/components/mcp-server-icon.md",
|
|
29
|
+
"jsonUrl": "/r/components/mcp-server-icon.json",
|
|
30
|
+
"specimens": [
|
|
31
|
+
{
|
|
32
|
+
"title": "The container icon set",
|
|
33
|
+
"group": "icons",
|
|
34
|
+
"components": [
|
|
35
|
+
"CatalogueIcon",
|
|
36
|
+
"StackIcon",
|
|
37
|
+
"StacksMatrixIcon",
|
|
38
|
+
"AudienceIcon",
|
|
39
|
+
"ChannelReleasedIcon",
|
|
40
|
+
"ChannelBetaIcon",
|
|
41
|
+
"FolderIcon",
|
|
42
|
+
"McpServerIcon",
|
|
43
|
+
"CliToolIcon",
|
|
44
|
+
"SkillIcon"
|
|
45
|
+
],
|
|
46
|
+
"code": "<Specimens>\n {CONTAINERS.map(([label, name, Icon]) => (\n <Specimen key={name} label={label}>\n <Icon className=\"size-icon-md text-fg\" />\n </Specimen>\n ))}\n</Specimens>\n<Specimens>\n <Specimen label=\"icon-sm\">\n <SkillIcon className=\"size-icon-sm text-fg\" />\n </Specimen>\n <Specimen label=\"icon-md\">\n <SkillIcon className=\"size-icon-md text-fg\" />\n </Specimen>\n <Specimen label=\"inherited\">\n <SkillIcon className=\"size-icon-md\" />\n </Specimen>\n <Specimen label=\"muted\">\n <SkillIcon className=\"size-icon-md text-fg-muted\" />\n </Specimen>\n <Specimen label=\"accent\">\n <SkillIcon className=\"size-icon-md text-accent\" />\n </Specimen>\n <Specimen label=\"danger\">\n <SkillIcon className=\"size-icon-md text-danger\" />\n </Specimen>\n</Specimens>\n<Specimens>\n <Specimen label=\"in a row\" wide>\n <span className=\"inline-flex items-center gap-(--cue-space-2) font-mono text-(length:--cue-text-ui) text-fg-muted\">\n <ChannelReleasedIcon className=\"size-icon-md shrink-0\" />\n Our skills · released\n </span>\n </Specimen>\n <Specimen label=\"current row\" wide>\n <span className=\"inline-flex items-center gap-(--cue-space-2) font-mono text-(length:--cue-text-ui) text-fg\">\n <ChannelBetaIcon className=\"size-icon-md shrink-0\" />\n Our skills · beta\n </span>\n </Specimen>\n</Specimens>",
|
|
47
|
+
"note": "One grid and one weight across all ten, at size-icon-md — the size a navigation row draws them at. Each is a plain <svg> that takes every SVG prop.",
|
|
48
|
+
"interaction": "none. They are decorative by default: aria-hidden, announced by nothing, because the row they mark already carries its name."
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"todo": true
|
|
52
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "McpServerPanel",
|
|
3
|
+
"slug": "mcp-server-panel",
|
|
4
|
+
"group": "elements",
|
|
5
|
+
"importPath": "@cueplusplus/ui/elements",
|
|
6
|
+
"peerDependencies": [
|
|
7
|
+
"lucide-react"
|
|
8
|
+
],
|
|
9
|
+
"clientOnly": true,
|
|
10
|
+
"description": "Which servers are connected, what each one brought, and which is still waiting on\nyou.",
|
|
11
|
+
"props": [
|
|
12
|
+
{
|
|
13
|
+
"name": "servers",
|
|
14
|
+
"type": "readonly McpServer[]",
|
|
15
|
+
"required": true,
|
|
16
|
+
"defaultValue": null,
|
|
17
|
+
"description": "Every configured server, connected or not. The header counts how many are live."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "expandedId",
|
|
21
|
+
"type": "string",
|
|
22
|
+
"required": false,
|
|
23
|
+
"defaultValue": null,
|
|
24
|
+
"description": "Which server is open. Only one expands at a time; omit for an all-collapsed list."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "onToggle",
|
|
28
|
+
"type": "((id: string) => void)",
|
|
29
|
+
"required": false,
|
|
30
|
+
"defaultValue": null,
|
|
31
|
+
"description": "Called when a server row is expanded or collapsed."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "onAuthorize",
|
|
35
|
+
"type": "((id: string) => void)",
|
|
36
|
+
"required": false,
|
|
37
|
+
"defaultValue": null,
|
|
38
|
+
"description": "Called from the Authorize button, shown only while a server needs auth."
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"typeReferences": [
|
|
42
|
+
"Omit<\n ComponentProps<\"div\">,\n \"children\" | \"servers\" | \"expandedId\" | \"onToggle\" | \"onAuthorize\"\n> & {\n /** Every configured server, connected or not. The header counts how many are live. */\n servers: readonly McpServer[];\n /** Which server is open. Only one expands at a time; omit for an all-collapsed list. */\n expandedId?: string;\n /** Called when a server row is expanded or collapsed. */\n onToggle?: (id: string) => void;\n /** Called from the Authorize button, shown only while a server needs auth. */\n onAuthorize?: (id: string) => void;\n}"
|
|
43
|
+
],
|
|
44
|
+
"subcomponents": [],
|
|
45
|
+
"parts": [],
|
|
46
|
+
"variants": {},
|
|
47
|
+
"defaultVariants": {},
|
|
48
|
+
"tokensUsed": [
|
|
49
|
+
"--cue-danger",
|
|
50
|
+
"--cue-fg-muted",
|
|
51
|
+
"--cue-fg-subtle",
|
|
52
|
+
"--cue-ok",
|
|
53
|
+
"--cue-radius-control",
|
|
54
|
+
"--cue-radius-overlay",
|
|
55
|
+
"--cue-radius-surface",
|
|
56
|
+
"--cue-surface-1",
|
|
57
|
+
"--cue-surface-3",
|
|
58
|
+
"--cue-text-body",
|
|
59
|
+
"--cue-text-label",
|
|
60
|
+
"--cue-warn"
|
|
61
|
+
],
|
|
62
|
+
"summary": "Which servers are connected, what each one brought, and which is still waiting on you.",
|
|
63
|
+
"examples": [
|
|
64
|
+
{
|
|
65
|
+
"title": "Usage",
|
|
66
|
+
"code": "import { McpServerPanel } from \"@cueplusplus/ui/elements\";\n\n<McpServerPanel\n servers={servers}\n expandedId={expandedId}\n onToggle={setExpandedId}\n onAuthorize={startOAuth}\n/>",
|
|
67
|
+
"language": "tsx"
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"status": "todo-docs",
|
|
71
|
+
"url": "/docs/components/mcp-server-panel",
|
|
72
|
+
"mdUrl": "/docs/components/mcp-server-panel.md",
|
|
73
|
+
"jsonUrl": "/r/components/mcp-server-panel.json",
|
|
74
|
+
"specimens": [
|
|
75
|
+
{
|
|
76
|
+
"title": "McpServerPanel",
|
|
77
|
+
"group": "elements-composer",
|
|
78
|
+
"components": [
|
|
79
|
+
"McpServerPanel"
|
|
80
|
+
],
|
|
81
|
+
"code": "<Specimens>\n <Specimen label=\"one needs authorising\" wide>\n <McpServerPanel\n servers={SERVERS}\n expandedId={server}\n onToggle={(id) => setServer((current) => (current === id ? undefined : id))}\n onAuthorize={() => setServer(undefined)}\n />\n </Specimen>\n <Specimen label=\"all collapsed\" wide>\n <McpServerPanel servers={SERVERS} />\n </Specimen>\n <Specimen label=\"one server, healthy\" wide>\n <McpServerPanel servers={SERVERS.slice(0, 1)} expandedId=\"srv-show\" />\n </Specimen>\n</Specimens>",
|
|
82
|
+
"note": "Which servers are connected, what each one brought, and which is still waiting on you. The header counts the live ones against the configured ones, and the status dot has a `sr-only` word beside it — a colour is not a status for everybody. Authorize only exists on a server that needs it, so the row that wants something from you is the only one offering an action.",
|
|
83
|
+
"interaction": "each server row carries `aria-expanded`; one expands at a time, and `expandedId` undefined is a legitimate all-collapsed state rather than a missing value."
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"todo": true
|
|
87
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "MemoryChips",
|
|
3
|
+
"slug": "memory-chips",
|
|
4
|
+
"group": "elements",
|
|
5
|
+
"importPath": "@cueplusplus/ui/elements",
|
|
6
|
+
"peerDependencies": [
|
|
7
|
+
"lucide-react"
|
|
8
|
+
],
|
|
9
|
+
"clientOnly": true,
|
|
10
|
+
"description": "What it now remembers about you, written during the turn and removable.",
|
|
11
|
+
"props": [
|
|
12
|
+
{
|
|
13
|
+
"name": "chips",
|
|
14
|
+
"type": "readonly MemoryChip[]",
|
|
15
|
+
"required": true,
|
|
16
|
+
"defaultValue": null,
|
|
17
|
+
"description": "What is remembered. Anything not marked existing is counted as new this turn and\ntinted."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "onForget",
|
|
21
|
+
"type": "((id: string) => void)",
|
|
22
|
+
"required": false,
|
|
23
|
+
"defaultValue": null,
|
|
24
|
+
"description": "Called to drop a fact. Every chip is removable, including ones it just learned."
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"typeReferences": [
|
|
28
|
+
"Omit<ComponentProps<\"div\">, \"children\" | \"chips\" | \"onForget\"> & {\n /**\n * What is remembered. Anything not marked existing is counted as new this turn and\n * tinted.\n */\n chips: readonly MemoryChip[];\n /** Called to drop a fact. Every chip is removable, including ones it just learned. */\n onForget?: (id: string) => void;\n}"
|
|
29
|
+
],
|
|
30
|
+
"subcomponents": [],
|
|
31
|
+
"parts": [],
|
|
32
|
+
"variants": {},
|
|
33
|
+
"defaultVariants": {},
|
|
34
|
+
"tokensUsed": [
|
|
35
|
+
"--cue-fg-muted",
|
|
36
|
+
"--cue-fg-subtle",
|
|
37
|
+
"--cue-stream",
|
|
38
|
+
"--cue-text-ui"
|
|
39
|
+
],
|
|
40
|
+
"summary": "What it now remembers about you, written during the turn and removable.",
|
|
41
|
+
"examples": [
|
|
42
|
+
{
|
|
43
|
+
"title": "Usage",
|
|
44
|
+
"code": "import { MemoryChips } from \"@cueplusplus/ui/elements\";\n\n<MemoryChips chips={chips} onForget={forget} />",
|
|
45
|
+
"language": "tsx"
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"status": "todo-docs",
|
|
49
|
+
"url": "/docs/components/memory-chips",
|
|
50
|
+
"mdUrl": "/docs/components/memory-chips.md",
|
|
51
|
+
"jsonUrl": "/r/components/memory-chips.json",
|
|
52
|
+
"specimens": [
|
|
53
|
+
{
|
|
54
|
+
"title": "MemoryChips",
|
|
55
|
+
"group": "elements-composer",
|
|
56
|
+
"components": [
|
|
57
|
+
"MemoryChips"
|
|
58
|
+
],
|
|
59
|
+
"code": "<Specimens>\n <Specimen label=\"two new this turn\" wide>\n <MemoryChips\n chips={memory}\n onForget={(id) => setForgotten((current) => [...current, id])}\n />\n </Specimen>\n <Specimen label=\"nothing new\" wide>\n <MemoryChips chips={MEMORY.map((chip) => ({ ...chip, change: \"existing\" as const }))} />\n </Specimen>\n</Specimens>",
|
|
60
|
+
"note": "What it now remembers about you, written during the turn it learned it. The header counts what is new rather than what is stored — `remembered 2` is the fact worth showing — and anything not marked `existing` takes the streaming hue so a new memory is visibly new. Every chip is removable, including the one it just learned, which is the only version of this control that is honest.",
|
|
61
|
+
"interaction": "each chip's remove button is labelled with the fact it would forget — `Forget ESPRITEs run in mode 8` — so the control names its consequence rather than saying 'remove'."
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"todo": true
|
|
65
|
+
}
|