source-code-mgmt 1.10.1 → 1.13.0
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/README.en.md +275 -219
- package/README.md +61 -5
- package/lib/client.js +726 -13
- package/lib/index.js +1248 -13
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> [English](README.en.md) | 中文
|
|
4
4
|
|
|
5
|
-
> 版本:**v1.
|
|
5
|
+
> 版本:**v1.12.0** | 更新日志见文末「[版本历史](#版本历史)」
|
|
6
6
|
|
|
7
7
|
> **界面语言跟随 DSH 设置实时切换**:面板与 host 端消息自动使用 DSH 的语言(设置 → 通用 → 语言),中文 ↔ 英文即时生效,无需重启。
|
|
8
8
|
|
|
9
|
-
> DSH Web GUI 源代码管理插件:把「环境检查 → SSH 配置 →
|
|
9
|
+
> DSH Web GUI 源代码管理插件:把「环境检查 → SSH 配置 → 代码上传推送 → 克隆仓库 → 提交 PR → 发布 npm 包」整合进「代码管理」面板,支持 GitHub / Gitee 双平台,一键管理代码仓库。
|
|
10
10
|
|
|
11
11
|
> 入口位置自适应:**已安装 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 时**,「代码管理」作为它侧边栏的一个新 Tab 页面出现(全新侧边栏 Tab);**未安装时**,「代码管理」按钮位于 DSH **右上角、常驻可见**——有会话时放在「Session 日志」旁边的右对齐列表里,无会话空态时改为一个固定在**右上角**的浮动按钮,点击后打开一个 **dsh-better-sidebar 外观的右侧集成面板**(推挤主内容区)。两种形态都复用同一套面板 UI。
|
|
12
12
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
> 检测只是激活时一次内存读取(`ctx.get('betterSidebar')`),零 I/O、零网络,不影响 DSH 启动速度;两种形态间自动切换。未安装 better-sidebar 时入口常驻右上角(有会话=Session 日志旁,空态=固定右上角浮动按钮),空态/新对话也可见。
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
面板分六步(①②③ 为核心三步,④⑤⑥ 为新扩展板块,默认折叠按需展开):
|
|
23
23
|
|
|
24
24
|
### ① 环境检查
|
|
25
25
|
- 显示**操作系统**(美化名:`Windows` / `macOS` / `Linux`,对应底层 Node 平台标识 `win32` / `darwin` / `linux`)
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
- **选择工作区**:下拉选择 DSH 已登记的工作区文件夹,选中即加载
|
|
45
45
|
- **选择目录 →**:下拉右侧按钮,可手动输入/粘贴目录绝对路径或点击「浏览…」弹出原生文件夹选择器;确认后**持久化加入自定义目录列表**(插件独立存储于 `~/.dsh/storages/source-code-mgmt-dirs.json`,**不写入插件目录**,开源不泄漏个人路径),下次打开无需重新选择;手动添加的目录会以**自定义目录徽标**显示,末端带 **✕** 可一键删除该下拉记录(只删记录,不删实际文件夹)
|
|
46
46
|
- 显示仓库状态:平台来源、分支、远程地址、待提交改动数、领先/落后远程、>100MB 文件
|
|
47
|
-
- **查看详情**:有改动时「改动」行旁出现「查看」按钮 →
|
|
47
|
+
- **查看详情**:有改动时「改动」行旁出现「查看」按钮 → 点击弹出窗口列出改动/新增/删除/重命名的**文件或文件夹名称**;所有**可文本预览**的文件(含新增/untracked 新文件)都可**点击文件行展开查看内容**——**并排视图**(左旧右新,删除行红底、新增行绿底),**纯新增文件没有旧版本,只显示「新版本」一列**;**二进制文件不显示「查看」**(内容无法按文本预览);本地与远程存在差异时「同步」行旁出现「查看」按钮 → 点击弹出窗口显示**本地领先/落后的具体提交列表**;无改动或已一致时不显示按钮
|
|
48
48
|
- **本地 Git 工作流**(不改动远程同步逻辑):
|
|
49
49
|
- 「改动」弹窗里每个文件行有**暂存 / 取消暂存**按钮(按 `git status` 的 XY 状态区分 staged/unstaged),并显示「已暂存 / 未暂存」标记
|
|
50
50
|
- ③ 面板仓库名上方有**提交信息输入框 + 「提交」按钮**(仅 git 仓库且有改动时显示)——可写自定义提交信息,**不再用固定 message**;留空则自动生成
|
|
@@ -60,6 +60,21 @@
|
|
|
60
60
|
- Gitee:用令牌调 Gitee OpenAPI `POST /user/repos` 建仓,再设置 SSH 远程 `git@gitee.com:<owner>/<name>.git` 并 `git push`(走 ② 已配的 SSH 密钥)
|
|
61
61
|
- **>100MB 文件处理**:自动识别超过 100MB 单文件限制的文件——文件在一级子目录内则**忽略整个一级目录**(该文件夹为一整体),根目录独立文件则**忽略单个文件**;已存在于 `.gitignore` 的不重复添加,并显示「未上传原因」
|
|
62
62
|
|
|
63
|
+
### ④ 克隆仓库(Clone)
|
|
64
|
+
- 跟随 ② 平台:把已登录账号(GitHub 走 `gh`,Gitee 走 OpenAPI)名下**所有远程仓库**列出来,并自动标记本地是否已有同名 git 仓库(默认按「默认工作区 + 已登记工作区 + 自定义目录」判定)
|
|
65
|
+
- **克隆到目录**:可选目标父目录(默认 = DSH 默认工作区),不选即克隆到默认位置;克隆走 SSH URL(`git@github.com:…` / `git@gitee.com:…`),成功后自动加入自定义目录列表,③ 里可直接选中
|
|
66
|
+
- 列表里「本地已有」的仓库不可重复克隆,其余每个仓库一个「克隆」按钮
|
|
67
|
+
|
|
68
|
+
### ⑤ 提交 PR(Pull Request)
|
|
69
|
+
- **目标仓库记录到本地**:填写要提交 PR 的仓库网址(`https://github.com/owner/repo` / `owner/repo` 等)→ 记录到 `~/.dsh/storages/source-code-mgmt-pr-targets.json`(**不写入插件目录**);已记录仓库以标签展示、点选回填、可删除
|
|
70
|
+
- **AI 分析 PR 规则**:抓取目标仓库的 README / CONTRIBUTING / PR 模板 / package.json scripts,交给 DSH 默认模型**思考该仓库应如何 PR**(如 awesome-dsh-plugin 收录插件:新建 `data/plugins/<owner>__<repo>.yml`、重生成 README、满足 `dsh.bundle`/提交数/topic 等门槛),输出结构化的**步骤规则并缓存到插件目录 `rules/<owner>__<repo>.json`**——下次对同一仓库直接读缓存执行,**不再重复消耗 AI**;「重新分析(忽略缓存)」可强制重新思考
|
|
71
|
+
- **AI 生成 PR 内容**:填插件信息(owner/repo、分类、中英描述)→ AI 按规则模板生成标题 + 描述 + 条目文件内容,**生成后可自由修改,绝不直接提交**
|
|
72
|
+
- **执行 PR**:按规则步骤执行 `fork → 克隆 fork → 加 upstream → 拉取 → 建分支 → 写条目 → (重生成 README)→ 提交 → 推送 → 开 PR`(GitHub 走 `gh pr create`,Gitee 走 OpenAPI),逐步显示执行日志与 PR 链接;工作目录默认 = 默认工作区
|
|
73
|
+
|
|
74
|
+
### ⑥ 发布 npm 包(npm publish)
|
|
75
|
+
- 五步向导(在目标目录执行):**① 确认源** `npm config get registry` → **② 查看认证配置** `npm config list`(自动脱敏 token/auth/password)→ **③ 验证身份** `npm whoami` → **④ 预览打包** `npm pack --dry-run`(先看会发布哪些文件,不真正打包发布)→ **⑤ 发布** `npm publish`
|
|
76
|
+
- 发布前必须勾选「我已核对以上内容,确认发布到 npm registry」才可点「发布」,防止误操作
|
|
77
|
+
|
|
63
78
|
### 数据加载时机(打开时联网、显示刷新中)
|
|
64
79
|
DSH 打开时**不联网同步仓库**,只预取静态的环境/SSH/工作区列表。**打开插件、切换工作区、刷新状态、以及推送/拉取/暂存/提交等操作后**,都会联网获取对应工作区的最新仓库状态,并显示「⟳ 刷新中…」提示——避免打开/重开/切换时显示可能过期的旧数据(如旧的「无改动」)。关闭面板再打开也会重新同步,不会停留在旧状态。
|
|
65
80
|
|
|
@@ -181,6 +196,7 @@ dsh web
|
|
|
181
196
|
- **git / gh / ssh / ssh-keygen 二进制自动探测**:启动时依次按 ①环境变量覆盖 → ②PATH 查找(Windows 加 `.exe`)→(仅 Windows)③Git 自带目录(`usr\bin` / `bin`)回退,最后兜底用裸命令名。因此只要装了 Git,即使 `ssh` 不在 PATH 里也能正常工作,换设备无需额外配置。
|
|
182
197
|
- 如需手动指定二进制路径,可用环境变量覆盖:`DSH_SCM_GIT` / `DSH_SCM_GH` / `DSH_SCM_SSH` / `DSH_SCM_SSH_KEYGEN`
|
|
183
198
|
- **SSH 传输修复**:Git for Windows 自带的 MSYS `ssh.exe`(`usr\bin\ssh.exe`)在被 detached/agent 进程调用时可能报 `couldn't create signal pipe, Win32 error 5`,导致 `git push`/`git pull` 失败。插件执行 git 远程命令时会自动注入 `GIT_SSH` 指向解析到的可用 `ssh`(通常为系统 OpenSSH `C:\Windows\System32\OpenSSH\ssh.exe`),避免该问题。
|
|
199
|
+
- **中文文件名兼容**:git 默认 `core.quotepath` 会把含非 ASCII 字节的路径输出成八进制转义的引号串(显示为乱码)。插件对所有 git 调用统一注入 `-c core.quotepath=false`(直接输出原始 UTF-8 路径),并对仍带引号转义的路径做 `parseGitPath()` 反转义兜底——改动列表 / diff 里的中文文件名显示正常
|
|
184
200
|
- **缺工具一键安装跨平台**:Windows 用 winget / 内置功能(回退 choco/scoop),macOS 用 brew,Linux 用 apt-get / dnf / pacman(自动带 `sudo -n`;已是 root 则省略)。SSH 密钥探测、本地 Git 工作流、并排 diff 等在三个平台行为一致;「浏览目录」的原生选择器仅 Windows 可用,macOS/Linux 上请在输入框直接填路径(可手动输入粘贴)。
|
|
185
201
|
|
|
186
202
|
## 开发
|
|
@@ -197,7 +213,47 @@ dsh plugin --profile web add link:$(pwd)
|
|
|
197
213
|
|
|
198
214
|
## 版本历史
|
|
199
215
|
|
|
200
|
-
### v1.
|
|
216
|
+
### v1.13.0(当前)
|
|
217
|
+
按第二轮反馈继续精化(④⑤⑥ 三处交互收敛):
|
|
218
|
+
|
|
219
|
+
- **④「本地已有」判定扩大到已登记的目录**:此前克隆列表只在「当前选中的克隆目录」下判定本地是否已有,用户若把克隆目录切到别处(如工作区 `workspace`),明明已存在的仓库仍标「可克隆」。现在新增 `localRepoExistsAnywhere()`:除了当前选中目录,还会遍历 ③ 代码管理登记过的**所有工作区 / 自定义目录**(`~/.dsh/storages/workspace.json` + `source-code-mgmt-dirs.json`)逐一判定——任一被登记的位置已有同名仓库即标「本地已有」;克隆成功后目标目录本就会记入自定义目录,因此「某位置已有该仓库」的知识会自动沉淀下来,下次列表直接命中。
|
|
220
|
+
- **④ 新增「按仓库地址克隆到任意位置」**:克隆板块底部新增一行——粘贴任意 git 仓库地址(HTTPS 或 SSH,GitHub / Gitee / 自建均可)+ 选择目标目录,自动从 URL 末段推导仓库名(去掉 `.git`)并 `POST /clone/run` 克隆到所选位置;复用「选择目录…」按钮(可输入绝对路径或弹系统文件夹选择器,确认后记住到自定义目录)。目标目录默认沿用顶部下拉,未选择时给出提示。
|
|
221
|
+
- **⑥ 发布 npm:目标目录默认留空**:此前默认回填默认工作区,用户不选就可能发布到非预期目录。现在目标目录**默认留空**,界面提示「当前留空,不会自动使用默认目录」;未选目录时「重新检查 / 登录 / 执行」按钮全部禁用并拦截,用户必须手动选择(同 ③/④ 的「选择目录…」按钮)。
|
|
222
|
+
- **⑤ 收敛为「提交 awesome-dsh-plugin 插件收录 PR」**:按你要求先只保留「awesome-dsh-plugin 插件收录 PR」这最常用的一条路——隐藏「目标仓库地址」输入框、隐藏「记录到本地 / 已记录」行与标签、隐藏「分析 PR 规则 / 重新分析(忽略缓存)」按钮与手填规则面板、隐藏通用 PR 流程兜底框;目标仓库锁定为 `https://github.com/awesome-dsh-plugin/awesome-dsh-plugin`,挂载时只读加载一次其**预置收录规则**(不消耗 AI)并展示加载状态。保留下部:插件信息(名称/分类/描述 en/zh)→「生成 PR 内容(AI)」(命中预置模板可免 AI 填充、仍可编辑)→ 可编辑的标题/描述/条目文件内容 + 工作目录 →「执行 PR」(逐步日志 + PR 链接)。host 端 `/pr/analyze`、`/pr/targets` 等路由与预置规则文件保持不变,仅前端做了收敛。
|
|
223
|
+
|
|
224
|
+
### v1.12.0(历史)
|
|
225
|
+
本次更新(新增④克隆 / ⑤提交 PR / ⑥发布 npm 三大板块):
|
|
226
|
+
|
|
227
|
+
- **④ 克隆仓库**:列出已登录账号(GitHub `gh repo list` / Gitee OpenAPI `user/repos`)名下所有远程仓库并标记本地是否已有;**默认目标目录 = 用户主目录(home)**,不选即克隆到 home;每一行目录都有与 ③ 代码管理一致的「选择目录…」按钮(输入绝对路径或系统文件夹选择器,确认后记住到自定义目录);克隆走 SSH URL,成功后自动加入自定义目录列表。host 新增 `GET /clone/default-dir`、`GET /clone/home`、`GET /clone/repos`、`POST /clone/run`;本地已存在判定同时覆盖「目录名 == 仓库名且含 .git」的场景
|
|
228
|
+
- **⑤ 提交 PR**:目标仓库网址记录到 `~/.dsh/storages/source-code-mgmt-pr-targets.json`(**不写入插件目录**);**输入网址即自动读取该仓库的本地规则**(`GET /pr/rule`,只读缓存、不消耗 AI):命中预置/缓存规则就显示对应专属 PR 功能,未命中则显示通用流程并提示「分析 PR 规则」;**预置 `rules/awesome-dsh-plugin__awesome-dsh-plugin.json`**——输入 `https://github.com/awesome-dsh-plugin/awesome-dsh-plugin` 直接给出它的收录规则(fork → clone → 在 `data/plugins/<owner>__<repo>.yml` 写条目 → `npm ci && node scripts/generate-readme.mjs` 重生成 README → commit → push → PR,规则写在插件目录);「分析 PR 规则」抓取目标仓库 README/CONTRIBUTING/PR 模板/package.json 交给 **DSH 默认模型**思考该仓库应如何 PR,输出结构化步骤规则并**缓存到插件目录 `rules/<owner>__<repo>.json`**(下次直接执行、不再消耗 AI;「重新分析(忽略缓存)」可强制重想);「生成 PR 内容」按规则模板产出标题/描述/条目文件内容(带预置模板时可免 AI 直接填充、仍可编辑),**生成后可改、绝不直接提交**;「执行 PR」按 `fork→clone→加 upstream→fetch→建分支→写条目→重生成 README→commit→push→gh pr create(Gitee 走 OpenAPI)` 逐步执行并显示日志与 PR 链接。host 新增 `GET /pr/targets`、`POST /pr/targets`、`POST /pr/rule`、`POST /pr/analyze`、`POST /pr/generate`、`POST /pr/execute`
|
|
229
|
+
- **⑥ 发布 npm 包**:五步向导(`npm config get registry` → `npm config list`(脱敏 token/auth/password)→ `npm whoami` → `npm pack --dry-run` → `npm publish`),发布前需勾选确认;**可切换包目录**(同样带「选择目录…」按钮);**未登录/未配置时明确提示**:显示当前 registry / whoami,未登录给出「打开终端执行 npm login」(host 弹系统终端、进入目标目录执行,`POST /npm/login`)与「复制登录命令」,登完回面板点「重新检查」;`GET /npm/status` 会报告目录是否存在、是否含 `package.json` 并给出对应警告。host 新增 `GET /npm/status`、`POST /npm/step`、`POST /npm/login`
|
|
230
|
+
- **host 端 AI 能力**:新增 `llmComplete()`——通过 `ctx.get('llm')` 调 DSH 的 LLM 运行时,默认模型取 `ctx.get('settings').get('agent-default-model')`(兜底解析 `~/.dsh/settings.yaml`),消息格式适配 `GenerateOptions`(text-delta 组装)
|
|
231
|
+
- **维护性**:新增 i18n 键通过 `Object.assign` 并入 `EN_DICT` / `HOST_EN`,不改动原超长字典行;新增 `inputStyle()` 共享输入框样式;`node --check` 双端通过
|
|
232
|
+
- **对抗式审查修复(同版本内)**:
|
|
233
|
+
- **修复 Windows npm 路径含空格导致 ⑥ 不可用**:npm 解析路径(如 `C:\Program Files\nodejs\npm.cmd`)含空格时,shell 模式会把命令截断成 `'C:\Program' 不是内部命令`。`run()` 现对含空格的可执行文件路径加引号包裹(只包裹路径本身,参数仍按数组安全传递),npm registry / whoami / version 实测通过;
|
|
234
|
+
- **修复「重新分析(忽略缓存)」失效**:`/pr/analyze` 路由此前未把 `force` 传给分析流程,导致该按钮永远走缓存。现已透传 `body.force`;
|
|
235
|
+
- **修复点号仓库名解析**:`parseRepoUrl` 此前把 `owner/my.repo` 截断成 `my`(正则排除点号),现允许点号、仅剥离尾部 `.git`;
|
|
236
|
+
- **安全加固 PR 规则执行**:规则来自 AI/缓存、默认受信任,新增 `safeEntryPath()` 拦截条目文件路径穿越(`..` / 绝对路径),`safeRegenerateCommand()` 只放行白名单构建命令并拒绝 shell 元字符——防止恶意仓库文档诱导 AI 产出危险规则后自动执行;
|
|
237
|
+
- **修复「确保 fork」日志假成功**:GitHub `gh repo fork` 失败时此前仍显示 ✅,现仅在真实成功或「already exists」时显示成功;
|
|
238
|
+
- **Gitee 仓库列表分页**:`user/repos` 默认每页 20,此前只列前 20 个;现按每页 100 分页拉全(上限 10 页 ≈ 1000 个,与 GitHub 对齐);
|
|
239
|
+
- 扩展 `tools/smoke-test.mjs` 至 31 项(覆盖点号仓库名、路径穿越、命令白名单等边界),全绿;`node --check` 双端通过
|
|
240
|
+
- **按反馈完善(同版本内)**:
|
|
241
|
+
- **④ 默认克隆目录改为用户主目录**:此前默认是 DSH 工作区,且「工作区目录本身就是仓库」时被误标为可克隆;现默认改为 `os.homedir()`(Windows 为 `C:\Users\<用户名>`,Linux/macOS 为用户主目录),本地已存在判定补上「基目录名 == 仓库名 且含 `.git`」;
|
|
242
|
+
- **④⑥ 目录选择按钮与 ③ 一致**:克隆目标与 npm 包目录都提供「选择目录…」按钮,行为与 ③ 代码管理相同(可输入绝对路径或弹出系统文件夹选择器,确认后记住到自定义目录),不再局限于工作区内;
|
|
243
|
+
- **⑤ 按仓库显示对应 PR 功能**:输入目标仓库网址后自动 `GET /pr/rule` 读缓存规则(不消耗 AI)——有规则显示专属流程、无规则显示通用流程并提示分析;预置 awesome-dsh-plugin 收录规则(写入插件目录 `rules/`),输入官方仓库网址即命中;
|
|
244
|
+
- **⑥ 未登录/未配置时引导登录**:`npm whoami` 未登录时面板给出明确警告,可一键弹出系统终端执行 `npm login`(`POST /npm/login`,Windows 用 `cmd /k`、其他平台回退常见终端模拟器)或复制登录命令,完成后「重新检查」即可继续发布流程;
|
|
245
|
+
- **⑤ 分析 PR 规则可手动输入规则来源**:点击「分析 PR 规则」展开输入面板——可手动填写该仓库的 PR 规则文本,或提供规则文件(本地路径 / URL,如某仓库 README),留空则由 AI 自动抓取仓库文档(README/CONTRIBUTING/PR 模板)分析;提供内容时走**精简提示词**(只忠实整理用户输入、不抓文档、不编造,节省 token),结果同样结构化缓存到插件目录 `rules/`;仓库已有本地规则时点击「分析 PR 规则」会先询问「是否重新分析」(选否则不做任何事)。
|
|
246
|
+
|
|
247
|
+
### v1.11.0(历史)
|
|
248
|
+
本次更新(改动文件查看体验 + 中文文件名兼容性):
|
|
249
|
+
|
|
250
|
+
- **新增/untracked 文件现在可以查看内容**:改动列表里「新增」文件行也显示「▸ 查看」,点击展开显示完整文件内容(按「全部新增」的 diff 渲染,超大文件只显示前 2000 行并附截断提示,上限 1MB 不会整读进内存);空的新文件显示「(空文件)」。
|
|
251
|
+
- **新增文件不再显示「旧版本」列**:并排 diff 在没有任何删除行(纯新增,如新增/untracked 文件)时只显示「新版本」一列,不再出现空白的「旧版本」表头与左列;有增有删的修改仍保留双列对比。
|
|
252
|
+
- **二进制文件不显示「查看」**:每个改动文件按内容嗅探(NUL 字节启发式,与 git 一致)判断是否可文本预览——二进制文件(图片、exe 等)不显示「查看」按钮(悬停提示「二进制文件,无法查看文本内容」);已删除/暂存后无副本的文件用 `git diff --numstat`(二进制条目 `-\t-`)判断。
|
|
253
|
+
- **中文文件名兼容性修复**:git 默认 `core.quotepath` 会把中文路径输出成八进制转义的引号串(如 `"\346\270\270…md"`),导致改动列表与 diff 头部的中文文件名显示成乱码。现在所有 git 调用统一注入 `-c core.quotepath=false`(直接输出 UTF-8 路径),并新增 `parseGitPath()` 反转义兜底——改动列表、`ls-files -z`、`diff --name-only`、`git diff`/`git show` 头部路径等解析点全覆盖。
|
|
254
|
+
- 新增 `tools/verify-cn-paths.test.mjs` 回归测试(中文路径解析、文本/二进制可查看性、新增文件 diff 生成、已删除文件判断)。
|
|
255
|
+
|
|
256
|
+
### v1.10.1(历史)
|
|
201
257
|
本次更新(修复 better-sidebar 集成与「未安装 better-sidebar」时入口的若干问题):
|
|
202
258
|
|
|
203
259
|
- **修复:装了 dsh-better-sidebar 后,右上角「代码管理」按钮仍残留**。根因:未装 better-sidebar 时的降级入口此前只给 ReactDOM 降级路径赋了 `entryUnmount`,slots 路径漏了——导致切到「侧边栏 Tab」形态时 header 入口没被拆掉。现已把 `slots.inject` 返回的 disposer 记进 `entryUnmount`,切到 Tab 时正确拆除(顺带修正同类清理逻辑)。
|