dsh-github-flow 0.3.0 → 0.5.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.
Files changed (121) hide show
  1. package/README.en.md +287 -143
  2. package/README.md +270 -125
  3. package/docs/UPGRADE-NOTES.md +12 -9
  4. package/docs/architecture.md +126 -126
  5. package/lib/api/routes-actions.js +249 -0
  6. package/lib/api/routes-overview.js +94 -2
  7. package/lib/cache.d.ts +4 -0
  8. package/lib/cache.js +14 -0
  9. package/lib/client.d.ts +14 -1
  10. package/lib/client.js +4287 -2500
  11. package/lib/commands/gh.d.ts +6 -1
  12. package/lib/commands/gh.js +144 -71
  13. package/lib/executor/git-parser.d.ts +57 -0
  14. package/lib/executor/git-parser.js +255 -0
  15. package/lib/executor/platform-guide.d.ts +14 -0
  16. package/lib/executor/platform-guide.js +40 -0
  17. package/lib/executor/process-utils.d.ts +51 -0
  18. package/lib/executor/process-utils.js +162 -0
  19. package/lib/executor/version-utils.d.ts +12 -0
  20. package/lib/executor/version-utils.js +27 -0
  21. package/lib/executor.d.ts +70 -48
  22. package/lib/executor.js +371 -356
  23. package/lib/git-watcher.d.ts +36 -0
  24. package/lib/git-watcher.js +91 -0
  25. package/lib/main.js +37 -3
  26. package/lib/renderers/agent-task.d.ts +16 -0
  27. package/lib/renderers/agent-task.js +107 -0
  28. package/lib/renderers/cache.d.ts +8 -0
  29. package/lib/renderers/cache.js +66 -0
  30. package/lib/renderers/codespace.d.ts +16 -0
  31. package/lib/renderers/codespace.js +103 -0
  32. package/lib/renderers/common.d.ts +24 -0
  33. package/lib/renderers/common.js +88 -0
  34. package/lib/renderers/discussion.d.ts +16 -0
  35. package/lib/renderers/discussion.js +101 -0
  36. package/lib/renderers/gist.d.ts +15 -0
  37. package/lib/renderers/gist.js +99 -0
  38. package/lib/renderers/issue.d.ts +4 -0
  39. package/lib/renderers/issue.js +70 -0
  40. package/lib/renderers/label.d.ts +4 -0
  41. package/lib/renderers/label.js +48 -0
  42. package/lib/renderers/markdown.d.ts +19 -32
  43. package/lib/renderers/markdown.js +19 -624
  44. package/lib/renderers/pr.d.ts +4 -0
  45. package/lib/renderers/pr.js +107 -0
  46. package/lib/renderers/project.d.ts +20 -0
  47. package/lib/renderers/project.js +128 -0
  48. package/lib/renderers/release.d.ts +4 -0
  49. package/lib/renderers/release.js +74 -0
  50. package/lib/renderers/repo.d.ts +4 -0
  51. package/lib/renderers/repo.js +149 -0
  52. package/lib/renderers/ruleset.d.ts +4 -0
  53. package/lib/renderers/ruleset.js +74 -0
  54. package/lib/renderers/run.d.ts +4 -0
  55. package/lib/renderers/run.js +79 -0
  56. package/lib/renderers/skill.d.ts +34 -0
  57. package/lib/renderers/skill.js +241 -0
  58. package/lib/renderers/status.d.ts +28 -0
  59. package/lib/renderers/status.js +176 -0
  60. package/lib/telemetry.d.ts +70 -0
  61. package/lib/telemetry.js +161 -0
  62. package/lib/tools/agent-task.d.ts +54 -0
  63. package/lib/tools/agent-task.js +135 -0
  64. package/lib/tools/cache.d.ts +64 -0
  65. package/lib/tools/cache.js +186 -0
  66. package/lib/tools/codespace.d.ts +51 -0
  67. package/lib/tools/codespace.js +154 -0
  68. package/lib/tools/discussion.d.ts +70 -0
  69. package/lib/tools/discussion.js +195 -0
  70. package/lib/tools/gist.d.ts +155 -0
  71. package/lib/tools/gist.js +190 -0
  72. package/lib/tools/help.js +214 -13
  73. package/lib/tools/image-utils.d.ts +8 -0
  74. package/lib/tools/image-utils.js +34 -0
  75. package/lib/tools/issue.d.ts +8 -1
  76. package/lib/tools/issue.js +26 -4
  77. package/lib/tools/label.d.ts +80 -0
  78. package/lib/tools/label.js +237 -0
  79. package/lib/tools/pr.d.ts +8 -0
  80. package/lib/tools/pr.js +48 -3
  81. package/lib/tools/project.d.ts +80 -0
  82. package/lib/tools/project.js +241 -0
  83. package/lib/tools/repo.js +13 -1
  84. package/lib/tools/ruleset.d.ts +80 -0
  85. package/lib/tools/ruleset.js +177 -0
  86. package/lib/tools/skill.d.ts +24 -1
  87. package/lib/tools/skill.js +115 -5
  88. package/lib/tools/status.d.ts +40 -0
  89. package/lib/tools/status.js +58 -0
  90. package/lib/types.d.ts +44 -0
  91. package/lib/ui/auth-guide-card.d.ts +4 -0
  92. package/lib/ui/auth-guide-card.js +161 -0
  93. package/lib/ui/branch-selector.d.ts +10 -0
  94. package/lib/ui/branch-selector.js +163 -0
  95. package/lib/ui/commit-modal.d.ts +8 -0
  96. package/lib/ui/commit-modal.js +219 -0
  97. package/lib/ui/help-modal.d.ts +15 -0
  98. package/lib/ui/help-modal.js +202 -0
  99. package/lib/ui/icons.d.ts +7 -0
  100. package/lib/ui/icons.js +53 -0
  101. package/lib/ui/network-banner.d.ts +10 -0
  102. package/lib/ui/network-banner.js +54 -0
  103. package/lib/ui/storage.d.ts +35 -0
  104. package/lib/ui/storage.js +158 -0
  105. package/lib/ui/styles.d.ts +6 -0
  106. package/lib/ui/styles.js +1544 -0
  107. package/lib/ui/sync-settings-modal.d.ts +11 -0
  108. package/lib/ui/sync-settings-modal.js +350 -0
  109. package/lib/ui/sync-status-badge.d.ts +8 -0
  110. package/lib/ui/sync-status-badge.js +64 -0
  111. package/lib/ui/upgrade-card.d.ts +7 -0
  112. package/lib/ui/upgrade-card.js +222 -0
  113. package/lib/ui/utils.d.ts +45 -0
  114. package/lib/ui/utils.js +226 -0
  115. package/lib/ui/workspace-panel.d.ts +4 -0
  116. package/lib/ui/workspace-panel.js +489 -0
  117. package/lib/upgrade-manager.d.ts +5 -1
  118. package/lib/upgrade-manager.js +24 -1
  119. package/lib/version.d.ts +1 -1
  120. package/lib/version.js +1 -1
  121. package/package.json +2 -2
@@ -10,8 +10,8 @@
10
10
 
11
11
  | # | 文件 | 位置 | 当前值 | 说明 |
12
12
  |---|---|---|---|---|
13
- | 1 | [package.json](../package.json) | 第 3 行 `"version": "0.3.0"` | `0.3.0` | npm 发布版本、CI 取版来源 |
14
- | 2 | [src/version.ts](../src/version.ts) | 第 9 行 `CURRENT_PLUGIN_VERSION = '0.3.0'` | `'0.3.0'` | 运行时版本比较基准(假横幅的教训来源) |
13
+ | 1 | [package.json](../package.json) | 第 3 行 `"version": "0.5.0"` | `0.5.0` | npm 发布版本、CI 取版来源 |
14
+ | 2 | [src/version.ts](../src/version.ts) | 第 9 行 `CURRENT_PLUGIN_VERSION = '0.5.0'` | `'0.5.0'` | 运行时版本比较基准(假横幅的教训来源) |
15
15
 
16
16
  **两处必须同值**。`pnpm run build` 会硬校验([scripts/build.mjs](../scripts/build.mjs) 的
17
17
  `assertVersionConsistency`),不一致直接构建失败——但不要依赖拦截,发版前手动核对。
@@ -41,28 +41,28 @@
41
41
  | # | 机制 | 说明 |
42
42
  |---|---|---|
43
43
  | 9 | CI 取版(.github/workflows/npm-publish.yml:62) | `VERSION=$(node -p "require('./package.json').version")`——从 package.json 读,无硬编码 |
44
- | 10 | Git tag | `git tag v0.3.0` 手动打,值必须 = package.json 版本(tag 与 package.json 不一致时:CI 发布的 npm 版本以 package.json 为准,GitHub Release 标题以 tag 为准,出现两者错位) |
44
+ | 10 | Git tag | `git tag v0.5.0` 手动打,值必须 = package.json 版本(tag 与 package.json 不一致时:CI 发布的 npm 版本以 package.json 为准,GitHub Release 标题以 tag 为准,出现两者错位) |
45
45
 
46
46
  ## 五、发版完整流程(含版本修改)
47
47
 
48
48
  ```powershell
49
49
  # 1. 改版本(两处同值)
50
- # package.json → "version": "0.3.0"
51
- # src/version.ts → CURRENT_PLUGIN_VERSION = '0.3.0'
50
+ # package.json → "version": "0.5.0"
51
+ # src/version.ts → CURRENT_PLUGIN_VERSION = '0.5.0'
52
52
 
53
53
  # 2. 文档已用占位符(npm-publish-guide 示例、README 安装命令),发版无需改文档版本号
54
54
 
55
55
  # 3. 构建(版本一致性校验在此拦截漏改)+ 全量测试
56
56
  pnpm run build
57
- pnpm test # 11 阶段全绿
57
+ pnpm test # 全量测试全绿
58
58
 
59
59
  # 4. 本机 e2e(必须先重启 DSH 桌面进程——Node 模块缓存,软链重建不注入运行中进程)
60
- # 重启后验证:GET /api/github/check-update 的 currentVersion = 0.3.0
60
+ # 重启后验证:GET /api/github/check-update 的 currentVersion = 0.5.0
61
61
 
62
62
  # 5. 提交 + 打 tag + 推送(tag 值 = package.json 版本)
63
63
  git add -A
64
- git commit -m "chore(release): v0.3.0"
65
- git tag v0.3.0
64
+ git commit -m "chore(release): v0.5.0"
65
+ git tag v0.5.0
66
66
  git push origin master --tags
67
67
  # CI(npm-publish.yml)自动:构建→发布 npm→创建 GitHub Release
68
68
 
@@ -79,6 +79,8 @@ git push origin master --tags
79
79
  | tag 与 npm 版本错位风险 | CI 以 package.json 为准、Release 标题以 tag 为准 | 第五节流程强调 tag = package.json |
80
80
  | pr checks 完全不可用(Issue #3) | 字段集混入 REST API 字段名(conclusion/detailsUrl),gh 从未支持 | 测试写死合法九字段基准清单(phase1);新增 --json 字段时对照 `gh <cmd> --json zzz` 错误提示核对 |
81
81
  | 无 gh 环境刷新永久卡死 | 前端数据链路 fetch 无 AbortController,代理劫持回环时挂起 | 全部数据 fetch 绑 signal(phase7 第 8 节锚点);新增前端 fetch 必须带 signal 或显式超时 |
82
+ | React Hook 变量提升 undefined 崩溃 | containerRef 写在 useEffect 下方,组件挂载读取 containerRef.current 抛致命 TypeError 白屏 | 必须在组件生命周期最顶部声明所有 useRef;访问点强制加 `containerRef && containerRef.current` 守卫 |
83
+ | 前端模块目录命名解析冲突 | 在包内创建同名 `src/client/` 目录导致模块解析器在解析 `exports["./client"]` 时发生歧义报错 | 前端拆分子模块统一下沉至独立命名空间(如 `src/ui/`),杜绝同名文件与目录冲突 |
82
84
 
83
85
  ## 七、环境陷阱速查(升级验证时必读)
84
86
 
@@ -91,3 +93,4 @@ git push origin master --tags
91
93
  | 沙箱解除后的测试盲区 | EPERM SKIP 分支掩盖真实缺陷 | CI/真机全绿 ≠ 本机沙箱绿;phase3/5 曾双双漏检 |
92
94
  | gh --json 字段集漂移 | Unknown JSON field 直接报错 | 新增字段前用 `gh <cmd> --json zzz` 探测合法集;不跨域复制字段名(checks≠run) |
93
95
  | PowerShell 5.1 默认策略 | 唤起终端报 profile 禁止运行红错 | 唤起命令带 -NoProfile(Windows 自带基线优先) |
96
+ | 浏览器单文件脚本环境 | 客户端产物带未剥除的 export/import 导致语法报错白屏 | build.mjs 聚合器自动剔除 export/import 并将子模块内联注入单一闭包 |
@@ -25,55 +25,76 @@
25
25
  │ │ - AI_AGENT=dsh 注入 [gh 官方 agent 识别·可配置开关] │ │
26
26
  │ │ - UpdateChecker (源可选探测 + 24h 缓存 + Fail-Safe) │ │
27
27
  │ │ - UpgradeManager (跨平台自适应 + 互斥锁 + macOS PATH 补全) │ │
28
- │ │ - spawnWithStdin (密文通道: spawn+stdin.end + kill 超时) │ │
28
+ │ │ - ProxyManager (环境变量集中路由 + 统一网络分发) │ │
29
+ │ │ - 模块化子系统 (src/executor/): │ │
30
+ │ │ · git-parser.ts (无 I/O 纯文本解析纯函数) │ │
31
+ │ │ · version-utils.ts (语义化版本比较纯函数) │ │
32
+ │ │ · process-utils.ts (spawnWithStdin 密文流控与字节截断) │ │
33
+ │ │ · platform-guide.ts (跨平台安装引导与升级建议) │ │
29
34
  │ └──────┬───────────────────────┬────────────────────────┬──────┘ │
30
35
  │ │ │ │ │
31
36
  │ ▼ ▼ ▼ │
32
37
  │ ┌──────────────────┐ ┌──────────────────┐ ┌───────────────────────┐ │
33
- │ │ 9 大 Agent 工具 │ │ 人类 Slash 指令 │ │ Host HTTP WebServer │ │
38
+ │ │ 18 大 Agent 工具 │ │ 人类 Slash 指令 │ │ Host HTTP WebServer │ │
34
39
  │ │ (defineTool DSL)│ │ /gh status │ │ (Effect Disposer 清理)│ │
35
- │ │ - pr (+ready· │ │ /gh upgrade │ │ - /api/github/overview│ │
36
- │ │ revert·update)│ │ /gh help │ │ - /api/github/action │ │
37
- │ │ - issue (+delete│ └──────────────────┘ │ - /api/github/refresh │ │
38
- │ │ ·transfer·pin·│ │ - /check-update (并行)│ │
39
- │ │ lock·status) │ │ - /upgrade (一键自动) │ │
40
- │ │ - run (+workflow│ │ - /update-settings │ │
41
- │ │ 系列·download)│ (workflow_enable/disable │ │ - /proxy (全局代理) │ │
42
- │ │ - repo (+search │ 启停·list/view·download) │ - /auth (轻量探针) │ │
43
- │ │ 三域+read_ │ └──────────┬────────────┘ │
44
- │ │ file &read_dir)│ │ │
45
- │ │ - api (逃生门) │ (search 三域=issues/prs/commits; │ │
46
- │ │ - release │ read_file/read_dir 免clone读取) │ │
47
- │ │ - secret (stdin │ │ │
48
- │ │ +variable 域) │ │ │
49
- │ │ - skill │ │ │
50
- │ │ - help (元指南) │ │ │
51
- │ └────────┬─────────┘ │ │
52
- │ │ │ │
40
+ │ │ - pr (+attach) │ │ /gh upgrade │ │ - /api/github/overview│ │
41
+ │ │ - issue (+attach│ │ /gh help │ │ - /api/github/action │ │
42
+ │ │ - run (workflow)│ └──────────────────┘ │ - /api/github/refresh │ │
43
+ │ │ - repo (read/sr)│ │ - /api/github/branches│ │
44
+ │ │ - api (逃生门) │ (workflow_enable/disable │ │ - /branch-switch │ │
45
+ │ │ - release │ 启停·list/view·download) │ - /api/github/git- │ │
46
+ │ │ - secret & var │ │ watch (定向监听) │ │
47
+ │ │ - skill (+pub/up│ (search 三域=issues/prs/ │ - /check-update (并行)│ │
48
+ │ │ - label (CRUD/cl│ commits; read_file/dir) │ - /upgrade (一键自动) │ │
49
+ │ │ - ruleset(check)│ │ - /update-settings │ │
50
+ │ │ - cache (治理) │ │ - /proxy (全局代理) │ │
51
+ │ │ - gist (分享) │ │ - /auth (轻量探针) │ │
52
+ │ │ - status (健康) │ └──────────┬────────────┘ │
53
+ │ │ - agent_task │ │ │
54
+ │ │ - discussion │ ▼ │
55
+ │ │ - project (v2) │ ┌───────────────────────────┐ │
56
+ │ │ - codespace(MVP)│ │ git-watcher (独立服务) │ │
57
+ │ │ - help (元指南) │ │ - .git/HEAD & index │ │
58
+ │ └────────┬─────────┘ │ - 800ms 防抖/35s 超时 │ │
59
+ │ │ └───────────────────────────┘ │
53
60
  │ ▼ │ │
54
61
  │ ┌──────────────────────────────────┐ │ │
55
- │ │ Markdown 渲染引擎 (renderers/) │ │ │
56
- │ │ - 列表表格化压缩 70%+ Token │ │ │
57
- │ │ - 状态徽章/超链接/转义防破损 │ │ │
58
- │ │ - 高危确认卡片/敏感字段隔离 │ │ │
62
+ │ │ Markdown 渲染引擎 (renderers/) │ │ │
63
+ │ │ - common.ts: 单元格清洗/通用徽章 │ │ │
64
+ │ │ - 15领域模块: pr/issue/run/repo/ │ │ │
65
+ │ │ release/skill/label/ruleset/ │ │ │
66
+ │ │ cache/gist/status/agent-task/ │ │ │
67
+ │ │ discussion/project/codespace │ │ │
68
+ │ │ - 统一门面出口 markdown.ts 兼容 │ │ │
59
69
  │ └──────────────────────────────────┘ │ │
60
- └─────────────────────────────────────────────────────────────┼───────────────┘
70
+ │ │ │ │
71
+ │ ▼ ▼ │
72
+ │ ┌───────────────────────────────────────────────────────────────────────┐ │
73
+ │ │ 遥测审计系统 (src/telemetry.ts ➔ Cordis tools/result 事件切面) │ │
74
+ │ │ - TelemetryRingBuffer (固定 200 条无锁环形队列,常驻内存 <200KB) │ │
75
+ │ │ - 实时计算 API 降级率 (Degradation Rate) 与工具链健康分 (0-100 分) │ │
76
+ │ └───────────────────────────────────────────────────────────────────────┘ │
77
+ └─────────────────────────────────────────────────────────────┬───────────────┘
61
78
  │
62
79
  ┌─────────────────────────────────────────────────────────────┼───────────────┐
63
80
  │ DSH Web Client ▼ │
64
81
  │ │
65
- │ ┌──────────────────────────────────┐ ┌─────────────────────────────┐ │
66
- │ │ 全局驾驶舱 (Main Slot) │ │ 右侧栏面板 (Right Sidebar) │ │
67
- │ │ - 账号全局所有 GitHub 仓库 │ │ - 五 Tab 互斥 (Git/未提交/ │ │
68
- │ │ - 本地工作区矩阵透视 │ │ PR/Issues/Actions) │ │
69
- │ │ - 三维待办 Issues (药丸筛选) │ │ - Git 记录与分支同步全景 │ │
70
- │ │ - 用户提单 / 分配待办 / 我发起 │ │ - 提交详情居中弹窗 (可滑动)│ │
71
- │ │ - 顶部升级通知横幅 (Banner) │ │ - 下滑自动分页加载更多 │ │
72
- │ │ - 动态数据新鲜度胶囊与 SWR 缓存│ │ - 快捷操作网格与设置入口 │ │
73
- │ │ - 四分区设置弹窗 (同步/代理/ │ │ - 官方标准 Git 矢量图标 │ │
74
- │ │ 更新源/关于) │ │ - 「插件」身份徽章 (直达) │ │
75
- │ │ - 「插件」身份徽章 (关于直达) │ │ │ │
76
- │ └──────────────────────────────────┘ └─────────────────────────────┘ │
82
+ │ ┌─────────────────────────────────────────────────────────────────────┐ │
83
+ │ │ 模块化 UI 架构 (src/ui/ ➔ 经 scripts/build.mjs 拓扑聚合单一 Bundle) │ │
84
+ │ │ │ │
85
+ │ │ · styles.ts (1290行自适应 CSS, 构建期紧凑压缩) │ │
86
+ │ │ · icons.ts (Octocat, Git 官方菱形分支矢量组件, 插件徽标) │ │
87
+ │ │ · storage.ts (LocalStorage SWR 状态机与偏好存储) │ │
88
+ │ │ · components/ (分支下拉/认证引导/升级通知/离线横幅/状态胶囊) │ │
89
+ │ │ · modals/ (Commit 详情弹窗 / 4分区全局设置弹窗) │ │
90
+ │ │ · panels/ (首页全景大面板 workspace-panel.ts) │ │
91
+ │ │ │ │
92
+ │ │ 核心组装入口 (src/client.ts, ~1,260 行高内聚): │ │
93
+ │ │ - applyTabState (纯 DOM 互斥状态应用, 满足单测白盒契约) │ │
94
+ │ │ - renderGithubRepoView (五 Tab 核心视图: Git/未提交/PR/Issue/Run) │ │
95
+ │ │ - GithubRightbarBody (右侧栏主体, 状态引用解耦与时序安全守护) │ │
96
+ │ │ - apply(ctx) (Cordis Client 插件安装入口与槽位注入) │ │
97
+ │ └─────────────────────────────────────────────────────────────────────┘ │
77
98
  └─────────────────────────────────────────────────────────────────────────────┘
78
99
  ```
79
100
 
@@ -93,100 +114,79 @@
93
114
 
94
115
  ### 2.3 上下文 Token 保护与防御性输出包装 (Token Budget Guard)
95
116
  - 所有的 `gh` 查询原生采用 `--json <fields>` 结构化投影;
96
- - 对长文本输出(如大型 PR 的完整 `diff`、CI 失败步骤日志)设置安全截断阈值(默认 24KB),采用码点安全切割与二分查找字节截断,保留头尾关键上下文并添加显式截断标记,杜绝撑爆模型上下文;
97
- - 列表与详情输出经独立 Markdown 渲染引擎(`src/renderers/markdown.ts`)转化为高密度表格与卡片(带状态徽章、可点击超链接与竖线转义防护),实测 20 条 PR 列表输出压缩 70%+ Token;
117
+ - 对长文本输出(如大型 PR 的完整 `diff`、CI 失败步骤日志)设置安全截断阈值(默认 24KB),采用码点安全切割与二分查找字节截断(`src/executor/process-utils.ts`),保留头尾关键上下文并添加显式截断标记,杜绝撑爆模型上下文;
118
+ - 列表与详情输出经独立 Markdown 渲染引擎(`src/renderers/` 7 大领域模块)转化为高密度表格与卡片(带状态徽章、可点击超链接与竖线转义防护),实测 20 条 PR 列表输出压缩 70%+ Token;
98
119
  - 所有 Agent 工具的输出统一经过归一化,列表自动打包为 `{ items, count }`,标量打包为 `{ result }`,100% 严丝合缝契合 DSH 工具网关模式约束;
99
- - **gh 版本守卫降级链(runGuarded)**:preview 命令与新特性按 `minVersion` 门槛路由——版本达标直通主命令、不足走 `fallback` 降级链路(结果携带 `degraded/degradedReason` 结构化标注,**降级不是静默的**,渲染层对 degraded 结果显式追加链路说明)、无降级时报错附平台升级指引;版本探测自身失败 fail-open 直通(守卫是路由优化不是安全边界)。版本比较采用数值分段(杜绝 `'2.96.0' > '2.100.0'` 字典序陷阱),探测结果 30s TTL 缓存且只缓存成功值;
120
+ - **gh 版本守卫降级链(runGuarded)**:preview 命令与新特性按 `minVersion` 门槛路由——版本达标直通主命令、不足走 `fallback` 降级链路(结果携带 `degraded/degradedReason` 结构化标注,**降级不是静默的**,渲染层对 degraded 结果显式追加链路说明)、无降级时报错附平台升级指引;版本探测自身失败 fail-open 直通(守卫是路由优化不是安全边界)。版本比较采用数值分段(`src/executor/version-utils.ts`,杜绝 `'2.96.0' > '2.100.0'` 字典序陷阱),探测结果 30s TTL 缓存且只缓存成功值;
100
121
  - **AI_AGENT 识别信号注入**:每次 gh 子进程启动注入 `AI_AGENT=dsh`(gh detect.go 最高优先级通用信号)——gh ≥2.99 自动切换 text-only spinner、≥2.100 命令误用时打印完整 help(模型可据此自我纠正)、telemetry 归因到 dsh;旧版 gh 忽略该变量零副作用。经 `agentEnvInjection` 配置开关(默认开启)可恢复 gh 原生行为。
101
122
 
102
123
  ### 2.3.1 高危操作确认与敏感值安全通道 (Safety Confirmation & Secret stdin Channel)
103
- - 不可逆写操作(`merge` / `close` / `issue delete`(物理删除)/ `issue transfer`(跨仓库迁移)/ `pr revert`(远端创建反向 PR)/ `release delete` / clobber 覆盖上传 / `secret delete` / `skill install`)强制要求 `confirm: true` 显式参数,未确认时仅返回影响评估卡片,不产生任何远端或本地副作用;
104
- - 密钥明文仅经子进程标准输入传递(`spawnWithStdin` 通道:`spawn` + `stdin.end(data)` 半关闭写入——`execFile` 的 `input` 选项在实测环境从不真正写入管道,密文通道此前从未生效过),全程不出现在命令行参数、进程列表与工具输出中;渲染层对 secret 输出采用独立实现,从结构上隔离「绝不渲染 value 字段」这条安全红线。secret 与 variable(CI 明文,get 可回显)的渲染走**两个物理独立的函数**——安全语义靠函数边界而非同一函数的分支隔离,防未来重构互相污染。
124
+ - 不可逆写操作(`merge` / `close` / `issue delete`(物理删除)/ `issue transfer`(跨仓库迁移)/ `pr revert`(远端创建反向 PR)/ `release delete` / clobber 覆盖上传 / `secret delete` / `skill install` / `skill publish`(创建 Release)/ `label delete`(物理删除且解绑)/ `cache delete all`(全量清空缓存)/ `gist delete`(代码片段永久删除)/ `codespace delete`(销毁开发机)/ `project item-delete`(移除看板条目))强制要求 `confirm: true` 显式参数,未确认时仅返回影响评估卡片,不产生任何远端或本地副作用;
125
+ - 密钥明文仅经子进程标准输入传递(`spawnWithStdin` 通道:`spawn` + `stdin.end(data)` 半关闭写入),全程不出现在命令行参数、进程列表与工具输出中;渲染层对 secret 输出采用独立实现,从结构上隔离「绝不渲染 value 字段」这条安全红线。
105
126
 
106
127
  ### 2.3.2 产物落盘纪律 (Artifact Download Discipline)
107
- - **目录固定派生,永不暴露路径参数**:构建产物下载(`run download` 等)的落盘目录由插件从 `~/.dsh/data/dsh-github-flow/artifacts/<owner>/<repo>/<run_id>/` 三级固定派生,不向调用方暴露任何目录参数——这是 GHSA-39wj-f2f4-978v(gh <2.102 符号链接路径穿越)的核心防线:用户无法注入 `../` 或符号链接目标,攻击面收敛到唯一一个 `mkdirSync(recursive)` 调用点,且目录天然按仓库与 run 隔离、可整体清理;
108
- - **低版本安全提示而非硬拒绝**:gh <2.102 时下载仍可执行(受控仓库场景是合理需求),但返回值携带 `securityNote` 升级指引;需要自定义落盘位置的场景显式引导经 `github_api` 手动拉取;
128
+ - **目录固定派生,永不暴露路径参数**:构建产物下载(`run download` 等)的落盘目录由插件从 `~/.dsh/data/dsh-github-flow/artifacts/<owner>/<repo>/<run_id>/` 三级固定派生,不向调用方暴露任何目录参数——这是 GHSA-39wj-f2f4-978v(gh <2.102 符号链接路径穿越)的核心防线;
129
+ - **低版本安全提示而非硬拒绝**:gh <2.102 时下载仍可执行,但返回值携带 `securityNote` 升级指引;需要自定义落盘位置的场景显式引导经 `github_api` 手动拉取;
109
130
  - **下载后零本地符号化操作**:插件对落盘产物仅做递归枚举(相对路径 + 大小清单),不执行链接、移动或执行类操作。
110
- 未来任何新增下载类能力(如 gist 资产)必须引用本节纪律,而非各自重述。
111
-
112
- ### 2.4 原生浅色/深色主题自适应与快捷操作网格
113
- - 全面对齐 DSH 官方 DSW 语义设计变量,基于 `body[data-ds-dark-theme]` 驱动无闪烁双模式切换;
114
- - 右侧栏快捷操作栏彻底废弃失效的阻塞弹窗,全面采用官方直达模式(查看所有 Issues、查看 PRs、Compare / New Issue),享有 100% 官方富文本体验。
115
-
116
- ### 2.5 Cordis 微内核标准规范
117
- - **按需依赖声明**:显式声明核心必需服务 `['tools', 'commands']`,防止因无头运行环境缺少 `webServer` 或 `workspaceRegistry` 导致插件陷入 `PENDING` 假死状态;
118
- - **优雅动态探测**:通过 `if (ctx.webServer)` 探测环境,有 Web UI 服务时动态挂载路由,无 Web 环境时无缝降级为纯 CLI 工具;
119
- - **生命周期 Effect 闭环**:所有 HTTP 路由与命令注册均持有 Disposer 清理函数,插件热重载或重新挂载时自动彻底注销,零内存泄漏;
120
- - **配置自校验与服务暴露**:基于 Standard Schema 规范实现强类型校验与默认值注入,通过 `ctx.provide('github', executor)` 向生态插件暴露单例服务。
121
-
122
- ### 2.6 三态环境诊断与交互引导状态机 (Setup & Authentication Lifecycle Guard)
123
- - **三态状态模型 (Three-State Machine)**:将环境就绪判定严格划分为 `NOT_INSTALLED`(未安装 CLI)、`NOT_LOGGED_IN`(已安装未登录)、`AUTHENTICATED`(已认证)三态,彻底消除“把未安装当作未登录”的状态屏蔽隐患;
124
- - **平台自适应安装策略**:后端探测到 `ENOENT` 时根据 `process.platform` 组装对应平台的安装命令(Windows: `winget`,macOS: `brew`,Linux: `apt/dnf`)与官方安装包地址;
125
- - **安全辅助与白名单终端唤起**:Web 端提供一键命令复制,后端 `/api/github/action` 提供安全白名单唤起接口,避免在前端模拟复杂交互式 PTY 的脆弱性;
126
- - **焦点感知自愈 (Focus Auto-Recovery)**:前端挂载 `window.focus` 事件监听,用户在外部浏览器或终端完成认证后切回 DSH 界面,自动静默重新探测并无缝更新 UI,实现零摩擦闭环体验。
127
-
128
- ### 2.7 多维 Issue 身份判定与并发聚合引擎 (Multi-Dimensional Issue Engine)
129
- - **多重身份决策矩阵**:基于当前登录用户 `currentUser`(`auth.user`)对 Issue 执行身份归类:
130
- - `reported`(用户提单):`repoOwner === currentUser && author != currentUser`(外部访客在本人维护的仓库中提出的反馈);
131
- - `assigned`(分配待办):`assignees.includes(currentUser)`(指派给本人的任务,跨仓库通用);
132
- - `created`(我发起的):`author === currentUser`(本人亲自创建的 Issue)。
133
- - **三路并发搜索与 URL 去重**:后端在 `/api/github/global-overview` 中通过 `Promise.all` 同时发起 `--owner=@me`、`--assignee=@me`、`--author=@me` 检索,按 URL 唯一性合并去重并按最后更新时间统一降序排列;
134
- - **双端视图无缝打标**:驾驶舱提供四态响应式药丸筛选(全部/用户提单/指派待办/我发起的),右侧栏直接常驻展现当前工作区所属 Issue 任务清单与状态徽章。
135
-
136
- ### 2.8 智能版本检测与跨平台一键升级引擎 (Update & Upgrade Engine)
137
- - **检查与 gh 链路完全并行**:
138
- - 前端版本检查与 gh 环境探测(安装/登录/业务数据)**零依赖并行发起**(挂载即触发,仅 300ms 微延迟避让首屏),不串行等待概览返回,gh 环境异常时升级横幅照常展示;
139
- - 服务端 `inFlightPromise` 请求合流 + 24 小时缓存,多面板同时挂载零请求风暴。
140
- - **更新源三态可选(UI 持久化 store 优先)**:
141
- - 三态单选:官方源(默认)/ 国内镜像 npmmirror / 关闭自动检查;
142
- - 持久化于 `~/.dsh/data/dsh-github-flow/update-settings.json`,保存即热切换并失效 24h 缓存(防"切换无效"感知);
143
- - **单源严格不互备**:显式选择的源不静默回落——镜像同步滞后正是选官方的理由,探测失败如实返回;
144
- - 「关闭检查」语义为关自动提示不关能力:`/gh upgrade`(force)与一键升级路由不受熔断;
145
- - 一键升级的 `NPM_CONFIG_REGISTRY` 跟随所选源(注入查询函数而非静态值,切源实时生效)。
146
- - **跨平台 Shell 调度与 macOS PATH 自愈**:
147
- - **Windows**:采用 `cmd.exe /d /s /c`,彻底规避 PowerShell 5.1 不支持 `||` 导致的语法崩溃,启动仅 ~10ms;
148
- - **macOS / Linux**:采用用户 Default Shell(`/bin/zsh` 或 `/bin/bash`);
149
- - **macOS PATH 智能补全**:针对 Mac 桌面端由 GUI (Finder/Dock) 启动不继承 `.zshrc` 的痛点,自动将当前 Node 目录、Apple Silicon `/opt/homebrew/bin` 及 Intel `/usr/local/bin` 动态注入 PATH 前端,确保 100% 发现 npm/pnpm。
150
- - **环境自省与源码保护防线 (Dev-Link Safe)**:
151
- - 自动识别当前是否处于本地 Git 源码软链接模式(`link:`),若是则自动阻止 npm 覆盖,保护工作区源码;
152
- - 自动识别桌面版 Profile 目录,无全局 CLI 时直接在 `~/.dsh/profiles/desktop` 下就地更新,无需用户具备终端知识。
153
- - **并发互斥锁与重启提示闭环**:
154
- - 内存互斥锁防止连续点击导致包管理器 lockfile 竞争;
155
- - 升级完成后明确提醒用户重启 DSH 服务以完全加载最新后端模块,同时支持立即刷新页面预览新界面。
156
-
157
- ### 2.9 客户端持久化与 SWR (Stale-While-Revalidate) 极速直出架构
158
- - **0ms 首屏瞬间直出机制**:
159
- - 在全景驾驶舱组件挂载时,`data` 初始值直接通过 `React.useMemo` 从 `localStorage` 读取上一次保存的历史快照;
160
- - 消除传统加载时全屏阻塞卡顿,彻底抹平每次打开等待 8~15 秒的痛点,达到即开即用的丝滑体感。
161
- - **透明数据新鲜度与状态胶囊 (SyncStatusBadge)**:
162
- - 胶囊状态精准映射:`[⏳ 后台同步中...]`、`[✅ 已是最新 (15:30)]`、`[📦 本地快照 (X分钟前)]`、`[⚠️ 同步超时已保留缓存]`;
163
- - 支持人性化相对时间推导(刚刚、X分钟前、X小时前、X天前),消除用户对数据时效性的疑虑。
164
- - **设置中心 (GlobalSyncSettingsModal) 四分区**:
165
- - **🔄 数据同步**:`⚡ 秒开模式 (SWR, 默认)` / `📋 仅手动刷新 (Manual Only)` 两态选择;
166
- - **🌐 网络代理**:代理配置即时全局生效(写 proxy.json + 重应用 dispatcher,零插件重载);
167
- - **⬆️ 更新设置**:更新源三态选择(官方/镜像/关闭),保存即热切换并真实验证;
168
- - **ℹ️ 关于**:插件身份信息(版本/仓库/npm/协议/求 Star);
169
- - 弹窗支持 `initialSection` 直开指定分区——插件徽标点击直开「关于」,齿轮默认「数据同步」。
170
- - **插件身份标识闭环**:
171
- - 面板标题(驾驶舱/右侧栏)带「插件」徽标,明确标注界面由第三方插件 `dsh-github-flow` 提供(非 DSH / GitHub 官方);
172
- - 徽标点击派发全局事件打开「关于」弹窗(不直接跳浏览器);多宿主同挂载时经可见性守卫防双层弹窗叠层;
173
- - 右侧栏同样提供 ⚙️ 设置按钮,与主页复用同一弹窗组件,保存经事件总线双侧实时对齐。
174
- - **离线极端容灾保护 (Fail-Safe Offline Guard)**:
175
- - 后台静默重验若遭遇断网、弱网或进程超时,界面平滑降级,**100% 保持旧数据完整可用**,绝不回退至空白占位或报错中断。
176
- - **数据链路超时防线**:
177
- - 全部前端数据链路 fetch 绑定 `AbortController`(45s 兜底;登录探测 10s)——代理劫持回环地址等极端场景下用户得到明确超时出口,绝不永久转圈(未安装 gh 用户的刷新卡死修复);
178
- - 后端 `gh` 探测毫秒级返回 ENOENT/安装引导,前端安装引导卡(AuthGuideCard)承载唤起终端(stdio ignore,无 profile)等自愈出口。
179
-
180
- ### 2.10 右侧栏五 Tab 互斥与本地 Git 状态全景架构 (Right Sidebar Tabs & Local Git Engine)
181
- - **五 Tab 响应式互斥布局**:
182
- - 将右侧栏原本纵向堆叠的 PR / Issues / Actions / Git 状态与未提交清单彻底重构成水平紧凑 Tab(Git / 未提交 / PR / Issues / Actions),默认激活 Git 记录页,首屏高度收敛 60% 以上;
183
- - 纯函数渲染约束与 DOM 级状态:`renderGithubRepoView` 坚守零 React Hooks 约束,激活态通过 `data-active-tab` 挂载在 DOM 容器上;根组件通过 `useEffect([data])` 与 `applyTabState` 联动,在 SWR 后台拉新完成触发重渲染时,自动重置回用户选择的 Tab,彻底解决后台数据刷新拽回默认 Tab 的缺陷。
184
- - **三段式提交日志与本地 0ms 秒开**:
185
- - 本地领先(待 push)、远程领先(待 pull,快照口径)与最近提交历史;
186
- - 采用 ASCII 单元/记录控制符(`%x1e` / `%x1f`)结构化解析 `git log`,一次性提取 fullSha、author、email、date、多行 body 说明与 `--stat` 文件改动统计,首屏 0ms 纯本地呈现,零网络失败风险;
187
- - 默认展示 15 条,通过右侧栏容器 `onScroll` 触底(<80px)与点击双重触发向后分页拉取,伴随实时进度计数(如 `15 / 74`)。
188
- - **内嵌模态弹窗 (CommitDetailModal)**:
189
- - 复用设置弹窗架构(`.dsh-github-modal-overlay` + `.dsh-github-modal-dialog`),挂载在右侧栏容器内部,天然受限于右侧栏边界居中,彻底消除传统 `<dialog>` 顶层穿透全屏居中的越界问题;
190
- - 弹窗外框限制 `max-height: 84vh; overflow: hidden;`,正文区域 `flex: 1; min-height: 0; overflow-y: auto;`,完美支持上下滑动浏览数十行详细正文与修改文件统计,支持 Esc 键与点击遮罩随手退出。
191
- - **全库统一 Git 官方矢量图标**:全量替换各处的植物/字符符号为标准 Git 菱形分支官方矢量组件(`#1296db` SVG)。
192
131
 
132
+ ---
133
+
134
+ ## 3. 工程解耦与单文件瘦身规范 (Modularization Specs)
135
+
136
+ 为彻底解决单文件臃肿过长(如旧版 `client.ts` 超过 5,200 行、`executor.ts` 超过 1,100 行)的技术债,项目已全面落地分层解耦与自包含构建规范:
137
+
138
+ ### 3.1 后端执行引擎分层 (`src/executor/`)
139
+ - [src/executor.ts](../src/executor.ts)(瘦身至 ~820 行):保留 `GhExecutor` 类核心编排(命令白名单、执行通道、认证与版本缓存),完整 Re-export 子模块符号,保持 100% 向后兼容;
140
+ - [src/executor/git-parser.ts](../src/executor/git-parser.ts):纯文本解析器(`status -sb`、`log`、`branch -a`),无 I/O、无副作用;
141
+ - [src/executor/version-utils.ts](../src/executor/version-utils.ts):语义化版本数值分段比对纯算法;
142
+ - [src/executor/process-utils.ts](../src/executor/process-utils.ts):`spawnWithStdin` 进程管道流控与 UTF-8 字符边界截断算法;
143
+ - [src/executor/platform-guide.ts](../src/executor/platform-guide.ts):跨平台 CLI 安装引导与升级命令文本生成。
144
+
145
+ ### 3.2 渲染层领域化细分 (`src/renderers/`)
146
+ - [src/renderers/markdown.ts](../src/renderers/markdown.ts):门面出口,统一聚合 Re-export 全部领域子模块;
147
+ - [src/renderers/common.ts](../src/renderers/common.ts):表格单元格字符净化、各类状态药丸 Emoji 徽章、API 降级透明注解;
148
+ - 15 大领域独立渲染模块:`pr.ts` / `issue.ts` / `run.ts` / `repo.ts` / `release.ts` / `skill.ts` / `label.ts` / `ruleset.ts` / `cache.ts` / `gist.ts` / `status.ts` / `agent-task.ts` / `discussion.ts` / `project.ts` / `codespace.ts`,彻底实现高内聚低耦合,避免跨工具改动冲突。
149
+
150
+ ### 3.3 本地 Git 元数据监听服务 (`src/git-watcher.ts`)
151
+ - 独立底层服务模块,彻底剥离路由控制器内部的物理文件系统监听与定时器杂糅;
152
+ - 靶向非递归监听 `.git/HEAD` 与 `.git/index`,内置 800ms 防抖合并、35s 超时熔断与物理句柄安全释放;
153
+ - 使 [src/api/routes-actions.ts](../src/api/routes-actions.ts) 彻底移除对 `node:fs` 与 `node:path` 的直接依赖,路由函数回归纯粹的 HTTP 请求接收与响应。
154
+
155
+ ### 3.4 前端客户端解耦与自包含 Bundle 机制 (`src/ui/` + `src/client.ts`)
156
+ - **源码物理剥离**:
157
+ - [src/client.ts](../src/client.ts)(由 5,290 行直降至 **1,263 行,瘦身 76%**):仅保留右侧栏核心协同 `renderGithubRepoView` 与 `GithubRightbarBody` 及插件入口;
158
+ - 12 个独立子模块下沉至 [src/ui/](../src/ui/) 目录(样式 1,295 行、全景大面板 732 行、设置弹窗 561 行、业务卡片 60~290 行);
159
+ - **命名空间防护**:
160
+ - 严禁在与 `package.json` 的 `exports["./client"]` 同级创建名为 `client/` 的目录,统一命名为 `src/ui/` 与编译产物 `lib/ui/`,彻底杜绝模块解析器产生“同名文件 vs 目录”的歧义报错;
161
+ - **自包含 Bundle 聚合器 (`scripts/build.mjs`)**:
162
+ - 构建脚本按严格拓扑顺序将 `lib/ui/` 子模块内联注入 `lib/client.js` 的 `window.__ModuleLoader__.load` 闭包中,移除 `export` 关键字;
163
+ - 保证 `GithubRightbarBody` 位于 `GithubWorkspacePanel` 之前(满足切片测试断言);
164
+ - 对嵌入的 1,290 行纯 CSS 实施紧凑压缩,消除空行与多余注释,使编译产物从 5,282 行减至 4,008 行;
165
+ - **React Hook 时序安全防线**:
166
+ - 组件内引用的 `useRef`(如 `containerRef`)必须在组件声明最前列初始化,严禁跨行下置引发变量提升 `undefined`;所有的 Ref 访问点必须配备 `containerRef && containerRef.current` 守卫,杜绝运行时渲染崩溃。
167
+
168
+ ---
169
+
170
+ ## 4. 自动化测试体系 (Test Suite)
171
+
172
+ 项目配备了 **20 个独立阶段的全量自动化回归测试套件(`test/run-all.mjs`)**,覆盖 **880+ 项全量自动化测试断言**:
173
+ - `phase1`:Issue / Run / PR / Repo / Help 命令装配与确认门禁;
174
+ - `phase2`:Native Markdown 渲染与 Token 压缩率实测(>60% 降幅);
175
+ - `phase3`:Release 资产交付、Secret 密文管道与 Skills 检索;
176
+ - `phase4`:工具装配完整性、版本一致性拦截与模糊边界防护;
177
+ - `phase5`:网络代理配置有效性校验、环境注入与容灾降级;
178
+ - `phase6`:插件版本更新检测、多源选择与跨平台自升级调度;
179
+ - `phase7`:终端唤起真实反馈、更新源设置 UI 锚点与 45s 数据链路超时保护;
180
+ - `phase8`:图片链接提取与图片下载;
181
+ - `phase9`:README 提取与相对路径解析;
182
+ - `phase10`:版本守卫降级链(runGuarded)、AI_AGENT 注入与命令白名单;
183
+ - `phase11`:右侧栏五 Tab 响应式互斥、Git 提交记录与滑动分页;
184
+ - `phase12`:工作区物理所有权隔离、SWR 离线快照防抹杀与安全分支切换;
185
+ - `phase13`:云端定时自动同步生命周期、三选一互斥设置模型与右侧栏独占本地 git-watch 监听;
186
+ - `phase14`:github_label(标签体系CRUD与克隆)与 github_ruleset(保护策略排障);
187
+ - `phase15`:github_cache(构建缓存治理)与 github_gist(代码片段与排障留痕);
188
+ - `phase16`:github_status(全局待办大盘)与 attach_images(图片附件上传通道);
189
+ - `phase17`:github_skill publish(agentskills.io 规范自检、--fix 修复与发布闭环);
190
+ - `phase18`:github_agent_task(云端编码智能体会话)与 github_discussion(社区讨论与RFC);
191
+ - `phase19`:github_project(Projects v2 看板)、github_codespace(云端开发机)与 skill update;
192
+ - `phase20`:TelemetryRingBuffer、Cordis tools/result 事件总线运行时遥测、降级率统计与健康度看板。