dsh-ssh-tui 0.3.7 → 0.3.9
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 +49 -28
- package/README.md +29 -14
- package/lib/i18n/en.js +429 -0
- package/lib/i18n/en.js.map +1 -0
- package/lib/i18n/index.js +94 -0
- package/lib/i18n/index.js.map +1 -0
- package/lib/i18n/zh.js +429 -0
- package/lib/i18n/zh.js.map +1 -0
- package/lib/index.js +71 -8
- package/lib/index.js.map +1 -1
- package/lib/picker.js +5 -4
- package/lib/picker.js.map +1 -1
- package/lib/route-memory.js +23 -4
- package/lib/route-memory.js.map +1 -1
- package/lib/session-list.js +46 -0
- package/lib/session-list.js.map +1 -1
- package/lib/session-lock.js +3 -6
- package/lib/session-lock.js.map +1 -1
- package/lib/subagent-model.js +81 -14
- package/lib/subagent-model.js.map +1 -1
- package/lib/supergrok-token.js +132 -0
- package/lib/supergrok-token.js.map +1 -0
- package/lib/tui.js +950 -346
- package/lib/tui.js.map +1 -1
- package/lib/types/i18n/en.d.ts +2 -0
- package/lib/types/i18n/index.d.ts +28 -0
- package/lib/types/i18n/zh.d.ts +2 -0
- package/lib/types/route-memory.d.ts +10 -0
- package/lib/types/session-list.d.ts +16 -0
- package/lib/types/subagent-model.d.ts +28 -2
- package/lib/types/supergrok-token.d.ts +22 -0
- package/lib/types/tui.d.ts +123 -3
- package/lib/update-check.js +2 -1
- package/lib/update-check.js.map +1 -1
- package/package.json +1 -1
package/lib/i18n/zh.js
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
/** Chinese UI catalog. Keys are stable; values are the current TUI copy. */
|
|
2
|
+
export const zh = {
|
|
3
|
+
'route.deepseek': 'DeepSeek 官方',
|
|
4
|
+
'route.supergrokKind': 'SuperGrok / X Premium 订阅',
|
|
5
|
+
'route.supergrokShort': 'SuperGrok',
|
|
6
|
+
'route.go': 'OpenCode Go',
|
|
7
|
+
'route.zen': 'OpenCode Zen',
|
|
8
|
+
'route.registered': '已注册提供商',
|
|
9
|
+
'paint.localMs': '本机绘制 {ms}ms',
|
|
10
|
+
'paint.sshMs': 'SSH 绘制 {ms}ms',
|
|
11
|
+
'paint.sshMsUnprobed': 'SSH 绘制 {ms}ms(未测到往返)',
|
|
12
|
+
'paint.localChip': '本机 {pips}',
|
|
13
|
+
'paint.sshChip': 'SSH {pips} {delay}',
|
|
14
|
+
'footer.turnsSteps': '{turns} 轮 · {steps} 步',
|
|
15
|
+
'footer.tokens': '输入 {input} · 输出 {output}',
|
|
16
|
+
'footer.ttft': '首字 {duration}',
|
|
17
|
+
'footer.llmMs': '模型 {duration}',
|
|
18
|
+
'footer.toolMs': '工具 {duration}',
|
|
19
|
+
'footer.cacheHit': '缓存命中 {percent}%',
|
|
20
|
+
'footer.planReview': '计划待审',
|
|
21
|
+
'footer.waiting': '等待回答',
|
|
22
|
+
'footer.compacting': '压缩中',
|
|
23
|
+
'footer.retry': '重试 {retry}/{max}',
|
|
24
|
+
'footer.subagents': '子代理 {count}',
|
|
25
|
+
'footer.tools': '工具 {count}',
|
|
26
|
+
'footer.planOpen': '本轮未收尾',
|
|
27
|
+
'footer.planSwitching': '计划切换中',
|
|
28
|
+
'footer.planMode': '计划模式',
|
|
29
|
+
'footer.goalActive': '目标进行中',
|
|
30
|
+
'footer.goalPaused': '目标已暂停',
|
|
31
|
+
'footer.goalBlocked': '目标受阻',
|
|
32
|
+
'footer.waitSeconds': '等待 {seconds}s',
|
|
33
|
+
'footer.running': '运行中',
|
|
34
|
+
'footer.idle': '空闲',
|
|
35
|
+
'footer.search': '搜索 {index}/{total}',
|
|
36
|
+
'footer.inputFolded': '输入已折叠',
|
|
37
|
+
'footer.multiLine': '多行输入',
|
|
38
|
+
'footer.queued': '排队 {count}',
|
|
39
|
+
'footer.cwdChip': '目录:{name}',
|
|
40
|
+
'footer.effortDefault': '跟随提供商默认',
|
|
41
|
+
'status.quotaNone': 'quota: none',
|
|
42
|
+
'status.quotaLine': 'quota: {plan} {parts}',
|
|
43
|
+
'status.questionsWaiting': 'questions: waiting {count}',
|
|
44
|
+
'status.questionsNone': 'questions: none',
|
|
45
|
+
'status.planOff': 'off',
|
|
46
|
+
'status.planPending': 'pending',
|
|
47
|
+
'status.planOn': 'on',
|
|
48
|
+
'sub.followParent': '跟随父',
|
|
49
|
+
'sub.pinned': '钉死 {provider}',
|
|
50
|
+
'sub.sameFamily': '同族',
|
|
51
|
+
'sub.crossFamily': '跨族',
|
|
52
|
+
'sub.light': '轻量',
|
|
53
|
+
'sub.expensiveNoLight': '较贵(目录无轻量)',
|
|
54
|
+
'sub.expensive': '较贵',
|
|
55
|
+
'sub.line': 'subagent: {model} · {follow} · {fit}',
|
|
56
|
+
'quota.alert': '⚠ 请注意你的 {plan} 的每{period}额度还剩余 {percent}%{reset},请合理规划剩余额度的使用。',
|
|
57
|
+
'quota.periodHourly': '5 小时',
|
|
58
|
+
'quota.periodWeekly': '周',
|
|
59
|
+
'quota.periodMonthly': '月',
|
|
60
|
+
'quota.periodUnknown': '周期',
|
|
61
|
+
'quota.resetIn': '约 {duration} 后重置',
|
|
62
|
+
'quota.resetAt': '已于 {when} 重置',
|
|
63
|
+
'quota.resetInParen': '(约 {duration} 后重置)',
|
|
64
|
+
'quota.throttled': '已限流',
|
|
65
|
+
'quota.ok': '正常',
|
|
66
|
+
'quota.unknown': '未知状态',
|
|
67
|
+
'quota.windowHourly': '滚动 5 小时',
|
|
68
|
+
'quota.windowWeekly': '本周',
|
|
69
|
+
'quota.windowMonthly': '本月',
|
|
70
|
+
'quota.snapshotHeader': '{plan} 额度({provider})',
|
|
71
|
+
'quota.snapshotWindow': ' {label} · {bar} 剩余 {percent}%{reset}',
|
|
72
|
+
'quota.unrecognized': '额度接口返回格式无法识别',
|
|
73
|
+
'quota.supergrokUnrecognized': 'SuperGrok 额度接口返回格式无法识别',
|
|
74
|
+
'quota.deepseekUnrecognized': 'DeepSeek 余额接口返回格式无法识别',
|
|
75
|
+
'balance.available': '可用余额',
|
|
76
|
+
'balance.granted': '赠送余额',
|
|
77
|
+
'balance.topped': '充值余额',
|
|
78
|
+
'balance.remaining': '剩余额度',
|
|
79
|
+
'balance.total': '总额度',
|
|
80
|
+
'balance.used': '已用',
|
|
81
|
+
'balance.hard': '硬限额',
|
|
82
|
+
'balance.soft': '软限额',
|
|
83
|
+
'balance.generic': '余额',
|
|
84
|
+
'balance.header': '{plan} 余额({provider})',
|
|
85
|
+
'balance.unavailable': '账号当前不可用',
|
|
86
|
+
'balance.source': ' 来源 {path}',
|
|
87
|
+
'toolTitle.edit': '编辑',
|
|
88
|
+
'toolTitle.write': '写入',
|
|
89
|
+
'toolTitle.str_replace_editor': '替换',
|
|
90
|
+
'toolTitle.fetch': '抓取网页',
|
|
91
|
+
'toolTitle.list_files': '列出文件',
|
|
92
|
+
'toolTitle.list': '列出文件',
|
|
93
|
+
'toolTitle.ls': '列出文件',
|
|
94
|
+
'toolTitle.find': '搜索文件',
|
|
95
|
+
'toolTitle.search': '网页搜索',
|
|
96
|
+
'toolTitle.delete': '删除文件',
|
|
97
|
+
'toolTitle.rm': '删除文件',
|
|
98
|
+
'toolTitle.rename': '重命名文件',
|
|
99
|
+
'toolTitle.mv': '重命名文件',
|
|
100
|
+
'toolTitle.mkdir': '创建目录',
|
|
101
|
+
'toolTitle.skills': '技能',
|
|
102
|
+
'toolTitle.create_goal': '创建目标',
|
|
103
|
+
'toolTitle.update_goal': '更新目标',
|
|
104
|
+
'toolTitle.complete_goal': '完成目标',
|
|
105
|
+
'toolTitle.clear_goal': '清除目标',
|
|
106
|
+
'toolTitle.pause_goal': '暂停目标',
|
|
107
|
+
'toolTitle.resume_goal': '恢复目标',
|
|
108
|
+
'toolTitle.todo_write': '更新待办',
|
|
109
|
+
'toolTitle.todo': '更新待办',
|
|
110
|
+
'toolTitle.compact': '压缩上下文',
|
|
111
|
+
'toolTitle.glob': '匹配文件',
|
|
112
|
+
'toolTitle.grep': '搜索',
|
|
113
|
+
'toolTitle.read': '读取',
|
|
114
|
+
'toolTitle.web_search': '网页搜索',
|
|
115
|
+
'toolTitle.web_fetch': '抓取网页',
|
|
116
|
+
'toolTitle.subagent': '子代理',
|
|
117
|
+
'toolTitle.subagent_fork': '子代理 fork',
|
|
118
|
+
'toolTitle.ask_user_question': '提问用户',
|
|
119
|
+
'toolTitle.exit_plan_mode': '提交计划',
|
|
120
|
+
'toolTitle.get_goal': '查看目标',
|
|
121
|
+
'card.thinking': '思考',
|
|
122
|
+
'card.plan': '计划',
|
|
123
|
+
'card.subagent': '子代理',
|
|
124
|
+
'card.reply': '回复',
|
|
125
|
+
'card.tool': '工具',
|
|
126
|
+
'card.question': '提问',
|
|
127
|
+
'card.goal': '目标',
|
|
128
|
+
'card.prompt': '提示词',
|
|
129
|
+
'card.expand': ' · Enter 展开',
|
|
130
|
+
'prompt.systemPreset': '系统预设',
|
|
131
|
+
'prompt.context': '上下文',
|
|
132
|
+
'prompt.inject': '提示词注入',
|
|
133
|
+
'prompt.injectWith': '提示词注入:{sources}',
|
|
134
|
+
'plan.nudge': '本轮结束时计划条还有未完成待办。请立刻再调用一次 todo_write,把已经做完的标成 completed,还没做的留 pending。不要开新任务。',
|
|
135
|
+
'plan.leftOpen': '本轮未收尾:还剩 {count} 项待办(会话日志未改)。',
|
|
136
|
+
'plan.pendingNext': '模式切换将在下一步生效。',
|
|
137
|
+
'plan.planningOnly': '只规划、不改代码;确认后再执行。',
|
|
138
|
+
'plan.executing': '正在按计划执行。',
|
|
139
|
+
'plan.allDone': '计划任务已全部完成。',
|
|
140
|
+
'plan.stillOpen': '计划还在,尚未全部完成。',
|
|
141
|
+
'plan.closed': '计划模式已关闭,可用 /plan 重新进入。',
|
|
142
|
+
'plan.todoDone': '{count} 已完成',
|
|
143
|
+
'plan.todoActive': '{count} 进行中',
|
|
144
|
+
'plan.todoPending': '{count} 待处理',
|
|
145
|
+
'plan.list': '计划列表',
|
|
146
|
+
'plan.todoSummary': '{done}/{total} 完成',
|
|
147
|
+
'plan.waitConfirm': '等待确认计划',
|
|
148
|
+
'plan.emptyBody': '计划正文为空',
|
|
149
|
+
'plan.reviewing': '待审计划',
|
|
150
|
+
'plan.switching': '切换中',
|
|
151
|
+
'plan.complete': '计划完成',
|
|
152
|
+
'plan.archived': '已归档',
|
|
153
|
+
'plan.header': '计划 · {summary}',
|
|
154
|
+
'plan.moreLines': ' … 还有 {count} 行计划',
|
|
155
|
+
'plan.noTodos': ' 还没有任务列表',
|
|
156
|
+
'plan.noTasks': '还没有任务',
|
|
157
|
+
'plan.entered': '已进入计划模式:先规划、等确认后再改代码。可用 /plan off 退出。',
|
|
158
|
+
'plan.exited': '已退出计划模式,可以继续执行改动。',
|
|
159
|
+
'plan.requestOn': '已请求进入计划模式。',
|
|
160
|
+
'plan.requestOff': '已请求退出计划模式。',
|
|
161
|
+
'plan.enterMode': '进入计划模式',
|
|
162
|
+
'plan.exitMode': '退出计划模式',
|
|
163
|
+
'plan.nudgeQueued': '已请模型补一次待办状态(本轮只问一次)。',
|
|
164
|
+
'plan.nudgeFailed': '补待办状态失败:{error}',
|
|
165
|
+
'todo.list': '待办列表',
|
|
166
|
+
'todo.empty': '还没有任务',
|
|
167
|
+
'todo.doneMark': '完成',
|
|
168
|
+
'todo.interrupted': '已中断',
|
|
169
|
+
'todo.failed': '失败',
|
|
170
|
+
'ask.multi': '{text}({count} 题)',
|
|
171
|
+
'tool.signal': ' [信号 {signal}]',
|
|
172
|
+
'tool.exitCode': ' [退出码 {code}]',
|
|
173
|
+
'tool.noOutput': '(无输出)',
|
|
174
|
+
'tool.args': '参数',
|
|
175
|
+
'tool.result': '结果',
|
|
176
|
+
'tool.reading': '读取中…',
|
|
177
|
+
'tool.inspectTitle': '工具全文 · {title}',
|
|
178
|
+
'tool.inspectHint': 'PgUp/PgDn/滚轮滚动 · Esc 返回会话',
|
|
179
|
+
'tool.inspectFooter': '全文 {pos} · Esc 返回',
|
|
180
|
+
'mode.standard': '标准模式',
|
|
181
|
+
'boot.help': '输入 /help 查看快捷键 · /find 搜索思考/计划/子代理/回复 · 空输入时 ↑/↓ 选卡片',
|
|
182
|
+
'cwd.entered': '已进入会话工作目录 {cwd}',
|
|
183
|
+
'cwd.notAbsolute': '会话工作目录不是绝对路径:{path}',
|
|
184
|
+
'cwd.missing': '会话工作目录不存在:{path}',
|
|
185
|
+
'cwd.failed': '无法进入会话工作目录 {path}:{error}',
|
|
186
|
+
'cwd.full': '工作目录 {cwd}',
|
|
187
|
+
'onboard.checkFailed': '首次配置检查失败: {error}',
|
|
188
|
+
'onboard.syncSubFailed': '同步子代理模型失败: {error}',
|
|
189
|
+
'onboard.oauthHint': '当前是 {kind}({provider}),走本机 SuperGrok / X Premium OAuth,无需 API Key。用 /model 切换 Grok 模型和思考强度;换官方或 OpenCode 用 /provider。只有要新增 API Key 提供商时才需要 /setup。',
|
|
190
|
+
'onboard.envInUse': '当前使用 {env}(环境变量/启动环境文件)。如需更换,随时输入 /setup 重新配置。',
|
|
191
|
+
'onboard.envStale': '检测到系统已注入 {env}(可能已失效)。首次启动向导将覆盖为你的 Key,保存后重启 TUI 生效。',
|
|
192
|
+
'onboard.needSetup': '首次启动:请先配置提供商和 API Key(随时可输入 /setup 重新配置)。',
|
|
193
|
+
'onboard.title': '首次配置向导 — 选择提供商(与官方 Models 页一致)',
|
|
194
|
+
'onboard.opt1': ' 1 DeepSeek 官方(api.deepseek.com)',
|
|
195
|
+
'onboard.opt2': ' 2 OpenCode Go(opencode.ai/zen/go,Responses 协议)',
|
|
196
|
+
'onboard.opt3': ' 3 自定义 OpenAI 兼容网关(Completions)',
|
|
197
|
+
'onboard.opt4': ' 4 自定义 OpenAI Responses 网关',
|
|
198
|
+
'onboard.opt5': ' 5 Anthropic Messages 兼容网关',
|
|
199
|
+
'onboard.pickHint': ' 按 1-5 选择,Esc 取消',
|
|
200
|
+
'onboard.providerLine': '提供商:{label}',
|
|
201
|
+
'onboard.idPrompt': 'Provider ID(小写字母/数字/连字符,永久标识):',
|
|
202
|
+
'onboard.default': ' 默认:{value}',
|
|
203
|
+
'onboard.enterEsc': ' Enter 确认,Esc 取消',
|
|
204
|
+
'onboard.keyPrompt': '请输入 API Key(输入时以 • 显示):',
|
|
205
|
+
'onboard.basePrompt': '请输入 Base URL(留空使用 {fallback}):',
|
|
206
|
+
'onboard.baseFallback': '官方/模板默认',
|
|
207
|
+
'onboard.modelsPrompt': '模型 ID(多个用逗号或空格分隔):',
|
|
208
|
+
'onboard.modelsFetched': ' 已获取({count}):{list}',
|
|
209
|
+
'onboard.ctrlF': ' Ctrl+F = 从端点获取模型列表',
|
|
210
|
+
'onboard.confirmTitle': '确认保存以下配置?',
|
|
211
|
+
'onboard.confirmProvider': ' 提供商: {label}',
|
|
212
|
+
'onboard.confirmBase': ' Base URL: {url}',
|
|
213
|
+
'onboard.confirmApi': ' API 协议: {api}',
|
|
214
|
+
'onboard.confirmModels': ' 模型: {list}',
|
|
215
|
+
'onboard.confirmKey': ' API Key: {head}…{tail}(长度 {length})',
|
|
216
|
+
'onboard.confirmHint': ' y = 保存, n = 重填, Esc = 取消',
|
|
217
|
+
'onboard.defaultParen': '(默认)',
|
|
218
|
+
'onboard.providerCompletions': '自定义 OpenAI 兼容网关(Completions)',
|
|
219
|
+
'onboard.providerResponses': '自定义 OpenAI Responses 网关',
|
|
220
|
+
'onboard.providerAnthropic': 'Anthropic Messages 兼容网关',
|
|
221
|
+
'onboard.providerGo': 'OpenCode Go(opencode.ai/zen/go)',
|
|
222
|
+
'onboard.idInvalid': 'Provider ID 只能包含小写字母、数字和连字符,且不能以连字符开头。',
|
|
223
|
+
'onboard.keyEmpty': 'API Key 不能为空,请重新输入。',
|
|
224
|
+
'onboard.needModel': '至少需要一个模型 ID。',
|
|
225
|
+
'onboard.needBase': '请先填写 Base URL 再获取模型列表。',
|
|
226
|
+
'onboard.fetchingModels': '正在从端点获取模型列表…',
|
|
227
|
+
'onboard.llmMissing': 'llm 服务不可用',
|
|
228
|
+
'onboard.noModels': '端点没有返回可用模型,请手动输入模型 ID。',
|
|
229
|
+
'onboard.fetchedModels': '已从端点获取 {count} 个模型:{list}(Enter 确认,也可继续修改)。',
|
|
230
|
+
'onboard.fetchFailed': '获取模型列表失败:{error}',
|
|
231
|
+
'onboard.baseSaved': 'Base URL 已保存 → {path}',
|
|
232
|
+
'onboard.officialDone': '配置完成,已记住 deepseek-official / {model}。用 /provider 可切回其它已保存的提供商,无需再 /setup。',
|
|
233
|
+
'onboard.settingsMissing': '设置服务不可用,自定义提供商未保存。',
|
|
234
|
+
'onboard.providerSaved': '提供商 {id} 已保存 → {path}',
|
|
235
|
+
'onboard.customDone': '配置完成,已记住 {id} / {model}。其它提供商的模型和 Key 仍保留;用 /provider 切换,下一步请求生效。',
|
|
236
|
+
'onboard.saveFailed': '保存配置失败: {error}',
|
|
237
|
+
'onboard.credSaved': '{env} 已保存 → {path}',
|
|
238
|
+
'onboard.envShadowWin': '环境变量 {env} 已存在且优先,已用 setx + env.cmd 覆盖;新开的终端生效。',
|
|
239
|
+
'onboard.envShadowUnix': '环境变量 {env} 已存在且优先,已写入启动环境覆盖;新开的终端生效。',
|
|
240
|
+
'onboard.credMissing': '凭据服务不可用,已写入启动环境覆盖 → {path}',
|
|
241
|
+
'dialog.planReview': '计划待审 {index}/{total}',
|
|
242
|
+
'dialog.ask': '提问用户 {index}/{total}: {question}',
|
|
243
|
+
'dialog.recommended': '(推荐)',
|
|
244
|
+
'dialog.freeform': ' (自由输入:在下方输入后按 Enter)',
|
|
245
|
+
'dialog.multiHint': ' 数字/字母切换,Enter 提交,Esc 取消',
|
|
246
|
+
'dialog.singleHint': ' 数字/字母选择,Enter 提交,Esc 取消',
|
|
247
|
+
'dialog.scrolled': '↑ 已回看 {count} 行 · PgUp/PgDn/滚轮滚动 · Esc 回到底部',
|
|
248
|
+
'reason.done': '{marker} 已思考 · {lines} 行',
|
|
249
|
+
'reason.live': '{marker} 思考中 {spinner} · {chars} 字',
|
|
250
|
+
'reason.elapsed': ' · {seconds}s',
|
|
251
|
+
'sub.cardWait': ' 等待子代理输出…',
|
|
252
|
+
'sub.cardEmpty': ' 没有可见输出',
|
|
253
|
+
'sub.cardSession': ' 会话 {id} · {provider}{external}',
|
|
254
|
+
'sub.external': ' · 外部进程',
|
|
255
|
+
'sub.stopReason': ' 结束原因:{reason}',
|
|
256
|
+
'sub.started': '已启动',
|
|
257
|
+
'sub.startedDetail': '已启动({provider}{external})',
|
|
258
|
+
'sub.ended': '结束({reason})',
|
|
259
|
+
'sub.label': '子代理 {provider}',
|
|
260
|
+
'sub.turnEnd': '轮次结束({reason})',
|
|
261
|
+
'sub.approval': '等待审批:{tool}',
|
|
262
|
+
'sub.listLine': '▶ {label} {id}({provider})运行 {seconds}s [{run}]{activity}',
|
|
263
|
+
'sub.listHint': '{lines}\n空输入时 ↑/↓ 选卡片,Enter 展开;Alt+3 跳到最新子代理。',
|
|
264
|
+
'sub.none': '当前没有活动的子代理。',
|
|
265
|
+
'sub.killNeedId': '/subagents kill <session-id> — 缺少子代理会话 ID',
|
|
266
|
+
'sub.killRequested': '已请求释放子代理:{ids}',
|
|
267
|
+
'sub.unknownAction': '/subagents 未知操作 "{action}"(支持 list / kill <id>)',
|
|
268
|
+
'sub.followed': '子代理已跟随提供商 {provider},模型改为 {model}{sessionOnly}',
|
|
269
|
+
'sub.sessionOnly': '(仅当前会话)',
|
|
270
|
+
'sub.settingsMissing': '设置服务不可用,子代理选择仅当前会话生效。',
|
|
271
|
+
'sub.fetchingModels': '正在从端点获取子代理模型列表({provider})…',
|
|
272
|
+
'sub.modelFollow': '子代理模型已切换:{model}(提供方跟随父会话 {provider})。',
|
|
273
|
+
'sub.modelPinned': '子代理模型已切换:{model}(提供方 {provider})。',
|
|
274
|
+
'sub.effortUnset': '模型 {provider}/{model} 未声明可选 reasoning effort,已保持提供商默认;请勿手动设置 high/max。',
|
|
275
|
+
'sub.pickEffort': '选择子代理思考强度({provider}/{model})',
|
|
276
|
+
'sub.effortFollowHint': '清空自定义强度,跟随提供商/模型默认',
|
|
277
|
+
'sub.effortRestored': '子代理思考强度已恢复为提供商默认。',
|
|
278
|
+
'sub.effortSet': '子代理思考强度已切换:{id}。',
|
|
279
|
+
'goal.active': '进行中',
|
|
280
|
+
'goal.paused': '已暂停',
|
|
281
|
+
'goal.blocked': '受阻',
|
|
282
|
+
'goal.complete': '已完成',
|
|
283
|
+
'goal.cleared': '已清除',
|
|
284
|
+
'goal.header': '● 目标{spinner} · {phase} · {objective}',
|
|
285
|
+
'goal.help': ' 用 /goal 查看、暂停、恢复或清除当前目标。',
|
|
286
|
+
'goal.unnamed': '(未命名目标)',
|
|
287
|
+
'goal.clearedLabel': '(已清除)',
|
|
288
|
+
'goal.clearedNotice': '当前目标已清除。',
|
|
289
|
+
'goal.set': '已设置目标',
|
|
290
|
+
'goal.pausedNotice': '目标已暂停',
|
|
291
|
+
'goal.blockedNotice': '目标受阻',
|
|
292
|
+
'goal.doneNotice': '目标已完成',
|
|
293
|
+
'question.waiting': '等待回答',
|
|
294
|
+
'question.answered': '已回答',
|
|
295
|
+
'question.cancelled': '已取消',
|
|
296
|
+
'question.planTitle': '计划待审',
|
|
297
|
+
'question.askTitle': '提问用户',
|
|
298
|
+
'question.dialogHint': ' 用下方对话框选择,数字/字母选中,Enter 提交,Esc 取消。',
|
|
299
|
+
'compact.recoverTokens': '回收 {tokens} token',
|
|
300
|
+
'compact.pruneChunks': '修剪 {count} 段',
|
|
301
|
+
'compact.prepare': '准备摘要',
|
|
302
|
+
'compact.running': '压缩上下文 · {detail}',
|
|
303
|
+
'compact.failed': '压缩失败 · {error}',
|
|
304
|
+
'compact.done': '压缩完成 · {detail}',
|
|
305
|
+
'compact.status': '压缩上下文…',
|
|
306
|
+
'compact.bodyRunning': ' 正在压缩会话上下文,完成后旧工具结果会被摘要替换。',
|
|
307
|
+
'compact.bodyError': ' {error}',
|
|
308
|
+
'compact.bodyDone': ' 压缩已写入会话日志,模型下一轮会看到更短的历史。',
|
|
309
|
+
'compact.finished': '上下文压缩已完成。',
|
|
310
|
+
'compact.failedNotice': '上下文压缩失败:{error}',
|
|
311
|
+
'compact.short': '压缩',
|
|
312
|
+
'jump.planDock': '已跳到{category}(底栏计划条)。',
|
|
313
|
+
'jump.missing': '当前没有{category}卡片。',
|
|
314
|
+
'jump.latest': '已跳到最新{category}。',
|
|
315
|
+
'find.none': '没有可搜索的卡片。',
|
|
316
|
+
'find.noMatch': '没有匹配「{query}」的卡片。',
|
|
317
|
+
'find.hits': '找到 {count} 条{query} · 第 {count}/{count} 条({where})。Ctrl+G / Alt+N 下一条,Alt+P 上一条。',
|
|
318
|
+
'find.empty': '还没有搜索结果。用 /find 思考 padAnsi,或 Ctrl+/ 打开搜索。',
|
|
319
|
+
'find.step': '搜索「{query}」· 第 {index}/{total} 条({where})。',
|
|
320
|
+
'title.done': '\x1b]0;dsh ✓ 已完成{suffix}\x07',
|
|
321
|
+
'title.waitAnswer': '等待用户回答',
|
|
322
|
+
'title.subagents': '运行中 · 子代理 {count}',
|
|
323
|
+
'title.tools': '运行中 · 工具 {count}',
|
|
324
|
+
'title.idle': '\x1b]0;dsh 待命{suffix}\x07',
|
|
325
|
+
'stall.warning': '模型/工具长时间无响应,可按 Esc 或 Ctrl+C 中断当前轮次。',
|
|
326
|
+
'stream.interrupted': ' ⚠ 已中断',
|
|
327
|
+
'stream.interruptedEmpty': '本轮输出已中断,没有可见内容。',
|
|
328
|
+
'retry.generatingTitle': '正在用模型生成会话标题…',
|
|
329
|
+
'retry.busy': '模型请求失败,正在重试',
|
|
330
|
+
'retry.progress': '模型请求失败,{ms}ms 后重试 {retry}/{max}:{message}',
|
|
331
|
+
'retry.started': '开始第 {retry} 次重试。',
|
|
332
|
+
'team.event': '[团队] {type}',
|
|
333
|
+
'command.failed': '命令失败。',
|
|
334
|
+
'command.images': '(可附图)',
|
|
335
|
+
'approval.prompt': '允许工具 "{tool}"?({agent}){reason}',
|
|
336
|
+
'approval.hint': 'y = 允许一次, n = 拒绝, Esc = 取消',
|
|
337
|
+
'approval.thisSession': '当前会话',
|
|
338
|
+
'steer.queued': '⚡ {text}(运行中已提交,将在下个步骤生效;Esc/Ctrl+C 可中断)',
|
|
339
|
+
'cancel.esc': '已请求取消当前轮次…',
|
|
340
|
+
'cancel.ctrlC': '已请求取消当前轮次…(Ctrl+C)',
|
|
341
|
+
'clear.transcript': '转录已清空。子代理、计划与提问卡片会在新事件到达时重新出现。',
|
|
342
|
+
'model.added': '模型 {model} 已加入提供商 {provider} 的配置。',
|
|
343
|
+
'model.addFailed': '无法把模型 {model} 写入提供商配置:{error}',
|
|
344
|
+
'model.prevPage': '« 上一页',
|
|
345
|
+
'model.nextPage': '» 下一页',
|
|
346
|
+
'model.current': '当前',
|
|
347
|
+
'model.pick': '选择模型(提供商 {provider} · {source}{pages})',
|
|
348
|
+
'model.configured': '已配置列表',
|
|
349
|
+
'model.fetching': '正在从端点获取 {provider} 的模型列表…',
|
|
350
|
+
'model.live': '端点实时列表',
|
|
351
|
+
'model.xaiCatalog': 'SuperGrok 目录',
|
|
352
|
+
'model.switched': '已切换到 {kind}:{provider}/{model}(思考强度 {effort}{undeclared});下一步请求生效。',
|
|
353
|
+
'model.effortDefault': '默认',
|
|
354
|
+
'model.undeclared': ',该模型未声明可选强度',
|
|
355
|
+
'model.pickEffort': '选择思考强度({model})',
|
|
356
|
+
'model.persistFailSettings': '默认选择未能固化:agentDefaultModel 不可用且 settings 写入失败({error})。本次切换仅当前会话生效,重启会回退到保存过的提供商。',
|
|
357
|
+
'model.persistFailNone': '默认选择未能固化:settings 服务不可用。本次切换仅当前会话生效。',
|
|
358
|
+
'provider.none': '没有可切换的提供商。用 /setup 先配置一条 API Key 路由。',
|
|
359
|
+
'provider.pick': '选择提供商',
|
|
360
|
+
'provider.currentKind': '{kind} · 当前',
|
|
361
|
+
'mode.pick': '选择模式',
|
|
362
|
+
'mode.currentPrefix': '当前 · ',
|
|
363
|
+
'mode.switched': '已切换到模式:{name}(当前会话生效)。',
|
|
364
|
+
'mode.remembered': '当前会话已有内容,无法中途切换模式;已记住 {name},下次启动生效。',
|
|
365
|
+
'mode.missingService': 'agentPresets 服务不可用。',
|
|
366
|
+
'mode.none': '没有可用的模式(preset)。',
|
|
367
|
+
'resume.running': '当前轮次运行中,请等待结束或按 Esc 取消后再切换会话。',
|
|
368
|
+
'resume.same': '已在当前会话。',
|
|
369
|
+
'resume.noCallback': '会话切换回调不可用,无法 /resume。',
|
|
370
|
+
'resume.switching': '正在切换到会话 {id}…',
|
|
371
|
+
'resume.noPersistence': 'sessionPersistence 服务不可用。',
|
|
372
|
+
'resume.none': '没有可恢复的历史会话(也可以直接 /resume <session-id>)。',
|
|
373
|
+
'resume.pick': '选择要恢复的历史会话',
|
|
374
|
+
'resume.unreadable': '⚠ 无法读取 · ',
|
|
375
|
+
'resume.cancelled': '会话选择已取消。',
|
|
376
|
+
'picker.title': 'DeepSeek Harness — 选择要恢复的历史会话',
|
|
377
|
+
'picker.new': '新建会话',
|
|
378
|
+
'picker.cancel': '取消',
|
|
379
|
+
'picker.noPersistence': 'dsh-ssh-tui: sessionPersistence service is unavailable\n',
|
|
380
|
+
'picker.none': 'dsh-ssh-tui: no resumable history sessions; starting a fresh session.\n',
|
|
381
|
+
'usage.querying': '查询额度…',
|
|
382
|
+
'usage.none': '当前提供商 {provider} 没有可用的余额或额度接口。DeepSeek 官方走 /user/balance;OpenAI Completions 兼容网关会探测 credit_grants;OpenCode Go 与 SuperGrok 走订阅额度。',
|
|
383
|
+
'usage.sessionTokens': '本会话已记录 token:输入 {input} · 输出 {output}(会话统计,非账单金额)',
|
|
384
|
+
'usage.sessionNone': '本会话尚无 token 用量记录。',
|
|
385
|
+
'usage.zenHeader': 'OpenCode Zen 按量计费({provider})',
|
|
386
|
+
'usage.zenBody': 'Zen 没有固定额度:请求按 API 账单计费,余额与账单请前往 https://opencode.ai/zen 查看。',
|
|
387
|
+
'usage.noDeepseekKey': '未找到 DEEPSEEK_API_KEY',
|
|
388
|
+
'usage.noCred': '未找到凭据 {env}',
|
|
389
|
+
'usage.pathBad': '{path}: 返回无法识别',
|
|
390
|
+
'usage.noGateway': 'OpenAI 兼容网关未找到余额接口({errors})',
|
|
391
|
+
'usage.noGrokToken': '未找到 SuperGrok OAuth token(~/.grok-bridge/auth.json)',
|
|
392
|
+
'usage.noGoCred': '未找到 OpenCode Go 凭据 {env}',
|
|
393
|
+
'usage.fetchFail': '无法访问 {label} 额度接口:{error}',
|
|
394
|
+
'usage.http': '{label} 额度接口返回 HTTP {status}',
|
|
395
|
+
'usage.goFetchFail': '无法访问 OpenCode 额度接口:{error}',
|
|
396
|
+
'usage.go401': 'OpenCode Go API Key 无效或未授权(401){detail}',
|
|
397
|
+
'usage.go403': '当前 Key 未订阅 OpenCode Go,或额度服务不可用(403){detail}',
|
|
398
|
+
'usage.goHttp': 'OpenCode Go 额度接口返回 HTTP {status}{detail}',
|
|
399
|
+
'help.intro1': '运行中按 Enter 可插入指示;Esc 取消选择或当前轮次;空闲 Ctrl+C 退出。',
|
|
400
|
+
'help.intro2': '空输入时 ↑/↓ 选卡片(与 Ctrl+N/P 相同);Enter 展开(正文超出窗口则单独全览,Esc 返回);Ctrl+R 全部展开/收起;Ctrl+T 折叠输入。',
|
|
401
|
+
'help.intro3': 'Alt+1 最新思考 · Alt+2 计划 · Alt+3 子代理 · Alt+4 最新回复。',
|
|
402
|
+
'help.intro4': '/find [思考|计划|子代理|回复|提示词] 关键字;Ctrl+/ 或 Alt+/ 打开搜索,Ctrl+G / Alt+N 下一条。',
|
|
403
|
+
'help.intro5': '/model 只换当前提供商的模型和思考强度。/provider 换提供商(并选模型),下一步请求生效,无需重启。',
|
|
404
|
+
'help.intro6': '/setup 只新增或更新某一条 API Key 提供商,不会删掉其它已保存的路由。SuperGrok 走本机 OAuth,不需要填 Key。',
|
|
405
|
+
'help.intro7': '/status 会标明当前是 DeepSeek 官方、SuperGrok 订阅、OpenCode Go / Zen,以及链路、额度窗口、子代理是否与父路由同族。',
|
|
406
|
+
'help.modelCancel': '模型选择已取消。',
|
|
407
|
+
'help.providerCancel': '提供商选择已取消。',
|
|
408
|
+
'help.submodelCancel': '子代理模型选择已取消。',
|
|
409
|
+
'help.subeffortCancel': '子代理思考强度选择已取消。',
|
|
410
|
+
'help.modeCancel': '模式选择已取消。',
|
|
411
|
+
'models.ellipsis': '{text}…(共 {count} 个)',
|
|
412
|
+
'lock.held': '会话 {session} 已在 pid {pid}{tty} 运行。\n不要再开第二份 TUI。若 SSH 断过:tmux attach -t dsh\n确认进程已死后,删除 $DSH_HOME/tui-locks/ 里对应的锁再启动。',
|
|
413
|
+
'lock.busy': '无法占用会话锁 {path}',
|
|
414
|
+
'update.notice': '发现新版本 dsh-ssh-tui {latest}(当前 {current})。更新:dsh plugin --profile tui add dsh-ssh-tui',
|
|
415
|
+
'grok.refreshFail': 'SuperGrok token 刷新失败(HTTP {status}{detail})',
|
|
416
|
+
'grok.writeFail': '无法写入 SuperGrok token({path})',
|
|
417
|
+
'grok.noRefresh': 'SuperGrok token 没有 refresh_token,请运行 dsh-llm-xai-oauth login --force',
|
|
418
|
+
'lang.pick': '界面语言',
|
|
419
|
+
'lang.zh': '中文',
|
|
420
|
+
'lang.en': 'English',
|
|
421
|
+
'lang.zhDesc': '中文界面(跳板机 SSH 默认)',
|
|
422
|
+
'lang.enDesc': '英文界面',
|
|
423
|
+
'lang.current': '当前',
|
|
424
|
+
'lang.switched': '界面语言已切换为 {name}。',
|
|
425
|
+
'lang.unknown': '未知语言 "{id}"。可用 zh 或 en。',
|
|
426
|
+
'lang.settingsMissing': '设置服务不可用,语言仅当前会话生效。',
|
|
427
|
+
'lang.cmd': '切换界面语言(zh / en);空参数打开选择器',
|
|
428
|
+
};
|
|
429
|
+
//# sourceMappingURL=zh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zh.js","sourceRoot":"","sources":["../../src/i18n/zh.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -5,15 +5,37 @@
|
|
|
5
5
|
* subagents, sandbox approvals) is the same one the web surface uses.
|
|
6
6
|
*/
|
|
7
7
|
import { installModelSelection } from '@deepseek-ai/dsh-agent';
|
|
8
|
-
import { errorChain } from '@deepseek-ai/dsh-llm';
|
|
8
|
+
import { errorChain, ReasoningEffortId } from '@deepseek-ai/dsh-llm';
|
|
9
9
|
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
10
10
|
import { randomUUID } from 'node:crypto';
|
|
11
|
+
import { readFileSync } from 'node:fs';
|
|
12
|
+
import { homedir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import yaml from 'js-yaml';
|
|
15
|
+
/** Read the user's `agent-default-model` straight from `$DSH_HOME/settings.yaml`. */
|
|
16
|
+
function readAgentDefaultFromFile() {
|
|
17
|
+
const home = process.env.DSH_HOME ?? join(homedir(), '.dsh');
|
|
18
|
+
try {
|
|
19
|
+
const parsed = yaml.load(readFileSync(join(home, 'settings.yaml'), 'utf8'));
|
|
20
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
21
|
+
return undefined;
|
|
22
|
+
const section = parsed['agent-default-model'];
|
|
23
|
+
return section !== null && typeof section === 'object' && !Array.isArray(section)
|
|
24
|
+
? section
|
|
25
|
+
: undefined;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
11
31
|
import { showSessionPicker } from './picker.js';
|
|
12
32
|
import { mountTui } from './tui.js';
|
|
13
33
|
import { defaultReasoningEffort } from './reasoning.js';
|
|
14
34
|
import { createSubagentSelection } from './subagent-model.js';
|
|
15
35
|
import { acquireSessionLock, releaseSessionLock, sessionLockDisabled } from './session-lock.js';
|
|
16
|
-
import { installRouteMemory } from './route-memory.js';
|
|
36
|
+
import { installRouteMemory, latestRememberedRoute, parseRouteMemory } from './route-memory.js';
|
|
37
|
+
import { enterSessionCwd } from './session-list.js';
|
|
38
|
+
import { installUiLocale, t } from './i18n/index.js';
|
|
17
39
|
export const name = 'ssh-tui';
|
|
18
40
|
/** Core services required before the terminal channel can drive an agent. */
|
|
19
41
|
export const inject = ['agents', 'agentDefaultModel'];
|
|
@@ -29,6 +51,7 @@ export function apply(ctx, config) {
|
|
|
29
51
|
}
|
|
30
52
|
const subagentSelection = createSubagentSelection(ctx);
|
|
31
53
|
installRouteMemory(ctx);
|
|
54
|
+
installUiLocale(ctx);
|
|
32
55
|
ctx.effect(() => {
|
|
33
56
|
let disposed = false;
|
|
34
57
|
let switching = false;
|
|
@@ -73,27 +96,57 @@ export function apply(ctx, config) {
|
|
|
73
96
|
if (agents === undefined)
|
|
74
97
|
throw new Error('dsh-ssh-tui: agents service is unavailable');
|
|
75
98
|
const defaultModel = ctx.get('agentDefaultModel');
|
|
76
|
-
const
|
|
99
|
+
const serviceSaved = defaultModel?.currentSelection();
|
|
100
|
+
// The settings document / on-disk file is the authoritative source for a
|
|
101
|
+
// default that must survive a restart. The agentDefaultModel service
|
|
102
|
+
// (or a duplicate settings instance) can report a stale in-memory
|
|
103
|
+
// selection, so prefer the file when it carries a user section.
|
|
104
|
+
const settingsSvc = ctx.get('settings');
|
|
105
|
+
const doc = settingsSvc?.document;
|
|
106
|
+
const docSection = doc !== null && typeof doc === 'object' && !Array.isArray(doc)
|
|
107
|
+
? doc['agent-default-model']
|
|
108
|
+
: undefined;
|
|
109
|
+
const fileSection = readAgentDefaultFromFile();
|
|
110
|
+
const authoritative = (fileSection ?? docSection);
|
|
111
|
+
const savedSelection = authoritative !== undefined
|
|
112
|
+
&& typeof authoritative.provider === 'string'
|
|
113
|
+
&& typeof authoritative.model === 'string'
|
|
114
|
+
? {
|
|
115
|
+
provider: authoritative.provider,
|
|
116
|
+
model: authoritative.model,
|
|
117
|
+
...(typeof authoritative.reasoningEffort === 'string'
|
|
118
|
+
? { reasoningEffort: ReasoningEffortId(authoritative.reasoningEffort) }
|
|
119
|
+
: {}),
|
|
120
|
+
}
|
|
121
|
+
: serviceSaved;
|
|
122
|
+
const hasUserDefaultSection = fileSection !== undefined || docSection !== undefined;
|
|
123
|
+
const rememberedFallback = !hasUserDefaultSection
|
|
124
|
+
? latestRememberedRoute(parseRouteMemory(settingsSvc?.document?.['ssh-tui-routes']))
|
|
125
|
+
: undefined;
|
|
77
126
|
// An explicit in-process change (/setup or /model) wins over launch-time
|
|
78
127
|
// CLI overrides for every session created or resumed later in this process.
|
|
79
128
|
const provider = liveSelection?.provider
|
|
80
129
|
?? config.provider
|
|
81
130
|
?? savedSelection?.provider
|
|
131
|
+
?? rememberedFallback?.provider
|
|
82
132
|
?? 'deepseek-official';
|
|
83
133
|
const model = liveSelection?.model
|
|
84
134
|
?? config.model
|
|
85
135
|
?? savedSelection?.model
|
|
136
|
+
?? rememberedFallback?.model
|
|
86
137
|
?? 'deepseek-v4-flash';
|
|
87
138
|
// Reasoning effort is only meaningful for the exact provider/model it
|
|
88
139
|
// belongs to. CLI overrides that change either route must not inherit the
|
|
89
140
|
// saved effort of a different model.
|
|
90
141
|
let reasoningEffort = liveSelection?.reasoningEffort;
|
|
91
142
|
if (reasoningEffort === undefined && liveSelection === undefined) {
|
|
92
|
-
const sameSavedRoute = savedSelection !== undefined
|
|
93
|
-
&& (config.provider === undefined || config.provider === savedSelection
|
|
94
|
-
&& (config.model === undefined || config.model === savedSelection
|
|
95
|
-
if (sameSavedRoute)
|
|
96
|
-
|
|
143
|
+
const sameSavedRoute = (savedSelection ?? rememberedFallback) !== undefined
|
|
144
|
+
&& (config.provider === undefined || config.provider === (savedSelection ?? rememberedFallback)?.provider)
|
|
145
|
+
&& (config.model === undefined || config.model === (savedSelection ?? rememberedFallback)?.model);
|
|
146
|
+
if (sameSavedRoute) {
|
|
147
|
+
const rawEffort = (savedSelection ?? rememberedFallback)?.reasoningEffort;
|
|
148
|
+
reasoningEffort = rawEffort === undefined ? undefined : ReasoningEffortId(String(rawEffort));
|
|
149
|
+
}
|
|
97
150
|
}
|
|
98
151
|
// OpenCode / third-party (llm-pi-ai) routes carry no adapter-level
|
|
99
152
|
// reasoning default, so default a supported effort ourselves when none is
|
|
@@ -125,10 +178,19 @@ export function apply(ctx, config) {
|
|
|
125
178
|
await agentPresets?.mount(agentCtx);
|
|
126
179
|
};
|
|
127
180
|
await takeSessionLock(String(sessionId));
|
|
181
|
+
let resumeCwdNotice;
|
|
128
182
|
try {
|
|
129
183
|
handle = resume
|
|
130
184
|
? await agents.resume({ resumeSessionId: sessionId, agentOptions, setup })
|
|
131
185
|
: await agents.create({ sessionId, meta: { cwd: process.cwd() }, agentOptions, setup });
|
|
186
|
+
if (resume) {
|
|
187
|
+
const entered = enterSessionCwd(handle.agent.session.header?.cwd);
|
|
188
|
+
resumeCwdNotice = entered.error !== undefined
|
|
189
|
+
? entered.error
|
|
190
|
+
: entered.changed
|
|
191
|
+
? t('cwd.entered', { cwd: entered.cwd })
|
|
192
|
+
: undefined;
|
|
193
|
+
}
|
|
132
194
|
}
|
|
133
195
|
catch (error) {
|
|
134
196
|
await dropSessionLock();
|
|
@@ -156,6 +218,7 @@ export function apply(ctx, config) {
|
|
|
156
218
|
resumePicker: false,
|
|
157
219
|
sessionId: String(sessionId),
|
|
158
220
|
resume,
|
|
221
|
+
...(resumeCwdNotice === undefined ? {} : { cwdNotice: resumeCwdNotice }),
|
|
159
222
|
provider,
|
|
160
223
|
model,
|
|
161
224
|
selectionRef,
|