dsh-claude-design-system 0.0.0-stage → 2.4.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 (30) hide show
  1. package/LICENSE +26 -0
  2. package/NOTICE.md +58 -0
  3. package/README.md +41 -2
  4. package/cordis.patch.yml +7 -0
  5. package/docs/DETAIL.md +27 -0
  6. package/docs/DETAIL.zh.md +16 -0
  7. package/icon.svg +11 -0
  8. package/lib/client.js +241 -0
  9. package/lib/index.js +342 -0
  10. package/locale/en.json +7 -0
  11. package/locale/zh.json +7 -0
  12. package/package.json +60 -4
  13. package/skills/claude-design-system/SKILL.md +252 -0
  14. package/skills/claude-design-system/artifact-type/demo.json +1 -0
  15. package/skills/claude-design-system/artifact-type/reference/cover.md +108 -0
  16. package/skills/claude-design-system/artifact-type/reference/craft.md +128 -0
  17. package/skills/claude-design-system/artifact-type/reference/format.md +206 -0
  18. package/skills/claude-design-system/artifact-type/reference/from-code.md +200 -0
  19. package/skills/claude-design-system/artifact-type/reference/from-design-tool.md +240 -0
  20. package/skills/claude-design-system/artifact-type/reference/sample-seazar-tokens.json +370 -0
  21. package/skills/claude-design-system/scripts/artifact.mjs +3061 -0
  22. package/skills/claude-design-system/scripts/editor/artifact-type/run.html +40 -0
  23. package/skills/claude-design-system/scripts/editor/artifact-type/vendor/react-dom.production.min.js +267 -0
  24. package/skills/claude-design-system/scripts/editor/artifact-type/vendor/react.production.min.js +31 -0
  25. package/skills/claude-design-system/scripts/editor/assets/anthropicons-fizzy-lake-taBimrpG.woff2 +0 -0
  26. package/skills/claude-design-system/scripts/editor/assets/index-BBq8YM1-.js +866 -0
  27. package/skills/claude-design-system/scripts/editor/assets/index-iALF7K4N.css +1 -0
  28. package/skills/claude-design-system/scripts/editor/index.html +19 -0
  29. package/skills/claude-design-system/scripts/editor/third-party-licenses.txt +566 -0
  30. package/skills/claude-design-system/scripts/server.mjs +1789 -0
package/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ This MIT License covers only the original work of Jim Liu 宝玉 in this repository
2
+ and in the baoyu-design npm packages. It does not cover the material from
3
+ Anthropic or the third-party open-source code listed in NOTICE.md, which keep
4
+ their own terms.
5
+
6
+ MIT License
7
+
8
+ Copyright (c) 2026 Jim Liu 宝玉
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
package/NOTICE.md ADDED
@@ -0,0 +1,58 @@
1
+ # Notices
2
+
3
+ baoyu-design holds material under three different sets of terms. The MIT License in [LICENSE](LICENSE) covers only the first. The same applies to the DeepSeek Harness plugins on npm, which ship this file next to their `LICENSE`.
4
+
5
+ [中文说明](#中文说明)
6
+
7
+ ## 1. The maintainer's own work: MIT
8
+
9
+ Copyright (c) 2026 Jim Liu 宝玉, under the MIT License in [LICENSE](LICENSE):
10
+
11
+ - The local tooling: each skill's `scripts/artifact.mjs` and, where there is one, `scripts/server.mjs` (the command line and the local editor server), the local comments, and what lets the editors run on a local machine instead of claude.ai.
12
+ - The DeepSeek Harness plugins' own code and files: `dsh-plugins/*/lib/`, `cordis.patch.yml`, `locale/`, `docs/` and `icon.svg`.
13
+ - The parts of the skills' text written for local agents: how to open and run the editors, local paths and files, comments.
14
+ - The READMEs, the changelogs, the images in `assets/` and the files in `.github/`.
15
+ - The maintainer's tools in `archive/baoyu-design/agents/`, apart from the open-source code vendored there (section 3).
16
+
17
+ ## 2. Material from Anthropic: not MIT
18
+
19
+ baoyu-design brings claude.ai's Artifact types and Claude Design to local agents, so much of what it ships comes from Anthropic, PBC. That material stays Anthropic's. Anthropic has published no license for it, apart from the one file in section 2.1, and this project grants none: the MIT License does not apply to it. It is included so the skills work as they do on claude.ai. This project is independent and is not affiliated with or endorsed by Anthropic.
20
+
21
+ - **Skill instructions.** Each `skills/claude-*/SKILL.md` adapts the SKILL.md of a claude.ai Artifact type. The maintainer's local-agent changes are described in section 1.
22
+ - **Reference docs.** `skills/*/artifact-type/reference/`, and the copies under `scripts/editor/artifact-type/`: the craft, format and layout guides, font lists and other references of the Artifact types.
23
+ - **The `dataviz` skill.** `skills/dataviz/` is Anthropic's dataviz skill. Its palette validators include code from Color.js (MIT, Lea Verou and Chris Lilley), credited in the files.
24
+ - **The editors.** `skills/claude-*/scripts/editor/` holds editors reconstructed from the claude.ai Artifact-type runtimes: their interface, wording and behaviour are Anthropic's. The built files mix that reconstruction with the maintainer's local additions (section 1) and with open-source packages (section 3).
25
+ - **Icon fonts.** The Anthropicons icon fonts: the `anthropicons-*.woff2` files in the editors' `assets/` and `artifact-type/` folders, and the Anthropicons font faces embedded as data URIs in the editors' CSS.
26
+ - **The archived `baoyu-design` skill.** In `archive/baoyu-design/`: `system-prompt.md`, `references/upstream-system-prompt.md` and `references/upstream-sync/` (the Claude Design system prompt, a snapshot of it and its sync records), `built-in-skills/` (Claude Design's built-in skills) and `starter-components/` (Claude Design's starter components; the local patches are recorded in the `*-patch.md` files there).
27
+
28
+ ### 2.1 frontend-design: Apache License 2.0
29
+
30
+ `archive/baoyu-design/built-in-skills/frontend-design.md` is Claude Design's copy of Anthropic's frontend-design skill, which Anthropic publishes under the Apache License 2.0. The full license text is in [`archive/baoyu-design/built-in-skills/LICENSE-frontend-design.txt`](archive/baoyu-design/built-in-skills/LICENSE-frontend-design.txt). The file was changed from the original: its frontmatter was rewritten for the built-in-skill format (its `license` line records the change), and its text follows the version Claude Design ships.
31
+
32
+ ## 3. Third-party open-source code
33
+
34
+ The editors bundle open-source packages, such as React, Base UI, d3 and pptxgenjs. Each keeps its own license, which this project's license does not replace. The licenses are in each editor's `scripts/editor/third-party-licenses.txt`, and for the slides compiler in `scripts/editor/node/third-party-licenses.txt`.
35
+
36
+ The archived `baoyu-design` skill vendors React, ReactDOM, Babel and fflate (MIT) in `archive/baoyu-design/agents/vendor/`, and pptxgenjs (MIT) in `archive/baoyu-design/agents/gen-pptx/vendor/pptxgenjs/`, with its `LICENSE`.
37
+
38
+ ## Questions and removal
39
+
40
+ If you hold rights in anything here and want it credited differently, changed or removed, open an issue at <https://github.com/JimLiu/baoyu-design/issues>.
41
+
42
+ ## 中文说明
43
+
44
+ 本仓库(以及 npm 上的 DeepSeek Harness 插件)里的内容分三类,许可各不相同。[LICENSE](LICENSE) 里的 MIT 许可只管第一类。
45
+
46
+ 1. **维护者自己写的部分,MIT。** 本地命令行和编辑器服务器(各技能的 `scripts/artifact.mjs`,以及有的技能带的 `scripts/server.mjs`)、本地评论、让编辑器离开 claude.ai 在本机运行的那部分代码;DeepSeek Harness 插件自己的代码和文件(`dsh-plugins/*/lib/`、`cordis.patch.yml`、`locale/`、`docs/`、`icon.svg`);技能说明里为本地 Agent 写的部分;README、更新日志、`assets/` 里的图片、`.github/`;`archive/baoyu-design/agents/` 里维护者写的工具。
47
+ 2. **取自 Anthropic 的部分,不适用 MIT。** 权利归 Anthropic。除 frontend-design 外,Anthropic 没有为这些内容公开许可,本项目也不授予任何许可。包括:
48
+ - 各 `skills/claude-*/SKILL.md` 所改编的 Artifact 类型技能说明;
49
+ - `artifact-type/reference/` 里的参考文档;
50
+ - `skills/dataviz/`(Anthropic 的 dataviz 技能);
51
+ - `scripts/editor/` 里从 claude.ai 运行时还原的编辑器(界面、文案和行为);
52
+ - Anthropicons 图标字体(`anthropicons-*.woff2` 文件,以及编辑器 CSS 里内嵌的字体);
53
+ - `archive/baoyu-design/` 里的 Claude Design 系统提示词、内置技能和起步组件。
54
+
55
+ `archive/baoyu-design/built-in-skills/frontend-design.md` 取自 Anthropic 以 Apache License 2.0 发布的 frontend-design 技能,许可全文见同目录的 `LICENSE-frontend-design.txt`。
56
+ 3. **第三方开源代码,各按原许可。** 编辑器打进去的开源包(React、Base UI、d3、pptxgenjs 等)的许可见各编辑器的 `scripts/editor/third-party-licenses.txt`;归档技能里内置的 React、Babel、fflate、pptxgenjs 见 `archive/baoyu-design/agents/vendor/` 和 `agents/gen-pptx/vendor/pptxgenjs/LICENSE`。
57
+
58
+ 本项目是独立的社区项目,与 Anthropic 无隶属或背书关系。权利人希望调整署名、修改或移除某部分内容,请在 <https://github.com/JimLiu/baoyu-design/issues> 提 issue。
package/README.md CHANGED
@@ -1,3 +1,42 @@
1
- # Temporary Holding Version
1
+ # dsh-claude-design-system
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
+ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin that adds the **claude-design-system**
4
+ skill from [baoyu-design](https://github.com/JimLiu/baoyu-design): the agent writes design systems (tokens, type,
5
+ components, assets and a brand book) as files in your workspace, built from a code repository, a design tool or
6
+ scratch, and opens them in a local design-system page, where you can browse and edit them.
7
+
8
+ ## Install
9
+
10
+ In the DeepSeek Harness desktop app: **Plugins** → **Add plugin** → enter `dsh-claude-design-system` in **Package name
11
+ or address** → **Install**, and turn the plugin on. From the command line, for a CLI profile such as `web`:
12
+
13
+ ```sh
14
+ dsh plugin --profile web add dsh-claude-design-system
15
+ ```
16
+
17
+ Then quit and reopen the app, start a new session, and ask for a design system, or type `/claude-design-system`. A
18
+ workspace that has its own `claude-design-system` skill (in `.agents/skills/` or `.dsh/skills/`) uses that copy instead
19
+ of this plugin's.
20
+
21
+ To update, uninstall the plugin, install it again, and quit and reopen the app. For a day after a release the app's
22
+ package manager (pnpm) still picks the previous version; to get the new one sooner, enter the name with the version,
23
+ such as `dsh-claude-design-system@2.4.0`.
24
+
25
+ ## What is inside
26
+
27
+ - `skills/claude-design-system/`: the skill as baoyu-design publishes it (`SKILL.md`, `artifact-type/reference/`, and
28
+ the prebuilt `scripts/`: the page, `artifact.mjs`, and its server).
29
+ - `lib/index.js`: the plugin. It registers the skill with the Harness skill registry and, when the skill loads, tells
30
+ the agent which Node executable runs `scripts/artifact.mjs`: the Host's own Node, the Node runtime the desktop app
31
+ ships, or `node` on PATH. Set `node` in the `claude-design-system` row's config to choose another. Whenever the agent
32
+ opens the page, the plugin also waits for comments, so a comment's **Send to agent** box is there: send one and the
33
+ agent wakes up, changes the system, and replies in the comment.
34
+ - `lib/client.js`: the part that runs in the app's window. It shows a comment sent to the agent as a card in the chat;
35
+ **View thread** on the card opens it in the page.
36
+ - `cordis.patch.yml`: the bundle layer that mounts the plugin row.
37
+
38
+ The page's server listens on 127.0.0.1 only and reads and writes only the design system's folder.
39
+
40
+ ## License
41
+
42
+ Not all MIT. The plugin's own code and files (`lib/`, `cordis.patch.yml`, `locale/`, `docs/`, `icon.svg`) and the skill's local tooling are MIT, in `LICENSE`. The bundled `claude-design-system` skill is adapted from Anthropic's claude.ai Design System type: its instructions, references, page and icon fonts stay Anthropic's and are not under the MIT License. `NOTICE.md` sets out which is which. The page's open-source licenses are in `skills/claude-design-system/scripts/editor/third-party-licenses.txt`.
@@ -0,0 +1,7 @@
1
+ # dsh-claude-design-system bundle patch: installing the package (the Plugins page, or
2
+ # `dsh plugin --profile <name> add <spec>`) adds it to the profile's bundles,
3
+ # and this layer mounts its one plugin row, which registers the claude-design-system
4
+ # skill with the profile's skill registry.
5
+ - insert:
6
+ - id: claude-design-system
7
+ name: dsh-claude-design-system
package/docs/DETAIL.md ADDED
@@ -0,0 +1,27 @@
1
+ # Claude Design System
2
+
3
+ Adds the **claude-design-system** skill to DeepSeek Harness. Ask for a design system ("a design system from this
4
+ repo's styles", "a brand kit for a tea shop") and the agent writes it as files in your workspace: a folder with
5
+ `project/design-system.json`, `tokens.json`, a README brand book, component previews, fonts and assets. It then starts
6
+ a local design-system page and gives you its link. claude-slides and claude-design can use the systems it makes.
7
+
8
+ ## Using it
9
+
10
+ - Ask for a design system in plain words, or type `/claude-design-system` to call the skill by name.
11
+ - Open the link the agent gives you. In the desktop app it opens in the right sidebar's Browser, beside the
12
+ conversation (Settings → General → Open chat links in: **In-App Sidebar**, the default).
13
+ - On the page you browse and edit the tokens, colors, type, components and assets. Your edits are saved back into the
14
+ same files, and the agent's changes show up in the page as it writes them.
15
+ - Comment on a token, color, type style, component, asset or section (Comment, or C). Tick **Send to agent** and the
16
+ agent picks it up at once, even when the conversation is idle: it changes the system and replies in the comment. The
17
+ comment also shows in the chat as a card; **View thread** on the card opens it in the page. The box is there while
18
+ comments can reach the agent, which starts each time it gives you the link. After restarting the app, ask the agent
19
+ to open the system again to bring it back.
20
+ - To change a system later, ask the agent to revise the folder that holds its `project/design-system.json`.
21
+ - A workspace that has its own `claude-design-system` skill (in `.agents/skills/` or `.dsh/skills/`) uses that copy
22
+ instead of this plugin's.
23
+
24
+ ## What runs where
25
+
26
+ The page is served by a small server on 127.0.0.1 that the skill's script starts in the background, one per system.
27
+ It reads and writes only that system's folder. The desktop app's own Node runtime runs it; nothing else is installed.
@@ -0,0 +1,16 @@
1
+ # Claude 设计系统
2
+
3
+ 给 DeepSeek Harness 加上 **claude-design-system** 技能。让 Agent 做一套设计系统("从这个仓库的样式整理一套设计系统"、"给一家茶饮店做一套品牌规范"),它会在工作区里把设计系统写成文件:一个文件夹,里面有 `project/design-system.json`、`tokens.json`、README 品牌手册、组件预览、字体和素材。写完它会启动本地设计系统页面,把链接给你。claude-slides 和 claude-design 都可以套用它做出来的设计系统。
4
+
5
+ ## 怎么用
6
+
7
+ - 直接用自然语言要设计系统,或者输入 `/claude-design-system` 点名调用这个技能。
8
+ - 打开 Agent 给的链接。桌面版里它会在右侧栏的浏览器里打开,和对话并排(设置 → 通用 → 聊天链接打开方式:**应用内侧栏**,默认就是这个)。
9
+ - 页面上可以浏览和修改设计令牌、颜色、字体样式、组件和素材。你的修改会存回同一批文件;Agent 写的改动也会实时出现在页面上。
10
+ - 可以给某个令牌、颜色、字体样式、组件、素材或章节加评论(点评论按钮或按 C)。勾上 **Send to agent** 发出去,Agent 会马上接手,对话空闲时也一样:它改好设计系统,再在评论里回复你。评论也会以卡片的形式出现在对话里,点卡片上的 **View thread**(中文界面是「查看评论」)会在页面里打开这条评论。这个勾选框只在评论能发给 Agent 时出现;Agent 每次给你页面链接时都会开始等评论。重启应用后,让 Agent 再打开一次这套设计系统就能恢复。
11
+ - 以后要改,让 Agent 修改那个装着 `project/design-system.json` 的文件夹即可。
12
+ - 如果工作区自己带了 `claude-design-system` 技能(在 `.agents/skills/` 或 `.dsh/skills/` 里),这个工作区会用它自己那份,而不是插件里的。
13
+
14
+ ## 运行方式
15
+
16
+ 页面由技能脚本在后台启动的一个本地服务(127.0.0.1)提供,一套设计系统一个,只读写这套设计系统自己的文件夹。用的是桌面版自带的 Node,不需要另外安装任何东西。
package/icon.svg ADDED
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="14" fill="#D97757"/>
3
+ <rect x="12" y="12" width="40" height="40" rx="4" fill="#FFF7F2"/>
4
+ <circle cx="22" cy="22" r="5" fill="#D97757"/>
5
+ <circle cx="32" cy="22" r="5" fill="#E9B8A3"/>
6
+ <circle cx="42" cy="22" r="5" fill="#8A4B33"/>
7
+ <rect x="17" y="32" width="14" height="3.5" rx="1.75" fill="#D97757"/>
8
+ <rect x="17" y="39" width="22" height="2.5" rx="1.25" fill="#E9B8A3"/>
9
+ <rect x="35" y="31" width="12" height="6" rx="3" fill="#D97757"/>
10
+ <rect x="17" y="44" width="16" height="2.5" rx="1.25" fill="#E9B8A3"/>
11
+ </svg>
package/lib/client.js ADDED
@@ -0,0 +1,241 @@
1
+ // dsh-claude-design-system 2.4.1: built from baoyu-design.
2
+ window.__ModuleLoader__.load({
3
+ id: "dsh-claude-design-system",
4
+ factory: (require) => {
5
+ var module = { exports: {} };
6
+ var exports = module.exports;
7
+ "use strict";
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+
26
+ var client_exports = {};
27
+ __export(client_exports, {
28
+ apply: () => apply,
29
+ inject: () => inject
30
+ });
31
+ module.exports = __toCommonJS(client_exports);
32
+
33
+ var define_CLIENT_default = { plugin: "dsh-claude-design-system", key: "dsh-claude-design-system", simple: false };
34
+
35
+ var import_react = require("react");
36
+ var import_jsx_runtime = require("react/jsx-runtime");
37
+ var CLIENT = define_CLIENT_default;
38
+ var COMMENT_SOURCE = "baoyu-design-comment";
39
+ var KIND = `${CLIENT.key}:comment`;
40
+ var NS = CLIENT.key;
41
+ var zh = {
42
+ "card.title": "已将对“{title}”的评论发给 Agent",
43
+ "card.request": "已将“{title}”上的 {label} 发给 Agent",
44
+ "card.view": "查看评论",
45
+ "card.more": "显示位置",
46
+ "card.less": "收起位置"
47
+ };
48
+ var en = {
49
+ "card.title": "Comment on “{title}” sent to agent",
50
+ "card.request": "{label} on “{title}” sent to agent",
51
+ "card.view": "View thread",
52
+ "card.more": "Show where",
53
+ "card.less": "Hide where"
54
+ };
55
+ var str = (value) => typeof value === "string" ? value : "";
56
+ function ours(event) {
57
+ if (event.type !== "user/message" || event.surfaceOp !== "append") return false;
58
+ const source = event.data?.source;
59
+ return source?.kind === COMMENT_SOURCE && source.plugin === CLIENT.plugin;
60
+ }
61
+ function cardData(event) {
62
+ const source = event.data?.source ?? {};
63
+ const threads = Array.isArray(source.threads) ? source.threads : [];
64
+ const requests = Array.isArray(source.requests) ? source.requests : [];
65
+ return {
66
+ title: str(source.title),
67
+ url: str(source.url),
68
+ threads: threads.map((t) => ({ id: str(t.id), where: str(t.where), text: str(t.text) })).filter((t) => t.id),
69
+ requests: requests.map((r) => ({ id: str(r.id), label: str(r.label), text: str(r.text) })).filter((r) => r.id && r.text),
70
+ seq: event.seq
71
+ };
72
+ }
73
+ var definition = {
74
+ kind: KIND,
75
+ target: "chat",
76
+ match: (event) => (
77
+ // Claimed: the built-in input-message Definition would draw it as a context row.
78
+ ours(event) ? { id: String(event.data?.id), role: "start", exclusive: true } : null
79
+ ),
80
+ start: (_context, match) => cardData(match.event),
81
+ update: (context) => context.state,
82
+ buildViewNode: (context) => {
83
+ if (context.state === void 0) return null;
84
+ return {
85
+ key: context.key,
86
+ kind: KIND,
87
+ id: context.id,
88
+ target: "chat",
89
+ anchorSeq: context.state.seq,
90
+ location: context.start?.location ?? context.matches[0]?.location ?? { kind: "unresolved" },
91
+ visibility: "visible",
92
+ // A person's input, as a user message: it opens the agent's reply below it.
93
+ groupTree: "input",
94
+ data: context.state
95
+ };
96
+ }
97
+ };
98
+ var CSS = `
99
+ .bdc-row{display:flex;flex-direction:column;align-items:flex-end;gap:8px;width:100%}
100
+ .bdc-card{box-sizing:border-box;max-width:min(calc(var(--dsh-chat-content-width, 748px) * 0.702), 82%);min-width:min(320px, 82%);
101
+ border:0.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-xl, 12px);background:var(--dsw-alias-markdown-code-block);
102
+ color:var(--dsw-alias-label-primary);padding:10px 14px 12px;display:flex;flex-direction:column;gap:6px}
103
+ .bdc-head{display:flex;align-items:center;gap:6px;color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxs-12, 12px/18px sans-serif)}
104
+ .bdc-head svg{flex:none}
105
+ .bdc-head-text{flex:1;min-width:0;display:flex;white-space:nowrap;overflow:hidden}
106
+ .bdc-head-text>span{flex:none}
107
+ .bdc-head-text>.bdc-head-title{flex:0 1 auto;min-width:1.5em;overflow:hidden;text-overflow:ellipsis}
108
+ .bdc-toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin:-2px -4px -2px 0;
109
+ border:0;border-radius:var(--dsw-radius-sm, 6px);background:none;color:inherit;cursor:pointer;padding:0}
110
+ .bdc-toggle:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}
111
+ .bdc-toggle svg{transition:transform .15s}
112
+ .bdc-toggle[aria-expanded=false] svg{transform:rotate(-90deg)}
113
+ .bdc-body{font-size:var(--dsh-content-font-size, 14px);line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere}
114
+ .bdc-meta{display:flex;flex-direction:column;gap:6px;padding-top:6px;border-top:0.5px solid var(--dsw-alias-border-l1)}
115
+ .bdc-where{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxs-12, 12px/18px sans-serif);overflow-wrap:anywhere}
116
+ .bdc-view{align-self:flex-start;display:inline-flex;align-items:center;gap:2px;height:24px;margin-left:-6px;padding:0 6px;border:0;
117
+ border-radius:var(--dsw-radius-sm, 6px);background:none;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxs-12, 12px/18px sans-serif);cursor:pointer}
118
+ .bdc-view:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
119
+ .bdc-view:focus-visible,.bdc-toggle:focus-visible{outline:var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));outline-offset:1px}
120
+ @media (prefers-reduced-motion:reduce){.bdc-toggle svg{transition:none}}
121
+ `;
122
+ var iconStyle = { display: "block" };
123
+ var TITLE_MARK = "";
124
+ function CommentIcon() {
125
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
126
+ "path",
127
+ {
128
+ d: "M3 3.5h10a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H8.2L5.4 13.8a.3.3 0 0 1-.5-.23V11.5H3a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1Z",
129
+ stroke: "currentColor",
130
+ strokeWidth: "1.2",
131
+ strokeLinejoin: "round"
132
+ }
133
+ ) });
134
+ }
135
+ function RequestIcon() {
136
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", style: iconStyle, children: [
137
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2", y: "4", width: "12", height: "7", rx: "2", stroke: "currentColor", strokeWidth: "1.2" }),
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8.5 8.5 11 14l.9-2.1L14 11l-5.5-2.5Z", fill: "currentColor", stroke: "var(--dsw-alias-markdown-code-block, #fff)", strokeWidth: "0.8", strokeLinejoin: "round" })
139
+ ] });
140
+ }
141
+ function ChevronDown() {
142
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 4.5 6 7.5l3-3", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round" }) });
143
+ }
144
+ function ChevronRight() {
145
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4.5 3 7.5 6l-3 3", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round" }) });
146
+ }
147
+ function Card({ title, thread, url, t, openThread }) {
148
+ const [open, setOpen] = (0, import_react.useState)(true);
149
+ const heading = t("card.title", { title });
150
+ const meta = !CLIENT.simple && (thread.where || url);
151
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bdc-card", "data-comment-id": thread.id, children: [
152
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bdc-head", children: [
153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommentIcon, {}),
154
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Heading, { text: heading, title, parts: t("card.title", { title: TITLE_MARK }).split(TITLE_MARK) }),
155
+ meta && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "bdc-toggle", "aria-expanded": open, "aria-label": t(open ? "card.less" : "card.more"), onClick: () => setOpen(!open), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, {}) })
156
+ ] }),
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bdc-body", children: thread.text }),
158
+ meta && open && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bdc-meta", children: [
159
+ thread.where && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bdc-where", children: thread.where }),
160
+ url && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: "bdc-view", onClick: () => openThread(url, thread.id), children: [
161
+ t("card.view"),
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, {})
163
+ ] })
164
+ ] })
165
+ ] });
166
+ }
167
+ function Heading({ text, title, parts }) {
168
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bdc-head-text", title: text, children: parts.length === 2 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
169
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: parts[0] }),
170
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bdc-head-title", children: title }),
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: parts[1] })
172
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bdc-head-title", children: text }) });
173
+ }
174
+ function RequestCardView({ title, request, t }) {
175
+ const label = request.label || "Request";
176
+ const heading = t("card.request", { title, label });
177
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bdc-card", "data-request-id": request.id, children: [
178
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bdc-head", children: [
179
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequestIcon, {}),
180
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Heading, { text: heading, title, parts: t("card.request", { title: TITLE_MARK, label }).split(TITLE_MARK) })
181
+ ] }),
182
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bdc-body", children: request.text })
183
+ ] });
184
+ }
185
+ function CommentCards({ node, t, openThread }) {
186
+ const { title, url, threads, requests } = node.data;
187
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bdc-row", children: [
188
+ threads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, { title, thread, url, t, openThread }, thread.id)),
189
+ (requests ?? []).map((request) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RequestCardView, { title, request, t }, request.id))
190
+ ] });
191
+ }
192
+ var inject = ["slots", "locale", "uiConversation"];
193
+ function threadUrl(url, id) {
194
+ try {
195
+ const at = new URL(url);
196
+ at.searchParams.set("comment", id);
197
+ return at.href;
198
+ } catch {
199
+ return url;
200
+ }
201
+ }
202
+ function apply(ctx) {
203
+ ctx.effect(() => {
204
+ if (typeof document === "undefined") return () => {
205
+ };
206
+ const id = `${CLIENT.plugin}/comment-card.css`;
207
+ if (document.querySelector(`style[data-plugin-css=${JSON.stringify(id)}]`)) return () => {
208
+ };
209
+ const tag = document.createElement("style");
210
+ tag.dataset.plugin = CLIENT.plugin;
211
+ tag.dataset.pluginCss = id;
212
+ tag.textContent = CSS;
213
+ document.head.appendChild(tag);
214
+ return () => tag.remove();
215
+ }, `${CLIENT.plugin}: comment card styles`);
216
+ ctx.effect(() => ctx.locale.register(NS, { zh, en }), `${CLIENT.plugin}: dictionaries`);
217
+ ctx.uiConversation.events.register(definition);
218
+ ctx.slots.inject(
219
+ "conversation.chat.node",
220
+ () => ctx.slots.register(
221
+ {
222
+ name: "conversation.chat.node",
223
+ key: KIND,
224
+ locale: NS,
225
+ inject: (sessionId) => ({
226
+ openThread: (url, threadId) => {
227
+ const target = threadUrl(url, threadId);
228
+ const sidebar = ctx.get("sidebarRight");
229
+ const tabs = ctx.get("sidebarRightTabs");
230
+ if (sidebar && tabs?.get("browser") !== void 0) sidebar.openTabIn(sessionId, "browser", { params: { url: target } });
231
+ else window.open(target, "_blank", "noopener,noreferrer");
232
+ }
233
+ })
234
+ },
235
+ CommentCards
236
+ )
237
+ );
238
+ }
239
+ return module.exports;
240
+ }
241
+ });