fix(media): accept workspace-relative paths in /sidebar/file and the HTML preview (#618) - #622
Open
yanzhaohui1999 wants to merge 3 commits into
Open
Conversation
2 tasks
yanzhaohui1999
force-pushed
the
fix/618-media-relative-path
branch
2 times, most recently
from
September 10, 2026 15:12
e172635 to
799ca7a
Compare
…ev#618) Since the native right-Sidebar migration a file tab is seeded by a dsh-resource://file/session/<sid>/<path> address, which spells an in-workspace file RELATIVE to the session root. /sidebar/file was the only file route that demanded an absolute path (requireAbsolute -> 400), so every image / PDF / download viewer answered 400 and stayed blank, while the text channel kept working because fs.read has always joined a relative target onto the session cwd. /sidebar/html is the same root cause and cannot be fixed host-side (its encoder drops a leading /, its decoder rebuilds an absolute path), so the client must resolve before encoding. Host: resolveWorkspaceTarget() joins a relative target onto the session's authoritative cwd before ensureWorkspacePath, keeping the realpath fence — ../ escapes, outside absolute paths and outward symlinks still 403. Client: mediaUrl / downloadUrl / htmlUrl resolve through resolveSidebarPath(cwd, path) first; an absolute path is unchanged and a relative one without a cwd is left to the host. Two new specs (17 cases) drive the real routes through a fake context over a temporary workspace; stashing the source change fails 15 of them. Fixes omdsh-dev#618. Root cause, reproduction requests and the client-side HTML constraint were reported by @longisland-icetea; see docs/plans/2026-09-10-media-relative-path-618.md.
yanzhaohui1999
force-pushed
the
fix/618-media-relative-path
branch
from
September 10, 2026 15:14
799ca7a to
064e8b8
Compare
Contributor
Author
本 PR 正文的三次修订(方便 review,不必重读全文)
代码自始至终没有变过: v3 相对 v2 的实质新增(约 850 字):真机抓包表、已跑通的最小复现、「本 PR 不覆盖的内容」(presented → 宿主桌面 / 交付行被 presented 顶掉 / bash 产物在正文里不可点)。其余约 71% 与 v2 逐字相同。 顺带说明本 PR 的边界:只修「路径拼法」这条线(相对拼法被媒体 / HTML 路由拒绝),不涉及「点开之后去哪」—— presented 文件走宿主桌面是 DSH 的交付语义,另开待办。 |
…vs absolute path)
longisland-icetea
pushed a commit
to longisland-icetea/DSH-better-sidebar
that referenced
this pull request
Sep 11, 2026
…a paths Same fix as the local patch this replaces, reviewed upstream and carrying its own 17 regression cases (tests/media-relative-path.spec.ts, tests/media-url-relative.spec.ts) plus the guide and plan updates, so the local fork stops maintaining a parallel implementation of issue omdsh-dev#618. Applied verbatim from the pull request (PR omdsh-dev#622, branch fix/618-media-relative-path). Verified here: typecheck clean, 17/17 tests pass, and on the live server a relative image path answers 200 while an escaping one still answers 403.
longisland-icetea
pushed a commit
to longisland-icetea/DSH-better-sidebar
that referenced
this pull request
Sep 11, 2026
…a paths Same fix as the local patch this replaces, reviewed upstream and carrying its own 17 regression cases (tests/media-relative-path.spec.ts, tests/media-url-relative.spec.ts) plus the guide and plan updates, so the local fork stops maintaining a parallel implementation of issue omdsh-dev#618. Applied verbatim from the pull request (PR omdsh-dev#622, branch fix/618-media-relative-path). Verified here: typecheck clean, 17/17 tests pass, and on the live server a relative image path answers 200 while an escaping one still answers 403.
longisland-icetea
pushed a commit
to longisland-icetea/DSH-better-sidebar
that referenced
this pull request
Sep 11, 2026
…a paths Same fix as the local patch this replaces, reviewed upstream and carrying its own 17 regression cases (tests/media-relative-path.spec.ts, tests/media-url-relative.spec.ts) plus the guide and plan updates, so the local fork stops maintaining a parallel implementation of issue omdsh-dev#618. Applied verbatim from the pull request (PR omdsh-dev#622, branch fix/618-media-relative-path). Verified here: typecheck clean, 17/17 tests pass, and on the live server a relative image path answers 200 while an escaping one still answers 403.
|
神医,解决了,谢谢大佬。希望作者速速merge |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题(真机抓包,已复现)
v0.19.0 迁到 DSH 原生右侧栏后,同一个文件从两种入口打开,结果不同:
path=(Chromium Network,过滤sidebar/file).sidebar-route-demo/demo.svg(相对,无前导/)"... is not an absolute path")/Users/y/workspace/dsh-better-sidebar/.sidebar-route-demo/demo.svg(绝对)两条请求的
sessionId/cwd完全相同,唯一差异就是路径拼法。受影响的是全部靠
mediaUrl取字节的渲染:图片、PDF、二进制下载、.html渲染模式(走/sidebar/html);markdown 预览里的本地图片走同一条mediaUrl通道(同因,未单独抓包)。文本 / 代码 / markdown 正文不受影响。已跑通的最小复现:
write一个.svg(文本可写 → 进 produced → 收尾消息里出现蓝色行内代码链接;.svg又落在 image viewer 的扩展名里 → 必走mediaUrl);sidebar/file的path=是相对拼法;path=是绝对拼法。根因:播地址的一侧与收地址的一侧,对同一份地址语法的假定不一致
ui-chat的openFile注入fileAddressFor(sessionId, cwd, path)带 session cwd → 工作区内的文件写成相对拼法(util/workspace-path:路径在 cwd 之下 →sessionFileAddress(sessionId, 相对路径))。聊天里一切文件打开(工具行 / 产物行 / 正文提及 / 行内代码路径)都经这里 —— 抓包第 1 行就是它的产物src/client/service.ts:708scope?.cwd建地址,而openSidebarFile()(src/client/intercept.tsx)不传 scope →cwd === undefined→fileAddressFor保留绝对拼法 —— 抓包第 2 行就是它的产物,也是「从文件树点开不复现」的原因src/client/native/index.tsfileParamsOf()把address.path原样交给 tab →tab.path就是地址里的拼法(0.18 及以前恒为绝对路径)src/client/EditorHost.tsx+src/fs-tree.ts:129mediaUrl(scope, path)原样交给/sidebar/file,而它是全插件唯一硬性要求绝对路径的文件路由(requireAbsolute);fs.read走resolveGitPath()会把相对路径 join 到 cwd → 坏掉的只有媒体通道src/html-route.ts/sidebar/html是同因异面,且宿主无法补救:编码器丢掉前导/、解码器再统一补成绝对路径,相对拼法在该语法里不可表达(chart.html被当成/chart.html)归属:触发点在宿主(聊天漏斗按相对拼法播地址)。插件侧容错仍然必须 —— 本仓硬约束不改 DSH 源码;相对拼法本就合法(
dsh-resource://file/session/<sid>/<path>对工作区内文件就是这么拼的);第三方 viewer 与「客户端 cwd 尚未 hydrate」的窗口同样会送相对拼法。可选的上游改法(DSH 无 issue 追踪,只能走 Discussions):聊天漏斗改送绝对拼法,或在地址契约里写明两种拼法消费方都必须接受。修复
resolveWorkspaceTarget(cwd, target)(src/path-security.ts):绝对目标原样透传,相对目标 join 到 session 权威 cwd;/sidebar/file在ensureWorkspacePath之前套用它 → 与fs.read的历史语义对齐,并覆盖「客户端 cwd 尚未 hydrate」与第三方mediaUrlviewer 这两类兜底场景mediaUrl/downloadUrl/htmlUrl统一先经resolveSidebarPath(cwd, path)再编码(无 cwd 时原样返回 → 由宿主 join)。图片这条症状靠这里(抓包第 1 行:客户端把相对拼法原样发了出去)/sidebar/html的地址语法不改:编码器改为可表达相对路径会破坏已发布 URL 的兼容性与相对资源解析语义,因此这一侧只能由调用方解析ensureWorkspacePath的 realpath + 包含检查(../逃逸、工作区外绝对路径、指向工作区外的软链接照旧 403)本 PR 不覆盖的内容(避免误解)
present交付过)的文件 → 在宿主桌面打开(远程访问时表现为"在 Mac 上弹出来")chatFileMentions的交付语义:命中deliveries就走POST /api/present.open,与路径拼法无关。插件要接管需包装chatFileMentions服务值 + 设置开关(待办 P2)conversation.chat.turnTail接管目前只认produced,会把 DSH 原生 presented 那半边顶掉(待办 P1,另见 #390)produced(DSH 只从 write/edit 的工具结果记路径)也不进presented,除非被present过验证
tests/media-relative-path.spec.ts(10 例,假 ctx 挂真实路由 + 临时工作区):相对路径且无cwd参数 200、嵌套相对 200、绝对路径不变、?download=1、../逃逸 403、工作区外绝对 403、缺失文件 400、软链接逃逸 403、客户端 builder 产物直接喂给真实路由 200、htmlUrl产物喂给/sidebar/html200。tests/media-url-relative.spec.ts(7 例):相对路径 join、Windows 反斜杠 cwd、绝对 / 工作区外绝对不变、无 cwd 透传、html 相对与绝对拼法产出同一 URL。src/三处改动 stash 掉后,这 17 例中 11 例失败(宿主 7 + 客户端 4;其余 6 例断言的是「绝对路径不变 / 无 cwd 透传」这类既有行为)。pnpm typecheck✅、pnpm build✅(客户端纯度门通过)、改动文件eslint✅。pnpm test:2 failed | 124 passed(1325 例中 29 例posix_spawnp failed),与本机基线(stash 后单跑同两个 pty 文件)失败数完全一致,属沙箱禁 pty 的环境性失败。文档 / 兼容性
docs/plans/2026-09-10-media-relative-path-618.md:根因、两条入口的真机抓包、最小复现、上游可选改法与「不做」清单。docs/external-plugin-guide.md:补充path的两种拼法,以及/sidebar/html必须由调用方先解析成绝对路径。cache-control: public, max-age=31536000, immutable供给 → 修复需硬刷新或重启宿主才在浏览器生效;宿主侧改动重启即生效。冲突提示
与开放中的 #554(
fix/absolute-markdown-session-preview)同改src/client/api.ts与src/index.ts,hunk 不重叠,仅src/index.ts顶部 import 区块会小冲突,后合的一方 rebase 一次即可。Fixes #618。curl 复现与地址语法分析来自 @longisland-icetea 的 issue;其中「从文件树点开」那一步经真机对照不成立,已在正文更正。