Repository navigation
Conversation
2 tasks done
Arfrsa
force-pushed
the
fix/editor-directory-fallback
branch
2 times, most recently
from
October 22, 2026 09:57
04efa68 to
19102dc
Compare
…1029) A path that resolves to a directory (a chat folder link, a sidebar_open folder, or a directory pasted into the editor address bar) was read as a file: the host answered 400 fs-error '"<path>" is a directory' and EditorHost painted that raw message into the tab instead of the plugin's folder window. - fs.read / fs.readPage now answer a directory with the dedicated fs-directory wire code (src/wire.ts, readText/readPage). - EditorHost promotes the tab to the folder window it already draws. - The promoted root is a PLATFORM-NATIVE ABSOLUTE path, resolved against the session workspace root by the new resolveNativeSidebarPath helper (paths.ts): chat file addresses carry session-relative, forward-slash spellings, while the host keys every listing by its path.resolve'd absolute path and FileTree caches levels by the requested root. A relative root or a mixed-separator root lands in another cache key and the tree sits on its loading placeholder forever. The helper also drops a trailing separator (except a drive root) like path.resolve does. - The fix covers all three entry points at once: conversation folder links (no meta.dir on the tab), sidebar_open folders (service.openTab drops the seed meta on the native resource route), and omdsh-dev#933's pasted/stepped directory path. Tests: isDirectoryReadError unit cases, the EditorHost relative-path and Windows-root fallback render cases, resolveNativeSidebarPath win32/POSIX cases, and the fs.readPage directory code. typecheck + build + lint pass; targeted suites 78/78; the full suite's remaining failures reproduce on a clean dev checkout (Windows symlink / pnpm pack / git smokes) and are unrelated to this change. Verified in the live GUI: a folder opened after the patch expands its tree immediately.
Arfrsa
force-pushed
the
fix/editor-directory-fallback
branch
from
October 22, 2026 09:58
19102dc to
b4e9924
Compare
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.
现象
从会话里打开一个目录时,右侧栏不会出现以该目录为根的 folder window,而是把它当文件读,并在页签里显示原始 host 错误:
两条可复现入口:
[legacy-implementation/](research/workspace-sections-campaign/legacy-implementation)。点击后
@deepseek-ai/dsh-client-ui-chat的openFile→fileAddressFor()→ctx.sidebarRight.openResource('dsh-resource://file/session/<sid>/<path>'),地址里没有「这是目录」的信息。sidebar_open打开目录:src/client/sidebar/use-host-feeds.ts给打开请求带了meta: { dir: true },但service.openTab的原生右栏 editor 分支(
src/client/service.ts1150–1167 行)把 path seed 转成surface.openResource(address)时没有转发
seed.meta(只有非 editor 类型在 1184 行才带 meta),meta.dir丢失后同样按文件读。第三个既存触发路径是 #933(编辑器地址栏粘贴/切换目录),根因相同。
根因
editor类型以patterns: ['dsh-resource://file/**']、priority: 'extension'注册为文件资源查看器(
src/client/native/index.ts约 350 行),canOpen只排除HOST_OWNED_EXTS;目录地址没有扩展名,也通过 canOpen,于是被编辑器认领。
EditorHost只有metaOf(tab).dir === true才渲染文件夹树(src/client/EditorHost.tsx137 行)。会话链接没有这个 meta,于是走文件加载,
api.fsRead→ hostfs.read→readText()stat 到目录后抛
fs-error400,EditorHost把原始 message 渲染成错误页签(EditorHost.tsx655 行)。chat 地址带的是会话相对路径,
FileTree又按请求的根路径缓存层级;而 hostfs.trees返回的每个层级
path是path.resolve后的平台原生绝对路径。只补meta.dir→ 相对 root 卡「加载中」;只解析成绝对路径 → Windows 上
C:\…\workspace\research/workspace-sections-campaign/x仍是混合斜杠,与 host 的全反斜杠 key 不一致,依旧卡「加载中」。
修复
fs.read/fs.readPage在目标为目录时返回专用错误码fs-directory(
src/wire.ts、src/index.ts的readText/readPage),不再与普通fs-error混在一起。src/client/editor-load.ts新增isDirectoryReadError(error)(检查code === 'fs-directory');EditorHost在fetchFsRead失败时,若是目录错误则把当前页签就地升级为插件已有的 folder window(
meta.dir: true+ TreePanel),不显示原始错误。src/client/paths.ts新增resolveNativeSidebarPath(cwd, path)—— 先resolveSidebarPath,Windows 方言下再把/全部规整为\并去掉尾部分隔符(drive 根保留;POSIX 保持原样,反斜杠是合法文件名字符)。promotion 用
ctx.sessions里的会话工作区根(fallbackscope.cwd)调用它,再updateTab({ path: nativeAbsolute, title, meta: { dir: true } })同时写 path/meta。sidebar_open目录、地址栏粘贴目录(同时覆盖 [Bug] 在已打开文件的编辑器中输入/切换文件夹路径报错:"..." is a directory #933)。模板/tab 记录沿用现有 folder 语义(
meta.dir与标题),未新增 UI、未新增 i18n key、未改公共 API 形状。选择「错误码 + 自愈」而不是「在 openResource 里正向传 meta」的原因:会话链接在进入插件前就不知道目标是目录,
插件侧也无法同步 stat;而 open 一旦发生,folder window 本来就是该 tab 的正确归宿,
fs.read的 stat 是唯一可靠判定点。
sidebar_open的正向 meta 透传可以另开 PR(会动SidebarSurface.openResource的公共参数面),本 PR 修的是所有入口共同的失败面。
测试
新增/更新:
tests/editor-load.spec.ts:isDirectoryReadError识别fs-directory,其它 code / 非对象返回 false。tests/editor-host.spec.tsx:src)在目录fs.read拒绝后,tab 的path被解析成绝对路径(
/tmp/src)、meta变成{ dir: true },重渲染后出现树面板搜索框,且不再显示is a directory;C:\work)下同一用例断言 promotion 结果是C:\work\src(分隔符规整),钉住「混合斜杠 → 树永远加载中」的回归。
tests/paths.spec.ts:resolveNativeSidebarPath的 win32 方言规整、尾部分隔符去除、drive 根保留、POSIX/undefined 保持原样。
tests/fs-read-page.spec.ts:目录分页读取的错误码从fs-error改为fs-directory。本地验证(Windows 11,Node 24,pnpm 11.8.0):
pnpm typecheck✅pnpm build✅pnpm lint✅pnpm exec vitest run tests/paths.spec.ts tests/editor-load.spec.ts tests/fs-read-page.spec.ts tests/editor-host.spec.tsx✅ 78/78子项(会话目录链接与
sidebar_open目录走同一条 promotion 分支),用户已确认可用。pnpm test(全量):2677 passed / 8 failed / 19 skipped(7 files failed)。失败项全部是环境类,且与本次改动无关:Windows 符号链接权限(archive-tools / fs-operations / fs-mkdir / file-stream-route)、本机 shell 里
pnpm pack失败(market-manifest / plugin-meta)、git smoke;上传并发用例为已知时序 flake(不同轮次会少/多 1 条)。
我在干净的
dev基线上复跑同类 6 个 spec,同类同样失败,因此不属于本 PR 引入的回归;与本改动直接相关的 spec 全绿。关联
Fixes #1029
Related #933(同一根因的第三条触发路径;本 PR 一并覆盖)
说明