@seekbuddy/dsh-ui 0.0.0-stage → 0.2.0-beta.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.
Files changed (195) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/LICENSE +22 -0
  3. package/README.md +175 -2
  4. package/README.zh.md +176 -0
  5. package/THIRD_PARTY_NOTICES.md +42 -0
  6. package/UPSTREAM.md +56 -0
  7. package/dist/blocks.js +1582 -0
  8. package/dist/chunks/chunk-23KOEBWJ.js +104 -0
  9. package/dist/chunks/chunk-3HCOU44R.js +697 -0
  10. package/dist/chunks/chunk-5JXG4BHW.js +31 -0
  11. package/dist/chunks/chunk-5XDVPALS.js +61 -0
  12. package/dist/chunks/chunk-AY44MQMD.js +3052 -0
  13. package/dist/chunks/chunk-B3EEK7A2.js +408 -0
  14. package/dist/chunks/chunk-CEBTQO6W.js +24 -0
  15. package/dist/chunks/chunk-CI73NXA5.js +202 -0
  16. package/dist/chunks/chunk-CTQPGUZP.js +22 -0
  17. package/dist/chunks/chunk-F352IICS.js +57 -0
  18. package/dist/chunks/chunk-IOBKTEKP.js +144 -0
  19. package/dist/chunks/chunk-KETGFAOH.js +66 -0
  20. package/dist/chunks/chunk-LA3QDZYN.js +2777 -0
  21. package/dist/chunks/chunk-NE62SYOZ.js +89 -0
  22. package/dist/chunks/chunk-OQPH36OI.js +754 -0
  23. package/dist/chunks/chunk-QJKAQ6PO.js +155 -0
  24. package/dist/chunks/chunk-R6AUJQ3G.js +129 -0
  25. package/dist/chunks/chunk-RNVSCTW7.js +24 -0
  26. package/dist/chunks/chunk-RZOP2PFC.js +152 -0
  27. package/dist/chunks/chunk-TQU54HSM.js +112 -0
  28. package/dist/chunks/chunk-TUK6UGXM.js +36 -0
  29. package/dist/chunks/chunk-TZ7HRE6D.js +328 -0
  30. package/dist/chunks/chunk-VIH56PDF.js +57 -0
  31. package/dist/chunks/chunk-WUL523OW.js +27 -0
  32. package/dist/chunks/chunk-XX6MSZLS.js +261 -0
  33. package/dist/chunks/chunk-ZA47FP7C.js +7 -0
  34. package/dist/chunks/chunk-ZZNL5PWF.js +170 -0
  35. package/dist/icons.js +803 -0
  36. package/dist/index.js +1182 -0
  37. package/dist/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  38. package/dist/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  39. package/dist/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  40. package/dist/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  41. package/dist/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  42. package/dist/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  43. package/dist/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  44. package/dist/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  45. package/dist/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  46. package/dist/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  47. package/dist/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  48. package/dist/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  49. package/dist/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  50. package/dist/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  51. package/dist/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  52. package/dist/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  53. package/dist/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  54. package/dist/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  55. package/dist/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  56. package/dist/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  57. package/dist/katex.css +1 -0
  58. package/dist/katex.css.d.ts +2 -0
  59. package/dist/markdown.js +148 -0
  60. package/dist/meta.json +6876 -0
  61. package/dist/root-inputs.json +67 -0
  62. package/dist/seekbuddy-card.js +7 -0
  63. package/dist/seekbuddy-empty.js +8 -0
  64. package/dist/seekbuddy-internal/DangerButton.js +7 -0
  65. package/dist/seekbuddy-internal/Mark.js +7 -0
  66. package/dist/seekbuddy-internal/Message.js +10 -0
  67. package/dist/seekbuddy-internal/Pagination.js +9 -0
  68. package/dist/seekbuddy-internal/StatusBadge.js +7 -0
  69. package/dist/seekbuddy-internal/SubtleButton.js +7 -0
  70. package/dist/seekbuddy-internal/Switch.js +7 -0
  71. package/dist/seekbuddy-internal/Upload.js +7 -0
  72. package/dist/seekbuddy-internal/date/Calendar.js +8 -0
  73. package/dist/seekbuddy-internal/date/DatePicker.js +9 -0
  74. package/dist/seekbuddy-internal/date/DateRangePicker.js +9 -0
  75. package/dist/seekbuddy-internal/date/TimePicker.js +8 -0
  76. package/dist/seekbuddy-internal/date/fields.js +16 -0
  77. package/dist/seekbuddy-internal/qr/QrCode.js +7 -0
  78. package/dist/seekbuddy-spinner.js +7 -0
  79. package/dist/seekbuddy-tabs.js +7 -0
  80. package/dist/seekbuddy-timeline.js +8 -0
  81. package/dist/seekbuddy.js +89 -0
  82. package/dist/theme-bootstrap.js +13 -0
  83. package/dist/theme.js +37 -0
  84. package/dist/tokens.css +934 -0
  85. package/dist/tokens.css.d.ts +2 -0
  86. package/dist/types/Button.d.ts +18 -0
  87. package/dist/types/Checkbox.d.ts +19 -0
  88. package/dist/types/CodeFileIcon.d.ts +11 -0
  89. package/dist/types/CodeToolbar.d.ts +29 -0
  90. package/dist/types/ConfigField.d.ts +32 -0
  91. package/dist/types/ConnectionIndicator.d.ts +25 -0
  92. package/dist/types/DiffBlock.d.ts +51 -0
  93. package/dist/types/DisclosureRow.d.ts +35 -0
  94. package/dist/types/FileTypeIcon.d.ts +42 -0
  95. package/dist/types/FoldToggle.d.ts +19 -0
  96. package/dist/types/HoverCard.d.ts +36 -0
  97. package/dist/types/ImageLightbox.d.ts +26 -0
  98. package/dist/types/ImagePreview.d.ts +11 -0
  99. package/dist/types/Input.d.ts +11 -0
  100. package/dist/types/JsonTree.d.ts +58 -0
  101. package/dist/types/LinkIcon.d.ts +33 -0
  102. package/dist/types/Menu.d.ts +142 -0
  103. package/dist/types/MenuGroup.d.ts +21 -0
  104. package/dist/types/MenuSurface.d.ts +15 -0
  105. package/dist/types/Modal.d.ts +43 -0
  106. package/dist/types/PermissionIcon.d.ts +38 -0
  107. package/dist/types/Pill.d.ts +12 -0
  108. package/dist/types/ReadBlock.d.ts +47 -0
  109. package/dist/types/ReferenceIcon.d.ts +20 -0
  110. package/dist/types/RiskConfirmation.d.ts +19 -0
  111. package/dist/types/SearchBlock.d.ts +71 -0
  112. package/dist/types/SegmentedControl.d.ts +34 -0
  113. package/dist/types/SegmentedTabs.d.ts +25 -0
  114. package/dist/types/ShortcutKeys.d.ts +10 -0
  115. package/dist/types/SiteGlyph.d.ts +24 -0
  116. package/dist/types/StateDot.d.ts +19 -0
  117. package/dist/types/Switch.d.ts +19 -0
  118. package/dist/types/Tag.d.ts +31 -0
  119. package/dist/types/TerminalBlock.d.ts +77 -0
  120. package/dist/types/TextShimmer.d.ts +22 -0
  121. package/dist/types/Toast.d.ts +48 -0
  122. package/dist/types/Tooltip.d.ts +63 -0
  123. package/dist/types/WebBlock.d.ts +60 -0
  124. package/dist/types/ansi.d.ts +16 -0
  125. package/dist/types/blocks.d.ts +19 -0
  126. package/dist/types/clipboard.d.ts +8 -0
  127. package/dist/types/code-file-icon-artwork.d.ts +53 -0
  128. package/dist/types/code-file-types.d.ts +29 -0
  129. package/dist/types/code-highlighting.d.ts +11 -0
  130. package/dist/types/css-modules.d.ts +6 -0
  131. package/dist/types/darwin-desktop.d.ts +8 -0
  132. package/dist/types/file-size.d.ts +7 -0
  133. package/dist/types/focus.d.ts +8 -0
  134. package/dist/types/guide-artwork.d.ts +14 -0
  135. package/dist/types/head-tail-cap.d.ts +22 -0
  136. package/dist/types/icons/index.d.ts +384 -0
  137. package/dist/types/icons/props.d.ts +8 -0
  138. package/dist/types/icons/shared-artwork.d.ts +42 -0
  139. package/dist/types/icons.d.ts +6 -0
  140. package/dist/types/index.d.ts +53 -0
  141. package/dist/types/input-modality.d.ts +18 -0
  142. package/dist/types/keyboard-composition.d.ts +10 -0
  143. package/dist/types/markdown/CodeBlock.d.ts +34 -0
  144. package/dist/types/markdown/JsonBlock.d.ts +7 -0
  145. package/dist/types/markdown/MarkdownDelegate.d.ts +45 -0
  146. package/dist/types/markdown/MarkdownText.d.ts +47 -0
  147. package/dist/types/markdown/cjkFriendlyStrong.d.ts +8 -0
  148. package/dist/types/markdown/file-link.d.ts +12 -0
  149. package/dist/types/markdown/highlight.d.ts +147 -0
  150. package/dist/types/markdown/incremental.d.ts +79 -0
  151. package/dist/types/markdown/katex.d.ts +18 -0
  152. package/dist/types/markdown/local-image-syntax.d.ts +9 -0
  153. package/dist/types/markdown/mathCompatibility.d.ts +10 -0
  154. package/dist/types/markdown/parse.d.ts +24 -0
  155. package/dist/types/markdown/plain-text.d.ts +21 -0
  156. package/dist/types/markdown/render.d.ts +140 -0
  157. package/dist/types/markdown/useViewportHighlighting.d.ts +10 -0
  158. package/dist/types/markdown.d.ts +9 -0
  159. package/dist/types/overlay-top-margin.d.ts +7 -0
  160. package/dist/types/plugin-artwork.d.ts +16 -0
  161. package/dist/types/pointer-grace.d.ts +21 -0
  162. package/dist/types/rank-by-name.d.ts +21 -0
  163. package/dist/types/relative-time.d.ts +22 -0
  164. package/dist/types/seekbuddy/Card.d.ts +28 -0
  165. package/dist/types/seekbuddy/DangerButton.d.ts +31 -0
  166. package/dist/types/seekbuddy/Empty.d.ts +34 -0
  167. package/dist/types/seekbuddy/Mark.d.ts +27 -0
  168. package/dist/types/seekbuddy/Message.d.ts +52 -0
  169. package/dist/types/seekbuddy/Pagination.d.ts +66 -0
  170. package/dist/types/seekbuddy/Spinner.d.ts +20 -0
  171. package/dist/types/seekbuddy/StatusBadge.d.ts +33 -0
  172. package/dist/types/seekbuddy/SubtleButton.d.ts +30 -0
  173. package/dist/types/seekbuddy/Switch.d.ts +36 -0
  174. package/dist/types/seekbuddy/Tabs.d.ts +49 -0
  175. package/dist/types/seekbuddy/Timeline.d.ts +42 -0
  176. package/dist/types/seekbuddy/Upload.d.ts +101 -0
  177. package/dist/types/seekbuddy/date/Calendar.d.ts +94 -0
  178. package/dist/types/seekbuddy/date/DatePicker.d.ts +29 -0
  179. package/dist/types/seekbuddy/date/DateRangePicker.d.ts +41 -0
  180. package/dist/types/seekbuddy/date/TimePicker.d.ts +35 -0
  181. package/dist/types/seekbuddy/date/date.d.ts +79 -0
  182. package/dist/types/seekbuddy/date/fields.d.ts +45 -0
  183. package/dist/types/seekbuddy/index.d.ts +49 -0
  184. package/dist/types/seekbuddy/qr/QrCode.d.ts +37 -0
  185. package/dist/types/seekbuddy/qr/qr.d.ts +38 -0
  186. package/dist/types/theme-bootstrap.d.ts +3 -0
  187. package/dist/types/theme-core.d.ts +14 -0
  188. package/dist/types/theme.d.ts +4 -0
  189. package/dist/types/use-copy-feedback.d.ts +13 -0
  190. package/dist/types/useAnchoredMaxHeight.d.ts +13 -0
  191. package/dist/types/useAnchoredPosition.d.ts +35 -0
  192. package/dist/types/useDismissOnOutsidePointer.d.ts +10 -0
  193. package/dist/types/useModalLayer.d.ts +26 -0
  194. package/dist/types/user-text.d.ts +36 -0
  195. package/package.json +151 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@seekbuddy/dsh-ui` are recorded here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
5
+ [Semantic Versioning](https://semver.org/). While the version is `0.x`, a minor bump may contain
6
+ breaking changes; they are listed under **Breaking**.
7
+
8
+ Upstream DSH synchronizations are recorded with the DSH tag they move to; the full list of local
9
+ changes to the DSH layer lives in [UPSTREAM.md](UPSTREAM.md).
10
+
11
+ ## [0.2.0-beta.0] - 2026-10-09
12
+
13
+ First release under the name `@seekbuddy/dsh-ui`. DSH layer synchronized with `dsh-v0.2.0-rc.2`.
14
+
15
+ ### Breaking
16
+
17
+ - The package is renamed from `dsh-ui-primitives` to `@seekbuddy/dsh-ui`. Entry paths are unchanged:
18
+ replace the `dsh-ui-primitives` import prefix.
19
+ - `BrandWordmark`, `FishLogo`, `FISH_LOGO_PATH` and `FISH_LOGO_VIEWBOX` are removed. They draw
20
+ DeepSeek's brand marks, which the MIT license does not cover.
21
+ - `Switch` from `/seekbuddy` now uses upstream's colours: the on track is `--dsw-alias-brand-primary`
22
+ (black in light, near-white in dark) instead of business blue, and the thumb follows
23
+ `--dsw-alias-label-primary-foreground` / `--dsw-alias-switch-thumb` instead of a fixed white.
24
+
25
+ ### Added
26
+
27
+ - Documentation for every extra component in `docs/components/`: usage, examples, behaviour,
28
+ accessibility and API tables generated from the TypeScript source. Every prop and field now has JSDoc.
29
+ - Chinese documentation next to the English pages (`README.zh.md`, `CONTRIBUTING.zh.md`,
30
+ `docs/components/*.zh.md`), following upstream DSH's bilingual pairing; the former
31
+ `README.zh-CN.md` is now `README.zh.md`.
32
+
33
+ ### Fixed
34
+
35
+ - `diff` and `@deepseek-ai/dsh-util-code-language` are declared as dependencies. Both were imported
36
+ but not declared, so installing the package outside the original monorepo failed to resolve them.
37
+ - `DangerButton` and `SubtleButton` forward their ref to the underlying `<button>`, so they work as
38
+ `Tooltip` and `HoverCard` anchors.
39
+ - Divider lines in `DatePicker`, `DateRangePicker` and `TimePicker` are 0.5px hairlines, matching
40
+ the DSH styling rules.
41
+ - `TimePicker` no longer overrides the theme's scrollbar width.
42
+
43
+ ### Known issues
44
+
45
+ - `DateField`, `DateRangeField` and `TimeField` log React's `useLayoutEffect does nothing on the
46
+ server` warning during React 18 server rendering. The markup is correct; the popover position is
47
+ computed on the client.
48
+
49
+ [0.2.0-beta.0]: https://github.com/seekbuddy/dsh-ui/releases/tag/v0.2.0-beta.0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeepSeek
4
+ Copyright (c) 2026 SeekBuddy contributors
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,176 @@
1
- # Temporary Holding Version
1
+ # @seekbuddy/dsh-ui
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ English | [中文](README.zh.md)
4
+
5
+ React components in the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH) web UI design system, for building product pages around DSH: the DSH primitives (`--dsw-*` design tokens, light / dark themes, controls, icons, Markdown and tool-output renderers) plus the components DSH does not provide, such as cards, tabs, pagination, messages, upload and date / time pickers, built on the same tokens. Packaged for ordinary React 18 / 19 and Next.js apps.
6
+
7
+ **Live preview:** every component in [Storybook](https://seekbuddy.github.io/dsh-ui/).
8
+
9
+ > **Unofficial.** This project is not affiliated with, endorsed by, or sponsored by DeepSeek. It ships no DeepSeek brand assets (logo or wordmark). See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
10
+
11
+ ## Why this package
12
+
13
+ The DSH UI primitives (`@deepseek-ai/dsh-client-ui-primitives`) cover what the DSH web shell needs: chat, tool output, menus, dialogs. A product built around DSH also has consoles, settings and admin pages, and those need components DSH does not have: cards, tabs, pagination, date and time input, upload, global messages. Writing them separately in each app drifts away from the DSH look; patching them into a copy of the primitives turns every upstream sync into a merge.
14
+
15
+ This package provides those components and keeps them apart from DSH:
16
+
17
+ - **Extension components** (`@seekbuddy/dsh-ui/seekbuddy`) fill the gaps. They are styled only with the DSH tokens and follow DSH's styling rules, so they sit next to DSH controls without looking different, and they reuse DSH controls through the public entry instead of re-implementing them. See [docs/components](docs/components/README.md).
18
+ - **The DSH layer** is a copy of the upstream primitives with packaging fixes only, each recorded in [UPSTREAM.md](UPSTREAM.md), so it follows upstream tags.
19
+
20
+ To make the DSH layer usable in an ordinary app, it also fixes three packaging problems of the official package:
21
+
22
+ | Official package | `@seekbuddy/dsh-ui` |
23
+ | --- | --- |
24
+ | One root entry re-exports everything, so Shiki and KaTeX land in the first page load | Split entries; the root entry is guarded at build time against reaching Markdown, Shiki, KaTeX or the code-file artwork |
25
+ | Theme tokens and theme switching live in a Cordis plugin | `tokens.css` and a standalone `light / dark / system` theme runtime with a no-flash bootstrap script |
26
+ | KaTeX output is converted with the browser-only `DOMParser` | SSR-safe KaTeX rendering; tested with React 18 SSR and a Next.js 16 build |
27
+
28
+ ## Install
29
+
30
+ ```sh
31
+ npm install @seekbuddy/dsh-ui
32
+ ```
33
+
34
+ Peer dependencies: `react` and `react-dom` `^18.2.0 || ^19.0.0`.
35
+
36
+ ## Quick start
37
+
38
+ Import the global token sheet once, in your app entry. Import `katex.css` only if you render math.
39
+
40
+ ```tsx
41
+ import '@seekbuddy/dsh-ui/tokens.css'
42
+ import '@seekbuddy/dsh-ui/katex.css'
43
+
44
+ import { Button, Pill } from '@seekbuddy/dsh-ui'
45
+ import { MarkdownText } from '@seekbuddy/dsh-ui/markdown'
46
+ import { IconCheckOutlineRegular } from '@seekbuddy/dsh-ui/icons'
47
+ import { setThemePreference } from '@seekbuddy/dsh-ui/theme'
48
+
49
+ const labels = {
50
+ code: { copyLabel: 'Copy', copiedLabel: 'Copied' },
51
+ footnotes: 'Footnotes',
52
+ }
53
+
54
+ export function Example() {
55
+ return (
56
+ <div>
57
+ <Button variant="primary" onClick={() => setThemePreference('dark')}>
58
+ <IconCheckOutlineRegular /> Dark theme
59
+ </Button>
60
+ <Pill active>Enabled</Pill>
61
+ <MarkdownText text={'Formula: $x^2$'} labels={labels} />
62
+ </div>
63
+ )
64
+ }
65
+ ```
66
+
67
+ Component styles are CSS Modules compiled into the JavaScript and injected into `<head>` once, the first time a component module loads. `tokens.css` and `katex.css` are the only global stylesheets.
68
+
69
+ Components contain no user-facing text: every visible or screen-reader label is a prop (usually a typed `labels` object), so you localize them in your app.
70
+
71
+ ## Entry points
72
+
73
+ Import only from these entries; anything else under `dist/` is internal.
74
+
75
+ | Entry | Contents |
76
+ | --- | --- |
77
+ | `@seekbuddy/dsh-ui` | Lightweight controls and utilities: `Button`, `Input`, `Pill`, `Tag`, `Switch`, `Checkbox`, `Menu`, `MenuSurface`, `Modal`, `Tooltip`, `Toast`, `HoverCard`, `SegmentedControl`, `SegmentedTabs`, positioning / modal hooks, and helpers such as `relativeTime`, `fileSizeText`, `rankByName` |
78
+ | `@seekbuddy/dsh-ui/blocks` | Tool-output renderers `TerminalBlock`, `ReadBlock`, `DiffBlock`, `SearchBlock`, `WebBlock`, `JsonTree`; file / link icons `FileTypeIcon`, `LinkIconRegular` / `LinkIconMedium`; code highlighting `languageForPath`, `useCodeHighlighter` (loads Shiki) |
79
+ | `@seekbuddy/dsh-ui/markdown` | `MarkdownText`, `CodeBlock`, `JsonBlock`, `MarkdownDelegateProvider`, `extractMarkdownPlainText` |
80
+ | `@seekbuddy/dsh-ui/icons` | 188 `Icon*` components (94 glyphs × `Regular` / `Medium` stroke), `PermissionIcon*`, `ReferenceIcon*`, `PluginArtwork*`, `GuideArtwork*` |
81
+ | `@seekbuddy/dsh-ui/theme` | Theme state, DOM application and React hooks |
82
+ | `@seekbuddy/dsh-ui/theme/bootstrap` | `THEME_BOOTSTRAP_SCRIPT`, an inline script with no React dependency |
83
+ | `@seekbuddy/dsh-ui/seekbuddy` | Extra components ([docs](docs/components/README.md)); the whole entry is a Client Component |
84
+ | `@seekbuddy/dsh-ui/seekbuddy/{card,empty,spinner,timeline}` | Hook-free extra components that a Next.js Server Component may import |
85
+ | `@seekbuddy/dsh-ui/seekbuddy/tabs` | `Tabs`; same as importing it from `/seekbuddy` |
86
+ | `@seekbuddy/dsh-ui/tokens.css` | The eight DSH theme sheets, concatenated in their cascade order |
87
+ | `@seekbuddy/dsh-ui/katex.css` | KaTeX CSS reduced to woff2 fonts |
88
+
89
+ ## Two layers
90
+
91
+ | Layer | Source | Contents |
92
+ | --- | --- | --- |
93
+ | DSH layer | `src/` except `src/seekbuddy/` | A copy of the DSH web UI primitives and theme sheets, kept in sync with upstream tags. Local changes are listed in [UPSTREAM.md](UPSTREAM.md); everything else is unchanged upstream code. |
94
+ | Extra components | `src/seekbuddy/` | Components DSH does not provide, written for this package and styled only with `--dsw-*` tokens |
95
+
96
+ Extra components: `Card`, `Empty`, `Mark`, `MessageProvider` + `useMessage`, `Pagination` (+ `pageItems`), `QrCode`, `Spinner`, `StatusBadge`, `Switch`, `Tabs`, `Timeline`, `Upload`, `DangerButton`, `SubtleButton`, and the date / time family `Calendar`, `DatePicker`, `DateRangePicker`, `TimePicker`, `DateField`, `DateRangeField`, `TimeField`. **Each one is documented — usage, examples and the full API — in [docs/components](docs/components/README.md).**
97
+
98
+ The extra components import DSH components through the public `@seekbuddy/dsh-ui` entry, never by relative path. A bundler can therefore alias that entry to another copy of the DSH primitives (for example the one a DSH web shell already loads), and the page keeps a single implementation of each control. Importing one component from `/seekbuddy` does not pull in the others: every component is built into its own chunk, together with its CSS.
99
+
100
+ ## Theme
101
+
102
+ The theme preference is `light | dark | system`. It is stored in `localStorage` under `dsh-ui-primitives.theme-preference` (the key keeps the package's former name for compatibility).
103
+
104
+ ```tsx
105
+ import { initializeTheme, setThemePreference, useIsDark, useThemePreference } from '@seekbuddy/dsh-ui/theme'
106
+
107
+ initializeTheme()
108
+ ```
109
+
110
+ `initializeTheme()` restores a valid stored value and falls back to `system`; it still applies the theme when `localStorage` is unavailable. The theme is applied through `document.documentElement.style.colorScheme` and the `data-ds-dark-theme` attribute on `body`.
111
+
112
+ For server-rendered apps, run the bootstrap script before the page content, so a stored dark preference does not flash light on first load. Next.js:
113
+
114
+ ```tsx
115
+ import { THEME_BOOTSTRAP_SCRIPT } from '@seekbuddy/dsh-ui/theme/bootstrap'
116
+ import '@seekbuddy/dsh-ui/tokens.css'
117
+
118
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
119
+ return (
120
+ <html suppressHydrationWarning>
121
+ <body>
122
+ <script dangerouslySetInnerHTML={{ __html: THEME_BOOTSTRAP_SCRIPT }} />
123
+ {children}
124
+ </body>
125
+ </html>
126
+ )
127
+ }
128
+ ```
129
+
130
+ `THEME_BOOTSTRAP_SCRIPT` is a constant from this package; never replace it with a string from user input or configuration.
131
+
132
+ ## Design tokens
133
+
134
+ Style your own components with the semantic tokens, not color literals:
135
+
136
+ | Prefix | Use |
137
+ | --- | --- |
138
+ | `--dsw-alias-*` | Semantic colors: backgrounds, labels, borders, interaction and status states. First choice for any color |
139
+ | `--dsw-font-*` | Complete type roles; use them as `font: var(--dsw-font-…)` |
140
+ | `--dsw-radius-*` | Corner radii: `xs` 4, `sm` 8, `md` 12, `lg` 16, `xl` 20, `panel` 28 |
141
+ | `--dsw-elevation-*` | Raised surfaces (menus, panels, dialogs); the shadow already draws the hairline border |
142
+ | `--dsw-static-*` | The raw palette behind the aliases; do not use it in components |
143
+
144
+ To add a brand theme, keep `light / dark / system` and set a separate attribute on `body`, then load an override sheet after `tokens.css` that remaps `--dsw-alias-*` for both light and dark. Put it on `body`, not on a page container: `Modal`, `Toast` and `ImageLightbox` render into `body` through portals.
145
+
146
+ ## Migrating from `dsh-ui-primitives`
147
+
148
+ This package was previously developed as `dsh-ui-primitives`.
149
+
150
+ 1. Replace the `dsh-ui-primitives` import prefix with `@seekbuddy/dsh-ui`; the entry paths are unchanged.
151
+ 2. `BrandWordmark`, `FishLogo`, `FISH_LOGO_PATH` and `FISH_LOGO_VIEWBOX` are removed. They draw DeepSeek's brand marks and are not redistributed.
152
+
153
+ ## Development
154
+
155
+ Requires Node.js 20.11+.
156
+
157
+ ```sh
158
+ npm install
159
+ npm run verify # typecheck → unit tests → build → package contents → React 18 SSR → Next.js 16 build
160
+ ```
161
+
162
+ `test:package` packs the real npm tarball and checks every export, the token cascade order and the KaTeX font URLs; `test:react18` and `test:next16` install that tarball into fixture apps. The build fails if the root entry reaches Markdown, Shiki or KaTeX, or if an extra component bundles a copy of a DSH component instead of importing it through the public entry.
163
+
164
+ `storybook/` is the component documentation and demo site (Storybook 10). It has its own dependencies and is not part of the published package:
165
+
166
+ ```sh
167
+ npm run build # the site reads dist/tokens.css
168
+ cd storybook
169
+ bun install
170
+ bun run dev # http://localhost:9109
171
+ bun run check # typecheck + every public runtime export has a story
172
+ ```
173
+
174
+ ## License
175
+
176
+ [MIT](LICENSE). The DSH layer is MIT-licensed code by DeepSeek; see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) for upstream attribution and dependency licenses.
package/README.zh.md ADDED
@@ -0,0 +1,176 @@
1
+ # @seekbuddy/dsh-ui
2
+
3
+ [English](README.md) | 中文
4
+
5
+ 基于 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)Web UI 设计系统的 React 组件库,用来搭建围绕 DSH 的产品页面:包含 DSH 的基础组件(`--dsw-*` 设计 token、明暗主题、基础控件、图标、Markdown 与工具输出渲染器),以及 DSH 没有提供、基于同一套 token 构建的组件,如卡片、标签页、分页、全局提示、上传、日期时间选择。打包成普通 React 18 / 19 与 Next.js 应用可以直接使用的形式。
6
+
7
+ **在线预览:**所有组件都可以在 [Storybook](https://seekbuddy.github.io/dsh-ui/) 里查看。
8
+
9
+ > **非官方项目。** 本项目与 DeepSeek 无关联,未获其认可或赞助,不包含 DeepSeek 的品牌素材(标志与字标)。详见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。
10
+
11
+ ## 为什么有这个包
12
+
13
+ DSH 的 UI 基础组件(`@deepseek-ai/dsh-client-ui-primitives`)覆盖的是 DSH Web 壳自己的需要:对话、工具输出、菜单、对话框。围绕 DSH 做产品,还会有控制台、设置页、管理后台,这些页面需要 DSH 没有的组件:卡片、标签页、分页、日期时间输入、上传、全局提示。每个应用各写一套,外观会和 DSH 越走越远;直接加进基础组件的副本里,每次同步上游都要处理合并冲突。
14
+
15
+ 本包提供这些组件,同时让它们和 DSH 保持分离:
16
+
17
+ - **扩展组件**(`@seekbuddy/dsh-ui/seekbuddy`)补上缺口。样式只用 DSH 的 token,遵守 DSH 的样式规则,和 DSH 控件放在一起看不出差别;需要 DSH 控件时通过公开入口复用,不重新实现。详见 [docs/components](docs/components/README.zh.md)。
18
+ - **DSH 层**是上游基础组件的副本,只做打包相关的修复,每一项都登记在 [UPSTREAM.md](UPSTREAM.md),因此可以跟随上游 tag 同步。
19
+
20
+ 为了让 DSH 层能在普通应用里使用,本包还解决了官方包在打包上的三个问题:
21
+
22
+ | 官方包 | `@seekbuddy/dsh-ui` |
23
+ | --- | --- |
24
+ | 单一根入口全量导出,Shiki 与 KaTeX 进首屏 | 拆分入口;构建期断言根入口不触达 Markdown、Shiki、KaTeX 与代码文件图标素材 |
25
+ | 主题 token 与主题切换在 Cordis 插件里 | 提供 `tokens.css` 与独立的 `light / dark / system` 主题运行时,附防闪烁的首屏脚本 |
26
+ | KaTeX 输出依赖浏览器 `DOMParser` 转换 | 服务端渲染安全的 KaTeX;用 React 18 SSR 与 Next.js 16 构建测试覆盖 |
27
+
28
+ ## 安装
29
+
30
+ ```sh
31
+ npm install @seekbuddy/dsh-ui
32
+ ```
33
+
34
+ peer 依赖:`react`、`react-dom` `^18.2.0 || ^19.0.0`。
35
+
36
+ ## 快速开始
37
+
38
+ 在应用入口导入一次全局 token 样式;只有渲染数学公式时才导入 `katex.css`。
39
+
40
+ ```tsx
41
+ import '@seekbuddy/dsh-ui/tokens.css'
42
+ import '@seekbuddy/dsh-ui/katex.css'
43
+
44
+ import { Button, Pill } from '@seekbuddy/dsh-ui'
45
+ import { MarkdownText } from '@seekbuddy/dsh-ui/markdown'
46
+ import { IconCheckOutlineRegular } from '@seekbuddy/dsh-ui/icons'
47
+ import { setThemePreference } from '@seekbuddy/dsh-ui/theme'
48
+
49
+ const labels = {
50
+ code: { copyLabel: 'Copy', copiedLabel: 'Copied' },
51
+ footnotes: 'Footnotes',
52
+ }
53
+
54
+ export function Example() {
55
+ return (
56
+ <div>
57
+ <Button variant="primary" onClick={() => setThemePreference('dark')}>
58
+ <IconCheckOutlineRegular /> Dark theme
59
+ </Button>
60
+ <Pill active>Enabled</Pill>
61
+ <MarkdownText text={'Formula: $x^2$'} labels={labels} />
62
+ </div>
63
+ )
64
+ }
65
+ ```
66
+
67
+ 组件样式是编译进 JS 的 CSS Modules,组件模块首次加载时注入 `<head>`,只注入一次。全局样式只有 `tokens.css` 与 `katex.css`。
68
+
69
+ 组件内不含任何界面文案:所有可见文字与读屏文字都通过 props(通常是带类型的 `labels` 对象)传入,由应用自己做本地化。
70
+
71
+ ## 公开入口
72
+
73
+ 只从下列入口导入;`dist/` 下的其他文件都是内部实现。
74
+
75
+ | 入口 | 内容 |
76
+ | --- | --- |
77
+ | `@seekbuddy/dsh-ui` | 轻量控件与工具:`Button`、`Input`、`Pill`、`Tag`、`Switch`、`Checkbox`、`Menu`、`MenuSurface`、`Modal`、`Tooltip`、`Toast`、`HoverCard`、`SegmentedControl`、`SegmentedTabs`、定位与模态 Hooks,以及 `relativeTime`、`fileSizeText`、`rankByName` 等工具函数 |
78
+ | `@seekbuddy/dsh-ui/blocks` | 工具输出渲染器 `TerminalBlock`、`ReadBlock`、`DiffBlock`、`SearchBlock`、`WebBlock`、`JsonTree`;文件 / 链接图标 `FileTypeIcon`、`LinkIconRegular` / `LinkIconMedium`;代码高亮 `languageForPath`、`useCodeHighlighter`(会加载 Shiki) |
79
+ | `@seekbuddy/dsh-ui/markdown` | `MarkdownText`、`CodeBlock`、`JsonBlock`、`MarkdownDelegateProvider`、`extractMarkdownPlainText` |
80
+ | `@seekbuddy/dsh-ui/icons` | 188 个 `Icon*`(94 个图形 × `Regular` / `Medium` 两档描边)、`PermissionIcon*`、`ReferenceIcon*`、`PluginArtwork*`、`GuideArtwork*` |
81
+ | `@seekbuddy/dsh-ui/theme` | 主题状态、DOM 应用函数与 React Hooks |
82
+ | `@seekbuddy/dsh-ui/theme/bootstrap` | `THEME_BOOTSTRAP_SCRIPT`,不依赖 React 的首屏内联脚本 |
83
+ | `@seekbuddy/dsh-ui/seekbuddy` | 扩展组件([文档](docs/components/README.zh.md));整个入口是 Client Component |
84
+ | `@seekbuddy/dsh-ui/seekbuddy/{card,empty,spinner,timeline}` | 不含 Hook 的扩展组件,Next.js Server Component 可以引用 |
85
+ | `@seekbuddy/dsh-ui/seekbuddy/tabs` | `Tabs`;与从 `/seekbuddy` 引用等价 |
86
+ | `@seekbuddy/dsh-ui/tokens.css` | 八份 DSH 主题样式,按级联顺序拼接 |
87
+ | `@seekbuddy/dsh-ui/katex.css` | 只保留 woff2 字体的 KaTeX 样式 |
88
+
89
+ ## 两层结构
90
+
91
+ | 层 | 源码位置 | 内容 |
92
+ | --- | --- | --- |
93
+ | DSH 层 | `src/` 中除 `src/seekbuddy/` 以外的部分 | DSH Web UI 基础组件与主题样式的副本,随上游 tag 同步。本地改动逐条列在 [UPSTREAM.md](UPSTREAM.md),其余与上游代码一致 |
94
+ | 扩展组件 | `src/seekbuddy/` | DSH 没有提供、为本包编写的组件,样式只用 `--dsw-*` token |
95
+
96
+ 扩展组件:`Card`、`Empty`、`Mark`、`MessageProvider` + `useMessage`、`Pagination`(附纯函数 `pageItems`)、`QrCode`、`Spinner`、`StatusBadge`、`Switch`、`Tabs`、`Timeline`、`Upload`、`DangerButton`、`SubtleButton`,以及日期时间族 `Calendar`、`DatePicker`、`DateRangePicker`、`TimePicker`、`DateField`、`DateRangeField`、`TimeField`。**每个组件的用法、示例和完整 API 见 [docs/components](docs/components/README.zh.md)。**
97
+
98
+ 扩展组件引用 DSH 组件时只走公开入口 `@seekbuddy/dsh-ui`,不用相对路径。因此打包器可以把这个入口别名到另一份 DSH 基础组件(例如 DSH Web 壳已经加载的那份),页面里每个控件只保留一份实现。从 `/seekbuddy` 只引一个组件不会带上其他组件:每个组件连同它的 CSS 各自构建成独立的 chunk。
99
+
100
+ ## 主题
101
+
102
+ 主题偏好是 `light | dark | system`,存在 `localStorage` 的 `dsh-ui-primitives.theme-preference` 键下(为兼容保留了本包旧名)。
103
+
104
+ ```tsx
105
+ import { initializeTheme, setThemePreference, useIsDark, useThemePreference } from '@seekbuddy/dsh-ui/theme'
106
+
107
+ initializeTheme()
108
+ ```
109
+
110
+ `initializeTheme()` 恢复合法的已存值,非法或缺失时回退到 `system`;`localStorage` 不可用时仍会应用主题。主题通过 `document.documentElement.style.colorScheme` 和 `body` 上的 `data-ds-dark-theme` 属性生效。
111
+
112
+ 服务端渲染的应用要在页面内容之前执行首屏脚本,避免已保存深色主题的页面先亮后暗。Next.js 写法:
113
+
114
+ ```tsx
115
+ import { THEME_BOOTSTRAP_SCRIPT } from '@seekbuddy/dsh-ui/theme/bootstrap'
116
+ import '@seekbuddy/dsh-ui/tokens.css'
117
+
118
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
119
+ return (
120
+ <html suppressHydrationWarning>
121
+ <body>
122
+ <script dangerouslySetInnerHTML={{ __html: THEME_BOOTSTRAP_SCRIPT }} />
123
+ {children}
124
+ </body>
125
+ </html>
126
+ )
127
+ }
128
+ ```
129
+
130
+ `THEME_BOOTSTRAP_SCRIPT` 是本包的常量,不得替换成来自用户输入或配置的字符串。
131
+
132
+ ## 设计 Token
133
+
134
+ 自己的组件用语义 token 写样式,不写颜色字面量:
135
+
136
+ | 前缀 | 用途 |
137
+ | --- | --- |
138
+ | `--dsw-alias-*` | 语义颜色:背景、文字、边框、交互与状态色;任何颜色首选 |
139
+ | `--dsw-font-*` | 完整的字体角色,写成 `font: var(--dsw-font-…)` |
140
+ | `--dsw-radius-*` | 圆角:`xs` 4、`sm` 8、`md` 12、`lg` 16、`xl` 20、`panel` 28 |
141
+ | `--dsw-elevation-*` | 浮起表面(菜单、面板、对话框);阴影里已包含发丝描边 |
142
+ | `--dsw-static-*` | alias 背后的原始色板;组件里不要直接用 |
143
+
144
+ 要加品牌主题,保留 `light / dark / system`,在 `body` 上另设一个属性,并在 `tokens.css` 之后加载覆盖样式,成对重映射亮色与暗色的 `--dsw-alias-*`。属性要放在 `body` 上而不是页面容器上:`Modal`、`Toast`、`ImageLightbox` 通过 Portal 渲染到 `body`。
145
+
146
+ ## 从 `dsh-ui-primitives` 迁移
147
+
148
+ 本包此前以 `dsh-ui-primitives` 为名开发。
149
+
150
+ 1. 把导入前缀 `dsh-ui-primitives` 换成 `@seekbuddy/dsh-ui`,各入口路径不变。
151
+ 2. 删除了 `BrandWordmark`、`FishLogo`、`FISH_LOGO_PATH`、`FISH_LOGO_VIEWBOX`:它们绘制的是 DeepSeek 的品牌标志,本包不再分发。
152
+
153
+ ## 开发
154
+
155
+ 需要 Node.js 20.11+。
156
+
157
+ ```sh
158
+ npm install
159
+ npm run verify # typecheck → unit tests → build → package contents → React 18 SSR → Next.js 16 build
160
+ ```
161
+
162
+ `test:package` 打出真实的 npm tarball,校验全部导出、token 级联顺序与 KaTeX 字体 URL;`test:react18` 与 `test:next16` 把这个 tarball 装进测试应用。根入口触达 Markdown、Shiki 或 KaTeX,或扩展组件没走公开入口而打进了一份 DSH 组件时,构建直接失败。
163
+
164
+ `storybook/` 是组件文档站,也是组件演示(Storybook 10),依赖独立安装,不进发布包:
165
+
166
+ ```sh
167
+ npm run build # the site reads dist/tokens.css
168
+ cd storybook
169
+ bun install
170
+ bun run dev # http://localhost:9109
171
+ bun run check # typecheck + every public runtime export has a story
172
+ ```
173
+
174
+ ## 许可证
175
+
176
+ [MIT](LICENSE)。DSH 层是 DeepSeek 以 MIT 授权的代码;上游归属与依赖许可证见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。
@@ -0,0 +1,42 @@
1
+ # Third-Party Notices
2
+
3
+ `@seekbuddy/dsh-ui` is an unofficial project. It is not affiliated with, endorsed by, or sponsored by
4
+ DeepSeek. "DeepSeek" and "DeepSeek Harness" are trademarks of their respective owner; this package uses
5
+ the names only to describe compatibility, and ships none of DeepSeek's brand assets (logo, wordmark).
6
+
7
+ ## DeepSeek Harness UI primitives and theme
8
+
9
+ Everything under `src/` except `src/seekbuddy/` is a copy of the DeepSeek Harness web UI primitives and
10
+ theme sheets, with the local adaptations listed in `UPSTREAM.md`.
11
+
12
+ - Upstream repository: https://github.com/deepseek-ai/deepseek-harness
13
+ - Tag: `dsh-v0.2.0-rc.2`, commit `639ed015397290b3745d163aafe02ffee4aa3f84`
14
+ - `packages/client/ui-primitives/src` → `src/` (components, CSS Modules, icons, Markdown renderer)
15
+ - `packages/client/ui-theme/src/styles` → `src/styles/` (`base.css`, `corner-shape.css`,
16
+ `design-platform.css`, `focus.css`, `onboarding.css`, `scrollbar.css`, `gradient-shadow-text.css`,
17
+ `shiki.css`)
18
+ - Not included: `BrandWordmark`, `FishLogo` (DeepSeek brand assets), `PathLabel`, `settings-form/`,
19
+ `brand-font.css` and its Montserrat fonts.
20
+
21
+ License: MIT, Copyright (c) 2026 DeepSeek. The full text is reproduced in this package's `LICENSE`.
22
+
23
+ ## Bundled assets
24
+
25
+ - **KaTeX CSS and fonts** (`dist/katex.css`, `dist/katex/fonts/*.woff2`, copied from the `katex`
26
+ package at build time): MIT, Copyright (c) 2013-2020 Khan Academy and other contributors
27
+ (https://github.com/KaTeX/KaTeX/blob/main/LICENSE; fonts: https://github.com/KaTeX/katex-fonts).
28
+
29
+ ## Runtime dependencies
30
+
31
+ Installed from npm, not bundled into `dist/` (except the KaTeX CSS and fonts above):
32
+
33
+ | Package | License |
34
+ | --- | --- |
35
+ | `katex` | MIT |
36
+ | `shiki`, `@shikijs/langs` | MIT |
37
+ | `mdast-util-*`, `micromark*`, `@types/mdast` | MIT |
38
+ | `anser` | MIT |
39
+ | `diff` | BSD-3-Clause |
40
+ | `@deepseek-ai/dsh-util-code-language` | MIT |
41
+ | `clsx` | MIT |
42
+ | `simple-icons` | CC0-1.0 (the drawn marks remain trademarks of their respective sites; `LinkIcon*` uses them only to identify the linked site) |
package/UPSTREAM.md ADDED
@@ -0,0 +1,56 @@
1
+ # Upstream synchronization
2
+
3
+ - Tag: `dsh-v0.2.0-rc.2`
4
+ - Commit: `639ed015397290b3745d163aafe02ffee4aa3f84`
5
+ - Primitives source: `packages/client/ui-primitives/src`
6
+ - Theme source: `packages/client/ui-theme/src/styles`
7
+
8
+ The TypeScript, CSS Modules, and eight theme sheets are synchronized from those paths. No `src/invariant.ts` is copied because the upstream no longer publishes a Cordis invariant companion.
9
+
10
+ > Baseline advanced `dsh-v0.1.7-rc.2` → `dsh-v0.2.0-rc.2` (2026-10-01), after the host's `@deepseek-ai/dsh-client-ui-primitives` moved to `0.2.0-rc.2`. A small step: 18 mirrored files changed, 2 added (`MenuGroup.*`), none removed; the eight theme sheets keep their order. New: `MenuGroup` + `observeStickyMenuGroups` (named menu sections with sticky headings) and the root export of `pointerModality`. Changed: `TextShimmer` is re-implemented as a masked decorative copy tinted by `--dsw-alias-label-shimmer` — `children` widens from `string` to `ReactNode`, `active` becomes optional, `contentClassName` is new, and nested instances share the outer sweep; `DisclosureRow` wraps its title and collapsed content in one shimmer (new `contentClassName` / `contentLayoutClassName`) and its row colour now drives the title (tertiary, secondary on hover); `Input` forwards its ref; `Tooltip` gains `openOnClick` (pinned, pointer-enterable bubble, outside-pointer dismissal), `focusDelayMs` and `aria-describedby` wiring; `useAnchoredPosition` and `overlay-top-margin` clear the frame strip by 20px and ignore it in fullscreen; `Menu` / `Modal` read `--dsh-frame-overlay-top` instead of `--dsh-frame-top-clearance` and the Modal mask starts below `--dsh-frame-chrome-top`; the unchecked upstream `Switch` thumb takes `--dsw-alias-switch-thumb`; two plugin-artwork colours changed. Tokens: +8 `--dsw-alias-*` (107 total: `bg-document-selection`, `label-deep-diving`, `label-deep-diving-shimmer`, `label-shimmer`, `switch-thumb`, `turn-trigger-bg`, `turn-trigger-bg-hover`, `menu-group-header-fill`); content font size range widens to 10–22px (comment only). Merged three-way as before; the only conflict was `Tooltip.tsx`'s import line (our context guard).
11
+ >
12
+ > Baseline advanced `dsh-v0.1.7-rc.1` → `dsh-v0.1.7-rc.2` (2026-09-25), the day after the host's `@deepseek-ai/dsh-client-ui-primitives` moved to `0.1.7-rc.2`. Upstream changed 46 mirrored files (9 primitives added, `OnboardingSurface.*` removed) and the theme sheets, which grew from six to eight (`focus.css`, `onboarding.css`). Visual: every hard-coded radius became a `--dsw-radius-xs/sm/md/lg/xl/panel` token (Button 18px → 12px, Toast 14 → 16, Modal 24 → 28), focus rings read `--dsw-focus-ring-width/color` and hide under `html[data-input-modality='pointer']`, `--dsw-mask-blur` is `none`, and menus paint through the new `MenuSurface` (`--dsw-menu-surface-fill`, opaque backing on macOS). New: `MenuSurface`, `ShortcutKeys` (also `Menu` item `shortcut` and `Tooltip` `shortcutKeys`), `useModalLayer` + `closeTopModal` / `isBehindModal` / `modalSelector` (now inside `Modal`: focus trap, `data-modal-autofocus`, return focus, `backdropBlur`), `focusWithoutRing`, `observeComposition`, `GuideArtworkBrowser` / `GuideArtworkFiles`, glyph `IconArchiveOff*` (188 icon exports). Tokens: +9 `--dsw-alias-*` (99 total). The mirror was merged three-way (Prettier-normalised rc.1 → rc.2 applied onto the local copy); the only conflicts were `index.ts` (our entry split) and `Tooltip.tsx` (our context guard), resolved below. The extension layer's own hard-coded radii were replaced with the same `--dsw-radius-*` tokens in the same wave, and its focus rings now declare only `outline-style: solid`, taking width and colour from `focus.css`'s global `:focus-visible` rule (so pointer-modality hiding applies to them too), so it keeps tracking the host.
13
+ >
14
+ > Baseline advanced `dsh-v0.1.5-rc.2` → `dsh-v0.1.7-rc.1` (2026-09-24), same day the host's `@deepseek-ai/dsh-client-ui-primitives` moved to `0.1.7-rc.1`. Upstream changed 79 primitives files (33 added, none removed) and the theme sheets. Breaking: all 75 product icons were renamed from a size suffix to a stroke-weight suffix (`IconCheckOutline16` → `IconCheckOutlineRegular` / `…Medium`, 186 exports; `Regular` is the old 1px look, the drawn size became the `size` default), `ReferenceIcon` / `LinkIcon` split into `…Regular` / `…Medium`, `ConnectionIndicator` dropped `reconnectLabel`, `DiffBlock` dropped its `files` label, `TerminalBlockLabels` gained `noExitCode`, and Read/Diff labels gained the code-toolbar trio. Tokens: +11 `--dsw-alias-*` (90 total), +4 static alpha steps, `--dsw-menu-backdrop-filter`, brighter `deepseek-400`, translucent `--dsw-specific-menu`, 5px scrollbars. The mirror was merged three-way (Prettier-normalised rc.2 → 0.1.7 applied onto the local copy), so every local adaptation below survived.
15
+ >
16
+ > Earlier: `dsh-v0.1.2-rc.1` → `dsh-v0.1.5-rc.2` (2026-09-11), briefly ahead of the npm runtime; the host moved the host's `@deepseek-ai/dsh-client-ui-primitives` to `0.1.5-rc.2` the same day, lifting the temporary ban on rc.2-only primitives (`Tag`, `Switch`, `FileTypeIcon`, `LinkIcon`, `IconGaugeOutline16`) and the `--dsw-alias-link` token in the extension layer. Upstream changed 34 primitives files (13 added, 19 modified, `markdown/MessageText.*` removed) and `design-platform.css` (new `--dsw-alias-link`, lighter Markdown inline code). Before this sync the mirror matched rc.1 except the adaptations below; eleven apparent differences were Prettier formatting only.
17
+ >
18
+ > Earlier: `dsh-v0.1.2-alpha.4` → `dsh-v0.1.2-rc.1` (2026-09-04) carried no source change.
19
+
20
+ Local packaging adaptations:
21
+
22
+ - Public APIs are split into root, blocks, markdown, icons, theme, and theme/bootstrap entries.
23
+ - `.ts`/`.tsx` source specifiers are rewritten in emitted declarations.
24
+ - CSS Modules are compiled to idempotent style injection code.
25
+ - KaTeX CSS is not imported by Markdown; the package publishes explicit woff2-only CSS and font assets. Re-applied on every sync: upstream `markdown/MarkdownText.tsx` imports `katex/dist/katex.min.css`.
26
+ - Theme persistence and bootstrap are standalone and do not use DSH settings or Cordis services.
27
+ - KaTeX's trusted generated markup uses an SSR-safe React wrapper instead of the upstream browser-only `DOMParser` conversion.
28
+ - `HoverCard` fixes the alpha.3 dark-surface foreground omission by explicitly using white text in both themes.
29
+ - The file/link icon family (`FileTypeIcon`, `classifyFileType`, `fileExtension`, `LinkIcon`, `classifyLinkPath` and their types) is exported from the `blocks` entry instead of the root: `FileTypeIcon` embeds ~57KB of code-file artwork (`code-file-icon-artwork.ts`) and `assertLightweightRoot` forbids the root from reaching it. `WebBlock` and the Markdown renderer already import it, so the blocks and markdown entries gain no weight.
30
+ - `MessageText` was removed upstream in rc.2 (`d0da8ccf40`); the `markdown` entry drops it too — a breaking change for 0.2.0 consumers of the standalone package.
31
+ - `code-file-icon-artwork.manifest.json` is copied as the upstream design record; no source imports it.
32
+ - `Tooltip` creates its suppression context only where React provides `createContext` (0.1.7): the `react-server` build has none, and a Server Component evaluates `Tooltip.tsx` through the root entry because the server-safe `Empty` imports `Button` from it. Upstream's module-level `createContext` call failed the `next16` fixture with `createContext is not a function`. Tooltip only renders on the client, so behaviour is unchanged. Since rc.2 upstream exports `TooltipSuppression` (HoverCard consumes it); the export is kept, still behind the guard. `TextShimmer`'s `DecorativeCopy` context (0.2.0) is created behind the same guard for the same reason: `DisclosureRow` pulls it into the root entry.
33
+ - Upstream exports `CodeToolbarLabels`, `CODE_HIGHLIGHT_EXTENSIONS`, `languageForPath`, `useCodeHighlighter` (and their types) from its root; they live in `blocks` here because they reach the Shiki highlighter, which `assertLightweightRoot` keeps off the root. `MarkdownDelegateProvider` and its types go to `markdown`; `PermissionIcon*`, `ReferenceIcon*`, `PluginArtwork*` and (rc.2) `GuideArtwork*` go to `icons`; `LinkIcon*` stays in `blocks` with the rest of the file/link family. `MenuSurface`, `ShortcutKeys`, `useModalLayer` and the focus / composition helpers stay on the root as upstream has them.
34
+ - Not mirrored: `PathLabel.*` and `settings-form/` (`SettingsForm`, `SettingsSecretField`, `SettingsValueField`, `SettingsFormModel`, `settingsNumberField`, `settingsTextField` and their types). They import `@deepseek-ai/dsh-util-workspace-path` and `@deepseek-ai/dsh-client-store` (zustand + immer, Cordis peer), which this Cordis-free standalone package does not take on; nothing here consumes them. Revisit when a consumer appears.
35
+ - Not mirrored: `ui-theme`'s opt-in `brand-font.css` with its three Montserrat woff2 files and OFL text. It is not one of the six theme sheets (upstream's `installThemeStyles` does not load it either); only the desktop welcome page uses it.
36
+ - Not mirrored: `BrandWordmark.tsx` and `FishLogo.tsx` (with `FISH_LOGO_PATH` / `FISH_LOGO_VIEWBOX`). They draw DeepSeek's wordmark and logo; MIT licenses the code, not the trademarks, so this public package ships no DeepSeek brand assets. Drop both files again on every sync.
37
+ - `simple-icons` (pinned `16.31.0`, same as upstream) is a runtime dependency: `LinkIcon*` draws known sites' marks through `SiteGlyph.tsx`.
38
+ - Type / lint-only edits, re-applied on every sync: `useRef<T | undefined>(undefined)` in `JsonTree.tsx` and `RefObject<… | null>` in `useAnchoredMaxHeight.ts` / `markdown/useViewportHighlighting.ts` (React 19 `@types/react`); `catch {}` without the unused binding in `markdown/file-link.ts` (root oxlint `no-unused-vars` is an error).
39
+
40
+ ## SeekBuddy extension layer (not synchronized)
41
+
42
+ `src/seekbuddy/` and the `@seekbuddy/dsh-ui/seekbuddy` entry family are SeekBuddy-owned and have no
43
+ upstream counterpart. Synchronization must leave that directory untouched, and nothing under it
44
+ may be copied back into the mirror. The build asserts every extension entry bundles only `src/seekbuddy/*`
45
+ (upstream primitives are consumed through the public `@seekbuddy/dsh-ui` entry, kept external).
46
+
47
+ `storybook/` is also SeekBuddy-owned and not synchronized: a self-contained Storybook island (own
48
+ `package.json` / `node_modules`, not a workspace member) that documents both layers by reading
49
+ `src/` directly. It never enters `dist/`, the npm `files` list, or any plugin bundle. Stories may
50
+ describe mirror-layer components (`parameters.docs.description`) but must not edit their source.
51
+
52
+ ## Repository origin
53
+
54
+ This repository is the source of truth for `@seekbuddy/dsh-ui`. It was created from the SeekBuddy monorepo's `packages/ui` (package `dsh-ui-primitives`) at commit `5db817380bfdb2ace334e814c1ed7f345feb4225`; that copy had itself been imported from `https://github.com/seekbuddy/dsh-ui-primitives` at `db5f935301b73acd7062256e48d05312f02e52c6`. Runtime identifiers keep the old name for compatibility with that copy: the style-injection attribute `data-dsh-ui-primitives` and the theme storage key `dsh-ui-primitives.theme-preference`.
55
+
56
+ - `tokens.css` is built from eight sheets since rc.2: `base`, `corner-shape`, `design-platform`, `focus`, `onboarding`, `scrollbar`, `gradient-shadow-text`, `shiki`, in upstream's `ui-theme/src/client/styles.ts` order. `input-modality.ts` publishes `data-input-modality` on `<html>` from module-level listeners; it is reached through `Tooltip`, so the root entry installs it in an app exactly as the host does.