@askdkc/dsh-cli 0.11.3 → 0.11.4
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.md +64 -79
- package/bin/dsh-tui.js +88 -88
- package/cordis.patch.yml +9 -9
- package/cordis.yml +8 -8
- package/lib/types/adapter/standard/descriptor.js +2 -2
- package/lib/types/components/LogoV2.d.ts +1 -1
- package/lib/types/components/LogoV2.js +2 -2
- package/lib/types/dsh-adapter/invariant.js +1 -1
- package/lib/types/dsh-adapter/migrate/cli.js +9 -9
- package/lib/types/dsh-adapter/packaged-presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/packaged-presets.js +3 -2
- package/lib/types/update.d.ts +2 -2
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +33 -32
- package/package.json +5 -4
package/bin/dsh-tui.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* dsh-
|
|
3
|
+
* dsh-cli — 双态启动器(delegating launcher,0.9.3)。
|
|
4
4
|
*
|
|
5
5
|
* 同一个文件按“自己住在哪”决定扮演的角色:
|
|
6
6
|
*
|
|
7
|
-
* 全局安装副本(npm i -g 得到的 `dsh-
|
|
8
|
-
* 1. 找到 $DSH_HOME/profiles/dsh-
|
|
7
|
+
* 全局安装副本(npm i -g 得到的 `dsh-cli` 命令)→ 瘦壳:
|
|
8
|
+
* 1. 找到 $DSH_HOME/profiles/dsh-cli 里的同包 bin;
|
|
9
9
|
* 2. 可读 → 原样转发 argv 委托它执行(完整逻辑永远来自 profile 副本,
|
|
10
10
|
* 版本随 /update 一起前进,启动器滞后问题从结构上消失);
|
|
11
11
|
* 3. 不可读(首次运行)→ 探测 dsh/pnpm 后自举
|
|
12
|
-
* `dsh plugin --profile dsh-
|
|
12
|
+
* `dsh plugin --profile dsh-cli add <本包>@<本包版本>`,成功后委托。
|
|
13
13
|
*
|
|
14
14
|
* profile 内副本(被委托执行,或 junction/源码目录里直接运行)→ 完整
|
|
15
15
|
* 启动逻辑(与 0.8.6 及之前一致):
|
|
16
16
|
* dsh 预检 / profile 版本核对 / --resume 与工作区目标拦截 /
|
|
17
|
-
* `dsh --profile dsh-
|
|
17
|
+
* `dsh --profile dsh-cli` 启动与退出码透传。
|
|
18
18
|
*
|
|
19
19
|
* 自举角色判定用 realpath:Windows Junction 轨(profile 指回仓库)与
|
|
20
20
|
* `pnpm run dev` 源码运行都会折叠成同一物理目录 → 走完整逻辑,不会
|
|
@@ -59,9 +59,9 @@ const readJson = p => {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
const ownPackage = readJson(join(ownDir, 'package.json'))
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const PROFILE = 'dsh-
|
|
62
|
+
const PACKAGE = '@askdkc/dsh-cli'
|
|
63
|
+
const ownVersion = ownPackage?.name === PACKAGE ? ownPackage.version : undefined
|
|
64
|
+
const PROFILE = 'dsh-cli'
|
|
65
65
|
// 救援 profile(最小可用):同 home 下的空白 profile(仅 base+TUI,无第三方
|
|
66
66
|
// 插件),是主 profile 装炸时的干净启动通道——创建走官方 dsh plugin add
|
|
67
67
|
// (钉当前版本,同 bootstrap 语义)。
|
|
@@ -71,7 +71,7 @@ const PROFILE = 'dsh-tui'
|
|
|
71
71
|
// profileDir 这个新目录里,任何一次 dsh 启动都会维护**共享**的
|
|
72
72
|
// `$DSH_HOME/profiles/node_modules` 模块回退链接(上游 dsh 的
|
|
73
73
|
// healProfilesModuleFallback,无开关),救援启动也不例外。
|
|
74
|
-
const RESCUE_PROFILE = 'dsh-
|
|
74
|
+
const RESCUE_PROFILE = 'dsh-cli-safe'
|
|
75
75
|
// 安装钉版本:ownVersion 缺失(bin 被单独拿走、package.json 不可读/改名)
|
|
76
76
|
// 时拼出 `@undefined` 只会让 add 失败得更晚、更难懂——退回 @latest。
|
|
77
77
|
const installVersion = ownVersion ?? 'latest'
|
|
@@ -136,72 +136,72 @@ const isVersionNewer = (a, b) => {
|
|
|
136
136
|
const lang = process.env.DSH_TUI_LANG === 'en' ? 'en' : 'zh'
|
|
137
137
|
const MSG = {
|
|
138
138
|
noDsh: {
|
|
139
|
-
en: '[dsh-
|
|
140
|
-
zh: '[dsh-
|
|
139
|
+
en: '[dsh-cli] dsh CLI not found. Install the official client first:\n npm install -g @deepseek-ai/dsh',
|
|
140
|
+
zh: '[dsh-cli] 未检测到 dsh CLI。请先安装官方客户端:\n npm install -g @deepseek-ai/dsh',
|
|
141
141
|
},
|
|
142
142
|
noPnpm: {
|
|
143
|
-
en: '[dsh-
|
|
144
|
-
zh: '[dsh-
|
|
143
|
+
en: '[dsh-cli] The first-time setup needs pnpm (dsh plugin delegates installs to it):\n npm install -g pnpm (or via corepack: corepack enable pnpm)',
|
|
144
|
+
zh: '[dsh-cli] 首次安装需要 pnpm(dsh plugin 会把安装转发给它):\n npm install -g pnpm (或启用 corepack:corepack enable pnpm)',
|
|
145
145
|
},
|
|
146
146
|
bootstrapStart: {
|
|
147
|
-
en: `[dsh-
|
|
148
|
-
zh: `[dsh-
|
|
147
|
+
en: `[dsh-cli] First run — initializing the ${PROFILE} profile (${PACKAGE}@${installVersion})…`,
|
|
148
|
+
zh: `[dsh-cli] 首次运行,正在初始化 ${PROFILE} profile(${PACKAGE}@${installVersion})…`,
|
|
149
149
|
},
|
|
150
150
|
bootstrapRetryW: {
|
|
151
|
-
en: '[dsh-
|
|
152
|
-
zh: '[dsh-
|
|
151
|
+
en: '[dsh-cli] pnpm refused to add to the workspace root (ERR_PNPM_ADDING_TO_ROOT) — retrying with -w…',
|
|
152
|
+
zh: '[dsh-cli] pnpm 拒绝写入 workspace 根(ERR_PNPM_ADDING_TO_ROOT)——带 -w 重试…',
|
|
153
153
|
},
|
|
154
154
|
installFailed: {
|
|
155
|
-
en: `[dsh-
|
|
156
|
-
zh: `[dsh-
|
|
155
|
+
en: `[dsh-cli] Plugin install failed. Retry manually later:\n dsh plugin --profile ${PROFILE} add -w ${PACKAGE}@${installVersion}`,
|
|
156
|
+
zh: `[dsh-cli] 插件安装失败。可稍后手工重试:\n dsh plugin --profile ${PROFILE} add -w ${PACKAGE}@${installVersion}`,
|
|
157
157
|
},
|
|
158
158
|
bootstrapUnreadable: {
|
|
159
159
|
en: dir =>
|
|
160
|
-
`[dsh-
|
|
160
|
+
`[dsh-cli] install reported success but the plugin package is still unreadable under:\n` +
|
|
161
161
|
` ${dir}\n` +
|
|
162
162
|
` pnpm treats this half-installed profile as already up to date, so every retry\n` +
|
|
163
163
|
` reports success while boot keeps failing. Recovery:\n` +
|
|
164
|
-
` rm -rf ${dir} && dsh-
|
|
164
|
+
` rm -rf ${dir} && dsh-cli`,
|
|
165
165
|
zh: dir =>
|
|
166
|
-
`[dsh-
|
|
166
|
+
`[dsh-cli] 安装报告成功,但插件包仍不可读:\n` +
|
|
167
167
|
` ${dir}\n` +
|
|
168
168
|
` pnpm 把半残的 profile 视为已装好,重试永远「成功」而启动照旧崩溃。\n` +
|
|
169
169
|
` 恢复方法:\n` +
|
|
170
|
-
` rm -rf ${dir} 后重新运行 dsh-
|
|
170
|
+
` rm -rf ${dir} 后重新运行 dsh-cli`,
|
|
171
171
|
},
|
|
172
172
|
launchFailed: {
|
|
173
|
-
en: err => `[dsh-
|
|
174
|
-
zh: err => `[dsh-
|
|
173
|
+
en: err => `[dsh-cli] Failed to launch: ${err.message}`,
|
|
174
|
+
zh: err => `[dsh-cli] 启动失败:${err.message}`,
|
|
175
175
|
},
|
|
176
176
|
delegateFailed: {
|
|
177
177
|
en: path =>
|
|
178
|
-
`[dsh-
|
|
178
|
+
`[dsh-cli] cannot launch the profile copy:\n ${path}\nReinstall the global launcher:\n npm install -g --legacy-peer-deps ${PACKAGE}@latest\n(--legacy-peer-deps avoids an npm 12 peer-resolution crash; the launcher is a thin shim, so skipping global peer resolution is safe.)`,
|
|
179
179
|
zh: path =>
|
|
180
|
-
`[dsh-
|
|
180
|
+
`[dsh-cli] 无法启动 profile 内副本:\n ${path}\n请重装全局启动器:\n npm install -g --legacy-peer-deps ${PACKAGE}@latest\n(--legacy-peer-deps 可绕过 npm 12 的 peer 解析崩溃;启动器是瘦壳,跳过全局 peer 解析是安全的。)`,
|
|
181
181
|
},
|
|
182
182
|
profileExited: {
|
|
183
|
-
en: code => `[dsh-
|
|
184
|
-
zh: code => `[dsh-
|
|
183
|
+
en: code => `[dsh-cli] dsh profile exited with code ${code}. Run it directly for diagnostics:\n dsh --profile ${PROFILE}`,
|
|
184
|
+
zh: code => `[dsh-cli] dsh profile 已退出(退出码 ${code})。可直接运行以下命令查看诊断:\n dsh --profile ${PROFILE}`,
|
|
185
185
|
},
|
|
186
186
|
safeAsk: {
|
|
187
|
-
en: code => `dsh-
|
|
188
|
-
zh: code => `dsh-
|
|
187
|
+
en: code => `dsh-cli exited unexpectedly (code ${code}). Enter safe mode? [Y/n] `,
|
|
188
|
+
zh: code => `dsh-cli 异常退出(码 ${code})。进入安全模式?[Y/n] `,
|
|
189
189
|
},
|
|
190
190
|
safeHint: {
|
|
191
|
-
en: code => `[dsh-
|
|
192
|
-
zh: code => `[dsh-
|
|
191
|
+
en: code => `[dsh-cli] Exited with code ${code}. Run dsh-cli safe for diagnostics and repair guidance.`,
|
|
192
|
+
zh: code => `[dsh-cli] 异常退出(码 ${code})。可运行 dsh-cli safe 进入安全模式`,
|
|
193
193
|
},
|
|
194
194
|
safeRetrySignaled: {
|
|
195
|
-
en: signal => `[dsh-
|
|
196
|
-
zh: signal => `[dsh-
|
|
195
|
+
en: signal => `[dsh-cli] retry signaled: ${signal}`,
|
|
196
|
+
zh: signal => `[dsh-cli] 重试被信号中断:${signal}`,
|
|
197
197
|
},
|
|
198
198
|
safeTitle: {
|
|
199
|
-
en: role => `dsh-
|
|
200
|
-
zh: role => `dsh-
|
|
199
|
+
en: role => `dsh-cli safe · safe mode (read-only control plane) [${role}]`,
|
|
200
|
+
zh: role => `dsh-cli safe · 安全模式(控制面只读) [${role}]`,
|
|
201
201
|
},
|
|
202
202
|
safeIgnoredArgs: {
|
|
203
|
-
en: n => `[dsh-
|
|
204
|
-
zh: n => `[dsh-
|
|
203
|
+
en: n => `[dsh-cli] ignored ${n} extra argument(s) after \`safe\``,
|
|
204
|
+
zh: n => `[dsh-cli] 已忽略附加参数:${n} 个`,
|
|
205
205
|
},
|
|
206
206
|
safeListUnreadable: {
|
|
207
207
|
en: reason => `Profile inventory unreadable (${reason}). See repair guidance below.`,
|
|
@@ -212,45 +212,45 @@ const MSG = {
|
|
|
212
212
|
zh: '修复命令(需自行执行——安全模式只读):',
|
|
213
213
|
},
|
|
214
214
|
safeRescueCreating: {
|
|
215
|
-
en: `[dsh-
|
|
216
|
-
zh: `[dsh-
|
|
215
|
+
en: `[dsh-cli] Creating the blank rescue profile (${RESCUE_PROFILE})…`,
|
|
216
|
+
zh: `[dsh-cli] 正在创建空白救援 profile(${RESCUE_PROFILE})…`,
|
|
217
217
|
},
|
|
218
218
|
safeRescueExists: {
|
|
219
|
-
en: `[dsh-
|
|
220
|
-
zh: `[dsh-
|
|
219
|
+
en: `[dsh-cli] Rescue profile already exists — starting it as-is.`,
|
|
220
|
+
zh: `[dsh-cli] 救援 profile 已存在——按现状直接启动。`,
|
|
221
221
|
},
|
|
222
222
|
safeRescueCreated: {
|
|
223
|
-
en: `[dsh-
|
|
224
|
-
zh: `[dsh-
|
|
223
|
+
en: `[dsh-cli] Rescue profile created (base + TUI only, no third-party plugins) — starting it.`,
|
|
224
|
+
zh: `[dsh-cli] 救援 profile 已创建(仅 base + TUI,无第三方插件)——正在启动。`,
|
|
225
225
|
},
|
|
226
226
|
// 上面两条是**交互**路径的措辞(菜单选项 5 与 TTY 下的 `safe --rescue` 都经
|
|
227
227
|
// runRescue → startDshSession),说「正在启动」属实。非交互 `safe --rescue`
|
|
228
228
|
// 只做门禁 + 创建/复用就退出(没有终端可交接,见文件末尾该分支),一条会话
|
|
229
229
|
// 都不启动,故它单独用下面两条:不承诺启动,把启动动作交回用户。
|
|
230
230
|
safeRescueExistsNonInteractive: {
|
|
231
|
-
en: `[dsh-
|
|
232
|
-
zh: `[dsh-
|
|
231
|
+
en: `[dsh-cli] Rescue profile already exists and is ready — nothing was started here (no terminal). Start it in a terminal: dsh --profile ${RESCUE_PROFILE}`,
|
|
232
|
+
zh: `[dsh-cli] 救援 profile 已存在且已就绪——此处没有终端,未启动任何会话。请在终端里启动:dsh --profile ${RESCUE_PROFILE}`,
|
|
233
233
|
},
|
|
234
234
|
safeRescueCreatedNonInteractive: {
|
|
235
|
-
en: `[dsh-
|
|
236
|
-
zh: `[dsh-
|
|
235
|
+
en: `[dsh-cli] Rescue profile created (base + TUI only, no third-party plugins) and ready — nothing was started here (no terminal). Start it in a terminal: dsh --profile ${RESCUE_PROFILE}`,
|
|
236
|
+
zh: `[dsh-cli] 救援 profile 已创建(仅 base + TUI,无第三方插件)且已就绪——此处没有终端,未启动任何会话。请在终端里启动:dsh --profile ${RESCUE_PROFILE}`,
|
|
237
237
|
},
|
|
238
238
|
safeRescueFailed: {
|
|
239
|
-
en: detail => `[dsh-
|
|
240
|
-
zh: detail => `[dsh-
|
|
239
|
+
en: detail => `[dsh-cli] Rescue profile creation failed (${detail}). See the diagnostics above and the guidance (option 4).`,
|
|
240
|
+
zh: detail => `[dsh-cli] 救援 profile 创建失败(${detail})。请看上方诊断与指引(选项 4)。`,
|
|
241
241
|
},
|
|
242
242
|
// 干净性门禁的三条拒绝文案:救援的前置是「可证明的干净」,证不出就不启动
|
|
243
243
|
// ——把路径与处置办法交给用户(安全模式只读,不代劳改文件)。
|
|
244
244
|
safeRescueHomePatch: {
|
|
245
245
|
en: path =>
|
|
246
|
-
`[dsh-
|
|
246
|
+
`[dsh-cli] Rescue refused: the home-level patch layer exists:\n` +
|
|
247
247
|
` ${path}\n` +
|
|
248
248
|
` dsh applies that file over EVERY profile, so a broken layer here breaks the\n` +
|
|
249
249
|
` rescue too — "clean" cannot be proven, and this launcher neither parses YAML\n` +
|
|
250
250
|
` nor sees the composed result. Move or fix the file yourself (safe mode is\n` +
|
|
251
251
|
` read-only), then retry.`,
|
|
252
252
|
zh: path =>
|
|
253
|
-
`[dsh-
|
|
253
|
+
`[dsh-cli] 救援被拒绝:home 层补丁文件存在:\n` +
|
|
254
254
|
` ${path}\n` +
|
|
255
255
|
` dsh 把它叠加在每个 profile 之上,home 层坏掉时救援一起坏——「干净」\n` +
|
|
256
256
|
` 无法证明(启动器既不解析 YAML 也拿不到组合结果)。请先自行移走或修好\n` +
|
|
@@ -258,24 +258,24 @@ const MSG = {
|
|
|
258
258
|
},
|
|
259
259
|
safeRescueUnrecognized: {
|
|
260
260
|
en: path =>
|
|
261
|
-
`[dsh-
|
|
261
|
+
`[dsh-cli] Rescue refused: ${path} exists but is not a recognizable profile\n` +
|
|
262
262
|
` (no valid root package.json), so it may belong to someone else. Refusing to\n` +
|
|
263
263
|
` install into an unknown directory. Move or remove it yourself:\n` +
|
|
264
264
|
` rm -rf ${path}`,
|
|
265
265
|
zh: path =>
|
|
266
|
-
`[dsh-
|
|
266
|
+
`[dsh-cli] 救援被拒绝:${path} 已存在,但不是可识别的 profile(根\n` +
|
|
267
267
|
` package.json 缺失或非法),可能是别的用途的目录。拒绝向未知目录安装。\n` +
|
|
268
268
|
` 请自行移走或删除后重试:\n` +
|
|
269
269
|
` rm -rf ${path}`,
|
|
270
270
|
},
|
|
271
271
|
safeRescueUnclean: {
|
|
272
272
|
en: (path, extras) =>
|
|
273
|
-
`[dsh-
|
|
273
|
+
`[dsh-cli] Rescue refused: the existing ${RESCUE_PROFILE} profile declares third-party\n` +
|
|
274
274
|
` plugins (${extras}), so starting it would not be clean:\n ${path}\n` +
|
|
275
275
|
` Remove them yourself, or delete the profile and retry:\n` +
|
|
276
276
|
` rm -rf ${path}`,
|
|
277
277
|
zh: (path, extras) =>
|
|
278
|
-
`[dsh-
|
|
278
|
+
`[dsh-cli] 救援被拒绝:既有的 ${RESCUE_PROFILE} profile 声明了第三方插件\n` +
|
|
279
279
|
` (${extras}),启动它就不是干净环境:\n ${path}\n` +
|
|
280
280
|
` 请自行卸载它们,或删除该 profile 后重试:\n` +
|
|
281
281
|
` rm -rf ${path}`,
|
|
@@ -284,13 +284,13 @@ const MSG = {
|
|
|
284
284
|
// 与 home 层同一类隐藏面,同样不解析 YAML——非默认内容一律拒绝。
|
|
285
285
|
safeRescuePatched: {
|
|
286
286
|
en: path =>
|
|
287
|
-
`[dsh-
|
|
287
|
+
`[dsh-cli] Rescue refused: the profile's own patch layer carries entries:\n` +
|
|
288
288
|
` ${path}\n` +
|
|
289
289
|
` dsh composes that file into the profile after the bundle layers, and this\n` +
|
|
290
290
|
` launcher neither parses YAML nor sees the composed result, so "clean" cannot\n` +
|
|
291
291
|
` be proven. Empty the file (or move it aside) yourself, then retry.`,
|
|
292
292
|
zh: path =>
|
|
293
|
-
`[dsh-
|
|
293
|
+
`[dsh-cli] 救援被拒绝:profile 自带的补丁层里有条目:\n` +
|
|
294
294
|
` ${path}\n` +
|
|
295
295
|
` dsh 会把该文件组合进 profile(排在 bundle 层之后),而启动器既不解析\n` +
|
|
296
296
|
` YAML 也拿不到组合结果——「干净」无法证明。请自行清空该文件(或移走)\n` +
|
|
@@ -298,30 +298,30 @@ const MSG = {
|
|
|
298
298
|
},
|
|
299
299
|
safeRescueStray: {
|
|
300
300
|
en: (path, stray) =>
|
|
301
|
-
`[dsh-
|
|
301
|
+
`[dsh-cli] Rescue refused: ${path} holds entries this launcher did not generate\n` +
|
|
302
302
|
` (${stray}), so removing the half-installed profile would delete your files.\n` +
|
|
303
303
|
` Move them aside yourself, then retry (or delete the whole directory):\n` +
|
|
304
304
|
` rm -rf ${path}`,
|
|
305
305
|
zh: (path, stray) =>
|
|
306
|
-
`[dsh-
|
|
306
|
+
`[dsh-cli] 救援被拒绝:${path} 里有不是本启动器生成的条目(${stray}),\n` +
|
|
307
307
|
` 清理半装状态会连你的文件一起删掉,因此不代劳。请先自行移走,再重试\n` +
|
|
308
308
|
` (或整个删除该目录):\n` +
|
|
309
309
|
` rm -rf ${path}`,
|
|
310
310
|
},
|
|
311
311
|
safeRescueCleanup: {
|
|
312
312
|
en: path =>
|
|
313
|
-
`[dsh-
|
|
313
|
+
`[dsh-cli] removed the half-installed profile (only dsh/pnpm-generated files were\n` +
|
|
314
314
|
` present, checked before removing) so the next attempt starts clean:\n ${path}`,
|
|
315
315
|
zh: path =>
|
|
316
|
-
`[dsh-
|
|
316
|
+
`[dsh-cli] 已清理半装的 profile(删除前已确认目录里只有 dsh/pnpm 生成的文件),\n` +
|
|
317
317
|
` 下次尝试将从零开始:\n ${path}`,
|
|
318
318
|
},
|
|
319
319
|
safeRescueRemoveFailed: {
|
|
320
320
|
en: (path, reason) =>
|
|
321
|
-
`[dsh-
|
|
321
|
+
`[dsh-cli] could not remove the half-installed profile:\n ${path}\n ${reason}\n` +
|
|
322
322
|
` Remove it yourself, then retry.`,
|
|
323
323
|
zh: (path, reason) =>
|
|
324
|
-
`[dsh-
|
|
324
|
+
`[dsh-cli] 无法删除半装的 profile:\n ${path}\n ${reason}\n` +
|
|
325
325
|
` 请自行删除后重试。`,
|
|
326
326
|
},
|
|
327
327
|
safeMenuLabels: {
|
|
@@ -330,7 +330,7 @@ const MSG = {
|
|
|
330
330
|
doctor: 'Run environment diagnostics',
|
|
331
331
|
inventory: 'Show profile plugin inventory (read-only)',
|
|
332
332
|
guide: 'Show repair command guidance',
|
|
333
|
-
rescue: 'Create blank rescue profile and start clean (dsh-
|
|
333
|
+
rescue: 'Create blank rescue profile and start clean (dsh-cli-safe)',
|
|
334
334
|
exit: code => `Exit (exit code ${code})`,
|
|
335
335
|
prompt: 'safe> ',
|
|
336
336
|
invalid: 'Invalid choice — enter 1-6:',
|
|
@@ -346,7 +346,7 @@ const MSG = {
|
|
|
346
346
|
doctor: '运行环境诊断',
|
|
347
347
|
inventory: '查看 profile 插件清单(只读)',
|
|
348
348
|
guide: '显示修复命令指引',
|
|
349
|
-
rescue: '创建空白救援 profile 并干净启动(dsh-
|
|
349
|
+
rescue: '创建空白救援 profile 并干净启动(dsh-cli-safe)',
|
|
350
350
|
exit: code => `退出(退出码 ${code})`,
|
|
351
351
|
prompt: 'safe> ',
|
|
352
352
|
invalid: '无效选择——请输入 1-6:',
|
|
@@ -367,7 +367,7 @@ const MSG = {
|
|
|
367
367
|
notReadyReason: 'profile not ready (missing or half-installed)',
|
|
368
368
|
uninstallThird: ' # Remove third-party plugins (one by one):',
|
|
369
369
|
nothingThird: ' # No third-party direct dependencies to uninstall',
|
|
370
|
-
reinstallTui: ' # Reinstall/align the TUI (see dsh-
|
|
370
|
+
reinstallTui: ' # Reinstall/align the TUI (see dsh-cli doctor for the version):',
|
|
371
371
|
versionPlaceholder: '<version>',
|
|
372
372
|
diagnostics: ' # Environment diagnostics:',
|
|
373
373
|
globalUpgrade: ' # Global upgrade when the launcher is too old:',
|
|
@@ -382,7 +382,7 @@ const MSG = {
|
|
|
382
382
|
notReadyReason: 'profile 未就绪(未安装或残缺)',
|
|
383
383
|
uninstallThird: ' # 卸载第三方插件(逐个执行):',
|
|
384
384
|
nothingThird: ' # 无第三方直接依赖可卸载',
|
|
385
|
-
reinstallTui: ' # 重装/对齐 TUI(版本见 dsh-
|
|
385
|
+
reinstallTui: ' # 重装/对齐 TUI(版本见 dsh-cli doctor):',
|
|
386
386
|
versionPlaceholder: '<版本>',
|
|
387
387
|
diagnostics: ' # 环境诊断:',
|
|
388
388
|
globalUpgrade: ' # 启动器过旧时的全局升级:',
|
|
@@ -400,7 +400,7 @@ const MSG = {
|
|
|
400
400
|
en: {
|
|
401
401
|
dshMissing: 'not found — install it first: npm install -g @deepseek-ai/dsh',
|
|
402
402
|
pnpmMissing: 'not found — needed for install/update: npm install -g pnpm',
|
|
403
|
-
profileMissing: 'not installed — run `dsh-
|
|
403
|
+
profileMissing: 'not installed — run `dsh-cli` once to bootstrap it',
|
|
404
404
|
aligned: 'aligned',
|
|
405
405
|
profileNewer: v => `profile is newer — align the launcher: npm install -g ${PACKAGE}@${v}`,
|
|
406
406
|
profileOlder: v => `profile is older — align it: dsh plugin --profile ${PROFILE} add ${PACKAGE}@${v}`,
|
|
@@ -413,7 +413,7 @@ const MSG = {
|
|
|
413
413
|
zh: {
|
|
414
414
|
dshMissing: '未找到——请先安装: npm install -g @deepseek-ai/dsh',
|
|
415
415
|
pnpmMissing: '未找到——安装/升级需要它: npm install -g pnpm',
|
|
416
|
-
profileMissing: '未安装——运行一次 `dsh-
|
|
416
|
+
profileMissing: '未安装——运行一次 `dsh-cli` 即可自举',
|
|
417
417
|
aligned: '已对齐',
|
|
418
418
|
profileNewer: v => `profile 较新——对齐启动器: npm install -g ${PACKAGE}@${v}`,
|
|
419
419
|
profileOlder: v => `profile 较旧——对齐它: dsh plugin --profile ${PROFILE} add ${PACKAGE}@${v}`,
|
|
@@ -426,23 +426,23 @@ const MSG = {
|
|
|
426
426
|
},
|
|
427
427
|
updateUnavailable: {
|
|
428
428
|
en:
|
|
429
|
-
`[dsh-
|
|
429
|
+
`[dsh-cli] \`update\` needs the profile's compiled copy, but it is missing or too old to carry the CLI entry.\n` +
|
|
430
430
|
`Update manually instead:\n dsh plugin --profile ${PROFILE} add ${PACKAGE}@latest`,
|
|
431
431
|
zh:
|
|
432
|
-
`[dsh-
|
|
432
|
+
`[dsh-cli] \`update\` 需要 profile 的编译产物,但它缺失或版本过旧、不含 CLI 入口。\n` +
|
|
433
433
|
`请改用手工升级:\n dsh plugin --profile ${PROFILE} add ${PACKAGE}@latest`,
|
|
434
434
|
},
|
|
435
435
|
migrateUnavailable: {
|
|
436
436
|
en:
|
|
437
|
-
`[dsh-
|
|
438
|
-
`Update first:\n dsh-
|
|
437
|
+
`[dsh-cli] \`migrate\` needs the profile's compiled copy, but it is missing or too old to carry the CLI entry.\n` +
|
|
438
|
+
`Update first:\n dsh-cli update`,
|
|
439
439
|
zh:
|
|
440
|
-
`[dsh-
|
|
441
|
-
`请先升级:\n dsh-
|
|
440
|
+
`[dsh-cli] \`migrate\` 需要 profile 的编译产物,但它缺失或版本过旧、不含 CLI 入口。\n` +
|
|
441
|
+
`请先升级:\n dsh-cli update`,
|
|
442
442
|
},
|
|
443
443
|
helpText: {
|
|
444
444
|
en:
|
|
445
|
-
`Usage: dsh-
|
|
445
|
+
`Usage: dsh-cli|dst [command] [options] [path|url]\n\n` +
|
|
446
446
|
`Commands:\n` +
|
|
447
447
|
` update Update the ${PROFILE} profile to the latest release\n` +
|
|
448
448
|
` migrate [agent] Import conversations from claude-code/codex/omp/zcode/grok-build (--dry-run to preview)\n` +
|
|
@@ -457,7 +457,7 @@ const MSG = {
|
|
|
457
457
|
` <path|url> Open with the given workspace target\n\n` +
|
|
458
458
|
`Any other argument is forwarded to \`dsh --profile ${PROFILE}\`.`,
|
|
459
459
|
zh:
|
|
460
|
-
`用法:dsh-
|
|
460
|
+
`用法:dsh-cli|dst [命令] [选项] [路径|URL]\n\n` +
|
|
461
461
|
`命令:\n` +
|
|
462
462
|
` update 将 ${PROFILE} profile 升级到最新版本\n` +
|
|
463
463
|
` migrate [agent] 迁移 claude-code/codex/omp/zcode/grok-build 的对话(--dry-run 预览)\n` +
|
|
@@ -489,12 +489,12 @@ const sameDir = (a, b) => {
|
|
|
489
489
|
|
|
490
490
|
const dshHome = process.env.DSH_HOME || join(homedir(), '.dsh')
|
|
491
491
|
const profileDir = join(dshHome, 'profiles', PROFILE)
|
|
492
|
-
const profilePkgDir = join(profileDir, 'node_modules', 'dsh-cli')
|
|
492
|
+
const profilePkgDir = join(profileDir, 'node_modules', '@askdkc', 'dsh-cli')
|
|
493
493
|
const profileBin = join(profilePkgDir, 'bin', 'dsh-tui.js')
|
|
494
494
|
const installedPkgPath = join(profilePkgDir, 'package.json')
|
|
495
495
|
const runningInsideProfile = sameDir(ownDir, profilePkgDir)
|
|
496
496
|
const rescueProfileDir = join(dshHome, 'profiles', RESCUE_PROFILE)
|
|
497
|
-
const rescueInstalledPkg = join(rescueProfileDir, 'node_modules', 'dsh-cli', 'package.json')
|
|
497
|
+
const rescueInstalledPkg = join(rescueProfileDir, 'node_modules', '@askdkc', 'dsh-cli', 'package.json')
|
|
498
498
|
// profile 层补丁文件:dsh 给**每个**新建 profile 都写它(默认只有注释与 `[]`),
|
|
499
499
|
// 并在 bundle 层之后把它组合进 profile(dsh-app-boot `loadProfile` →
|
|
500
500
|
// `composed.profile.patches`)。它与下面的 home 层是同一类隐藏面——见
|
|
@@ -526,7 +526,7 @@ const GENERATED_FILE_ENTRIES = new Set([
|
|
|
526
526
|
|
|
527
527
|
// ─── 子命令:version / help ──────────────────────────────────────────────────
|
|
528
528
|
// 只认第一个参数,且在角色分支之前应答:两种角色都不经过委托与自举——
|
|
529
|
-
// `dsh-
|
|
529
|
+
// `dsh-cli --help` 在没装 dsh、profile 残缺时也必须能出(否则求助命令
|
|
530
530
|
// 本身先触发一轮安装)。后续位置的同名字符串不截获,保持既有透传与
|
|
531
531
|
// 工作区目标嗅探行为不变。
|
|
532
532
|
const subcommand = process.argv[2]
|
|
@@ -575,7 +575,7 @@ const runDoctorChecks = () => {
|
|
|
575
575
|
const lines = []
|
|
576
576
|
let hardFailure = false
|
|
577
577
|
const report = (ok, label, detail) => lines.push(`${ok ? '✓' : '✗'} ${label}: ${detail}`)
|
|
578
|
-
lines.push(`dsh-
|
|
578
|
+
lines.push(`dsh-cli doctor · ${PACKAGE} ${ownVersion ?? 'unknown'}`)
|
|
579
579
|
report(true, 'node', `${process.version} · ${process.platform} ${process.arch}`)
|
|
580
580
|
const probeVersion = command => {
|
|
581
581
|
const probe = spawnSync(...cmd(command, ['--version']), { stdio: 'pipe', encoding: 'utf8', ...shellOpt })
|
|
@@ -668,7 +668,7 @@ const renderGuide = lines => {
|
|
|
668
668
|
lines.push(L.reinstallTui)
|
|
669
669
|
lines.push(` dsh plugin --profile ${PROFILE} add ${PACKAGE}@${L.versionPlaceholder}`)
|
|
670
670
|
lines.push(L.diagnostics)
|
|
671
|
-
lines.push(` dsh-
|
|
671
|
+
lines.push(` dsh-cli doctor`)
|
|
672
672
|
lines.push(L.globalUpgrade)
|
|
673
673
|
lines.push(` npm install -g --legacy-peer-deps ${PACKAGE}@${L.versionPlaceholder}`)
|
|
674
674
|
lines.push(L.rescueProfile)
|
|
@@ -1163,14 +1163,14 @@ const checkProfileAlignment = installedVersion => {
|
|
|
1163
1163
|
const [ownMajor, ownMinor] = majorMinor(ownVersion)
|
|
1164
1164
|
if (installedMajor < ownMajor || (installedMajor === ownMajor && installedMinor < ownMinor)) {
|
|
1165
1165
|
console.error(
|
|
1166
|
-
`[dsh-
|
|
1166
|
+
`[dsh-cli] cannot start: the profile runs v${installedVersion} but this launcher is v${ownVersion}.\n` +
|
|
1167
1167
|
` dsh plugin --profile ${PROFILE} add ${PACKAGE}@${ownVersion}`,
|
|
1168
1168
|
)
|
|
1169
1169
|
process.exit(1)
|
|
1170
1170
|
}
|
|
1171
1171
|
if (isVersionNewer(installedVersion, ownVersion)) {
|
|
1172
1172
|
console.error(
|
|
1173
|
-
`[dsh-
|
|
1173
|
+
`[dsh-cli] note: the profile is already v${installedVersion}; this launcher copy is v${ownVersion}.\n` +
|
|
1174
1174
|
` npm install -g --legacy-peer-deps ${PACKAGE}@${installedVersion}\n` +
|
|
1175
1175
|
`(--legacy-peer-deps avoids an npm 12 peer-resolution crash, see issue #459)`,
|
|
1176
1176
|
)
|
|
@@ -1178,7 +1178,7 @@ const checkProfileAlignment = installedVersion => {
|
|
|
1178
1178
|
// profile 更旧但同 minor(patch 级错位):允许启动,指引用 add 把
|
|
1179
1179
|
// profile 对齐到启动器版本(精确版本,@latest 可能越过对齐点)。
|
|
1180
1180
|
console.error(
|
|
1181
|
-
`[dsh-
|
|
1181
|
+
`[dsh-cli] note: the profile is running v${installedVersion} but this launcher is v${ownVersion}.\n` +
|
|
1182
1182
|
` dsh plugin --profile ${PROFILE} add ${PACKAGE}@${ownVersion}`,
|
|
1183
1183
|
)
|
|
1184
1184
|
}
|
|
@@ -1270,7 +1270,7 @@ if (subcommand === 'migrate') {
|
|
|
1270
1270
|
if (!runningInsideProfile && ownVersion !== undefined && process.env.DSH_TUI_NO_DELEGATE !== '1') {
|
|
1271
1271
|
if (!profileReady()) bootstrapProfile()
|
|
1272
1272
|
// Refuse to delegate into a profile from an older release line: the profile
|
|
1273
|
-
// copy would launch `dsh --profile dsh-
|
|
1273
|
+
// copy would launch `dsh --profile dsh-cli` against a composition built from
|
|
1274
1274
|
// this launcher's patch surface and fail inside the loader.
|
|
1275
1275
|
checkProfileAlignment(profileVersion())
|
|
1276
1276
|
// 委托 profile 内副本执行全部启动逻辑。外层代际通过
|
package/cordis.patch.yml
CHANGED
|
@@ -293,22 +293,22 @@
|
|
|
293
293
|
# Generic terminal workspace registry. Optional plugins add providers;
|
|
294
294
|
# the TUI itself always supplies LOCAL and has no provider-specific code.
|
|
295
295
|
- id: dsh-tui-workspaces
|
|
296
|
-
name: 'dsh-cli/workspaces'
|
|
296
|
+
name: '@askdkc/dsh-cli/workspaces'
|
|
297
297
|
|
|
298
298
|
# Optional plugins contribute nested slash-command completion here;
|
|
299
299
|
# execution and durable command events remain owned by dsh-commands.
|
|
300
300
|
- id: dsh-tui-command-trees
|
|
301
|
-
name: 'dsh-cli/command-trees'
|
|
301
|
+
name: '@askdkc/dsh-cli/command-trees'
|
|
302
302
|
# Optional plugins declare editable settings sections here (issue #165);
|
|
303
303
|
# storage, validation and writes remain owned by the dsh settings service.
|
|
304
304
|
- id: dsh-tui-settings-sections
|
|
305
|
-
name: 'dsh-cli/settings-sections'
|
|
305
|
+
name: '@askdkc/dsh-cli/settings-sections'
|
|
306
306
|
|
|
307
307
|
# Optional plugins register full-screen scenes (trajectory-style whole-
|
|
308
308
|
# terminal views) here and open them from their own command handlers;
|
|
309
309
|
# rendering and input ownership remain owned by the TUI's Chat screen.
|
|
310
310
|
- id: dsh-tui-scenes
|
|
311
|
-
name: 'dsh-cli/scenes'
|
|
311
|
+
name: '@askdkc/dsh-cli/scenes'
|
|
312
312
|
|
|
313
313
|
# Plugin-interop anchor (Community Consensus v0.15): the unified grant
|
|
314
314
|
# store, runtime generation id, and Host Descriptor live here; later
|
|
@@ -317,7 +317,7 @@
|
|
|
317
317
|
# once for the whole alignment. Mounted ahead of the extensions row and
|
|
318
318
|
# any third-party plugin row.
|
|
319
319
|
- id: dsh-tui-plugin-host
|
|
320
|
-
name: 'dsh-cli/plugin-host'
|
|
320
|
+
name: '@askdkc/dsh-cli/plugin-host'
|
|
321
321
|
|
|
322
322
|
# Plugin-facing UI seams (the pi-style extension surface): managed
|
|
323
323
|
# dialogs (select/confirm/input), keyed status-line contributions,
|
|
@@ -326,7 +326,7 @@
|
|
|
326
326
|
# tui/compact, …) are fired by the channel on the cordis bus directly
|
|
327
327
|
# and need no row.
|
|
328
328
|
- id: dsh-tui-extensions
|
|
329
|
-
name: 'dsh-cli/extensions'
|
|
329
|
+
name: '@askdkc/dsh-cli/extensions'
|
|
330
330
|
|
|
331
331
|
# The agent-preset roster (issue #8): `ctx.agentPresets`, the service the
|
|
332
332
|
# TUI composes every session's model-facing world from. 0.1.2 packages
|
|
@@ -393,7 +393,7 @@
|
|
|
393
393
|
# the plugin module's own inject is empty so a stale patch cannot
|
|
394
394
|
# deadlock a composition lacking these services (#183 pattern).
|
|
395
395
|
- id: dsh-tui-auth
|
|
396
|
-
name: 'dsh-cli/oauth'
|
|
396
|
+
name: '@askdkc/dsh-cli/oauth'
|
|
397
397
|
inject: [llm, commands]
|
|
398
398
|
|
|
399
399
|
# The interactive front door. The plugin creates/resumes its agent at
|
|
@@ -402,7 +402,7 @@
|
|
|
402
402
|
# feeds the session id through DSH_TUI_RESUME_SESSION (see
|
|
403
403
|
# src/sessionHistory.ts for the launcher contract).
|
|
404
404
|
- id: dsh-tui
|
|
405
|
-
name: 'dsh-cli'
|
|
405
|
+
name: '@askdkc/dsh-cli'
|
|
406
406
|
# The entry-level dependency augments the plugin's `agents` inject and
|
|
407
407
|
# prevents startup Session creation from racing WorkspaceRegistry init.
|
|
408
408
|
inject: [workspaceRegistry, agents, tuiWorkspaces, tuiScenes, tuiDialogs, tuiStatus, tuiShortcuts, tuiRenderers, tuiThemes]
|
|
@@ -476,7 +476,7 @@
|
|
|
476
476
|
# TUI's working line comes from; never persist activity/status, so the
|
|
477
477
|
# shared log remains Web-readable.
|
|
478
478
|
- id: working-activity
|
|
479
|
-
name: 'dsh-cli/working-activity'
|
|
479
|
+
name: '@askdkc/dsh-cli/working-activity'
|
|
480
480
|
config:
|
|
481
481
|
publish: false
|
|
482
482
|
publishIntervalMs: 500
|
package/cordis.yml
CHANGED
|
@@ -25,32 +25,32 @@
|
|
|
25
25
|
policy: !!js "process.platform === 'win32' ? 'never' : ((process.env.DSH_PERMISSION_MODE ?? 'workspace-write') === 'danger-full-access' ? 'never' : 'ask')"
|
|
26
26
|
|
|
27
27
|
- id: dsh-tui-workspaces
|
|
28
|
-
name: 'dsh-cli/workspaces'
|
|
28
|
+
name: '@askdkc/dsh-cli/workspaces'
|
|
29
29
|
|
|
30
30
|
- id: dsh-tui-command-trees
|
|
31
|
-
name: 'dsh-cli/command-trees'
|
|
31
|
+
name: '@askdkc/dsh-cli/command-trees'
|
|
32
32
|
|
|
33
33
|
# Optional plugins declare editable settings sections here (issue #165);
|
|
34
34
|
# storage, validation and writes remain owned by the dsh settings service.
|
|
35
35
|
- id: dsh-tui-settings-sections
|
|
36
|
-
name: 'dsh-cli/settings-sections'
|
|
36
|
+
name: '@askdkc/dsh-cli/settings-sections'
|
|
37
37
|
|
|
38
38
|
- id: dsh-tui-scenes
|
|
39
|
-
name: 'dsh-cli/scenes'
|
|
39
|
+
name: '@askdkc/dsh-cli/scenes'
|
|
40
40
|
|
|
41
41
|
# Plugin-interop anchor (v0.15): unified grant store, runtime generation
|
|
42
42
|
# id, Host Descriptor; later contract surfaces mount off this row's apply.
|
|
43
43
|
- id: dsh-tui-plugin-host
|
|
44
|
-
name: 'dsh-cli/plugin-host'
|
|
44
|
+
name: '@askdkc/dsh-cli/plugin-host'
|
|
45
45
|
|
|
46
46
|
# Plugin-facing UI seams: managed dialogs, status-line contributions,
|
|
47
47
|
# keyboard shortcuts, custom session-entry renderers, and runtime themes
|
|
48
48
|
# (decision events are fired by the channel and need no row).
|
|
49
49
|
- id: dsh-tui-extensions
|
|
50
|
-
name: 'dsh-cli/extensions'
|
|
50
|
+
name: '@askdkc/dsh-cli/extensions'
|
|
51
51
|
|
|
52
52
|
- id: dsh-tui
|
|
53
|
-
name: 'dsh-cli'
|
|
53
|
+
name: '@askdkc/dsh-cli'
|
|
54
54
|
# Entry-level only: orders/rebinds optional extension services on reload;
|
|
55
55
|
# dsh-tui does not hard-inject them at code level, so stale profiles degrade
|
|
56
56
|
# to static themes and inert extension surfaces instead of deadlocking boot.
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
# from install layouts that never link transitive dependencies into the
|
|
216
216
|
# boot anchor's node_modules — pnpm's isolated profile layout, issue #60.
|
|
217
217
|
- id: working-activity
|
|
218
|
-
name: 'dsh-cli/working-activity'
|
|
218
|
+
name: '@askdkc/dsh-cli/working-activity'
|
|
219
219
|
config:
|
|
220
220
|
publish: false
|
|
221
221
|
publishIntervalMs: 500
|
|
@@ -24,7 +24,7 @@ function freezeDeep(value, seen = new WeakSet()) {
|
|
|
24
24
|
export function readOwnPackageVersion() {
|
|
25
25
|
const candidates = [];
|
|
26
26
|
try {
|
|
27
|
-
candidates.push(fileURLToPath(import.meta.resolve('dsh-cli/package.json')));
|
|
27
|
+
candidates.push(fileURLToPath(import.meta.resolve('@askdkc/dsh-cli/package.json')));
|
|
28
28
|
}
|
|
29
29
|
catch {
|
|
30
30
|
// Fall through to the source/package walk-up path.
|
|
@@ -40,7 +40,7 @@ export function readOwnPackageVersion() {
|
|
|
40
40
|
for (const candidate of candidates) {
|
|
41
41
|
try {
|
|
42
42
|
const manifest = JSON.parse(readFileSync(candidate, 'utf8'));
|
|
43
|
-
if (manifest.name === 'dsh-cli'
|
|
43
|
+
if (manifest.name === '@askdkc/dsh-cli'
|
|
44
44
|
&& typeof manifest.version === 'string'
|
|
45
45
|
&& manifest.version !== '')
|
|
46
46
|
return manifest.version;
|
|
@@ -13,7 +13,7 @@ import { type WhaleIntroId } from './whaleFrames.js';
|
|
|
13
13
|
* unsubscribed, zero timers.
|
|
14
14
|
*
|
|
15
15
|
* Layout: the 13-row pixel whale beside a text column of matching height —
|
|
16
|
-
* the `✦ dsh-
|
|
16
|
+
* the `✦ dsh-CLI` wordmark with version, the `DEEPSEEK`/`HARNESS` tagline in
|
|
17
17
|
* the 5-row block font (brand-blue → ice gradient), the model/effort and
|
|
18
18
|
* cwd in plain text (no brand-color highlight), the startup tip, and below
|
|
19
19
|
* the whale the welcome tagline, centered under the art, in ice
|
|
@@ -69,7 +69,7 @@ function capitalize(text) {
|
|
|
69
69
|
* unsubscribed, zero timers.
|
|
70
70
|
*
|
|
71
71
|
* Layout: the 13-row pixel whale beside a text column of matching height —
|
|
72
|
-
* the `✦ dsh-
|
|
72
|
+
* the `✦ dsh-CLI` wordmark with version, the `DEEPSEEK`/`HARNESS` tagline in
|
|
73
73
|
* the 5-row block font (brand-blue → ice gradient), the model/effort and
|
|
74
74
|
* cwd in plain text (no brand-color highlight), the startup tip, and below
|
|
75
75
|
* the whale the welcome tagline, centered under the art, in ice
|
|
@@ -231,7 +231,7 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
231
231
|
setHeartSeq(0);
|
|
232
232
|
setHeartKey(k => k + 1);
|
|
233
233
|
}
|
|
234
|
-
}, children: _jsx(WhaleArt, { frameIndex: frameIndex, pose: settled && whaleIdle && !whaleFrozen ? (idlePose ?? RESTING_POSE) : undefined, width: FULL_WHALE_WIDTH }) })), _jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-
|
|
234
|
+
}, children: _jsx(WhaleArt, { frameIndex: frameIndex, pose: settled && whaleIdle && !whaleFrozen ? (idlePose ?? RESTING_POSE) : undefined, width: FULL_WHALE_WIDTH }) })), _jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-CLI', t, wordmarkRGB, wordmarkShimmerRGB, 60), _jsx(Text, { dimColor: true, children: ' v' + VERSION })] }), bigDeepSeek.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `ds-${index}`))), bigHarness.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `h-${index}`))), _jsxs(Text, { wrap: "truncate-end", children: [model, effort !== undefined && _jsx(Text, { dimColor: true, children: ' · ' + capitalize(effort) + ' effort' })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd }), _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { dimColor: true, children: tr('logo-tip-prefix') }), getLang() === 'zh' ? randomTip.zh : randomTip.en, _jsx(Text, { dimColor: true, children: ' · /tips ' + tr('logo-tip-more') })] }), driftLine != null && (_jsxs(Text, { color: "warning", wrap: "wrap", children: ["\u26A0", ' ', tOr(`logo-drift-${driftLine.kind}`, `The dsh engine (${driftLine.versions.join(' / ')}) does not match the validated ${UPSTREAM_VALIDATED_VERSION}; reinstall via npm i -g @deepseek-ai/dsh@${UPSTREAM_VALIDATED_VERSION}.`, {
|
|
235
235
|
installed: driftLine.versions.join(' / '),
|
|
236
236
|
validated: UPSTREAM_VALIDATED_VERSION,
|
|
237
237
|
primary: UPSTREAM_VALIDATED_VERSION,
|