# @dsh-external/dsh-git-panel **简体中文** | [English](README.md) [![License: BSD-3-Clause](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE) ![DSH](https://img.shields.io/badge/DSH-web%20plugin-4b8bf5) ![Platform](https://img.shields.io/badge/platform-web-0ea5e9) DSH Web 的 **Git 面板**:左栏一个 Git 图标,点开就是「所有工作区一眼看尽 + 单仓库三视图」的整页面板。不切分支、不 force push、不偷偷暂存——所有破坏性动作都要你二次确认。 ![总览:每个工作区一张卡片,带分支/上游同步、变更计数和一句 AI 项目简介](docs/overview.jpg) ## 安装 这个包是一个 **DSH bundle 插件**(profile 装配层)。三种装法: **① 装进 profile(推荐,重启后仍在)** —— 在 profile 的 `cordis.patch.yml` 里登记包名与配置: ```yaml - id: git-panel name: '@dsh-external/dsh-git-panel' config: aiCommitProvider: minimax-cn aiCommitModel: MiniMax-M3.1-Flash-Preview aiCommitReasoningEffort: low ``` 然后把包放进 profile 的 `dsh.profile.bundles`(或 `npm i` 到 profile 目录)。插件自带的 `cordis.patch.yml` 会插入 loader 行——**这一行只能来自包内的 patch 文件**,缺了它重启后面板和路由会一起消失(见「它是一个 bundle」)。 **② 免重启注入(开发时最顺手)**: ``` dev_install_package { "dir": "/path/to/dsh-git-panel" } # 首次装配 dev_reload_package { "packageName": "dsh-git-panel" } # 改了 host 代码后热更新 ``` **③ 从源码构建** —— `scripts/build.sh` 会把构建依赖(cordis、schemastery、react、`@types/node`、`@deepseek-ai/dsh-tools`、tsdown)直接从 checkout 链接过来,干净 clone **不需要 `npm i`**: ```bash git clone git@github.com:kolawong/dsh-git-panel.git cd dsh-git-panel DSH_CHECKOUT=/path/to/deepseek-harness npm run build:all # host tsc + client 打包 ``` > ⚠️ 改了 `src/client/**` 必须跑 `npm run build:client`(或 `build:all`):`scripts/build.sh` 只编译 host 并给 client 做类型检查,**不**打包 `lib/client.js`,否则类型检查通过、浏览器里还是旧界面。 ## 配置 | 配置项 | 默认值 | 作用 | |---|---|---| | `timeoutMs` | `20000` | 单条只读 git 命令的超时 | | `actionTimeoutMs` | `60000` | fetch/pull/push 的超时 | | `outputMaxBytes` | `4194304` | 单条命令 stdout 上限 | | `actionOutputMaxBytes` | `32768` | 回传给面板的每路输出上限 | | `contextLines` | `3` | diff 上下文行数 | | `overviewConcurrency` | `4` | 总览并发读取的工作区数 | | `allowPush` | `true` | 关掉后 push 一律 403,fetch/pull 照常 | | `allowRepoWrites` | `true` | 关掉后 stage/unstage/discard/stash/commit 一律 403 | | `watchEnabled` | `true` | 关掉后 `/events` 返 503,面板退回轮询 | | `fetchBeforePull` | `true` | pull 前先 `fetch --prune` | | `aiCommitEnabled` | `true` | AI 总开关(提交信息草稿 + 项目简介) | | `aiCommitProvider` / `aiCommitModel` | 空 | 面板用的模型;空 = 跟随 profile 默认模型 | | `aiCommitReasoningEffort` | 空 | 推理等级(`low`/`medium`/`high`/`max`…)。**空 = 整个省略该选项**,不是 `off`——见「思考等级」 | | `aiCommitLanguage` | `zh` | 草稿与简介的语言 | | `aiCommitMaxDiffLines` / `aiCommitMaxDiffBytes` | `1200` / `65536` | 一次草稿最多读多少 diff | | `aiCommitTimeoutMs` | `60000` | 一次模型调用的超时 | | `aiCommitExtraPrompt` | 空 | 追加到草稿 system prompt 的额外要求 | ## 截图 | 总览 | 变更 + diff | |---|---| | ![总览](docs/overview.jpg) | ![变更](docs/changes.jpg) | | 历史(图形化泳道) | 分支 | |---|---| | ![历史](docs/history.jpg) | ![分支](docs/branches.jpg) | --- DSH Web 的 Git 面板:左栏活动栏一个 **Git** 图标(`sidebar.panellist` @order 15),点开在中列渲染整页面板(`main`,key 同为 `git`)。两屏: 1. **总览(落地屏)**——每个已注册工作区一张卡片,脏的排前面,一眼看出哪个项目要处理: ``` ┌────────────────────────────────────┐ │ dsh-plugin-quota-badges [有改动] │ │ /root/dsh-plugin-quota-badges │ │ [main] [↑0 ↓0] │ │ 8 变更 · 2 未跟踪 │ └────────────────────────────────────┘ ``` 卡片左侧色条 = 冲突(红)/ 有改动(黄)/ 干净(绿)/ 非仓库或不可用(灰);顶部汇总 `12 个工作区 · 4 个有改动`。 2. **仓库页**——点卡片进入,标题栏三个视图: - **变更**:分支/上游/ahead-behind、变更文件列表(冲突 / 已暂存 / 变更 / 未跟踪)、按文件 unified diff、提交框(可让模型写信息); - **历史**:图形化提交历史(泳道 + 合并曲线 + ref 标签),范围/作者/提交信息/路径过滤,翻页加载更早的提交,右侧看单个提交的文件与 diff(合并提交可选父提交); - **分支**:本地分支列表(当前分支、上游与 ahead/behind、tip 时间与标题),「看历史」把它交给历史视图。**只读,不切分支。** - `← 总览` 返回。 面板的图标是一整套 16×16 线性 SVG(`src/client/icons.tsx`),没有 emoji,也没有任何字体符号——视觉套件里有一条断言专门盯着这件事。 ## 界面语言(2026-10-05 重构) 面板带一套自己的设计系统(`src/client/styles.ts`,一个注入式 `