@deepseek-ai/dsh-client-ui-primitives 0.0.1-rc.1

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 (49) hide show
  1. package/LICENSE +28 -0
  2. package/README.i18n.yaml +6 -0
  3. package/README.md +50 -0
  4. package/README.zh.md +50 -0
  5. package/lib/index.js +5680 -0
  6. package/lib/invariant.js +24 -0
  7. package/lib/types/BrandWordmark.d.ts +9 -0
  8. package/lib/types/Button.d.ts +18 -0
  9. package/lib/types/ConnectionBanner.d.ts +12 -0
  10. package/lib/types/DiffBlock.d.ts +34 -0
  11. package/lib/types/DisclosureRow.d.ts +29 -0
  12. package/lib/types/FishLogo.d.ts +9 -0
  13. package/lib/types/HoverCard.d.ts +24 -0
  14. package/lib/types/Input.d.ts +11 -0
  15. package/lib/types/JsonTree.d.ts +50 -0
  16. package/lib/types/Menu.d.ts +72 -0
  17. package/lib/types/Modal.d.ts +31 -0
  18. package/lib/types/OnboardingSurface.d.ts +11 -0
  19. package/lib/types/Pill.d.ts +13 -0
  20. package/lib/types/ReadBlock.d.ts +35 -0
  21. package/lib/types/RiskConfirmation.d.ts +19 -0
  22. package/lib/types/SearchBlock.d.ts +58 -0
  23. package/lib/types/StateDot.d.ts +15 -0
  24. package/lib/types/TerminalBlock.d.ts +67 -0
  25. package/lib/types/Tooltip.d.ts +30 -0
  26. package/lib/types/WebBlock.d.ts +48 -0
  27. package/lib/types/ansi.d.ts +17 -0
  28. package/lib/types/clipboard.d.ts +9 -0
  29. package/lib/types/head-tail-cap.d.ts +23 -0
  30. package/lib/types/icons/index.d.ts +150 -0
  31. package/lib/types/icons/props.d.ts +9 -0
  32. package/lib/types/index.d.ts +47 -0
  33. package/lib/types/invariant.d.ts +16 -0
  34. package/lib/types/markdown/CodeBlock.d.ts +14 -0
  35. package/lib/types/markdown/JsonBlock.d.ts +8 -0
  36. package/lib/types/markdown/MarkdownText.d.ts +38 -0
  37. package/lib/types/markdown/MessageText.d.ts +4 -0
  38. package/lib/types/markdown/cjkFriendlyStrong.d.ts +9 -0
  39. package/lib/types/markdown/highlight.d.ts +75 -0
  40. package/lib/types/markdown/incremental.d.ts +69 -0
  41. package/lib/types/markdown/katex.d.ts +27 -0
  42. package/lib/types/markdown/mathCompatibility.d.ts +11 -0
  43. package/lib/types/markdown/parse.d.ts +25 -0
  44. package/lib/types/markdown/plain-text.d.ts +22 -0
  45. package/lib/types/markdown/render.d.ts +112 -0
  46. package/lib/types/pointer-grace.d.ts +22 -0
  47. package/lib/types/use-copy-feedback.d.ts +14 -0
  48. package/lib/types/useAnchoredMaxHeight.d.ts +11 -0
  49. package/package.json +66 -0
@@ -0,0 +1,112 @@
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
+ * Untrusted-output policy (unchanged from the replaced pipeline): link and
8
+ * image destinations pass a protocol allowlist, 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 { PositionedBlock } from './incremental.ts';
21
+ /** Copy-button labels forwarded to fence CodeBlocks (this package is cordis-free, so copy arrives via props). */
22
+ export interface MarkdownCodeLabels {
23
+ /** Copy-button idle label. */
24
+ copyLabel?: string | undefined;
25
+ /** Copy-button label during the post-copy confirmation window. */
26
+ copiedLabel?: string | undefined;
27
+ }
28
+ /** Link/image reference targets collected from a document (first definition per identifier wins, as in CommonMark). */
29
+ export interface ReferenceTargets {
30
+ /** Link/image definitions keyed by upper-cased identifier. */
31
+ definitions: Map<string, Md.Definition>;
32
+ /** Footnote definitions keyed by upper-cased identifier. */
33
+ footnotes: Map<string, Md.FootnoteDefinition>;
34
+ }
35
+ /**
36
+ * Create an empty {@link ReferenceTargets}.
37
+ * @returns Fresh empty maps.
38
+ */
39
+ export declare function createReferenceTargets(): ReferenceTargets;
40
+ /**
41
+ * Record every definition and footnote definition under `nodes` into
42
+ * `targets`, depth-first, keeping the first definition per identifier.
43
+ * @param nodes - Subtrees to walk (top-level blocks or any nested children).
44
+ * @param targets - Accumulator, typically shared across incremental segments.
45
+ */
46
+ export declare function collectReferenceTargets(nodes: readonly Md.RootContent[], targets: ReferenceTargets): void;
47
+ /**
48
+ * File-mention affordance for inline code: the owner resolves an authored
49
+ * token to the file it names, using its own vocabulary of real files — the
50
+ * renderer never guesses at what looks like a path.
51
+ */
52
+ export interface MarkdownFileMentions {
53
+ /**
54
+ * Resolve one inline-code token.
55
+ * @param value - The authored token, exactly as written.
56
+ * @returns The opener with its accessible label and full-path title, or
57
+ * undefined when the token names no known file — it then stays inert code.
58
+ */
59
+ resolve(value: string): {
60
+ open: () => void;
61
+ label: string;
62
+ title: string;
63
+ } | undefined;
64
+ }
65
+ /**
66
+ * One render pass's state: immutable options and targets plus the footnote
67
+ * numbering accumulated in document order while references render.
68
+ */
69
+ export interface MarkdownRenderContext {
70
+ /** Streaming arm: fences render plain and TeX stays literal. */
71
+ readonly streaming: boolean;
72
+ /** Localized fence copy-button labels. */
73
+ readonly codeLabels: MarkdownCodeLabels | undefined;
74
+ /** Inline-code file mentions; absent wherever no opener vocabulary exists. */
75
+ readonly fileMentions: MarkdownFileMentions | undefined;
76
+ /** Inside an anchor's children: interactive mentions must not nest there. */
77
+ readonly inLink?: boolean;
78
+ /** Reference targets visible to this pass. */
79
+ readonly targets: ReferenceTargets;
80
+ /** Footnote identifiers in first-reference order; a footnote's number is its 1-based index here. */
81
+ readonly footnoteOrder: string[];
82
+ /** References rendered per identifier; drives the section's back-reference count. */
83
+ readonly footnoteCounts: Map<string, number>;
84
+ }
85
+ /**
86
+ * Render top-level blocks. Nodes that render nothing (definitions, unmapped
87
+ * types) are dropped rather than kept as null placeholders, matching the
88
+ * replaced pipeline's child lists so separator newlines land identically.
89
+ * @param blocks - Blocks with their stream-stable render keys.
90
+ * @param context - The pass state; footnote numbering mutates in document order.
91
+ * @returns One React node per rendered block.
92
+ */
93
+ export declare function renderBlocks(blocks: readonly PositionedBlock[], context: MarkdownRenderContext): ReactNode[];
94
+ /**
95
+ * Interleave the newline text nodes the replaced pipeline emitted between
96
+ * block-level children. They are invisible between elements but coalesce
97
+ * into adjacent literal raw-HTML text, where the DOM parity fixtures pin
98
+ * them.
99
+ * @param elements - Rendered block children with empty renders already dropped.
100
+ * @param edges - Also emit the leading and trailing newline (hast's loose wrap).
101
+ * @returns The interleaved children.
102
+ */
103
+ export declare function wrapBlockChildren(elements: readonly ReactNode[], edges: boolean): ReactNode[];
104
+ /**
105
+ * Render the trailing footnote section for every footnote referenced during
106
+ * the pass, in first-reference order, with one plain-text back-reference
107
+ * marker per rendered reference.
108
+ * @param context - The pass state after all blocks rendered.
109
+ * @returns The section, or null when no referenced footnote has a definition.
110
+ */
111
+ export declare function renderFootnoteSection(context: MarkdownRenderContext): ReactNode | null;
112
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1,22 @@
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;
22
+ //# sourceMappingURL=pointer-grace.d.ts.map
@@ -0,0 +1,14 @@
1
+ /** The copy-feedback hook's return: the transient flag and the copy handler. */
2
+ export interface CopyFeedback {
3
+ /** True for {@link COPIED_FEEDBACK_MS} after a successful write; render the success label off it. */
4
+ copied: boolean;
5
+ /** Copy the hook's text; no-op while `copied` is still true, silent on a refused write. */
6
+ onCopy: () => void;
7
+ }
8
+ /**
9
+ * Copy `text` to the clipboard with one-second success feedback.
10
+ * @param text - the text to write on copy.
11
+ * @returns the `copied` flag and the `onCopy` handler.
12
+ */
13
+ export declare function useCopyFeedback(text: string): CopyFeedback;
14
+ //# sourceMappingURL=use-copy-feedback.d.ts.map
@@ -0,0 +1,11 @@
1
+ import type { RefObject } from 'react';
2
+ /**
3
+ * Clamp a bottom-anchored overlay's max-height to the viewport.
4
+ * @param ref - the overlay element; a null current (overlay closed) skips measuring.
5
+ * @param cap - design max-height in px (the clamp never exceeds it).
6
+ * @param signal - re-measure trigger: pass the overlay's render state so anchor
7
+ * moves (composer growth) re-fit; resize/scroll re-fit while mounted.
8
+ * @returns the max-height to apply inline, in px.
9
+ */
10
+ export declare function useAnchoredMaxHeight(ref: RefObject<HTMLElement>, cap: number, signal: unknown): number;
11
+ //# sourceMappingURL=useAnchoredMaxHeight.d.ts.map
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@deepseek-ai/dsh-client-ui-primitives",
3
+ "description": "Pure React atoms for the dsh web UI: controls, icons, markdown, and JSON inspectors (zero cordis)",
4
+ "version": "0.0.1-rc.1",
5
+ "publishConfig": {
6
+ "access": "restricted"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
11
+ "directory": "packages/client/ui-primitives"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./invariant": {
22
+ "types": "./lib/types/invariant.d.ts",
23
+ "default": "./lib/invariant.js"
24
+ },
25
+ "./src/*": "./src/*",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "license": "BSD-3-Clause",
29
+ "dependencies": {
30
+ "@shikijs/langs": "^4.3.1",
31
+ "@types/mdast": "^4.0.4",
32
+ "anser": "^2.3.5",
33
+ "clsx": "^2.0.0",
34
+ "katex": "^0.16.47",
35
+ "mdast-util-from-markdown": "^2.0.3",
36
+ "mdast-util-gfm": "^3.1.0",
37
+ "mdast-util-math": "^3.0.0",
38
+ "micromark-core-commonmark": "^2.0.3",
39
+ "micromark-extension-gfm": "^3.0.0",
40
+ "micromark-extension-math": "^3.1.0",
41
+ "micromark-factory-space": "^2.0.1",
42
+ "micromark-util-character": "^2.1.1",
43
+ "micromark-util-classify-character": "^2.0.1",
44
+ "micromark-util-sanitize-uri": "^2.0.1",
45
+ "micromark-util-symbol": "^2.0.1",
46
+ "micromark-util-types": "^2.0.2",
47
+ "react": "^18.2.0",
48
+ "react-dom": "^18.2.0",
49
+ "shiki": "^4.3.1"
50
+ },
51
+ "devDependencies": {
52
+ "@types/react": "~18.3.1",
53
+ "@types/react-dom": "~18.3.0",
54
+ "@deepseek-ai/cordis": "^4.0.1-rc.1",
55
+ "@deepseek-ai/dsh-invariants": "^0.0.1-rc.1"
56
+ },
57
+ "files": [
58
+ "lib/index.js",
59
+ "lib/invariant.js",
60
+ "lib/types/**/*.d.ts"
61
+ ],
62
+ "peerDependencies": {
63
+ "@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
64
+ "@deepseek-ai/cordis": "^4.0.1-rc.1"
65
+ }
66
+ }