Chuyển đến nội dung chính

dsh-git-ui

Đã xác minh

dsh-git-ui · v0.2.0 · MIT · Giao diện web

DeepSeek Harness (dsh) plugin: visualize Git status in the Web UI — current branch, HEAD, staged/modified/untracked counts, ahead/behind, recent commits and changed files.

Cài đặt

dsh plugin add dsh-git-ui

Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.

Mã nguồn

Thẻ

Tác giả

Readme

dsh-git-ui

npm version npm license npm downloads

DeepSeek Harness(dsh)Web UI 插件:在会话界面中可视化展示 Git 状态——会话头部的 Pill 一眼呈现当前分支(或游离 HEAD)与脏状态计数(已暂存/已修改/未跟踪)及领先/落后。点击查看最近提交与变更文件,或打开 Git 中心进行完整管理。无需切换终端。

English version: README.md

功能特性

会话头部分支 Pill

每个会话头部右侧的独立状态胶囊:状态点(干净为绿、脏为橙)+ 分支名 + 脏/领先落后徽标,点击展开详情面板:

会话头部分支 Pill 与展开的详情面板
状态 Pill 显示
干净 ● main
脏状态 ● main · +2 −1 ?3
领先/落后 ● main · ↑1 ↓2
游离 HEAD ● (游离 HEAD) · a1b2c3d
unborn(无提交) ● main · 无提交
非 git 仓库 弱化显示 无 Git 仓库
git 不可用/出错 弱化显示 Git 不可用(tooltip 显示原因)

+N −N ?N = 已暂存/已修改/未跟踪;↑N ↓N = 领先/落后。脏且领先落后时徽标合并(如 ● main · +2 −1 ?3 · ↑1 ↓2)。

详情面板

点击 Pill 打开的详情:仓库根目录、状态计数与脏/领先落后徽标、最近提交(哈希·主题·作者·相对时间)、变更文件列表(状态 chip + 行内暂存/取消/丢弃操作)、分支内联切换、手动刷新按钮、上次检查时间:

详情面板内的分支内联切换

Git 中心

从面板进入的管理面板,四个标签——变更历史记录设置,统一阅览与操作工作区:

Git 中心——变更标签(分组文件变更)
  • 变更:IDE 式三段分组(已暂存/更改/未跟踪),单文件与全部暂存/取消暂存/丢弃(两步确认)、提交框(勾选文件或全部已暂存),以及选中文件的并排差异对照(前后导航)。

  • 历史:分页提交列表 + 分支图渲染,按分支/标签/作者/日期/文本或哈希过滤,以及拉取远程按钮:

    Git 中心——历史标签(提交列表与分支图)

    选中提交后,右侧展示提交详情(主题·正文·变更文件树,目录可展开/折叠):

    Git 中心——历史标签(提交详情与变更文件树)
  • 记录:Turn 工作记录的时段时间轴视图(见下节)。

    Git 中心——记录标签(Turn 工作记录时段)
  • 设置:Pill 信息组件与差异查看器的可配置项——实时预览、四档显示模式(极简/标准/完整/自定义,纯派生——手动调整重新匹配预设时自动吸附回档位)与逐项开关:状态点、分支名、三类变更计数徽标、领先/落后;弹窗区块:仓库路径、状态栏、分支切换器、新建分支行、最近提交条数、变更文件列表;另有差异查看器组(代码字号、语法高亮、上下文折叠)。点击面板头部齿轮图标直达:

    Git 中心——设置标签(显示模式与开关)

Turn 工作记录

按 turn 归因文件系统变更,回答「这轮工作动了哪些文件、是谁动的」,统计严格基于 git(ignored / 仓库外文件不计)。

  • 单 turn 模式(Pill,默认):最近工作时段的紧凑徽章——增量未读优先(自上次查看 新 N,查看即清零),其后为作者三分计数( 本会话 agent / 其他 dsh 会话 AI / 人工)。点击胶囊查看分组文件列表与任务叙事;【设置】中可关闭徽章。
  • 全 session 模式(Git 中心「记录」标签):连续有工作的 turn 聚合为工作时段(默认间隔 10 分钟内合并)——时段卡片流:头部为任务叙事(驱动该时段的用户指令摘要,「做了什么」先于「何时」)+ 时间窗 + 三分计数;展开为「本会话 / 其他会话 / 外部」三组文件(状态徽章:仍变更 / 已提交 / 已还原 / 已离开);顶部工具栏提供摘要(时段数 · 文件数 · 仍待提交)与四路过滤。任何时段都可点击展开——未产出文件变更的时段头部弱化标注「无变更产出」,展开区显示空态说明。
  • 作者三分本会话(本会话 agent 含 subagent 委托)/ 其他会话(同工作区其他 dsh 会话的 AI 写入)/ 外部(人工:IDE / 命令行 / 未识别来源)——归因轴对齐用户心智:「AI 改的」与「我改的」不再混桶。其他会话归因固化于观测时间线,会话离场或宿主重启后不漂移。
  • 行动闭环:时段卡片展开区支持批量暂存(「暂存 AI 变更」= 本会话+其他会话的仍变更、不带人工 WIP;「暂存全部」);已提交条目点击直达历史页对应提交(自动定位并选中)。
  • 归因置信度 + 人工纠错:平台自证写意图的条目为实心徽章;启发式推断的条目为虚线徽章 + 标记——误差可见。悬停条目 可人工改判归因(仓库级持久化,弹窗/记录页/未读计数统一生效)。
  • 本轮新增识别:每轮工作边界被快照捕获,不在上一轮边界内的条目标记「新」,一眼看出本轮新增。

原理:宿主折叠会话事件日志(turn/start·turn/end·tool/call·user/message 自带时间戳)得到精确的 per-turn 窗口与任务叙事;复用每个工具自声明的写意图提取 agent 写路径(bash 走静态目标启发式);其他会话写入经同 cwd 会话枚举归并;外部变更经轮询观测时间线归因(每路径首见时刻 + HEAD 移动提交检测 + 仍脏文件的 mtime 精修)。观测时间线与叙事/指纹等持久化于宿主插件数据目录,宿主重启后记录不丢。

差异对照增强

变更标签的并排查看:

  • 新增文件直接展示:纯新增(--- /dev/null 形态)单栏全宽直接展示创建后的完整文件内容(含行号);0 字节空文件显示「文件为空」。
  • 语法高亮:按文件类型着色关键字/字符串/注释/数字等;整块 tokenize 后按行渲染,跨行注释与多行字符串保持正确。颜色复用宿主主题 token(亮/暗自适应);高亮开关与代码字号可在设置中调整(语言子集见已知限制)。
  • 上下文折叠:连续 12 行以上未变更的上下文段折叠为「… N 行未变更」横条,点击展开/收起;可在设置关闭。
  • 设置项:代码字号(10–16px)、语法高亮开关、上下文折叠开关,独立于显示模式档位。

数据保鲜与边界行为

  • 数据自动保鲜,零操作:进入会话自动加载状态快照、静默轮询(间隔由主机下发,默认 30s,不重叠请求)、agent 完成一个回合后立即刷新(此时工作区最可能已变化)、断线重连 resync、面板内手动刷新。
  • 确定性降级:非 git 目录、无 cwd、git 缺失、超时、巨型仓库等边界显示稳定降级态——不崩溃、不刷屏。
  • 零 agent 影响:不给模型新增工具、不写会话事件,从不改变 agent 行为。Git 中心的写操作(暂存/提交/分支/拉取)均由用户从 UI 主动发起。

安装

需要已安装 DeepSeek Harness(dsh)且使用 web profile。

# 从 npm registry 安装。
dsh plugin --profile web add dsh-git-ui

安装后重启 dsh web。在 git 仓库目录打开会话,头部即出现分支 Pill。

验证安装:

cat ~/.dsh/profiles/web/package.json   # dsh.profile.bundles 中应包含 dsh-git-ui

卸载:

dsh plugin --profile web remove dsh-git-ui

本地开发安装(把本仓库链接进 profile):dsh plugin --profile web add ./。 本地 tgz / 目录 / GitHub 直装(file:...tgzgithub:...)会把包以 symlink 方式装进 profile,Node 沿真实路径解析时无法触达宿主提供的 @deepseek-ai/* peer 依赖。本地安装时请保持本仓库 node_modules/@deepseek-ai/* 的 peer 链接 存在(步骤见 开发)。

使用方式

  1. 打开一个工作目录位于 git 仓库内的会话。
  2. 随时扫一眼头部 Pill——无需任何操作。
  3. 点击 Pill 查看仓库根目录、计数、最近提交与变更文件;点 刷新 立即重新检查,或打开 Git 中心进行完整变更管理与历史浏览。

每个会话显示自己工作目录的 Git 状态;非仓库会话显示弱化占位而非 Pill。

配置(可选)

默认零配置开箱即用。高级用户可在 profile 的 cordis.patch.yml 中覆盖插件配置(后层覆盖,整行替换 config):

- id: git-ui
  config:
    defaultRefreshIntervalMs: 60000   # 轮询间隔(毫秒);0 = 关闭轮询
    maxChanges: 200                   # 快照中变更文件条数上限
    timeoutMs: 3000                   # 单条 git 命令超时(毫秒)
    maxStatusBytes: 8388608           # status 输出上限,超出截断
    dshHome: /path/to/harness-home    # 可选:Harness home(默认 $DSH_HOME → ~/.dsh)
                                      # 插件数据存放于 <home>/plugin-data/dsh-git-ui/

环境要求

  • Node.js ^22.19.0 || >=24.0.0
  • dsh >= 0.1.0-rc(开发者预览版)
  • 主机可执行 git(插件通过子进程调用 git 命令)

已知限制

  • 仅展示会话工作目录的 Git 状态。历史页的过滤树列出远程分支、领先/落后与手动拉取,但不暴露 push / pull / merge。
  • 轮询式刷新(默认 30s);基于文件监听的事件推送为规划中的扩展。
  • 变更文件列表有上限(maxChanges);未跟踪目录内部文件逐个枚举。status 输出超过内存上限(默认 4 MiB)时会从私有 spill 文件恢复完整输出,计数保持精确——仅当 spill 上限(64 MiB)也被突破时才回退为近似(truncated: true)。
  • 浏览器只传 sessionId,不传路径;主机解析权威 cwd 并执行 git 命令(写操作用 -- 路径分隔、拒绝绝对路径与 .. 逃逸)。
  • Turn 工作记录:bash 动态构造写目标($(...)、glob、find -execeval)不可静态提取,落入「外部」且带 推断标记(根治路径待上游沙箱提供 per-turn 权威写集,插件已预留接口缝);冷 subagent / 冷兄弟会话(未加载)跳过对应归因——兄弟归因随观测时间线固化(已判定不漂移),但从未被查询判定过的兄弟写入仍落「外部」;兄弟会话识别经 realpath 归一 + 仓库子目录纳入;观测时间线每会话上限 2000 条(裁剪最旧),且在一个轮询间隔内出现又消失的外部变更在宿主重启后无法重建;turn 边界为首次观测点近似(轮询粒度内的先写后还原不可分);早于首个 turn 的变更无归属窗口;人工改判为仓库级(跨会话生效),不随会话回收。
  • 语法高亮为 bundle 预算裁剪的语言子集(TypeScript/JS 族、JSON/YAML/TOML/INI、Markdown、XML/HTML、CSS/SCSS/LESS、Python、Shell、Java、Go、Rust、C、C#、Kotlin、SQL、Makefile)。C++ 以 C grammar 近似、HTML 以 XML grammar 近似、SCSS/LESS 以 CSS grammar 近似(基础 token 正确,语言特有结构回落纯文本);PHP、Swift、Ruby、Lua 等未注册语言整体回落纯文本(仍为等宽字体、不报错)。
  • 设置持久化于宿主磁盘;若 host RPC 不可达(降级),设置仅停留在内存态(本次会话有效)。

开发

pnpm install
# 把宿主提供的 peer 依赖链接进仓库,本地 `dsh plugin --profile web add ./` 才能解析:
# pnpm 以 symlink 把包装进 profile,Node 沿真实路径回到本仓库,
# 因此 node_modules/@deepseek-ai/* 需要指向宿主的 fallback 目录。
mkdir -p node_modules/@deepseek-ai
for p in "$HOME"/.dsh/profiles/node_modules/@deepseek-ai/*; do
  ln -sfn "$p" "node_modules/@deepseek-ai/$(basename "$p")"
done
pnpm run typecheck
pnpm test
pnpm run build        # host(esbuild ESM,禁止压缩)+ client(ModuleLoader factory 闭包)
dsh plugin --profile web add ./   # 本地安装;重启 dsh web 验证

架构

插件采用分层架构,将 dsh 平台隔离在窄适配层之后,dsh API 演进时业务逻辑零改动:

flowchart TB
    subgraph Biz["业务层 — 零 dsh import"]
        HostBiz["src/host/ · core / actions / queries / parser"]
        ClientBiz["src/client/ · controller / GitPill / GitCenter"]
    end
    subgraph Contracts["契约层 — 稳定接口"]
        C["src/contracts/ · host-endpoints / client-platform / ui-primitives"]
    end
    subgraph Adapters["适配层 — 唯一感知 dsh 的代码"]
        A["src/adapters/dsh/ · client-adapter / ui-primitives / types"]
    end
    HostBiz --> C
    ClientBiz --> C
    C --> A
    A --> DSH["dsh 平台 · cordis / typert / ui-primitives"]
  • src/contracts/ 定义插件自己的稳定接口(零 dsh import)。
  • src/host/src/client/ 基于这些接口实现业务逻辑。
  • src/adapters/dsh/唯一 import @deepseek-ai/* 的地方; dsh 升级只需修改此处。

许可证

MIT