@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
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Untrusted assistant-Markdown renderer over the direct mdast pipeline:
3
+ * `parse.ts` grammars, the incremental streaming parser, and `render.tsx`.
4
+ * While a message streams, all but the trailing two blocks freeze as cached
5
+ * React elements and only the source tail behind them re-parses per chunk,
6
+ * so per-chunk work tracks the tail size instead of the whole reply. Frozen
7
+ * blocks keep their source-offset keys when they cross the freeze boundary,
8
+ * so React reconciles instead of remounting. Known deviation while
9
+ * streaming: a reference-style link or footnote whose definition sits on the
10
+ * other side of the freeze boundary renders literally until the settled
11
+ * full parse self-heals it.
12
+ */
13
+ import type { MarkdownFileMentions, MarkdownLabels, MarkdownPathImages } from './render.js';
14
+ export type { MarkdownCodeLabels, MarkdownFileMentions, MarkdownLabels, MarkdownPathImages } from './render.js';
15
+ /**
16
+ * Render untrusted assistant-authored Markdown as semantic React elements.
17
+ * @param props - Markdown source text preserved by the session projection;
18
+ * `streaming` parses incrementally across chunks and highlights fences as
19
+ * they grow (each fence re-tokenizes only appended text; TeX stays literal
20
+ * until the finalize swap so incomplete formulae never flash errors);
21
+ * `labels` forwards localized fence and footnote chrome — pass a
22
+ * reference-stable object (memoized per locale revision), because a new
23
+ * identity discards the streaming render cache mid-message. `fileMentions`
24
+ * links inline-code tokens its resolver recognizes as real files, and
25
+ * `pathImages` rewrites image destinations that are local file paths into
26
+ * displayable URLs its resolver vouches for. Those two vocabularies are the
27
+ * single streaming gate — they apply to settled renders only, because a
28
+ * streaming message's vocabulary is not final and frozen cached elements
29
+ * must not bake in handlers that could go stale. A surrounding
30
+ * `MarkdownDelegateProvider` can delegate ordinary HTTP(S) activation while
31
+ * modified clicks retain native behavior. `variant="compact"` uses secondary
32
+ * text sizing, uniform bold headings, and tight block spacing; the default
33
+ * `body` variant uses the full document typography.
34
+ * The provider's `openFile` enables local Markdown links in settled messages,
35
+ * including `#L24` and `#L24-L30` destinations (ranges open at their first line).
36
+ * @returns A GFM document with TeX math rendered through KaTeX; raw HTML and
37
+ * unsafe protocols are disabled. Local links without an opener remain text;
38
+ * absolute HTTP(S) images render directly.
39
+ */
40
+ export declare const MarkdownText: import("react").MemoExoticComponent<({ text, streaming, labels, fileMentions, pathImages, variant, }: {
41
+ text: string;
42
+ streaming?: boolean;
43
+ labels: MarkdownLabels;
44
+ fileMentions?: MarkdownFileMentions | undefined;
45
+ pathImages?: MarkdownPathImages | undefined;
46
+ variant?: 'body' | 'compact';
47
+ }) => import("react").JSX.Element>;
@@ -0,0 +1,8 @@
1
+ /** Let asterisk strong emphasis close after punctuation when CJK prose continues without whitespace. */
2
+ import type { Extension } from 'micromark-util-types';
3
+ /**
4
+ * Extend CommonMark asterisk strong emphasis for punctuation-delimited CJK
5
+ * prose, as a micromark syntax extension for `fromMarkdown`.
6
+ * @returns The micromark syntax extension.
7
+ */
8
+ export declare function cjkFriendlyStrong(): Extension;
@@ -0,0 +1,12 @@
1
+ /** Local Markdown destinations accepted by the file-preview callback. */
2
+ /**
3
+ * Decode a file destination and its optional GitHub-style line fragment.
4
+ * Literal `?` and `#` in filenames must be percent-encoded.
5
+ * @param value - Parsed Markdown link destination.
6
+ * @returns A local path and optional first line, or undefined for URLs,
7
+ * fragment-only links, queries, malformed escapes, or invalid line ranges.
8
+ */
9
+ export declare function parseFileLink(value: string): {
10
+ path: string;
11
+ line?: number;
12
+ } | undefined;
@@ -0,0 +1,147 @@
1
+ /**
2
+ * The client's ONE syntax highlighter: a synchronous fine-grained shiki core
3
+ * (JavaScript regex engine — no oniguruma WASM, bundle-friendly) with an
4
+ * explicit grammar allowlist and a CSS-variables theme. Colors live in the
5
+ * theme package's token sheets as `--shiki-*` custom properties (light and
6
+ * dark blocks), never here — the repo's tokens-only styling rule.
7
+ *
8
+ * Only the three markdown-fence and `run_code` grammars (TypeScript, shell,
9
+ * JSON) load into the singleton at boot — the set every session renders. Every
10
+ * other language in the shared extension table
11
+ * (`@deepseek-ai/dsh-util-code-language`: python, rust, yaml, markup, …) is
12
+ * imported lazily and registered the first time such a language is requested,
13
+ * so a session that never opens a code surface in one of those languages pays
14
+ * neither the grammar modules nor their synchronous init. The first render of a
15
+ * lazy language falls back to plain text while its grammar loads, then
16
+ * {@link onGrammarLoaded} notifies subscribers to re-render with highlighting.
17
+ * An unknown or absent language falls back to plain text (no highlighting, still
18
+ * monospace) — never an error.
19
+ */
20
+ import type { CSSProperties } from 'react';
21
+ /**
22
+ * Resolve a language hint to the grammar id {@link LANG_ALIASES} selects.
23
+ * @param lang - Language hint from a code surface: a canonical grammar id or the read card's persisted short id.
24
+ * @returns The resolved grammar id, or `undefined` when the table aliases no grammar.
25
+ */
26
+ export declare function grammarForHint(lang: string | undefined): string | undefined;
27
+ /**
28
+ * Whether a language hint can use the shared syntax highlighter.
29
+ * @param lang - Language hint from a code surface.
30
+ * @returns Whether the hint resolves to a supported grammar.
31
+ */
32
+ export declare function supportsHighlighting(lang: string | undefined): boolean;
33
+ /**
34
+ * Subscribe to lazy-grammar load completions; `listener` fires after a
35
+ * {@link LAZY_GRAMMARS} grammar finishes registering on the singleton, so a
36
+ * caller that rendered its plain fallback while the grammar loaded can
37
+ * re-highlight. Uses the `useSyncExternalStore` subscribe signature; pair it with
38
+ * {@link grammarLoadCount} as the snapshot. Returns an unsubscribe function.
39
+ * @param listener - invoked (no args) on each grammar-load completion.
40
+ * @returns a disposer that removes the listener.
41
+ */
42
+ export declare function subscribeGrammarLoaded(listener: () => void): () => void;
43
+ /**
44
+ * The lazy-grammar load counter — a value that changes on every load, so a
45
+ * `useSyncExternalStore` snapshot re-renders the subscriber when a grammar
46
+ * registers. Opaque: only its identity across renders matters.
47
+ * @returns the current load count.
48
+ */
49
+ export declare function grammarLoadCount(): number;
50
+ /**
51
+ * Highlight `code` into shiki's HTML (a single `<pre class="shiki">` tree)
52
+ * when `lang` maps to a registered grammar; `undefined` means the caller
53
+ * renders its plain fallback. A lazy grammar not yet loaded returns `undefined`
54
+ * for this call and loads in the background; subscribe with
55
+ * {@link onGrammarLoaded} to re-highlight once it registers.
56
+ * @param code - the source text.
57
+ * @param lang - the language hint (a markdown fence info string or a fixed caller id).
58
+ * @returns the highlighted HTML, or `undefined` for unknown or not-yet-loaded languages.
59
+ */
60
+ export declare function highlightToHtml(code: string, lang: string | undefined): string | undefined;
61
+ /**
62
+ * One highlighted run of a line: the text and the inline style shiki assigned
63
+ * it. The css-variables theme colors every run through a `--shiki-*` custom
64
+ * property, so `style.color` is always present; it is held as a style object
65
+ * rather than a bare color so a run spreads onto a `<span style>` uniformly.
66
+ */
67
+ export interface HighlightSpan {
68
+ text: string;
69
+ style: CSSProperties;
70
+ }
71
+ /**
72
+ * Incremental highlighter for one growing streaming fence. TextMate
73
+ * tokenization is line-based and forward-only — a line's tokens depend only on
74
+ * its own text and the grammar state entering it — so appended text never
75
+ * changes a completed line's tokens. The session caches the spans of every
76
+ * completed line together with the grammar state after them;
77
+ * {@link updateFrame} reports only newly completed lines plus the still-growing
78
+ * last line, while {@link update} materializes the complete compatibility
79
+ * result. Per-call tokenization cost therefore excludes the completed prefix,
80
+ * and the result equals a from-scratch tokenization of the same code.
81
+ * Non-append input and a change of resolved grammar reset the cache and
82
+ * re-tokenize fully, so any input stays correct.
83
+ */
84
+ export declare class StreamingHighlightSession {
85
+ /** Grammar id the cache was built with; a different resolution resets it. */
86
+ private resolved;
87
+ /** Newline-terminated source prefix covered by {@link spans}. */
88
+ private prefix;
89
+ /** Cached spans, one entry per completed line of {@link prefix}. */
90
+ private spans;
91
+ /** Grammar state after {@link prefix}; undefined = the grammar's initial state. */
92
+ private state;
93
+ private lastCode;
94
+ private lastLang;
95
+ private lastResult;
96
+ private generation;
97
+ private lastFrame;
98
+ private reset;
99
+ /** Tokenize `text` with `resolved`, resuming from the cached grammar state when one exists. */
100
+ private tokenize;
101
+ /**
102
+ * Tokenize one update as a delta for a retained renderer.
103
+ * @param code - the fence text accumulated so far.
104
+ * @param lang - the language hint.
105
+ * @returns Newly completed lines plus the current tail, or `undefined` for the plain arm.
106
+ */
107
+ updateFrame(code: string, lang: string | undefined): StreamingHighlightFrame | undefined;
108
+ /**
109
+ * Tokenize the fence's current text into per-line highlighted runs;
110
+ * `undefined` means the caller renders its plain fallback. Idempotent per
111
+ * (`code`, `lang`) input — repeated calls return the identical result array —
112
+ * and a retained line keeps its span-array identity across growing calls, so
113
+ * a React caller can reuse cached line elements. A lazy grammar not yet
114
+ * loaded returns `undefined` and loads in the background exactly as
115
+ * {@link highlightToHtml} does; the next call after it registers highlights.
116
+ * @param code - the fence text accumulated so far (display-trimmed, no synthetic trailing newline).
117
+ * @param lang - the language hint (a markdown fence info string).
118
+ * @returns one entry per line of `code` (each an array of runs), or `undefined` for unknown or not-yet-loaded languages.
119
+ */
120
+ update(code: string, lang: string | undefined): readonly HighlightSpan[][] | undefined;
121
+ }
122
+ /** One retained-renderer update from {@link StreamingHighlightSession.updateFrame}. */
123
+ export interface StreamingHighlightFrame {
124
+ /** Changes whenever prior completed lines must be discarded. */
125
+ readonly generation: number;
126
+ /** Completed lines added since the preceding frame in this generation. */
127
+ readonly appended: readonly HighlightSpan[][];
128
+ /** The still-growing final line or lines, replaced by the next frame. */
129
+ readonly tail: readonly HighlightSpan[][];
130
+ }
131
+ /**
132
+ * Tokenize `code` into per-line highlighted runs when `lang` maps to a
133
+ * registered grammar; `undefined` means the caller renders its plain fallback.
134
+ * A line-numbered view needs the token runs split per line (one gutter number
135
+ * per line), which the single-`<pre>` {@link highlightToHtml} does not expose,
136
+ * so this returns shiki's own 2D line/token structure narrowed to what a run
137
+ * renders. Each run's color is a `--shiki-*` custom property, keeping token
138
+ * colors on the theme package's sheets exactly as the HTML path does; the
139
+ * markup font-style bits the theme lets through (bold/italic/underline in
140
+ * markdown scopes) are dropped — the line-numbered file view renders
141
+ * color-only runs. The trailing newline shiki appends as a final empty line
142
+ * is dropped so the run count matches the caller's own line array.
143
+ * @param code - the source text.
144
+ * @param lang - the language hint (a file-extension-derived language id).
145
+ * @returns one entry per source line (each an array of runs), or `undefined` for unknown or not-yet-loaded languages.
146
+ */
147
+ export declare function highlightLines(code: string, lang: string | undefined): HighlightSpan[][] | undefined;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Incremental block-level markdown parsing for an append-only text stream.
3
+ *
4
+ * Re-parsing the whole accumulated document on every streaming chunk is
5
+ * quadratic in the final reply length. CommonMark block parsing is line-based
6
+ * and appended text can only reshape the parse frontier — the last top-level
7
+ * block (a paragraph becoming a setext heading or a table, or a list
8
+ * continuing after a blank line) — so earlier blocks are final. This parser
9
+ * therefore freezes all but the trailing {@link UNSTABLE_TAIL_BLOCKS} blocks
10
+ * and re-parses only the source tail behind them. A final unclosed top-level
11
+ * fence cannot freeze as a block, so its completed content lines use a second
12
+ * frontier: only the last completed line and current partial line return
13
+ * through the caller's grammar. Each source region is therefore parsed a
14
+ * bounded number of times over the stream instead of once per chunk.
15
+ *
16
+ * The block freeze boundary comes from the parser's own `position` offsets.
17
+ * The cut sits at the *end offset* of the last frozen block (not the next
18
+ * block's start): a following block's start offset excludes up to three spaces
19
+ * of insignificant leading indentation, which is harmless to drop, but
20
+ * cutting at the previous end also keeps the inter-block blank lines in the
21
+ * tail so the sliced source stays verbatim. Fence scanning only recognizes a
22
+ * parser-confirmed code node and closing delimiter; ambiguous input returns to
23
+ * the normal tail parse.
24
+ *
25
+ * Known deviation, shared with any prefix-freeze scheme: micromark resolves
26
+ * reference-style links and footnotes document-wide at parse time, so a
27
+ * reference whose definition lands on the other side of the freeze boundary
28
+ * renders literally until the settled full parse self-heals it.
29
+ */
30
+ import type { Root, RootContent } from 'mdast';
31
+ /** A top-level mdast block plus a render key that is stable across chunks. */
32
+ export interface PositionedBlock {
33
+ /** The parsed block. Positions inside it are relative to its parse slice. */
34
+ readonly node: RootContent;
35
+ /**
36
+ * The block's start offset in the full source text. Stable from the frame
37
+ * a block first appears through freezing, so React reconciles rather than
38
+ * remounts when a block crosses the freeze boundary.
39
+ */
40
+ readonly key: number;
41
+ }
42
+ /** One {@link IncrementalMarkdownParser.update} result. */
43
+ export interface IncrementalBlocks {
44
+ /** Blocks that can no longer change; grows monotonically per generation. */
45
+ readonly frozen: readonly PositionedBlock[];
46
+ /** The re-parsed unstable tail (at most {@link UNSTABLE_TAIL_BLOCKS} blocks plus growth). */
47
+ readonly tail: readonly PositionedBlock[];
48
+ /** Bumped whenever non-append input discards the frozen prefix; callers drop caches keyed on it. */
49
+ readonly generation: number;
50
+ }
51
+ /**
52
+ * Append-only incremental parser over a caller-supplied grammar. One instance
53
+ * accumulates one streaming document; non-append input resets it.
54
+ */
55
+ export declare class IncrementalMarkdownParser {
56
+ private readonly parse;
57
+ private prevText;
58
+ private tailStart;
59
+ private frozen;
60
+ private generation;
61
+ private cached;
62
+ private openFence;
63
+ /** @param parse - Grammar shared with whatever renders the blocks, so boundaries agree. */
64
+ constructor(parse: (text: string) => Root);
65
+ /** Parse one unclosed-fence content slice through the caller's grammar. */
66
+ private fenceValue;
67
+ /** Recognize the parsed tail's final unclosed fence and prepare its incremental content frontier. */
68
+ private openFenceState;
69
+ /** Extend a recognized unclosed fence without parsing its completed content prefix again. */
70
+ private updateOpenFence;
71
+ /**
72
+ * Fold the current accumulated text and return the frozen/tail split.
73
+ * Idempotent for identical input (the previous result is returned as-is),
74
+ * so callers may invoke it from render paths that re-execute.
75
+ * @param text - The full accumulated markdown source.
76
+ * @returns Frozen and tail blocks with stream-stable render keys.
77
+ */
78
+ update(text: string): IncrementalBlocks;
79
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * TeX-to-React via KaTeX, replicating the rehype-katex pipeline this renderer
3
+ * replaced: the same three-arm error chain (strict render, `strict: 'ignore'`
4
+ * retry, error span). KaTeX emits a static span/MathML/SVG vocabulary with no
5
+ * raw user HTML, the same trusted innerHTML path shiki uses in CodeBlock. The
6
+ * stable wrapper keeps server rendering and hydration identical without a
7
+ * browser-only DOMParser dependency.
8
+ */
9
+ import type { ReactNode } from 'react';
10
+ /**
11
+ * Render TeX source to React elements through KaTeX.
12
+ * @param value - The TeX source (math node value; fenced `math` blocks append
13
+ * their trailing newline to match the replaced pipeline's text extraction).
14
+ * @param displayMode - Display (block) versus inline rendering.
15
+ * @returns KaTeX's element tree, or the error span when the source does not
16
+ * parse (colored with KaTeX's stock `errorColor`, matching rehype-katex).
17
+ */
18
+ export declare function renderTexToReact(value: string, displayMode: boolean): ReactNode;
@@ -0,0 +1,9 @@
1
+ /** Recover standalone local image references with bare spaces without changing code or source offsets. */
2
+ import type { Root } from 'mdast';
3
+ /**
4
+ * Recover only unambiguous, unescaped image-only paragraphs containing a local path with spaces.
5
+ * @param root - Parsed Markdown tree, modified in place.
6
+ * @param source - Original source used to distinguish authored syntax from escaped examples.
7
+ * @returns The same root with recovered image nodes.
8
+ */
9
+ export declare function recoverLocalImages(root: Root, source: string): Root;
@@ -0,0 +1,10 @@
1
+ /** Extend upstream dollar-only math syntax with TeX delimiters while reusing its token vocabulary. */
2
+ import type { Extension } from 'micromark-util-types';
3
+ /**
4
+ * TeX backslash delimiters and same-line display-dollar blocks as a micromark
5
+ * syntax extension reusing `micromark-extension-math`'s token vocabulary; the
6
+ * caller must also register `math()` on the same parse so the emitted tokens
7
+ * compile to standard math nodes.
8
+ * @returns The micromark syntax extension.
9
+ */
10
+ export declare function mathCompatibility(): Extension;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The markdown renderer's two mdast grammars, one per rendering arm. Each
3
+ * arm is internally consistent — the incremental tail parses, the one-shot
4
+ * parses, and the plain-text projection of a given grammar always agree on
5
+ * where blocks start and end — and the settled grammar is the streaming one
6
+ * plus the math extensions, so the arms differ only where TeX delimiters
7
+ * begin a math construct (a `$$` block is a paragraph while streaming and a
8
+ * math block once settled, by design).
9
+ */
10
+ import type { Root } from 'mdast';
11
+ /**
12
+ * Parse GFM markdown (the streaming arm's grammar: no math, so incomplete
13
+ * TeX never flashes KaTeX errors mid-stream).
14
+ * @param text - Markdown source.
15
+ * @returns The mdast root.
16
+ */
17
+ export declare function parseGfm(text: string): Root;
18
+ /**
19
+ * Parse GFM markdown plus TeX math with the compatibility delimiters
20
+ * (the settled arm's grammar).
21
+ * @param text - Markdown source.
22
+ * @returns The mdast root.
23
+ */
24
+ export declare function parseGfmWithMath(text: string): Root;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Markdown-to-plain-text projection for compact summaries and labels.
3
+ * Parsing shares the renderer's streaming GFM grammar ({@link parseGfm}), so
4
+ * the projection strips exactly the markup the renderer would draw; raw HTML
5
+ * stays literal, links keep their labels, images keep alt text, and code
6
+ * keeps its source text.
7
+ */
8
+ /** Amount of parsed Markdown content returned by the extractor. */
9
+ export type MarkdownPlainTextMode = 'all' | 'first-line' | 'first-paragraph';
10
+ /** Options for {@link extractMarkdownPlainText}. */
11
+ export interface MarkdownPlainTextOptions {
12
+ /** Projection boundary; defaults to the complete document. */
13
+ mode?: MarkdownPlainTextMode;
14
+ }
15
+ /**
16
+ * Parse GFM Markdown, remove its presentation markup, and preserve raw HTML literally.
17
+ * @param markdown - Markdown source.
18
+ * @param options - Optional extraction boundary.
19
+ * @returns Plain text for the whole document, first visible line, or first semantic paragraph.
20
+ */
21
+ export declare function extractMarkdownPlainText(markdown: string, options?: MarkdownPlainTextOptions): string;
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Direct mdast→React markdown renderer. Replaces the react-markdown /
3
+ * remark-rehype pipeline with one switch over parsed nodes so streaming can
4
+ * cache frozen blocks as React elements; the rendered DOM is pinned
5
+ * byte-for-byte by `tests/fixtures/markdown-dom` and must not drift.
6
+ *
7
+ * External link and image destinations pass a protocol allowlist; settled
8
+ * local file links use an explicit owner callback. Images additionally require
9
+ * absolute HTTP(S), raw HTML renders as literal text (no HTML enters the
10
+ * DOM), and KaTeX runs without trusted commands. Fragment-anchor URLs fail
11
+ * the allowlist, so footnote references and back-references render as plain
12
+ * text rather than in-page links.
13
+ *
14
+ * Merge-extensible node unions fall through the documented default (render
15
+ * nothing) rather than ending in assertNever: grammars registered elsewhere
16
+ * may add node types this renderer has no mapping for.
17
+ */
18
+ import type { ReactNode } from 'react';
19
+ import type * as Md from 'mdast';
20
+ import type { CodeToolbarLabels } from '../CodeToolbar.js';
21
+ import type { PositionedBlock } from './incremental.js';
22
+ /** Copy-button labels forwarded to fence CodeBlocks (this package is cordis-free, so copy arrives via props). */
23
+ export interface MarkdownCodeLabels {
24
+ /** Copy-button idle label. */
25
+ copyLabel: string;
26
+ /** Copy-button label during the post-copy confirmation window. */
27
+ copiedLabel: string;
28
+ /** Shared card controls; omitted for custom toolbar layouts. */
29
+ toolbarLabels?: CodeToolbarLabels | undefined;
30
+ }
31
+ /** Localized chrome for a Markdown document. */
32
+ export interface MarkdownLabels {
33
+ code: MarkdownCodeLabels;
34
+ footnotes: string;
35
+ }
36
+ /** Link/image reference targets collected from a document (first definition per identifier wins, as in CommonMark). */
37
+ export interface ReferenceTargets {
38
+ /** Link/image definitions keyed by upper-cased identifier. */
39
+ definitions: Map<string, Md.Definition>;
40
+ /** Footnote definitions keyed by upper-cased identifier. */
41
+ footnotes: Map<string, Md.FootnoteDefinition>;
42
+ }
43
+ /**
44
+ * Create an empty {@link ReferenceTargets}.
45
+ * @returns Fresh empty maps.
46
+ */
47
+ export declare function createReferenceTargets(): ReferenceTargets;
48
+ /**
49
+ * Record every definition and footnote definition under `nodes` into
50
+ * `targets`, depth-first, keeping the first definition per identifier.
51
+ * @param nodes - Subtrees to walk (top-level blocks or any nested children).
52
+ * @param targets - Accumulator, typically shared across incremental segments.
53
+ */
54
+ export declare function collectReferenceTargets(nodes: readonly Md.RootContent[], targets: ReferenceTargets): void;
55
+ /**
56
+ * Local-path image vocabulary for image destinations: the owner maps an
57
+ * authored destination that fails the remote-URL allowlist (an absolute local
58
+ * file path, for example) to a displayable URL it can vouch for. Absent
59
+ * wherever no such vocabulary exists, authored local destinations keep their
60
+ * documented fallback (the image's alt text). Rewritten destinations must be
61
+ * absolute; the renderer re-checks their protocol before emitting them.
62
+ */
63
+ export interface MarkdownPathImages {
64
+ /**
65
+ * Resolve one authored image destination.
66
+ * @param value - The destination exactly as the markdown author wrote it.
67
+ * @returns A displayable absolute URL, or undefined when the destination
68
+ * names no displayable image — it then stays inert alt text.
69
+ */
70
+ resolve(value: string): string | undefined;
71
+ }
72
+ /**
73
+ * File-mention affordance for inline code: the owner resolves an authored
74
+ * token to the file it names, using its own vocabulary of real files — the
75
+ * renderer never guesses at what looks like a path.
76
+ */
77
+ export interface MarkdownFileMentions {
78
+ /**
79
+ * Resolve one inline-code token.
80
+ * @param value - The authored token, exactly as written.
81
+ * @returns The opener with its accessible label and full-path title, or
82
+ * undefined when the token names no known file — it then stays inert code.
83
+ */
84
+ resolve(value: string): {
85
+ open: () => void;
86
+ label: string;
87
+ title: string;
88
+ } | undefined;
89
+ }
90
+ /**
91
+ * One render pass's state: immutable options and targets plus the footnote
92
+ * numbering accumulated in document order while references render.
93
+ */
94
+ export interface MarkdownRenderContext {
95
+ /** Streaming arm: fences highlight incrementally as they grow; TeX (including ```math fences) stays literal until the settled pass. */
96
+ readonly streaming: boolean;
97
+ /** Localized fence copy-button labels. */
98
+ readonly labels: MarkdownLabels;
99
+ /** Inside a blockquote's children: tables there always fill the quote's width. */
100
+ readonly inBlockquote?: boolean;
101
+ /** Inline-code file mentions; absent wherever no opener vocabulary exists. */
102
+ readonly fileMentions: MarkdownFileMentions | undefined;
103
+ /** Local-path image vocabulary; absent wherever no rewriting owner exists. */
104
+ readonly pathImages: MarkdownPathImages | undefined;
105
+ /** Inside an anchor's children: interactive mentions must not nest there. */
106
+ readonly inLink?: boolean;
107
+ /** Reference targets visible to this pass. */
108
+ readonly targets: ReferenceTargets;
109
+ /** Footnote identifiers in first-reference order; a footnote's number is its 1-based index here. */
110
+ readonly footnoteOrder: string[];
111
+ /** References rendered per identifier; drives the section's back-reference count. */
112
+ readonly footnoteCounts: Map<string, number>;
113
+ }
114
+ /**
115
+ * Render top-level blocks. Nodes that render nothing (definitions, unmapped
116
+ * types) are dropped rather than kept as null placeholders, matching the
117
+ * replaced pipeline's child lists so separator newlines land identically.
118
+ * @param blocks - Blocks with their stream-stable render keys.
119
+ * @param context - The pass state; footnote numbering mutates in document order.
120
+ * @returns One React node per rendered block.
121
+ */
122
+ export declare function renderBlocks(blocks: readonly PositionedBlock[], context: MarkdownRenderContext): ReactNode[];
123
+ /**
124
+ * Interleave the newline text nodes the replaced pipeline emitted between
125
+ * block-level children. They are invisible between elements but coalesce
126
+ * into adjacent literal raw-HTML text, where the DOM parity fixtures pin
127
+ * them.
128
+ * @param elements - Rendered block children with empty renders already dropped.
129
+ * @param edges - Also emit the leading and trailing newline (hast's loose wrap).
130
+ * @returns The interleaved children.
131
+ */
132
+ export declare function wrapBlockChildren(elements: readonly ReactNode[], edges: boolean): ReactNode[];
133
+ /**
134
+ * Render the trailing footnote section for every footnote referenced during
135
+ * the pass, in first-reference order, with one plain-text back-reference
136
+ * marker per rendered reference.
137
+ * @param context - The pass state after all blocks rendered.
138
+ * @returns The section, or null when no referenced footnote has a definition.
139
+ */
140
+ export declare function renderFootnoteSection(context: MarkdownRenderContext): ReactNode | null;
@@ -0,0 +1,10 @@
1
+ import type { RefObject } from 'react';
2
+ /**
3
+ * Activate one supported code surface when it first intersects the viewport.
4
+ * Activation lasts for the component lifetime; browsers without
5
+ * IntersectionObserver activate immediately.
6
+ * @param target - Code surface whose plain rendering reserves its geometry.
7
+ * @param lang - Optional language hint.
8
+ * @returns Whether this component may build highlighted output.
9
+ */
10
+ export declare function useViewportHighlighting(target: RefObject<Element | null>, lang: string | undefined): boolean;
@@ -0,0 +1,9 @@
1
+ export { CodeBlock } from './markdown/CodeBlock.js';
2
+ export type { CodeBlockProps } from './markdown/CodeBlock.js';
3
+ export { JsonBlock } from './markdown/JsonBlock.js';
4
+ export { MarkdownDelegateProvider } from './markdown/MarkdownDelegate.js';
5
+ export type { MarkdownDelegate, MarkdownDelegateProviderProps, MarkdownExternalLinkHandler, } from './markdown/MarkdownDelegate.js';
6
+ export { MarkdownText } from './markdown/MarkdownText.js';
7
+ export type { MarkdownCodeLabels, MarkdownFileMentions, MarkdownLabels, MarkdownPathImages, } from './markdown/MarkdownText.js';
8
+ export { extractMarkdownPlainText } from './markdown/plain-text.js';
9
+ export type { MarkdownPlainTextMode, MarkdownPlainTextOptions } from './markdown/plain-text.js';
@@ -0,0 +1,7 @@
1
+ /** Shared viewport inset for overlays, derived from the desktop frame's reserved top strip. */
2
+ /**
3
+ * Resolve the top margin an overlay keeps from the viewport edge.
4
+ * @param min - the overlay's own viewport margin in px, used as the floor.
5
+ * @returns the larger of `min` and the frame clearance plus 20px; fullscreen keeps only the 20px gap.
6
+ */
7
+ export declare function overlayTopMargin(min: number): number;
@@ -0,0 +1,16 @@
1
+ import type { IconProps } from './icons/props.js';
2
+ /** Light-blue terminal artwork shared by plugin cards and sidebar guide entries. */
3
+ export declare const PluginArtworkTerminal: ({ size, className }: IconProps) => import("react").JSX.Element;
4
+ /** Agent-loop plugin artwork (four leaves circling a center). */
5
+ export declare const PluginArtworkLoop: ({ size, className }: IconProps) => import("react").JSX.Element;
6
+ /** Subagent plugin artwork (two stacked rounded squares); also marks every row inside a bundle. */
7
+ export declare const PluginArtworkSubagent: ({ size, className }: IconProps) => import("react").JSX.Element;
8
+ /**
9
+ * Web-search plugin artwork (conic-gradient ring and handle). SVG has no
10
+ * native conic gradient, so the ring clips an HTML div painted with CSS
11
+ * `conic-gradient` — the same emulation Figma exports; it renders inline in
12
+ * the browser UI but would stay empty in an `<img>` or mask context.
13
+ */
14
+ export declare const PluginArtworkSearch: ({ size, className }: IconProps) => import("react").JSX.Element;
15
+ /** Default plugin artwork for plugins without one of their own (connector blocks and a node). */
16
+ export declare const PluginArtworkDefault: ({ size, className }: IconProps) => import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Grace before a pointer-dismissed popup closes. Covers the anchor->popup gap
3
+ * (8px for HoverCard, 4px for Menu) at a hand's travel speed without leaving a
4
+ * popup lingering once the pointer has genuinely moved on.
5
+ */
6
+ export declare const POINTER_GRACE_MS = 200;
7
+ /** Cancelable delayed close for a pointer-dismissed popup. */
8
+ export interface PointerGrace {
9
+ /** Schedule the close {@link POINTER_GRACE_MS} from now, replacing any pending one. */
10
+ arm: () => void;
11
+ /** Abort a pending close (the pointer came back). */
12
+ cancel: () => void;
13
+ }
14
+ /**
15
+ * Delay a pointer-dismissed popup's close so the pointer can cross the gap
16
+ * between anchor and popup. A pending close is dropped on unmount.
17
+ * @param close - runs when the grace elapses with no re-entry; read at fire
18
+ * time, so callers may pass a fresh closure each render.
19
+ * @returns the {@link PointerGrace} handle.
20
+ */
21
+ export declare function usePointerGrace(close: () => void): PointerGrace;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Shared ranking for `/` menu candidates: the query must be a
3
+ * case-insensitive ordered subsequence of the candidate name or, when the
4
+ * candidate carries one, of its display label (a localized title). Prefix
5
+ * hits rank first, then the strongest alignment score over either key, then
6
+ * the source order of the input. Decision record:
7
+ * .agents/notes/archived/feature/2026-08-04-web-slash-command-fuzzy-discovery.md
8
+ */
9
+ /**
10
+ * Rank named items by a menu query.
11
+ * @param items - candidates in source order (a host catalog, then client
12
+ * contributions); an item's optional `label` is a second search key beside
13
+ * its name.
14
+ * @param rawQuery - the text typed after the trigger, matched case-insensitively.
15
+ * @returns the matching items: prefix hits first, then by alignment score,
16
+ * then in source order. The input list itself for an empty query.
17
+ */
18
+ export declare function rankByName<T extends {
19
+ readonly name: string;
20
+ readonly label?: string;
21
+ }>(items: readonly T[], rawQuery: string): readonly T[];
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Compact relative-time bucketing shared by every surface that dates a
3
+ * session. Bucketing is here so two surfaces naming the same session agree;
4
+ * the words stay in each plugin's own dictionary, per locale-owned copy.
5
+ *
6
+ * @module @deepseek-ai/dsh-client-ui-primitives/relative-time
7
+ */
8
+ /** Relative-time bucket of a dated row's trailing label. */
9
+ export type RelativeTimeUnit = 'now' | 'minutes' | 'hours' | 'days' | 'months' | 'years';
10
+ /** Structured relative time: the bucket plus its magnitude (0 for 'now'). */
11
+ export interface RelativeTime {
12
+ unit: RelativeTimeUnit;
13
+ n: number;
14
+ }
15
+ /**
16
+ * Compact relative time, as a structured bucket the renderer localizes
17
+ * ("now"/"5min"/"3h"/"2d"/"4mo"/"1y" in en).
18
+ * @param at - epoch ms of the dated moment.
19
+ * @param now - current epoch ms (injected for pure rendering).
20
+ * @returns the row's trailing time bucket and magnitude.
21
+ */
22
+ export declare function relativeTime(at: number, now: number): RelativeTime;