@khorsheed/dsh-file-preview 0.3.2 → 0.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.
- package/CHANGELOG.md +11 -0
- package/README.en.md +38 -20
- package/README.i18n.yaml +2 -2
- package/README.md +39 -21
- package/cordis.patch.yml +10 -2
- package/lib/client.js +9590 -0
- package/lib/index.js +6 -6
- package/lib/typert.host.js +6 -2
- package/lib/types/client/DiffHistory.d.ts +20 -0
- package/lib/types/client/DiffHistory.js +56 -0
- package/lib/types/client/FilePreviewTab.d.ts +34 -0
- package/lib/types/client/FilePreviewTab.js +193 -0
- package/lib/types/client/TurnFileRow.d.ts +30 -0
- package/lib/types/client/TurnFileRow.js +72 -0
- package/lib/types/client/contract.d.ts +39 -0
- package/lib/types/client/contract.js +2 -0
- package/lib/types/client/definition.d.ts +55 -0
- package/lib/types/client/definition.js +93 -0
- package/lib/types/client/file-preview-store.d.ts +42 -0
- package/lib/types/client/file-preview-store.js +58 -0
- package/lib/types/client/icons.d.ts +21 -0
- package/lib/types/client/icons.js +5 -0
- package/lib/types/client/index.d.ts +80 -0
- package/lib/types/client/index.js +238 -0
- package/lib/types/client/locales.d.ts +16 -0
- package/lib/types/client/locales.js +177 -0
- package/lib/types/client/mentions-wrap.d.ts +60 -0
- package/lib/types/client/mentions-wrap.js +42 -0
- package/lib/types/client/open-in-app.d.ts +85 -0
- package/lib/types/client/open-in-app.js +146 -0
- package/lib/types/client/path-utils.d.ts +53 -0
- package/lib/types/client/path-utils.js +110 -0
- package/lib/types/client/preview.d.ts +27 -0
- package/lib/types/client/preview.js +72 -0
- package/lib/types/client/turn-files-cache.d.ts +24 -0
- package/lib/types/client/turn-files-cache.js +39 -0
- package/lib/types/client/turn-files.d.ts +26 -0
- package/lib/types/client/turn-files.js +14 -0
- package/lib/types/open-external.js +1 -1
- package/lib/types/reveal.js +5 -5
- package/locale/en.json +2 -2
- package/locale/zh.json +2 -2
- package/package.json +62 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# 变更记录
|
|
2
2
|
|
|
3
|
+
## 0.4.1(2026-09-30)
|
|
4
|
+
|
|
5
|
+
- **适配宿主 0.2.0 的 `runNativeCommand` 第四参**(`'hidden' | 'visible'`,Windows 启动可见性,其余平台忽略——0.2.0 起必填):GUI 启动器(`open -a`、`open -R`、`explorer /select`、nautilus/dolphin/nemo `--select`)传 `'visible'`,wslpath 翻译工具传 `'hidden'`
|
|
6
|
+
- 加宽 `@deepseek-ai/dsh-*` peer 区间以覆盖宿主 0.2.0
|
|
7
|
+
|
|
8
|
+
## 0.4.0(2026-09-27)
|
|
9
|
+
|
|
10
|
+
- **BREAKING(包结构)**:`@khorsheed/dsh-client-ui-file-preview` 并入本包——宿主 Remote 与浏览器半(「会话产物」右栏 tab、回合变更卡片、详情页)合并为一个包、一条 loader 行(id 仍为 `file-preview`,浏览器半经 `dsh.client` 发现,message-tools / taskpilot 同形态)。迁移:卸载旧界面包并删除组合里的 `ui-file-preview` 行;针对旧行 id 的 `disabled` 覆盖不再匹配,需要的话改写为 `file-preview`。旧包名已在 npm deprecate。
|
|
11
|
+
- 插件清单展示卡片(`locale/*.json` 的 meta)改用产物预览那张(会话产物 / Session Artifacts)。
|
|
12
|
+
- tab 实现 id(`FILE_PREVIEW_ID`)与文档/注释里的旧包名统一归一到 `@khorsheed/dsh-file-preview`;行为、wire 命名空间(`filePreview`)与字典命名空间不变。
|
|
13
|
+
|
|
3
14
|
## 0.3.2(2026-09-27)
|
|
4
15
|
|
|
5
16
|
无功能变更。随宿主 0.1.7-rc.2 基线发布波重发:全量构建+测试在 rc.2 基线通过(rc.1→rc.2 无触及本包的宿主变更,逐类清点见 [Agent Note](../../.agents/notes/implemented/architecture/2026-09-27-host-017-rc2-breaking-changes.md))。
|
package/README.en.md
CHANGED
|
@@ -4,21 +4,25 @@ English | [中文](README.md)
|
|
|
4
4
|
|
|
5
5
|
Every file the agent touched, on one page: what changed, and what it looks like now.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The agent worked for an hour; which files did it actually touch, and what did they end up looking like? With this plugin, the right sidebar's guide page gains a "Session products" entry: every file the session read, wrote, or edited, latest activity first. Clicking a row opens a detail view in the same tab, rendered by the shared content pane (title row: name + language chip + copy-path / show-in-folder / open-in-IDE — a split control with an app menu when several IDEs resolved; path row: path plus the view controls; search row: content search). It carries a Content / Change history toggle: document-form previews (markdown rendered, JSON inspector tree, CSV table, tiered sandboxed HTML, highlighted code) on one side, and a step-through of every recorded write/edit diff on the other. Each finished turn also ends with a small card summarizing which files changed and by how many lines. Files the agent happened to write through bash (heredocs, redirects, and the like) are collected too. The whole service is read-only — it looks at files, never touches them.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Since 0.4.0 the host Remote service and the browser UI ship as **this one package** (previously two packages and two rows: file-preview + ui-file-preview; the old name `@khorsheed/dsh-client-ui-file-preview` is deprecated on npm).
|
|
10
|
+
|
|
11
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/file-preview1.png" width="640" alt="the Produced tab's file preview: file list and inline markdown preview">
|
|
10
12
|
|
|
11
13
|
## Features
|
|
12
14
|
|
|
13
|
-
- **
|
|
15
|
+
- **Right-sidebar Produced page (one form on both host lines)** — a page-type right-sidebar tab (entered from the guide page) that is also a claimant: every file the session wrote or edited, latest activity first, searchable; a row click opens the detail view in-tab. The tab type claims `dsh-resource://file/**` addresses with a renderable-suffix filter at the extension band, outranking the official document tab's fallback band (a purely static test with no cold-cache window) — file-tree / mention / turn-card / product-row clicks all land in our detail view; types we cannot render (pdf, archives, binaries) fall through to the official document tab.
|
|
16
|
+
- **Detail view** — breadcrumb path header with actions (copy path always; "show in folder" = the file selected in the host file manager, and "open in IDE" = file-exact open via a split button listing every probed IDE, when the host probe finds a handler); the title row's "Reload" gesture re-reads the current file's content (the old read stays visible in flight, and a failure keeps it, reporting through the existing error slot); a Content / Change history toggle — document-form previews with content search, and per-write diff stepping (the official side still has no such dimension: workspace-changes is memory-resident, git-only, and lost on a host restart — this dimension stays self-drawn, **tracked upstream**).
|
|
17
|
+
- **Turn mutation card (both lines)** — each finished turn ends with a collapsible "N products" card (including bash captures — broader than the official deliverables row) with per-file line deltas; clicks take the official open route. On list-kind hosts (0.1.6-alpha.2+) the official deliverables entry in the same slot (present card + memory-resident changes card) is shadowed by a first-class slot mechanism — the turn area keeps only this durable, complete card.
|
|
18
|
+
- **Session file list (host Remote)** — every file the session's `read`/`write`/`edit` calls touched, with each write/edit change's diff attached.
|
|
14
19
|
- **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 instead of errors.
|
|
15
|
-
- **Bash-write capture** — files written through `bash` (heredocs, redirects, `tee`, `sed -i`) merged into the list, stat-verified and rebuilt after a host restart.
|
|
16
|
-
- **Reveal in folder** — opens the file's folder with the file selected, on macOS, Windows, WSL, and desktop Linux.
|
|
20
|
+
- **Bash-write capture** — files written through `bash` (heredocs, redirects, `tee`, `sed -i`) merged into the list, stat-verified and rebuilt after a host restart; artifacts bash wrote beyond the workspace root still render content and change history in our own detail view (through this plugin's Remote, which the workspace-scoped official read cannot serve).
|
|
17
21
|
- **Read-only by design** — no session state, no writes; a restarted host loses nothing.
|
|
18
22
|
|
|
19
|
-
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-
|
|
23
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/file-preview2.png" width="640" alt="per-artifact change history: pageable per-turn diffs">
|
|
20
24
|
|
|
21
|
-
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-
|
|
25
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/file-preview3.png" width="640" alt="the Produced tab: every file the session wrote, at a glance">
|
|
22
26
|
|
|
23
27
|
## Install
|
|
24
28
|
|
|
@@ -26,18 +30,14 @@ This package is the host half of file preview. Install it together with the comp
|
|
|
26
30
|
dsh plugin --profile web add @khorsheed/dsh-file-preview
|
|
27
31
|
```
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```sh
|
|
32
|
-
dsh plugin --profile web add @khorsheed/dsh-client-ui-file-preview
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Uninstall; if the client half is left behind, its zero-session handshake fails and every UI surface is absent (no error card or empty tab remains):
|
|
33
|
+
Since 0.4.0 one package is everything: the host row provides the `filePreview` Remote and the browser half is discovered through `dsh.client`. Restart the web instance to activate; uninstalling restores the previous composition exactly:
|
|
36
34
|
|
|
37
35
|
```sh
|
|
38
36
|
dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
39
37
|
```
|
|
40
38
|
|
|
39
|
+
> **Upgrading from 0.3.x**: the two rows are now one — drop the `ui-file-preview` row (`dsh plugin --profile web remove @khorsheed/dsh-client-ui-file-preview`) and keep/upgrade the `file-preview` row. A `disabled` override pinned to the old `ui-file-preview` row id no longer matches anything; retarget it to `file-preview` if needed.
|
|
40
|
+
|
|
41
41
|
## Config
|
|
42
42
|
|
|
43
43
|
```yaml
|
|
@@ -53,15 +53,20 @@ dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
|
53
53
|
|
|
54
54
|
## Compatibility
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
| Host line | Verdict |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| deepseek-harness master (`0.1.7-rc.2`) | ✅ full — the same form as 0.1.5: the self-drawn page claims renderable addresses at the extension band (rc.1's tab registry kept the band mechanism); the turnTail list arm also carries the official deliverables shadow |
|
|
59
|
+
| npm release (`>= 0.1.5-rc.1`) | ✅ full (`verifiedHost: 0.1.5-rc.1`) — same form; on chain-kind turnTail slots the registration probes and falls back to the select + priority -1 preemptive arm; the 0.1.5-rc.1 PTC rename is adapted (only `tool/ptc-dispatch` matches; the official v2→v3 log migration renames persisted rows) |
|
|
60
|
+
| npm release (`<= 0.1.4.x`) | ❌ unsupported — the right-sidebar tab system (`ctx.sidebarRightTabs` / `openResource`) landed in 0.1.5; older hosts stay on the previous release line |
|
|
58
61
|
|
|
59
|
-
**Version line mapping**:
|
|
62
|
+
**Version line mapping**: 0.3.0 and up require host `0.1.5-rc.1` or later; hosts on `0.1.2-rc.1` ~ `0.1.4.x` stay on the 0.2.x release line, and hosts on `0.1.0-rc.6` ~ `0.1.1-rc.2` stay on the 0.1.x release line (last release `0.1.1`). minHost does not move: the package carries no rc.1-only API (the turnTail list/chain arms already had a 0.1.5 fallback).
|
|
60
63
|
|
|
61
64
|
## Known Limitations
|
|
62
65
|
|
|
63
66
|
- **List is a point-in-time fold** — no push channel; the client refreshes by re-calling `list`.
|
|
64
67
|
- **No binary preview content** — non-image binaries answer `kind: 'binary'` with their size only.
|
|
68
|
+
- **Outside-workspace artifacts stay off the official route** — files bash wrote beyond the session's workspace root produce no `dsh-resource://file/...` address (the official `file` resource is workspace-scoped), so their rows carry a marker; our own detail view is unaffected — content and change history both render.
|
|
69
|
+
- **Current session only** — shows the selected session's files; not an arbitrary file browser.
|
|
65
70
|
|
|
66
71
|
## How it works
|
|
67
72
|
|
|
@@ -70,7 +75,7 @@ dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
|
70
75
|
|
|
71
76
|
`ctx.filePreview` (wire namespace `filePreview`) exposes six generated Remote methods:
|
|
72
77
|
|
|
73
|
-
- `capabilities()` — a zero-session availability handshake returning `{ protocolVersion: 1 }`; the
|
|
78
|
+
- `capabilities()` — a zero-session availability handshake returning `{ protocolVersion: 1 }`; the browser half installs UI surfaces only after it succeeds.
|
|
74
79
|
|
|
75
80
|
- `list(agent)` — a pure fold over `agent.session.events`: `read`/`write`/`edit` `tool/call`s contribute display paths, as do settled nested PTC `tool/ptc-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. Before returning, each path is resolved against the session cwd and `stat`-ed, keeping only those that still exist as a regular file — the log fold is history, the product list reflects disk state (a temp script a turn wrote then cleaned up is no longer a product); existence is probed fresh per call (not cached with the log fold).
|
|
76
81
|
- `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).
|
|
@@ -80,9 +85,22 @@ dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
|
80
85
|
|
|
81
86
|
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`.
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
The browser half (`src/client/`):
|
|
89
|
+
|
|
90
|
+
- `src/client/index.ts` — apply mounts the `filePreview` Remote and performs the zero-session `capabilities()` handshake; on success `installFilePreviewSurfaces` registers every UI surface and owns disposal; the turnTail list arm also registers the official deliverables entry's shadow
|
|
91
|
+
- `src/client/definition.tsx` — the page-type tab's registry definition (guide entry + `dsh-resource://file/**` renderable-suffix claims) and the claim suffix list
|
|
92
|
+
- `src/client/FilePreviewTab.tsx` — the right-sidebar Produced page (list + detail view)
|
|
93
|
+
- `src/client/preview.ts` — the adaptation layer: `filePreview` wire kind → the kernel's `PreviewRead`, dictionary adapters (the detail view's header and preview stack come from the shared kernel `@khorsheed/dsh-client-ui-content-preview`, inlined at the source plane)
|
|
94
|
+
- `src/client/DiffHistory.tsx` — per-write diff stepping (unique to this plugin)
|
|
95
|
+
- `src/client/mentions-wrap.ts` — the in-place wrap unifying mention opens into the sidebar (seam S1 tail)
|
|
96
|
+
- `src/client/open-in-app.ts` — the official open-in-app probe (action visibility)
|
|
97
|
+
- `src/client/TurnFileRow.tsx` — the per-turn "N products" card
|
|
98
|
+
|
|
99
|
+
Purely additive: the host half is one Remote service; the browser half self-mounts that Remote through the official `ctx.remote.$mount` channel, registers one right-sidebar tab type (`ctx.sidebarRightTabs` + the keyed `sidebar.right.pane.tab` seat) and one turn-file row (`conversation.chat.turnTail` — list-kind since 0.1.6-alpha.2, where the arm also registers an empty body under the official deliverables entry's cell id at priority -1 — the slot system's first-class shadowing: one cell, entries at distinct priorities, the lowest renders; the official entry stays on the ledger so its declared `deliverables.file.actions` child slot never collapses; on 0.1.5 hosts the slot is still the election chain and the registration falls back to the old select + `priority: -1` preemptive shape on a probe) — a stock dsh core runs it with zero edits. The namespace is not declared as an inject (self-mounting it would deadlock the loader); the mount is awaited, the service is read back via `ctx.get('remote.filePreview')`, and the zero-session `capabilities()` probe must return `{ protocolVersion: 1 }` before any UI surface is installed. If the host is absent, all surfaces remain absent. The turn card reads the same host `filePreview.turnFiles` RPC through a per-session client cache — one source of truth for card and tab.
|
|
84
100
|
|
|
85
|
-
|
|
101
|
+
The 0.1.5-rc.1 move retired four workarounds (upstream seam S1 landed): the `conversation.view` Produced tab, the `shell.overlay` preview drawer, the capture-phase DOM interception of prose mentions, and the turnTail `priority: -1` preemption — the official file-open entries (deliverables row / prose mentions / tool-result lines) all converge on `ctx.sidebarRight.openResource()`. Plan B (landed and vetoed by the repo owner on the same day, 2026-09-24): registering the content face into the official `documentPreviews` registry as the document tab's default renderer, plus the phase-two headless embedding — the seam cost (the renderer loading protocol, the extension-band takeover semantics, the headless layout coupling) and the UX compromises (change history demoted to the renderer dropdown, the copy button floating over the search row) did not hold up, so the self-drawn products page (the address-claim form) was restored on both lines; the turnTail shadow was not part of the veto and stays.
|
|
102
|
+
|
|
103
|
+
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.
|
|
86
104
|
|
|
87
105
|
</details>
|
|
88
106
|
|
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/file-preview/README.en.md
|
|
5
|
-
packages/file-preview/README.en.md:
|
|
6
|
-
packages/file-preview/README.md:
|
|
5
|
+
packages/file-preview/README.en.md: 0a6260b6ac67c37b7bf09549497a017724e8c5b7
|
|
6
|
+
packages/file-preview/README.md: 09e282f89ccbca7e1a7aaaab3e80c4f35c23a466
|
package/README.md
CHANGED
|
@@ -4,21 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
agent 碰过的文件一页看全:改了什么、现在长什么样。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
agent 干了半天活,到底动了哪些文件、改成了什么样?装了这个插件,右栏向导页会多出「会话产物」入口:这个会话读过、写过、改过的每个文件按最近活动倒序列出;点一个进入详情页——头部与预览栈由共享内容面板渲染(标题行:文件名 + 语言标签 + 复制路径 / 在文件夹打开 / 在 IDE 打开,多 IDE 时是带 app 菜单的分体控件;路径行:路径 + 内容/改动记录与渲染/源码等视图控件;搜索行:内容搜索),内容侧是文档形态(Markdown 渲染成文档、JSON 检查树、CSV 表格、HTML 沙箱分级渲染、代码高亮),改动记录逐次步进回看每一次 write/edit 的 diff。每个回合结束,对话里出现一张小卡片,汇总这一轮改了哪几个文件、各增删了多少行。agent 用 bash 顺手写的文件(heredoc、重定向之类)也一样收进来。整个服务只读——它只看文件,从不动文件。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
0.4.0 起宿主 Remote 服务与浏览器界面合并为**这一个包**(此前是 file-preview + ui-file-preview 两个包两行;旧包名 `@khorsheed/dsh-client-ui-file-preview` 已在 npm deprecate)。
|
|
10
|
+
|
|
11
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/file-preview1.png" width="640" alt="「产物」tab 的文件预览:文件列表与内联 markdown 预览">
|
|
10
12
|
|
|
11
13
|
## 功能
|
|
12
14
|
|
|
13
|
-
-
|
|
15
|
+
- **右栏「产物」页(双线一致)**——page-type 右栏 tab(向导页进入)兼认领方:会话写入或编辑过的每个文件按最近活动倒序、可搜索;点行进入详情页。0.1.5 与 0.1.7-rc.2 同一份形态。tab 类型以 `dsh-resource://file/**` + 可渲染后缀认领,extension 档压过官方 document tab 的 fallback 档(纯静态判定无冷启动窗口);pdf、压缩包等渲染不了的类型自动回落官方 document tab——文件树/mention/回合卡/产物行点击全部落自绘详情页。
|
|
16
|
+
- **详情页**——面包屑路径头 + 行动作(复制路径恒定可用;宿主探测到对应应用时另有「在文件夹中打开」= 文件管理器选中该文件、「在 IDE 打开」= 文件级精确打开,split button 下拉可选探测到的任一 IDE);标题行「重新加载」手势重读当前文件的内容(重读期间旧内容保持显示,失败保留旧内容并走既有错误槽);「内容 / 改动记录」切换——内容是文档形态预览(含内容搜索),改动记录逐次步进每一次 write/edit 的 diff(官方至今仍无对应维度:workspace-changes 内存态、git-only、宿主重启即失——此维度长期自留,**跟踪上游**)。
|
|
17
|
+
- **回合变更卡片(双线)**——每个已完成回合末尾可收起的「N 个产物」卡片(含 bash 捕获,比官方产物行数据全),逐文件列出行数增减;点击走官方打开路由(可渲染地址由本页认领)。list 槽宿主上(0.1.6-alpha.2 起)同槽官方 deliverables 条目(present 卡 + 内存态 changes 卡)被一等 slot 遮蔽压下——回合区只留这张持久全量卡。
|
|
18
|
+
- **会话文件清单(宿主 Remote)**——会话 `read`/`write`/`edit` 调用触碰过的每个文件,每次 write/edit 改动附 diff。
|
|
14
19
|
- **内容读取**——文件当前文本,超限截断并标记;web 宿主上图片返回浏览器可加载的 URL;二进制、不存在、超限的文件返回分类提示而不是报错。
|
|
15
|
-
- **bash 写入采集**——经 `bash` 写入的文件(heredoc、重定向、`tee`、`sed -i`)并入清单,经 stat
|
|
16
|
-
- **在文件夹中打开**——在宿主文件管理器中打开所在文件夹并选中文件,支持 macOS、Windows、WSL、桌面 Linux。
|
|
20
|
+
- **bash 写入采集**——经 `bash` 写入的文件(heredoc、重定向、`tee`、`sed -i`)并入清单,经 stat 验证,宿主重启后自动重建;工作区外的 bash 产物在我们的详情页里内容和改动记录照常可看(走本插件 Remote,官方工作区读覆盖不到)。
|
|
17
21
|
- **只读设计**——无会话状态、无写入;宿主重启不丢任何东西。
|
|
18
22
|
|
|
19
|
-
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-
|
|
23
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/file-preview2.png" width="640" alt="每个产物的改动记录:逐轮 diff 可翻页回看">
|
|
20
24
|
|
|
21
|
-
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-
|
|
25
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/file-preview3.png" width="640" alt="「产物」tab:会话写过的全部文件一览">
|
|
22
26
|
|
|
23
27
|
## 安装
|
|
24
28
|
|
|
@@ -26,18 +30,14 @@ agent 碰过的文件一页看全:改了什么、现在长什么样。
|
|
|
26
30
|
dsh plugin --profile web add @khorsheed/dsh-file-preview
|
|
27
31
|
```
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```sh
|
|
32
|
-
dsh plugin --profile web add @khorsheed/dsh-client-ui-file-preview
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
卸载;如果只残留客户端半,它的零会话握手会失败,全部 UI 面均缺席(不留错误卡或空 tab):
|
|
33
|
+
0.4.0 起一个包即是全部:宿主行提供 `filePreview` Remote,浏览器半经 `dsh.client` 发现。重启 web 实例后生效;卸载即精确还原:
|
|
36
34
|
|
|
37
35
|
```sh
|
|
38
36
|
dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
39
37
|
```
|
|
40
38
|
|
|
39
|
+
> **从 0.3.x 升级**:两行合一——删掉组合里的 `ui-file-preview` 行(`dsh plugin --profile web remove @khorsheed/dsh-client-ui-file-preview`),保留/升级 `file-preview` 行即可。旧组合里针对 `ui-file-preview` 行的 `disabled` 覆盖不再匹配任何行,需要的话改写为 `file-preview`。
|
|
40
|
+
|
|
41
41
|
## 配置
|
|
42
42
|
|
|
43
43
|
```yaml
|
|
@@ -53,15 +53,20 @@ dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
|
53
53
|
|
|
54
54
|
## Compatibility
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
| Host 行 | 结论 |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| deepseek-harness master(`0.1.7-rc.2`) | ✅ 完整——与 0.1.5 同一形态:自建产物页 extension 档认领可渲染地址(rc.1 的 tab-registry 保留 band 机制);turnTail list 槽臂附带官方 deliverables 遮蔽 |
|
|
59
|
+
| npm release(`>= 0.1.5-rc.1`) | ✅ 完整(`verifiedHost: 0.1.5-rc.1`)——同一形态;turnTail 为 chain 槽时按探测回落 select + priority -1 抢占臂;0.1.5-rc.1 的 PTC 更名已适配(只匹配 `tool/ptc-dispatch`;旧日志由官方 v2→v3 迁移改写到新名) |
|
|
60
|
+
| npm release(`<= 0.1.4.x`) | ❌ 不可用——右栏 tab 体系(`ctx.sidebarRightTabs` / `openResource`)随 0.1.5 落地;旧宿主请停留在旧发布线 |
|
|
58
61
|
|
|
59
|
-
**版本线对照**:0.
|
|
62
|
+
**版本线对照**:0.3.0 起要求宿主 `0.1.5-rc.1` 及以后;宿主 `0.1.2-rc.1` ~ `0.1.4.x` 的用户请停留在 0.2.x 发布线,宿主 `0.1.0-rc.6` ~ `0.1.1-rc.2` 的用户请停留在 0.1.x 发布线(末版 `0.1.1`)。minHost 不动:包内没有 rc.1 专有 API(turnTail 的 list/chain 双臂本就有 0.1.5 回退)。
|
|
60
63
|
|
|
61
|
-
##
|
|
64
|
+
## 已知限制
|
|
62
65
|
|
|
63
66
|
- **列表是时间点折叠**——没有推送通道;客户端通过重新调用 `list` 刷新。
|
|
64
67
|
- **不提供二进制预览内容**——非图片二进制文件只返回 `kind: 'binary'` 及大小。
|
|
68
|
+
- **工作区外产物不进官方路由**——bash 写到会话工作区之外的文件造不出 `dsh-resource://file/...` 地址(官方 `file` 资源限定工作区内),列表行带提示标记;但我们自己的详情页不受此限——内容与改动记录照常可看。
|
|
69
|
+
- **仅当前会话**——只显示当前所选会话的文件,不是任意文件浏览器。
|
|
65
70
|
|
|
66
71
|
## 实现原理
|
|
67
72
|
|
|
@@ -70,7 +75,7 @@ dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
|
70
75
|
|
|
71
76
|
`ctx.filePreview`(wire 命名空间 `filePreview`)暴露六个生成的 Remote 方法:
|
|
72
77
|
|
|
73
|
-
- `capabilities()`——零会话可用性握手,返回 `{ protocolVersion: 1 }
|
|
78
|
+
- `capabilities()`——零会话可用性握手,返回 `{ protocolVersion: 1 }`;浏览器半只在握手成功后安装 UI 面。
|
|
74
79
|
|
|
75
80
|
- `list(agent)`——对 `agent.session.events` 的纯折叠:`read`/`write`/`edit` 的 `tool/call` 贡献展示路径,这些工具的已完结嵌套 PTC `tool/ptc-dispatch` 同样计入(失败的派发不记录;条目借用根调用的 turn/step)。携带 `diffs` 元数据的 `write`/`edit` `tool/result` 把每次改动按事件序追加进条目,`lastDiff` 保留为最后一次。响应携带条目、最后扫描的 seq,以及是否触达 `maxFiles`。折叠本身不访问文件系统;`captureBashWrites` 开启时并入采集器验证过的 bash 写入路径。返回前按会话 cwd 解析每条路径并 `stat`,只保留当前仍存在的常规文件——日志折叠是历史,产物列表只看磁盘现状(某回合写后又清理的临时脚本不再是产物);存在性每次调用都现查(不随日志折叠缓存)。
|
|
76
81
|
- `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`(含消息)。
|
|
@@ -80,9 +85,22 @@ dsh plugin --profile web remove @khorsheed/dsh-file-preview
|
|
|
80
85
|
|
|
81
86
|
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` 读当前内容。
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
浏览器半(`src/client/`):
|
|
89
|
+
|
|
90
|
+
- `src/client/index.ts` —— apply:挂载 `filePreview` Remote 并执行零会话 `capabilities()` 握手;成功后由 `installFilePreviewSurfaces` 注册所有 UI 面并统一卸载;turnTail 的 list 臂同时注册官方 deliverables 条目的遮蔽体
|
|
91
|
+
- `src/client/definition.tsx` —— page-type tab 的注册表定义(guide 入口 + `dsh-resource://file/**` 可渲染后缀认领)与认领后缀清单
|
|
92
|
+
- `src/client/FilePreviewTab.tsx` —— 右栏「产物」页(列表 + 详情视图)
|
|
93
|
+
- `src/client/preview.ts` —— 适配层:`filePreview` wire kind → 内核 `PreviewRead`、字典适配(详情页的头部与预览栈来自共享内核 `@khorsheed/dsh-client-ui-content-preview`,源码面内联)
|
|
94
|
+
- `src/client/DiffHistory.tsx` —— 逐次 write/edit diff 步进(本插件独有)
|
|
95
|
+
- `src/client/mentions-wrap.ts` —— mention 打开方向统一进右栏的就地包装(缝 S1 尾巴)
|
|
96
|
+
- `src/client/open-in-app.ts` —— 官方 open-in-app 探测(行动作可见性)
|
|
97
|
+
- `src/client/TurnFileRow.tsx` —— 每回合的「N 个产物」卡片
|
|
98
|
+
|
|
99
|
+
纯增量插件:宿主半是一个 Remote 服务,浏览器半经官方 `ctx.remote.$mount` 通道自挂载该 Remote,注册一个右栏 tab 类型(`ctx.sidebarRightTabs` + keyed `sidebar.right.pane.tab` seat)与一个回合文件行(`conversation.chat.turnTail`——0.1.6-alpha.2 起该槽为 list 语义,本行另注册一条同官方 deliverables cell id、priority -1 的空体遮蔽官方 present/changes 卡——slot 系统一等遮蔽:同 cell 异优先级共存、最低者渲染,官方条目仍在册故其声明的 `deliverables.file.actions` 子槽不塌;0.1.5 宿主上该槽仍是 chain 选举,注册按探测回落为旧的 select + `priority: -1` 抢占形)——原版 dsh 核心零改动即可运行。该命名空间不声明为 inject(自挂载会让加载器死锁);挂载被 await 后用 `ctx.get('remote.filePreview')` 读回,并先执行零会话 `capabilities()`;只有 `{ protocolVersion: 1 }` 成功返回才安装这些 UI 面,宿主缺席时全部缺席。回合卡片经按会话的客户端缓存读同一个宿主 `filePreview.turnFiles` RPC——卡片与 tab 同一事实源。
|
|
84
100
|
|
|
85
|
-
|
|
101
|
+
0.1.5-rc.1 迁移退役了四处绕行(上游缝 S1 已落地):`conversation.view` 的「产物」tab、`shell.overlay` 预览抽屉、正文 mention 的捕获阶段 DOM 拦截、turnTail 的 `priority: -1` 抢占——产物行 / 正文 mention / 工具结果行的打开入口官方已统一收敛到 `ctx.sidebarRight.openResource()`。方案 B(2026-09-24 落地、同日被仓主否决回退):内容面注册进官方 `documentPreviews` 面做官方 document tab 默认渲染器 + 二期 headless 嵌入——接缝成本(renderer loading 协议、extension 档接管语义、headless 布局耦合)与 UX 妥协(改动记录塞进渲染器下拉、复制钮浮动压搜索行)不成立,自绘产物页(地址认领形态)双线恢复;turnTail 遮蔽不在否决范围,保留。
|
|
102
|
+
|
|
103
|
+
信任与状态:受信任的只读能力——能读取 `ctx.fs` 允许会话访问的一切,组合它即授予对会话文件系统视图的预览权限;它不是安全边界。不产生会话事件;仅有的按会话状态是回合折叠缓存与 bash 采集器的已验证写入登记表。
|
|
86
104
|
|
|
87
105
|
</details>
|
|
88
106
|
|
package/cordis.patch.yml
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# file-preview bundle patch: inserts the plugin row into the composing
|
|
2
|
-
# profile.
|
|
3
|
-
#
|
|
2
|
+
# profile. Since 0.4.0 this ONE row carries both halves — the host half
|
|
3
|
+
# provides the `filePreview` Remote service and the browser half (the
|
|
4
|
+
# right-sidebar 会话产物 tab, the per-turn change cards, the detail view) is
|
|
5
|
+
# discovered through the package.json `dsh.client` block (the message-tools /
|
|
6
|
+
# taskpilot single-package shape). Before 0.4.0 the two halves shipped as two
|
|
7
|
+
# packages and mounted as two rows (`file-preview` + `ui-file-preview`); the
|
|
8
|
+
# merged row keeps the `file-preview` id, so a composition upgrade only drops
|
|
9
|
+
# the `ui-file-preview` row — a `disabled` override pinned to that old row id
|
|
10
|
+
# no longer matches anything (one-time migration: retarget it to
|
|
11
|
+
# `file-preview`).
|
|
4
12
|
# Note: the @-prefixed name must stay quoted — it is a YAML reserved character.
|
|
5
13
|
- insert:
|
|
6
14
|
- id: file-preview
|