@keith9681/dsh-sidebar 0.15.2

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 (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/README_EN.md +0 -0
  4. package/cordis.patch.yml +49 -0
  5. package/lib/client-editor.js +34651 -0
  6. package/lib/client-mermaid.js +200629 -0
  7. package/lib/client-registry.js +13388 -0
  8. package/lib/client-terminal.js +8904 -0
  9. package/lib/client.js +13388 -0
  10. package/lib/index.js +3959 -0
  11. package/lib/invariant.js +22 -0
  12. package/lib/types/agent-pty.d.ts +226 -0
  13. package/lib/types/browser-probe.d.ts +15 -0
  14. package/lib/types/bundle-route.d.ts +12 -0
  15. package/lib/types/client/BrowserView.d.ts +22 -0
  16. package/lib/types/client/DiffTab.d.ts +6 -0
  17. package/lib/types/client/DiffView.d.ts +51 -0
  18. package/lib/types/client/EditorHost.d.ts +12 -0
  19. package/lib/types/client/FileTree.d.ts +36 -0
  20. package/lib/types/client/GitView.d.ts +8 -0
  21. package/lib/types/client/OrphanedTab.d.ts +11 -0
  22. package/lib/types/client/PdfView.d.ts +6 -0
  23. package/lib/types/client/RenderBoundary.d.ts +32 -0
  24. package/lib/types/client/SandboxStatusBar.d.ts +10 -0
  25. package/lib/types/client/SideCardSection.d.ts +74 -0
  26. package/lib/types/client/SideChatView.d.ts +16 -0
  27. package/lib/types/client/Sidebar.d.ts +6 -0
  28. package/lib/types/client/SubagentView.d.ts +16 -0
  29. package/lib/types/client/TabBar.d.ts +43 -0
  30. package/lib/types/client/TerminalView.d.ts +24 -0
  31. package/lib/types/client/TextEditor.d.ts +10 -0
  32. package/lib/types/client/TreePanel.d.ts +23 -0
  33. package/lib/types/client/UploadOverlay.d.ts +20 -0
  34. package/lib/types/client/add-plugin-modal.d.ts +15 -0
  35. package/lib/types/client/api.d.ts +268 -0
  36. package/lib/types/client/binary-download.d.ts +12 -0
  37. package/lib/types/client/breakpoints.d.ts +12 -0
  38. package/lib/types/client/browser.d.ts +50 -0
  39. package/lib/types/client/builtins/index.d.ts +18 -0
  40. package/lib/types/client/builtins/tabs.d.ts +11 -0
  41. package/lib/types/client/builtins/viewers.d.ts +3 -0
  42. package/lib/types/client/chunk-loader.d.ts +124 -0
  43. package/lib/types/client/chunks/editor.d.ts +9 -0
  44. package/lib/types/client/chunks/mermaid.d.ts +10 -0
  45. package/lib/types/client/chunks/terminal.d.ts +9 -0
  46. package/lib/types/client/cm-themes.d.ts +24 -0
  47. package/lib/types/client/conversation-draft.d.ts +14 -0
  48. package/lib/types/client/desktop-env.d.ts +35 -0
  49. package/lib/types/client/editable-state.d.ts +27 -0
  50. package/lib/types/client/editor-load.d.ts +66 -0
  51. package/lib/types/client/frame-batcher.d.ts +24 -0
  52. package/lib/types/client/icons.d.ts +57 -0
  53. package/lib/types/client/image-types.d.ts +3 -0
  54. package/lib/types/client/ime-guard.d.ts +36 -0
  55. package/lib/types/client/index.d.ts +19 -0
  56. package/lib/types/client/intercept.d.ts +33 -0
  57. package/lib/types/client/lang.d.ts +12 -0
  58. package/lib/types/client/lazy-chunk.d.ts +25 -0
  59. package/lib/types/client/link-intercept.d.ts +42 -0
  60. package/lib/types/client/locales.d.ts +366 -0
  61. package/lib/types/client/mermaid-blocks.d.ts +41 -0
  62. package/lib/types/client/mermaid-sanitize.d.ts +2 -0
  63. package/lib/types/client/mermaid.d.ts +12 -0
  64. package/lib/types/client/open-when-sized.d.ts +20 -0
  65. package/lib/types/client/open-with-settings.d.ts +4 -0
  66. package/lib/types/client/open-with.d.ts +87 -0
  67. package/lib/types/client/openpath-intercept.d.ts +41 -0
  68. package/lib/types/client/paths.d.ts +35 -0
  69. package/lib/types/client/pdf-types.d.ts +2 -0
  70. package/lib/types/client/plugin-settings.d.ts +8 -0
  71. package/lib/types/client/plugins-shared.d.ts +27 -0
  72. package/lib/types/client/plugins-tabs.d.ts +3 -0
  73. package/lib/types/client/plugins-viewers.d.ts +3 -0
  74. package/lib/types/client/prefs.d.ts +41 -0
  75. package/lib/types/client/produced-files.d.ts +23 -0
  76. package/lib/types/client/selection-payload.d.ts +27 -0
  77. package/lib/types/client/service.d.ts +440 -0
  78. package/lib/types/client/settings-nav-icon.d.ts +19 -0
  79. package/lib/types/client/shell-presets.d.ts +48 -0
  80. package/lib/types/client/sidechat-transcript.d.ts +103 -0
  81. package/lib/types/client/split-pane.d.ts +30 -0
  82. package/lib/types/client/state.d.ts +359 -0
  83. package/lib/types/client/subagent-detect.d.ts +54 -0
  84. package/lib/types/client/subagent-jobs.d.ts +63 -0
  85. package/lib/types/client/tab-content-memo.d.ts +33 -0
  86. package/lib/types/client/terminal-font.d.ts +20 -0
  87. package/lib/types/client/theme.d.ts +45 -0
  88. package/lib/types/client/titlebar-strip.d.ts +23 -0
  89. package/lib/types/client/upload.d.ts +69 -0
  90. package/lib/types/client/wco.d.ts +47 -0
  91. package/lib/types/config.d.ts +64 -0
  92. package/lib/types/context-types.d.ts +603 -0
  93. package/lib/types/fs-operations.d.ts +28 -0
  94. package/lib/types/fs-search.d.ts +24 -0
  95. package/lib/types/fs-tree.d.ts +51 -0
  96. package/lib/types/git.d.ts +82 -0
  97. package/lib/types/html-route.d.ts +59 -0
  98. package/lib/types/index.d.ts +47 -0
  99. package/lib/types/invariant.d.ts +15 -0
  100. package/lib/types/jobs-routes.d.ts +45 -0
  101. package/lib/types/open-external.d.ts +24 -0
  102. package/lib/types/prefs-shared.d.ts +225 -0
  103. package/lib/types/pty-deps.d.ts +78 -0
  104. package/lib/types/pty-manager.d.ts +168 -0
  105. package/lib/types/sidechat-core.d.ts +172 -0
  106. package/lib/types/sidechat-routes.d.ts +30 -0
  107. package/lib/types/subagent-activity.d.ts +44 -0
  108. package/lib/types/subagent-live-route.d.ts +44 -0
  109. package/lib/types/tools.d.ts +31 -0
  110. package/lib/types/trust-fence.d.ts +24 -0
  111. package/lib/types/wire.d.ts +38 -0
  112. package/package.json +173 -0
  113. package/scripts/install.ps1 +289 -0
  114. package/scripts/install.sh +287 -0
  115. package/src/agent-pty.ts +527 -0
  116. package/src/browser-probe.ts +26 -0
  117. package/src/bundle-route.ts +129 -0
  118. package/src/client/BrowserView.tsx +253 -0
  119. package/src/client/DiffTab.tsx +110 -0
  120. package/src/client/DiffView.tsx +305 -0
  121. package/src/client/EditorHost.tsx +525 -0
  122. package/src/client/FileTree.tsx +653 -0
  123. package/src/client/GitView.tsx +558 -0
  124. package/src/client/OrphanedTab.tsx +27 -0
  125. package/src/client/PdfView.tsx +110 -0
  126. package/src/client/RenderBoundary.tsx +49 -0
  127. package/src/client/SandboxStatusBar.tsx +60 -0
  128. package/src/client/SideCardSection.module.css +960 -0
  129. package/src/client/SideCardSection.tsx +1152 -0
  130. package/src/client/SideChatView.module.css +437 -0
  131. package/src/client/SideChatView.tsx +644 -0
  132. package/src/client/Sidebar.tsx +1148 -0
  133. package/src/client/SubagentView.module.css +547 -0
  134. package/src/client/SubagentView.tsx +883 -0
  135. package/src/client/TabBar.tsx +305 -0
  136. package/src/client/TerminalView.tsx +383 -0
  137. package/src/client/TextEditor.tsx +500 -0
  138. package/src/client/TreePanel.tsx +273 -0
  139. package/src/client/UploadOverlay.tsx +62 -0
  140. package/src/client/add-plugin-modal.tsx +199 -0
  141. package/src/client/api.ts +335 -0
  142. package/src/client/binary-download.tsx +23 -0
  143. package/src/client/breakpoints.ts +51 -0
  144. package/src/client/browser.ts +119 -0
  145. package/src/client/builtins/index.ts +37 -0
  146. package/src/client/builtins/tabs.tsx +331 -0
  147. package/src/client/builtins/viewers.tsx +125 -0
  148. package/src/client/chunk-loader.ts +351 -0
  149. package/src/client/chunks/editor.tsx +9 -0
  150. package/src/client/chunks/mermaid.tsx +10 -0
  151. package/src/client/chunks/terminal.tsx +9 -0
  152. package/src/client/cm-themes.ts +129 -0
  153. package/src/client/conversation-draft.ts +29 -0
  154. package/src/client/css-modules.d.ts +5 -0
  155. package/src/client/desktop-env.ts +72 -0
  156. package/src/client/editable-state.ts +70 -0
  157. package/src/client/editor-load.ts +92 -0
  158. package/src/client/frame-batcher.ts +56 -0
  159. package/src/client/icons.tsx +161 -0
  160. package/src/client/image-types.ts +8 -0
  161. package/src/client/ime-guard.ts +47 -0
  162. package/src/client/index.tsx +369 -0
  163. package/src/client/intercept.tsx +110 -0
  164. package/src/client/lang.ts +103 -0
  165. package/src/client/layout.css +94 -0
  166. package/src/client/lazy-chunk.tsx +89 -0
  167. package/src/client/link-intercept.ts +73 -0
  168. package/src/client/locales.ts +734 -0
  169. package/src/client/mermaid-blocks.ts +110 -0
  170. package/src/client/mermaid-sanitize.ts +93 -0
  171. package/src/client/mermaid.tsx +401 -0
  172. package/src/client/open-when-sized.ts +43 -0
  173. package/src/client/open-with-settings.tsx +135 -0
  174. package/src/client/open-with.ts +221 -0
  175. package/src/client/openpath-intercept.ts +62 -0
  176. package/src/client/paths.ts +47 -0
  177. package/src/client/pdf-types.ts +4 -0
  178. package/src/client/plugin-settings.ts +43 -0
  179. package/src/client/plugins-shared.ts +29 -0
  180. package/src/client/plugins-tabs.ts +87 -0
  181. package/src/client/plugins-viewers.ts +30 -0
  182. package/src/client/prefs.ts +207 -0
  183. package/src/client/produced-files.ts +91 -0
  184. package/src/client/selection-payload.ts +86 -0
  185. package/src/client/service.ts +838 -0
  186. package/src/client/settings-nav-icon.ts +45 -0
  187. package/src/client/shell-presets.ts +83 -0
  188. package/src/client/sidebar.module.css +2577 -0
  189. package/src/client/sidechat-transcript.ts +321 -0
  190. package/src/client/split-pane.tsx +322 -0
  191. package/src/client/state.ts +1175 -0
  192. package/src/client/subagent-detect.ts +137 -0
  193. package/src/client/subagent-jobs.ts +161 -0
  194. package/src/client/tab-content-memo.ts +46 -0
  195. package/src/client/terminal-font.ts +28 -0
  196. package/src/client/theme.ts +110 -0
  197. package/src/client/titlebar-strip.ts +37 -0
  198. package/src/client/upload.ts +187 -0
  199. package/src/client/wco.ts +120 -0
  200. package/src/config.ts +155 -0
  201. package/src/context-types.ts +610 -0
  202. package/src/fs-operations.ts +99 -0
  203. package/src/fs-search.ts +86 -0
  204. package/src/fs-tree.ts +158 -0
  205. package/src/git.ts +244 -0
  206. package/src/html-route.ts +106 -0
  207. package/src/index.ts +1132 -0
  208. package/src/invariant.ts +32 -0
  209. package/src/jobs-routes.ts +257 -0
  210. package/src/open-external.ts +90 -0
  211. package/src/prefs-shared.ts +268 -0
  212. package/src/pty-deps.ts +240 -0
  213. package/src/pty-manager.ts +376 -0
  214. package/src/sidechat-core.ts +468 -0
  215. package/src/sidechat-routes.ts +344 -0
  216. package/src/subagent-activity.ts +91 -0
  217. package/src/subagent-live-route.ts +93 -0
  218. package/src/tools.ts +479 -0
  219. package/src/trust-fence.ts +77 -0
  220. package/src/wire.ts +100 -0
@@ -0,0 +1,287 @@
1
+ #!/usr/bin/env bash
2
+ # =============================================================================
3
+ # dsh-better-sidebar 一键安装脚本(官方 CLI 方式,macOS / Linux / Windows Git Bash)
4
+ #
5
+ # 通过 DSH 官方插件命令安装 npm 包并自动挂载:
6
+ # dsh plugin --profile web add dsh-better-sidebar@<version>
7
+ #
8
+ # 包内声明了 dsh.bundle.patch(cordis.patch.yml):CLI 的 bundle 协调会把它
9
+ # 自动加进 profile 的 dsh.profile.bundles,下次启动即挂载——无需手动写
10
+ # cordis.patch.yml 挂载行。符合仓库硬约束:不修改 DSH 源码,插件永远作为
11
+ # 独立包被 profile 引用。
12
+ #
13
+ # 用法:
14
+ # bash scripts/install.sh [版本] [--restart] [--dry-run]
15
+ # bash scripts/install.sh --repair [--profile <名>] [--dry-run]
16
+ #
17
+ # 版本 npm 版本号/范围,缺省为 latest(自动解析为 ^<最新>)。
18
+ # 示例:0.10.2、^0.10.2、~0.10.2、latest
19
+ # --repair 修复模式:不重装插件,只确保 profile 的 pnpm-workspace.yaml
20
+ # 放行 node-pty 构建脚本,然后重跑 pnpm install + pnpm rebuild
21
+ # node-pty(终端提示「node-pty 加载失败」时用它,见 issue #140)。
22
+ # --profile 目标 profile 名(缺省 web);安装与修复模式均适用。
23
+ # --restart 装完后尝试 `pm2 restart dsh-web`(无 pm2 时仅打印提示)。
24
+ # 注意:重启会断开当前 DSH 页面会话,默认不自动重启。
25
+ # --dry-run 只打印将要执行的操作,不写任何文件。
26
+ # -h/--help 打印本帮助。
27
+ #
28
+ # 环境(均可省略,脚本会自动探测):
29
+ # DSH_HOME 默认 ~/.dsh(Windows Git Bash 下回退 $USERPROFILE/.dsh)
30
+ # REGISTRY 默认 https://registry.npmjs.org(发布源;装依赖仍走 pnpm 配置)
31
+ # DSH_CMD 默认优先用 PATH 上的 `dsh`,缺省回退 npx -y --package @deepseek-ai/dsh
32
+ #
33
+ # 说明:
34
+ # - pnpm 11 的 strict-dep-builds 会拦截 node-pty/protobufjs 的构建脚本并使
35
+ # `dsh plugin add` 非零退出(bundle 协调因此被跳过)。脚本会先把这两个
36
+ # 构建许可写进 profile 的 pnpm-workspace.yaml(幂等),保证 CLI 一步成功。
37
+ # - pnpm 11 的 minimumReleaseAge 会拒绝发布 <24h 的新版本。脚本会预写
38
+ # minimumReleaseAgeExclude(幂等),放行本插件,避免"重跑一次才成功"。
39
+ # - 老版本(<0.10.2)用手动挂载行,bundle 通道激活后需移除,否则双挂载
40
+ # (Node 半挂两次、页面两个侧边栏)。脚本会幂等移除 better-sidebar 挂载行。
41
+ # - 回滚:dsh plugin --profile web remove dsh-better-sidebar,或把 profile 依赖
42
+ # 改回 "dsh-better-sidebar": "link:<路径>" 再 pnpm install。
43
+ # =============================================================================
44
+ set -euo pipefail
45
+
46
+ # 帮助请求优先处理
47
+ for arg in "$@"; do
48
+ if [ "$arg" = "-h" ] || [ "$arg" = "--help" ]; then
49
+ cat <<'EOF'
50
+ dsh-better-sidebar 一键安装 / 依赖修复脚本
51
+
52
+ 用法:
53
+ bash scripts/install.sh [版本] [--restart] [--dry-run] [--profile <名>]
54
+ bash scripts/install.sh --repair [--profile <名>] [--dry-run]
55
+
56
+ 版本 npm 版本号/范围,缺省 latest(自动解析为最新)。示例:0.10.2、^0.10.2、latest
57
+ --repair 修复模式:确保 profile 放行 node-pty 构建脚本并重装 node-pty(终端提示依赖加载失败时用)
58
+ --profile 目标 profile 名(缺省 web)
59
+ --restart 装完后尝试 `pm2 restart dsh-web`(无 pm2 时仅提示)
60
+ --dry-run 只打印将要执行的操作,不写任何文件
61
+
62
+ 环境变量(可省略):DSH_HOME(默认 ~/.dsh)、REGISTRY(npm 源)、DSH_CMD(dsh 命令)
63
+ EOF
64
+ exit 0
65
+ fi
66
+ done
67
+
68
+ DSH_HOME="${DSH_HOME:-${HOME:-${USERPROFILE:-}}/.dsh}"
69
+ REGISTRY="${REGISTRY:-https://registry.npmjs.org}"
70
+ PKG="dsh-better-sidebar"
71
+ DSH_CMD="${DSH_CMD:-dsh}"
72
+
73
+ RESTART=false
74
+ DRY_RUN=false
75
+ REPAIR=false
76
+ VERSION_SPEC=""
77
+ PROFILE_NAME="web"
78
+ while [ $# -gt 0 ]; do
79
+ case "$1" in
80
+ --restart) RESTART=true ;;
81
+ --dry-run) DRY_RUN=true ;;
82
+ --repair) REPAIR=true ;;
83
+ --profile)
84
+ if [ $# -lt 2 ]; then echo "--profile 需要一个 profile 名(如 web)" >&2; exit 2; fi
85
+ PROFILE_NAME="$2"; shift ;;
86
+ -h|--help) : ;; # 已在上面处理
87
+ -*) echo "未知参数: ${1}(用 -h 查看用法)" >&2; exit 2 ;;
88
+ *) VERSION_SPEC="$1" ;;
89
+ esac
90
+ shift
91
+ done
92
+
93
+ PROFILE_DIR="$DSH_HOME/profiles/$PROFILE_NAME"
94
+ WS_YML="$PROFILE_DIR/pnpm-workspace.yaml"
95
+ PATCH_YML="$PROFILE_DIR/cordis.patch.yml"
96
+
97
+ say() { printf '\033[32m[install]\033[0m %s\n' "$*"; }
98
+ warn() { printf '\033[33m[warn]\033[0m %s\n' "$*" >&2; }
99
+ die() { printf '\033[31m[error]\033[0m %s\n' "$*" >&2; exit 1; }
100
+
101
+ # 步骤 1(安装与修复共用):预写 workspace 设置(幂等),保证 pnpm 不拦截
102
+ # node-pty/protobufjs 构建脚本、放行本插件新版本
103
+ ensure_workspace_settings() {
104
+ WS_RESULT="$(node -e '
105
+ const fs = require("fs");
106
+ const p = process.argv[1];
107
+ let t = fs.readFileSync(p, "utf8");
108
+ const before = t;
109
+ // allowBuilds:把 node-pty/protobufjs 归位为 true
110
+ t = t.replace(/^(\s*)(node-pty|protobufjs):.*$/gm, "$1$2: true");
111
+ if (!/^\s*allowBuilds:\s*$/m.test(t)) {
112
+ t += "\nallowBuilds:\n node-pty: true\n protobufjs: true\n";
113
+ } else {
114
+ for (const k of ["node-pty", "protobufjs"]) {
115
+ if (!new RegExp("^\\s*" + k + ":\\s*true\\s*$", "m").test(t)) {
116
+ t = t.replace(/^(\s*allowBuilds:\s*)$/m, "$1\n " + k + ": true");
117
+ }
118
+ }
119
+ }
120
+ // minimumReleaseAgeExclude:放行本插件(版本无关),避免 <24h 新版本被拒
121
+ if (!/^\s*-\s+dsh-better-sidebar\s*$/m.test(t)) {
122
+ if (/^\s*minimumReleaseAgeExclude:\s*$/m.test(t)) {
123
+ t = t.replace(/^(\s*minimumReleaseAgeExclude:\s*)$/m, "$1\n - dsh-better-sidebar");
124
+ } else {
125
+ t += "\nminimumReleaseAgeExclude:\n - dsh-better-sidebar\n";
126
+ }
127
+ }
128
+ if (t !== before) fs.writeFileSync(p, t);
129
+ console.log(t === before ? "unchanged" : "updated");
130
+ ' "$WS_YML")"
131
+ [ "$WS_RESULT" = "updated" ] \
132
+ && say "已确保 ${WS_YML}:allowBuilds(node-pty/protobufjs: true)+ minimumReleaseAgeExclude(${PKG})" \
133
+ || say "workspace 设置已就绪,跳过"
134
+ }
135
+
136
+ # 解析用户给的版本 -> CLI 要用的 npm spec("x.y.z" / "^x.y.z" / latest)
137
+ resolve_spec() {
138
+ local given="${1:-latest}"
139
+ case "$given" in
140
+ latest)
141
+ local v=""
142
+ if command -v npm >/dev/null 2>&1; then
143
+ v="$(npm view "$PKG" version --registry="$REGISTRY" 2>/dev/null)" || v=""
144
+ fi
145
+ if [ -z "$v" ] && command -v pnpm >/dev/null 2>&1; then
146
+ v="$(pnpm view "$PKG" version --registry="$REGISTRY" 2>/dev/null)" || v=""
147
+ fi
148
+ if [ -n "$v" ]; then
149
+ printf '%s' "$v"
150
+ else
151
+ warn "无法联网解析最新版本(npm/pnpm 查询失败),回退为 latest,由 pnpm 直接解析。"
152
+ warn "若已知版本号,可显式传入:bash scripts/install.sh 0.10.2"
153
+ printf 'latest'
154
+ fi
155
+ ;;
156
+ *) printf '%s' "$given" ;;
157
+ esac
158
+ }
159
+
160
+ # 组装 dsh CLI 调用:优先 PATH 上的 dsh,缺省 npx 拉官方包
161
+ dsh_cli() {
162
+ if command -v "$DSH_CMD" >/dev/null 2>&1; then
163
+ printf '%s' "$DSH_CMD"
164
+ elif command -v npx >/dev/null 2>&1; then
165
+ printf 'npx -y --package @deepseek-ai/dsh dsh'
166
+ else
167
+ die "未找到 dsh 或 npx。请先安装 DSH(并确保 Node/npm 可用),或用 DSH_CMD 指定 dsh 路径。"
168
+ fi
169
+ }
170
+
171
+ # 前置校验
172
+ command -v node >/dev/null 2>&1 || die "未找到 node(DSH 运行需要 Node.js ≥ 20),请先安装 Node.js 并加入 PATH。"
173
+
174
+ [ -d "$PROFILE_DIR" ] || die "找不到 profile 目录:${PROFILE_DIR}(请先安装并运行过一次 dsh web)"
175
+ [ -f "$WS_YML" ] || die "找不到 ${WS_YML}(请先初始化 ${PROFILE_NAME} profile)"
176
+
177
+ # ── 修复模式(issue #140):不重装插件,只修复 node-pty 依赖 ────────────
178
+ # 终端提示「node-pty 加载失败」时运行:确保 allowBuilds 后重跑
179
+ # pnpm install + pnpm rebuild node-pty(重放被 pnpm 11 拦截的构建脚本)。
180
+ if [ "$REPAIR" = true ]; then
181
+ if [ "$DRY_RUN" = true ]; then
182
+ say "[dry-run] 修复:确保 $WS_YML 含 allowBuilds(node-pty: true)"
183
+ say "[dry-run] 修复:cd $PROFILE_DIR && pnpm install && pnpm rebuild node-pty"
184
+ exit 0
185
+ fi
186
+ say "修复模式:重装 node-pty(profile: ${PROFILE_NAME},${PROFILE_DIR})..."
187
+ ensure_workspace_settings
188
+ if ! (cd "$PROFILE_DIR" && pnpm install && pnpm rebuild node-pty); then
189
+ die "修复失败:pnpm install / pnpm rebuild node-pty 非零退出。请确认 pnpm 在 PATH 上、网络可用,然后重试。"
190
+ fi
191
+ say "修复完成:node-pty 已重装(与 DSH 核心保持同一版本)。请重启 DSH 后重试终端。"
192
+ exit 0
193
+ fi
194
+
195
+ SPEC="$(resolve_spec "$VERSION_SPEC")"
196
+ CLI="$(dsh_cli)"
197
+ say "目标:$CLI plugin --profile $PROFILE_NAME add $PKG@${SPEC}(profile: ${PROFILE_DIR})"
198
+
199
+ if [ "$DRY_RUN" = true ]; then
200
+ say "[dry-run] 步骤 1:确保 $WS_YML 含 allowBuilds(node-pty/protobufjs: true)与 minimumReleaseAgeExclude(${PKG})"
201
+ say "[dry-run] 步骤 2:执行 $CLI plugin --profile $PROFILE_NAME add $PKG@${SPEC}(安装 + bundle 自动注册)"
202
+ say "[dry-run] 步骤 3:校验 dsh.profile.bundles 含 $PKG"
203
+ say "[dry-run] 步骤 4:幂等移除 $PATCH_YML 里旧的 better-sidebar 手动挂载行(避免双挂载)"
204
+ if [ "$RESTART" = true ]; then say "[dry-run] 步骤 5:pm2 restart dsh-web"; else say "[dry-run] 步骤 5:提示用户手动重启 DSH"; fi
205
+ exit 0
206
+ fi
207
+
208
+ # 步骤 1:预写 workspace 设置(幂等),保证 pnpm 不拦截构建、不放行旧版本策略
209
+ ensure_workspace_settings
210
+
211
+ # 步骤 2:官方 CLI 安装 + bundle 自动注册(含挂载)
212
+ say "执行 $CLI plugin --profile $PROFILE_NAME add $PKG@$SPEC ..."
213
+ if ! $CLI plugin --profile "$PROFILE_NAME" add "$PKG@$SPEC" 2>&1 | tail -n +1; then
214
+ warn "dsh plugin add 失败。已预写 allowBuilds 与 minimumReleaseAgeExclude,仍失败的可能原因:"
215
+ warn " - 网络/登录问题:npm registry 不可达或需要登录。"
216
+ warn " - 依赖安装冲突:可手动重试 cd $PROFILE_DIR && pnpm install。"
217
+ exit 1
218
+ fi
219
+
220
+ # 校验 bundle 已注册(挂载生效的判据)
221
+ if ! node -e '
222
+ const fs = require("fs");
223
+ const p = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
224
+ const bundles = p.dsh?.profile?.bundles ?? [];
225
+ process.exit(bundles.includes(process.argv[2]) ? 0 : 1);
226
+ ' "$PROFILE_DIR/package.json" "$PKG"; then
227
+ warn "dsh-better-sidebar 未出现在 dsh.profile.bundles 中——挂载未注册。"
228
+ warn "若上面的 pnpm 输出提示 ignored build scripts,请确认 $WS_YML 的 allowBuilds 后重跑本脚本。"
229
+ exit 1
230
+ fi
231
+ say "bundle 已注册:dsh.profile.bundles 包含 ${PKG}(下次启动自动挂载)"
232
+
233
+ # 步骤 3:幂等移除旧的 manual 挂载行(避免与 bundle 双挂载)
234
+ MOUNT_RESULT="$(node -e '
235
+ const fs = require("fs");
236
+ const p = process.argv[1];
237
+ const lines = fs.readFileSync(p, "utf8").split("\n");
238
+ const out = [];
239
+ let i = 0;
240
+ let removed = false;
241
+ while (i < lines.length) {
242
+ const line = lines[i];
243
+ if (/^[ \t]*- insert:\s*$/.test(line)) {
244
+ const block = [line];
245
+ let j = i + 1;
246
+ while (j < lines.length && lines[j].trim() !== "" && !/^-\s/.test(lines[j])) {
247
+ block.push(lines[j]);
248
+ j++;
249
+ }
250
+ if (block.some((l) => /id:\s*better-sidebar\b/.test(l))) {
251
+ while (out.length && /^[ \t]*#/.test(out[out.length - 1])) out.pop();
252
+ i = j;
253
+ removed = true;
254
+ continue;
255
+ }
256
+ }
257
+ out.push(line);
258
+ i++;
259
+ }
260
+ if (!removed) {
261
+ console.log("none");
262
+ } else {
263
+ const t = out.join("\n").replace(/\n{3,}/g, "\n\n");
264
+ fs.writeFileSync(p, t);
265
+ console.log("removed");
266
+ }
267
+ ' "$PATCH_YML")"
268
+ [ "$MOUNT_RESULT" = "removed" ] \
269
+ && say "已从 $PATCH_YML 移除旧的 better-sidebar 手动挂载行(bundle 通道接管挂载)" \
270
+ || say "无旧手动挂载行,跳过"
271
+
272
+ say "安装完成:$PKG@$SPEC"
273
+
274
+ # 步骤 4:重启提示
275
+ if [ "$RESTART" = true ]; then
276
+ if command -v pm2 >/dev/null 2>&1; then
277
+ say "重启 dsh-web(pm2)..."
278
+ pm2 restart dsh-web || warn "pm2 restart 失败,请手动重启 DSH"
279
+ else
280
+ warn "未找到 pm2,请手动重启 DSH(如:pm2 restart dsh-web 或 dsh web)"
281
+ fi
282
+ else
283
+ say "下一步:重启 DSH 并硬刷新(Cmd/Ctrl+Shift+R)使新副本生效。"
284
+ if command -v pm2 >/dev/null 2>&1; then
285
+ say "本机可用:pm2 restart dsh-web(会短暂断开当前页面会话)"
286
+ fi
287
+ fi