@khorsheed/dsh-file-preview 0.1.0
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 +11 -0
- package/LICENSE +21 -0
- package/README.en.md +88 -0
- package/README.i18n.yaml +6 -0
- package/README.md +88 -0
- package/cordis.patch.yml +7 -0
- package/lib/index.js +1338 -0
- package/lib/invariant.js +25 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/typert.host.d.ts +3 -0
- package/lib/typert.host.js +549 -0
- package/lib/typert.remote-client.d.ts +35 -0
- package/lib/typert.remote-client.d.ts.map +1 -0
- package/lib/typert.remote-client.js +210 -0
- package/lib/types/bash-writes.d.ts +83 -0
- package/lib/types/bash-writes.d.ts.map +1 -0
- package/lib/types/bash-writes.js +367 -0
- package/lib/types/fold.d.ts +77 -0
- package/lib/types/fold.d.ts.map +1 -0
- package/lib/types/fold.js +309 -0
- package/lib/types/index.d.ts +105 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +517 -0
- package/lib/types/invariant.d.ts +16 -0
- package/lib/types/invariant.d.ts.map +1 -0
- package/lib/types/invariant.js +23 -0
- package/lib/types/reveal.d.ts +36 -0
- package/lib/types/reveal.d.ts.map +1 -0
- package/lib/types/reveal.js +77 -0
- package/lib/types/types.d.ts +124 -0
- package/lib/types/types.d.ts.map +1 -0
- package/lib/types/types.js +2 -0
- package/package.json +81 -0
- package/skills/3d-artifact/SKILL.md +52 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# 变更记录
|
|
2
|
+
|
|
3
|
+
## 0.1.0(2026-08-22)
|
|
4
|
+
|
|
5
|
+
首个公开发布。
|
|
6
|
+
|
|
7
|
+
- 会话文件清单:列出会话 `read`/`write`/`edit` 触碰过的每个文件,每次 write/edit 改动附 diff
|
|
8
|
+
- 内容读取:返回文件当前文本,超限截断并标记;web 宿主上图片返回浏览器可加载的 URL;二进制、缺失、超限文件返回分类提示
|
|
9
|
+
- bash 写入采集:heredoc、重定向、`tee`、`sed -i` 写入的文件并入清单,经 stat 验证,宿主重启后重建
|
|
10
|
+
- 在宿主文件管理器中打开所在文件夹并选中文件,支持 macOS、Windows、WSL、桌面 Linux
|
|
11
|
+
- 只读设计:无会话状态、无写入,宿主重启不丢任何东西
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-plugins contributors
|
|
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.en.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @khorsheed/dsh-file-preview
|
|
2
|
+
|
|
3
|
+
English | [中文](README.md)
|
|
4
|
+
|
|
5
|
+
Host service for dsh's file-preview surface: lists every file a session's tool calls touched — each write/edit change's diff included — and serves any file's current content for preview. Pair it with `@khorsheed/dsh-client-ui-file-preview` and the web GUI gains a Produced-files tab with inline previews and reveal-in-folder.
|
|
6
|
+
|
|
7
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/file-preview1.png" width="480" alt="the companion client's file-preview pane: file list and inline markdown preview">
|
|
8
|
+
|
|
9
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/file-preview2.png" width="480" alt="per-artifact change history: pageable per-turn diffs">
|
|
10
|
+
|
|
11
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/file-preview3.png" width="480" alt="the Produced tab: every file the session wrote, at a glance">
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Session file list** — every file the session's `read`/`write`/`edit` calls touched, with each write/edit change's diff attached.
|
|
16
|
+
- **Content reads** — current text, capped and flagged when truncated; images as browser-loadable URLs on web hosts; binary, missing, and oversized files answer classified notices.
|
|
17
|
+
- **Bash-write capture** — files written through `bash` (heredocs, redirects, `tee`, `sed -i`) merged into the list, stat-verified and rebuilt after a host restart.
|
|
18
|
+
- **Reveal in folder** — opens the file's folder with the file selected, on macOS, Windows, WSL, and desktop Linux.
|
|
19
|
+
- **Read-only by design** — no session state, no writes; a restarted host loses nothing.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
dsh plugin --profile web add @khorsheed/dsh-file-preview
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Host half only — install the companion client for the visible surface (Produced tab, preview drawer, per-turn change card):
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
dsh plugin --profile web add @khorsheed/dsh-client-ui-file-preview
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Uninstall; a leftover client half degrades to an empty state rather than an error:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Config
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
- id: file-preview
|
|
43
|
+
name: '@khorsheed/dsh-file-preview'
|
|
44
|
+
config:
|
|
45
|
+
maxReadBytes: 524288
|
|
46
|
+
maxFiles: 500
|
|
47
|
+
captureBashWrites: true
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`maxReadBytes` caps a single `read` (larger files answer `too-large`), `maxFiles` caps the `list` fold — both positive integers, defaults 512 KiB and 500 — and `captureBashWrites` (default `true`) toggles the bash-write collector.
|
|
51
|
+
|
|
52
|
+
## Compatibility
|
|
53
|
+
|
|
54
|
+
- npm release line (`@deepseek-ai/dsh@0.1.1-rc.2`): ✅ full — the rc.8→0.1.1-rc.1 API audit (2026-08-21) confirms every surface this plugin consumes is unchanged or additive (the ProjectionDefinition restructure, cacheHitPercent return-type change, and the credentials/updated event rename do not touch this package); no source change was needed; re-audited for rc.2 (2026-08-22): consumed surface unchanged, full build+test green.
|
|
55
|
+
- source line (deepseek-harness master): ✅
|
|
56
|
+
|
|
57
|
+
## Known Limitations
|
|
58
|
+
|
|
59
|
+
- **List is a point-in-time fold** — no push channel; the client refreshes by re-calling `list`.
|
|
60
|
+
- **No binary preview content** — non-image binaries answer `kind: 'binary'` with their size only.
|
|
61
|
+
|
|
62
|
+
## How it works
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary>Internals (click to expand)</summary>
|
|
66
|
+
|
|
67
|
+
`ctx.filePreview` (wire namespace `filePreview`) exposes four generated Remote methods:
|
|
68
|
+
|
|
69
|
+
- `list(agent)` — a pure fold over `agent.session.events`: `read`/`write`/`edit` `tool/call`s contribute display paths, as do settled nested Code Mode `tool/code-dispatch`es for those tools (failed dispatches record nothing; entries borrow the root call's turn/step). A `write`/`edit` `tool/result` carrying `diffs` meta appends each change to the entry in event order, `lastDiff` kept as the final one. The response carries the entries, the last scanned seq, and whether `maxFiles` was hit. No filesystem access in the fold; with `captureBashWrites` on, entries merge with the collector's verified bash-written paths.
|
|
70
|
+
- `read(agent, path, signal)` — resolves `path` against the session cwd and serves `kind: 'text'` (capped at `maxReadBytes`, flagged `truncated`), or `kind: 'image'` with a browser-loadable URL on web hosts — bytes ride a dedicated `/file-preview-image/<sessionId>/<path>` route, registered only when the optional `webServer` and `agents` services are composed; headless hosts answer `binary` — or a classified notice: `binary` (binary extension or NUL bytes; never read), `missing`, `too-large`, or `error` (message included).
|
|
71
|
+
- `reveal(agent, path, signal)` — opens the file's folder with the file selected, shell-free through `@deepseek-ai/dsh-native-command`: macOS `open -R`, Windows `explorer /select,<path>`, WSL via `wslpath`, desktop Linux tries `nautilus`/`dolphin`/`nemo --select` in order. Answers `{ revealed: true }`, or `false` with `reason: 'missing'` (no such target) or `'select-failed'` (no capable file manager — the caller then opens the parent folder, so the gesture always lands somewhere visible). Writes nothing.
|
|
72
|
+
- `turnFiles(agent)` — every turn's file mutations for the turn-tail card, the same single source of truth as `list` but NOT deduped: a file touched in two turns appears in both groups, so each card lists exactly what that turn mutated. Line deltas are summed from result diffs; the fold is cached per session and invalidated by the log watermark, which the response carries for the client's own cache.
|
|
73
|
+
|
|
74
|
+
Bash-write collector: watches each session's bash `tool/call`/`tool/result` pairs, extracts high-precision write targets (`cat > path` heredocs, single `>` redirects, `tee` non-append, `sed -i`), expands `$VAR`/`~`/relative paths against the host environment and session cwd, and records only paths `fs.stat` confirms as files (a miss beats a false positive). Captures live in a per-session in-memory registry rebuilt by replaying the session's own history on `session/created`, so a restarted host regains them; the session log itself is never mutated (the official `Session.append` cannot mark a plugin event `ignorable` — see the S2 seam in `docs/upstream-seam-registry.md`). Bash-captured files carry no diff history; previews read current content through `read`.
|
|
75
|
+
|
|
76
|
+
Trust and state: a trusted, read-only capability — it reads whatever `ctx.fs` allows for the session, so composing it grants preview access to the session's filesystem view; it is not a security boundary. It emits no session events; its only per-session state is the turn-fold cache and the bash collector's verified-writes registry.
|
|
77
|
+
|
|
78
|
+
Sharing: a pure host-side addition — one Remote service, mounted by the browser half through the official `ctx.remote.$mount` channel. The browser half (`@khorsheed/dsh-client-ui-file-preview`) is equally additive; both distribute independently and compose into a stock dsh core with zero edits.
|
|
79
|
+
|
|
80
|
+
</details>
|
|
81
|
+
|
|
82
|
+
## Development
|
|
83
|
+
|
|
84
|
+
Part of the [dsh-plugins](https://github.com/Khorsheed/dsh-plugins) monorepo (`packages/file-preview`). Issues and contributions welcome there.
|
|
85
|
+
|
|
86
|
+
## Changelog
|
|
87
|
+
|
|
88
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record: the git blob hash of each side as of the
|
|
2
|
+
# last confirmed-consistent state. Both languages carry equal authority; after
|
|
3
|
+
# editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/file-preview/README.en.md
|
|
5
|
+
packages/file-preview/README.en.md: 244347bb89f3796d687220bfdb44c3daf7d68a5a
|
|
6
|
+
packages/file-preview/README.md: 3131fafedb08f02e90323172cfd4d087e3ce77a6
|
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @khorsheed/dsh-file-preview
|
|
2
|
+
|
|
3
|
+
[English](README.en.md) | 中文
|
|
4
|
+
|
|
5
|
+
dsh 文件预览界面的宿主服务:列出会话工具调用触碰过的每个文件——附每次 write/edit 改动的 diff——并提供任一文件的当前内容用于预览。与 `@khorsheed/dsh-client-ui-file-preview` 成对安装,web GUI 即获得「产物」tab:内联预览与"在文件夹中打开"。
|
|
6
|
+
|
|
7
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/file-preview1.png" width="480" alt="配套客户端的文件预览:文件列表与内联 markdown 预览">
|
|
8
|
+
|
|
9
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/file-preview2.png" width="480" alt="每个产物的改动记录:逐轮 diff 可翻页回看">
|
|
10
|
+
|
|
11
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/file-preview3.png" width="480" alt="「产物」tab:会话写过的全部文件一览">
|
|
12
|
+
|
|
13
|
+
## 特性
|
|
14
|
+
|
|
15
|
+
- **会话文件清单**——会话 `read`/`write`/`edit` 调用触碰过的每个文件,每次 write/edit 改动附 diff。
|
|
16
|
+
- **内容读取**——文件当前文本,超限截断并标记;web 宿主上图片返回浏览器可加载的 URL;二进制、不存在、超限文件返回分类提示。
|
|
17
|
+
- **bash 写入采集**——经 `bash` 写入的文件(heredoc、重定向、`tee`、`sed -i`)并入清单,经 stat 验证,宿主重启后重建。
|
|
18
|
+
- **在文件夹中打开**——在宿主文件管理器中打开所在文件夹并选中文件,支持 macOS、Windows、WSL、桌面 Linux。
|
|
19
|
+
- **只读设计**——无会话状态、无写入;宿主重启不丢任何东西。
|
|
20
|
+
|
|
21
|
+
## 安装
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
dsh plugin --profile web add @khorsheed/dsh-file-preview
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
仅宿主半——可见界面(「产物」tab、预览抽屉、回合变更卡片)在配套客户端里:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
dsh plugin --profile web add @khorsheed/dsh-client-ui-file-preview
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
卸载;残留的客户端半降级为空态而非报错:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 配置
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
- id: file-preview
|
|
43
|
+
name: '@khorsheed/dsh-file-preview'
|
|
44
|
+
config:
|
|
45
|
+
maxReadBytes: 524288
|
|
46
|
+
maxFiles: 500
|
|
47
|
+
captureBashWrites: true
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`maxReadBytes` 限制单次 `read`(超限返回 `too-large`),`maxFiles` 限制 `list` 折叠结果——均为正整数,默认 512 KiB 与 500——`captureBashWrites`(默认 `true`)开关 bash 写入采集器。
|
|
51
|
+
|
|
52
|
+
## Compatibility
|
|
53
|
+
|
|
54
|
+
- npm 发布线(`@deepseek-ai/dsh@0.1.1-rc.2`):✅ 完整——rc.8→0.1.1-rc.1 API 审计(2026-08-21)确认本插件消费的所有面无变化或纯增量(ProjectionDefinition 重构、cacheHitPercent 返回值变更、credentials/updated 事件改名均不涉及本包),无需改动源码;rc.1→rc.2 复核(2026-08-22):消费面无变化,全量构建测试通过。
|
|
55
|
+
- 源码线(deepseek-harness master):✅
|
|
56
|
+
|
|
57
|
+
## 已知限制
|
|
58
|
+
|
|
59
|
+
- **列表是时间点折叠**——没有推送通道;客户端通过重新调用 `list` 刷新。
|
|
60
|
+
- **不提供二进制预览内容**——非图片二进制文件只返回 `kind: 'binary'` 及大小。
|
|
61
|
+
|
|
62
|
+
## 实现原理
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary>内部结构(点击展开)</summary>
|
|
66
|
+
|
|
67
|
+
`ctx.filePreview`(wire 命名空间 `filePreview`)暴露四个生成的 Remote 方法:
|
|
68
|
+
|
|
69
|
+
- `list(agent)`——对 `agent.session.events` 的纯折叠:`read`/`write`/`edit` 的 `tool/call` 贡献展示路径,这些工具的已完结嵌套 Code Mode `tool/code-dispatch` 同样计入(失败的派发不记录;条目借用根调用的 turn/step)。携带 `diffs` 元数据的 `write`/`edit` `tool/result` 把每次改动按事件序追加进条目,`lastDiff` 保留为最后一次。响应携带条目、最后扫描的 seq,以及是否触达 `maxFiles`。折叠本身不访问文件系统;`captureBashWrites` 开启时并入采集器验证过的 bash 写入路径。
|
|
70
|
+
- `read(agent, path, signal)`——以会话 cwd 为基准解析 `path`,返回 `kind: 'text'`(超过 `maxReadBytes` 截断并标记 `truncated`);web 宿主上图片返回 `kind: 'image'` 及浏览器可加载 URL——字节走专门的 `/file-preview-image/<sessionId>/<path>` 路由,仅当组合了可选的 `webServer` 与 `agents` 服务时注册;无 web 宿主返回 `binary`——否则返回分类提示:`binary`(二进制扩展名或 NUL 字节;绝不读取)、`missing`、`too-large`、`error`(含消息)。
|
|
71
|
+
- `reveal(agent, path, signal)`——在宿主文件管理器中打开文件所在文件夹并选中它,全程无 shell,走 `@deepseek-ai/dsh-native-command`:macOS `open -R`、Windows `explorer /select,<path>`、WSL 经 `wslpath`、桌面 Linux 依次尝试 `nautilus`/`dolphin`/`nemo --select`。选中返回 `{ revealed: true }`,否则 `false` 及 `reason: 'missing'`(目标不存在)或 `'select-failed'`(无可用文件管理器——调用方改开父文件夹,手势总能落在可见处)。不写入任何东西。
|
|
72
|
+
- `turnFiles(agent)`——每个回合的文件变更,回合卡片与 `list` 同源但**不**去重:同一文件在两个回合改过,两个分组都有它——每张卡片精确列出该回合改了什么。行数增减由 result diff 求和;折叠按会话缓存、由日志水位线失效,响应携带水位线供客户端自缓存。
|
|
73
|
+
|
|
74
|
+
bash 写入采集器:监听每个会话的 bash `tool/call`/`tool/result` 配对,提取高精度写入目标(`cat > path` heredoc、单 `>` 重定向、`tee` 非追加、`sed -i`),按宿主环境与会话 cwd 展开 `$VAR`/`~`/相对路径,只记录 `fs.stat` 确认为文件的路径(宁缺毋滥)。采集结果存于按会话的内存登记表,`session/created` 时重放会话自身历史重建——宿主重启后不丢;会话日志本身绝不被改动(官方 `Session.append` 无法给插件事件标 `ignorable`——见 `docs/upstream-seam-registry.md` 的 S2 条目)。bash 采集的文件没有 diff 历史;预览与普通条目一样通过 `read` 读当前内容。
|
|
75
|
+
|
|
76
|
+
信任与状态:受信任的只读能力——能读取 `ctx.fs` 允许会话访问的一切,组合它即授予对会话文件系统视图的预览权限;它不是安全边界。不产生会话事件;仅有的按会话状态是回合折叠缓存与 bash 采集器的已验证写入登记表。
|
|
77
|
+
|
|
78
|
+
分享:纯宿主侧增量——一个 Remote 服务,由浏览器半经官方的 `ctx.remote.$mount` 通道挂载。浏览器半(`@khorsheed/dsh-client-ui-file-preview`)同样纯增量;两个包独立分发,零改动组合进原版 dsh 核心。
|
|
79
|
+
|
|
80
|
+
</details>
|
|
81
|
+
|
|
82
|
+
## 开发
|
|
83
|
+
|
|
84
|
+
隶属 [dsh-plugins](https://github.com/Khorsheed/dsh-plugins) monorepo(`packages/file-preview`)。问题与贡献请移步该仓库。
|
|
85
|
+
|
|
86
|
+
## 变更记录
|
|
87
|
+
|
|
88
|
+
见 [CHANGELOG.md](CHANGELOG.md)。
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# file-preview bundle patch: inserts the plugin row into the composing
|
|
2
|
+
# profile. Host half only (the session file-fold Remote service); the browser
|
|
3
|
+
# side ships in the companion @khorsheed/dsh-client-ui-file-preview package.
|
|
4
|
+
# Note: the @-prefixed name must stay quoted — it is a YAML reserved character.
|
|
5
|
+
- insert:
|
|
6
|
+
- id: file-preview
|
|
7
|
+
name: '@khorsheed/dsh-file-preview'
|