@wisdoverse/dsh-inline-media-viewer 1.0.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.
- package/CHANGELOG.md +29 -0
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/README.zh-CN.md +155 -0
- package/SECURITY.md +67 -0
- package/client/client.js +554 -0
- package/cordis.patch.yml +3 -0
- package/index.js +185 -0
- package/lib.js +178 -0
- package/package.json +74 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.1
|
|
4
|
+
|
|
5
|
+
- Publish the plugin as `@wisdoverse/dsh-inline-media-viewer` for one-command
|
|
6
|
+
installation through the DSH plugin manager.
|
|
7
|
+
- Align the bundle manifest, package metadata, and bilingual installation
|
|
8
|
+
documentation with the scoped package name.
|
|
9
|
+
|
|
10
|
+
## 1.0.0
|
|
11
|
+
|
|
12
|
+
- **Initial public release.** Inline image/video/audio previews in the
|
|
13
|
+
conversation tail (`conversation.chat.turnTail` projection): any media
|
|
14
|
+
path or media URL mentioned in a chat turn renders inline under that
|
|
15
|
+
turn.
|
|
16
|
+
- **Workspace-confined local reads** — a path renders only when it
|
|
17
|
+
resolves inside the calling session's workspace root (`realpath` +
|
|
18
|
+
containment; no symlink escapes).
|
|
19
|
+
- **Configurable ComfyUI proxy** — media URLs on the local aliases
|
|
20
|
+
(`127.0.0.1`/`localhost` on port 8188) or on the configured server
|
|
21
|
+
address are fetched server-side from the configured origin, with
|
|
22
|
+
redirects refused, a 20 s timeout, and a 48 MiB cap.
|
|
23
|
+
- **Settings page** (媒体预览 / Media preview): auto-render toggle,
|
|
24
|
+
per-turn cap (1–30), max media height (160–1200 px), ComfyUI server
|
|
25
|
+
address — persisted through the DSH settings document (loopback
|
|
26
|
+
writes).
|
|
27
|
+
- **Pure helpers** in a dependency-free `lib.js` with a zero-dependency
|
|
28
|
+
unit test runner (`node test.mjs`), plus README, SECURITY, and MIT
|
|
29
|
+
LICENSE.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Wisdoverse
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<h1 align="center">dsh-inline-media-viewer</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Inline image, video, and audio previews for DeepSeek Harness Web</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="CHANGELOG.md"><img alt="Latest tag" src="https://img.shields.io/github/v/tag/Wisdoverse/dsh-inline-media-viewer-plugin?style=flat-square&label=version"></a>
|
|
9
|
+
<a href="LICENSE"><img alt="License" src="https://img.shields.io/github/license/Wisdoverse/dsh-inline-media-viewer-plugin?style=flat-square"></a>
|
|
10
|
+
<a href="package.json"><img alt="Top language" src="https://img.shields.io/github/languages/top/Wisdoverse/dsh-inline-media-viewer-plugin?style=flat-square"></a>
|
|
11
|
+
<a href="#configuration"><img alt="ComfyUI support" src="https://img.shields.io/badge/ComfyUI-supported-ff6f00?style=flat-square"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<strong>English</strong> · <a href="README.zh-CN.md">简体中文</a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
Turn media paths and URLs mentioned in a DSH conversation into secure inline
|
|
19
|
+
previews—without copying them out of the chat log.
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
https://…/view?filename=frame.png → <img>
|
|
23
|
+
exports/demo.mp4 → <video controls>
|
|
24
|
+
audio/sound.mp3 → <audio controls>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Contents
|
|
28
|
+
|
|
29
|
+
- [Features](#features)
|
|
30
|
+
- [Supported media](#supported-media)
|
|
31
|
+
- [Installation](#installation)
|
|
32
|
+
- [Configuration](#configuration)
|
|
33
|
+
- [Security](#security)
|
|
34
|
+
- [Development](#development)
|
|
35
|
+
- [License](#license)
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
| Feature | Description |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| Inline rendering | Displays images, videos, and audio directly below the chat turn that mentions them. |
|
|
42
|
+
| Workspace-safe reads | Resolves local paths with `realpath` and rejects traversal, out-of-workspace paths, and symlink escapes. |
|
|
43
|
+
| ComfyUI proxy | Fetches recognized ComfyUI media URLs server-side from the configured origin, including for remote users and HTTPS pages. |
|
|
44
|
+
| Bounded transfers | Limits each file or response to 48 MiB and remote requests to 20 seconds. |
|
|
45
|
+
| User controls | Provides auto-render, per-turn item limit, media height, and ComfyUI origin settings. |
|
|
46
|
+
|
|
47
|
+
## Supported media
|
|
48
|
+
|
|
49
|
+
| Type | Extensions |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| Images | `png`, `jpg`, `jpeg`, `webp`, `gif`, `avif`, `bmp`, `svg` |
|
|
52
|
+
| Video | `mp4`, `webm`, `mov`, `m4v`, `mkv`, `avi`, `ogv` |
|
|
53
|
+
| Audio | `mp3`, `wav`, `m4a`, `aac`, `ogg`, `oga`, `flac`, `opus` |
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
### From npm
|
|
58
|
+
|
|
59
|
+
Install and activate the bundle in your Web profile:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
dsh plugin --profile web add @wisdoverse/dsh-inline-media-viewer
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Restart the Web profile after installation.
|
|
66
|
+
|
|
67
|
+
### From source
|
|
68
|
+
|
|
69
|
+
1. Clone the plugin into a location available to your Web profile:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
git clone https://github.com/Wisdoverse/dsh-inline-media-viewer-plugin.git \
|
|
73
|
+
/path/to/local-plugins/dsh-inline-media-viewer
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
2. Add the bundle to `profiles/web/package.json`:
|
|
77
|
+
|
|
78
|
+
```jsonc
|
|
79
|
+
{
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"@wisdoverse/dsh-inline-media-viewer": "link:/path/to/local-plugins/dsh-inline-media-viewer"
|
|
82
|
+
},
|
|
83
|
+
"dsh": {
|
|
84
|
+
"profile": {
|
|
85
|
+
"bundles": ["…", "@wisdoverse/dsh-inline-media-viewer"]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
3. Rebuild or restart the Web profile.
|
|
92
|
+
|
|
93
|
+
The plugin mounts its host RPC channel, client projection, and settings section
|
|
94
|
+
through [`cordis.patch.yml`](cordis.patch.yml).
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
Open **Settings → 媒体预览 / Media preview**.
|
|
99
|
+
|
|
100
|
+
| Setting | Default | Allowed values |
|
|
101
|
+
| --- | --- | --- |
|
|
102
|
+
| Auto-render detected media | On | On / off |
|
|
103
|
+
| Maximum items per turn | `12` | `1`–`30` |
|
|
104
|
+
| Maximum media height | `380 px` | `160`–`1200 px` |
|
|
105
|
+
| ComfyUI origin | Empty | `http(s)://host[:port]` |
|
|
106
|
+
|
|
107
|
+
Settings are stored in the DSH settings document. Writes are available only on
|
|
108
|
+
loopback connections; remote browsers can read settings but cannot persist
|
|
109
|
+
changes.
|
|
110
|
+
|
|
111
|
+
### ComfyUI origin
|
|
112
|
+
|
|
113
|
+
- Leave the field empty to use `http://127.0.0.1:8188`.
|
|
114
|
+
- Accepted forms are `http://host[:port]`, `https://host[:port]`, and bare
|
|
115
|
+
`host[:port]` (`http` is assumed).
|
|
116
|
+
- The default port is `8188` for HTTP and `443` for HTTPS.
|
|
117
|
+
- Credentials, paths, query strings, and fragments are rejected.
|
|
118
|
+
- The origin must be reachable from the DSH host process. For a containerized
|
|
119
|
+
host, use the address visible from inside the container.
|
|
120
|
+
|
|
121
|
+
Local aliases (`127.0.0.1:8188` and `localhost:8188`) and the configured origin
|
|
122
|
+
are recognized as ComfyUI sources. A non-empty invalid address fails explicitly
|
|
123
|
+
instead of silently falling back to another target.
|
|
124
|
+
|
|
125
|
+
## Security
|
|
126
|
+
|
|
127
|
+
The plugin is designed as a local trust helper, not a general-purpose file or
|
|
128
|
+
network proxy:
|
|
129
|
+
|
|
130
|
+
- Local reads are confined to the active session's workspace and known media
|
|
131
|
+
extensions.
|
|
132
|
+
- Remote reads can target only the configured ComfyUI origin; redirects are
|
|
133
|
+
refused.
|
|
134
|
+
- Local files and remote responses are capped at 48 MiB.
|
|
135
|
+
- Settings writes are restricted to loopback connections.
|
|
136
|
+
- The browser receives media as `data:` URLs rather than filesystem paths.
|
|
137
|
+
|
|
138
|
+
See [SECURITY.md](SECURITY.md) for the complete trust model and known
|
|
139
|
+
limitations.
|
|
140
|
+
|
|
141
|
+
## Development
|
|
142
|
+
|
|
143
|
+
### Commands
|
|
144
|
+
|
|
145
|
+
| Command | Purpose |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `node test.mjs` | Run the dependency-free unit tests directly. |
|
|
148
|
+
| `npm test` | Run the same unit test suite through npm. |
|
|
149
|
+
| `npm run lint` | Syntax-check the host modules and test file. |
|
|
150
|
+
|
|
151
|
+
### Project structure
|
|
152
|
+
|
|
153
|
+
| Path | Responsibility |
|
|
154
|
+
| --- | --- |
|
|
155
|
+
| `index.js` | Host RPC channel, ComfyUI proxy, and settings registration. |
|
|
156
|
+
| `lib.js` | Pure, dependency-free helpers. |
|
|
157
|
+
| `client/client.js` | Turn projection, media renderer, and settings UI. |
|
|
158
|
+
| `cordis.patch.yml` | Bundle mounting and integration points. |
|
|
159
|
+
| `test.mjs` | Unit tests for the pure helpers. |
|
|
160
|
+
|
|
161
|
+
The running Web profile serves a bundled copy. Rebuild or restart it after
|
|
162
|
+
changing the source files.
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
Released under the [MIT License](LICENSE).
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<h1 align="center">dsh-inline-media-viewer</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>为 DeepSeek Harness Web 提供内联图像、视频和音频预览</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="CHANGELOG.md"><img alt="最新标签" src="https://img.shields.io/github/v/tag/Wisdoverse/dsh-inline-media-viewer-plugin?style=flat-square&label=version"></a>
|
|
9
|
+
<a href="LICENSE"><img alt="许可证" src="https://img.shields.io/github/license/Wisdoverse/dsh-inline-media-viewer-plugin?style=flat-square"></a>
|
|
10
|
+
<a href="package.json"><img alt="主要语言" src="https://img.shields.io/github/languages/top/Wisdoverse/dsh-inline-media-viewer-plugin?style=flat-square"></a>
|
|
11
|
+
<a href="#配置"><img alt="支持 ComfyUI" src="https://img.shields.io/badge/ComfyUI-supported-ff6f00?style=flat-square"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="README.md">English</a> · <strong>简体中文</strong>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
将 DSH 对话中出现的媒体路径和 URL 安全地转换为内联预览,无需再从聊天日志中复制路径。
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
https://…/view?filename=frame.png → <img>
|
|
22
|
+
exports/demo.mp4 → <video controls>
|
|
23
|
+
audio/sound.mp3 → <audio controls>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 目录
|
|
27
|
+
|
|
28
|
+
- [功能特性](#功能特性)
|
|
29
|
+
- [支持的媒体格式](#支持的媒体格式)
|
|
30
|
+
- [安装](#安装)
|
|
31
|
+
- [配置](#配置)
|
|
32
|
+
- [安全设计](#安全设计)
|
|
33
|
+
- [开发](#开发)
|
|
34
|
+
- [许可证](#许可证)
|
|
35
|
+
|
|
36
|
+
## 功能特性
|
|
37
|
+
|
|
38
|
+
| 特性 | 说明 |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| 内联渲染 | 在提及媒体的聊天消息下方直接显示图像、视频和音频。 |
|
|
41
|
+
| 工作区安全读取 | 使用 `realpath` 解析本地路径,并拒绝目录穿越、工作区外路径和符号链接逃逸。 |
|
|
42
|
+
| ComfyUI 代理 | 由服务端从配置的源站获取识别到的 ComfyUI 媒体 URL,使远程用户和 HTTPS 页面也能正常查看。 |
|
|
43
|
+
| 资源限制 | 每个文件或响应最大 48 MiB,远程请求最长 20 秒。 |
|
|
44
|
+
| 用户控制 | 提供自动渲染、每条消息的媒体数量、媒体高度和 ComfyUI 源站设置。 |
|
|
45
|
+
|
|
46
|
+
## 支持的媒体格式
|
|
47
|
+
|
|
48
|
+
| 类型 | 扩展名 |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| 图像 | `png`、`jpg`、`jpeg`、`webp`、`gif`、`avif`、`bmp`、`svg` |
|
|
51
|
+
| 视频 | `mp4`、`webm`、`mov`、`m4v`、`mkv`、`avi`、`ogv` |
|
|
52
|
+
| 音频 | `mp3`、`wav`、`m4a`、`aac`、`ogg`、`oga`、`flac`、`opus` |
|
|
53
|
+
|
|
54
|
+
## 安装
|
|
55
|
+
|
|
56
|
+
### 通过 npm 安装
|
|
57
|
+
|
|
58
|
+
在 Web profile 中安装并启用 Bundle:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
dsh plugin --profile web add @wisdoverse/dsh-inline-media-viewer
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
安装后重启 Web profile。
|
|
65
|
+
|
|
66
|
+
### 从源码安装
|
|
67
|
+
|
|
68
|
+
1. 将插件克隆到 Web profile 可以访问的位置:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
git clone https://github.com/Wisdoverse/dsh-inline-media-viewer-plugin.git \
|
|
72
|
+
/path/to/local-plugins/dsh-inline-media-viewer
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
2. 将插件添加到 `profiles/web/package.json`:
|
|
76
|
+
|
|
77
|
+
```jsonc
|
|
78
|
+
{
|
|
79
|
+
"dependencies": {
|
|
80
|
+
"@wisdoverse/dsh-inline-media-viewer": "link:/path/to/local-plugins/dsh-inline-media-viewer"
|
|
81
|
+
},
|
|
82
|
+
"dsh": {
|
|
83
|
+
"profile": {
|
|
84
|
+
"bundles": ["…", "@wisdoverse/dsh-inline-media-viewer"]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
3. 重新构建或重启 Web profile。
|
|
91
|
+
|
|
92
|
+
插件通过 [`cordis.patch.yml`](cordis.patch.yml) 挂载宿主 RPC 通道、客户端投影和设置区域。
|
|
93
|
+
|
|
94
|
+
## 配置
|
|
95
|
+
|
|
96
|
+
打开 **设置 → 媒体预览 / Media preview**。
|
|
97
|
+
|
|
98
|
+
| 设置项 | 默认值 | 可选范围 |
|
|
99
|
+
| --- | --- | --- |
|
|
100
|
+
| 自动渲染检测到的媒体 | 开启 | 开启 / 关闭 |
|
|
101
|
+
| 每条消息的最大媒体数量 | `12` | `1`–`30` |
|
|
102
|
+
| 媒体最大高度 | `380 px` | `160`–`1200 px` |
|
|
103
|
+
| ComfyUI 源站 | 留空 | `http(s)://host[:port]` |
|
|
104
|
+
|
|
105
|
+
设置值保存在 DSH 设置文档中。只有回环连接可以写入;远程浏览器可以读取设置,但不能持久化修改。
|
|
106
|
+
|
|
107
|
+
### ComfyUI 源站
|
|
108
|
+
|
|
109
|
+
- 留空时使用 `http://127.0.0.1:8188`。
|
|
110
|
+
- 支持 `http://host[:port]`、`https://host[:port]` 和不带协议的
|
|
111
|
+
`host[:port]`(默认使用 `http`)。
|
|
112
|
+
- HTTP 的默认端口为 `8188`,HTTPS 的默认端口为 `443`。
|
|
113
|
+
- 不允许包含凭据、路径、查询字符串或片段。
|
|
114
|
+
- 该地址必须能从 DSH 宿主进程访问。如果宿主运行在容器中,请填写容器内部可见的地址。
|
|
115
|
+
|
|
116
|
+
本地别名(`127.0.0.1:8188` 和 `localhost:8188`)以及配置的源站都会被识别为
|
|
117
|
+
ComfyUI 来源。非空的无效地址会明确报错,而不会静默回退到其他目标。
|
|
118
|
+
|
|
119
|
+
## 安全设计
|
|
120
|
+
|
|
121
|
+
本插件是本地信任辅助工具,不是通用的文件或网络代理:
|
|
122
|
+
|
|
123
|
+
- 本地读取仅限当前会话的工作区和已知媒体扩展名。
|
|
124
|
+
- 远程读取只能访问配置的 ComfyUI 源站,并拒绝重定向。
|
|
125
|
+
- 本地文件和远程响应均限制为最大 48 MiB。
|
|
126
|
+
- 设置写入仅允许回环连接。
|
|
127
|
+
- 浏览器接收的是 `data:` URL,而不是文件系统路径。
|
|
128
|
+
|
|
129
|
+
完整的信任模型和已知限制请参阅 [SECURITY.md](SECURITY.md)。
|
|
130
|
+
|
|
131
|
+
## 开发
|
|
132
|
+
|
|
133
|
+
### 常用命令
|
|
134
|
+
|
|
135
|
+
| 命令 | 用途 |
|
|
136
|
+
| --- | --- |
|
|
137
|
+
| `node test.mjs` | 直接运行无依赖的单元测试。 |
|
|
138
|
+
| `npm test` | 通过 npm 运行同一套单元测试。 |
|
|
139
|
+
| `npm run lint` | 对宿主模块和测试文件执行语法检查。 |
|
|
140
|
+
|
|
141
|
+
### 项目结构
|
|
142
|
+
|
|
143
|
+
| 路径 | 职责 |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| `index.js` | 宿主 RPC 通道、ComfyUI 代理和设置注册。 |
|
|
146
|
+
| `lib.js` | 无依赖的纯辅助函数。 |
|
|
147
|
+
| `client/client.js` | 消息投影、媒体渲染器和设置界面。 |
|
|
148
|
+
| `cordis.patch.yml` | Bundle 挂载和集成点。 |
|
|
149
|
+
| `test.mjs` | 纯辅助函数的单元测试。 |
|
|
150
|
+
|
|
151
|
+
运行中的 Web profile 使用构建后的副本。修改源文件后,请重新构建或重启 Web profile。
|
|
152
|
+
|
|
153
|
+
## 许可证
|
|
154
|
+
|
|
155
|
+
本项目采用 [MIT 许可证](LICENSE)。
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
This plugin renders media in a user's chat. It is a **local trust helper**, not
|
|
4
|
+
a security boundary: the conversation content it renders is produced by the
|
|
5
|
+
same session that views it. What shipping standards demand here is that the
|
|
6
|
+
plugin *cannot be turned into a wider primitive* — no arbitrary local file
|
|
7
|
+
exfiltration, no arbitrary SSRF, no unbounded memory use.
|
|
8
|
+
|
|
9
|
+
## Local file reads
|
|
10
|
+
|
|
11
|
+
- Only the session's workspace root is readable: `realpath(cwd)` + containment
|
|
12
|
+
check (`isInside`) against the resolved target. Symlink escapes, `..`
|
|
13
|
+
traversal, and out-of-workspace paths are rejected.
|
|
14
|
+
- Only known media extensions are accepted (MIME map in `lib.js`).
|
|
15
|
+
- Size cap: 48 MiB per file.
|
|
16
|
+
- The client must supply a valid session id; the workspace root is taken from
|
|
17
|
+
that session's header, never from client input.
|
|
18
|
+
|
|
19
|
+
## Remote (ComfyUI) proxy
|
|
20
|
+
|
|
21
|
+
- The fetch target is always the **configured ComfyUI origin** (default
|
|
22
|
+
`http://127.0.0.1:8188`, `comfyUrl` in the `inline-media` settings
|
|
23
|
+
namespace) — never the source host. Chat content can therefore only
|
|
24
|
+
select a path/query on a server the user configured, not an arbitrary
|
|
25
|
+
host.
|
|
26
|
+
- A source URL is accepted only when its host:port is a local alias
|
|
27
|
+
(`127.0.0.1` / `localhost` on port 8188) **or** matches the configured
|
|
28
|
+
origin; everything else is rejected before any network I/O.
|
|
29
|
+
- The configured address is validated to a bare `http(s)://host[:port]`
|
|
30
|
+
origin: credentials, paths, queries, hashes, and odd hostnames are
|
|
31
|
+
rejected. A non-empty invalid value fails remote reads with an explicit
|
|
32
|
+
error instead of silently retargeting; an empty value uses the built-in
|
|
33
|
+
default.
|
|
34
|
+
- Settings writes are loopback-only (see below), so only the local user
|
|
35
|
+
can point the proxy at another host — a remote viewer cannot retarget it.
|
|
36
|
+
- `redirect: "error"` — redirects are refused.
|
|
37
|
+
- 20 s timeout, 48 MiB response cap, and the response MIME must be
|
|
38
|
+
image/video/audio.
|
|
39
|
+
|
|
40
|
+
## Transport
|
|
41
|
+
|
|
42
|
+
- The media channel `/inline-media/read` is registered with the DSH
|
|
43
|
+
connection service (`authority: "trusted-host"`), so it runs under the same
|
|
44
|
+
browser-trust fence and session gating as DSH's own RPC surface.
|
|
45
|
+
- The client renderer never receives file system paths back — only `data:`
|
|
46
|
+
URLs — so a hostile session cannot use the channel as a file oracle for
|
|
47
|
+
paths the UI already knows.
|
|
48
|
+
|
|
49
|
+
## Settings
|
|
50
|
+
|
|
51
|
+
- Values are normalized client-side and validated server-side against the
|
|
52
|
+
schema (autoRender boolean; displayCap 1–30; imageMaxPx 160–1200;
|
|
53
|
+
comfyUrl string ≤ 512 chars, parsed to a bare origin at use time).
|
|
54
|
+
- The settings service only writes back for **loopback** connections; remote
|
|
55
|
+
browsers are read-only, so a remote viewer cannot persist state.
|
|
56
|
+
|
|
57
|
+
## Known limitations
|
|
58
|
+
|
|
59
|
+
- Remote (non-loopback) browsers cannot persist settings by design (DSH
|
|
60
|
+
settings writes are loopback-only).
|
|
61
|
+
- ComfyUI on a non-standard host/port: set the server address in the settings
|
|
62
|
+
page. The proxy fetches only from that configured origin, so it must be
|
|
63
|
+
reachable from the DSH host process — plain `http://` for a local install,
|
|
64
|
+
`https://` behind a TLS-terminating proxy. The loopback aliases
|
|
65
|
+
(`127.0.0.1`/`localhost` on port 8188) are always accepted as source
|
|
66
|
+
origins; editing `COMFY_HOSTS`/`COMFY_PORTS` is deliberate code surgery,
|
|
67
|
+
not a configuration surface.
|