🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

侧栏 Git Gnatnaituy/dsh-sidebar-git

DeepSeek Harness
Gnatnaituy24 天前有提交已提供中文文档扫描:含敏感能力

在会话侧栏查看变更、提交代码并管理分支远端

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/10 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Gnatnaituy/dsh-sidebar-git
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · browser
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 24 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 5 处,展示前 5 条)
  • 读取本地文件
    lib/index.js:101
    if (existsSync(join(candidate, 'sessions'))) return resolve(candidate)
  • 写入剪贴板
    lib/client.js:172
    return navigator.clipboard?.writeText(String(text)) ?? Promise.resolve()
  • 发起网络请求
    lib/client.js:274
    response = await fetch(ROUTE + path, options)
  • 写入剪贴板
    lib/client.js:1575
    ui.writeClipboard(commit.hash).catch(() => {})
  • 读取本地文件
    lib/binding.js:157
    return existsSync(path)
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 查看改动与diff
  • 暂存并提交代码
  • 切换分支与推送拉取

DSH 右侧边栏的 Git 标签页:跟随会话所在仓库查看改动和 diff、暂存、提交、切换分支、推送/拉取——破坏性操作走「准备→确认」两道关。

README

由 DeepSeek 最新模型翻译生成
dsh-sidebar-git DSH(DeepSeek Harness)动态插件:右侧栏里的一个 Git 页签。跟随当前会话的仓库,看变更与 diff、暂存提交、切分支、推拉远端——整个「改完代码 → stage → commit → push」流程不离开会话页面。 它与 harness 内建的 workspace-changes(按回合汇总 agent 工作区改动的只读快照)分工互补:那是「这一轮 agent 改了什么」,这里是「仓库整体的长期状态分支、远端、历史」,并且带写操作。 特性 | 特性 | 说明 | | 原生右侧栏页签 | 注册为右侧栏自己的页签类型「Git」,kind sidebar-git,与文件 / 终端 / 聊天 / 浏览器并列,无第三方依赖 | | 跟随会话绑定 | 默认绑定「当前页签所属会话」的工作目录(sessions.get(id).header.cwd → git rev-parse);会话 cwd 在仓库子目录里也正确显示(文件展示路径相对工作区,带 ../);bind 失败出空态 + 手动改绑 | | 变更页签 | 分组的文件行(已暂存 / 未暂存 / 未跟踪 / 冲突),状态徽标 + numstat,行内展开 diff(±行着色、自动换行开关、二进制/超大占位说明);「全部 ±」组操作 |
展开完整文档(README 剩余 1 节)
dsh-sidebar-git

DSH(DeepSeek Harness)动态插件:右侧栏里的一个 Git 页签。跟随当前会话的仓库,看变更与 diff、暂存提交、切分支、推拉远端——整个「改完代码 → stage → commit → push」流程不离开会话页面。

它与 harness 内建的 workspace-changes(按回合汇总 agent 工作区改动的只读快照)分工互补:那是「这一轮 agent 改了什么」,这里是「仓库整体的长期状态分支、远端、历史」,并且带写操作。

特性

| 特性 | 说明 |
| 原生右侧栏页签 | 注册为右侧栏自己的页签类型「Git」,kind sidebar-git,与文件 / 终端 / 聊天 / 浏览器并列,无第三方依赖 |
| 跟随会话绑定 | 默认绑定「当前页签所属会话」的工作目录(sessions.get(id).header.cwd → git rev-parse);会话 cwd 在仓库子目录里也正确显示(文件展示路径相对工作区,带 ../);bind 失败出空态 + 手动改绑 |
| 变更页签 | 分组的文件行(已暂存 / 未暂存 / 未跟踪 / 冲突),状态徽标 + numstat,行内展开 diff(±行着色、自动换行开关、二进制/超大占位说明);「全部 ±」组操作 |
| 提交 | 底部提交卡片(24px 圆角,与聊天同款);amend 上一次提交(勾选时自动预填 HEAD 的 subject + body);提交后 composer 清空 |
| 历史页签 | 时间倒序列表(短 hash、refs 徽标、作者、相对时间),展开 commit 看文件列表 + 逐文件 diff;复制完整 hash |
| 分支页签 | 顶部分支 chip:切换分支(列表按提交时间倒序)、新建并切换(check-ref-format --branch 双重校验)、删除(branch -d 拒合并不了时升级 -D 走确认)、推送到远端 / 拉取(--ff-only) |
| Stash 页签 | 存入(可留备注)/ 弹出 / 应用 / 删除;pop 等破坏型动作走两步确认 |
| 推拉远端 | 无 force 通道;pull 硬绑 --ff-only,非 ff 给出「到终端处理」的明确提示;凭据完全交给用户自己的 git credential helper(GIT_TERMINAL_PROMPT=0 使凭据交互不可能发生,失败归类为 AUTH_FAILED 提示回终端) |
| 危险操作分级 | T0 只读 / T1 保存型写(一次点击)/ T2 破坏型写(prepare → 预览 → confirm,一次性 token 30 秒过期);reset --hard / clean / push --force 在路由层面不存在 |
| 状态实时感 | 页签可见时 2.5s 轮询聚合的 /overview(分支状态 + 文件三分组 + stash 数);打出来的 diff 若仓库 rev 变化显示「内容已变化,点击刷新」,不自动改写正在读的 diff |
| 与桌面端同款外观 | 用 DSH 内置组件库(@deepseek-ai/dsh-client-ui-primitives)与 design token 渲染:同款按钮 / Pill / Tooltip / 菜单,图标缺失时自带 16px stroke 路径兜底;组件库缺失退化为纯原生元素 + 本插件样式表 |
| 失败可见 | 错误按稳定 code 分类(LOCKED / AUTH_FAILED / NOT_FAST_FORWARD / PUSH_REJECTED / UNMERGED / BRANCH_INVALID…)给出可操作提示;index.lock 冲突不移除锁文件,只如实说明 |
| 深浅主题跟随 | shell token 优先,缺席时才用兜底字面值;body[data-ds-dark-theme] |

安装

已装在 DeepSeek Harness 的 desktop profile(~/.dsh/profiles/desktop)。重装或换机器:

node tools/install-into-profile.mjs --dry-run # 先看要改什么
node tools/install-into-profile.mjs # 幂等:软链 + link: 依赖 + bundles 挂载
node tools/install-into-profile.mjs --uninstall # 卸载

脚本做三件事,不走 dsh plugin add(那会联网重解析整个 profile):

1. 把包软链(或 --copy 复制)进 profile 的 node_modules;
2. 在 profile 的 package.json 里记一条 link: 依赖,并把包加进 dsh.profile.bundles(紧跟 dsh-sidebar-chat 之后,四个 UI 插件聚在一起);
3. 清扫旧版脚本可能留在 profile cordis.patch.yml 里的手写 sidebar-git 行。

挂载行由包自己的 cordis.patch.yml 声明(package.json 的 dsh.bundle.patch 指向它)。profile 的 bundles 列表与 cordis.patch.yml 都被热重载,存盘几秒后刷新页面即可,不用重启。想临时停用而不卸载,在 profile 的 cordis.patch.yml 里加一条:

- id: sidebar-git
name: dsh-sidebar-git
disabled: true

数据放在哪

| 内容 | 位置 | 生命周期 |
| 手动改绑记录 | $DSH_HOME/dsh-sidebar-git/bindings.json | 持久化,重启保留;目标路径失效时自动回落到会话目录解析 |
| 其余全部 | 不落盘 —— 仓库自身的 .git 之外,插件不留任何缓存或索引 | – |

想确认实际路径:curl -s http://127.0.0.1:19387/dsh-sidebar-git/info。

原理

┌─ 浏览器(右侧栏「Git」页签,keepMounted) ────────────────────────────┐ │ lib/client.js(单文件、免构建 CJS,与 chat/browser 同形态) │ │ sidebarRightTabs.register(kind: 'sidebar-git') + 两个 slot seat │ │ 轮询 /overview(页签可见才轮询,同仓库多会话共享一份新数据) │ │ 变更(行内 diff)· 历史(commit 详情)· Stash · 提交卡片 │ └──────────────────────────┬──────────────────────────────────────────┘ │ 同源 fetch(loopback) ┌──────────────────────────▼──────────────────────────────────────────┐ │ host 半 lib/index.js(cordis 插件,inject webServer·subprocess·sessions)│ │ routes: /repo /overview /diff /log /branches /stashes │ │ /stage /unstage /commit /branch /push /pull /stash /binding│ │ /ops/prepare → /ops/confirm(T2 门,一次性 token) │ │ 模块分工: │ │ git.js 执行器:白名单 argv → ctx.subprocess,稳定环境 │ │ parse.js 解析器(纯函数):porcelain v2-z / numstat / log / diff│ │ guard.js 参数校验 · T2 门(prepare/confirm token) │ │ queue.js 每仓库串行队列(写操作排队,避免 index.lock 竞争) │ │ binding.js 会话↔仓库解析链 + bindings.json 持久化 │ └──────────────────────────┬──────────────────────────────────────────┘ │ ctx.subprocess(GIT_TERMINAL_PROMPT=0, │ GIT_OPTIONAL_LOCKS=0,超时与输出上限) ▼ 用户仓库(只经正规 git 命令触碰)

几个关键平台事实决定了上面的样子:

* 模型:git 经 ctx.subprocess 跑——显式 argv、无 shell 解释、scrub 凭据环境、有界输出。稳定性环境写死在执行器:GIT_TERMINAL_PROMPT=0(远端要凭据交互时立即失败,被归类为 AUTH_FAILED)、GIT_OPTIONAL_LOCKS=0、GIT_PAGER=cat、GIT_EDITOR=:、GIT_CONFIG_COUNT=0、LC_ALL=C.UTF-8。macOS 的 Xcode stub(/usr/bin/git 未装 CLT)用 xcode-select -p 探测,与 harness 自带 workspace-changes 同一套姿势。
* 解析:status --porcelain=v2 -z(NUL 条目 + 原始路径 + unborn/detached 标记)、diff --numstat -z(rename 条目是「空路径字段 + 两个 NUL 半段」)、log --format=<%x00 字段,%x01 记录>(body 放最后一个字段,任意外字节不作)、diff 用统一的 hunk 解析。三套格式逐字节对照 Apple Git 2.54 验证(见 test/core.test.mjs 的 canned 字节)。
* 注意一个坑:git branch --format= 与 git log --format= 是两个格式引擎——前者(for-each-ref)不展开 %x00,所以分支列表用真实 TAB 字段分隔;后者支持 NUL。git stash list --format= 用的是 log 引擎。这类「同名不同义」是测试里锁着的。
* mount:外壳给每个会话渲染一份右侧栏(隐藏的用 display:none 保留),本页签 keepMounted——同一页签可能同时存在多份实例;共享 store 按 sessionId 收敛,轮询按仓库去重(1.8s 内同仓库只 fetch 一份),浮动菜单用 isOnScreen()(checkVisibility + 包围盒)在不可见实例上不画。组件 kit 的 props 没有默认值、slot 抛错会被退役成白板——那些坑 chat 插件踩过,本包同样做了 MarkdownBoundary 式的克制(无 markdown 渲染面 + fallback kit 全量等价实现)。
* 刷新语义:/overview 返回一个 rev 状态 hash(分支 tip + ahead/behind + 每文件 XY + stash 数),客户端比对它判断「打开着的 diff 是否过时」。agent 或终端对仓库的任何改动都会体现——不需要文件监听。

状态与操作对应表

| 请求 | 危险级 | 做什么 |
| GET /info /repo /overview /diff /log /branches /stashes | T0 | 只读 |
| POST /stage /unstage /commit /branch(create/checkout/delete -d) /stash(push) /push /pull /binding | T1 | 保存型写:单次点击完成,响应内联最新 /overview |
| POST /ops/prepare {op: discard · stash-pop · stash-apply · stash-drop · branch-force-delete} → POST /ops/confirm {token} | T2 | 破坏型写:prepare 冻结参数 + 给出 argv/影响摘要,confirm 消耗一次性 token(30 秒)执行 |
| POST /binding {remove: true} | T1 | malware-free 的清理通道(smoke 用),等价丢一条绑定 |

安全与边界

* 插件的路由挂在 harness web 服务器上,不经过 /api 的 Host/Origin + 浏览器鉴权栅栏(与现存三个侧边栏插件一致)。同源页面之外的网页读不到响应(无 CORS),但本机进程可以访问——缓解靠:所有 git 参数由插件源码里的固定 argv 模板装配(无 shell、无参数拼接、路径/分支名/消息走校验,分支名要过 check-ref-format --branch),T2 操作必须 prepare→confirm。本机进程的直呼界面请与 chat / 浏览器插件同等的边界认识对待——这是三个现存插件的共同事实(介意的话 --uninstall)。
* 凭据隔离:插件不读、不存、不传任何凭据 —— 推拉借用用户 git 自己的 credential helper;GIT_TERMINAL_PROMPT=0 使凭据交互不可能发生(失败归类 AUTH_FAILED 而不是挂起)。
* 与智能体的并发:智能体与本插件都能改工作区,设计上「一切以实时 status 为准 + 写操作每仓库串行 + 冲突显式呈现」,不假装原子性;index.lock 冲突如实报告 LOCKED 并建议稍后重试,绝不自动删锁。
* v1 明确不做:任意 git 命令输入框、shell 拼接、参数模板注入;reset --hard、clean、push --force(非 lease)、cherry-pick、rebase、merge 冲突解决 UI(冲突以 banner 呈现并引导到终端或智能体)、submodule 内容操作(gitlink 如实展示)、自动后台 fetch(只在用户显式 push/pull 时动网络)。

已知边界

* hunk 级操作(逐块暂存/丢弃)延后到 v2:v1 只能文件粒度。
* 「自动换行」开关只影响 diff 显示;横向没有滚动条(等宽小字 + 换行)。
* 冲突合并、detached HEAD、空仓库都以只读提示呈现;不存在私自恢复动作。
* 会话 cwd 不在仓库内的空态必须手动 bind —— 没有全局 repo 收藏夹(那属于另一类工具)。
* pull 固定 --ff-only;需要 merge/rebase 的场景给出去终端的明确指引。v2 候选才做自动 merge。
* 页签标题在 ready 前显示「Git」,ready 后显示「分支 · Git」。

开发

node --test test/ # 82 个用例:解析器(逐字节 canned 格式)、守卫、队列、绑定、路由集成(真 git fixture)、client vm 渲染
node tools/smoke.mjs # 对着正在运行的 harness 跑真实链路

smoke 自建三个 fixture 仓库(正常 / 干净 / 空仓库)+ 一个本地 file:// 裸远端,经 /binding 接入后全链路验证,最后自删并清除绑定 —— 全程无网络,仓库在系统临时目录。

改 host 半想免重启,把本包 lib 加进 profile 的 hmr 监听根(cordis.patch.yml 的 hmr 行;那一行的 config 是整体覆盖,要连既有 browser/chat 条目一起写)。存盘秒级重挂 —— 本包开发流程已验证。client 半由模块系统按 revision 重取,刷新页面即可。

这次测试先行的几个用例锁住了真实 git 的惊喜:

* 干净树上 git stash push exit 0、提示在 stdout —— 路由按「诚实判断留存」而不是「exit 0 即成功」处理(NOTHING_TO_COMMIT)。
* 「You have not concluded your merge」(合并中间态提交被拒)归类 UNMERGED。
* branch --format 里 %(upstream:track,nobracket) 的值含逗号空格,BRANCH_FORMAT 用 TAB 分隔、subject 放最后,让 subject 里的意外 TAB 也能 join 回来。

License

MIT
预览分享卡片长什么样 ↓Gnatnaituy/dsh-sidebar-git
分享 · DeepSeek Harness Hub
Gnatnaituy/dsh-sidebar-git

在会话侧栏查看变更、提交代码并管理分支远端

这是你的仓库?认领条目

回到顶部