@qilin-agent/client-ui-primitives 3.1.3 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +38 -38
- package/README.md +8 -2
- package/README.zh.md +8 -2
- package/lib/CommandText.module.css +12 -0
- package/lib/MenuSurface.module.css +1 -1
- package/lib/index.js +964 -362
- package/lib/settings-form/SettingsForm.module.css +53 -0
- package/lib/settings-form/fields.module.css +145 -0
- package/lib/types/CommandText.d.ts +16 -0
- package/lib/types/TerminalBlock.d.ts +2 -0
- package/lib/types/darwin-desktop.d.ts +9 -0
- package/lib/types/icons/index.d.ts +3 -0
- package/lib/types/index.d.ts +9 -1
- package/lib/types/settings-form/SettingsForm.d.ts +46 -0
- package/lib/types/settings-form/fields.d.ts +70 -0
- package/lib/types/settings-form/form-model.d.ts +214 -0
- package/package.json +3 -2
package/README.i18n.yaml
CHANGED
|
@@ -5,57 +5,57 @@
|
|
|
5
5
|
/:
|
|
6
6
|
en: b6701ad9280c43fb
|
|
7
7
|
zh: bc1ed7854daac92e
|
|
8
|
-
/qilin-client-ui-primitives:
|
|
9
|
-
en:
|
|
10
|
-
zh:
|
|
11
|
-
/qilin-client-ui-primitives/summary:
|
|
12
|
-
en:
|
|
13
|
-
zh:
|
|
14
|
-
/qilin-client-ui-primitives/table-of-contents:
|
|
8
|
+
/qilin-agent-client-ui-primitives:
|
|
9
|
+
en: 77c8b257195e8d1c
|
|
10
|
+
zh: e14d896c8f1374c2
|
|
11
|
+
/qilin-agent-client-ui-primitives/summary:
|
|
12
|
+
en: cb45feeda688bec7
|
|
13
|
+
zh: bf5480fcaafc640e
|
|
14
|
+
/qilin-agent-client-ui-primitives/table-of-contents:
|
|
15
15
|
en: d152484eb41ac6b4
|
|
16
16
|
zh: 09388d293f9be9cb
|
|
17
|
-
/qilin-client-ui-primitives/use-this-package:
|
|
18
|
-
en:
|
|
19
|
-
zh:
|
|
20
|
-
/qilin-client-ui-primitives/use-this-package/component-catalog:
|
|
21
|
-
en:
|
|
22
|
-
zh:
|
|
23
|
-
/qilin-client-ui-primitives/use-this-package/controls-and-icons:
|
|
24
|
-
en:
|
|
25
|
-
zh:
|
|
26
|
-
/qilin-client-ui-primitives/use-this-package/rendering-agent-output:
|
|
17
|
+
/qilin-agent-client-ui-primitives/use-this-package:
|
|
18
|
+
en: ca3db95551971b07
|
|
19
|
+
zh: 083ba0e187ce544a
|
|
20
|
+
/qilin-agent-client-ui-primitives/use-this-package/component-catalog:
|
|
21
|
+
en: 070f2305cb51f06d
|
|
22
|
+
zh: a5cbfdded55ec641
|
|
23
|
+
/qilin-agent-client-ui-primitives/use-this-package/controls-and-icons:
|
|
24
|
+
en: d563c3a7f4eba0bc
|
|
25
|
+
zh: 49b6834de626eb6c
|
|
26
|
+
/qilin-agent-client-ui-primitives/use-this-package/rendering-agent-output:
|
|
27
27
|
en: 7aac8d4af442ee84
|
|
28
28
|
zh: 484000023a699d59
|
|
29
|
-
/qilin-client-ui-primitives/use-this-package/localizing-copy:
|
|
29
|
+
/qilin-agent-client-ui-primitives/use-this-package/localizing-copy:
|
|
30
30
|
en: 4aef65dea11de083
|
|
31
31
|
zh: abc22cd7c65cdf38
|
|
32
|
-
/qilin-client-ui-primitives/understand-the-implementation:
|
|
33
|
-
en:
|
|
34
|
-
zh:
|
|
35
|
-
/qilin-client-ui-primitives/understand-the-implementation/source-map:
|
|
36
|
-
en:
|
|
37
|
-
zh:
|
|
38
|
-
/qilin-client-ui-primitives/understand-the-implementation/input-modality:
|
|
32
|
+
/qilin-agent-client-ui-primitives/understand-the-implementation:
|
|
33
|
+
en: ff71d06c5d21ac81
|
|
34
|
+
zh: f5739d0e28e73552
|
|
35
|
+
/qilin-agent-client-ui-primitives/understand-the-implementation/source-map:
|
|
36
|
+
en: 5b8a88c0706a7c1c
|
|
37
|
+
zh: a3dcbfabffe4e5ec
|
|
38
|
+
/qilin-agent-client-ui-primitives/understand-the-implementation/input-modality:
|
|
39
39
|
en: 44dfc06332ca3b5b
|
|
40
40
|
zh: 94df10cde37c18e6
|
|
41
|
-
/qilin-client-ui-primitives/understand-the-implementation/streaming-markdown:
|
|
41
|
+
/qilin-agent-client-ui-primitives/understand-the-implementation/streaming-markdown:
|
|
42
42
|
en: 8bbfa14c27f3bfd7
|
|
43
43
|
zh: 88f7548ac3a114e1
|
|
44
|
-
/qilin-client-ui-primitives/understand-the-implementation/geometry-and-overflow:
|
|
45
|
-
en:
|
|
46
|
-
zh:
|
|
47
|
-
/qilin-client-ui-primitives/further-exploration:
|
|
48
|
-
en:
|
|
49
|
-
zh:
|
|
50
|
-
/qilin-client-ui-primitives/model-experience:
|
|
44
|
+
/qilin-agent-client-ui-primitives/understand-the-implementation/geometry-and-overflow:
|
|
45
|
+
en: 64cddabf7d398df4
|
|
46
|
+
zh: 0aad27f39486db06
|
|
47
|
+
/qilin-agent-client-ui-primitives/further-exploration:
|
|
48
|
+
en: 1ef5e5fdbe3d2436
|
|
49
|
+
zh: af5cb7ace2ab6e64
|
|
50
|
+
/qilin-agent-client-ui-primitives/model-experience:
|
|
51
51
|
en: 3120df665299c634
|
|
52
52
|
zh: 1d9f365d091d0d2a
|
|
53
|
-
/qilin-client-ui-primitives/model-experience/kv-cache-effect:
|
|
53
|
+
/qilin-agent-client-ui-primitives/model-experience/kv-cache-effect:
|
|
54
54
|
en: ca75c51c89c2c9b0
|
|
55
55
|
zh: de54f3467ef3b9be
|
|
56
|
-
/qilin-client-ui-primitives/known-limitations-and-deferred-work:
|
|
57
|
-
en:
|
|
58
|
-
zh:
|
|
59
|
-
/qilin-client-ui-primitives/known-limitations-and-deferred-work/dev-note:
|
|
56
|
+
/qilin-agent-client-ui-primitives/known-limitations-and-deferred-work:
|
|
57
|
+
en: de2ce8b129329ea0
|
|
58
|
+
zh: 53465e4a8255748a
|
|
59
|
+
/qilin-agent-client-ui-primitives/known-limitations-and-deferred-work/dev-note:
|
|
60
60
|
en: e67f633dc6fe7773
|
|
61
61
|
zh: 3bb0c20c93f16f98
|
package/README.md
CHANGED
|
@@ -48,6 +48,7 @@ Check this table before writing a control in a feature package. A plugin cannot
|
|
|
48
48
|
| `StateDot` | Status mark: `done`, `warning`, `ongoing`, `error`, or `idle`. `aria-hidden`, so the render site owns the name. |
|
|
49
49
|
| `ConnectionIndicator` | Inline connection-recovery control across outage, retry, and recovered states. |
|
|
50
50
|
| `DisclosureRow` | 24px compact disclosure that lays title and content side by side. |
|
|
51
|
+
| `CommandText` | One command line, gaining a Tab stop, a group role, and its accessible name only while it overflows horizontally. |
|
|
51
52
|
| `Modal` | Centered dialog over a page mask. |
|
|
52
53
|
| `RiskConfirmation` | Sensitive action gated behind an explicit checkbox. |
|
|
53
54
|
| `OnboardingSurface` | First-run stage that holds the application root inert. |
|
|
@@ -58,6 +59,7 @@ Check this table before writing a control in a feature package. A plugin cannot
|
|
|
58
59
|
| `JsonTree`, `JsonBlock` | Read-only JSON inspection. |
|
|
59
60
|
| `MarkdownText`, `MarkdownDelegateProvider`, `CodeBlock` | Untrusted GFM with TeX math, Mermaid diagrams, owner-delegated HTTP(S) navigation, and highlighted code. `CodeBlock` accepts opt-in `lineNumbers`; copied source excludes the gutter, and `contentRef` exposes its stable source wrapper to an owner that uses it as a scrollport. Set `showHeader={false}` when the owner supplies its own language and copy toolbar. |
|
|
60
61
|
| `TerminalBlock`, `ReadBlock`, `DiffBlock`, `SearchBlock`, `WebBlock` | The agent-output card matching each tool-result intent. |
|
|
62
|
+
| `SettingsForm`, `SettingsValueField`, `SettingsSecretField` | Staged configuration form over `SettingsFormModel`: fields report what the reader typed, and its save is the single point where a draft becomes a document mutation. |
|
|
61
63
|
| `icons/*`, `QilinSeal`, `ReferenceIcon`, `LinkIcon` | Glyphs and brand marks. Use `LinkIcon` for 14px clickable-link categories and known-site marks. |
|
|
62
64
|
| `FileTypeIcon`, `classifyFileType`, `fileExtension` | A category-colored 28px file or folder glyph and the shared case-insensitive filename mapping behind it. Code and configuration files use detailed full-color technology glyphs; use `LinkIcon` for link-leading glyphs and image previews for image content. |
|
|
63
65
|
|
|
@@ -72,7 +74,7 @@ Writing your own component in your own package is fine when the need is genuinel
|
|
|
72
74
|
|
|
73
75
|
### Controls and icons
|
|
74
76
|
|
|
75
|
-
The catalog above lists what each export is for; this section covers the behavior that props alone do not show. The `ic_ds_*` icon set fills the inline-icon slots, and the `QilinSeal` stamp is the brand mark. `FileTypeIcon` renders the traditional 28px Excel, folder, HTML, image, Markdown, generic, PDF, PPT, video, and Word glyphs, and uses the imported square technology artwork for the established 48 code and configuration categories. The import replaces artwork only: archive-only categories do not extend `CodeFileType`. `classifyFileType` applies exact filename, prefix, suffix, optional project-context, and extension rules in that order; React names win over TypeScript/JavaScript, Angular suffixes win over their base extension, and a Dart file becomes Flutter only when the supplied project files contain a `pubspec.yaml` with `flutter:`. Markdown and SVG remain traditional Markdown and image files. Office mappings include XLSM/Numbers as Excel, KEY as slides, and RTF/ODT/Pages as documents. `fileExtension` exposes the same basename and final-dot parsing for adjacent metadata labels. Traditional glyphs use a solid category-colored sheet with a white mark and translucent white corner; the generic file uses a grey sheet and darker grey corner. Callers may override the sheet color through `--qilin-file-type-icon-color`. The full-color technology artwork is the deliberate exception and retains its embedded palette. All glyphs are decorative and carry no label. `LinkIcon` remains the smaller leading glyph for clickable artifact links — globe, folder, code, image, document, or plain paper, and for a `url` link the mark of a well-known site named by its `href` — the developer sites a transcript usually cites (GitHub, GitLab, npm, PyPI, Stack Overflow, MDN, Wikipedia, Hacker News, YouTube, X, Bilibili, Zhihu, Juejin, CSDN) and mainstream search, video, social, shopping, and reference sites (Google, Baidu, DuckDuckGo, TikTok, Netflix, Spotify, Facebook, Instagram, Reddit, Telegram, WhatsApp, WeChat, QQ, Weibo, Taobao, AliExpress, eBay, Quora, V2EX, Apple) — while `classifyLinkPath` folds the shared file types into that existing six-category vocabulary. `ConnectionIndicator` renders a warning-colored disconnected action whose permanent retry glyph marks the retry action beside the owner-supplied outage label, a connecting spinner beside a label whose one-to-three dots advance every 500ms independently of retry timing, or a success-colored recovered status. Clicking either warning state requests an immediate reconnect; no hover interaction changes the copy. The pill fades in on appearance, fades out for 150ms before unmounting, and sizes to its current label. Its owner supplies visibility, the recovery hold, localized labels, and the immediate-reconnect callback; the primitive uses no native title tooltip. `useAnchoredPosition` and `useAnchoredMaxHeight` keep floating panels and bottom-anchored overlays clamped to the viewport and following their anchor. `HoverCard` keeps its portaled preview reachable across the anchor gap and can expose a copy button through the `copyText` prop. `Toast` holds for the window its owner names through `holdMs`, because how long a banner has to stay depends on how much there is to read; the same value drives its unmount timer and the stylesheet's fade delay, so the two cannot disagree. `rankByName` is the `/` menu's shared candidate ranker for the command and skill sources: the query must be a case-insensitive ordered subsequence of the name; prefix hits rank first, then alignment score, then source order. `Menu.autoFocus` focuses its first enabled item, supports Arrow Up/Down and Home/End navigation, and focuses the first button in the anchor on Escape; it is opt-in for action menus.
|
|
77
|
+
The catalog above lists what each export is for; this section covers the behavior that props alone do not show. The `ic_ds_*` icon set fills the inline-icon slots, and the `QilinSeal` stamp is the brand mark. Upstream weight-suffixed icon names (`Icon*OutlineRegular`, `Icon*OutlineMedium`) resolve as compat aliases to the nearest same-name size-suffixed glyph, and the two names without a drawn QiLin glyph (Users, WorkspaceTree) port the upstream artwork, so dsh-community plugins importing `@deepseek-ai/dsh-client-ui-primitives` render. `FileTypeIcon` renders the traditional 28px Excel, folder, HTML, image, Markdown, generic, PDF, PPT, video, and Word glyphs, and uses the imported square technology artwork for the established 48 code and configuration categories. The import replaces artwork only: archive-only categories do not extend `CodeFileType`. `classifyFileType` applies exact filename, prefix, suffix, optional project-context, and extension rules in that order; React names win over TypeScript/JavaScript, Angular suffixes win over their base extension, and a Dart file becomes Flutter only when the supplied project files contain a `pubspec.yaml` with `flutter:`. Markdown and SVG remain traditional Markdown and image files. Office mappings include XLSM/Numbers as Excel, KEY as slides, and RTF/ODT/Pages as documents. `fileExtension` exposes the same basename and final-dot parsing for adjacent metadata labels. Traditional glyphs use a solid category-colored sheet with a white mark and translucent white corner; the generic file uses a grey sheet and darker grey corner. Callers may override the sheet color through `--qilin-file-type-icon-color`. The full-color technology artwork is the deliberate exception and retains its embedded palette. All glyphs are decorative and carry no label. `LinkIcon` remains the smaller leading glyph for clickable artifact links — globe, folder, code, image, document, or plain paper, and for a `url` link the mark of a well-known site named by its `href` — the developer sites a transcript usually cites (GitHub, GitLab, npm, PyPI, Stack Overflow, MDN, Wikipedia, Hacker News, YouTube, X, Bilibili, Zhihu, Juejin, CSDN) and mainstream search, video, social, shopping, and reference sites (Google, Baidu, DuckDuckGo, TikTok, Netflix, Spotify, Facebook, Instagram, Reddit, Telegram, WhatsApp, WeChat, QQ, Weibo, Taobao, AliExpress, eBay, Quora, V2EX, Apple) — while `classifyLinkPath` folds the shared file types into that existing six-category vocabulary. `ConnectionIndicator` renders a warning-colored disconnected action whose permanent retry glyph marks the retry action beside the owner-supplied outage label, a connecting spinner beside a label whose one-to-three dots advance every 500ms independently of retry timing, or a success-colored recovered status. Clicking either warning state requests an immediate reconnect; no hover interaction changes the copy. The pill fades in on appearance, fades out for 150ms before unmounting, and sizes to its current label. Its owner supplies visibility, the recovery hold, localized labels, and the immediate-reconnect callback; the primitive uses no native title tooltip. `useAnchoredPosition` and `useAnchoredMaxHeight` keep floating panels and bottom-anchored overlays clamped to the viewport and following their anchor. `HoverCard` keeps its portaled preview reachable across the anchor gap and can expose a copy button through the `copyText` prop. `Toast` holds for the window its owner names through `holdMs`, because how long a banner has to stay depends on how much there is to read; the same value drives its unmount timer and the stylesheet's fade delay, so the two cannot disagree. `rankByName` is the `/` menu's shared candidate ranker for the command and skill sources: the query must be a case-insensitive ordered subsequence of the name; prefix hits rank first, then alignment score, then source order. `Menu.autoFocus` focuses its first enabled item, supports Arrow Up/Down and Home/End navigation, and focuses the first button in the anchor on Escape; it is opt-in for action menus.
|
|
76
78
|
|
|
77
79
|
### Rendering agent output
|
|
78
80
|
|
|
@@ -109,6 +111,8 @@ The package enforces one separation: presentational React atoms with zero Kylin
|
|
|
109
111
|
| [`src/index.ts`](src/index.ts) | Public atom exports |
|
|
110
112
|
| [`src/markdown/`](src/markdown/) | Markdown and math pipeline: micromark parsing, KaTeX typesetting, incremental streaming renderer, `CodeBlock`/`JsonBlock` |
|
|
111
113
|
| [`src/TerminalBlock.tsx`](src/TerminalBlock.tsx) | ANSI escape parsing (`anser`) and terminal card rendering |
|
|
114
|
+
| [`src/CommandText.tsx`](src/CommandText.tsx) | One command line's horizontal scrollport and its overflow-only accessible name |
|
|
115
|
+
| [`src/settings-form/`](src/settings-form/) | Staged configuration form, its field controls, and the draft/write model behind them |
|
|
112
116
|
| [`src/ReadBlock.tsx`](src/ReadBlock.tsx) / [`src/DiffBlock.tsx`](src/DiffBlock.tsx) | Read and diff cards |
|
|
113
117
|
| [`src/SearchBlock.tsx`](src/SearchBlock.tsx) / [`src/WebBlock.tsx`](src/WebBlock.tsx) | Search and web-retrieval cards |
|
|
114
118
|
| [`src/icons/`](src/icons/) | `ic_ds_*` glyph components and brand marks |
|
|
@@ -126,7 +130,7 @@ While a reply streams, `MarkdownText` parses incrementally: all but the trailing
|
|
|
126
130
|
|
|
127
131
|
### Geometry and overflow
|
|
128
132
|
|
|
129
|
-
The output cards share one geometry model: `white-space: pre` with horizontal scrolling so column-aligned content keeps its alignment, and a head-plus-tail slice behind an expand button past `maxLines` (default 16) so a long body never stretches the card. `TerminalBlock` parses ANSI into React spans with a per-line column buffer for cursor movement, honoring erase-in-line, tab stops, and character width.
|
|
133
|
+
The output cards share one geometry model: `white-space: pre` with horizontal scrolling so column-aligned content keeps its alignment, and a head-plus-tail slice behind an expand button past `maxLines` (default 16) so a long body never stretches the card. `TerminalBlock` uses `CommandText` to keep each authored command line selectable and horizontally scrollable; the prompt and status stay fixed. Only horizontally overflowing text enters the Tab order as a named group, using the owner's localized `commandLine(line)` label. `TerminalBlock` parses ANSI into React spans with a per-line column buffer for cursor movement, honoring erase-in-line, tab stops, and character width.
|
|
130
134
|
|
|
131
135
|
</details>
|
|
132
136
|
|
|
@@ -164,6 +168,8 @@ These limits define how the atoms behave at the edges; they are current package
|
|
|
164
168
|
- **Diff search is bounded, input processing is linear** — the edit-distance limit trades precise alignment for a coarse replacement on heavily changed fragments. Normalization, fallback rows, and copied output still scale with input size; the height cap limits visible rows, not those allocations.
|
|
165
169
|
- **Known-site marks are a fixed list** — only the named hosts resolve to their own mark, and every other external host keeps the globe; recognizing an arbitrary site would require fetching its icon over the network.
|
|
166
170
|
- **Streaming defers cross-boundary reference resolution** — a reference-style link or footnote whose definition sits on the other side of the incremental freeze boundary renders as literal text while the reply streams; the settled full parse at finalize resolves it.
|
|
171
|
+
- **Overlong lines stay uncolored** — a source line of 1,000 or more UTF-16 units renders as one plain run in every highlighted surface, because TextMate scanning cost grows superlinearly with line length and a single generated line can otherwise block the page for seconds. The grammar state skips that line, so a comment or template literal that opens or closes on it mis-colors the following line.
|
|
172
|
+
|
|
167
173
|
- **A long highlighted fence retains its complete token DOM** — streaming avoids re-parsing, re-tokenizing, and reconciling the completed prefix, but it does not discard old colors or virtualize token spans. Final DOM cardinality therefore still follows the fence's token count; nested/container fences and a pathological single long line remain on the general tail path.
|
|
168
174
|
- **Glyph-level icons are redrawn approximations** — the fish logo and the sparkle mark come from font glyphs whose vector geometry is not exportable from the local design data; hand-authored recreations stand in until an exact export path exists.
|
|
169
175
|
- **`Pill` and `Input` have no design source** — both atoms are self-defined; the sidebar search field and view-tab strip that resemble them are consumer-owned compositions, not these atoms.
|
package/README.zh.md
CHANGED
|
@@ -48,6 +48,7 @@ kind: "package-library"
|
|
|
48
48
|
| `StateDot` | 状态标记:`done`、`warning`、`ongoing`、`error` 或 `idle`。它是 `aria-hidden` 的,名称由渲染点提供。 |
|
|
49
49
|
| `ConnectionIndicator` | 行内连接恢复控件,覆盖断线、重试与已恢复三种状态。 |
|
|
50
50
|
| `DisclosureRow` | 24px 紧凑折叠行,标题与内容左右排列。 |
|
|
51
|
+
| `CommandText` | 一行命令文本:仅在横向溢出时才获得 Tab 停靠、group 角色与可访问名。 |
|
|
51
52
|
| `Modal` | 页面遮罩之上的居中对话框。 |
|
|
52
53
|
| `RiskConfirmation` | 以显式复选框把关的敏感操作确认。 |
|
|
53
54
|
| `OnboardingSurface` | 首次运行的引导舞台,期间保持应用根节点 inert。 |
|
|
@@ -58,6 +59,7 @@ kind: "package-library"
|
|
|
58
59
|
| `JsonTree`、`JsonBlock` | 只读 JSON 查看。 |
|
|
59
60
|
| `MarkdownText`、`MarkdownDelegateProvider`、`CodeBlock` | 不可信 GFM 与 TeX 数学、owner 委托的 HTTP(S) 导航,以及高亮代码。`CodeBlock` 可通过 `lineNumbers` 开启行号;复制的源码不含行号栏,`contentRef` 则向需要把稳定源码包装节点用作滚动区的 owner 提供该节点。调用方提供自己的语言与复制工具栏时,设置 `showHeader={false}`。 |
|
|
60
61
|
| `TerminalBlock`、`ReadBlock`、`DiffBlock`、`SearchBlock`、`WebBlock` | 与各类工具结果意图对应的 agent 输出卡片。 |
|
|
62
|
+
| `SettingsForm`、`SettingsValueField`、`SettingsSecretField` | 基于 `SettingsFormModel` 的分阶段配置表单:字段如实报告读者输入,保存是草稿变成文档变更的唯一入口。 |
|
|
61
63
|
| `icons/*`、`QilinSeal`、`ReferenceIcon`、`LinkIcon` | 字形与品牌标识。`LinkIcon` 用于 14px 的可点击链接分类及已知站点标记。 |
|
|
62
64
|
| `FileTypeIcon`、`classifyFileType`、`fileExtension` | 按类别着色的 28px 文件或文件夹图形,以及它背后共享的不区分大小写文件名映射。代码与配置文件使用细分的全彩技术图形;链接前置图形使用 `LinkIcon`,图片内容使用图片预览。 |
|
|
63
65
|
|
|
@@ -72,7 +74,7 @@ kind: "package-library"
|
|
|
72
74
|
|
|
73
75
|
### 控件与图标
|
|
74
76
|
|
|
75
|
-
上面的目录说明每个导出的用途;本节讲 props 本身看不出来的行为。`ic_ds_*` 图标集填充行内图标 slot,`QilinSeal`
|
|
77
|
+
上面的目录说明每个导出的用途;本节讲 props 本身看不出来的行为。`ic_ds_*` 图标集填充行内图标 slot,`QilinSeal` 印章是品牌标记。上游字重后缀图标名(`Icon*OutlineRegular`、`Icon*OutlineMedium`)按兼容别名解析到尺寸就近的同名字形,本集没有的两个名字(Users、WorkspaceTree)原样移植上游字形,使引用 `@deepseek-ai/dsh-client-ui-primitives` 的 dsh 社区插件可以正常渲染。`FileTypeIcon` 渲染传统的 28px Excel、folder、HTML、image、Markdown、generic、PDF、PPT、video 与 Word 图形,并为现有 48 个代码和配置类别使用导入的方形技术图形。该导入只替换图形:资源包中额外的类别不会扩展 `CodeFileType`。`classifyFileType` 按完整文件名、前缀、后缀、可选项目上下文、扩展名的顺序匹配;React 文件名优先于 TypeScript/JavaScript,Angular 后缀优先于基础扩展名,只有传入的项目文件包含带 `flutter:` 的 `pubspec.yaml` 时 Dart 文件才使用 Flutter。Markdown 与 SVG 仍分别使用传统 Markdown 与图片图形。办公文件映射包含 XLSM/Numbers 的表格图标、KEY 的幻灯片图标,以及 RTF/ODT/Pages 的文档图标。`fileExtension` 为相邻元数据 label 暴露同一套 basename 与最终点号解析。传统图形使用实色分类底板、白色标记和半透明白色折角;通用文件使用灰色底板与较深灰色折角。调用方可通过 `--qilin-file-type-icon-color` 覆盖底板颜色。全彩技术图形是明确例外,会保留其内嵌调色板。所有图形都是装饰性的,不自带 label。`LinkIcon` 仍是可点击产物链接较小的前置图形——地球、文件夹、代码、图片、文档或纸张,`url` 链接的 `href` 指向已知站点时则改用该站点自己的标记——转写内容常引用的开发者站点(GitHub、GitLab、npm、PyPI、Stack Overflow、MDN、Wikipedia、Hacker News、YouTube、X、Bilibili、知乎、掘金、CSDN),以及主流搜索、视频、社交、购物与参考资料站点(Google、百度、DuckDuckGo、TikTok、Netflix、Spotify、Facebook、Instagram、Reddit、Telegram、WhatsApp、微信、QQ、微博、淘宝、速卖通、eBay、Quora、V2EX、Apple)——`classifyLinkPath` 把共享文件类型折叠进原有六类词汇。`ConnectionIndicator` 可渲染警告色的断联操作(常驻重试图形指明重试动作,断联文案由持有方提供)、spinner 加一至三个点以独立于 retry 时序的 500ms 节奏推进的连接中状态,或成功色的恢复状态。点击任一警告状态都会请求立即重连;没有任何悬停交互会改变文案。药丸出现时淡入、卸载前淡出 150ms,宽度随当前 label 自适应。它的持有方提供可见性、恢复驻留时间、本地化 label 与立即重连回调;该原语不使用原生 title tooltip。`useAnchoredPosition` 与 `useAnchoredMaxHeight` 让浮动面板与底部锚定浮层始终钳制在视口内并跟随锚点。`HoverCard` 通过指针离开宽限期让采用 portal 的预览在跨过锚点间隙时仍可触及,并可通过 `copyText` prop 提供复制按钮。`Toast` 的停留时长由使用方通过 `holdMs` 指定,因为横幅该留多久取决于有多少内容要读;同一个值同时驱动它的卸载定时器与样式表的淡出延迟,两者不可能再错位。`rankByName` 是 `/` 菜单命令源与 skill(技能)源共享的候选排序器:查询必须是名字的不区分大小写的有序子序列;前缀命中排最前,其次按对齐分数,再按来源顺序。 `Menu.autoFocus` 聚焦首个启用项,支持上下方向键与 Home/End 导航,并在 Escape 时聚焦 anchor 内的第一个按钮;操作菜单可显式启用。
|
|
76
78
|
|
|
77
79
|
### 渲染 agent 输出
|
|
78
80
|
|
|
@@ -109,6 +111,8 @@ kind: "package-library"
|
|
|
109
111
|
| [`src/index.ts`](src/index.ts) | 原子组件公开导出 |
|
|
110
112
|
| [`src/markdown/`](src/markdown/) | Markdown 与数学公式流水线:micromark 解析、KaTeX 排版、增量流式渲染器、`CodeBlock`/`JsonBlock` |
|
|
111
113
|
| [`src/TerminalBlock.tsx`](src/TerminalBlock.tsx) | ANSI 转义解析(`anser`)与终端卡片渲染 |
|
|
114
|
+
| [`src/CommandText.tsx`](src/CommandText.tsx) | 单行命令的横向滚动区,以及仅在溢出时出现的可访问名 |
|
|
115
|
+
| [`src/settings-form/`](src/settings-form/) | 分阶段配置表单、其字段控件,以及背后的草稿/写入模型 |
|
|
112
116
|
| [`src/ReadBlock.tsx`](src/ReadBlock.tsx) / [`src/DiffBlock.tsx`](src/DiffBlock.tsx) | 读取与差异卡片 |
|
|
113
117
|
| [`src/SearchBlock.tsx`](src/SearchBlock.tsx) / [`src/WebBlock.tsx`](src/WebBlock.tsx) | 搜索与网页检索卡片 |
|
|
114
118
|
| [`src/icons/`](src/icons/) | `ic_ds_*` 字形组件与品牌标记 |
|
|
@@ -126,7 +130,7 @@ kind: "package-library"
|
|
|
126
130
|
|
|
127
131
|
### 几何与溢出
|
|
128
132
|
|
|
129
|
-
输出卡片共享同一套几何模型:`white-space: pre` 并横向滚动,让按列对齐的内容保持对齐;超过 `maxLines`(默认 16)时折叠为头部切片加尾部切片,由展开按钮控制,长正文不会撑高卡片。`TerminalBlock` 把 ANSI 解析为 React span,并带逐行列缓冲处理光标移动,遵循行内擦除、制表位与字符宽度。
|
|
133
|
+
输出卡片共享同一套几何模型:`white-space: pre` 并横向滚动,让按列对齐的内容保持对齐;超过 `maxLines`(默认 16)时折叠为头部切片加尾部切片,由展开按钮控制,长正文不会撑高卡片。`TerminalBlock` 用 `CommandText` 让每条作者写的命令行都可选中、可横向滚动;提示符与状态保持固定。只有横向溢出的文本才以具名 group 进入 Tab 顺序,名称取自 owner 本地化的 `commandLine(line)`。`TerminalBlock` 把 ANSI 解析为 React span,并带逐行列缓冲处理光标移动,遵循行内擦除、制表位与字符宽度。
|
|
130
134
|
|
|
131
135
|
</details>
|
|
132
136
|
|
|
@@ -164,6 +168,8 @@ kind: "package-library"
|
|
|
164
168
|
- **Diff 搜索有上限,输入处理仍为线性**:编辑距离上限使大量改动的片段采用粗粒度替换,不再精确对齐。规范化、回退行及复制内容仍随输入大小增长;高度限制只约束可见行数,不限制这些分配。
|
|
165
169
|
- **已知站点标记是固定列表**:只有列名的主机解析为自己的标记,其余外部主机仍使用地球;要识别任意站点需要通过网络抓取它的图标。
|
|
166
170
|
- **流式期间跨边界引用解析被推迟**:定义落在增量冻结边界另一侧的引用式链接或脚注,在回复流式输出期间渲染为字面文本;定稿时的全量解析会将其解析。
|
|
171
|
+
- **超长行不着色**:1,000 个 UTF-16 单元及以上的源码行在所有高亮面中渲染为单个纯文本 run,因为 TextMate 的扫描成本随行长超线性增长,一条生成出来的长行足以阻塞页面数秒。语法状态会跳过该行,因此在其上开启或结束的注释或模板字符串会让下一行着色错误。
|
|
172
|
+
|
|
167
173
|
- **长高亮 fence 会保留完整 token DOM**:流式路径避免重新解析、重新 tokenize 和 reconcile 已完成前缀,但不会丢弃旧颜色或虚拟化 token span。因此最终 DOM 数量仍随 fence 的 token 数增长;嵌套/容器内 fence 与病态的单个超长行仍走通用尾部路径。
|
|
168
174
|
- **字形级图标是重新绘制的近似版本**:鱼形标志与闪光标记来自字体字形,而本地设计数据无法导出其矢量几何;在获得精确导出路径前,使用手工重建版本代替。
|
|
169
175
|
- **`Pill` 与 `Input` 没有设计来源**:两个原子组件均自行定义;与其相似的侧边栏搜索字段和视图标签条由消费方组合,不是这些原子组件。
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
.text {
|
|
2
|
+
display: block;
|
|
3
|
+
min-width: 0;
|
|
4
|
+
overflow-x: auto;
|
|
5
|
+
white-space: var(--qilin-command-whitespace, pre);
|
|
6
|
+
overflow-wrap: anywhere;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.text:focus-visible {
|
|
10
|
+
outline: var(--qilin-focus-ring-width) solid var(--qilin-focus-ring-color, var(--qilin-alias-state-business-primary));
|
|
11
|
+
outline-offset: -2px;
|
|
12
|
+
}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
inset: 0;
|
|
24
24
|
z-index: -1;
|
|
25
25
|
border-radius: inherit;
|
|
26
|
-
background: var(--qilin-menu-surface-fill);
|
|
26
|
+
background: var(--qilin-menu-surface-fill, var(--qilin-specific-menu, var(--qilin-alias-bg-layer-2)));
|
|
27
27
|
backdrop-filter: var(--qilin-menu-backdrop-filter);
|
|
28
28
|
pointer-events: none;
|
|
29
29
|
}
|