Commit Graph
133 Commits
Author SHA1 Message Date
figmar 23ca3daac3 chore(sync): re-base the fork onto upstream dsh-better-sidebar v0.24.1 (rename only) 2026-10-04 00:46:18 +08:00
Menghuan1918 0ac62b3a49 Merge origin/main (v0.22.1 与三个热修 PR) into feat/files-changes-uiux
冲突面 11 个文件,逐项裁决如下:

1. src/client/native/index.ts —— **取 main 版**。main 的 v0.22.1 在同一处做了更强的修复
   (清理循环同样跳过 FILES_KIND,另加 `disposeSafely` 与「注册失败必须回滚已占用 id /
   已建槽位」),是我们那行守卫的超集。
   ⚠️ 但 main 分支从来没有过我们 task-19 的 `records.attachStore(store)` 调用,整文件
   采用会**静默丢掉**它(records 拿不到 store → `toggleExpanded` 直接 return → 点目录
   树毫无反应),且 jsdom 单测看不见(它们自己绑 records)。已按原注释恢复该调用,并在
   注释里记下这次合并教训。真实宿主 lane 证明:恢复前 `zz-expand-refresh` 红(请求为
   空、`big` 不展开),恢复后 9/9 全绿。
2. package.json / dsh.plugin.json / src/client/service.ts —— 版本相关冲突取我们的
   0.24.1(支持线 ^0.2.0-rc.1 不变)。
3. CHANGELOG / README(中英各一)—— 双方版本节全部保留:我们的 v0.24.1 / v0.24.0 +
   **新增缺失的 v0.23.0 节**(开发线,内容随 v0.24.1 发布)+ main 的 v0.22.1。
   同时修正两处事实错误:① 「0.1.7 线请固定 v0.23.0」→ **v0.22.1**(0.23.0 从未发布);
   ② 安装对照表里 0.1.7 行的安装命令同改。README 并补上 v0.23.0 摘要(含 ⚠️ 删除工作区
   路径检测这一安全相关的行为变更)。
4. docs/external-plugin-guide.md —— 版本行取我们的(0.2.0 线)。

验证(合并后的树):pnpm typecheck / lint / test = **137 文件 / 1491 通过 / 9 跳过**
(含 main 新增的 native-registration.spec.ts);pnpm build ✓;
DSH_CMD='npx -y --package @deepseek-ai/dsh@0.2.0-rc.1 dsh' pnpm test:mount = **9/9**
(mount 5 + perf 2 + main 的 native-reload 1 + 我们的 zz-expand-refresh 1)。
2026-09-28 23:13:36 +08:00
Menghuan1918 98a446bbfc fix(sidebar): 点击展开时文件树整体重建(两处根因)+ v0.24.1
用户报告:「点击展开的时候,文件树会频繁整体刷新,看起来非常难受」。

根因 1(主):src/client/native/index.ts 的 sync() 把 files 接管项当成多余注册。
它按 KIND 记账、永远不在 wanted 里,于是每次 sync 都被 dispose + 重建;而
disposeSubscriptions 同时订阅了 service 与 store,**任何会话状态写入**(展开/收起、
切 tab、拖底部工作台、选中…)都会跑一遍 sync。替换 slot 注册 = 宿主换 slot entry →
插件 tab body 被 unmount/remount → 文件树丢失层缓存、滚动位置与目录 watcher,并重新
fs.trees([root, ...expanded]) 重列整棵可见树。机械证明(临时插桩,已回退):
  [probe-sync] enter live=[editor,git,subagent,sidechat,diff,files]
  [probe-registerSlots] slot inject ran for dsh-better-sidebar:files
  [probe-body] unmount tab3 kind=files
  [probe-body] mount tab3 kind=files
修法:wantsFiles 提前,删除循环里对 files 接管项 skip(禁用 editor 时仍照旧释放)。

根因 2(次):FileTree.tsx 的 retryDir 先把该层缓存删掉再请求,行被「Loading…」
占位替换后重建——目录有外部写入(构建 / 格式化 / 模型跑 bash)时整层闪空。
修法:复用既有 force 路径 loadLevels([dir], { force: true }),保留旧行直到新答案到达
(与 refreshTick 的强制刷新路径行为一致)。

判别性证据(回退任一修复即红)
- tests/native-surface.spec.ts:三次 store 写入不得产生任何注册/注销 → 回退后
  registered 6 → 12、disposed 全是 dsh-better-sidebar:files
- tests/file-tree-batch-load.spec.tsx:重列期间旧行仍在屏 → 回退后层被删空
- 新增真实宿主 lane tests/e2e/zz-expand-refresh.e2e.ts(quiescence 判据,无固定 sleep;
  zz- 前缀保证它最后跑,因为它会自建 workspace + session):A1 展开只请求被展开那一层、
  A2 tab body 存活(不重开 watch socket)、A3 屏上行数不归零;回退修复 1 后退出码 1
  (Error: expanding a folder must ask for that folder, not the whole visible set)

修复后实测(40 子项目录,同一探针/机器/工作区)
| 阶段 | fs.trees payload | 新开 ws | DOM +/- | 被删行 | body 替换 | 层内最小行数 |
| 展开 big | [big](原 [root, big]) | 0(原 1) | +41/-1 | 0(原 45) | 0(原是) | 40(原 40) |
| 外部写入 big | [big] | 0 | +1/-0(原 +41/-40) | 0 | 0 | 40(原 0) |
| 展开 bravo | [bravo] | 0 | +2/-1 | 0(原 45) | 0(原是) | 41 |

证伪记录:新建 fs.watch(dir,{persistent:false}) 在 macOS 上无改动时 0 事件(Node 微
探针两遍 + 8 轮真实时序 + 浏览器侧从未收到 {dir} 陈旧帧)→ src/fs-watch.ts 与
use-dir-watch.ts 一行未改。

验证:pnpm typecheck / lint / test(136 文件 1486 通过 9 跳过,基线 1484 + 新增 2)/ build
全绿;DSH_CMD='npx -y --package @deepseek-ai/dsh@0.2.0-rc.1 dsh' pnpm test:mount = 8/8。
版本 0.24.0 → 0.24.1(package.json / dsh.plugin.json / SIDEBAR_SERVICE_VERSION /
README×2 / CHANGELOG×2 同步)。
2026-09-28 22:33:30 +08:00
Menghuan1918 b91675ae61 feat(dsh): 适配 DSH 0.2.0-rc.1(单线支持)+ v0.24.0
支持线从 ^0.1.7-rc.1 整体前移到 ^0.2.0-rc.1;0.1.7 线(含 npm latest 的
0.1.7-rc.2)停留在 v0.23.0。适配前实测确认这是纯增量,故本版无运行时兼容分支。

必改项(否则装不上/不加载)
- 14 条 DSH peer → ^0.2.0-rc.1。实测 caret 跨 minor 不成立:`^0.1.7-rc.1`
  展开为 >=0.1.7-rc.1 <0.2.0-0,对 0.2.0-rc.1 判定 false(includePrerelease
  也救不了)。判别性验证:把 peer 回退成 ^0.1.7-rc.1 后,在 0.2.0-rc.1 宿主上
  `dsh plugin add` 直接拒绝并回滚包树——
  "installation rejected: Plugin dsh-better-sidebar@0.24.0 is incompatible with
   dsh 0.2.0-rc.1: peerDependencies {…^0.1.7-rc.1…}";恢复 ^0.2.0-rc.1 后安装通过
- 28 个 @deepseek-ai/* devDependencies 精确钉 0.2.0-rc.1(cordis 4.0.4 /
  cordis-plugin-group 1.0.4 / cordis-plugin-include 1.0.9 不变)
- 新增 @deepseek-ai/dsh-util-code-language@0.2.0-rc.1:0.2.0 的 ui-primitives
  产物裸 import 它(0.1.7 的产物同样 import,只是旧树里恰好被传递提供),
  不补则所有加载 ui-primitives 的 20 个 spec 在收集期失败

实测证据(写进 docs/plans/2026-09-28-dsh-0.2.0-rc.1-adaptation.md)
- 本插件消费的 19 个宿主包零值导出删除(对比 export {} / exports.x=)
- 类型面仅 3 处且全为增量:ui-primitives(DisclosureRow/TextShimmer/Tooltip
  新增可选 prop、overlay 顶部内距)、dsh-session(新增 ToolCallRecovery)、
  dsh-api-remotes(新增 product-analytics remote)
- 会话格式仍 v4、SUBAGENT_DESCRIPTOR_VERSION 仍 3、dsh/lib/bin.js 与
  dsh-client-modules 运行时逐字节相同、web profile 客户端 inject 列表相同、
  ui-primitives 裸 import 集合不变、agent-team 四包类型逐字相同
- 宿主 web profile:新增 desktop-only product-analytics/telemetry(web 上
  disabled);time-context/schedule/ui-schedule(本就 disabled)移入可选
  dsh-experimental-schedule-bundle;插件不依赖宿主 schedule

其余同步
- CI 与挂载 lane 钉 @deepseek-ai/dsh@0.2.0-rc.1(scripts/e2e-common.sh 的
  DSH_NPX_SPEC/DSH_EXPECT_VERSION、ci.yml),注释记下「0.2.0 首个候选版只挂
  next」与「caret 跨 minor 必失效」两条教训
- tests/market-manifest.spec.ts 的 peer 形状断言钉当前基线 tuple
- dsh.plugin.json engines.dsh → >=0.2.0-rc.1;SIDEBAR_SERVICE_VERSION → 0.24.0
- README/README_EN、CHANGELOG/CHANGELOG_EN、AGENTS.md(§2 钉版句 + §3 改为
  「DSH 版本适配要点」并新增 §3.0 当前基线,0.1.7 内容降为历史分节)、
  docs/external-plugin-guide.md 全部同步

验证:pnpm peers check 仅剩上游 better-locale 的 5 条 unmet(非本插件 peer);
typecheck / lint / test(136 文件 1484 通过 9 跳过)/ build 全绿;
DSH_CMD='npx -y --package @deepseek-ai/dsh@0.2.0-rc.1 dsh' pnpm test:mount = 7/7;
pnpm test:mount:aggregate 通过(聚合双挂载退让)
2026-09-28 21:21:45 +08:00
Menghuan1918 5c95002641 perf(sidebar): fs.tree 22.8ms→3.8ms + 删除工作区路径检测(放开权限)+ 树展开状态按会话
用户实测反馈:

1) `/sidebar/api/fs.tree` 性能极差 —— 先测后改(10k 条目目录、热缓存、中位数):
   - 冷调用 cap=1000:22.76ms → **3.77ms**;TTL 内重复:≈23ms → **0.000ms**
   - 改法:opendir for-await → readdir(withFileTypes) 一次取回;只为 cap 条建行
     (slice + 定长数组);路径用字符串拼接而非 path.join;排序弃 localeCompare
     (14.6ms/10k → 0.35ms)改小写比较 + 原名码点兜底;新增 1.5s 目录级缓存
     (键 绝对路径\0cap,上限 512),由 fs.write/rename/remove/mkdir/upload 与
     fs-watch 的变更通知显式失效
   - 契约逐字不变;新增 tests/fs-tree.spec.ts 6 例 + fs-watch 失效用例(判别性验证)

2) 删除工作区路径检测(默认不检测、放开权限):
   - path-security 变纯词法解析(realpath/包含性判定删除)、fs-operations 去 fence
     分支、所有 fs 路由不再读 fence、403 分支消失、config 删 workspaceFence 字段
     (schemastery 容忍未知键,旧 profile 不会加载失败)、settings 开关删除
   - ⚠️ 安全影响:插件 fs 路由(tree/read/write/rename/remove/mkdir/媒体/HTML/
     upload/archive)现在可读写宿主用户可访问的任意路径,只受 OS 权限约束;
     指南 §8.1 已加醒目声明
   - 死代码清理:FenceErrorNotice 组件 + EditorHost 分支 + 4 个词条(settingsFence*、
     fenceErrorReason、fenceDisableAction)+ isOutsideWorkspace* 助手 + TreePanel 的
     store prop + 相关 CSS 块

3) 批量列举路由 `fs.trees`(单层失败只在该层带 error)+ 客户端批量加载:
   挂载/刷新时的 N+1 请求变为 1 个(8 个展开目录:9 → 1,探针断言)
   refreshTick 不再先清缓存(旧行保留到新答案;失败保留旧行 + warn 提示)

4) 修复「关闭文件后返回文件树,展开状态被重置」:
   原生承载面的展开集合原来存在每个 tab 的记录里(drop 即丢),改为**每会话状态**
   的投影(ensure 从会话态读、toggleExpanded 写回会话态、registerNativeSurface 用
   attachStore 订阅);同一会话多 tab 共享、不同会话隔离;revealed 保持 per-tab

验证:typecheck / lint / test(136 文件 / 1484 通过 / 9 跳过)/ build 全绿;
DSH_CMD='npx -y --package @deepseek-ai/dsh@0.1.7-rc.1 dsh' pnpm test:mount 7/7 通过;
版本镜像同步(dsh.plugin.json + SIDEBAR_SERVICE_VERSION)
2026-09-28 20:37:56 +08:00
Menghuan1918 b011be1e98 feat(sidebar): 打开方式双源并存 + 多选压缩下载 + 文件变动层级树
用户追加三条需求,全部落地:

1) 打开方式 = 宿主探测应用 + 插件自研 open-with(并存)
- 逐字恢复 src/client/open-with.ts / open-with-settings.tsx / plugin-settings.ts /
  src/open-external.ts / open.external 路由 / api.openExternal / editor descriptor
  的 settings.render,以及 20 个 openWith* 词条(19 份词典从 main 取回原文)
- 恢复 menu-flip.ts + layout.css 子菜单翻转规则(子菜单回来了)
- FileTree 菜单段(无标题行):宿主行 → 分隔线 → 插件 pinned + 「在应用中打开 >」
  子菜单(图钉 / SSH 后缀原样)→ 分隔线 → 宿主 reveal;宿主可用时过滤插件
  explorer 目标,宿主不可用时插件行照旧(SSH 远端场景保持可用)
- 死键清理:菜单去掉标题行后 openInApp 词条无引用,已从 21 份词典删除

2) 文件页多选右键「压缩并打包下载」
- 新增 src/zip.ts(自研 ZIP:方法 0/8 按收益二选一、UTF-8 bit 11、目录条目、
  自实现 CRC32、无第三方依赖)+ src/archive-route.ts(名净化 + 递归收集)+
  GET /sidebar/archive(同一道 workspace fence、目录递归跳过符号链接、
  10000 条目 / 256 MiB 上限)+ api.archiveUrl
- FileTree:多选 ≥2 项或单选目录时出现;fetch → blob → objectURL 下载,
  路由错误(超限 / fence / 非 GET)以 zipFailed 显示在错误条
- 修掉真实缺陷:central directory 只写 MS-DOS 位而 version-made-by 声称 Unix,
  Info-ZIP 会把每个文件解成 mode 000;改为 Unix 语义(0o100644 * 0x10000,
  << 16 会溢出 int32)。系统 unzip 复验:mode 644/755、unzip -t 无错

3) 文件变动页层级树 + 视觉打磨
- 新增 src/client/changes/change-tree.ts:单子目录链压缩成一行、目录先于文件、
  大小写不敏感排序、文件带 GitFileStatus、目录带下级变更数
- GitLens 两组各自渲染树:折叠状态按「组+路径」独立、默认展开;分组头吸顶 +
  计数胶囊;Stage all/Unstage all 改为带 aria-label 的 IconButton;选中 =
  interactive-bg-active + 2px 内嵌强调条;12px/级缩进 + l1 参考线;
  历史行 hash 徽标 / ref 胶囊 / 作者·时间右对齐

验证:typecheck / lint / test(134 文件 1422 通过)/ build 全绿;
DSH_CMD='npx -y --package @deepseek-ai/dsh@0.1.7-rc.1 dsh' pnpm test:mount 7/7 通过;
真实宿主截图确认三条需求(多选+双源菜单+zip 项、变动页树形层级)
2026-09-28 18:08:21 +08:00
Menghuan1918 a18e0f000d docs(release): 修正 v0.22.1 条目里的测试计数与「3/3」措辞(独立 review 发现)
- 单测计数:`122 files / 1292 passed / 9 skipped` → **1293**。1292 是 #785 当时的数字,
  本 commit 自己的 `make check` 两次都报 1293(`tests/` 与 main 逐字相同,122 个 spec +
  `it.each` 展开 = 1293)。涉及 CHANGELOG.md / CHANGELOG_EN.md / README.md / README_EN.md
  与事故文档。
- 「3/3 红 / 3/3 绿」措辞改为「连续 3 次运行全红 / 全绿」并注明该 lane 里只有 1 个用例、
  是重复跑三次——原措辞会被读成「3 个用例各红一次」。涉及上述四份发布文档 + 事故文档
  + AGENTS.md §2(同一句话在那边也有)。
- 其余 review 结论均已满足:版本三处锁步 + 两个守护用例绿、无遗留 0.22.0 引用、
  zh/en 段落一一对应、「最近更新」保持两条并把指针下移为 v0.21.1 → v0.12.3、
  release.yml 的 tag 校验与 `latest` dist-tag 都能过、lockfile 无需改动。
2026-09-28 11:30:29 +08:00
Menghuan1918 2e94b56c36 chore(release): v0.22.1——修复 files 接管 id 孤儿化与 macOS 拖拽失效
- package.json / dsh.plugin.json / SIDEBAR_SERVICE_VERSION → 0.22.1(三者锁步由
  tests/service.spec.ts 与 tests/manifest-consistency.spec.ts 断言)
- README / README_EN:新增 v0.22.1 条目、同步三处徽章与 latest/支持线表格、
  切回 npm 通道的示例版本号;「最近更新」保持两条(v0.22.1 + v0.22.0),
  更早版本指针区间随之下移为 v0.21.1 → v0.12.3
- docs/external-plugin-guide.md:当前版本行 → v0.22.1
- CHANGELOG / CHANGELOG_EN:补 v0.22.1 条目(两个缺陷的根因链、真机证据、
  修复要点与守卫清单)

支持线**不变**:仅 DSH 0.1.7-rc.1+(peer 下限 ^0.1.7-rc.1,CI 钉 0.1.7-rc.1);
0.21.1 / 0.22.0 用户直接升级;0.1.6-alpha.2 及更早仍固定 v0.19.1。

内容提要:① 修复客户端条目替换后 `dsh-better-sidebar:files` id 被孤儿化
(#777 + #785:清理循环跳过 FILES_KIND + 注册失败回滚已占用的 id 与槽位,
并新增部署级回归门 tests/e2e/native-reload.e2e.ts);② 修复 macOS 桌面版
窗口拖拽/双击缩放失效(#773 + #786:视口层用 initial !important 退出
app-region 计算,补齐放大视图,探针改用真实级联计算值)。

验证:make check 全绿(typecheck / lint / build / test 122 files 1293 passed
9 skipped / check:consumer-types);此外本地 pnpm test:mount 与
pnpm test:mount:aggregate 绿,npm 0.22.0 与修复版在 scratch profile 上的
红→绿对照见 PR #785 / #786。
2026-09-28 11:23:48 +08:00
Menghuan1918 36fbc5ac7e feat(sidebar): 文件页与文件变动页 UIUX 重构 + 全局组件抽取
文件页(FileTree/TreePanel)
- Ctrl/Cmd 多选 + Shift 按可见行序连选(Esc/点空白/右键收敛),批量条支持复制路径、批量删除(共享 ConfirmDialog + 顺序 fsRemove)
- Git 变更着色:行名按状态上色 + M/A/D/U 徽标,目录按 dirHasChanges 着色,非仓库静默降级(数据来自共享 git 状态存储)
- 新建文件夹:fs.mkdir 路由 + mkdirWorkspaceEntry + 内联输入行(Enter/Esc/blur/IME 守卫)
- 性能:FileRow/DirRow memo(含反向验证)、搜索 hidden 停车不再卸载树、level 拉取世代守卫 + AbortController、fs.tree truncated 提示、use-dir-watch 入参 memo
- 拖拽上传视觉 token 化(硬编码色清零);可见性下传后隐藏页签停止轮询
- 右键「打开方式」改为复用 DSH 自带 open-in-app(宿主探测的关联应用 + 文件管理器显示)

文件变动页(changes/diff)
- 36px 头(宿主 SegmentedControl)+ 单一 ChangeRow + SectionHeader 分组 + 吸底提交条单状态行 + 历史独立空态
- 修掉:双份空态、暂存失败 unhandled rejection、手动刷新被丢、仓库切换刷新两次、worktree 清单缺 repoRoot、工作树被自动切走、预览持旧快照、恢复高度未 clamp、session ops 无谓轮询
- DiffPane/DiffTab 共用 use-git-diff;修掉 DiffPane 的 untracked 预览从不渲染

全局组件与宿主接入
- 新增 src/client/ui(IconButton/Chip/SectionHeader/Notice/ConfirmDialog/StatusBadge + 共享 git 状态存储)
- 新增 src/client/open-in-app.ts(宿主 open-in-app 客户端适配),删除自研 open-with 全链路与 open.external 路由
- 客户端 inject 补 remote / remote.session:缺声明时 ctx.get('remote').session 会抛出并把整个面板打成错误条(真实挂载 lane 抓到)
- 词典:+25 键 / -20 openWith* / -noChanges,20 份同步

验证:typecheck / lint / test(126 文件 1322 通过)/ build 全绿;
DSH_CMD='npx -y --package @deepseek-ai/dsh@0.1.7-rc.1 dsh' pnpm test:mount 7/7 通过(含 tab sweep 与 perf lane)
2026-09-28 00:27:31 +08:00
Menghuan1918 606339f81e chore(release): v0.22.0——任务管理页重做(工作流图)+ DSH 0.1.7 团队/后台任务数据面
版本号 bump 到 0.22.0(含 dsh.plugin.json 与 SIDEBAR_SERVICE_VERSION 两处镜像,
tests/manifest-consistency.spec.ts 与 tests/service.spec.ts 就是守这两处的),
README / README_EN 的版本徽章、支持线表格、npm 通道说明与「最近更新」段落同步,
CHANGELOG / CHANGELOG_EN 补 v0.22.0 条目正文。

支持线**不变**:仅 DSH 0.1.7-rc.1+(peer 下限 ^0.1.7-rc.1),0.21.1 用户可直接升级。
主内容是任务管理页从「子代理拓扑」重做为工作流图(图/树双视图、双段式节点卡、
主 Agent 同款合并活动行、扫光、两组折叠聚合、两个常驻浮动窗),以及随后按真机反馈
打磨的四轮修正;团队与后台任务两个数据面按 0.1.7 删掉的 Remote 方法/自建路由改写。

验证:typecheck / lint 通过;pnpm test 1288 passed / 9 skipped;build + pack 产出
dsh-better-sidebar-0.22.0.tgz。
2026-09-27 22:33:57 +08:00
Menghuan1918 aed5244236 docs(readme): move the community section ahead of recent updates 2026-09-27 12:00:59 +08:00
Menghuan1918 b69912b32e docs(readme): slim down and highlight improvements over the stock sidebar
- Rewrite the feature list as comparison bullets (editable editor,
  enhanced file tree, Changes / Background Tasks / Side Chat / bottom
  workbench — none of which the stock sidebar has)
- Split the full release history into CHANGELOG.md / CHANGELOG_EN.md;
  READMEs keep only v0.21.1 and link out
- Drop Star History; move the ecosystem section after Community
- Fix stale claims: v0.21.1 is the npm latest stable (not the alpha
  channel); drop the untruthful 'built-in browser' hero badge; pin
  '^0.21.1' in update / source-install notes
- Condense the install prose and the top IMPORTANT block
2026-09-27 11:08:09 +08:00
Menghuan1918 ab2246da47 chore(release): cut v0.21.1 as the stable adapter for DSH 0.1.7-rc.1
The rc.1 adapter first went out as 0.21.0-rc.1, but DSH 0.1.7-rc.1 is
upstream's release batch, so the plugin that targets it must not sit on a
prerelease channel. Re-cut it as v0.21.1: the version is now free of `-`,
so release.yml publishes it under npm's `latest` instead of `alpha`.

Version literals only — package.json, dsh.plugin.json and
SIDEBAR_SERVICE_VERSION (tests/service.spec.ts still pins the last two
together). No code change: the peer floor stays ^0.1.7-rc.1 and the
support line stays "DSH 0.1.7-rc.1 and later".

Docs follow the channel move: README/README_EN/guide drop the "alpha
channel" framing, the install command becomes @latest, and every older
DSH line now gets an explicitly pinned command in the version table
(@0.19.1 and so on) because `latest` no longer covers them. The rc.1
design record keeps its history and gains a §8 for the re-cut.
2026-09-23 23:58:59 +08:00
Menghuan1918 991c5a92e0 docs(readme): give the version table real install commands
The table named a version spec per DSH line; it now carries the command a
reader can copy, one row per DSH generation, pinned to the exact version
(`@0.19.1`, not `@latest`) so a row cannot rot when `latest` moves to a
newer stable cut.

The command form is the one every era of this plugin documented itself —
`dsh plugin --profile web add dsh-better-sidebar@<spec>` — and DSH's CLI
has had `plugin --profile` since 0.1.0-rc.8, so the old rows are accurate
rather than invented.
2026-09-23 23:55:23 +08:00
Menghuan1918 3af8793434 docs(readme): spell out which plugin version each DSH version needs
Adds an explicit DSH-to-plugin table to the Installation section of both
READMEs, because "which version do I install" now has more than one right
answer: 0.21.0-rc.1 targets DSH 0.1.7-rc.1 and later, 0.19.1 is the cut for
0.1.6-alpha.2 and earlier, and the two 0.1.7 alphas have NO published plugin
at all (0.21.0-alpha.1 never reached npm), so those hosts must move DSH to
rc.1 first.

The peer column is included on purpose: it is a range, not an exact pin —
`^0.1.7-rc.1` already admits a later rc.2 or the stable 0.1.7, so upstream
shipping one does not require a new plugin version. Pinning the peer to an
exact 0.1.7-rc.1 would instead be actively harmful: DSH 0.1.7-rc.1's own
boot preflight silently disables any plugin row whose `@deepseek-ai/dsh*`
peers do not satisfy the running host.
2026-09-23 23:38:11 +08:00
Menghuan1918 6805ab51a2 docs: record the 0.1.7-rc.1 adaptation and resync the user docs
New design record `docs/plans/2026-09-23-dsh-0.1.7-rc.1-adaptation.md`
(method, the version-bump-only delta, the code-card break and the mermaid
regression it exposed, the over-yield recovery, the live 3080 upgrade with
its boot-log findings, and the evidence — including the note that the
mount lane first ran against a stale tarball because `e2e_resolve_tarball`
picks the newest existing one instead of packing).

AGENTS.md §3 gains the rc.1 rules: the boot-time peer preflight (a new
§3.4 item 12) with its four gotchas, the vendor hoist lesson, and the
code-card/toolbarLabels contract. Two claims are corrected while we are
here: the guide's four-entry description cap was attributed to rc.1 but
`GuideBody.tsx` and the host's terminal guide entry are byte-identical
across alpha.1 / alpha.2 / rc.1, and the icon surface is 25 named imports
plus a type-only `IconProps`, not 26.

README / README_EN / guide: version, badges, peer floor, the pinned-DSH
advice (`alpha` is now 0.1.7-alpha.2 while rc.1 rides `next`), the reduced
refusal list, and the correction that npm `latest` is 0.1.5-rc.3.
2026-09-23 22:36:05 +08:00
Menghuan1918 6586e3e2d3 feat: adapt to DSH 0.1.7-alpha.1 and yield the read-only previews
DSH 0.1.7-alpha.1 is 1299 commits past 0.1.6-alpha.2 and rewrites four
contracts this plugin was built on. The peer floor moves to
^0.1.7-alpha.1 (semver's prerelease rule means ^0.1.6-alpha.2 can never
match a 0.1.7 prerelease); 0.1.6-alpha.2 and earlier stay on v0.19.1.
Released as 0.21.0-alpha.1 (dist-tag alpha).

Hard breaks:
- dsh-settings was rewritten: register(ns, schema) is gone, a form is
  addressed by the plugin row's Loader entry id and read from the
  module's exported Config. The preferences are merged into Config and
  marked volatile — which requires DSH's own schemastery, because only
  that build wraps a volatile field in the cosmokit reference the
  loader's volatile commit walks. With the public package a settings
  write reports success and revision 1 while the effective value never
  changes.
- ui-primitives renamed its whole icon family (IconXxx14/16 ->
  IconXxxRegular/Medium): 26 imported symbols, 17 files. The failing
  mode is render-time, not load-time. Five call sites that relied on the
  old 14px default now pass size={14} explicitly.
- Session format v4 rejects source.kind === 'plugin'; the side-chat
  boundary injection now writes plugin:dsh-better-sidebar, the same kind
  DSH's own v3->v4 migration produces, so historical threads survive.
  Tool results moved to role 'tool' with top-level content/isError; all
  four parsers accept both shapes.
- The client session snapshot dropped subagentsByParent/jobsBySession
  and the on-demand subagent-catalog observation API. The Tasks page
  reads projectionsBySession and a new jobs.list route.

Yields and convergence:
- The read-only previews go to DSH's documentpreview (Office->PDF, a
  spreadsheet worker, zoom, per-directory refresh); editor.canOpen
  refuses those 26 extensions. Markdown, HTML (with its sandbox
  switches) and the editable code buffer stay.
- The host browser kind is desktop-profile-only now, so the web e2e
  lanes expect no browser entry and assert its absence.
- Link takeover claims only urlTarget links and passes the rest to the
  host, fixing a regression from the 0.1.6 round: the fallback pointed
  at a 'browser' type the plugin no longer registers, so http links in
  its own markdown did nothing.

Also fixed, found along the way:
- The file tree refreshes live (new directory watch over the plugin's
  own socket), since the plugin owns the `files` kind.
- ctx.sessions.list has no `current` field at either tag; the three
  readers were dead. They now use ctx.sidebarRight.mounted.
- package.json.files was missing lib/client-locale.js.
- Two genuinely dead call sites: sessions.openSubagent/open/
  refreshSubagents do not exist on the current baseline, so the
  topology click, the jump-back and the retry were all no-ops.
- The test harness window shim lacked addEventListener, which the 0.1.7
  primitives call at module-evaluation time; and the e2e token exchange
  needs Playwright's request stack, not Node's fetch.
2026-09-22 17:09:08 +08:00
Menghuan1918 de99fd4cfb docs: record the 0.1.6-alpha.2 adaptation and resync the user docs
Adds the per-version adaptation record (docs/plans/2026-09-21-…-adaptation.md),
rewrites AGENTS.md §3 for the new baseline (the two silent contract breaks, the
terminal/browser handoff, the new official plugin-manager surface, the three
ui-primitives breaks, the widened primitives bare-import set), and updates both
READMEs and the integration guide for the v0.20.0 feature set.

Also retires the support text the terminal deletion made false: the install
flow is one step again (no build-script approval), the FAQ's two node-pty rows
collapse into one pointing at DSH's own terminal, the platform note no longer
promises prebuilt native binaries (there are no native deps left), and the
installers drop the -Repair mode and their allowBuilds writes along with
pnpm-workspace.yaml's now-empty allowBuilds block. Removes the dead
browserNoSandboxWarning locale key (its setting went with the plugin's browser)
and tightens theme.spec's capsule guard so a literal colour fails it.

The e2e resolver now refuses a PATH  that is not on the baseline line:
this machine's PATH  is 0.1.6-alpha.1, and running the mount lane against
it fails at 'the bundle was not registered' with a zero exit from the CLI —
a misleading dead end worth one explicit error instead.
2026-09-21 21:00:09 +08:00
Menghuan1918 6317dde7c0 docs(icons): record the host-artwork decision and update the rules that cite it
- docs/plans/2026-09-11-file-icons-and-tab-glyphs.md: the design record —
  what the two stacked PRs did, the measured upstream facts that made their
  colored implementation redundant (rc.2's `FileTypeIcon`/`CodeFileIcon` with
  the host's own palette, the classifier never returning a folder, the native
  tab definition having no icon field while its title slot IS the chip), the
  three merge conflicts and how each was resolved, what was deleted, the
  catch-all semantics change, and the verification evidence.
- docs/plans/2026-09-10-dsh-0.1.5-rc.2-adaptation.md: cross-link it from the
  change table.
- docs/external-plugin-guide.md: the file-icon fallback chain now ends at the
  host's artwork, with the catch-all caveat spelled out; §12 loses its "one
  exemption" paragraph entirely — the plugin draws no color of its own any
  more (file icons are host pixels, tab glyphs ride tokens).
- AGENTS.md §5: replaces the icon-theme exemption with the two new rules
  (file-icon chain + catch-all hazard, and where the colored tab glyphs live
  plus the fact that the native chip glyph is drawn by the plugin inside the
  host's title slot).
- README.md / README_EN.md: the v0.19.1 entry gains the icon section
  (#611 / #531 / #594) with the dataset deletion and the new public API.
2026-09-11 15:32:07 +08:00
Menghuan1918 5451f5c699 fix(ci): raise the global testTimeout and drop --legacy-peer-deps (real-CI feedback)
The first run of this PR against real Windows and real npm found two things
the local macOS pass could not:

1. ci-windows lost a THIRD file to vitest's 5000 ms default —
   `tests/git.spec.ts:85` ("caps status entries at the truncation limit")
   took 9607 ms building a pathological untracked set with real git calls.
   Three different files (git / powershell / agent-pty), one root cause, so
   per-file timeouts were whack-a-mole: vitest.config.ts now sets a global
   `testTimeout: 15_000`. The two heaviest suites keep their own 30 s budgets
   and a genuinely hung case still fails.

2. `--legacy-peer-deps` made the mount lane's CLI install broken instead of
   robust: it skips exactly the peers a global install has to supply, and
   `@deepseek-ai/cordis-plugin-group` — required at boot by
   `@deepseek-ai/dsh-app-boot` — is a peer, not a dependency, so the CLI died
   with ERR_MODULE_NOT_FOUND (`Cannot find package
   '@deepseek-ai/cordis-plugin-group'`) before the smoke could start. The
   flag is removed; the pin to a fully-published rc.2 (no ETARGET) plus the
   4 GB heap (no resolver OOM) is the whole fix.

Verified locally: a plain `npm install -g @deepseek-ai/dsh@0.1.5-rc.2` into a
scratch prefix (with NODE_OPTIONS=--max-old-space-size=4096) resolves the peer
(`dsh/node_modules/@deepseek-ai/cordis-plugin-group` present), that CLI reports
0.1.5-rc.2, and `DSH_CMD` pointed at it runs the mount lane green — 7 passed.
`pnpm test` stays green with the new timeout: 126 files / 1312 passed / 9 skipped.

Docs (plan §C, AGENTS.md §2, both READMEs' v0.19.1 entries) record the rejected
middle step and why, so nobody re-adds it.
2026-09-11 12:10:16 +08:00
Menghuan1918 e567bf6924 docs: record the rc.2 baseline (README badges, guide, AGENTS, plan)
- docs/plans/2026-09-10-dsh-0.1.5-rc.2-adaptation.md: the adaptation plan —
  the upstream rc.1 -> rc.2 delta per affected area, why there is no
  plugin-side code change, and the CI failure taxonomy (A real Windows
  timeouts, B the two silent worker deaths, C the mount lane's npm
  ETARGET/OOM) with the evidence and the fix for each.
- AGENTS.md §2/§3: CI pins rc.2, the mount lane's npm flags and their reason
  (floating transitives + staged prerelease publishing), the Windows lane's
  bounded pool and why, and the primitives-dependencies note extended to rc.2.
- README.md / README_EN.md: support badge (v0.19.1, verified on rc.2), the
  install section's stable-release note (rc.1 hosts need no upgrade — the peer
  floor is unchanged) and a v0.19.1 changelog entry covering the two CI fixes.
- docs/external-plugin-guide.md: baseline line -> v0.19.1 / DSH 0.1.5-rc.1+,
  verified on rc.2.
- Comment-only: `DSH 0.1.5-rc.1` -> `0.1.5-rc.1+` where the note describes a
  behaviour that arrived in rc.1 and is unchanged in rc.2 (native guide
  description rendering, in src/client/native/index.ts, src/client/service.ts
  and the three specs that assert it).
2026-09-11 12:02:44 +08:00
Menghuan1918 bbf953b8a8 docs(readme): declare the native sidebar API adaptation at the top
A GFM IMPORTANT alert under the title states that the right column is
DSH's own sidebar since v0.19.0 (tab types/bodies via ctx.sidebarRightTabs
/ ctx.sidebarRight, file opens via ctx.sidebarRight.openResource, no
self-drawn right panel), and that the bottom workbench plus the
ctx.betterSidebar service are unchanged.
2026-09-10 15:13:36 +08:00
Menghuan1918 191b764154 docs(readme): cite the rc.1 adaptation PR in the changelog 2026-09-10 14:41:40 +08:00
Menghuan1918 725b2f7cec feat(dsh): adapt to DSH 0.1.5-rc.1 and restore the guide description
Baseline moves to DSH 0.1.5-rc.1 — the 0.1.5 line's first release
candidate, and the npm `latest` dist-tag now: peer floor ^0.1.5-rc.1,
devDependency pins, the CI mount-lane pin and dsh.plugin.json engines
all follow. 0.1.5-alpha.2 users stay on v0.19.0-alpha.1.

The upstream delta from alpha.2 is small: 373 changed files, mostly
version bumps, sidebar preview polish and test snapshots. Exactly two
changes touch this plugin, and only one needs work:

- `SidebarRightGuideEntry.description` is back (optional). The native
  guide renders it only while it lists at most 4 entries; a longer list
  drops every description. The plugin restores `TabDescriptor.description`
  and the six built-in `guideDesc*` lines (20 dictionaries) verbatim from
  0b6ac5d^, but deliberately does NOT restore the old generic
  `nativeGuideDesc` fallback: the host has no fallback of its own, so a
  descriptor that declares none now ships no `description` field at all
  and renders as a clean title-only capsule.

  Consequence worth knowing: the plugin contributes six guide entries, so
  the default composition is over the 4-entry limit and shows titles only.
  The mount lane proves the restored field end to end by shrinking the
  enabled set to three types through the plugin's own settings route
  (scratch profile only) and requiring the Files capsule to grow its line.

- The built-in `files` type declares a guide description again and uses a
  coloured folder glyph; the plugin owns that kind, so nothing to do.

Verified unchanged from alpha.2 (so nobody re-checks them): the global
main-panel model, the file address grammar (util/workspace-path changed
only its package.json), the native tab-body host contract (.paneBody is
still a block scroller with a definite height), the core/agent/session/
subagent host APIs and the ui-primitives export surface.

Restore caveat fixed in the lane: the settings route merges patches
key-wise, so undoing a temporary `tabsEnabled` change by posting the
original (empty) map leaves the disabled keys behind — the e2e restores
every key it touched explicitly.
2026-09-10 14:41:16 +08:00
Menghuan1918 0e9b9169eb docs(readme): cite the alpha.2 adaptation PR in the changelog 2026-09-09 23:10:08 +08:00
Menghuan1918 0b6ac5d267 feat(dsh): adapt to DSH 0.1.5-alpha.2
Baseline moves to DSH 0.1.5-alpha.2 only (peer floor ^0.1.5-alpha.2,
CI pin, manifest engines); alpha.1 users stay on v0.19.0-alpha.0.

Host-contract changes handled:
- the native guide entry lost its `description` field (entries are
  icon+title capsules now): `TabDescriptor.description` and the six
  `guideDesc*` keys plus the `nativeGuideDesc` fallback are removed.
- the file address grammar changed: `fileAddressFor` always returns a
  session-scoped address (absolute paths keep their leading `/`),
  `parseFileAddress` is prefix-based and strips `?`/`#`. The plugin's
  purity-gated mirror follows.
- global main panels replaced the `conversation` root slot with the
  keyed `main` slot (`main.conversation`): the bottom workbench's
  center-column locator now accepts both keys and skips
  `display: contents` slot hosts.

Fixes a pre-existing fill bug the alpha.2 probe made obvious: the native
tab body host is a block scroller with a definite height, so tab roots
that only declared `flex: 1` collapsed to content height and the side
chat composer drifted off the pane bottom. The native adapter now wraps
every tab body in a `height: 100%` column flex host.

Also promotes the dependencies `dsh-client-ui-primitives@0.1.5-alpha.2`
dropped from its manifest (anser / shiki / mdast-util-* / micromark-* /
katex / @shikijs/langs) and the newly unmet `dsh-session-persistence`
peer into devDependencies.
2026-09-09 23:09:48 +08:00
Menghuan1918 2d9f90b551 docs: link the phase-3 PR in the v0.19.0-alpha.0 changelog 2026-09-09 15:18:06 +08:00
Menghuan1918 223b2545d9 refactor(shell): retire the plugin's own right panel and free windows
DSH 0.1.5 owns the right column (its native Sidebar hosts every tab type
this plugin registers), so the plugin's own right panel, its width drag /
new-session seed prefs, and the free-window feature are gone. The bottom
workbench is the only plugin-owned surface left, and its expand/collapse
control is registered into DSH's session-header utilities list slot (the
header's corner seat belongs to the native sidebar's own control).

- state: one `bottomSplits` tree; `makeDefaultState()` takes no arguments;
  `toggleBottomPanel` / `openTabInBottomPane` are the only landing
  reducers; `setBottomHeight` and `sanitizeState` share the
  `CONVERSATION_MIN` cap (a persisted tall height no longer snaps on the
  first drag).
- service: every landing in the workbench (creation or focus) expands it;
  `SIDEBAR_FEATURES` drops `'floatWindows'`; the open/close/activate tab
  pools cover the single tree.
- shell: `Sidebar.tsx` renders only the bottom workbench; the toggle lives
  in `sidebar/bottom-toggle.tsx`; layout-push pushes height only (no width,
  no `--dsh-sidebar-width`).
- prefs: `openByDefault` / `defaultWidthPercent` / `changesDiffFloat`
  removed from the schema, defaults, client parser, settings page, and all
  20 dictionaries; the retired keys in stored documents are ignored.
- tests: free-window specs deleted, panel/float assertions dropped,
  remaining suites adapted (124 files / 1287 tests); the mount lane asserts
  the header toggle and sweeps the native sidebar's guide page.
- docs: README / README_EN / guide §0,§11 / AGENTS test map.
2026-09-09 15:18:06 +08:00
Menghuan1918 364a48df98 chore(release): 0.18.1
- package.json / dsh.plugin.json / SIDEBAR_SERVICE_VERSION → 0.18.1(三者锁步由
  tests/service.spec.ts 与 tests/manifest-consistency.spec.ts 断言)
- README / README_EN:新增 v0.18.1 条目并同步三处徽章版本号——自 v0.18.0 起的
  11 个 PR:#499 变更面板预览增强(md 阅读模式 / html·pdf 渲染 / 密钥脱敏)、
  #550 文件树重命名与删除、#535 目录名词典化、#562 侧边对话种子补 fork 标记、
  #569 markdown 本地图片改写、#576 git 折叠上下文按需展开(含 git.show 路由
  rev:path 修正),以及 #524/#526/#527/#534/#536/#540/#541/#542 的内部收敛
- docs/external-plugin-guide.md:当前版本行 → v0.18.1
- DSH 基线不变(peer ^0.1.2-rc.1,CI 钉 0.1.2-rc.1),无运行时行为改动

验证:make check(typecheck → lint → build → test → check:consumer-types)全绿,
124 test files / 1319 passed, 9 skipped
2026-09-08 16:16:16 +08:00
lhh010 6df06717ad feat(changes): PDF render preview for .pdf op targets 2026-09-06 23:06:18 +08:00
lhh010 e356791661 feat(changes): HTML render preview for .html op targets
.html/.htm/.xhtml op previews (read / write / edit, non-error) gain a
Render/Raw toggle in the preview pane head: the render view loads the
SAVED file through the same /sidebar/html route the editor's html viewer
uses, so relative assets (./style.css, img/x.png) resolve inside the
route and a segmented read still renders the whole document (the route
serves the file, not the op snapshot — the file-trace-style srcDoc
approach would render a cut-off document whose scripts never run).

The frame is ALWAYS sandboxed (HTML_IFRAME_SANDBOX, moved to the shared
html-preview.ts module — opaque origin, no allow-same-origin, no
top-navigation) plus the route's CSP sandbox header as
defense-in-depth; unlike the editor viewer this surface has no
no-sandbox escape hatch. The contract is pinned by new sandbox-spec
tests on the extracted HtmlRenderPreview component and the pane toggle
(off by default; absent for non-html and error targets).

Locales: zh/en + all 19 shipped third-language overrides (key-set-equal
gate green). Typecheck + eslint clean; sandbox/redact/diff-rows/frontmatter
suites 36/36 green. The full-suite host-side failures (fs-operations /
pty smoke / git / install-powershell) are pre-existing on the base
branch (verified via stash) and unrelated.
2026-09-06 10:37:53 +08:00
lhh010 16d8df2e93 Merge remote-tracking branch 'origin/main' into feat/changes-md-reading
# Conflicts:
#	src/client/changes/DiffPane.tsx
#	src/client/locales-ar.ts
#	src/client/locales-de.ts
#	src/client/locales-fr.ts
#	src/client/locales-hi.ts
#	src/client/locales-id.ts
#	src/client/locales-it.ts
#	src/client/locales-ja.ts
#	src/client/locales-ko.ts
#	src/client/locales-nl.ts
#	src/client/locales-pl.ts
#	src/client/locales-pt.ts
#	src/client/locales-ru.ts
#	src/client/locales-sv.ts
#	src/client/locales-th.ts
#	src/client/locales-tr.ts
#	src/client/locales-vi.ts
#	src/client/locales-zh-HK.ts
#	src/client/locales-zh-MO.ts
#	src/client/locales-zh-TW.ts
2026-09-04 14:13:34 +08:00
lhh010 a2d3faf7b5 feat(changes): secret redaction layer for op previews
The changes-tab op previews replay read/write/edit payloads into the DOM
(diff rows, read rows, markdown reading mode, error text) — when the model
reads a credentials file, that plaintext must not land on screen or in
inspectable DOM. New display-only redaction layer, on by default with a
one-click pane toggle (persisted in localStorage):

- path layer: credential-shaped filenames (.env / *secret* / *credential* /
  *token* / *api-key* / private keys...) mask whole files line-wise
- content layer: ordinary files mask only secret-shaped spans — secret
  field assignments keep the field name (api_key: [REDACTED]), plus bare
  token prefixes (sk- / AKIA / ghp_ / xox / ya29.), Bearer headers, and
  PEM private-key block headers
- redacted payloads flow through the same viewOp shape into diff rows,
  read rows, markdown reading mode, and error text

Known edge (documented in README): an unquoted mermaid node label
containing a redacted secret breaks the diagram and falls back to source;
workaround is quoting the label. Session data is untouched — this is
display-only and not a boundary against same-context malicious plugins.

Locales: zh/en dictionaries + all 19 shipped third-language overrides
(key-set-equal gate green). 9 new unit tests; typecheck clean; targeted
suites 40/40 green. The fs-operations failure is pre-existing on the base
branch (environment-dependent, verified via stash) and unrelated.
2026-09-04 13:10:21 +08:00
Menghuan1918 98e9a4ff0f docs(readme): 开发与构建命令清单补 pnpm lint(双语镜像) 2026-09-03 20:00:08 +08:00
Menghuan1918 fbfd59bd1b feat: adapt to DSH 0.1.2-rc.1 and bump to v0.18.0 (stable)
Graduate from the alpha track to the stable channel:

- Baseline: CI mount pin, dsh.plugin.json engines floor, and every
  @deepseek-ai/* peer floor / devDependencies pin move to 0.1.2-rc.1
  (published on the `next` dist-tag). alpha.5 -> rc.1 is a pure version
  bump in the harness (all package.json "version" lines, zero source
  delta), so no code adaptation; every host contract was re-verified
  unchanged and the real-host mount smoke passes.
- dsh-client-locale resumed publishing; its trailing-pin exception is
  gone — peers and devDeps align at 0.1.2-rc.1 (pnpm peers check clean).
- Version: fold the unpublished v0.18.1-alpha.0 / v0.19.0-alpha.0 bumps
  into the v0.18.0 stable release; SIDEBAR_SERVICE_VERSION follows
  package.json (asserted by tests/service.spec.ts).
- Docs: README/README_EN badges + channel notes + a full "since v0.17.1"
  changelog entry (the two folded alpha numbers are annotated), AGENTS.md
  §2/§3 baseline wording, external-plugin-guide version line, and the
  e2e-host-protocol header's re-verified list gains 0.1.2-rc.1.
2026-09-03 17:32:04 +08:00
Menghuan1918 35111e163c docs(readme): 双语补 Makefile 用法、聚合挂载回归与一键安装入口
- 开发与构建:补 Makefile 薄封装示例(help/check/mount/clean)与
  pnpm check:consumer-types 的定位说明(浏览器-only 消费者视角)
- 参与贡献:提交前自检补 make check 与 pnpm test:mount:aggregate
- 安装:补方式三一键脚本(bash scripts/install.sh;Windows install.ps1,
  -h 查看参数);README 与 README_EN 同步镜像
2026-09-03 12:07:35 +08:00
Justin Skowyra d6c587e577 fix: avoid forcing mobile drawer on auto-activation 2026-09-02 23:26:04 +08:00
Menghuan1918 a78dd57b23 feat: adapt to DSH 0.1.2-alpha.5 and bump to v0.19.0-alpha.0
- pins: CI mount-gate CLI, dsh.plugin.json engines floor, and the
  @deepseek-ai/* peer floor / devDependencies baseline move to
  0.1.2-alpha.5 (dsh-client-locale trails at 0.1.2-alpha.3 — no such
  release upstream; ^0.1.2-alpha.3 already accepts the alpha.5 runtime)
- code: migrate the alpha.4 Session.events removal to snapshotEvents()
  (sidechat transcript live reads, fork inheritance, jobs.output replay,
  subagent activity) and drop the seedLength meta field the host removed
  from CreateAgentOptions.meta
- gates: pnpm peers check clean, typecheck + 1137 unit tests green,
  real-host mount smoke 14/14 on npm-published 0.1.2-alpha.5
2026-09-02 21:43:34 +08:00
lhh010 2eb9f66ce8 feat(changes): render mermaid fences in the reading mode via the shared lazy chunk
Documents containing mermaid fences now route through the editor preview chunk-resident renderer (splitMermaidBlocks detection + LazyMermaidMarkdown), so diagrams draw with zoom/pan instead of code blocks, while plain documents keep the byte-for-byte single MarkdownText pass. The lazy stub moves to a light mermaid-lazy.tsx module (re-exported from MarkdownHtml.tsx) so the core client bundle imports it without statically pulling DOMPurify/HTML analysis along. Typecheck, 4 affected suites (22 tests), and the full build pass.
2026-09-02 09:14:59 +08:00
lhh010 0142ac550b feat(diff): expand syntax highlighting — mjs/cjs/mts/cts, CSS/SCSS/Less, HTML/XML/SVG/Vue, GraphQL, JSONC/JSON5
Ports dsh-file-trace v0.2.1 highlight coverage into the shared diff engine: JS/TS module suffixes share the js/ts keyword lists; CSS gains its own config (slash-star block comments threaded across lines, hyphenated property words via a wider word charset, 120+ properties/selectors/at-rules); markup files gain markup comments plus common tags/attributes; GraphQL and JSONC/JSON5 map in. Previously css/scss/less had a wrong hash-comment config and html was plain CONFIG_LANG, so both effectively rendered uncolored.
2026-09-01 23:05:26 +08:00
lhh010 b7138cf4fd feat(changes): markdown reading mode for .md op previews
The changes tab preview pane gains a Reading/Raw toggle for .md/.markdown/.mdx session ops (read, write, and edit alike). Reading mode renders the resulting document through the shared MarkdownText pass (the same stack as the editor preview): GFM tables with alignment, task lists, strikethrough, footnotes, math, and code fences, with local image destinations rewritten through the session-scoped /sidebar/file media route (rewriteLocalImageUrls). Content sources: read -> parseReadContent (envelope stripped, blank lines preserved — markdown block structure depends on them, which parseReadLines drops); write -> the written content; edit -> the reconstructed resulting document from the in-window prior content when known, else the new snippet. Ported from dsh-file-trace v0.2.0 (PR #471 lineage), re-based onto the unified changes tab (#475) and the repo shared-renderer conventions (markdownTextProps labels contract, skin tokens, 21-dictionary locale parity).
2026-09-01 18:23:28 +08:00
Menghuan1918 b2722ece5d feat: adapt to DSH 0.1.2-alpha.3 and bump to v0.18.1-alpha.0
Point-by-point audit of all 117 commits between alpha.2 and alpha.3:
every host contract this plugin relies on (token auth, slash RPC,
MarkdownText labels, the event-stream/persistence APIs behind
sidechat.events, SettingsNamespaceInput, SUBAGENT_DESCRIPTOR_VERSION
(still 3), dsh-client-store, the profile loader, the node-pty pin) is
unchanged, so no plugin code needed rewiring. alpha.3's breaking
changes (required BeginSubmissionInput.mode, the renamed
attachment-invalid subagent error, the removed SQLite persistence
backend, the identity-gated projection change feed) do not touch this
plugin.

What did need adapting was the dependency tree: the alpha.3 npm
artifacts ship with workspace-era metadata that does not match their
published code —

- dsh-subagent@0.1.2-alpha.3 imports `admitPromptContent` from
  @deepseek-ai/dsh-attachment without declaring that dependency, so
  resolution floats to a stale 0.1.1-rc.1 copy that lacks the export
  (broke 5 test files at load time);
- six transitive peers (dsh-scope, dsh-session-projection,
  dsh-system-prompt, dsh-user-approval, dsh-util-time, dsh-code-runtime)
  drifted to pre-alpha.3 versions against the ^0.1.2-alpha.3 ranges the
  alpha.3 packages declare;
- the alpha.3 line peers on @deepseek-ai/cordis ^4.0.2 (was ^4.0.1).

Fix: pin the seven stragglers via pnpm-workspace.yaml overrides (with
a note to drop them once upstream fixes its metadata), narrow the
cordis peer to ^4.0.2, and bump the baseline pins — CI mount gate,
dsh.plugin.json engines, peer/devDependencies, README badges, plus
SIDEBAR_SERVICE_VERSION in lockstep.

Verified on the npm-published @deepseek-ai/dsh@0.1.2-alpha.3:
typecheck clean, 107 test files / 1137 tests green, `pnpm peers check`
reports zero unmet peers, and the real-host mount smoke passes 14/14.
2026-09-01 15:02:28 +08:00
Menghuan1918 24a3813c63 feat!: 合并 Git 面板与文件追踪为统一「文件变动」tab(双视角 + 统一 diff 栈)
在 PR #471(file-trace)基础上的演进:

- 合并 tab:git tab(id 保留,兼容持久化布局)升级为「文件变动」双视角
  tab——Git 视角(原 GitView 全部能力:staged/unstaged/提交/历史/worktree·
  子仓库选择/右键菜单/确认弹窗)+ 本轮文件视角(原 file-trace:会话事件
  日志实时折叠的模型读写编辑记录,按文件分组、新增类型筛选 chips、相对
  时间);file-trace tab 移除(未随任何版本发布)。
- 统一 diff 组件:新 src/client/diff/ 模块(rows.ts 引擎 + DiffRows/
  DiffFiles 渲染器 + highlight.ts 语法着色)——git diff 与会话操作 diff
  共用一套渲染:mod 改写配对(del-run/add-run 对半标蓝)、行内字符级
  高亮(修复了旧实现旧侧失配不高亮的问题,改为行对象身份键)、上下文
  hunk 折叠、git hunk 间未输出区间按行号范围生成不可展开折叠、语法着色
  色相落位 diff 三色空档、+n −m 统计 chips、行底色 tint;DiffTab 改用
  该栈(git diff tab 从此也有高亮)。
- 交互:两视角共用底部可拖拽预览面板(点击文件/提交/操作即预览,不再
  直接开 diff tab;面板可刷新、可键盘/拖拽调高、git 目标可一键展开为
  独立 diff tab);视角选择与面板高度持久化在 tab.meta;git 行 XY 徽章
  按状态字母着色;选中行高亮。
- i18n:fileTrace* 十键重命名为 changes* 前缀,git 键值更新为「文件
  变动」,新增 7 键(视角/筛选/面板操作),全部 21 个词典同步。
- 结构:src/client/changes/(ChangesTab/GitLens/SessionLens/DiffPane/
  ops)+ src/client/diff/;GitView/DiffView/filetrace/ 删除;git 样式
  从 sidebar.module.css 迁至 changes.module.css。
- 测试:builtins 8→7(git tab 承接 badge pin)、diff-rows(unified
  转换/mod 配对/间隙折叠/统计)、changes-tab(壳交互 jsdom)、
  diff-files-collapse(原 DiffView 折叠行为钉住)、changes-ops(原
  filetrace 数据层)、git-view-worktree 迁移至 GitLens;全量 1122 通过。
- 文档:README ×2 功能矩阵合并、external-plugin-guide §4.4 与内置清单
  7 tab、mount e2e 菜单标题同步。
2026-08-31 01:31:22 +08:00
lhh010 9255040489 Merge origin/main into feat/file-trace-tab: resolve external-plugin-guide version line (keep 8-tab count, adopt v0.18.0-alpha.0 alpha-track wording) 2026-08-31 00:21:10 +08:00
Menghuan1918 07eebbbad0 feat!: move to the alpha track — DSH 0.1.2-alpha.x only (v0.18.0-alpha.0)
DSH itself is still on its 0.1.2-alpha line (npm `alpha` dist-tag), so the
plugin mirrors it: v0.18.0-alpha.0 publishes under the npm `alpha`
dist-tag and supports DSH 0.1.2-alpha.x only. Stable-DSH (0.1.0-rc.8 ~
0.1.1-rc.2) users stay on v0.17.1 (npm `latest`). Verified end-to-end
against a real 0.1.2-alpha.2 host: full vitest suite, typecheck,
build/pack, consumer type surface, and the headless mount smoke 14/14
(the prerelease version also passes `dsh plugin add file:`).

- peer floor raised `^0.1.0-rc.8` -> `^0.1.2-alpha.2` (the mount install
  no longer warns: the old floor could not semver-match a prerelease
  host); dsh.plugin.json engines.dsh `>=0.1.2-alpha.2`.
- Dropped the pre-alpha compatibility layer:
  - e2e host RPC collapsed from the dot/slash dual dialect to slash-only
    (rpcAttempt; the 404-probe negotiation and its cache are gone), and
    parseLaunchUrl now requires the ?token= launch URL;
  - MarkdownText labels collapsed to the nested single shape (the cast
    became unnecessary against the alpha.2 declarations);
  - the defunct `@deepseek-ai/dsh-client-runtime` row is gone from the
    chunk externals allowlist (chunk-loader / tsdown / two specs) and
    from dsh.client.inject.
- market-manifest guard now allows an exact prerelease version (alpha
  cuts are not the market's verified `latest` target); release.yml picks
  the npm dist-tag from the version (prerelease -> `alpha`, else
  `latest`) so an alpha can never hijack `latest`.
- Docs retargeted: AGENTS.md §2/§3, README/README_EN badges + v0.18.0
  -alpha.0 section + install note (`dsh-better-sidebar@alpha`), guide.
2026-08-30 23:42:16 +08:00
Menghuan1918 f9e00bb0d0 feat: adapt to DSH 0.1.2-alpha.2 (npm-published) and bump to v0.17.2
DSH 0.1.2-alpha.2 is on npm under the `alpha` dist-tag, so the CI mount
pin and the @deepseek-ai/* devDependencies baseline move up from
0.1.1-rc.1/rc.2 (the dead dsh-client-runtime devDep goes away with
them). Verified end-to-end against a real 0.1.2-alpha.2 host: full
vitest suite (1106), typecheck, build/pack, consumer type surface, and
the headless mount smoke 14/14 — the token URL, slash RPC and
MarkdownText labels contracts are unchanged from alpha.1.

- dsh-settings dropped the runtime `settingsNamespace` export:
  namespaces are validated at compile time (SettingsNamespaceInput), so
  the host passes the 'dsh-better-sidebar' constant directly and the
  fake settings service in smoke.spec casts to the branded type.
- dsh-subagent bumped SUBAGENT_DESCRIPTOR_VERSION 2 -> 3: the version is
  stamped by the host package; the sidechat seed assertion now follows
  the constant instead of pinning a literal.
- Restored SessionEvent.ignorable and the RemoteError wrapping were
  verified to have no impact on this plugin.
- e2e scratch profiles (e2e-mount.sh / e2e-aggregate-mount.sh) add
  '@deepseek-ai/*' to minimumReleaseAgeExclude (mirroring the repo
  root): alpha releases are often <24h old when the lane runs, which
  pnpm 11's default minimumReleaseAge would refuse to install.
- vitest excludes .worktrees/** — local task worktrees carried stale
  code against the shared node_modules and broke on the devDeps bump.
- Version lockstep 0.17.2 (package.json, dsh.plugin.json,
  SIDEBAR_SERVICE_VERSION, README/AGENTS/guide docs).
2026-08-30 22:38:09 +08:00
lhh010 02d3936b92 feat: 新增第 8 个内置 tab「文件追踪」——移植 dsh-file-trace 插件
- 数据层:直接折叠会话事件日志(tool/call + tool/result 对)提取文件操作,
  与仓库「读事件日志而非动注册表」的取向一致;含错误文本捕获与
  running 态实时更新(ctx.on('session/event'),不可见时暂停、恢复时追平)
- 视图:操作列表 + 底部可拖拽 diff 面板;行级 diff(删红/增绿/改蓝)+
  行内字符级高亮;读取视图带真实行号;失败操作统一展示真实错误文本
- 语法着色:轻量分词器(关键字/字符串/数字/类型/函数/注释/预处理),
  色相经 color-mix 落在 diff 三色之间的空档;跨行块注释状态按行序推导
- 单实例 tab,+ 菜单 order 55,角标显示操作数;设置页可整体关闭
  (与独立维护的 dsh-file-trace 插件共存)
- i18n:10 个新 key 同步全部 21 个词典;builtins 测试 7→8;
  README/指南内置清单同步
2026-08-30 20:59:50 +08:00
chenwei ffe68ae9f8 List dsh-better-overleaf and dsh-quicklook in the ecosystem tables (en) 2026-08-29 17:09:13 +08:00
Menghuan1918 50e05ecea0 docs(agents): slim AGENTS.md to repo-global rules, single-source the API reference
AGENTS.md (546 -> 63 lines) now carries only project-global development
rules: hard constraints, mount-smoke CI, DSH 0.1.2-alpha.1 adaptation
notes, npm release, a quick-rule list, and a docs/tests map. The
consumer plugin API reference lives solely in
docs/external-plugin-guide.md.

Reference sync:
- README/README_EN: collapse the dual 'full integration docs' links to
  the guide; AGENTS.md stays linked as the repo rules
- shell-presets.ts / mount.e2e.ts comments: skinning contract pointer
  moved from AGENTS.md §8 to guide §12
2026-08-28 21:42:39 +08:00
Menghuan1918 6cfe7a736f feat: adapt to DSH 0.1.2-alpha.1 (Remote gateway + token auth + MarkdownText labels)
Dual-version compatibility: the plugin now works identically on
0.1.0-rc.8 ~ 0.1.1-rc.2 and 0.1.2-alpha.1 (the latter verified against a
source build of the dsh-v0.1.2-alpha.1 tag: mount smoke 14/14 + aggregate
double-mount; 0.1.1-rc.2 re-verified 14/14).

- MarkdownText: alpha.1 renamed the flat optional `codeLabels` prop to a
  required nested `labels: { code: {copyLabel, copiedLabel}, footnotes }`;
  the old prop alone crashes fence rendering with "reading 'code'". All
  four render sites (mermaid / MarkdownHtml / TextEditor / SideChatView)
  now go through src/client/markdown-labels.tsx (dual-shape object passed
  under both prop names).
- e2e mount lanes speak both host dialects (tests/e2e/host-protocol.ts +
  host.ts, unit-locked by tests/e2e-host-protocol.spec.ts):
  - one-time-token browser auth: the launch URL grep extends past the
    `/?token=` query (truncating at `/` loses the token), goto navigates
    the token URL (browser cookie exchange), and stamped navigations
    pre-seed the context cookie via addCookies — the exchange 303 drops
    sibling query params;
  - Remote gateway: dot endpoints first, slash endpoints on 404 fallback,
    with args keyed by the controller parameter name (workspace/create ->
    {request}, session/list -> {_request}; verified on a live host).
- package.json: drop the @deepseek-ai/dsh-client-runtime peer (package
  removed upstream in alpha.1; zero references in the source — the chunk
  externals entry stays and is resolution-tolerant).
- scripts/e2e-mount.sh: fix a latent set -u crash in the npx fallback
  branch ($DSH_CMD followed by a full-width comma parsed as part of the
  variable name).
- CI pin stays at @deepseek-ai/dsh@0.1.1-rc.2 until alpha.1 publishes to
  npm (comment updated); README/AGENTS document the new contracts.
- Version lockstep bumped to 0.17.1.
2026-08-28 04:20:36 +08:00