@khorsheed/dsh-inline-html-render 0.1.16 → 0.1.17

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # 变更记录
2
2
 
3
+ ## 0.1.17(2026-10-26)
4
+
5
+ - **README 重写**:改为面向用户的简短说明。无功能变更。
6
+
3
7
  ## 0.1.16(2026-10-22)
4
8
 
5
9
  - **技能卡来源归一为包全名**:随包注册的两个作者 skill(`inline-html-card`、`3d-artifact`)的 `provider` 从裸词 `inline-html-render` 改为 `@khorsheed/dsh-inline-html-render`——能力目录的技能卡与其他插件一样显示包全名;行为与 skill 内容不变
package/README.en.md CHANGED
@@ -2,97 +2,43 @@
2
2
 
3
3
  English | [中文](README.md)
4
4
 
5
- "Show me" stops being a code block — a `` ```dsh-card `` fence the agent writes turns into a live, clickable HTML card right in the conversation.
5
+ When the agent says "let me show you", it really does: the small web page it writes becomes a live, clickable card right in the conversation.
6
6
 
7
- Without it, an agent that wants you to *see* a result can only paste code for you to imagine, or write an HTML file you have to open in a preview. This plugin swaps the fenced block whose info string is `dsh-card` for a sandboxed iframe — mid-message — that runs the authored HTML: inline between paragraphs and genuinely interactive, not ASCII art or a prose description.
7
+ Before, an agent that wanted you to see something could only paste code for you to imagine, or write an HTML file and wait for you to open it. With Inline Cards, say "make me a card", "show me a few color schemes side by side", and it draws a card in the middle of its reply: buttons click, tabs switch, animations move — right where it is talking, and the conversation carries on below.
8
8
 
9
- <img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/inline-html-card-1.png" width="640" alt="a dsh-card block in the agent's reply rendered as a tabbed data-observation card, flowing with the surrounding text">
9
+ <img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/inline-html-card-1.png" width="560" alt="a dsh-card block in the middle of an agent reply, rendered as a tabbed data-observation card that flows with the surrounding text">
10
10
 
11
- ```dsh-card
12
- <div style="font:14px system-ui;padding:16px;background:#1e1e1e;border-radius:10px;color:#eee">
13
- <div style="font-weight:600;margin-bottom:8px">design token reference</div>
14
- <div style="display:flex;gap:8px">
15
- <span style="background:#4f8cff;color:#fff;padding:4px 10px;border-radius:6px">primary</span>
16
- <span style="background:#2ea043;color:#fff;padding:4px 10px;border-radius:6px">success</span>
17
- <span style="background:#d29922;color:#fff;padding:4px 10px;border-radius:6px">warning</span>
18
- </div>
19
- </div>
20
- ```
21
-
22
- In the session, that is not a code block — it is a rendered card.
23
-
24
- ## Features
11
+ ## What it does
25
12
 
26
- - **Inline between paragraphs** — the card sits exactly where the agent wrote it, flowing with the surrounding text; not an attachment, not a sidebar.
27
- - **Truly interactive** — the card runs in a `sandbox="allow-scripts"` iframe with full DOM/CSS/JS: hover, click, tab switching, inline SVG/canvas animation all work.
28
- - **Strict sandbox** — an opaque origin (never `allow-same-origin`) plus an injected strict CSP (`connect-src 'none'`, scripts/styles inline only): card scripts cannot touch host DOM or cookies and cannot reach the network. The only way out is `window.dshBridge` with three capabilities — `openLink` (https only), `copy`, `download` (data: URLs only) — each validated host-side for source window and argument shape.
29
- - **Auto-height** — the opaque origin keeps the parent from reading content height, so the card document posts its real content height on load/resize and the parent sizes to it (capped at 20000px against runaway cards).
30
- - **Links follow the host's route** — `openLink` opens into the right-Sidebar Browser tab on hosts shipping ui-sidebar-browser, and falls back to a new window (`noopener`) otherwise; probed on every open, so hot-added or hot-removed tab types never wedge.
31
- - **Zero-invasive, degrades by design** — it only rewrites DOM the official client has **already rendered** (inserting an iframe beside the code block and hiding the block); no official source is touched. Without this plugin, `` ```dsh-card `` is just a normal code block — nothing breaks.
32
- - **Two bundled authoring skills** — the host half registers `inline-html-card` and `3d-artifact` (both with provider `inline-html-render`), discovered pull-style: the agent picks up the protocol when it needs to *draw*, instead of every session carrying it.
13
+ - **Ask to see it, and it draws it**: when you want to see an effect, a small widget, or a few options compared, the agent decides on its own to draw a card — nothing to teach it.
14
+ - **The card lives in the reply**: it sits between paragraphs, flowing with the text around it, not in a sidebar and not as an attachment to open.
15
+ - **Really interactive**: hover, click, switch tabs, charts and animations all work — it is not a screenshot.
16
+ - **3D scenes too**: to look at a 3D model or scene, the agent can write a single-file 3D page straight into the conversation.
17
+ - **Safe to look at**: the card runs in a sandbox, can't touch your page or login, and can't reach the network; its links open only in a new window or the right-sidebar browser.
18
+ - **Nothing breaks without it**: without the plugin, the same content just shows as an ordinary code block.
33
19
 
34
20
  ## Install
35
21
 
36
- ```sh
37
- dsh plugin --profile web add @khorsheed/dsh-inline-html-render
38
- ```
39
-
40
- Restart the web instance to activate; uninstall restores the previous composition exactly.
22
+ In DSH, open Plugins → Add plugin, enter the package name below, and click install:
41
23
 
42
- ```sh
43
- dsh plugin --profile web remove @khorsheed/dsh-inline-html-render
24
+ ```
25
+ @khorsheed/dsh-basic
44
26
  ```
45
27
 
46
- ## Authoring for the agent
47
-
48
- The two skills the host half registers, `inline-html-card` and `3d-artifact`, share one HTML-authoring protocol. Whenever the user wants a **visible result** ("show me", "preview", "make me a card", "compare these visual options", a clickable widget), the agent picks up this protocol. Core constraints (the full protocol lives in the bundled skills):
28
+ Inline Cards come with the Basic Essentials suite. Once installed, tell the agent in any session "make me a card to show it" to try it.
49
29
 
50
- - Exactly one fenced block whose info string is exactly `dsh-card`; **three backticks, never four, never nested** — a nested fence is parsed as an outer code block and the card never renders.
51
- - Self-contained content: all CSS/JS inline, images as `data:` URIs, zero runtime network.
52
- - The content IS the card: render the thing itself, not a fake window/title-bar container around it.
53
- - Never reach the host — open links, copy, and download through `window.dshBridge`.
30
+ ## Known limits
54
31
 
55
- `3d-artifact` targets single-file 3D / digital-twin HTML (three.js via whitelisted-CDN importmaps, GLB models inlined as base64, a self-embedded Tier1 CSP); the renderer respects a card's own CSP and never injects a duplicate.
32
+ - Cards can't go online; for something that loads web resources, open it in the file preview instead.
33
+ - When the conversation re-renders, cards reload, so anything typed into a card and its scroll position are lost.
34
+ - A card grows with its content, up to about 20000 pixels tall.
56
35
 
57
36
  ## Compatibility
58
37
 
59
- - npm release line (`@deepseek-ai/dsh@0.1.5-rc.1`): ✅ full — this plugin consumes only standard DOM plus the client-runtime `ClientContext`, with no host-service dependency; minHost is 0.1.2-rc.1 — older hosts stay on the previous release line.
60
- - source line (deepseek-harness master): ✅ (verifiedHost: 0.2.1-rc.1) — host-021 wave: full build+test green against the 0.2.1-rc.1 tree, no other surface changes; the DOM anchors re-checked on master (0.1.7-rc.2) are unchanged: `CodeBlock` still renders the `.md-code-block` wrapper with the info string in its banner (a CSS-module hashed class, caught by the leading-text fallback), `AssistantMarkdown` still sets `data-streaming`, and `ui-sidebar-browser` still registers the `browser` right-Sidebar tab kind.
61
-
62
- ## Known Limitations
63
-
64
- - **Depends on official rendered DOM details** — blocks are located via the `.md-code-block` wrapper, and recognition runs in three arms: the explicit `.infostring` element (older shape) → the banner's leading text (0.1.6 shape) → the **content signature** (0.1.7-rc.1+: `CodeToolbar` shows only the host's localized generic label for fence languages shiki cannot highlight, so `dsh-card` never reaches the DOM; there a complete HTML document — doctype/`<html` head, `</html>` tail — or a block carrying the verbatim strict-CSP meta counts as a card). Streaming completion is aligned via `AssistantMarkdown`'s `data-streaming`. This is the repo-accepted last-resort DOM-anchor pattern (same shape as message-tools' dom-hider). Known gap: on hosts where the info string is invisible, **bare HTML fragments** (not a complete document, no CSP meta) are no longer recognized as cards — author cards as complete documents; once the host ships a `data-lang` hook (proposal in docs/upstream-proposals) recognition falls back to the pure info string.
65
- - **No network under the default CSP** — the injected default CSP allows no network at all, not even whitelisted CDNs (stricter than file-preview's Tier1); a card document's own embedded CSP wins (`3d-artifact` embeds the Tier1 CSP that whitelists two CDNs for `script-src`). For other network-bearing visuals use file-preview's HTML render path instead.
66
- - **Card interaction state does not survive re-renders** — React rebuilds the code-block node on content change; the old iframe is collected and re-mounted, so transient state inside a card (inputs, scroll position) is lost.
67
- - **Auto-height has edges** — height comes from the card's own report, capped at 20000px; rare continuously-growing layouts may need a manual re-scan to settle.
68
-
69
- ## How it works
70
-
71
- <details>
72
- <summary>Internals (click to expand)</summary>
73
-
74
- **Architecture.** The browser half is a pure DOM-layer effect: it owns no slot and registers no Remote, mutating only the DOM the official client already rendered — the same repo-accepted last-resort pattern as message-tools' dom-hider — so it composes as an independent package with no core edits. The host half (`src/index.ts`) does exactly one thing: once the skill registry is ready (awaited via `ctx.inject(['skills'], …)` rather than probed synchronously at apply time), it registers the two bundled content-only skills (a missing/malformed SKILL.md warns, never throws; a composition without the `skills` service stays pending, never fails boot). Identity triangle: the cordis.patch.yml row id `inline-html-render` = the package.json name = the tsdown `clientBundle` id.
75
-
76
- | Module | Responsibility |
77
- | --- | --- |
78
- | `src/client/renderer.ts` | A `MutationObserver` watches the DOM; for each `.md-code-block` whose info string is `dsh-card` (an explicit `.infostring` or the banner's leading text) it reads the `<pre>` text (the raw HTML), inserts an iframe beside the block, and hides the block; never mounts while streaming (a `data-streaming` ancestor exists), re-scans once settled; collects orphaned iframes and re-mounts when React rebuilds a block. |
79
- | `src/client/srcdoc.ts` | Wraps the card HTML into a complete srcdoc document carrying the strict CSP plus `dshBridge`: fragments get `<html>/<head>` synthesized, full documents get the injection right after their `<head>`; a card that already declares a CSP is not given a duplicate. The sandbox never carries `allow-same-origin`. |
80
- | `src/client/bridge.ts` | Host-side validation of every iframe message (`event.source` must be the controlled frame's window, an `fn` whitelist, per-function argument shapes), answering `openLink/copy/download` and height reports; unknown or malformed calls get an error reply, never a host exception. |
81
-
82
- **Why a sibling instead of replacing the node**: React owns the markdown tree, so a bare `removeChild` would make React's reconciliation fight the DOM (potentially throwing or resurrecting the block). The plugin never removes a React node — the iframe is inserted as a sibling right after the block, the block is hidden with `style.display='none'` (a style React does not manage), and a MutationObserver re-scans on every change; when React replaces a node, the new block is caught and hidden again.
83
-
84
- **Streaming alignment**: while a turn runs, `AssistantMarkdown` sets `data-streaming` on its root and the block content is partial and re-rendered; the plugin only mounts when no `data-streaming` ancestor exists, so a card never renders on a half-streamed body. When the turn ends, React re-renders, drops the attribute, and rebuilds the block — the observer swaps then.
85
-
86
- **Link routing**: `openLink` probes `sidebarRightTabs`/`sidebarRight` on every open — when the host registers the `browser` tab kind (ui-sidebar-browser) the link opens as a right-Sidebar Browser tab; a failed probe or a throwing open falls back to `window.open` (https, `noopener`). The bridge handler enforces https-only targets.
87
-
88
- **For plugin authors**: the card protocol is pull-based (a skill), not pushed to every session — just write self-contained HTML inside a `` ```dsh-card `` fence.
89
-
90
- </details>
91
-
92
- ## Development
93
-
94
- Part of the [dsh-plugins](https://github.com/Khorsheed/dsh-plugins) monorepo (`packages/inline-html-render`). Issues and contributions welcome there.
38
+ Needs DSH 0.1.2-rc.1 or later; verified on 0.2.1-rc.1.
95
39
 
96
- ## Changelog
40
+ ## For developers
97
41
 
98
- See [CHANGELOG.md](CHANGELOG.md).
42
+ - The card authoring protocol (the `` ```dsh-card `` block), the sandbox and capability bridge, how cards are detected on the page, and the internals are in the [full reference](https://github.com/Khorsheed/dsh-plugins/blob/main/packages/inline-html-render/docs/reference.en.md); the complete protocol is in the bundled skills `skills/inline-html-card` and `skills/3d-artifact`.
43
+ - Entry points: `src/index.ts` (registers the two skills), `src/client/renderer.ts` (swaps code blocks for cards). Standalone install: `dsh plugin --profile web add @khorsheed/dsh-inline-html-render`.
44
+ - Part of [dsh-plugins](https://github.com/Khorsheed/dsh-plugins); open issues and contributions there. Changes: [CHANGELOG.md](CHANGELOG.md).
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority; after
3
3
  # editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/inline-html-render/README.en.md
5
- packages/inline-html-render/README.en.md: e87317bab7778e1be2d5db04c4759610d13eb0ae
6
- packages/inline-html-render/README.md: 11c14dd73d0fe3085b23259fd64ef2ee57e1b718
5
+ packages/inline-html-render/README.en.md: de4717e972b6b4c8a0304d1b4515ad991edf8def
6
+ packages/inline-html-render/README.md: 449645dfaa2da641d5dbb1c7030d47cc4aef9bad
package/README.md CHANGED
@@ -2,97 +2,43 @@
2
2
 
3
3
  [English](README.en.md) | 中文
4
4
 
5
- 把「做出来给你看」变成字面意思——agent 写的 `` ```dsh-card `` 代码块,在对话正文里原地变成一张能点、能动的 HTML 卡片。
5
+ 让 agent 把「做出来给你看」变成真的:它写的小网页直接在对话里变成一张能点、能动的卡片。
6
6
 
7
- 没有它的时候,agent 想让你**看到**一个效果,只能贴段代码让你脑补,或者写个 HTML 文件等你去预览里打开。这个插件把 info string 为 `dsh-card` 的 fenced block 在消息流中间替换成一个沙箱 iframe,直接运行其中的 HTML——内联在段落之间、真正可交互,而不是 ASCII 图或一句描述。
7
+ 以前 agent 想让你看一个效果,只能贴一段代码让你自己想象,或者写个 HTML 文件等你去打开。装上内联卡片,你说一句「做个卡片看看」「对比几种配色给我看」,它就在回复中间画出一张卡片:按钮能点、标签能切、动画能动,就长在它说话的位置,看完接着往下聊。
8
8
 
9
- <img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/inline-html-card-1.png" width="640" alt="agent 回复中间的 dsh-card 代码块被渲染成一张带 tab 的数据观测卡片,与上下文文字自然衔接">
9
+ <img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/inline-html-card-1.png" width="560" alt="agent 回复中间的 dsh-card 代码块被渲染成一张带 tab 的数据观测卡片,与上下文文字自然衔接">
10
10
 
11
- ```dsh-card
12
- <div style="font:14px system-ui;padding:16px;background:#1e1e1e;border-radius:10px;color:#eee">
13
- <div style="font-weight:600;margin-bottom:8px">设计 token 对照</div>
14
- <div style="display:flex;gap:8px">
15
- <span style="background:#4f8cff;color:#fff;padding:4px 10px;border-radius:6px">primary</span>
16
- <span style="background:#2ea043;color:#fff;padding:4px 10px;border-radius:6px">success</span>
17
- <span style="background:#d29922;color:#fff;padding:4px 10px;border-radius:6px">warning</span>
18
- </div>
19
- </div>
20
- ```
21
-
22
- 上面这段在会话里不是一个代码块,而是一张渲染出来的卡片。
23
-
24
- ## 特性
11
+ ## 能做什么
25
12
 
26
- - **内联在段落中间**——卡片就长在 agent 写它的位置,与上下文文字自然衔接;不是附件,也不占侧栏。
27
- - **真正可交互**——卡片跑在 `sandbox="allow-scripts"` 的 iframe 里,完整 DOM/CSS/JS 可用:hover、点击、tab 切换、内联 SVG/canvas 动图都行。
28
- - **严格沙箱**——不透明源(永不带 `allow-same-origin`)加注入式严格 CSP(`connect-src 'none'`,脚本/样式仅内联):卡片脚本碰不到宿主 DOM 与 Cookie,也联不了网。对外只开放 `window.dshBridge` 的 `openLink`(仅 https)/`copy`/`download`(仅 data: URL)三个能力,宿主侧逐条校验来源窗口与参数形状。
29
- - **高度自适应**——不透明源让外层读不到内容高度,卡片文档在 load/resize 时把真实内容高度 postMessage 出来,外层据此撑开(封顶 20000px,防失控卡片)。
30
- - **链接走宿主路由**——`openLink` 在带 ui-sidebar-browser 的宿主上开进右侧栏 Browser 标签页,否则退化为新窗口(`noopener`);每次打开时现探测,标签类型热增热删都不卡死。
31
- - **零侵入、天然降级**——只改写官方**已经渲染出来的** DOM(在代码块旁插入 iframe 并隐藏原块),不改一行官方源码;没装本插件时,`` ```dsh-card `` 就是一个普通代码块,什么也不坏。
32
- - **随包两个作者 skill**——host 半边注册 `inline-html-card` 与 `3d-artifact`(provider 均为 `inline-html-render`),拉取式发现:agent 需要「画出来」时按协议写作,不往每个会话里塞协议。
13
+ - **说要看,就画给你看**:想看效果、做个小组件、对比几种方案时,agent 会自己决定画一张卡片,不用你教它怎么写。
14
+ - **卡片长在回复里**:卡片就在段落之间,和前后文字连在一起,不占侧栏,也不是要另外打开的附件。
15
+ - **真的能点**:悬停、点击、切标签、图表和动画都能用,不是一张截图。
16
+ - **3D 场景也能看**:要看一个 3D 模型或场景,agent 可以写一个单文件的 3D 页面直接放进对话。
17
+ - **放心看**:卡片关在沙箱里,碰不到你的页面和登录信息,也连不了网;卡片里的链接只能在新窗口或右侧栏浏览器里打开。
18
+ - **不装也不坏**:没装这个插件时,同样的内容只显示成一段普通代码。
33
19
 
34
20
  ## 安装
35
21
 
36
- ```sh
37
- dsh plugin --profile web add @khorsheed/dsh-inline-html-render
38
- ```
39
-
40
- 重启 web 实例后生效;卸载即精确还原之前的组合。
22
+ 在 DSH 的「插件 → 添加插件」里输入下面的包名,点安装:
41
23
 
42
- ```sh
43
- dsh plugin --profile web remove @khorsheed/dsh-inline-html-render
24
+ ```
25
+ @khorsheed/dsh-basic
44
26
  ```
45
27
 
46
- ## 给 agent 的写法
47
-
48
- host 半边注册的 `inline-html-card` 与 `3d-artifact` 两个 skill 同属一套 HTML 作者协议。只要用户想要**看得见的结果**(“show me / 预览 / 做个卡片看看 / 对比几个视觉效果 / 想要个能点的小组件”),agent 就会套用这个协议。核心约束(完整协议见随包 skill):
49
-
50
- - 恰好一个 fenced block,info string 严格为 `dsh-card`;**用三个反引号,不要四个、不要嵌套**——嵌套会被解析成外层代码块,卡片不渲染。
51
- - 内容自包含:CSS/JS 全部内联,图片用 `data:` URI,零运行时网络。
52
- - 内容即卡片:直接渲染内容本身,别再包一层假窗口/标题栏容器。
53
- - 不访问宿主——外链、复制、下载走 `window.dshBridge`。
54
-
55
- `3d-artifact` 面向单文件 3D / 数字孪生 HTML(three.js importmap 走白名单 CDN、GLB 模型 base64 内联、自带 Tier1 CSP);渲染器尊重卡片自带的 CSP,不重复注入。
56
-
57
- ## Compatibility
58
-
59
- - npm 发布线(`@deepseek-ai/dsh@0.1.5-rc.1`):✅ 完整——本插件只消费标准 DOM 与客户端运行时 `ClientContext`,不依赖任何 host 服务;minHost 0.1.2-rc.1,0.1.2 之前的宿主请停留在旧发布线。
60
- - 源码线(deepseek-harness master):✅(verifiedHost: 0.2.1-rc.1)——host-021 波对 0.2.1-rc.1 树全量 build+test 绿,无其它表面变化;所依赖的 DOM 锚点在 master(0.1.7-rc.2)复核无变化:`CodeBlock` 仍渲染 `.md-code-block` 容器且 banner 带 info string(CSS-module 哈希类名,由前导文本回退路径识别),`AssistantMarkdown` 仍置 `data-streaming`,`ui-sidebar-browser` 仍注册 `browser` 右侧栏标签类型。
28
+ 内联卡片会跟着「基础体验」一起装好。装完在任何会话里对 agent 说「做个卡片给我看看」就能试。
61
29
 
62
30
  ## 已知限制
63
31
 
64
- - **依赖官方渲染 DOM 细节**——定位靠 `.md-code-block` 容器,识别走三层:显式 `.infostring` 元素(旧形状)→ banner 前导文本(0.1.6 形状)→ **内容签名**(0.1.7-rc.1 起:`CodeToolbar` 对 shiki 不认得的 fence 语言只显示本地化通用标签,`dsh-card` 信息串不进 DOM;此时完整 HTML 文档——doctype/`<html` 开头、`</html>` 收尾——或含逐字严格 CSP meta 的块即判为卡片)。并用 `AssistantMarkdown` 的 `data-streaming` 对齐流式结束。这是仓库接受的 last-resort DOM-anchor 模式(与 message-tools 的 dom-hider 同型)。已知缺口:信息串不可见的宿主上,**裸 HTML 片段**(非完整文档、无 CSP meta)不再识别为卡片——请把卡片写成完整文档;官方若提供 `data-lang` 钩子(提案见 docs/upstream-proposals)即可退回纯信息串识别。
65
- - **默认 CSP 无网络**——渲染器注入的默认 CSP 连白名单 CDN 也不放行(比 file-preview 的 Tier1 更严);卡片文档自带 CSP 时以自带为准(`3d-artifact` 协议即内嵌放行两个 CDN `script-src` 的 Tier1 CSP)。需要联网画面的其它场景请走 file-preview 的 HTML 渲染链路,而非本插件。
66
- - **卡片交互状态不跨重渲染**——React 内容变化会重建代码块节点,旧 iframe 随之回收重挂,卡片里的临时状态(输入、滚动位置)不保留。
67
- - **高度自适应有边界**——高度来自卡片内部上报,封顶 20000px;极少数持续动态撑高的布局可能需要手动触发重扫。
68
-
69
- ## 实现原理
70
-
71
- <details>
72
- <summary>内部结构(点击展开)</summary>
73
-
74
- **架构。** 浏览器半部分是纯 DOM 层效果:不拥有 slot、不注册 Remote,只改写官方已渲染的 DOM——与 message-tools 的 dom-hider 同属仓库接受的 last-resort 模式,因此可以作为独立包组合,不改任何核心包。host 半部分(`src/index.ts`)只做一件事:经 `ctx.inject(['skills'], …)` 等 skill 注册表就绪后,注册随包的两个内容型 skill(SKILL.md 缺失/畸形只 warn 不 throw;组合里没有 `skills` 服务时保持 pending,绝不炸 boot)。身份三角:cordis.patch.yml 行 id `inline-html-render` = package.json name = tsdown `clientBundle` id。
75
-
76
- | 模块 | 职责 |
77
- | --- | --- |
78
- | `src/client/renderer.ts` | `MutationObserver` 监控 DOM;对每个 info string 为 `dsh-card` 的 `.md-code-block`(显式 `.infostring` 或 banner 前导文本)读取 `<pre>` 文本(原始 HTML),在块旁插入 iframe、隐藏原块;流式未结束(`data-streaming` 祖先存在)时不挂载,落定后重扫;React 重建块后回收孤儿 iframe 并重挂。 |
79
- | `src/client/srcdoc.ts` | 把卡片 HTML 包成带严格 CSP + `dshBridge` 的完整 srcdoc 文档:片段自动补 `<html>/<head>`,完整文档在其 `<head>` 后注入;卡片已自带 CSP 时不重复注入。sandbox 永不带 `allow-same-origin`。 |
80
- | `src/client/bridge.ts` | 宿主侧逐条校验 iframe 消息(`event.source` 必须是受控 iframe 的 window、fn 白名单、按函数校验参数形状),响应 `openLink/copy/download` 与高度上报;未知或畸形调用回错误,绝不在宿主抛异常。 |
81
-
82
- **为什么插兄弟节点而不是替换**:React 拥有 markdown 树,直接 `removeChild` 会让 React 的 reconciliation 与 DOM 打架(可能抛错或让原块复活)。所以本插件**从不删 React 的节点**——iframe 作为兄弟节点插在块之后,再把块 `style.display='none'`(React 不管的样式),并用 MutationObserver 在每次变更后重扫;React 替换节点时新块同样被捕获、再次隐藏。
32
+ - 卡片不能联网,要加载网上资源的画面请改用文件预览打开。
33
+ - 对话重新渲染时卡片会重新加载,卡片里输入的内容、滚动位置不会保留。
34
+ - 卡片高度跟着内容走,但最高约 20000 像素。
83
35
 
84
- **流式对齐**:回合运行时 `AssistantMarkdown` 在根上置 `data-streaming`,块内容是部分且会被重渲染;插件只在无 `data-streaming` 祖先时挂载,杜绝在半截内容上渲染。回合结束 React 重渲染、移除该属性并重建块,observer 此时才真正替换。
85
-
86
- **链接路由**:`openLink` 每次打开时探测 `sidebarRightTabs`/`sidebarRight`——宿主注册了 `browser` 标签类型(ui-sidebar-browser)就开进右侧栏 Browser 标签,探测失败或 open 抛错都退化为 `window.open`(https、noopener);桥处理器强制仅 https 目标。
87
-
88
- **给插件作者**:卡片协议是拉取式(skill),不推给每个会话;照 `` ```dsh-card `` 写自包含 HTML 即可。
89
-
90
- </details>
91
-
92
- ## 开发
36
+ ## Compatibility
93
37
 
94
- 隶属 [dsh-plugins](https://github.com/Khorsheed/dsh-plugins) monorepo(`packages/inline-html-render`)。问题与贡献请移步该仓库。
38
+ 需要 DSH 0.1.2-rc.1 或更新版本,已在 0.2.1-rc.1 上验证。
95
39
 
96
- ## 变更记录
40
+ ## 给开发者
97
41
 
98
- 见 [CHANGELOG.md](CHANGELOG.md)。
42
+ - 卡片的写法协议(`` ```dsh-card `` 代码块)、沙箱与能力桥、在页面上识别卡片的方式和实现原理,都在[完整参考](https://github.com/Khorsheed/dsh-plugins/blob/main/packages/inline-html-render/docs/reference.md)里;完整写法见随包 skill `skills/inline-html-card` 与 `skills/3d-artifact`。
43
+ - 入口:`src/index.ts`(注册两个 skill)、`src/client/renderer.ts`(把代码块换成卡片)。也可以单独安装:`dsh plugin --profile web add @khorsheed/dsh-inline-html-render`。
44
+ - 隶属 [dsh-plugins](https://github.com/Khorsheed/dsh-plugins),问题与贡献请到该仓库;变更见 [CHANGELOG.md](CHANGELOG.md)。
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "card",
11
11
  "sandbox"
12
12
  ],
13
- "version": "0.1.16",
13
+ "version": "0.1.17",
14
14
  "type": "module",
15
15
  "main": "lib/index.js",
16
16
  "types": "lib/types/index.d.ts",