dsh-vt-gen-ui 0.0.0-stage → 1.0.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/ICON-NAMES.md +30 -0
- package/LICENSE +21 -0
- package/README.md +111 -2
- package/SKILL.md +371 -0
- package/THIRD_PARTY_NOTICES.md +55 -0
- package/assets/vt-gen-ui-icon.svg +20 -0
- package/cordis.patch.yml +14 -0
- package/docs/CAPABILITY-MAP.md +171 -0
- package/docs/recon/scaffold.md +790 -0
- package/docs/recon/schema.md +543 -0
- package/docs/recon/trim.md +22 -0
- package/docs/recon/visual.md +412 -0
- package/lib/assets/echarts-core.js +43 -0
- package/lib/assets/echarts-full.js +72 -0
- package/lib/assets/icons.js +1 -0
- package/lib/assets/mermaid.js +3673 -0
- package/lib/assets/standalone-runtime.js +1507 -0
- package/lib/assets/three.js +3844 -0
- package/lib/client.js +408 -0
- package/lib/index.js +5586 -0
- package/lib/types/client/EChartNode.d.ts +4 -0
- package/lib/types/client/ErrorBoundary.d.ts +30 -0
- package/lib/types/client/GenuiBlock.d.ts +9 -0
- package/lib/types/client/PlotBlock.d.ts +46 -0
- package/lib/types/client/TemplateDrawer.d.ts +7 -0
- package/lib/types/client/achievement-store.d.ts +35 -0
- package/lib/types/client/achievement-toast.d.ts +2 -0
- package/lib/types/client/achievements.d.ts +63 -0
- package/lib/types/client/action-context.d.ts +7 -0
- package/lib/types/client/artifact/ExportableGenuiBlock.d.ts +6 -0
- package/lib/types/client/artifact/create.d.ts +5 -0
- package/lib/types/client/artifact/download.d.ts +9 -0
- package/lib/types/client/artifact/html.d.ts +5 -0
- package/lib/types/client/artifact/index.d.ts +8 -0
- package/lib/types/client/artifact/json.d.ts +3 -0
- package/lib/types/client/artifact/parse.d.ts +3 -0
- package/lib/types/client/artifact/portability.d.ts +4 -0
- package/lib/types/client/artifact/standalone-theme.d.ts +2 -0
- package/lib/types/client/artifact/types.d.ts +33 -0
- package/lib/types/client/asset-echarts-core.d.ts +1 -0
- package/lib/types/client/asset-echarts.d.ts +17 -0
- package/lib/types/client/asset-loader.d.ts +33 -0
- package/lib/types/client/asset-mermaid.d.ts +1 -0
- package/lib/types/client/asset-three.d.ts +1 -0
- package/lib/types/client/blocks/advanced.d.ts +104 -0
- package/lib/types/client/blocks/basic.d.ts +22 -0
- package/lib/types/client/blocks/blocks.d.ts +12 -0
- package/lib/types/client/blocks/charts.d.ts +54 -0
- package/lib/types/client/blocks/checkbox.d.ts +17 -0
- package/lib/types/client/blocks/diagram/geometry.d.ts +73 -0
- package/lib/types/client/blocks/diagram/index.d.ts +5 -0
- package/lib/types/client/blocks/diagram/layout.d.ts +41 -0
- package/lib/types/client/blocks/diagram/theme.d.ts +37 -0
- package/lib/types/client/blocks/forms.d.ts +77 -0
- package/lib/types/client/blocks/icon.d.ts +4 -0
- package/lib/types/client/blocks/image.d.ts +6 -0
- package/lib/types/client/blocks/render-node.d.ts +10 -0
- package/lib/types/client/blocks/state.d.ts +63 -0
- package/lib/types/client/blocks/svg.d.ts +4 -0
- package/lib/types/client/chart-theme.d.ts +84 -0
- package/lib/types/client/copy-preview-state.d.ts +10 -0
- package/lib/types/client/dom-fence.d.ts +31 -0
- package/lib/types/client/echarts-engine.d.ts +4 -0
- package/lib/types/client/echarts-lazy.d.ts +18 -0
- package/lib/types/client/embed.d.ts +10 -0
- package/lib/types/client/fence-render.d.ts +90 -0
- package/lib/types/client/file-address.d.ts +4 -0
- package/lib/types/client/file-link-context.d.ts +49 -0
- package/lib/types/client/file-link.d.ts +17 -0
- package/lib/types/client/gallery.d.ts +13 -0
- package/lib/types/client/genui-runtime/diagnostics.d.ts +18 -0
- package/lib/types/client/genui-runtime/index.d.ts +1 -0
- package/lib/types/client/genui-runtime/limits.d.ts +61 -0
- package/lib/types/client/genui-runtime/normalize.d.ts +15 -0
- package/lib/types/client/genui-runtime/schema.d.ts +100 -0
- package/lib/types/client/genui-runtime/value-utils.d.ts +18 -0
- package/lib/types/client/guard.d.ts +147 -0
- package/lib/types/client/i18n/en.d.ts +314 -0
- package/lib/types/client/i18n/index.d.ts +44 -0
- package/lib/types/client/i18n/runtime.d.ts +64 -0
- package/lib/types/client/i18n/zh.d.ts +8 -0
- package/lib/types/client/icons/asset-icons.d.ts +1 -0
- package/lib/types/client/icons/icon-data-full.d.ts +23 -0
- package/lib/types/client/icons/icon-data.d.ts +24 -0
- package/lib/types/client/icons/icon-lazy.d.ts +18 -0
- package/lib/types/client/icons/icon-names-full.d.ts +12 -0
- package/lib/types/client/index.d.ts +26 -0
- package/lib/types/client/inline.d.ts +5 -0
- package/lib/types/client/interaction-store.d.ts +48 -0
- package/lib/types/client/mermaid-colors.d.ts +2 -0
- package/lib/types/client/mermaid-core.d.ts +9 -0
- package/lib/types/client/mermaid-lazy.d.ts +13 -0
- package/lib/types/client/mermaid-safe.d.ts +52 -0
- package/lib/types/client/panel-command.d.ts +54 -0
- package/lib/types/client/panel-store.d.ts +94 -0
- package/lib/types/client/panel.d.ts +23 -0
- package/lib/types/client/parse-partial.d.ts +63 -0
- package/lib/types/client/primitive-adapter.d.ts +2 -0
- package/lib/types/client/primitive-labels.d.ts +18 -0
- package/lib/types/client/safe-math.d.ts +43 -0
- package/lib/types/client/scene3d-core.d.ts +21 -0
- package/lib/types/client/scene3d-lazy.d.ts +8 -0
- package/lib/types/client/session-resolver.d.ts +19 -0
- package/lib/types/client/source-fence.d.ts +29 -0
- package/lib/types/client/spec.d.ts +819 -0
- package/lib/types/client/standalone/asset-loader.d.ts +2 -0
- package/lib/types/client/standalone/bootstrap-types.d.ts +9 -0
- package/lib/types/client/standalone/katex-style.d.ts +1 -0
- package/lib/types/client/standalone/primitive-adapter.d.ts +50 -0
- package/lib/types/client/standalone/runtime.d.ts +2 -0
- package/lib/types/client/submission-registry.d.ts +51 -0
- package/lib/types/client/svg-fence.d.ts +2 -0
- package/lib/types/client/table-details.d.ts +20 -0
- package/lib/types/client/templates.d.ts +41 -0
- package/lib/types/client/toolview.d.ts +7 -0
- package/lib/types/client/walk-spec.d.ts +3 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/plugin/chart-contract.d.ts +9 -0
- package/lib/types/plugin/fence-feedback.d.ts +155 -0
- package/lib/types/plugin/genui-diagnostic.d.ts +13 -0
- package/lib/types/plugin/index.d.ts +39 -0
- package/lib/types/plugin/inline-content-diagnostic.d.ts +8 -0
- package/lib/types/plugin/tool.d.ts +27 -0
- package/lib/types/shared/fence-language.d.ts +14 -0
- package/lib/types/shared/fence-repair.d.ts +79 -0
- package/lib/types/shared/fence-resolve.d.ts +39 -0
- package/package.json +227 -4
- package/src/client/EChartNode.tsx +512 -0
- package/src/client/ErrorBoundary.tsx +67 -0
- package/src/client/GenuiBlock.module.css +2631 -0
- package/src/client/GenuiBlock.tsx +239 -0
- package/src/client/PlotBlock.module.css +156 -0
- package/src/client/PlotBlock.tsx +522 -0
- package/src/client/TemplateDrawer.module.css +152 -0
- package/src/client/TemplateDrawer.tsx +147 -0
- package/src/client/achievement-store.ts +151 -0
- package/src/client/achievement-toast.tsx +71 -0
- package/src/client/achievements.ts +160 -0
- package/src/client/action-context.ts +22 -0
- package/src/client/artifact/ArtifactExport.module.css +95 -0
- package/src/client/artifact/ExportableGenuiBlock.tsx +121 -0
- package/src/client/artifact/create.ts +69 -0
- package/src/client/artifact/download.ts +42 -0
- package/src/client/artifact/html.ts +157 -0
- package/src/client/artifact/index.ts +15 -0
- package/src/client/artifact/json.ts +6 -0
- package/src/client/artifact/parse.ts +32 -0
- package/src/client/artifact/portability.ts +52 -0
- package/src/client/artifact/standalone-theme.ts +94 -0
- package/src/client/artifact/types.ts +44 -0
- package/src/client/asset-echarts-core.ts +39 -0
- package/src/client/asset-echarts.ts +27 -0
- package/src/client/asset-loader.ts +96 -0
- package/src/client/asset-mermaid.ts +13 -0
- package/src/client/asset-three.ts +12 -0
- package/src/client/blocks/advanced.tsx +669 -0
- package/src/client/blocks/basic.tsx +121 -0
- package/src/client/blocks/blocks.tsx +143 -0
- package/src/client/blocks/charts.tsx +1047 -0
- package/src/client/blocks/checkbox.tsx +61 -0
- package/src/client/blocks/diagram/geometry.ts +151 -0
- package/src/client/blocks/diagram/index.tsx +293 -0
- package/src/client/blocks/diagram/layout.ts +202 -0
- package/src/client/blocks/diagram/theme.ts +127 -0
- package/src/client/blocks/forms.tsx +531 -0
- package/src/client/blocks/icon.tsx +93 -0
- package/src/client/blocks/image.tsx +29 -0
- package/src/client/blocks/render-node.tsx +529 -0
- package/src/client/blocks/state.ts +65 -0
- package/src/client/blocks/svg.tsx +66 -0
- package/src/client/chart-theme.ts +173 -0
- package/src/client/copy-preview-state.ts +39 -0
- package/src/client/dom-fence.tsx +1785 -0
- package/src/client/echarts-engine.ts +9 -0
- package/src/client/echarts-lazy.ts +41 -0
- package/src/client/embed.ts +19 -0
- package/src/client/fence-render.tsx +250 -0
- package/src/client/file-address.ts +37 -0
- package/src/client/file-link-context.tsx +116 -0
- package/src/client/file-link.ts +46 -0
- package/src/client/gallery.ts +243 -0
- package/src/client/genui-runtime/diagnostics.ts +165 -0
- package/src/client/genui-runtime/index.ts +1 -0
- package/src/client/genui-runtime/limits.ts +61 -0
- package/src/client/genui-runtime/normalize.ts +365 -0
- package/src/client/genui-runtime/schema.ts +387 -0
- package/src/client/genui-runtime/value-utils.ts +67 -0
- package/src/client/guard.ts +2125 -0
- package/src/client/i18n/en.ts +342 -0
- package/src/client/i18n/index.ts +125 -0
- package/src/client/i18n/runtime.ts +130 -0
- package/src/client/i18n/zh.ts +337 -0
- package/src/client/icons/asset-icons.ts +16 -0
- package/src/client/icons/icon-data-full.ts +5715 -0
- package/src/client/icons/icon-data.ts +507 -0
- package/src/client/icons/icon-lazy.ts +80 -0
- package/src/client/icons/icon-names-full.ts +12 -0
- package/src/client/index.tsx +204 -0
- package/src/client/inline.ts +117 -0
- package/src/client/interaction-store.ts +127 -0
- package/src/client/mermaid-colors.ts +40 -0
- package/src/client/mermaid-core.ts +341 -0
- package/src/client/mermaid-lazy.ts +126 -0
- package/src/client/mermaid-safe.ts +122 -0
- package/src/client/panel-command.ts +152 -0
- package/src/client/panel-store.ts +471 -0
- package/src/client/panel.tsx +300 -0
- package/src/client/parse-partial.ts +170 -0
- package/src/client/primitive-adapter.ts +2 -0
- package/src/client/primitive-labels.ts +55 -0
- package/src/client/safe-math.ts +298 -0
- package/src/client/scene3d-core.ts +195 -0
- package/src/client/scene3d-lazy.ts +26 -0
- package/src/client/session-resolver.ts +24 -0
- package/src/client/source-fence.ts +72 -0
- package/src/client/spec.ts +1016 -0
- package/src/client/standalone/asset-loader.ts +9 -0
- package/src/client/standalone/bootstrap-types.ts +11 -0
- package/src/client/standalone/katex-style.ts +1 -0
- package/src/client/standalone/primitive-adapter.tsx +86 -0
- package/src/client/standalone/runtime.tsx +27 -0
- package/src/client/submission-registry.ts +150 -0
- package/src/client/svg-fence.tsx +39 -0
- package/src/client/table-details.ts +152 -0
- package/src/client/templates.ts +322 -0
- package/src/client/toolview.tsx +67 -0
- package/src/client/walk-spec.ts +43 -0
- package/src/css-modules.d.ts +5 -0
- package/src/index.ts +9 -0
- package/src/plugin/chart-contract.ts +13 -0
- package/src/plugin/fence-feedback.ts +701 -0
- package/src/plugin/genui-diagnostic.ts +112 -0
- package/src/plugin/index.ts +249 -0
- package/src/plugin/inline-content-diagnostic.ts +178 -0
- package/src/plugin/node-shims.d.ts +31 -0
- package/src/plugin/tool.ts +433 -0
- package/src/shared/fence-language.ts +30 -0
- package/src/shared/fence-repair.ts +572 -0
- package/src/shared/fence-resolve.ts +80 -0
- package/tsconfig.json +35 -0
- package/tsdown.config.ts +274 -0
package/ICON-NAMES.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# 图标名清单(全量 749 个)
|
|
2
|
+
|
|
3
|
+
> 本文件由 `scripts/generate-icon-data.mjs` 生成,请勿手改。
|
|
4
|
+
> 来源:OpenAI Apps SDK UI,commit `0f00143c7a639906f1621fe58e1b6be7b5bea46d`,MIT。
|
|
5
|
+
|
|
6
|
+
`icon` 节点接受下列任意名字(区分大小写)。未知名字渲染为中性圆点,
|
|
7
|
+
不会丢块,也不会触发下载。
|
|
8
|
+
|
|
9
|
+
不支持的嵌套 SVG 结构按整图排除(6 个):
|
|
10
|
+
- Document: unsupported nested SVG structure
|
|
11
|
+
- DownloadGifWatermark: unsupported nested SVG structure
|
|
12
|
+
- Linear: unsupported nested SVG structure
|
|
13
|
+
- OpenaiLogoBold: unsupported nested SVG structure
|
|
14
|
+
- OpenaiLogoRegular: unsupported nested SVG structure
|
|
15
|
+
- Zendesk: unsupported nested SVG structure
|
|
16
|
+
|
|
17
|
+
## 内联(64 个,无需下载)
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
Check CheckCircle Info InfoCircle Warning Error X Plus Minus ArrowDown ArrowUp ArrowRight ArrowLeft ArrowCurvedRight Function Functions Operator Atom Nodes Connect Share Branch Grid GridAlt Stack Cube Storage Chart Trending Pulse Speed Timer Clock TableFilled Code SquareCode Terminal File FileCode Folder Folders Link Paperclip Lightbulb Book BookOpen GraduationCap Flask Lab Brain Robot Sparkles ShieldCheck Lock Globe WebsiteNetwork Search MagnifyingGlassSearch PluginPuzzle Settings Bolt Compass Trash Report
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 按需载入(685 个)
|
|
24
|
+
|
|
25
|
+
首次用到非内联名字时,会一次性拉取 `lib/assets/icons.js`(约 1 MB),
|
|
26
|
+
此后本页全部可用。
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
AddMember AddSources Agent AgentMode AllGizmos AllProductsExplore Analytics AnalyzeData ApiKey ApiKeyAdmin ApiKeyServiceAccount ApiKeys Archive Array ArrowBottomLeftSm ArrowBottomRightSm ArrowCurved ArrowCurvedLeft ArrowCurvedRightXs ArrowCurvedRightXs24px ArrowDownLg ArrowDownSm ArrowLeftLg ArrowLeftSm ArrowRightLg ArrowRightSm ArrowRotateCcw ArrowRotateCw ArrowTopLeftSm ArrowTopRightSm ArrowUpLg ArrowUpRight ArrowUpSm AspectRatio11 AspectRatio169 AspectRatio34 AspectRatio43 AspectRatio916 Assistant Astronout AtSign AutoPairApps AutoSuggestedEdits Autocomplete AvatarFilledProfile AvatarProfile Back10s Back15s BackLarge BackSmall BackToApp BackgroundConversation BalancingScale BarChart BarChartFilled Batch Batches Bell BellFilled Beta Bills Blend BlendingCurveSharp BlendingCurveSmooth BlendingCurveSubtle BookBookmark BookClock BookClosed BookWrench Boolean BranchAlt Bug BuilderProfileCard BuildingWorkspace Business BusinessFilled Cabinet Calendar CalendarAlt CalendarToday Camera CameraFilledPhoto CameraPhoto CaptionCcOff CaptionCcOn CaptionOff CaptionOn Card CaretDown CaretLeft CaretRight CaretUp Category Certificate ChartXAxis ChartYAxis Chat ChatCompose ChatDashedCheckedTemp ChatDashedTemp ChatTemporary ChatTripleDots Chats CheckCircleDashed CheckCircleFilled CheckLg CheckMd ChevronDown ChevronDownLg ChevronDownMd ChevronDownUp ChevronDownVector ChevronLeft ChevronLeftLg ChevronLeftMd ChevronRight ChevronRightAlt ChevronRightLg ChevronRightMd ChevronSmallDown ChevronSmallLeft ChevronSmallRight ChevronSmallUp ChevronUp ChevronUpDown ChevronUpLg ChevronUpMd Circle CircleDashed CircleQuestion ClappingBoardClosed ClappingBoardOpen Cleanup Clear Click Clip Clipboard ClipboardCopy Clock10s Clock15s Clock20s Clock5s ClockOff CloseBold CodeSquareSlash Collapse CollapseLarge CollapseLeft CollapseLg CollapseRight CollapseSm CollapseSmall ColorTheme Comment Commit Compare CompareArrows Complete ComposeCanvasEditStar ComposeDashedTemporary ComposeEditSquare Confetti ConfettiParty ConnectApps ConnectedDynamicGpt ConnectorsConnectedApps Copy CreditCard Credits Cursor Customize DarkMode DataControls DeepSearchTelescope Delete DeleteAccount Desktop DiningEvents DisabledCursor Dock Documentation DollarCircle Dot DotsHorizontal DotsHorizontalCircle DotsHorizontalMoreMenu DotsVertical DotsVerticalCircle DotsVerticalMoreMenu DoubleChevronLeft DoubleChevronRight Download DownloadCircle DownloadSimple DownloadVideo DownloadVideoWatermark Dropdown DropdownVector Dumbbell EarthTravelWorld Edit EditAlt EditDalleImage EditPencil EditStar EditXs Education Email EmojiAdd EmojiLists EmojiRemove EmojiSections EmojiWords EmptyCircle EmptyCircleFilled EnterLogin Enum Equal ExclamationMarkCircle ExitLogout Expand ExpandLarge ExpandLg ExpandMd ExpandSm ExpandSmall Explore ExploreSora ExternalLink Eye EyeClosed EyeOff FeaturedWreath File3d FileAudio FileBlank FileDocument FileImage FilePresentation FileSpreadsheet FileSpreedsheet FileUpload FileVideo FileZip Filter FineTuning FistBump Flag Flash FlaskFilled FolderDocumentsFinder FolderOpen FolderPlus FolderPlusAdd FolderShared FolderSharedOpen FolderStuffed FolderUnshare Followup Forum Forward Forward10s Forward15s Frozen GenerateSuggestedEdits Glasses GlobeAltRealTimeSearch GlobeFilled GlobeOffRealTimeSearch GlobeRealTimeSearch GlobeSpin Go GoFilled Graduate Group GroupFilled Groups Hamburger HandBack HandFront HandPeace HandRaised HandRaisedHey HandWavingBye HapticFeedback Headphones Health Heart HeartFilled HeartFilledXs HeartXs Help History HistoryOff HistoryOn Home HomeAlt Identity IdentityMeSecure ImageCaption ImageSquare ImageSquarePictureLibrary ImageToText ImageWide ImageWideFilled ImageWidePictureLibrary Images Inkedin Inpaint InpaintRespond Inspiration InspirationFilled Instagram Interactiv InternalKnowledge InternalKnowledgeOptimizedForCircle Invoice Io Jira JumpToCaption Kettlebell Key Keyboard KeyboardShortcut Language Latency Lifesaver LightMode Lightbulb20 Lightbulb22 Lightbulb22Filled LightbulbGlow LinkDisabledBold LinkExternalWebsite LocalServices LockKeyHole Logout Loop LoopLong LoopNormal LoopShort LoopXs Lotus Love MagnifyingGlassSmSearch Mail ManageHistory MapPin Maps MapsAddress MapsDirections MarkerCode MarkerData MarkerMultiple MarkerQuote Mcp Members MembersFilled MemoryFilledSm MemoryOffRemember MemoryOnRemember MemoryWriteSm Menu MenuInverted MenuSidebar Menubar Messaging Mic MicFilled MicFilledOff MicLgDictate MicOff MinimizeDown MinimizeLeft MinimizeRight MinimizeTop MinusCircle MinusCircleFilled Mobile Moon MoonSunSystem MoreCircleMenuDots Music MyGptProfileMe Name NewsPaper NoTraining Notebook NotebookCheck NotebookNarrow NotebookPencil Notepad NotificationBell NotificationOffBell Number ObjectIcon On OpenLeft OpenRight OpenaiLogoBoldBoundingBox OpenaiLogoRegularBoundingBox OpenaiLogoWebappVariable480 Order PageBlank Paid PaperclipAttach ParentControl PastedText Pause PauseCircle PauseCircleFilled PauseOutline PauseSm Paw Pencil PencilSparkle PencilSquare Pens Phone PhoneMissed PhoneRing PhoneWaves PictureInPicture Pin PinFilled PinWindow Plane PlantDesk Play PlayCircle PlayCircleFilled PlayOutline PlaySm PlayTriangle Playground Plugin Plus14px PlusCircle PlusCircleAdd PlusCircleFilled PlusComposer PlusFilled PlusLg PlusLg18pxAdd PlusSm12px PlusSquareAdd PopOutWindow PresetDefault PresetSelected PrivacyIntern ProDiamond ProFilledDiamond ProductTag PullRequestClosed PullRequestDraft PullRequestMerged PullRequestOpen Question QuestionMark QuestionMarkCircle QuickStart Quote QuoteReplyFilledQuoteXs RadioSelected ReadingLevel Record Regenerate RegenerateOff RegenerateStar Reload RemixMild RemixMildXs RemixStrong RemixSubtle RemoveForeverPermanently RemoveRedEye Reply Resend ResetChat Resolution1080p Resolution360p Resolution480p Resolution720p RestoreUntrash Rewind RobotHead RobotHeadSad SavedFilledXs SavedXs Scales Scissor ScissorXs ScreenPosition SearchConnector SearchFeed SearchXs SelectText SettingsCircle SettingsCog SettingsSlider SettingsWrench ShareChat ShareScreen ShareScreenFilled ShareScreenOff ShareScreenOffFilled ShieldKey ShieldLock ShieldPerson ShoppingBag Shortcuts Shuffle Sidebar SidebarCollapseLeft SidebarCollapseRight SidebarFloatingLeft SidebarFloatingOpenLeft SidebarFloatingOpenRight SidebarFloatingRight SidebarLeft SidebarMenuMobile SidebarMenuMobileBadgeCutout SidebarOpenLeft SidebarOpenLeftAlt SidebarOpenRight SidebarOpenRightAlt SidebarRight SimpleRelax SimpleSad SimpleSmile Skip Sleep Snapchat Snorkle Snowflake SoraBasicPopcorn SoraProDirector SoundOffSimpleMute SoundOffSpeaker SoundOnReadOutLoudSpeaker Sparkle SparkleDouble SparkleFilledPlus SparklePlus SparklesFilled Speak SpeechToText SpeedometerLatencySpeed Spelling Spin SquareCheckCheckboxChecked SquareCheckFilledCheckboxCheckedFilled SquareCheckboxUnchecked SquareFilledTableLegend SquareImage SquarePlus SquarePlusAlt SquareTableLegend SquareText Star StarFilled StartStrokeMd Status Stethoscope StickyNote Stop StopCircle StopCircleFilled StopOutline StopSm StopStrokeMd Stopwatch Storyboard String Studio Stuff StuffTools SubscriptionPlan SuggestEdit Suitcase SuitcaseFilledWorkBusiness SuitcaseWorkBusiness Sun SystemMode TBoneRaw TableCellFilled TableCellsFilled TableColumnFilled TableRowFilled Tag Tap Tasks Telescope TerminalLg Terms Text TextLonger TextPrompt TextShorter TextShorterConcise TextToSpeech ThumbDown ThumbDownFilled ThumbMixed ThumbUp ThumbUpFilled ThumbnailLarge ThumbnailMedium ThumbnailSmall Thumbs Tiktok Tools ToolsSkills Translate TrashRemove TriangleExclamationErrorWarning TriangleExclamationFilledErrorWarning TrophyTop TuningFork Unarchive Undo Unlink Unpin Upgrade UpgradePlan UploadDocuments Upscale UpscaleXs Usage User UserAdd UserGpts UserHeart UserLock UserVoice Users Variation2v2 VariationV21 VariationV31 VariationV32 VariationV33 VariationV41 VariationV42 VariationV43 VariationV44 VersionsV1 Video VideoCaption VideoFilled VideoFilledOff VideoGrid VideoList VideoToText Videos Voice Voice4Bars Voice5BarsSoundwave VoiceBold VoiceInputAreaMobileFilledVoiceXs VoiceLight WarningFilledWrapCenteredForCircle WarningWrapCenteredForCircle Wave Wechat Whatsapp Whisk WhisperAutoSubmit Widget WidgetAdd WorkWithApps Workspace Wreath WriteAlt WriteAlt2 Writing XCircle XCircleCrossedClose XCircleFilled XCircleFilledCrossedClose XCrossed XSquareCrossed XSquareFilledCrossed XXs XXsCrossed Youtube
|
|
30
|
+
```
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-external
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,112 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-vt-gen-ui · VT GenUI 生成式界面
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
DeepSeek Harness(DSH)的生成式界面插件:模型在**回答正文**里写一段 ` ```dsh-ui ` 围栏,
|
|
4
|
+
渲染器把它画成可点、可填、可拖动的真实界面。协议与 50 个组件词汇沿用上游,视觉层按
|
|
5
|
+
「宿主正文的延伸」重做——关闭插件即回到普通 Markdown 代码块,会话不受影响。
|
|
6
|
+
|
|
7
|
+
## 它能做什么
|
|
8
|
+
|
|
9
|
+
- **四种渲染通道**:正文内联围栏(边流边渲染,组件 JSON 闭合一个上屏一个)、常驻面板
|
|
10
|
+
(`panel: true` 或 `/panel` 命令,原地更新、可调高度、支持追加)、工具卡 `render_ui`、
|
|
11
|
+
以及直接安全渲染的 ` ```svg ` 围栏。
|
|
12
|
+
- **50 个白名单组件**:标题/stat/表格/列表/图表/流程图/时间线/树/代码/JSON/diff/测验…
|
|
13
|
+
共 33 项资源上限;JSON 坏了或插件不在时**退回代码块**,不会破坏会话。
|
|
14
|
+
- **图表与图形**:bars / line / donut、ECharts、mermaid 流程图、公式绘图(可拖拽缩放、
|
|
15
|
+
参数滑杆与动画)、3D 场景。
|
|
16
|
+
- **本地交互与判分**:radio / checkbox / input / slider / 表单组件就地承载选择与填写;
|
|
17
|
+
`radio` + `answer` 组成的测验可以**本地判分**,不打扰模型。
|
|
18
|
+
- **面板与产出**:面板 dock、收藏模板、成就提示、导出(HTML / JSON)、复制原文。
|
|
19
|
+
- **模型侧配套**:自动注册 `genui` 技能(`SKILL.md`,一套完整的围栏语法与组件手册),
|
|
20
|
+
并提供 `validate_dsh_ui` 工具让模型**发出前**自检 JSON、拿到修复建议。
|
|
21
|
+
- **按需加载**:mermaid / three / ECharts / 749 个图标目录都是懒加载资产,只在用到时下载。
|
|
22
|
+
- **视觉层**:颜色只来自宿主 `--dsw-alias-*` token,深浅色双主题都要成立;
|
|
23
|
+
细节、判据与取舍见 [`DESIGN.md`](./DESIGN.md)。
|
|
24
|
+
|
|
25
|
+
> ⚠️ **不要与上游 `@changfenhuang/dsh-genui` 同时启用**:两者注册同一个 system prompt 段、
|
|
26
|
+
> 同一批工具、同一个会话 DOM 渲染器,第二个 `apply` 会直接抛错。
|
|
27
|
+
|
|
28
|
+
## 安装
|
|
29
|
+
|
|
30
|
+
插件装进某个 profile 后**必须重启 dsh**,刷新页面不生效。
|
|
31
|
+
|
|
32
|
+
**插件市场**(推荐,可在界面里看到更新提示)
|
|
33
|
+
在「插件 → 发现 → 添加索引源」填入:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
https://vontean.github.io/vt-dsh-plugin/index.json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
第一次使用市场要先在插件页开启 **Custom plugin markets**;然后在本插件条目上点安装。
|
|
40
|
+
市场里的「更新」是卸载再安装。
|
|
41
|
+
|
|
42
|
+
**npm**
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
dsh plugin --profile <profile> add dsh-vt-gen-ui@1.0.0
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Release tarball**
|
|
49
|
+
|
|
50
|
+
到 [Releases](https://github.com/Vontean/vt-dsh-plugin/releases) 下载
|
|
51
|
+
`dsh-vt-gen-ui-1.0.0.tgz`,然后:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
dsh plugin --profile <profile> add /绝对路径/dsh-vt-gen-ui-1.0.0.tgz
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**与上游共存时的切换顺序**(顺序不能反,否则重复注册抛错):先在插件页停用上游,或在 profile 里
|
|
58
|
+
`remove` 掉它,再装本插件;回滚时先停用本插件,再启用上游。
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# 装本插件前:先去掉上游
|
|
62
|
+
dsh plugin --profile <profile> remove @changfenhuang/dsh-genui
|
|
63
|
+
dsh plugin --profile <profile> add dsh-vt-gen-ui@1.0.0
|
|
64
|
+
|
|
65
|
+
# 回滚:先去掉本插件,再装回上游
|
|
66
|
+
dsh plugin --profile <profile> remove dsh-vt-gen-ui
|
|
67
|
+
dsh plugin --profile <profile> add @changfenhuang/dsh-genui@0.14.0
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 支持的 DSH 版本
|
|
71
|
+
|
|
72
|
+
`engines.dsh` = `>=0.2.1-rc.5 <0.3.0`。超出范围时 DSH 会在加载前拒绝该插件,不会带着
|
|
73
|
+
不兼容的代码跑起来;DSH 大版本升级后需要本插件跟进发布新版本。
|
|
74
|
+
|
|
75
|
+
## 安全边界
|
|
76
|
+
|
|
77
|
+
- 插件代码在**用户进程内**运行,**没有沙箱**,也没有额外权限边界:host 半边能读自身包目录
|
|
78
|
+
里的文件、能注册 HTTP 路由,client 半边能读写页面 DOM。只从你信任的来源安装。
|
|
79
|
+
- 本插件的网络行为仅限**本机自取自用**:懒加载引擎通过 `/plugins/dsh-vt-gen-ui/assets/*`
|
|
80
|
+
从插件自己的目录下载,不访问外部服务、不上传遥测。
|
|
81
|
+
- 交互状态、面板状态与成就计数存在浏览器 **localStorage**,不写系统文件;密码类
|
|
82
|
+
`input` 字段永不持久化。
|
|
83
|
+
- 围栏内容是**模型生成的**:其中的链接、图片、代码块会按 host 的既有规则渲染,模型说什么
|
|
84
|
+
不等于事实。`svg` 围栏经过安全过滤后才上屏。
|
|
85
|
+
|
|
86
|
+
## 开发
|
|
87
|
+
|
|
88
|
+
| 要做的事 | 先读 |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| 文件路由、硬约束(协议不可改的那部分) | [`AGENTS.md`](./AGENTS.md) |
|
|
91
|
+
| 视觉体系、token 与验收判据 | [`DESIGN.md`](./DESIGN.md) |
|
|
92
|
+
| 这个插件到底做了什么(能力全景) | [`docs/CAPABILITY-MAP.md`](./docs/CAPABILITY-MAP.md) |
|
|
93
|
+
| 50 个组件的字段表、渲染现状诊断、构建与安装契约 | [`docs/recon/`](./docs/recon/) |
|
|
94
|
+
| 749 个图标名 | [`ICON-NAMES.md`](./ICON-NAMES.md) |
|
|
95
|
+
| 模型看的语法手册 | [`SKILL.md`](./SKILL.md) |
|
|
96
|
+
| 仓库级约定(包名、bundle patch、市场信息) | [`docs/plugin-conventions.md`](../../docs/plugin-conventions.md) |
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
pnpm install
|
|
100
|
+
pnpm build # → lib/index.js(host)+ lib/client.js(浏览器)+ lib/assets/*
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
构建产物 `lib/` 必须一起提交:git 子目录安装与 Release tarball 直接读产物,不执行构建脚本。
|
|
104
|
+
装好之后,视觉层改动只需 `pnpm build`,浏览器约 0.5 s 内热替换(host 半边改动需重启应用)。
|
|
105
|
+
|
|
106
|
+
## 来源与许可
|
|
107
|
+
|
|
108
|
+
- 本包是 [`@changfenhuang/dsh-genui@0.14.0`](https://www.npmjs.com/package/@changfenhuang/dsh-genui)
|
|
109
|
+
的 fork,包名、bundle 行 id、模块 id 与资产路由都改成 `dsh-vt-gen-ui` 独占;
|
|
110
|
+
上游以 MIT 发布,归属说明见 [`THIRD_PARTY_NOTICES.md`](./THIRD_PARTY_NOTICES.md)。
|
|
111
|
+
- 内联图标来自 OpenAI Apps SDK UI(MIT),同样记录在 `THIRD_PARTY_NOTICES.md`。
|
|
112
|
+
- 本仓库代码以 MIT 发布,见 [`LICENSE`](./LICENSE)。
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: genui
|
|
3
|
+
description: "Render structured interactive UI inline through the dsh-ui fence. Use for key points, emphasis, comparisons, flows, steps, status, data, demos, and interactions whenever structured presentation would be clearer than prose. Preserve conversation language for all user-visible text."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GenUI — 生成式 UI 输出规范
|
|
7
|
+
|
|
8
|
+
**Language:** Match the user's requested language (otherwise the language of their message) in both surrounding prose and all user-visible UI text: titles, labels, content, options, and explanations. Chinese examples below illustrate the schema only; do not switch the conversation to Chinese after loading this skill. Keep JSON keys, component types, IDs, and actions unchanged. An English request gets English prose and UI text; a Chinese request gets Chinese prose and UI text. `<user-language ...>` tokens are meta-placeholders only. Replace every one with actual content in the conversation language; never emit these placeholders literally.
|
|
9
|
+
|
|
10
|
+
你可以**在回答正文中间**输出可交互 UI 组件:写一个 `dsh-ui` 围栏(fenced block with language tag `dsh-ui`),内含 JSON 规格,渲染器会把这一整块画成真实组件,文字照常穿插在前后。组件**就是回答的一部分**,不是工具调用。
|
|
11
|
+
|
|
12
|
+
```dsh-ui
|
|
13
|
+
{"title":"<user-language text>","gap":14,"items":[...]}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 围栏书写铁律(先读这一节)
|
|
17
|
+
|
|
18
|
+
围栏开头那一行的语言标记**统一写 `dsh-ui`**,不要添加标点、引号或注释。渲染器会容错大小写、首尾空格和部分尾部标点;其他语言标记不会作为 GenUI 接管,用户会看到普通代码块。
|
|
19
|
+
|
|
20
|
+
| 写法 | 结果 |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| ` ```dsh-ui ` | ✅ 渲染 |
|
|
23
|
+
| ` ```dsh-ui> ` | ✅ 容错渲染;生成时仍应去掉 `>` |
|
|
24
|
+
| ` ```dsh-ui ` 带行尾空格 | ✅ 渲染(自动 trim) |
|
|
25
|
+
| ` ``` DSH-UI ` | ✅ 渲染(忽略大小写) |
|
|
26
|
+
| ` ```dshui ` / ` ```ds-ui ` | ❌ 不是合法标记 |
|
|
27
|
+
|
|
28
|
+
此前同一模型曾在同一会话里写出 **182** 个 ` ```dsh-ui> ` 围栏并导致静默失效;现在已对这类尾部标点统一容错。写围栏时**只写 `dsh-ui` 这六个字符**,不要加任何标点、引号、注释;收尾必须是单独一行的 ` ``` `。
|
|
29
|
+
|
|
30
|
+
围栏位置:只写在**回答正文**里。写进 reasoning / 思考块不会渲染,用户看不到。
|
|
31
|
+
|
|
32
|
+
公式:`$...$` / `\(...\)` 为行内公式,`$$...$$` / `\[...\]` 为独立公式;支持矩阵、分段函数、多行对齐推导,以及加粗/高亮内的公式。正文、列表、键值、表头/单元格、卡片/步骤/时间线/标签页标题、题目与说明、按钮与表单标签、指标、媒体说明和图表外层标题共用此能力。JSON 字符串中的反斜杠必须双写,如 `"content": "\\(\\frac{a}{b}\\)"`。代码源码、输入值/占位符、原生下拉选项和图表引擎内部绘图文本仍遵循各自的原生格式,不解析富文本。数学语法以 KaTeX 为准,不执行 HTML、外部资源或脚本;不支持 LaTeX 文档编译、加载任意宏包。
|
|
33
|
+
|
|
34
|
+
## 组件词汇(只允许这些 type)
|
|
35
|
+
|
|
36
|
+
布局:`text` `row` `col` `grid` `card` `divider` `spacer` `arrow` `hero`
|
|
37
|
+
展示:`stat` `badge` `progress` `list` `table` `keyvalue` `avatar` `image` `audio` `video` `timeline` `file-tree` `breadcrumb` `diff` `json` `code` `callout` `steps` `icon` `blocks`
|
|
38
|
+
图表:`chart`(bars/line/donut,可多序列)`plot`(数学函数图)`echart`(ECharts 全功能图表)
|
|
39
|
+
交互:`button` `input` `select` `checkbox` `radio` `switch` `slider` `textarea` `tabs` `accordion` `copy` `link` `submit`
|
|
40
|
+
高级:`svg` `mermaid` `diagram` `scene3d` `quiz`
|
|
41
|
+
|
|
42
|
+
### 布局
|
|
43
|
+
- text: `{"type":"text","size":"display|h1|h2|h3|body|muted|caption","content":"...","align":"left|center|right"?}`(`tone:"danger|success|warning|info|muted"` 给整行文字上语义色,不用套 badge;`mono:true` 走等宽字体,用于十六进制/二进制/标识符,不带行内代码底色)(`size:"display"` 比标题大一档,作引言/开篇点题句,**一条回答 ≤1**;`center:true` 是旧写法,等价 `align:"center"`,新写一律用 `align`)
|
|
44
|
+
- row / col: `{"type":"row"|"col","items":[...],"wrap":true?,"spacer":true?,"gap":n?}`;`row.justify:"center"` 主轴居中(图标+标题那种图头);`col.width:n`(1-100)给这一列占行宽的百分比,不写就按内容宽
|
|
45
|
+
- grid: `{"type":"grid","cols":n,"items":[...]}`
|
|
46
|
+
- hero: `{"type":"hero","title":"<user-language title>","subtitle":"<user-language text>","value":"99.96%","label":"<user-language metric>","delta":"+0.02%","spark":[...],"tone":"accent|success|warning|danger"}` — **封面块**:eyebrow + 超大数字(52px,带入场计数)+ 标题 + 副标题 + tone 渐变底色。**一条回答最多用一个**,放在最前面当视觉锚点
|
|
47
|
+
- span: 任意节点都可加 `"span":2`(grid 子节点占几列)——bento 排版的唯一原语:一张 `span:2` 宽卡配一张窄卡,比一列方块堆下去好看得多
|
|
48
|
+
- card: `{"type":"card","title":"...","items":[...]}`;`"tone":"info|success|warning|danger"` 给卡片语义底色(用于结论卡/风险卡);`"accent":"#f59e0b"` 指定强调色(边框 + 标题 + 极淡底色);`"flat":true` 去掉阴影、换成极淡中性底——**图里的面板必须用 flat**,否则每层都像浮起的卡片,叠两层就脏了;`"eyebrow":"<user-language 小引题>"` 在标题上方加一行 meta 小字(把多张卡分章时用——**连续同章的卡片不要每张都加**,一段回答 ≤3 个)
|
|
49
|
+
- palette: `chart` / `echart` 都支持 `"palette":["#ff8800","#3ecf8e"]` 覆盖分类色板(默认跟随宿主主题)。**只有语义上需要指定颜色时才写**(成本=红、收益=绿),否则跟随主题更稳
|
|
50
|
+
- divider: `{"type":"divider"}`;**带章节名** `{"type":"divider","label":"<user-language 章节名>"}`(线 + 小标签居中,作章节切换:报告从摘要切入数据、图表册开新章时用一段;卡片/列表内部、连续同主题内容之间**不要用**,一条回答 ≤3 个); spacer: `{"type":"spacer"}`
|
|
51
|
+
|
|
52
|
+
### 展示
|
|
53
|
+
- stat: `{"type":"stat","label":"...","value":"...","delta":"+12.4%|-3%"}`(`-` 开头自动红、`+` 绿);可选 `"spark":[3,5,4,8,6]` 画一条微趋势线(2–60 个有限数值);`"size":"hero"` 渲染超大数字(一条回答最多用一次,作为视觉锚点)
|
|
54
|
+
- badge: `{"type":"badge","label":"...","tone":"success|warn|danger|accent","icon":"emoji?"}`
|
|
55
|
+
- progress: `{"type":"progress","label":"...","value":0-100,"valueLabel":"70%"}`;`"variant":"ring"` 画环形进度,`"target":70` 在轨道上标出目标刻度
|
|
56
|
+
- avatar: `{"type":"avatar","name":"...","color":"#hex?"}`
|
|
57
|
+
- image: `{"type":"image","src":"/mmx-files/result.png","alt":"<user-language description>"}` — 展示浏览器可访问的 http(s) 或同源相对图片地址;懒加载;不支持 `file:`/`data:` 等本地或主动协议;`"caption":"<user-language 图注>"` 在图**下方**加说明行(来源/解读/署名;`alt` 是图**上方**的标签行,两者分工不同)
|
|
58
|
+
- audio: `{"type":"audio","src":"/mmx-files/result.mp3","alt":"<user-language description>","loop":true?}` — 原生控制条;用户主动播放,不自动播放;仅 http(s) 或同源相对地址
|
|
59
|
+
- video: `{"type":"video","src":"/mmx-files/result.mp4","alt":"<user-language description>","poster":"/mmx-files/poster.jpg"?,"loop":true?,"muted":true?,"aspectRatio":"16:9|4:3|1:1|9:16"?}` — 原生播放/音量/全屏控制;不自动播放
|
|
60
|
+
- list: `{"type":"list","items":["..."] 或 [{"title":"...","desc":"..."}] 或嵌套节点(如 {"type":"badge","label":"TS"})}` — 行内可嵌节点(计入节点预算);记录中的 `label`/`name` 归一化为 `title`,`description`/`content`/`text`/`body`/`detail` 归一化为 `desc`;只有正文时将正文用作标题,未知字段会收到警告
|
|
61
|
+
- table: `{"type":"table","columns":["..."],"rows":[["...","..."]],"types":["text|num|delta|bar|badge"]?,"details":[[...]]?,"total":true?}` — 表头点击本地排序(升/降/还原,零往返);数值感知:千分位(`1,234`)、`k/m/b`、`万/亿`、`%`、货币符号都能按真实数值比较,纯数值列自动右对齐;**带符号单元格自动着色**(`+12.4%` 绿、`-3` 红,无需额外字段);`types` 可按列指定 `bar`(0-100 内联进度条)、`ring`(0-100 小环)、`spark`(单元格写 `"3,5,4,8"` 画微趋势线)、`badge`(胶囊标签)、`delta`(强制涨跌色)、`num`(强制右对齐)、`index`(行号)、`group`(首列当分组标题:该行只有第一格有内容时渲染成跨列小标题);`"total":true` 追加合计行(数值列自动求和);**`"export":true`**:表格上方出现「复制 Markdown / 复制 CSV」两个小按钮(纯本地剪贴板,不发请求);**`"filter":"输入框id"`**:把表格和某个 input/select 绑定,读者输入即时过滤(`filterColumn` 可限定列)——数据多时**默认就该配一个**;**`"sortField":"下拉id"`** 用下拉的值(列名)排序;**`"details"` 与 rows 同序**,第 i 项是该行展开后的内容(可放任意组件,`null` = 该行不可展开)——首列出现 chevron,点开在整行下方展开明细,适合「主表 + 明细」
|
|
62
|
+
- keyvalue: `{"type":"keyvalue","pairs":[{"key":"...","value":"..."}]}`
|
|
63
|
+
- timeline: `{"type":"timeline","items":[{"title":"...","desc":"...","time":"..."}]}`
|
|
64
|
+
- file-tree: `{"type":"file-tree","items":[{"name":"...","type":"file|dir","children":[...]?}]}` — 目录行可点击折叠/展开(本地,零往返)
|
|
65
|
+
- breadcrumb: `{"type":"breadcrumb","items":["<user-language text>","<user-language text>","<user-language text>"]}`
|
|
66
|
+
- diff: `{"type":"diff","diffs":[{"path":"...","oldText":"..."|null,"newText":"..."}]}`
|
|
67
|
+
- json: `{"type":"json","value":...}`(JSON 树查看器)
|
|
68
|
+
- code: `{"type":"code","lang":"ts","code":"..."}`
|
|
69
|
+
- callout: `{"type":"callout","tone":"info|success|warning|error","title":"...","content":"..."}` — 用于单条强调、提醒或风险摘要;`content` 是文本字符串,可用 JSON `"\n"` 分行。多条独立事项用 `list` 的 `{title,desc}` 保留逐项层次
|
|
70
|
+
- steps: `{"type":"steps","current":n,"steps":[{"title":"...","desc":"..."}]}`
|
|
71
|
+
- arrow: `{"type":"arrow","dir":"down|right","length":16-96,"label":"..."}` — 图里两个块之间的**细线连接件**(1.4px 线宽 + V 形箭头,固定长度)。上下流程图一律用它,**不要用文字「↓」**:字符箭头跟着文字基线走,撑不开间距
|
|
72
|
+
- icon: `{"type":"icon","name":"Nodes","tone":"info|success|warning|danger|muted|default","size":16|20|24|32,"tile":true,"label":"<user-language 无障碍名>"}` — 内置图标集(749 个可忠实渲染;64 个内联秒开,其余首次使用时载入,完整名单见 ICON-NAMES.md)。`tile:true` 画成**淡色圆角方底**,用于阶段卡/语义标记;不带 `tile` 是跟随文字色的行内图标。`label` 可省略(纯装饰),成对出现时只给一个加 label
|
|
73
|
+
- blocks: `{"type":"blocks","title":"...","rows":[{"label":"初始","cells":["0","1","2"],"color":"#64748b"}],"columns":n?,"caption":"..."}` — **色块图解**:按行分组的格子。三种形态同一个结构:① 阶梯图(每行格子数不同,各行自己等分宽度,如 8→4→2→1)② 等分块(一行 4 块)③ 泳道图(`columns` 固定列数,`cells` 里写 `"—"` 或留空)。`color` 省略时用强调色淡底;文字颜色按亮度自动反转(深底白字/浅底黑字)。**有「分成几份、逐轮推进、分组对照」的结构就用它,不要手写 svg 坐标。** `caption` 必写:一句话说明每格代表什么
|
|
74
|
+
- 行级 `"variant":"outline"`:细边框不填充,用于**矩阵**(每格都是一个框);`"variant":"plain"`:连框都不画,用于**位串**(`1 0 1 0 0 0 0 0` 读起来是数字不是表格)——只有带 `tone`/`color` 的格子会画出底色
|
|
75
|
+
- 格子可以写成对象:`{"text":"1","tone":"danger","sub":"SF"}` —— `tone`(accent/success/warning/danger/muted)给**单个格子**上语义色,`sub` 在格子下方挂一行小字(位名、序号、角色)。`color` 可显式指定十六进制,优先于 tone
|
|
76
|
+
- 例:`{"columns":8,"rows":[{"variant":"outline","cells":[{"text":"1","tone":"danger","sub":"SF"},"0","1","1","0","0","1","0","0"]}],"caption":"最高位为 1,所以 SF=1。"}`
|
|
77
|
+
|
|
78
|
+
内置图标名:以下 **64 个内联在包里、立即渲染**,优先从这里面选:
|
|
79
|
+
|
|
80
|
+
Check CheckCircle Info InfoCircle Warning Error X Plus Minus Circle ArrowDown ArrowUp ArrowRight ArrowLeft ArrowCurvedRight Function Functions Operator Atom Nodes Connect Share Branch Grid GridAlt Stack Cube Storage Chart Trending Pulse Speed Timer Clock TableFilled Code SquareCode Terminal File FileCode Folder Link Paperclip Lightbulb Book BookOpen GraduationCap Flask Lab Brain Robot Sparkles ShieldCheck Lock Globe WebsiteNetwork Search MagnifyingGlassSearch PluginPuzzle Settings Bolt Compass
|
|
81
|
+
|
|
82
|
+
其余 **685 个按需载入**(首次用到时拉取约 1 MB,此后本页全部可用)。完整名单在本 SKILL 同目录的 `ICON-NAMES.md`——需要猜名字时读它或 grep 它,不要在对话里穷举。
|
|
83
|
+
### 图表
|
|
84
|
+
- chart: `{"type":"chart","title":"...?","kind":"bars|line|donut","data":[{"label":"...","value":n,"color":"#hex?"}],"series":[{"label":"...","data":[...]}]?,"horizontal":true?}` — bars 默认;line 趋势;donut 占比;**series:bars 是分组柱,line 是多序列折线;每个 `series[].data` 使用 `[{"label":"Q1","value":30},{"label":"Q2","value":45}]` 这样的对象数组,不是 `[30,45]` 这样的纯数字数组**;**`horizontal:true` 画横向柱**(排行/长标签首选);**`stacked:true` 把 series 堆叠**(构成/占比随时间);堆叠段够高时数值直接印在段内,鼠标悬停任意柱/段/点/扇区都会弹出即时 tooltip(堆叠显示该段数值 + 合计)。v3 渲染:宽度自适应、Y 轴 1/2/5 刻度、单序列负值在零线以下真实绘制、line 带面积渐变与抽稀 X 标签、donut 图例显示数值与百分比。`title` 会显示在图上方(与 echart / plot 同一排版);**≤8 个点的快速对比用 chart;多序列、需要缩放/交互或数据量大时用 echart**
|
|
85
|
+
- plot: `{"type":"plot","series":[{"expr":"a*sin(b*x)","label":"...","color":"#hex?","params":[{"name":"a","value":1,"min":0,"max":5,"animateTo":3,"durationMs":4000,"loop":true},{"name":"b","value":1,"min":0.5,"max":5}]}],"xMin":-6.28,"xMax":6.28,"title":"..."}` — SVG 函数图;**series 可带 `"kind":"line|area|scatter"`**(缺省 line;area 填色到基线;scatter 散点);**params 渲染成实时滑块**(拖动即时重绘,**y 轴锁定**=只变曲线不变数轴);**animateTo 参数会显示播放按钮**(自动动画演示);SVG 可拖拽平移、滚轮缩放;表达式支持 sin/cos/tan/asin/acos/atan/sqrt/cbrt/exp/log/ln/abs/floor/ceil/round/min/max/pow,常量 pi/e/tau,变量 x(其他字母=参数)
|
|
86
|
+
- echart: `{"type":"echart","title":"...","height":300,"preset":"bar|line|area|pie|scatter","data":[{"label":"...","value":n}],"series":[...]?}` — **ECharts 全功能图表**,视觉效果远超 `chart`(渐变、tooltip、动画、图例交互);**preset 模式**:用和 `chart` 一样的 `data`/`series` 格式,自动构建主题化的 ECharts 配置(颜色跟随宿主主题);**preset 一览**(只写 preset + data/series/links,主题自动跟随):
|
|
87
|
+
`bar` · `line` · `area` · `pie` · `scatter` · **`radar`**(每 series 一个多边形,指标取第一条 series 的 label)· **`gauge`**(每个 datum 一个仪表,适合单 KPI)· **`funnel`**(漏斗/转化)· **`treemap`**(体积/层级占比)· **`sankey`**(流向,用 `links:[{from,to,value}]`)· **`graph`**(关系图,`links` 驱动,节点大小随连接数)· **`heatmap`**(`series` 当行、第一条 series 的 label 当列)· **`bigline`**(长序列 + 内置缩放)· **`wordCloud`**(词云,`data:[{label,value}]` 的 value 表示权重;颜色跟随 `palette` 或主题调色板)
|
|
88
|
+
**full option 模式**:传 `"option":{...}` 直接写 ECharts 原生配置(支持 ECharts 内置图表及已注册的 `wordCloud` 词云扩展;其他第三方扩展不保证可用),option 中的函数会被过滤(只接受数据)。选择原则:**chart 轻量(无额外下载)适合 ≤8 点的快速对比;echart 视觉更丰富(渐变、tooltip、图例交互、dataZoom),但会按需下载约 1MB 引擎,多序列/大屏/交互场景优先**
|
|
89
|
+
|
|
90
|
+
### 交互
|
|
91
|
+
**本地优先(v2.6)**:UI 自己能做的状态变化——判卷、判题、重置、展开、选中——一律本地即时完成,**零模型往返**。action 只用于必须模型参与的事(生成新内容、执行工具、下一步建议)。**交互组件必须带 action:不带 action 的按钮渲染为禁用态,用户点不了;带 action 的按钮点击后有「已触发」本地反馈。**
|
|
92
|
+
- button: `{"type":"button","label":"...","tone":"primary|danger|success|ghost","full":true?,"small":true?,"icon":"emoji?","action":"refresh"?}`
|
|
93
|
+
- **秘密禁令**:不得索取或生成密码、API Key、访问令牌、恢复码等秘密输入;遇到此类需求直接拒绝并解释
|
|
94
|
+
- input: `{"type":"input","label":"...","placeholder":"...","inputType":"text|email|color","value":"...","action":"name"?,"id":"field-id"?}` — `color` 使用浏览器原生取色器,值使用 `#RRGGBB`;action 在失焦**和回车**时触发(回车带 `submit:true`);**blur 仅值有变化才发送**(聚焦又离开不产生空往返);payload 带 `id` 帮模型定位字段;带 `id` 的值刷新后保留、并被 submit 收集进 `fields`
|
|
95
|
+
- select: `{"type":"select","label":"...","options":["...","..."],"selected":下标?,"action":"pick"?,"id":"field-id"?}` — `selected` 预选某选项(缺省显示「请选择…」占位,不静默预选第一项);带 `id` 的选择跨刷新保留并进 submit 的 `fields`
|
|
96
|
+
- checkbox: `{"type":"checkbox","label":"<user-language option>","checked":true?,"action":"toggle"?,"group":"group-id"?}` — 默认保持逐次 `action` 行为;**加 `group` 进入多选聚合模式**:同组 checkbox 可反复勾选/取消,变化只在本地记录、不发逐次 action,兄弟 `submit` 一次性把该组已选 label 作为字符串数组放进 `answers`(例如 `{"styles":["<user-language option>","<user-language option>"]}`)
|
|
97
|
+
- slider: `{"type":"slider","label":"...","min":0,"max":100,"step":1,"value":n?,"action":"name"?,"id":"field-id"?}` — 数值表单滑块:实时显示数值;带 `id` 跨刷新保留并进 submit 的 `fields`(拖拽经防抖合并成一次 action)
|
|
98
|
+
- radio: `{"type":"radio","label":"<user-language label>","options":["<user-language option>","<user-language option>"],"selected":n?,"action":"pick"?}` — 单选;**加 `"group":"group-id"` 进入聚合模式**:选择只本地记录、不发往返;可设置 `"answer":正确下标或标签` 和 `"explanation":"<user-language explanation>"`,在纯 radio 且没有其他待发送表单状态时本地判卷
|
|
99
|
+
- link: `{"type":"link","label":"...","href":"https://..."?}` — 仅 http(s)/mailto 协议被接受;无 `href` 时渲染为纯文本样式(不会假装可点)
|
|
100
|
+
- submit: `{"type":"submit","label":"<user-language action>","action":"grade","groups":["q1","styles"],"resetAction":"redo"?}` — 聚合按钮:`groups` 引用当前 block 中的 submission member key,来源为 `radio.group`、`checkbox.group`、`input.id`、`textarea.id`、`select.id`、`slider.id`;radio 需已选择,checkbox 组需至少选择一项,普通 field 的值需在 trim 后非空。`groups` 控制提交所需成员与完成进度;未设置时,至少有一个已完成成员即可提交。纯 radio 范围含 `answer` 且本次没有范围外 payload 时可本地判卷;其余场景一次发送 `[genui-action]`,payload 继续收集当前 block 中已填写的表单状态,字段名称保持 `answers`、`fields`、`total`、`answered`
|
|
101
|
+
- switch: `{"type":"switch","label":"...","checked":true?,"action":"toggle"?}`
|
|
102
|
+
- textarea: `{"type":"textarea","label":"...","placeholder":"...","rows":n?,"value":"...","action":"save"?,"id":"field-id"?}` — action 在失焦和 **Ctrl/Cmd+Enter** 时触发;blur 仅值有变化才发送;带 `id` 的值刷新后保留
|
|
103
|
+
- tabs: `{"type":"tabs","tabs":[{"label":"...","items":[...]}]}` — 空 tab 可以省略 `items`,会按空数组处理
|
|
104
|
+
- accordion: `{"type":"accordion","items":[{"title":"...","items":[...]}]}`
|
|
105
|
+
- copy: `{"type":"copy","label":"<user-language action>","text":"<user-language text>","expandable":true?,"previewLines":n?}` · [docs/copy-preview.md](docs/copy-preview.md)
|
|
106
|
+
|
|
107
|
+
**状态持久化(v2.7)**:radio 答案、checkbox 分组选择、交卷锁定、输入值按「会话 + 内容指纹」自动保存——用户刷新页面/重开会话,同一块 UI 的状态原样恢复;你重渲染**相同内容**会保留用户状态,渲染**新内容**(换题等)自动从头开始。
|
|
108
|
+
|
|
109
|
+
**卷子模式(多道选择题)**:每题一个 radio(带唯一 `group` + `answer` + `explanation`),最后放一个 submit(`groups` 列出全部题号)——用户全部选完点交卷,**分数和对错当场在 UI 里出现**,不用等你。只有换新题/进阶建议才发 action。不要每题单独发 action(会刷屏)。
|
|
110
|
+
|
|
111
|
+
### 高级
|
|
112
|
+
- svg: `{"type":"svg","title":"<user-language title>","height":300,"code":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 200 100\"><rect width=\"200\" height=\"100\" fill=\"#534ab7\"/></svg>"}` — 独立 SVG 图片预览;`title`/`height` 可省略,height 为 100–800,code 最多 12,000 字符。必须提供完整 SVG 文档(含 xmlns),建议带 viewBox。使用隔离图片模式,不支持脚本、宿主 CSS 或外部资源;图形无法加载时显示源码和提示。**放在 dsh-ui 围栏中;这不是 ECharts renderer 配置。**
|
|
113
|
+
- 也可以直接输出 ```svg 代码围栏(不带 dsh-ui 包装):会自动显示为「预览/源码」切换的图形预览,源码可复制;无法解析时保留源码并提示。
|
|
114
|
+
- mermaid: `{"type":"mermaid","code":"graph TD\\nA-->B"}` — flowchart/sequence/class/gantt/pie/er/state/journey;主题自动跟随宿主(暗/浅)
|
|
115
|
+
- diagram: `{"type":"diagram","kind":"architecture","title":"<user-language title>","variant":"light|dark|editorial","nodes":[...],"edges":[...],"theme":{...}}` — **编辑级品牌图**(移植自 diagram-design 的 27 种视觉类型)。节点: `{"id":"a","label":"<user-language label>","type":"focal|backend|store|external|input|optional|security","x":40,"y":40,"w":128,"h":48,"sub":"<user-language text>","tag":"<user-language text>"}`;边: `{"from":"a","to":"b","label":"<user-language label>","kind":"solid|dashed|accent|link"}`。**规则由渲染器强制**: 正交连接器(r=8 弯折、禁止斜线)、4px 网格、语义 token(paper/ink/muted/accent)、焦点色 ≤2 个、复杂度预算(≤9 节点/≤12 边)、z-order(箭头在节点后)、边标签 6-10px 间隙。27 种 kind:architecture / it-state / flowchart / sequence / state / er / timeline / swimlane / quadrant / radar / loop / nested / tree / org-chart / layers / venn / pyramid / bar / line / gantt / scatter / high-level / process / medallion / data-flow / dp-integration / dp-security-matrix。**坐标类 kind**(architecture/it-state/high-level/process/medallion/data-flow/dp-integration)用 x/y/w/h 精确定位;**规则类 kind** 只给数据自动排版。架构/流程/层次结构优先用 diagram 而非 mermaid(自动布局用 mermaid,编辑级排版用 diagram)。
|
|
116
|
+
- scene3d: `{"type":"scene3d","title":"...","meshes":[{"shape":"box|sphere|cone|cylinder|torus","color":"#hex?","size":n|[w,h,d]?,"position":[x,y,z]?,"rotation":[rx,ry,rz]?,"scale":n?|[...]?}],"ambient":0-2?,"background":"#hex?"}` — 3D WebGL,可拖拽旋转、滚轮缩放;mesh 数量 1–5 个
|
|
117
|
+
- quiz: `{"type":"quiz","question":"...","options":[{"label":"...","correct":true?,"feedback":"..."?}],"explanation":"...","id":"..."?,"action":"answer"?}` — 教学问答:点选即判题、可重试;`id` 变化时重置;带 action 时另回传 `{type:'quiz',question,answer,correct}`
|
|
118
|
+
|
|
119
|
+
## 什么时候用:内容类型 → 组件映射
|
|
120
|
+
|
|
121
|
+
**判断口诀**:这段内容换成结构化组件,会不会比纯文字更好扫、更好懂、更好操作?会 → 就用,**不需要等用户开口要 UI**。
|
|
122
|
+
|
|
123
|
+
**硬触发(出现就至少出一个围栏,不要退回纯文字段落)**:
|
|
124
|
+
- ≥3 条并列要点 → `list`;≥2 组数字对比 → `table`;指标/进度/状态 → `stat`/`progress`/`badge`
|
|
125
|
+
- 步骤/时间线 → `steps`/`timeline`/`mermaid`;架构/流程 → `diagram`/`mermaid`;单条风险/结论摘要 → `callout`;代码/改动 → `code`/`diff`/`json`
|
|
126
|
+
- 趋势/占比 → `chart`(≤8 点)或 `echart`(多序列/要交互/数据量大)
|
|
127
|
+
- 收尾自检:回答超过约 10 行时确认至少有一个围栏;同一份信息不要既写文字又重复出组件;纯问答不套 UI。
|
|
128
|
+
|
|
129
|
+
| 你要呈现的内容 | 用这些组件 |
|
|
130
|
+
|---|---|
|
|
131
|
+
| 并列结论 / 要点罗列(≥2 条) | `list`、`keyvalue` |
|
|
132
|
+
| 单条重点强调 / 警告 / 注意事项 | `callout`(info/success/warning/error)、`badge`、`stat` |
|
|
133
|
+
| 多项风险 / 注意事项 | `list`;需要统一风险底色时用 `card.tone` + `list` |
|
|
134
|
+
| 数据对比 / 趋势 / 占比 | `chart`(bars/line/donut)、`echart`(ECharts 全功能)、`table` |
|
|
135
|
+
| 关键指标数字 / 进度状态 | `stat`、`progress`、`badge` |
|
|
136
|
+
| 回答的视觉锚点(第一个组件) | `hero`(封面块,一条回答最多一个) |
|
|
137
|
+
| 想排版不呆板 | `grid` + 子节点 `span`(bento:宽窄混排) |
|
|
138
|
+
| 数据多、需要读者自己找 | `input`(id)+ `table`/`chart`/`list` 的 `filter` 绑定 |
|
|
139
|
+
| 流程 / 步骤 / 阶段 / 时间线 | `steps`、`timeline`、`mermaid`(flowchart/sequence/gantt) |
|
|
140
|
+
| 架构 / 系统拓扑 / 数据流 / 品牌图 | `diagram`(编辑级,27 种类型;自动布局需求才用 `mermaid`) |
|
|
141
|
+
| 目录 / 文件结构 / 层级关系 | `file-tree`、`mermaid`、`accordion` |
|
|
142
|
+
| 状态一览 / 检查结果 | `badge` + `table` + `progress` 组合 |
|
|
143
|
+
| 代码 / 配置 / 改动对比 | `code`、`diff`、`json` |
|
|
144
|
+
| 图片 / 截图 / 图表预览 | `image` |
|
|
145
|
+
| 语音 / 音乐 / AI 视频 / 演示录像 | `audio`、`video` |
|
|
146
|
+
| 两个方案 / 选项对比 | `table`、`tabs`、`diff` |
|
|
147
|
+
| 教学 / 自测 / 判断题 | `quiz` |
|
|
148
|
+
| 数学函数 / 曲线关系 | `plot`(可带参数滑块、动画) |
|
|
149
|
+
| 需要用户操作 / 筛选 / 反馈 | `button`、`input`、`select`、`checkbox`、`radio`、`switch`、`tabs` |
|
|
150
|
+
| 3D 物体 / 空间布局 | `scene3d` |
|
|
151
|
+
|
|
152
|
+
多项风险需要统一底色时,复用 `card` 包含 `list`;普通要点直接用 `list`。卡片的严重风险色是 `danger`,提示框对应的是 `error`。
|
|
153
|
+
|
|
154
|
+
```json dsh-ui
|
|
155
|
+
{"items":[{"type":"card","tone":"warning","title":"<user-language risk summary>","items":[{"type":"list","items":[{"title":"<user-language item title>","desc":"<user-language description>"},{"title":"<user-language item title>","desc":"<user-language description>"},{"title":"<user-language item title>","desc":"<user-language description>"}]}]}]}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**别用的情况**:一句话能说清的事、纯闲聊、用户明确说不要 UI、以及"为了炫技硬塞"——组件服务内容,不是内容服务组件。
|
|
159
|
+
|
|
160
|
+
## 行内富文本(文字类回答的底座)
|
|
161
|
+
|
|
162
|
+
`text.content`、`list` 项、`table` 文本列、`keyvalue` 值、`callout` 标题与正文里可以直接写四种行内标记——**重点留在句子里,不必为一个词单起一个组件**:
|
|
163
|
+
|
|
164
|
+
| 写法 | 渲染 |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `` `code` `` | 行内代码胶囊 |
|
|
167
|
+
| `**加粗**` | 强调(不换行、不成块) |
|
|
168
|
+
| `==高亮==` | 极淡底色标记 |
|
|
169
|
+
| `[文字](https://…)` | 行内链接(http/https/mailto;围栏会话中的本地文件链接支持右侧栏打开与行号定位;无效目标及独立 HTML artifact 中的本地文件链接显示为普通文字) |
|
|
170
|
+
| JSON `"\n"`(真实换行符) | 换行——**多段文字写同一个字段**,不要为换行拆成多个节点 |
|
|
171
|
+
|
|
172
|
+
不嵌套、不解析 HTML(每个标记生成 React 元素,不走 innerHTML;`<br>` 字面显示,换行用 `"\n"`);标记没闭合时原样显示。表格文本、`badge`、`delta` 单元格只识别本地文件链接,外部链接与无效目标显示为普通文字;`bar`、`spark`、`ring`、`index` 等专用数值单元格保持原有展示。
|
|
173
|
+
|
|
174
|
+
文字字段只支持行内富文本。`text.content`、`callout.content`、`list` 项、`keyvalue` 值、`table` 单元格等字段中不要嵌入 Markdown 表格或连续三个及以上反引号、波浪号组成的代码围栏;表格使用 `table`,代码使用 `code`,代码改动使用 `diff`,结构化 JSON 使用 `json`。误写入文字字段的代码围栏连同内部标记保持原文,未闭合时从围栏标记开始保持原文。`validate_dsh_ui` 返回 `warning=block_markdown` 时,按照 `replacement` 改写结构节点并重新验证。
|
|
175
|
+
|
|
176
|
+
## 回答级版式:默认无卡,焦点唯一
|
|
177
|
+
|
|
178
|
+
**规则来自设计规范,不是口味**(`design` skill 的 `references/design-reference.md`):
|
|
179
|
+
「通用圆角矩形卡片当默认容器 = 模板思维,默认无卡;只有内容类型确实需要时才加卡片处理」,
|
|
180
|
+
「如果替换内容不需要改布局,那就是模板,重做」。
|
|
181
|
+
|
|
182
|
+
### 三条判据(不设组件数量上限)
|
|
183
|
+
|
|
184
|
+
1. **必要性**:这个组件承载的信息,用文字表达会明显更差吗?数字对比、趋势、空间关系、代码/数据原文才算过关,否则删掉。
|
|
185
|
+
2. **焦点唯一**:一条回答只有一个视觉焦点(最大那张图或那组数字);其余组件的视觉权重必须明显更低,靠尺寸/位置/色彩强度拉开,**不是靠数组件个数**。
|
|
186
|
+
3. **不重复**:同一批数据不做两种表达(表格与图表二选一)。
|
|
187
|
+
|
|
188
|
+
### 卡片(`card`)只在有明确用途时用
|
|
189
|
+
|
|
190
|
+
- 需要**并排**的 `grid` 子项(没有边界就分不清内容归属);
|
|
191
|
+
- 承载**数据对象**:表格、图、keyvalue、指标组;
|
|
192
|
+
- 同组风险需要**统一语义底色**:`card.tone` 包含 `list`,保留逐项标题与说明。
|
|
193
|
+
|
|
194
|
+
普通单段文字、普通列表、已经自带边界的表格/图表,**不要包卡**。用 `h3` 标题 + 正文 + 间距代替。
|
|
195
|
+
|
|
196
|
+
### 层级靠字,不靠框
|
|
197
|
+
|
|
198
|
+
- 卡片标题 16px / 字重 650 / 句首大小写(**不是** 12.5px 全大写小标签);
|
|
199
|
+
- 12.5px 全大写只用于 eyebrow(如 hero 上方那一行);
|
|
200
|
+
- 大字号带负字距(≥32px 约 -0.022em,20–28px 约 -0.012em),数字列 `tabular-nums`;
|
|
201
|
+
- CJK 正文行高 1.7,长段落行宽 ≤68ch;
|
|
202
|
+
- 表面对比遵循规范:浅色相邻表面明度差 ≥4%,或阴影 ≥ `0 1px 3px rgba(0,0,0,0.10)`;深色靠半透明白叠加(卡片约 4%,抬升面 8%),投影在深色几乎无效。
|
|
203
|
+
|
|
204
|
+
### 不要
|
|
205
|
+
|
|
206
|
+
- 装饰性编号(①②③):该分点用 `list`,该分节用标题;
|
|
207
|
+
- 同一套骨架每条回答复用(标题栏 → 卡片网格 → 表格 → callout);
|
|
208
|
+
- 为了"显得丰富"堆组件:读者找不到重点就是失败。
|
|
209
|
+
|
|
210
|
+
### 怎么验证没模板化
|
|
211
|
+
|
|
212
|
+
`node scripts/genui-usage-audit.mjs` 输出「版式多样性」:不同版式签名数、最常见签名占比、归一化熵(越接近 1 越多样)、每回答 card 数分布。熵明显下降或 card 数不降反升,就说明规则没生效。
|
|
213
|
+
|
|
214
|
+
## 范例:示范「判断」,不要照抄组件序列
|
|
215
|
+
|
|
216
|
+
每个范例后面都跟着**什么时候不要这样**。组件多是好事——只要每个都在承载不同信息、并且有焦点和层次;真正的毛病是重复表达、以及把纯文字段落包进卡片。
|
|
217
|
+
|
|
218
|
+
### 1. 状态汇报(多点 + 有构图)
|
|
219
|
+
|
|
220
|
+
```json dsh-ui
|
|
221
|
+
{"items":[{"type":"grid","cols":4,"items":[{"type":"stat","label":"<user-language metric>","value":"26","delta":"#123–#148"},{"type":"stat","label":"<user-language metric>","value":"0"},{"type":"stat","label":"<user-language metric>","value":"556","delta":"<user-language status>"},{"type":"stat","label":"<user-language metric>","value":"45"}]},{"type":"table","columns":["<user-language column>","<user-language column>","<user-language column>"],"types":["text","badge","text"],"rows":[["<user-language text>","<user-language status>","<user-language text>"],["<user-language text>","<user-language status>","<user-language text>"]]},{"type":"callout","tone":"info","title":"<user-language title>","content":"<user-language text>"}]}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
不要这样:把同一句话既写进正文又放进卡片;也不要为每条信息配一张卡(4 个 stat 排一行就够)。
|
|
225
|
+
|
|
226
|
+
### 2. 解释/教学(文字为主,一个点睛组件)
|
|
227
|
+
|
|
228
|
+
```json dsh-ui
|
|
229
|
+
{"items":[{"type":"text","size":"body","content":"<user-language text>"},{"type":"list","items":[{"title":"<user-language title>","desc":"<user-language description>"},{"title":"<user-language title>","desc":"<user-language description>"}]},{"type":"callout","tone":"warning","title":"<user-language title>","content":"<user-language text>"}]}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
不要这样:每段都配一个组件;把一句话拆成好几个 text 节点(用行内标记就够了)。
|
|
233
|
+
|
|
234
|
+
### 3. 对比选型
|
|
235
|
+
|
|
236
|
+
```json dsh-ui
|
|
237
|
+
{"items":[{"type":"table","columns":["<user-language column>","<user-language column>","<user-language column>"],"types":["text","text","badge"],"rows":[["<user-language text>","<user-language text>","<user-language status>"],["<user-language text>","<user-language text>","<user-language status>"]]},{"type":"callout","tone":"success","title":"<user-language title>","content":"<user-language text>"}]}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
不要这样:表格里放同一批数据后又画一张图。
|
|
241
|
+
|
|
242
|
+
反例(这条会被围栏校验直接拒绝,所以别抄):
|
|
243
|
+
|
|
244
|
+
```json dsh-ui-bad
|
|
245
|
+
{"items":[{"type":"chart","kind":"donut","data":[{"label":"A","value":1}],"series":[{"label":"B","data":[{"label":"B","value":2}]}]}]}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
为什么拒:`series` 只对 `bars`/`line` 有效;环形图给了 `series` 属于契约冲突,围栏会**静默降级为代码块**。
|
|
249
|
+
|
|
250
|
+
### 4. 排查诊断(顺序即叙事)
|
|
251
|
+
|
|
252
|
+
```json dsh-ui
|
|
253
|
+
{"items":[{"type":"steps","current":1,"steps":[{"title":"<user-language step>","desc":"<user-language description>"},{"title":"<user-language step>","desc":"<user-language description>"},{"title":"<user-language step>","desc":"<user-language description>"}]},{"type":"diff","diffs":[{"path":"PlotBlock.tsx","oldText":"e.preventDefault()","newText":"if (!e.metaKey && !e.ctrlKey) return"}]},{"type":"callout","tone":"info","title":"<user-language title>","content":"<user-language text>"}]}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
不要这样:把"复现/定位/修复"写成三个卡片并列(那是流程,用 steps)。
|
|
257
|
+
|
|
258
|
+
### 5. 数据结论(一个主图 + 明细)
|
|
259
|
+
|
|
260
|
+
```json dsh-ui
|
|
261
|
+
{"items":[{"type":"chart","kind":"line","data":[],"series":[{"label":"<user-language series>","data":[{"label":"<user-language point>","value":8},{"label":"<user-language point>","value":12},{"label":"<user-language point>","value":9}]}]},{"type":"table","columns":["<user-language column>","<user-language column>","<user-language column>"],"types":["text","num","delta"],"rows":[["<user-language text>","8","-4%"],["<user-language text>","12","+50%"]]}]}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
不要这样:图与表用同一粒度表达同一批数据(图看趋势、表看明细才不重复)。
|
|
265
|
+
|
|
266
|
+
### 6. 短回答:正确地不套组件
|
|
267
|
+
|
|
268
|
+
> 这个改动我先不做了——它要动宿主的输入组件,而你说了不碰宿主。
|
|
269
|
+
|
|
270
|
+
不要这样:一句话的结论配 stat + 表格 + callout。**没有内容就不发组件,这是对的,不算漏发。**
|
|
271
|
+
|
|
272
|
+
## 编排范式:高频场景的默认起点
|
|
273
|
+
|
|
274
|
+
范式是**验证过的起点,不是模板**:判断永远优先(上一节的「不要照抄」同样适用于范式)。六个范式各管一类高频场景——**数据问答**用「主表明细」、**分析收尾**用「结论卡」、**报告开篇**用「封面页」、**方案权衡**用「对比页」、**过程复盘**用「时间线叙事」、**教学自测**用「测验页」。从成套结构出发、按需增删;范式之外的场景自由组合。
|
|
275
|
+
|
|
276
|
+
### 阶段图(讲清「分几步 / 怎么变」的默认结构)
|
|
277
|
+
|
|
278
|
+
适用:一个过程有 2–4 个阶段,或一份数据被分成若干块、逐轮合并。
|
|
279
|
+
|
|
280
|
+
```json dsh-ui
|
|
281
|
+
{"items":[{"type":"text","size":"h2","content":"<user-language 过程名>"},{"type":"card","items":[{"type":"row","items":[{"type":"icon","name":"Function","tone":"info","tile":true},{"type":"col","gap":2,"items":[{"type":"text","size":"h3","content":"<user-language 阶段一:名称>"},{"type":"text","size":"muted","content":"<user-language 这一步做什么>"}]}]},{"type":"arrow","length":22},{"type":"row","items":[{"type":"icon","name":"Nodes","tone":"success","tile":true},{"type":"col","gap":2,"items":[{"type":"text","size":"h3","content":"<user-language 阶段二:名称>"},{"type":"text","size":"muted","content":"<user-language 这一步做什么>"}]}]}]},{"type":"blocks","rows":[{"cells":["<user-language 块 0>","<user-language 块 1>","<user-language 块 2>","<user-language 块 3>"],"color":"#3d7eb8"}],"caption":"<user-language 每块代表什么>"}]}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
何时不用:只有一步就别画阶段图;纯数值对比用 `chart`,别把数字塞进色块。
|
|
285
|
+
|
|
286
|
+
### 主表明细(数据问答的默认结构)
|
|
287
|
+
|
|
288
|
+
适用:用户问的数据要「先看总量 → 再筛 → 再钻某一行」。
|
|
289
|
+
|
|
290
|
+
```json dsh-ui
|
|
291
|
+
{"items":[{"type":"grid","cols":2,"items":[{"type":"stat","label":"<user-language metric>","value":"<user-language value>","delta":"+3.1%"},{"type":"stat","label":"<user-language metric>","value":"<user-language value>"}]},{"type":"input","label":"<user-language filter>","placeholder":"<user-language hint>","id":"master-filter"},{"type":"table","filter":"master-filter","columns":["<user-language column>","<user-language column>","<user-language column>"],"types":["text","num","badge"],"rows":[["<user-language text>","128","<user-language status>"],["<user-language text>","190","<user-language status>"],["<user-language text>","250","<user-language status>"]],"details":[[{"type":"keyvalue","pairs":[{"key":"<user-language key>","value":"<user-language value>"}]}],null,[{"type":"progress","value":91,"target":80,"label":"<user-language metric>"}]]}]}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
何时不用:行数 ≤5 不要配 `filter`;没有逐行明细可展开就别配 `details`;展开行里只放该行自己的信息,不要塞与该行无关的图表。
|
|
295
|
+
|
|
296
|
+
### 结论卡(分析收尾的默认结构)
|
|
297
|
+
|
|
298
|
+
适用:指标 + 一个明确判断 + 可执行的下一步(周报结论、复盘、健康度检查)。
|
|
299
|
+
|
|
300
|
+
```json dsh-ui
|
|
301
|
+
{"items":[{"type":"grid","cols":3,"items":[{"type":"stat","label":"<user-language metric>","value":"<user-language value>","delta":"+2.4%"},{"type":"stat","label":"<user-language metric>","value":"<user-language value>"},{"type":"stat","label":"<user-language metric>","value":"<user-language value>","delta":"-1.2%"}]},{"type":"card","tone":"success","title":"<user-language title>","items":[{"type":"text","size":"body","content":"<user-language text>"},{"type":"progress","value":72,"target":80,"label":"<user-language metric>","valueLabel":"72%"}]},{"type":"row","items":[{"type":"button","label":"<user-language action>","tone":"primary","action":"<action-name>"},{"type":"button","label":"<user-language action>","tone":"ghost","action":"<action-name>"}]}]}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
何时不用:结论还不成立时不要硬造结论卡(先摆数据,让读者自己看);没有真实可执行的下一步就不要放按钮;`tone` 只有在确实传递语义(好/坏/险)时才用。
|
|
305
|
+
|
|
306
|
+
### 封面页(报告开篇的默认结构)
|
|
307
|
+
|
|
308
|
+
适用:正式报告/复盘/评审材料的**第一屏**——一个大数字定调,一句引言点题,三张摘要卡预告正文。
|
|
309
|
+
|
|
310
|
+
```json dsh-ui
|
|
311
|
+
{"items":[{"type":"hero","label":"<user-language metric>","value":"99.96%","delta":"+0.02%","tone":"accent","title":"<user-language title>","subtitle":"<user-language text>"},{"type":"text","size":"display","content":"<user-language statement>"},{"type":"divider","label":"<user-language chapter>"},{"type":"grid","cols":3,"items":[{"type":"card","title":"<user-language title>","items":[{"type":"stat","label":"<user-language metric>","value":"<user-language value>"}]},{"type":"card","title":"<user-language title>","items":[{"type":"stat","label":"<user-language metric>","value":"<user-language value>"}]},{"type":"card","title":"<user-language title>","items":[{"type":"stat","label":"<user-language metric>","value":"<user-language value>"}]}]}]}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
何时不用:短回答不需要封面(hero 已是唯一焦点,再加 `display` 就是两个焦点);hero 与 `display` 同屏时,后面不要再出现 h1 级大标题;普通问答直接给答案,不要套封面。
|
|
315
|
+
|
|
316
|
+
### 对比页(方案权衡的默认结构)
|
|
317
|
+
|
|
318
|
+
适用:两个(至多三个)方案/版本/选型的正面对决——定性取舍进卡,定量差异进表。
|
|
319
|
+
|
|
320
|
+
```json dsh-ui
|
|
321
|
+
{"items":[{"type":"grid","cols":2,"items":[{"type":"card","tone":"success","title":"<user-language option>","items":[{"type":"list","items":["<user-language text>","<user-language text>"]}]},{"type":"card","tone":"warning","title":"<user-language option>","items":[{"type":"list","items":["<user-language text>","<user-language text>"]}]}]},{"type":"table","columns":["<user-language column>","<user-language column>","<user-language column>"],"types":["text","num","num"],"rows":[["<user-language text>","8","12"],["<user-language text>","5","9"]]}]}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
何时不用:只有单一方案时就是普通陈述,不要硬摆两张卡假装权衡;卡与表要承载**不同粒度**(卡给取舍理由、表给数值对比),两边复制同一批数字就是重复表达。
|
|
325
|
+
|
|
326
|
+
### 时间线叙事(过程复盘的默认结构)
|
|
327
|
+
|
|
328
|
+
适用:有先后顺序的过程/事故/迭代叙事——时间线主叙事,收尾一张卡给汇总结论。
|
|
329
|
+
|
|
330
|
+
```json dsh-ui
|
|
331
|
+
{"items":[{"type":"timeline","items":[{"title":"<user-language milestone>","desc":"<user-language description>","time":"<user-language date>"},{"title":"<user-language milestone>","desc":"<user-language description>","time":"<user-language date>"},{"title":"<user-language milestone>","desc":"<user-language description>","time":"<user-language date>"}]},{"type":"card","title":"<user-language title>","items":[{"type":"keyvalue","pairs":[{"key":"<user-language key>","value":"<user-language value>"},{"key":"<user-language key>","value":"<user-language value>"}]}]}]}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
何时不用:两步以内的小流程用正文一句话讲清;纯日志列举不要套卡,`timeline` 单独就够。
|
|
335
|
+
|
|
336
|
+
### 测验页(教学自测的默认结构)
|
|
337
|
+
|
|
338
|
+
适用:教学/检查理解——两题以上的成组测验,radio 组带答案与解析,`submit` 聚合交卷本地判卷。
|
|
339
|
+
|
|
340
|
+
```json dsh-ui
|
|
341
|
+
{"items":[{"type":"radio","label":"<user-language question>","group":"q1","options":["<user-language option>","<user-language option>","<user-language option>"],"answer":1,"explanation":"<user-language explanation>"},{"type":"radio","label":"<user-language question>","group":"q2","options":["<user-language option>","<user-language option>"],"answer":0,"explanation":"<user-language explanation>"},{"type":"submit","label":"<user-language action>","action":"grade","groups":["q1","q2"]}]}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
何时不用:单一知识点用单个 `radio`(自带本地判卷)或 `quiz` 组件,不需要 submit 组卷;题目多于 5 个拆成多条回答分批发。
|
|
345
|
+
|
|
346
|
+
## 使用规则
|
|
347
|
+
|
|
348
|
+
1. **围栏放哪,组件就出现在哪** —— 文字在前后自然流动,不要用工具、不要解释"这是一个围栏"。**围栏一闭合就立即渲染**(不等整条回答结束),所以可以边写文字边出组件
|
|
349
|
+
2. **组合优先**:复杂界面用 `grid`+`card`+`stat`+`table` 拼,不要追求单一巨型组件
|
|
350
|
+
3. **JSON 必须严格合法,发出前完成 4 步自检**:插件**只**修标点级小错(字符串内半角引号、尾随逗号);**缺括号/错括号等结构错误一律不修**,直接红横幅退化成代码块——写错就重发,别指望兜底。**最容易犯的错:字符串值里用了半角引号 `"`**——中文引语一律写 `“”` 或 `「」`。发出围栏前自检 4 条:① 括号配对:`{` 与 `}`、`[` 与 `]` 数量相等,**收尾序列逐个核对**(长表格最易在最后几行错位:把 `]]}]}` 写成 `]}]}]}`)② 无尾随逗号 ③ 值内引号用中文引号 ④ 最后一个字符必须是 `}`(**`}` 之后不要再写任何字符**——实测常见错误是习惯性追加 `</p>` 或一句解释,整条围栏就解析不了)。不要在 JSON 字符串里放 markdown;超长表格/列表拆成多个组件分开发,宁短勿长
|
|
351
|
+
3.5. **字段名逐个核对(写错一个 = 整条围栏降级为代码块)**:某个组件的必填字段写错 / 缺失 → 该组件被丢弃 → 整份 spec 判定不可渲染 → 用户只看到一段裸 JSON。高频误写:`callout` 正文是 `content`(不是 text/body);`table` 要 `columns` + `rows`(不是 data,只给二维 rows 时首行会当表头);`keyvalue` 要 `pairs:[{key,value}]`(不是 items);`diff` 是 `diffs`;图片/音视频是 `src`;`code` 是 `code`、`copy` 是 `text`。拿不准就调 `validate_dsh_ui`,不要凭直觉命名
|
|
352
|
+
4. **不要嵌套围栏**:dsh-ui 里不要再包 ``` 代码围栏
|
|
353
|
+
5. **深色主题友好**:配色选深底亮色;UI 主题跟随应用
|
|
354
|
+
6. **场景判断**:先查上面的映射表 —— 内容类型命中就上对应组件;只有纯文字问答、一句话能说清时才不用
|
|
355
|
+
7. **图表范围**:`plot` 给合理 xMin/xMax(如 -3.14 到 3.14);3D 场景 mesh 少而精
|
|
356
|
+
8. **规格要紧凑**:整棵组件树 ≤200 节点、≤8 层嵌套;单个 `tabs` ≤12 个标签页、`accordion` ≤24 项(超出部分会被渲染器按上限截断渲染)。避免巨型 spec
|
|
357
|
+
9. **一个主题选一个主组件**:命中映射表后选**一种**组件承载,同一信息不要用两种组件重复表达(同一批数据又画 bars 又画 donut = 冗余)
|
|
358
|
+
10. **数量纪律**:一条回答 3–8 个组件为宜,宁缺毋滥。反例:该用 `table` 对比时写三段 `text`;一个 `stat` 能说清的事套 `card`+`grid`;与内容无关的 `scene3d` 炫技——3D 只在内容本身就是几何/空间时才用
|
|
359
|
+
12. **给命令就给能直接粘的**:多行 python 一律写成 heredoc 包装的**一整段** shell 代码块(`python - <<'PY'` … `PY`),不要用 `python -c "…"` 配反斜杠续行——续行在复制/粘贴里最容易碎成多行,用户还得自己拼回 heredoc。单行表达式才用 `-c`,且必须真的在一行内写完。示例:
|
|
360
|
+
|
|
361
|
+
````text
|
|
362
|
+
cd /path/to/repo
|
|
363
|
+
python - <<'PY'
|
|
364
|
+
import json
|
|
365
|
+
d = json.load(open('report.json'))
|
|
366
|
+
print(d.get('status'))
|
|
367
|
+
PY
|
|
368
|
+
````
|
|
369
|
+
|
|
370
|
+
同理:需要用户执行的脚本放进 `code` 节点(`lang`: `bash`/`python`)或正文围栏,并保证**从第一行到最后一行一次粘进终端就能跑**。
|
|
371
|
+
11. **先验后发(复杂 UI)**:发出 ```dsh-ui 围栏前,若 spec ≥3 个组件或含 `table`(长表格最易括号错位),先调用 `validate_dsh_ui` 工具(参数 `spec` 传围栏内的 JSON 文本)验证;返回 `next=fix_and_revalidate` 就按诊断修正后重新验证;返回 `next=emit_fence` 再发出;返回 `next=emit_repaired_fence` 时直接照抄 `repaired_json` 发出,无需再次验证;简单 UI(≤2 个组件)不必验证,渲染器会自动修复大部分标点/括号错误
|