Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.i18n.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# git hash-object CHANGELOG.md CHANGELOG.zh.md
CHANGELOG.md: 3dc51086634341c4337b7eaf7ad25550f41a662a
CHANGELOG.zh.md: 8e209ab5efbc6f893b9c1008701a61030970a7fd
CHANGELOG.md: 6eac2e89ff3ca4054339b9041cfc7375938262ad
CHANGELOG.zh.md: 6da7452dc645ffc427aa7aebd3195e666acba123
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Compatibility release extending the exact DSH support list to `0.2.0-rc.2`, with

### Changed

- Git file comparisons now use the official DSH `DiffBlock` instead of the plugin-owned line renderer and styles. The plugin retains Git fetching and sidebar addresses, supports the existing DSH matrix, and distinguishes binary, metadata-only, empty, incomplete, and end-of-file newline changes. Copying and folding are provided by DSH; newer hosts also provide line wrapping.

- The exact DSH compatibility matrix now includes `0.2.0-rc.1` and `0.2.0-rc.2`. Development dependencies and the committed lockfile pin `0.2.0-rc.2` (Cordis `4.0.4`, schemastery `3.18.4`). Existing structure probes in `src/compat/` still cover settings, schema, and icons. Lane-only packages that this pin publishes (`dsh-util-code-language`, `dsh-client-shortcuts`) are development dependencies only; they stay out of the peer OR.

### Fixed
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

### Changed

- Git 文件比较改为复用官方 DSH `DiffBlock`,删除插件自写的逐行渲染器与样式。插件保留 Git 取数和侧栏地址,继续支持现有 DSH 矩阵,并区分二进制、仅元数据、空 patch、不完整输出及末尾换行变化。复制和折叠由 DSH 提供,新宿主还提供换行控件。

- 精确 DSH 兼容矩阵加入 `0.2.0-rc.1` 与 `0.2.0-rc.2`。开发依赖与提交锁文件 pin 在 `0.2.0-rc.2`(Cordis `4.0.4`、schemastery `3.18.4`)。`src/compat/` 里已有的设置、schema 与图标结构探测继续覆盖这两个版本。该 pin 发布的车道专用包(`dsh-util-code-language`、`dsh-client-shortcuts`)只作为开发依赖,不进入 peer OR。

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions README.i18n.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# git hash-object README.md README.zh.md
README.md: 0ac474cf11ac7921db78f5333269f14f23e6f940
README.zh.md: 3ae0617935f776950ee3c298275f0eae95888385
README.md: 92e4b2be3a7e362fd4d34d60e144ddd0890de766
README.zh.md: 58520684bb27c80f31bf5f5751a9d939f268c488
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Repository controls (refresh / reveal) render inside each Git frame through a lo

In the conversation composer, Git contributes a branch selector and a changed-files indicator on the left of the input area. Clicking either control opens `git.changes` as a right-sidebar tab. Creating a branch opens a shared conversation Modal; after `git init` with no commits (unborn HEAD), the menu shows the symbolic default branch as disabled, explains that the first commit is required, and disables create until HEAD exists.

The **Changes** surface shows the current branch beside refresh, then a single-line auto-growing commit message field with a wand **Generate** control and a split **Commit** button (Commit, Amend, Commit & Push, Commit & Sync). Staged, unstaged, and untracked paths follow as icon-action sections: plus or minus toggles the index, undo discards after a two-step confirm, and a porcelain letter badges the row. Clicking a path opens the matching diff. The **Diff** surface shows refresh in the top-right and renders one file's working-tree or staged diff per tab. The **Graph** surface shows Auto / All / First parent beside refresh, then the commit history as a canvas-drawn lane graph — one continuous coordinate space, so rails and merge edges never break at row boundaries — with subject, author, date, hash, and HEAD/branch/tag decoration badges, paged incrementally with a load-more control. When the host exposes an LLM runtime, a staged diff is sent to the session model — or to a custom provider/model from plugin configuration — and the streamed suggestion is written into the editable input. That same configuration page also edits the generation system message. Hosts through `0.1.6-alpha.1` show it under **Settings → Plugins → Plugin configuration**; from `0.1.6-alpha.2` it opens on that bundle's detail page in plugin management. Generation never stages, commits, or pushes anything. On Electron, optional Desktop enhancement adds reveal-in-folder and open-path actions when the Desktop provider is present.
The **Changes** surface shows the current branch beside refresh, then a single-line auto-growing commit message field with a wand **Generate** control and a split **Commit** button (Commit, Amend, Commit & Push, Commit & Sync). Staged, unstaged, and untracked paths follow as icon-action sections: plus or minus toggles the index, undo discards after a two-step confirm, and a porcelain letter badges the row. Clicking a path opens the matching diff. The **Diff** adapter shows refresh in the top-right and supplies one file's working-tree or staged comparison to the official DSH `DiffBlock`, which owns copying, folding, and line wrapping where supported. Git patch conversion and non-text states are described in the [architecture overview](docs/architecture/overview.md); the original resource addresses remain restorable. The **Graph** surface shows Auto / All / First parent beside refresh, then the commit history as a canvas-drawn lane graph — one continuous coordinate space, so rails and merge edges never break at row boundaries — with subject, author, date, hash, and HEAD/branch/tag decoration badges, paged incrementally with a load-more control. When the host exposes an LLM runtime, a staged diff is sent to the session model — or to a custom provider/model from plugin configuration — and the streamed suggestion is written into the editable input. That same configuration page also edits the generation system message. Hosts through `0.1.6-alpha.1` show it under **Settings → Plugins → Plugin configuration**; from `0.1.6-alpha.2` it opens on that bundle's detail page in plugin management. Generation never stages, commits, or pushes anything. On Electron, optional Desktop enhancement adds reveal-in-folder and open-path actions when the Desktop provider is present.

<a id="composition"></a>
## Composition
Expand Down
2 changes: 1 addition & 1 deletion README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ declare module '@deepseek-ai/dsh-client-ui-sidebar-right/client' {

在会话输入区左侧,Git 贡献 branch selector 与 changed-files indicator。点击任一控件会在右侧边栏打开 `git.changes` 标签页。创建分支会打开共享的 conversation Modal;在仅有 `git init`、尚无提交(unborn HEAD)时,菜单以禁用态展示符号默认分支,说明需要先完成首次提交,并在 HEAD 存在前禁用创建。

**Changes** surface 顶部展示当前 branch 与 refresh,其下是默认一行、随内容增高的 commit message 输入框,带魔法棒 **Generate** 控件,以及分裂式 **Commit** 按钮(Commit、Amend、Commit & Push、Commit & Sync)。Staged、unstaged 与 untracked 路径以图标操作分区列出:plus/minus 切换 index,undo 在两步确认后 discard,porcelain 字母标记行状态。点击路径打开对应 diff。**Diff** surface 在右上角展示 refresh,并在每个标签页渲染一个文件的 working-tree 或 staged diff。**Graph** surface 顶部在同一行展示自动/全部/首父链与 refresh,其下以 canvas 绘制的 lane graph 展示提交历史——整页共享一个连续坐标系,rail 与 merge 边不会在行边界断裂——包含 subject、author、date、hash 与 HEAD/branch/tag 装饰徽标,并通过 load-more 控件增量分页。当 host 暴露 LLM runtime 时,staged diff 会发送到会话模型——或发送到插件配置里的自定义 provider/model——流式生成的建议写入可编辑输入框。同一张配置页也可以编辑生成所用的 system message。`0.1.6-alpha.1` 及更早在 **设置 → 插件 → 插件配置**;自 `0.1.6-alpha.2` 起在插件管理页该组合包的详情页。生成绝不 stage、commit 或 push 任何内容。在 Electron 上,optional Desktop enhancement 在 Desktop provider 存在时提供 reveal-in-folder 与 open-path 操作。
**Changes** surface 顶部展示当前 branch 与 refresh,其下是默认一行、随内容增高的 commit message 输入框,带魔法棒 **Generate** 控件,以及分裂式 **Commit** 按钮(Commit、Amend、Commit & Push、Commit & Sync)。Staged、unstaged 与 untracked 路径以图标操作分区列出:plus/minus 切换 index,undo 在两步确认后 discard,porcelain 字母标记行状态。点击路径打开对应 diff。**Diff** 适配层在右上角展示 refresh,将单文件的 working-tree 或 staged 比较交给官方 DSH `DiffBlock`;复制、折叠以及支持版本上的换行由官方组件负责。Git patch 转换与非文本状态见[架构总览](docs/architecture/overview.md),原有资源地址仍可恢复。**Graph** surface 顶部在同一行展示自动/全部/首父链与 refresh,其下以 canvas 绘制的 lane graph 展示提交历史——整页共享一个连续坐标系,rail 与 merge 边不会在行边界断裂——包含 subject、author、date、hash 与 HEAD/branch/tag 装饰徽标,并通过 load-more 控件增量分页。当 host 暴露 LLM runtime 时,staged diff 会发送到会话模型——或发送到插件配置里的自定义 provider/model——流式生成的建议写入可编辑输入框。同一张配置页也可以编辑生成所用的 system message。`0.1.6-alpha.1` 及更早在 **设置 → 插件 → 插件配置**;自 `0.1.6-alpha.2` 起在插件管理页该组合包的详情页。生成绝不 stage、commit 或 push 任何内容。在 Electron 上,optional Desktop enhancement 在 Desktop provider 存在时提供 reveal-in-folder 与 open-path 操作。

<a id="composition"></a>
## 组合
Expand Down
1 change: 1 addition & 0 deletions docs/architecture/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
- **RPC**:DSH Web 宿主存在时,Connection 子 fiber 注册 loopback `/git` 通道;过期输出(stale mutation)被丢弃,文件名按字面 pathspec 处理。
- **Client 刷新合并**:`GitClientController.refresh()` 对同一工作区复用在途刷新(复用键为 `path` + `operationGeneration`,只有同 `generation` 才复用;轮次结束在 `finally` 中释放槽位)。复用只在该轮尚未发出 `status` 读取时成立;请求在该轮读取之后到达时,该轮记一次 trailing 读取,合并进来的调用方 await 到这轮 trailing 读取落地,共享轮次失败(瞬时错误)也不例外——请求的依据是「读取已发出」,与那轮成败无关。一个 burst 最多两轮往返(trailing 不再递归链接,避免控制器自身的 Host 流量——Windows 下每条 git 命令弹出的控制台窗口带来的焦点事件——自激成永久循环)。composer 控件的 `window` focus 监听因此不会在焦点抖动时叠加多轮 discover/status,也不会让重叠轮次互相判旧。背景见 [troubleshooting](../troubleshooting/windows-desktop-console-flood.md)。
- **右侧边栏集成**:Client manifest 以 `inject` 声明运行时依赖 `ctx.sidebarRight` / `ctx.sidebarRightTabs`;对 sidebar 包只有 `import type`(动态 plugin 不得 import 其他包的运行时值),bundle 中类型被擦除,故无 `external`。阶段一向 `ctx.sidebarRightTabs.register` 注册三个 tab type(changes/graph 是 page type,diff 是 resource type,pattern `dsh-resource://git/diff/**`);阶段二把 body 注入 `sidebar.right.pane.tab` 座(key 为 definition id)。导航统一走 `ctx.sidebarRight.openTab(kind)` 与 `openResource(address, { params })`:changes/graph 由侧栏按 kind 每 pane 去重,diff 以精确地址为 tab 身份,重复打开 reveal 既有 tab 并递增 `navigation.revision`;参数类型通过 `SidebarRightResourceParamsMap` 模块扩充。tab 栏、guide 页、停靠几何与面板宽度由右侧边栏(基于 ui-dockkit)拥有。Diff 结果是面板局部的:controller 只提供无状态的 `fetchDiff`,每个 Diff surface 持有自己的在途请求与结果(按仓库根 + tab 地址为键,乱序完成互相不可见),故分屏、浮动窗口与同文件的 staged/worktree 两个 tab 永不互串正文。changes/graph 另在 `sidebar.right.pane.tab.title` 座注册 live title(diff chip 是语言无关的文件名,不注册),已打开的 chip 随语言切换更新,而非冻结在打开时刻的文本。provider 卸载只移除 tab type 注册,保留 tab 记录:上游 body 座转为其 "unavailable" 兜底,重新注册后正文恢复。
- **Diff 显示**:插件不再维护逐行 patch 渲染器;`GitDiffSurface` 只负责 Git 取数、面板状态与侧栏适配,正文交给 `@deepseek-ai/dsh-client-ui-primitives` 公开导出的 `DiffBlock`。`git-diff-adapter.ts` 用已有 `diff` 包的 `parsePatch` 把 Git unified patch 转成组件接受的 old/new 文本片段,显示路径取用户选择的字面路径,不从 Git 引号头部反推。复制、折叠与新宿主的换行控件由官方组件拥有;Git 的工作区/index/HEAD 比较不转换成会话回合快照。二进制、仅元数据更改、空 patch 与不完整 patch 分别显示状态;末尾换行差异另有说明,因为官方组件会归一化行终止符;适配器分别记录旧、新文本是否缺少末尾换行,仅两侧状态不同时显示提示,双方均缺少换行(包括共享上下文中的标记)不算换行差异。支持版本上的上下文与 labels 差异集中在 `src/compat/dsh-diff.ts`,见[兼容性参考](../reference/dsh-compatibility.md#官方-diffblock-接入)。
- **可移植 / 原生分离**:主 fiber 不 require `desktop`;子 fiber `ctx.inject(['desktop'], ...)` 只接受 `shell.showItemInFolder`、`shell.openPath`、`notification.show`。缺 Desktop 时核心操作全部可用,仅原生动作不显示。
- **Graph layout engine**(`src/client/graph/`):纯逻辑模块——不访问 Git、不依赖 React、不触碰 DOM,可独立测试;输出 geometry 与 Canvas 2D 绘制解耦。设计决策与不变量见 [Git Graph Layout Engine](../reference/git-graph-layout.md)、[ADR-0001](../decisions/ADR-0001-graph-lane-not-owned-by-branch.md)、[ADR-0002](../decisions/ADR-0002-graph-lane-cap-max-three-lanes.md)。
- **Commit message 生成**:Host 侧独立 LLM 请求(不经会话上下文,无 KV Cache 影响);需要 LLM runtime 与可解析模型,否则 Client 报告 `git/generation-unavailable`。配置结构见根 README [Configuration](../../README.md#configuration)(canonical)。
Expand Down
10 changes: 10 additions & 0 deletions docs/reference/dsh-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
- **0.2.0 新增包不进入 peer OR。** `@deepseek-ai/dsh-client-product-analytics`、`dsh-otel`、`dsh-experimental-schedule-bundle` 与 `dsh-client-ui-settings-session-log` 仅从 0.2.0-rc.1 发布。conversation 对 product-analytics 是类型侧 `import type {}` 与 devDependency;候选类型构建与测试未要求安装该包。把它们写成与支持清单相同的 peer OR,会让旧宿主的 `app-boot` 预检失败。
- **车道专用包继续按发布探测。** `dsh-util-code-language` 与 `dsh-client-shortcuts` 在 `0.1.7-rc.2`、`0.2.0-rc.1` 与 `0.2.0-rc.2` 均有发布。开发 pin 现为 `0.2.0-rc.2`,提交锁文件包含这两项;它们仍不进入 peer OR。升级脚本只在 `npm view` 看到目标精确版本时把它们写入该车道的 devDependencies,切到更早发行版时再移除。0.2.0 的 primitives 发布 bundle 仍顶层导入 `dsh-util-code-language`,并额外导入 `dsh-util-workspace-path`;后者由传递依赖装上,不进入 peer OR。已有的 `diff`、`simple-icons`、`zustand` 与 `immer` peer 继续覆盖更早的未声明导入。

## 官方 DiffBlock 接入

Git Client 从 primitives 的公开入口复用 `DiffBlock`,不导入官方 `ui-deliverables` 的私有 `FileDiff` 源码,也不要求改动 DSH 宿主。官方完整 `changes-review` 页面绑定会话回合的变更记录,不能直接代替 Git 的 index/HEAD/worktree 比较;本插件保留原有 `git.diff` 地址与取数适配,只删除自写的 patch 行渲染与样式。渲染职责见[架构总览](../architecture/overview.md)。

`0.1.5-rc.2` 的组件把 old/new 片段中的每行当作移除/添加;自 `0.1.6-alpha.1` 起,组件比较片段并保留共享上下文。`src/compat/dsh-diff.ts` 用公开纯函数 `diffTotals` 对相同文本的计数探测该行为:支持上下文时传完整 hunk,否则只传由上下文隔开的修改片段,避免把未修改行当成更改。旧版的 `files(count)` labels 与新版的 code/wrap/unwrap labels 同时提供,中文和英文都由 Git 字典拥有。支持清单和开发 pin 不变。

新增的 `tests/dsh-diff.client.spec.ts` 在矩阵每个车道使用该车道实际安装的官方组件计数,验证共享上下文不会增加编辑数;详情面板与并发面板测试直接渲染官方组件,覆盖复制控件、折叠、地址恢复、再次导航与结果隔离。新增 adapter 规格用临时仓库的真实 Git patch 验证增删、暂存/工作区、Unicode 路径、二进制、重命名与缺少末尾换行,并拒绝截断输出。

本次迁移对开发 pin `0.2.0-rc.2` 运行完整测试、构建与产物检查;其余八个支持版本分别在临时目录重建安装树,通过兼容门禁、78 项相关回归、构建与产物检查。实际开发安装树、manifest 与 lockfile 保持原 pin。未进行真实 Web/Desktop 浏览器交互验证。

## 静态一致性门禁

上游 DSH 包把同级依赖写成 caret,例如 `^0.1.5-rc.2`。这个范围接受同一 core 上更后的 prerelease,pnpm 在 `autoInstallPeers` 下会装成 registry 里当前最高的匹配版本。只钉住根清单时,锁文件仍会混入 `0.1.5-rc.3`、`0.1.7-alpha.1` 或更旧的 `0.1.1-rc.2`。`.pnpmfile.cjs` 在每次安装时把传递依赖、可选依赖和 peer 里的全部 `@deepseek-ai/dsh-*` 改成当前精确版本。目标版本优先取 `DSH_COMPAT_VERSION`,否则取根 devDependency 的唯一 pin。根清单自己的 devDependency pin 和多版本 peer OR 范围保持不变。
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements/scope-and-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
| --- | --- |
| FR-1 | 仓库发现、Git 版本、当前分支与 HEAD 读取 |
| FR-2 | staged / unstaged / untracked 状态查询(porcelain v2,NUL 路径分隔) |
| FR-3 | 工作区与暂存区 diff 读取 |
| FR-3 | 工作区与暂存区 diff 读取;复用官方 `DiffBlock` 显示文件比较,插件只拥有 Git 数据与侧栏适配 |
| FR-4 | stage / unstage / commit / amend / push / rebase-then-push 同步 |
| FR-5 | 丢弃单条变更(含暂存后修改的 add/rename),两步显式确认 |
| FR-6 | 本地分支创建与切换;unborn HEAD 时禁用创建并说明原因 |
Expand Down
33 changes: 0 additions & 33 deletions src/client/GitDetailsSurface.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -374,39 +374,6 @@
color: var(--dsw-alias-label-secondary);
}

.diffBody {
overflow: auto;
border: 0.5px solid var(--dsw-alias-border-l2);
border-radius: 8px;
background: var(--dsw-specific-sidebar-fill);
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 12px;
line-height: 1.55;
}

.diffPlain,
.diffMeta,
.diffAdd,
.diffDel {
padding: 0 10px;
white-space: pre;
}

.diffMeta {
color: var(--dsw-alias-label-tertiary);
background: var(--dsw-alias-interactive-bg-hover);
}

.diffAdd {
color: var(--dsw-alias-state-success-primary);
background: rgb(46 160 67 / 8%);
}

.diffDel {
color: var(--dsw-alias-state-error-primary);
background: rgb(207 34 46 / 8%);
}

.generateButton {
position: absolute;
right: 6px;
Expand Down
Loading
Loading