@xingjisoft/neutrino 0.3.0 → 0.4.1
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 +33 -549
- package/assets/neutrino.ico +0 -0
- package/assets/neutrino.svg +7 -0
- package/assets/pro/backend_output_model.txt +5 -0
- package/assets/pro/claude-module-prompt.txt +65 -0
- package/assets/pro/common.txt +9 -0
- package/assets/pro/confirm_model.txt +5 -0
- package/assets/pro/front_output_model.txt +9 -0
- package/assets/pro/genimage_model.txt +1 -0
- package/assets/pro/main_model.txt +5 -0
- package/assets/pro/model-template.json +376 -0
- package/assets/pro/modeling_model.txt +5 -0
- package/assets/pro/plan_model.txt +8 -0
- package/assets/pro/thinking_model.txt +3 -0
- package/dist/agents.js +22 -3
- package/dist/app.js +199 -26
- package/dist/background.js +358 -0
- package/dist/bin.js +184 -44
- package/dist/browser.js +57 -0
- package/dist/config.js +174 -26
- package/dist/header.js +2 -1
- package/dist/index.js +1 -1
- package/dist/llm/approval.js +6 -2
- package/dist/llm/client.js +197 -28
- package/dist/llm/subagent.js +37 -1
- package/dist/llm/tools.js +3 -1
- package/dist/migration.js +33 -0
- package/dist/pro/agents.js +104 -0
- package/dist/pro/config.js +88 -0
- package/dist/pro/preflight.js +172 -0
- package/dist/screens/agentConversation.js +48 -5
- package/dist/screens/agentHistory.js +4 -2
- package/dist/screens/chat.js +14 -8
- package/dist/screens/modelSelect.js +15 -4
- package/dist/screens/settings.js +52 -9
- package/dist/screens/start.js +48 -15
- package/dist/state.js +1 -0
- package/dist/terminal/restore.js +3 -12
- package/dist/tray.js +138 -0
- package/dist/ui.js +58 -0
- package/dist/web/hub.js +26 -4
- package/dist/web/server.js +495 -74
- package/dist/web/service.js +135 -0
- package/dist/web/session.js +278 -25
- package/dist/web/settings.js +97 -24
- package/dist/web/terminalBridge.js +250 -0
- package/package.json +37 -37
- package/web/README.md +150 -16
- package/web/app.js +490 -25
- package/web/i18n.js +396 -345
- package/web/index.html +120 -15
- package/web/neutrino-pro.gif +0 -0
- package/web/neutrino.png +0 -0
- package/web/pro.js +184 -0
- package/web/settings.js +373 -247
- package/web/style.css +398 -0
package/web/i18n.js
CHANGED
|
@@ -1,345 +1,396 @@
|
|
|
1
|
-
// Interface translations for the Neutrino web console.
|
|
2
|
-
//
|
|
3
|
-
// English source strings are the lookup keys. `t()` returns the source text
|
|
4
|
-
// unchanged when a translation is missing, so a new label can never render as
|
|
5
|
-
// an internal identifier — it simply stays in English until it is translated.
|
|
6
|
-
// Translation values may use `{name}` placeholders; `t()` fills them in.
|
|
7
|
-
|
|
8
|
-
export const LANGUAGES = [
|
|
9
|
-
{ value: "en", label: "English" },
|
|
10
|
-
{ value: "zh", label: "简体中文" },
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
export function normalizeLanguage(value) {
|
|
14
|
-
return String(value ?? "").trim().toLowerCase().startsWith("zh") ? "zh" : "en";
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
let current = "en";
|
|
18
|
-
|
|
19
|
-
export function getLanguage() {
|
|
20
|
-
return current;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function setLanguage(value) {
|
|
24
|
-
current = normalizeLanguage(value);
|
|
25
|
-
return current;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function interpolate(template, values) {
|
|
29
|
-
if (!values) return template;
|
|
30
|
-
return String(template).replace(/\{(\w+)\}/g, (match, name) =>
|
|
31
|
-
Object.prototype.hasOwnProperty.call(values, name) ? String(values[name]) : match);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function t(source, values) {
|
|
35
|
-
const text = String(source ?? "");
|
|
36
|
-
const translated = current === "zh" ? ZH[text] : undefined;
|
|
37
|
-
return interpolate(translated ?? text, values);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** True when the Chinese dictionary covers this English source string. */
|
|
41
|
-
export function hasTranslation(source) {
|
|
42
|
-
return Object.prototype.hasOwnProperty.call(ZH, String(source ?? ""));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Apply every `data-i18n*` annotation under `root`. The attribute value is the
|
|
46
|
-
// English source string, so switching back to English always works without
|
|
47
|
-
// keeping a second copy of the DOM.
|
|
48
|
-
export function applyTranslations(root = typeof document === "undefined" ? null : document) {
|
|
49
|
-
if (!root || typeof root.querySelectorAll !== "function") return;
|
|
50
|
-
for (const node of root.querySelectorAll("[data-i18n]")) {
|
|
51
|
-
node.textContent = t(node.getAttribute("data-i18n"));
|
|
52
|
-
}
|
|
53
|
-
for (const node of root.querySelectorAll("[data-i18n-html]")) {
|
|
54
|
-
// Translations are authored locally (never model or user output), so the
|
|
55
|
-
// small amount of markup they carry is safe here.
|
|
56
|
-
node.innerHTML = t(node.getAttribute("data-i18n-html"));
|
|
57
|
-
}
|
|
58
|
-
for (const node of root.querySelectorAll("[data-i18n-title]")) {
|
|
59
|
-
node.title = t(node.getAttribute("data-i18n-title"));
|
|
60
|
-
}
|
|
61
|
-
for (const node of root.querySelectorAll("[data-i18n-placeholder]")) {
|
|
62
|
-
node.placeholder = t(node.getAttribute("data-i18n-placeholder"));
|
|
63
|
-
}
|
|
64
|
-
for (const node of root.querySelectorAll("[data-i18n-aria-label]")) {
|
|
65
|
-
node.setAttribute("aria-label", t(node.getAttribute("data-i18n-aria-label")));
|
|
66
|
-
}
|
|
67
|
-
if (typeof document !== "undefined" && root === document) {
|
|
68
|
-
document.documentElement?.setAttribute?.("lang", current === "zh" ? "zh-CN" : "en");
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function isChinese() {
|
|
73
|
-
return current === "zh";
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Locale tag for `toLocaleDateString` and friends. */
|
|
77
|
-
export function locale() {
|
|
78
|
-
return current === "zh" ? "zh-CN" : "en-US";
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const ZH = {
|
|
82
|
-
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"
|
|
150
|
-
"
|
|
151
|
-
"Choose
|
|
152
|
-
"
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"No
|
|
156
|
-
"
|
|
157
|
-
"No
|
|
158
|
-
"
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"Loading…": "
|
|
167
|
-
"
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
"
|
|
176
|
-
"
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
"
|
|
185
|
-
"
|
|
186
|
-
"
|
|
187
|
-
"
|
|
188
|
-
"
|
|
189
|
-
"
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
"
|
|
193
|
-
"
|
|
194
|
-
"
|
|
195
|
-
"
|
|
196
|
-
"
|
|
197
|
-
"
|
|
198
|
-
"
|
|
199
|
-
"
|
|
200
|
-
"
|
|
201
|
-
"
|
|
202
|
-
"
|
|
203
|
-
"
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
"
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"
|
|
212
|
-
"
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
"
|
|
218
|
-
"
|
|
219
|
-
"
|
|
220
|
-
"{
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"
|
|
224
|
-
"
|
|
225
|
-
"
|
|
226
|
-
"
|
|
227
|
-
"
|
|
228
|
-
"{n}
|
|
229
|
-
"
|
|
230
|
-
"
|
|
231
|
-
"
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"
|
|
236
|
-
"
|
|
237
|
-
"
|
|
238
|
-
"
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
"
|
|
244
|
-
"
|
|
245
|
-
"
|
|
246
|
-
"
|
|
247
|
-
"
|
|
248
|
-
"
|
|
249
|
-
"
|
|
250
|
-
"
|
|
251
|
-
"
|
|
252
|
-
"
|
|
253
|
-
"
|
|
254
|
-
"
|
|
255
|
-
"
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
"
|
|
261
|
-
"
|
|
262
|
-
"
|
|
263
|
-
"
|
|
264
|
-
"
|
|
265
|
-
"
|
|
266
|
-
"
|
|
267
|
-
"
|
|
268
|
-
"
|
|
269
|
-
"
|
|
270
|
-
"
|
|
271
|
-
"
|
|
272
|
-
"
|
|
273
|
-
"
|
|
274
|
-
"
|
|
275
|
-
"
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
"
|
|
279
|
-
"
|
|
280
|
-
"
|
|
281
|
-
"
|
|
282
|
-
"
|
|
283
|
-
"
|
|
284
|
-
"
|
|
285
|
-
"
|
|
286
|
-
"
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
"
|
|
290
|
-
"
|
|
291
|
-
"
|
|
292
|
-
"
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
"
|
|
296
|
-
"
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
"
|
|
300
|
-
"
|
|
301
|
-
"
|
|
302
|
-
"
|
|
303
|
-
"
|
|
304
|
-
"
|
|
305
|
-
"
|
|
306
|
-
"
|
|
307
|
-
"
|
|
308
|
-
"
|
|
309
|
-
"this
|
|
310
|
-
"
|
|
311
|
-
"
|
|
312
|
-
"
|
|
313
|
-
"
|
|
314
|
-
"
|
|
315
|
-
"
|
|
316
|
-
"
|
|
317
|
-
"
|
|
318
|
-
"
|
|
319
|
-
"
|
|
320
|
-
"
|
|
321
|
-
"
|
|
322
|
-
"
|
|
323
|
-
"
|
|
324
|
-
"
|
|
325
|
-
"
|
|
326
|
-
"
|
|
327
|
-
"
|
|
328
|
-
"
|
|
329
|
-
"
|
|
330
|
-
"
|
|
331
|
-
"
|
|
332
|
-
"
|
|
333
|
-
"
|
|
334
|
-
"
|
|
335
|
-
"
|
|
336
|
-
"
|
|
337
|
-
"
|
|
338
|
-
"
|
|
339
|
-
"
|
|
340
|
-
"
|
|
341
|
-
"
|
|
342
|
-
"
|
|
343
|
-
"
|
|
344
|
-
"
|
|
345
|
-
|
|
1
|
+
// Interface translations for the Neutrino web console.
|
|
2
|
+
//
|
|
3
|
+
// English source strings are the lookup keys. `t()` returns the source text
|
|
4
|
+
// unchanged when a translation is missing, so a new label can never render as
|
|
5
|
+
// an internal identifier — it simply stays in English until it is translated.
|
|
6
|
+
// Translation values may use `{name}` placeholders; `t()` fills them in.
|
|
7
|
+
|
|
8
|
+
export const LANGUAGES = [
|
|
9
|
+
{ value: "en", label: "English" },
|
|
10
|
+
{ value: "zh", label: "简体中文" },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
export function normalizeLanguage(value) {
|
|
14
|
+
return String(value ?? "").trim().toLowerCase().startsWith("zh") ? "zh" : "en";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let current = "en";
|
|
18
|
+
|
|
19
|
+
export function getLanguage() {
|
|
20
|
+
return current;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function setLanguage(value) {
|
|
24
|
+
current = normalizeLanguage(value);
|
|
25
|
+
return current;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function interpolate(template, values) {
|
|
29
|
+
if (!values) return template;
|
|
30
|
+
return String(template).replace(/\{(\w+)\}/g, (match, name) =>
|
|
31
|
+
Object.prototype.hasOwnProperty.call(values, name) ? String(values[name]) : match);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function t(source, values) {
|
|
35
|
+
const text = String(source ?? "");
|
|
36
|
+
const translated = current === "zh" ? ZH[text] : undefined;
|
|
37
|
+
return interpolate(translated ?? text, values);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** True when the Chinese dictionary covers this English source string. */
|
|
41
|
+
export function hasTranslation(source) {
|
|
42
|
+
return Object.prototype.hasOwnProperty.call(ZH, String(source ?? ""));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Apply every `data-i18n*` annotation under `root`. The attribute value is the
|
|
46
|
+
// English source string, so switching back to English always works without
|
|
47
|
+
// keeping a second copy of the DOM.
|
|
48
|
+
export function applyTranslations(root = typeof document === "undefined" ? null : document) {
|
|
49
|
+
if (!root || typeof root.querySelectorAll !== "function") return;
|
|
50
|
+
for (const node of root.querySelectorAll("[data-i18n]")) {
|
|
51
|
+
node.textContent = t(node.getAttribute("data-i18n"));
|
|
52
|
+
}
|
|
53
|
+
for (const node of root.querySelectorAll("[data-i18n-html]")) {
|
|
54
|
+
// Translations are authored locally (never model or user output), so the
|
|
55
|
+
// small amount of markup they carry is safe here.
|
|
56
|
+
node.innerHTML = t(node.getAttribute("data-i18n-html"));
|
|
57
|
+
}
|
|
58
|
+
for (const node of root.querySelectorAll("[data-i18n-title]")) {
|
|
59
|
+
node.title = t(node.getAttribute("data-i18n-title"));
|
|
60
|
+
}
|
|
61
|
+
for (const node of root.querySelectorAll("[data-i18n-placeholder]")) {
|
|
62
|
+
node.placeholder = t(node.getAttribute("data-i18n-placeholder"));
|
|
63
|
+
}
|
|
64
|
+
for (const node of root.querySelectorAll("[data-i18n-aria-label]")) {
|
|
65
|
+
node.setAttribute("aria-label", t(node.getAttribute("data-i18n-aria-label")));
|
|
66
|
+
}
|
|
67
|
+
if (typeof document !== "undefined" && root === document) {
|
|
68
|
+
document.documentElement?.setAttribute?.("lang", current === "zh" ? "zh-CN" : "en");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function isChinese() {
|
|
73
|
+
return current === "zh";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Locale tag for `toLocaleDateString` and friends. */
|
|
77
|
+
export function locale() {
|
|
78
|
+
return current === "zh" ? "zh-CN" : "en-US";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const ZH = {
|
|
82
|
+
"Pro preset": "Pro 预设",
|
|
83
|
+
"Preset": "预设",
|
|
84
|
+
"Neutrino Pro": "Neutrino Pro",
|
|
85
|
+
"Model details": "详细模型配置",
|
|
86
|
+
"Main model": "主模型",
|
|
87
|
+
"Reasoning model": "推理模型",
|
|
88
|
+
"Frontend model": "前端补全模型",
|
|
89
|
+
"Backend model": "后端补全模型",
|
|
90
|
+
"Approval model": "审批模型",
|
|
91
|
+
"Image model": "生图模型",
|
|
92
|
+
"Planning model": "规划模型",
|
|
93
|
+
"Modeling model": "建模模型",
|
|
94
|
+
"Reserved": "预留",
|
|
95
|
+
"Temporary fallback": "临时降档",
|
|
96
|
+
"No available model": "无可用模型",
|
|
97
|
+
"Checking every professional model before this task…": "正在检查本次任务的各个专业模型…",
|
|
98
|
+
"Pause the current turn to change presets.": "请暂停当前任务后再切换预设。",
|
|
99
|
+
"Models are checked before each task. Unavailable roles temporarily use a lower preset.": "每次任务开始前检查模型;不可用的角色临时使用低档位对应模型。",
|
|
100
|
+
"Pro orchestration": "Pro 智能体协作",
|
|
101
|
+
"Default Pro preset": "默认 Pro 预设",
|
|
102
|
+
"Maximum delegation depth": "最大调用递归深度",
|
|
103
|
+
"Every Pro task is planned first. All roles share the regular provider configuration. Image generation is reserved.": "每个 Pro 任务均先进行规划。各角色共用普通模式的供应商配置,生图功能暂时预留。",
|
|
104
|
+
"Edit role models, intensity and context windows in ~/.neutrino/pro/model.json. Default delegation depth: 10.": "在 ~/.neutrino/pro/model.json 中配置各角色模型、强度与上下文窗口。默认调用递归深度为 10。",
|
|
105
|
+
"Choose a working directory and a professional team preset.": "选择工作目录和专业模型团队预设。",
|
|
106
|
+
"Professional model availability": "专业模型可用性检查",
|
|
107
|
+
"These model substitutions apply only to this task in this conversation. Your preset configuration is unchanged.": "以下模型替换仅对当前对话的本次任务生效,不会修改预设配置文件。",
|
|
108
|
+
"Got it": "知道了",
|
|
109
|
+
// -- chrome -------------------------------------------------------------
|
|
110
|
+
"Neutrino": "Neutrino",
|
|
111
|
+
"Switch to Pro mode": "切换至Pro模式",
|
|
112
|
+
"Exit Pro mode": "返回普通模式",
|
|
113
|
+
"Click the badge to switch to Pro mode": "点击徽标切换至Pro模式",
|
|
114
|
+
"Dismiss": "关闭提示",
|
|
115
|
+
"Refresh conversations": "刷新会话",
|
|
116
|
+
"Settings": "设置",
|
|
117
|
+
"Send message": "发送消息",
|
|
118
|
+
"Close": "关闭",
|
|
119
|
+
"Close settings": "关闭设置",
|
|
120
|
+
"Back to conversations": "返回会话列表",
|
|
121
|
+
"Select a conversation": "选择一个会话",
|
|
122
|
+
"connecting…": "连接中…",
|
|
123
|
+
"reconnecting…": "重新连接中…",
|
|
124
|
+
"online": "在线",
|
|
125
|
+
"offline": "离线",
|
|
126
|
+
"locked": "已锁定",
|
|
127
|
+
"live": "实时",
|
|
128
|
+
"Local agent console": "本地 Agent 控制台",
|
|
129
|
+
"Interface language": "界面语言",
|
|
130
|
+
"New conversation": "新建对话",
|
|
131
|
+
"All directories": "所有目录",
|
|
132
|
+
"Working directory": "工作目录",
|
|
133
|
+
"Working directories": "工作目录",
|
|
134
|
+
"Other agents": "其他 Agent",
|
|
135
|
+
"Migrate session": "迁移会话",
|
|
136
|
+
"Migrating…": "迁移中…",
|
|
137
|
+
"Copy this history into a new Neutrino conversation in the same folder": "将历史复制为同一工作目录下的新 Neutrino 会话",
|
|
138
|
+
"Could not migrate this session: {error}": "无法迁移此会话:{error}",
|
|
139
|
+
"session not found in this working directory": "此工作目录中未找到该会话",
|
|
140
|
+
"this session has no messages to migrate": "此会话没有可迁移的消息",
|
|
141
|
+
"Read-only sessions recorded by other coding agents in this working directory.": "其他编码 Agent 在此工作目录中记录的只读会话。",
|
|
142
|
+
"No saved sessions from other agents in this folder.": "此文件夹中暂无其他 Agent 保存的会话。",
|
|
143
|
+
"Claude Code": "Claude Code",
|
|
144
|
+
"Codex": "Codex",
|
|
145
|
+
"OpenCode": "OpenCode",
|
|
146
|
+
"Could not load other agents' history: {error}": "无法加载其他 Agent 的历史记录:{error}",
|
|
147
|
+
"Could not load this session: {error}": "无法加载此会话:{error}",
|
|
148
|
+
"Choose a working directory to browse and start conversations in.": "选择一个工作目录,在其中浏览并开始对话。",
|
|
149
|
+
"Open folder…": "打开文件夹…",
|
|
150
|
+
"Open working directory": "打开工作目录",
|
|
151
|
+
"Choose a folder to open as the working directory.": "选择一个文件夹作为工作目录。",
|
|
152
|
+
"This folder no longer exists.": "此文件夹已不存在。",
|
|
153
|
+
"{n} conversations": "{n} 个对话",
|
|
154
|
+
"Recent folders": "最近文件夹",
|
|
155
|
+
"No recent folders.": "暂无最近文件夹。",
|
|
156
|
+
"Folders": "文件夹",
|
|
157
|
+
"No subfolders.": "没有子文件夹。",
|
|
158
|
+
"Open": "打开",
|
|
159
|
+
"Up": "上一级",
|
|
160
|
+
"New folder": "新建文件夹",
|
|
161
|
+
"Folder name": "文件夹名称",
|
|
162
|
+
"Create": "创建",
|
|
163
|
+
"Cancel": "取消",
|
|
164
|
+
"Use this folder": "使用此文件夹",
|
|
165
|
+
"This folder": "当前文件夹",
|
|
166
|
+
"Loading folders…": "正在加载文件夹…",
|
|
167
|
+
"Could not open this folder: {error}": "无法打开此文件夹:{error}",
|
|
168
|
+
"Folder created.": "文件夹已创建。",
|
|
169
|
+
"Enter a folder name.": "请输入文件夹名称。",
|
|
170
|
+
"Use an absolute path, for example C:\\projects or /home/me/projects.": "请使用绝对路径,例如 C:\\projects 或 /home/me/projects。",
|
|
171
|
+
"This working directory is used for the conversation's tools.": "该工作目录将用于对话中的工具操作。",
|
|
172
|
+
"New folder…": "新建文件夹…",
|
|
173
|
+
|
|
174
|
+
// -- new conversation ---------------------------------------------------
|
|
175
|
+
"Choose a working directory and a model.": "选择工作目录和模型。",
|
|
176
|
+
"Start conversation": "开始对话",
|
|
177
|
+
"Starting…": "正在启动…",
|
|
178
|
+
"Creating…": "正在创建…",
|
|
179
|
+
"Provider": "服务商",
|
|
180
|
+
"Model": "模型",
|
|
181
|
+
"Thinking": "思考强度",
|
|
182
|
+
"Default approval mode": "默认审批模式",
|
|
183
|
+
"Request Approval": "请求审批",
|
|
184
|
+
"Auto Approval": "自动审批",
|
|
185
|
+
"Delete-class calls still ask a human unless extreme-risk auto-approval is enabled in Settings.": "除非在设置中启用极高风险自动审批,删除类命令仍会询问用户。",
|
|
186
|
+
"This model has no API key configured. Add one in the terminal model screen, or choose another model.": "该模型尚未配置 API 密钥。请在终端模型界面添加密钥,或选择其他模型。",
|
|
187
|
+
"Could not start the conversation: {error}": "无法开始对话:{error}",
|
|
188
|
+
"Choose another folder": "选择其他文件夹",
|
|
189
|
+
"Browse…": "浏览…",
|
|
190
|
+
|
|
191
|
+
// -- conversation -------------------------------------------------------
|
|
192
|
+
"No conversation open": "未打开对话",
|
|
193
|
+
"Choose a conversation from the sidebar to view it.": "从侧边栏选择一个对话查看。",
|
|
194
|
+
"No conversations yet.": "暂无对话。",
|
|
195
|
+
"No conversations in this folder yet.": "此文件夹中暂无对话。",
|
|
196
|
+
"Type a message below to start a conversation in this folder.": "在下方输入消息,即可在此文件夹中开始对话。",
|
|
197
|
+
"Send a message to get started.": "发送一条消息开始对话。",
|
|
198
|
+
"This conversation is empty.": "此对话为空。",
|
|
199
|
+
"This live session has ended.": "此实时会话已结束。",
|
|
200
|
+
"Session ended": "会话已结束",
|
|
201
|
+
"The terminal session was closed.": "终端会话已关闭。",
|
|
202
|
+
"Connecting…": "连接中…",
|
|
203
|
+
"Loading…": "加载中…",
|
|
204
|
+
"Conversation": "对话",
|
|
205
|
+
"Could not load this conversation: {error}": "无法加载此对话:{error}",
|
|
206
|
+
"Read-only": "只读",
|
|
207
|
+
"Continue here": "在此继续",
|
|
208
|
+
"Resume this conversation in the browser and keep chatting": "在浏览器中恢复此对话并继续聊天",
|
|
209
|
+
"Could not continue this conversation: {error}": "无法继续此对话:{error}",
|
|
210
|
+
"Continue this conversation…": "继续此对话…",
|
|
211
|
+
"Message Neutrino…": "向 Neutrino 发送消息…",
|
|
212
|
+
"Message Neutrino in this folder…": "在此文件夹中向 Neutrino 发送消息…",
|
|
213
|
+
"Enter to send · Shift + Enter for a new line": "Enter 发送 · Shift + Enter 换行",
|
|
214
|
+
"to send": "发送",
|
|
215
|
+
"for a new line": "换行",
|
|
216
|
+
"just now": "刚刚",
|
|
217
|
+
"{n}m ago": "{n} 分钟前",
|
|
218
|
+
"{n}h ago": "{n} 小时前",
|
|
219
|
+
"{n} message": "{n} 条消息",
|
|
220
|
+
"{n} messages": "{n} 条消息",
|
|
221
|
+
"Show less": "收起",
|
|
222
|
+
"Show {n} more": "再显示 {n} 个",
|
|
223
|
+
"Live": "实时",
|
|
224
|
+
"Earlier conversation · {n} messages": "更早的对话 · {n} 条消息",
|
|
225
|
+
"Context summary · {n} messages": "上下文摘要 · {n} 条消息",
|
|
226
|
+
"You": "你",
|
|
227
|
+
"You: {text}": "你:{text}",
|
|
228
|
+
"{n} of {m} messages folded": "已折叠 {n}/{m} 条消息",
|
|
229
|
+
" — click to expand": " — 点击展开",
|
|
230
|
+
" — click to collapse": " — 点击收起",
|
|
231
|
+
"Clear": "清空",
|
|
232
|
+
"Clear conversation": "清空对话",
|
|
233
|
+
"Clear this conversation and start a fresh one in the same folder? The current transcript stays saved.": "清空此对话并在同一文件夹中重新开始?当前记录仍会保存在历史中。",
|
|
234
|
+
"Conversation cleared.": "对话已清空。",
|
|
235
|
+
"Could not clear this conversation: {error}": "无法清空此对话:{error}",
|
|
236
|
+
"Delete": "删除",
|
|
237
|
+
"Delete conversation": "删除对话",
|
|
238
|
+
"Delete this conversation? Its saved history will be removed.": "删除此对话?已保存的历史记录将被移除。",
|
|
239
|
+
"Conversation deleted.": "对话已删除。",
|
|
240
|
+
"Could not delete this conversation: {error}": "无法删除此对话:{error}",
|
|
241
|
+
|
|
242
|
+
// -- live status --------------------------------------------------------
|
|
243
|
+
"paused": "已暂停",
|
|
244
|
+
"working": "处理中",
|
|
245
|
+
"idle": "空闲",
|
|
246
|
+
"compressing": "正在压缩上下文",
|
|
247
|
+
"retrying {attempt}/{attempts}": "重试 {attempt}/{attempts}",
|
|
248
|
+
"reviewing": "自动审查中",
|
|
249
|
+
"reviewing · {n} reviewer": "自动审查中 · {n} 位审查者",
|
|
250
|
+
"reviewing · {n} reviewers": "自动审查中 · {n} 位审查者",
|
|
251
|
+
"reviewing round {round}/{rounds}": "自动审查中 第 {round}/{rounds} 轮",
|
|
252
|
+
"sub-agent: {label}": "子智能体:{label}",
|
|
253
|
+
"History save failed: {error}": "历史保存失败:{error}",
|
|
254
|
+
"Resume": "继续",
|
|
255
|
+
"Pause": "暂停",
|
|
256
|
+
"queued": "已排队",
|
|
257
|
+
"{prompt}→{completion} tok": "{prompt}→{completion} tok",
|
|
258
|
+
|
|
259
|
+
// -- approval -----------------------------------------------------------
|
|
260
|
+
"Approval required": "需要审批",
|
|
261
|
+
"EXTREME RISK": "极高风险",
|
|
262
|
+
"HIGH RISK": "高风险",
|
|
263
|
+
"Independent review": "独立审查",
|
|
264
|
+
"round {round} of {rounds}, ": "第 {round}/{rounds} 轮,",
|
|
265
|
+
"{n} reviewer": "{n} 位审查者",
|
|
266
|
+
"{n} reviewers": "{n} 位审查者",
|
|
267
|
+
"Working directory: {path}": "工作目录:{path}",
|
|
268
|
+
"Why: ": "原因:",
|
|
269
|
+
"All arguments": "全部参数",
|
|
270
|
+
"Approve": "批准",
|
|
271
|
+
"Deny": "拒绝",
|
|
272
|
+
"Command details unavailable.": "命令详情不可用。",
|
|
273
|
+
"Tool call": "工具调用",
|
|
274
|
+
"Switch between requesting approval and automatic review": "在请求审批与自动审查之间切换",
|
|
275
|
+
"Could not change approval mode: {error}": "无法切换审批模式:{error}",
|
|
276
|
+
|
|
277
|
+
// -- plan / usage -------------------------------------------------------
|
|
278
|
+
"Plan": "计划",
|
|
279
|
+
"Usage": "用量",
|
|
280
|
+
"No plan for this turn.": "本回合没有计划。",
|
|
281
|
+
"Done": "已完成",
|
|
282
|
+
"Active": "进行中",
|
|
283
|
+
"Pending": "待处理",
|
|
284
|
+
"Failed": "失败",
|
|
285
|
+
"Stopped": "已停止",
|
|
286
|
+
"{done} of {total} steps done": "已完成 {done}/{total} 步",
|
|
287
|
+
"Prompt": "提示",
|
|
288
|
+
"Completion": "补全",
|
|
289
|
+
"Total": "总计",
|
|
290
|
+
"tokens": "tokens",
|
|
291
|
+
"Show plan": "显示计划",
|
|
292
|
+
"Hide plan": "隐藏计划",
|
|
293
|
+
|
|
294
|
+
// -- settings -----------------------------------------------------------
|
|
295
|
+
"Models, approvals, and console access.": "模型、审批与控制台访问。",
|
|
296
|
+
"Defaults for new conversations": "新对话的默认设置",
|
|
297
|
+
"Thinking intensity": "思考强度",
|
|
298
|
+
"Apply": "应用",
|
|
299
|
+
"Conversation and approvals": "对话与审批",
|
|
300
|
+
"Model context window (tokens)": "模型上下文窗口(tokens)",
|
|
301
|
+
"Auto-compress at 80% of this model's context window. Default: 1,000,000 tokens.": "当上下文达到该模型窗口的 80% 时自动压缩。默认:1,000,000 tokens。",
|
|
302
|
+
"Approval reviewer model": "审批审查模型",
|
|
303
|
+
"Same as conversation": "与对话相同",
|
|
304
|
+
"Extreme-risk auto-approval (del class, 3 separate review rounds)": "极高风险自动审批(删除类命令,独立审查 3 轮)",
|
|
305
|
+
"Sound alerts (turn finished, approval waiting)": "声音提醒(回合结束、等待审批)",
|
|
306
|
+
"Start the Web console with the terminal": "随终端启动 Web 控制台(下次启动生效)",
|
|
307
|
+
"Background residency": "后台常驻",
|
|
308
|
+
"Run the Web console in the background and keep browser tasks alive after the CLI exits": "让 Web 控制台在后台运行,CLI 退出后浏览器中的任务继续执行",
|
|
309
|
+
"Off by default. Changes take effect immediately, including for running browser tasks. The regular and Pro workspaces share this setting. Terminal conversations still end when the terminal closes.": "默认关闭。切换立即生效,正在运行的浏览器任务也会受到保护;普通模式与 Pro 模式共用此设置。终端内的对话仍会在终端关闭时结束。",
|
|
310
|
+
"Enable background residency to avoid accidentally interrupting tasks": "建议开启后台常驻,避免误触中断任务",
|
|
311
|
+
"Enable": "开启",
|
|
312
|
+
"Background residency is on. Browser tasks keep running after the terminal closes.": "后台常驻已立即开启。关闭终端后,浏览器任务会继续执行。",
|
|
313
|
+
"Background residency is off. Current tasks can finish before the console closes.": "后台常驻已立即关闭。控制台退出前会等待当前任务完成。",
|
|
314
|
+
"Background residency could not be applied. Restart the console and try again.": "后台常驻未能生效,请重启控制台后重试。",
|
|
315
|
+
"Safety determines automatic approval; task relevance only blocks unanimously confirmed, extreme mismatches. Delete-class automatic approval also requires this setting.": "自动审批取决于安全性;任务相关性只有在两位审查者一致确认极端不匹配时才会阻止执行。删除类命令的自动审批还需要开启此设置。",
|
|
316
|
+
"Web access": "Web 访问",
|
|
317
|
+
"Allow access from other devices (LAN, 0.0.0.0)": "允许其他设备访问(局域网,0.0.0.0)",
|
|
318
|
+
"Binds the Web console to 0.0.0.0 so other devices on your network can open it, like --lan. Takes effect immediately; turning it off returns the console to 127.0.0.1. Keep the Web password on: anyone who can reach this port can drive the agent.": "将 Web 控制台绑定到 0.0.0.0,使局域网内的其他设备也能打开(等同于 --lan)。立即生效;关闭后恢复为 127.0.0.1。请保持 Web 密码开启:任何能访问此端口的人都可以驱动该 Agent。",
|
|
319
|
+
"LAN access is on. Open {urls} from another device.": "局域网访问已开启。请在其他设备上打开 {urls}。",
|
|
320
|
+
"LAN access is on, but no network address was found. Only this machine can connect.": "局域网访问已开启,但未找到可用的网络地址,目前只能在本机访问。",
|
|
321
|
+
"LAN access is off. Only this machine can connect.": "局域网访问已关闭,现在只能在本机访问。",
|
|
322
|
+
"New Web password": "新的 Web 密码",
|
|
323
|
+
"Confirm password": "确认密码",
|
|
324
|
+
"Leave blank to keep current password": "留空则保留当前密码",
|
|
325
|
+
"Repeat new password": "再次输入新密码",
|
|
326
|
+
"The password is permanent and survives restarts. Default: 114514. Saving a new password signs out other browsers.": "密码永久有效,重启后仍保留。默认:114514。保存新密码会使其他浏览器退出登录。",
|
|
327
|
+
"Save changes": "保存更改",
|
|
328
|
+
"Language": "语言",
|
|
329
|
+
"Interface": "界面",
|
|
330
|
+
"Plan-first turns": "先规划后执行",
|
|
331
|
+
"Split multi-step requests into a plan before answering.": "回答前先将多步骤请求拆分为计划。",
|
|
332
|
+
"Default approval mode for new conversations.": "新对话的默认审批模式。",
|
|
333
|
+
"Applying…": "正在应用…",
|
|
334
|
+
"Apply to conversation": "应用到对话",
|
|
335
|
+
"Continue with model": "使用该模型继续",
|
|
336
|
+
"Applies to the next turn.": "应用于下一回合。",
|
|
337
|
+
"Pause the current turn to change models.": "请先暂停当前回合再切换模型。",
|
|
338
|
+
"Model and intensity updated.": "模型与思考强度已更新。",
|
|
339
|
+
"Auto-compress at 80%: {tokens} tokens. Applies to this model in all conversations.": "达到 80% 时自动压缩:{tokens} tokens。应用于所有对话中的该模型。",
|
|
340
|
+
"Enter a positive whole number of tokens. Default: 1,000,000.": "请输入正整数的 token 数量。默认:1,000,000。",
|
|
341
|
+
"Defaults apply to new conversations. Other settings apply to future turns.": "默认设置应用于新对话;其他设置应用于之后的回合。",
|
|
342
|
+
"Passwords do not match.": "两次输入的密码不一致。",
|
|
343
|
+
"Password cannot be blank.": "密码不能为空。",
|
|
344
|
+
"Settings saved.": "设置已保存。",
|
|
345
|
+
"Settings saved. Web password updated permanently.": "设置已保存。Web 密码已永久更新。",
|
|
346
|
+
"(API key missing)": "(未配置 API 密钥)",
|
|
347
|
+
|
|
348
|
+
// -- login / server -----------------------------------------------------
|
|
349
|
+
"Sign in": "登录",
|
|
350
|
+
"Enter your Web password to open this console. The default password is 114514.": "输入 Web 密码以打开控制台。默认密码为 114514。",
|
|
351
|
+
"Password": "密码",
|
|
352
|
+
"Could not sign in.": "无法登录。",
|
|
353
|
+
"Incorrect password.": "密码错误。",
|
|
354
|
+
"Password login required.": "需要密码登录。",
|
|
355
|
+
"Select a conversation first.": "请先选择一个对话。",
|
|
356
|
+
"pause the current turn before changing models": "请先暂停当前回合再切换模型",
|
|
357
|
+
"unknown live session": "未知的实时会话",
|
|
358
|
+
"session not found": "未找到会话",
|
|
359
|
+
"this session cannot change approval mode": "此会话无法切换审批模式",
|
|
360
|
+
"this session has ended": "此会话已结束",
|
|
361
|
+
"this session cannot change models": "此会话无法切换模型",
|
|
362
|
+
"this session is owned by the terminal UI": "此会话由终端界面管理",
|
|
363
|
+
"working directory is required": "需要工作目录",
|
|
364
|
+
"working directory must be an absolute path": "工作目录必须是绝对路径",
|
|
365
|
+
"working directory does not exist": "工作目录不存在",
|
|
366
|
+
"working directory is not a folder": "工作目录不是文件夹",
|
|
367
|
+
"folder already exists": "文件夹已存在",
|
|
368
|
+
"folder name is required": "需要文件夹名称",
|
|
369
|
+
"folder name cannot contain a path separator": "文件夹名称不能包含路径分隔符",
|
|
370
|
+
"parent folder does not exist": "父文件夹不存在",
|
|
371
|
+
"cannot create a folder here": "无法在此创建文件夹",
|
|
372
|
+
"invalid settings body": "设置内容无效",
|
|
373
|
+
"invalid settings": "设置无效",
|
|
374
|
+
"unknown settings field": "未知的设置项",
|
|
375
|
+
"invalid language": "语言无效",
|
|
376
|
+
"invalid plan setting": "计划设置无效",
|
|
377
|
+
"invalid approval mode": "审批模式无效",
|
|
378
|
+
"invalid model selection": "模型选择无效",
|
|
379
|
+
"invalid request": "请求无效",
|
|
380
|
+
"invalid session id": "会话 ID 无效",
|
|
381
|
+
"invalid JSON body": "JSON 内容无效",
|
|
382
|
+
"empty message": "消息不能为空",
|
|
383
|
+
"cannot delete a running conversation": "无法删除正在运行的对话",
|
|
384
|
+
"this session cannot be cleared": "此会话无法清空",
|
|
385
|
+
"unknown agent": "未知的 Agent",
|
|
386
|
+
"cannot read this folder": "无法读取此文件夹",
|
|
387
|
+
"no approval is pending": "当前没有待处理的审批",
|
|
388
|
+
"mode must be request or auto": "模式必须是 request 或 auto",
|
|
389
|
+
"cross-origin request rejected": "跨域请求已被拒绝",
|
|
390
|
+
"provider, model and intensity are required": "需要服务商、模型和思考强度",
|
|
391
|
+
"invalid thinking intensity": "思考强度无效",
|
|
392
|
+
"this model does not support that thinking intensity": "该模型不支持此思考强度",
|
|
393
|
+
"unknown provider": "未知的服务商",
|
|
394
|
+
"unknown model for this provider": "该服务商下没有此模型",
|
|
395
|
+
"this model has no API key configured": "该模型尚未配置 API 密钥",
|
|
396
|
+
};
|