@young1lin/dsh-ui-gitworkbench 0.1.13 → 0.1.15

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 CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  本文件记录面向使用者的变更。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循语义化版本。
4
4
 
5
+ ## [0.1.15] - 2026-08-31
6
+
7
+ ### 修复
8
+
9
+ - **workspace 打开的是仓库子目录时,变更页的每个文件都能打开了。** 此前树是对的、点开全空白:抽屉里的路径全部来自 `git status` / `git diff --numstat`,它们无论在哪个目录运行,输出的都是仓库根相对路径;而 diff 的 pathspec、`:path`、blame、`hash-object`、`ls-tree` 清单和宿主侧的文件读取,全部相对命令的运行目录解析——两种「相对」只在仓库根重合。git 根在 `C:/mattermost/`、workspace 开在 `C:/mattermost/server` 时,`diff HEAD -- server/main.go` 在 `server/` 下运行会去找 `server/server/main.go`,匹配不到并以 exit 0 返回空输出;勾选暂存报 pathspec 不匹配,blame 直接失败,历史按路径过滤永远为空,路径选择器给出的树也缺着前缀。现在每个带路径的 RPC 先解析一次仓库根(`rev-parse --show-toplevel`,不在仓库里则原样回落、让调用方自己的 git 错误照旧冒出来),git 与文件读全部在根上进行;`stats` 的轮询把这次解析并进已有的并行批次,墙钟时间不变。实测(git for Windows,git 根与打开的 workspace 分处两级的 fixture):同一条 diff 在根 11 行、在子目录 0 行,修复后所有视图都从根读取。
10
+ - **peer 依赖范围跟上了当前 dsh 版本线。** 四个 `@deepseek-ai/*` peer 从 `^0.1.0-rc.2` 提到 `^0.1.1-rc.2`(当前发布并在跑的线)。带预发布号的 semver range 只匹配同 `主.次.补丁` 三元组的预发布版本,所以旧范围对 `0.1.1-rc.2` 实际是「不满足」——peer 在场时的兼容性检查会误报。`cordis` 的 `^4.0.1-rc.1` 已覆盖稳定版 `4.0.1`,不动。
11
+
12
+ ## [0.1.14] - 2026-08-31
13
+
14
+ ### 修复
15
+
16
+ - **回车在 diff 里画出来了。** CRLF 文件在 CHANGES 点开,是一整面红绿行而两侧文本看上去一模一样——文件没有被过滤(树逐字来自 `git status`),是 diff 行文本原样携带的回车字节浏览器一个像素都不画,只改行尾的变更于是「整文件都变了却看不出改了什么」。现在每个回车在渲染时画成 `␍`(U+240D,回车控制字符的标准图形,git 里 `^M` 想说的同一件事):CHANGES 的分栏视图在每个回车处标出;History / Compare 的 unified 视图标在行尾——词级高亮是行内字符偏移,行中插字形会把它们推偏。行里没有回车就只多付一次 `includes`,纯 LF 文件渲染与之前一致。编辑器对 CRLF 的拒绝不变(编辑框会把行尾统一成 LF,任何一次保存都会重写整个文件),但两条拒绝提示(CHANGES 与 Files)现在都直接建议把行尾统一成 LF。
17
+
5
18
  ## [0.1.13] - 2026-08-25
6
19
 
7
20
  ### 新增
package/CHANGELOG_EN.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  User-facing changes, newest first. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows SemVer.
4
4
 
5
+ ## [0.1.15] - 2026-08-31
6
+
7
+ ### Fixed
8
+
9
+ - **Every file opens from the Changes tab when the workspace is a subdirectory of the repository.** The tree was right and the pane was blank: the drawer's paths all come from `git status` / `git diff --numstat`, which print repository-relative paths wherever they run, while diff pathspecs, `:path` revisions, blame, `hash-object`, `ls-tree` listings and the host's own file reads all resolve against the directory the command runs in — and the two notions of "relative" agree only at the root. With the git root at `C:/mattermost/` and the workspace opened at `C:/mattermost/server`, `diff HEAD -- server/main.go` run from `server/` looked for `server/server/main.go`, matched nothing, and came back exit 0 with empty output; the stage tick died on "pathspec did not match", blame went fatal, a path-filtered history came back empty, and the path picker's tree lost its prefix. Every path-carrying RPC now resolves the repository root once (`rev-parse --show-toplevel`, falling back to the directory itself outside a repository so the caller's own git error still surfaces) and runs git and file reads there; the polled `stats` folds the resolve into its existing parallel batch, so its wall time is unchanged. Measured on git for Windows with a fixture whose git root and opened workspace sit two levels apart: the same diff was 11 lines from the root and 0 from the subdirectory, and every view now reads through the root.
10
+ - **The peer dependency ranges catch up with the current dsh line.** The four `@deepseek-ai/*` peers move from `^0.1.0-rc.2` to `^0.1.1-rc.2` — the line currently published and running. A semver range with a prerelease only matches prereleases of the same `major.minor.patch` tuple, so the old range actually FAILED against `0.1.1-rc.2`, making the compatibility check that runs when a peer is present report a mismatch. `cordis` stays at `^4.0.1-rc.1`, which already covers the stable `4.0.1`.
11
+
12
+ ## [0.1.14] - 2026-08-31
13
+
14
+ ### Fixed
15
+
16
+ - **The carriage return is drawn now.** Opening a CRLF file in CHANGES showed a wall of changed lines whose two sides looked byte-identical — nothing filtered the file (the tree lists `git status` verbatim), but the CR byte the diff text carries through verbatim gets zero pixels from a browser, so an endings-only rewrite read as "everything changed and nothing shows what". Every carriage return now renders as `␍` (U+240D, the standard picture of the control character — what git's `^M` means to say): the CHANGES side-by-side pane marks each one, and History/Compare's unified view marks the line's end, because word-level highlights are char offsets into the row text that a mid-line glyph would shift. A line without a CR pays one extra `includes` and renders exactly as before. The editor still declines to arm on CRLF (the edit box would normalise the endings, and any save would rewrite the whole file), but both refusal notices — CHANGES and Files — now recommend normalising the file to LF.
17
+
5
18
  ## [0.1.13] - 2026-08-25
6
19
 
7
20
  ### Added
package/README.md CHANGED
@@ -431,6 +431,57 @@ gutter 一变不透明就把它埋了。二是探针查不了这件事:`elemen
431
431
  box-shadow 的命中测试,行号左边那个点照样报 `.cm-line`,只能截图看像素,或者直接
432
432
  读 `getComputedStyle(...).boxShadow`。`scripts/verify_gutter.py` 走的是后者。
433
433
 
434
+ ### 6.21 探针「什么都没测到」的三种样子,都不长得像失败
435
+
436
+ 探针最贵的失败不是断言变红,是它根本没走到要测的那一步,然后一路 PASS 或者报一个
437
+ 和真实原因无关的超时。三条都是在实机上撞出来的:
438
+
439
+ **一、会话列表默认是折叠的。** 侧边栏按 workspace 分组,全新的无头上下文拿到的
440
+ `dsh.workspace.view.v5` 里 `groupExpansion` 是空对象——每个组都收着,会话行**根本不在
441
+ DOM 里**。`page.get_by_text('会话标题')` 于是永远找不到,再怎么等也没用。要先把
442
+ `[class*="projectRow"][aria-expanded="false"]` 一个个点开。这条会伪装成
443
+ `Locator.click: Timeout 30000ms exceeded` 卡在 `cardBranch` 上,看起来像抽屉没渲染。
444
+
445
+ **二、Changes 侧不点「编辑」就没有编辑器。** 未武装时 diff 右列渲染的是 `<span>`
446
+ (`DiffViews.tsx`),CodeMirror 只在 `layer === 'unstaged' && edit.armed` 时挂载。
447
+ 探针点开一个改动文件就去找 `.cm-gutters`,找不到是**对的**——但如果把这种情况写成
448
+ `SKIP`,那一整段就永远不会被验,而它看起来一直是绿的。要么点「编辑」把它武装起来,
449
+ 要么把「未武装时不该有编辑器」写成一条真断言。
450
+
451
+ **三、挑文件别用 `.first`。** fixture-01 的第一个改动文件是 PNG,二进制文件走的是
452
+ 「无文本差异」分支:没有分栏、没有「编辑」按钮、没有编辑器。用 `.first` 拿到它,
453
+ 报出来的是「分栏视图没有编辑按钮」——一个从来不存在的 bug。按扩展名挑一个文本文件。
454
+
455
+ 还有一条量级的:**把窗格「拖窄到一定要横向滚动」不能写死像素**。`320px` 在 Files 侧
456
+ 够窄,在 Changes 右列比最长的行还宽,于是 `scrollLeft` 停在 0,那一段测的是「没滚动
457
+ 所以没有重叠」——不是「没有 bug」。按 gutter 自身宽度加一条缝算目标宽度,再
458
+ `scrollLeft = scrollWidth` 滚到底,重叠就一定发生在最坏处。
459
+
460
+ ### 6.22 workspace 打开的是仓库子目录时,Changes 列得出文件、点开全是空白
461
+
462
+ git 的两种「路径」只在仓库根相等:`git status --porcelain` 和 `git diff --numstat`
463
+ 无论在哪个目录运行,输出的都是**仓库根相对**路径(抽屉里的 `path` 全部来自这里);
464
+ 而 pathspec、`:path` 版本语法、`hash-object` 的文件参数、`ls-tree` 的清单,全部相对
465
+ **当前运行目录**解析。会话打开的就是仓库根时两者天然一致;一旦 workspace 打开的是
466
+ 子目录(如 git 根在 `C:/mattermost/`、workspace 开在 `C:/mattermost/server`),抽屉就
467
+ 成了「树是对的,其余全空」:`diff HEAD -- server/main.go` 在 `server/` 下运行会去找
468
+ `server/server/main.go`,匹配不到,**exit 0、空输出**——点开改动文件一片空白,任何错
469
+ 都不报;勾选暂存报 `pathspec did not match`;blame 直接 fatal;`ls-tree` 从子目录吐出
470
+ **剥掉前缀**的清单,路径选择器给历史过滤喂的 pathspec 从此永远匹配不到;宿主侧
471
+ `join(cwd, path)` 读未跟踪文件同样拼出双前缀路径(实测 git for Windows:同一条
472
+ `diff HEAD -- server/main.go`,在根 11 行,在 `server/` 0 行)。
473
+
474
+ 修法:所有带路径的 RPC 先解析一次仓库根(`rev-parse --show-toplevel`,纯模块
475
+ `src/repo-root.ts` 的 `rootedDir`;不在仓库里则回落原目录,让调用方自己的 git 失败
476
+ 照旧冒出来),git 与文件读全部在根上做。`stats` 是轮询的,这次解析并进它已有的
477
+ 并行批次,墙钟零增加(status/numstat/rev-parse 本就 cwd 无关,仍跑在会话目录);
478
+ `commitStats` 把解析放在缓存探测之后,命中不多花 spawn。刻意**不缓存**解析结果:
479
+ 会话中途在子目录里 `git init`,下一次轮询就该认到新根。守卫两条:
480
+ `tests/repo-root.git.test.ts` 把 git 侧行为逐条钉死(子目录下 pathspec 匹配不到、
481
+ `ls-tree` 剥前缀、`hash-object` 双前缀报错——git 哪天改了行为它会先叫);
482
+ `tests/host-rooted-paths.test.ts` 源码扫描钉布线(先剥注释;断言带 path 的 @Remote
483
+ 恰好十个、每个方法体内必须出现 `rootedDirOf`;已做变异测试,改掉一个方法它会点名)。
484
+
434
485
  ---
435
486
 
436
487
  ## 7. dsh 仓库里的关键参考文件(去哪里抄)