nolo-cli 0.180.0-alpha.1 → 0.181.0-alpha.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.
Files changed (72) hide show
  1. package/{_executeModel-ACI2KGWO.js → _executeModel-EJUKYBFV.js} +17 -17
  2. package/{agentDeleteCommand-LVSLONDD.js → agentDeleteCommand-OWDZDREL.js} +22 -21
  3. package/{agentEmailCommands-BKH3Q6I6.js → agentEmailCommands-RJGVOJXD.js} +22 -21
  4. package/{agentListCommands-JPKRBHMP.js → agentListCommands-GRJAY5ZE.js} +6 -5
  5. package/{agentMachineCommands-HRORJN73.js → agentMachineCommands-FNYZSZQ4.js} +3 -3
  6. package/{agentRecordCommands-OSZF2EHL.js → agentRecordCommands-EBDTISRS.js} +21 -20
  7. package/{agentRunCommand-FCGNSB4D.js → agentRunCommand-GIBVOCOK.js} +22 -21
  8. package/{agentRuntimeLocal-SWG5ULIJ.js → agentRuntimeLocal-AG7RCTM3.js} +2 -2
  9. package/{agentSlice-FCDRLXVA.js → agentSlice-LD6SEBSP.js} +1 -1
  10. package/{appDeleteCommands-YH3BYQYK.js → appDeleteCommands-DXF3IOFE.js} +7 -6
  11. package/{appDeployCommands-F44TNQJG.js → appDeployCommands-JVKZ3ATD.js} +7 -6
  12. package/{appDeployStatusCommands-BFTGFVQY.js → appDeployStatusCommands-VLGEMFV6.js} +7 -6
  13. package/{appGetCommands-SFLFIXPW.js → appGetCommands-JQN7RPBD.js} +7 -6
  14. package/{appListCommands-RUO5SEAJ.js → appListCommands-MFPVNCVT.js} +7 -6
  15. package/{authCommand-UIF5UTYV.js → authCommand-AX23Q2Q5.js} +6 -5
  16. package/{authCommands-BKDT4ZYB.js → authCommands-PIUTADO5.js} +2 -2
  17. package/{chromeOpsCommands-IWKUA4C3.js → chromeOpsCommands-2KFQEE3H.js} +24 -46
  18. package/{chunk-6MXCQLLB.js → chunk-53HMDUG6.js} +14 -583
  19. package/{chunk-OBKPOFOB.js → chunk-5AIXW7RW.js} +10 -10
  20. package/{chunk-HS7JBDUJ.js → chunk-5LK5OYUB.js} +3 -3
  21. package/{chunk-QUCQVMYZ.js → chunk-7O6YJN4K.js} +6 -6
  22. package/{chunk-4KDYRX3O.js → chunk-CFW7JLTH.js} +2 -2
  23. package/{chunk-PD4KNHVU.js → chunk-CJYL3N3T.js} +2 -2
  24. package/{chunk-NJI5HZQA.js → chunk-DS47C2AI.js} +2 -2
  25. package/{chunk-DVSXZC7F.js → chunk-EP2L3JUM.js} +18 -18
  26. package/{chunk-SGATEZV5.js → chunk-F55WKIWE.js} +18 -18
  27. package/chunk-G5LNJZJH.js +584 -0
  28. package/{chunk-H63VHVFY.js → chunk-HZG23JG6.js} +3 -3
  29. package/{chunk-PT6335JZ.js → chunk-I4ZVPTAI.js} +1 -1
  30. package/chunk-LKZPX6YH.js +0 -0
  31. package/{chunk-TCCBECTT.js → chunk-MAS5KGBB.js} +5 -5
  32. package/{chunk-HTSXDJHA.js → chunk-OC4NVQ5S.js} +12 -12
  33. package/{chunk-GHKEUJ6I.js → chunk-OES4RYIG.js} +2 -2
  34. package/{chunk-TDX2L4W2.js → chunk-PS3GU7YU.js} +1857 -1138
  35. package/{chunk-CGKN34IJ.js → chunk-QZRAVGW3.js} +33 -33
  36. package/{chunk-GCAOOTIS.js → chunk-SCDJOWJT.js} +2 -2
  37. package/{chunk-YAN7XTXO.js → chunk-THZHXIKZ.js} +2 -2
  38. package/{chunk-WQAOAJ5Q.js → chunk-UCE66MIJ.js} +1 -1
  39. package/{chunk-DTA4JVXW.js → chunk-UXJ7R3EP.js} +2 -2
  40. package/{chunk-QOKJFYJK.js → chunk-WQ4M3IYD.js} +9 -9
  41. package/{commandRegistry-A2RXELBX.js → commandRegistry-XRHKJCWS.js} +80 -65
  42. package/{contentThunks-GZUPF67H.js → contentThunks-FBGQIS5J.js} +6 -6
  43. package/{cooldownCommands-NS63RGBO.js → cooldownCommands-QFV3ERZX.js} +14 -28
  44. package/{createAgentAutomationAction-ZOFCBZRE.js → createAgentAutomationAction-ASIS3C6Q.js} +6 -6
  45. package/{createDialogAction-G7QCYQT7.js → createDialogAction-XJGVTBWO.js} +7 -7
  46. package/{createPageAction-Z6JQZYS5.js → createPageAction-2IWTNKUE.js} +8 -8
  47. package/{dialogCommands-MITLWDBY.js → dialogCommands-VKBNO7EI.js} +2 -2
  48. package/{dialogSlice-PKFXK5WM.js → dialogSlice-BE76QRR4.js} +4 -4
  49. package/{docCreateCommands-G3S3LZMZ.js → docCreateCommands-HFDVOS2K.js} +11 -38
  50. package/{docDeleteCommands-MLRCMLVB.js → docDeleteCommands-DMKHPD5R.js} +17 -37
  51. package/{docReadCommands-6A6SBCOP.js → docReadCommands-VAUSL2N7.js} +12 -28
  52. package/{docStore-NAEY4CEK.js → docStore-FOTFZMVS.js} +1 -1
  53. package/{docUpdateCommands-UZQC2NDO.js → docUpdateCommands-6QQUX2IN.js} +19 -73
  54. package/{handleSendMessageAction-HUQLERJP.js → handleSendMessageAction-U6DQUBLF.js} +10 -10
  55. package/index.js +17 -7
  56. package/{localRuntimeAdapter-4DJDFM7A.js → localRuntimeAdapter-DM7ERZ6Z.js} +20 -19
  57. package/{machineCommands-A3WO3FMB.js → machineCommands-OJPPEMNZ.js} +326 -113
  58. package/{machineWsRunDispatch-CIJDSHTA.js → machineWsRunDispatch-I5WWJ2EY.js} +21 -20
  59. package/package.json +1 -1
  60. package/{readlineWorkspace-YCNAWRDL.js → readlineWorkspace-RMG27VY3.js} +31 -29
  61. package/{runAgentClientLoop-K7WRMT27.js → runAgentClientLoop-QJL24CN5.js} +15 -15
  62. package/{secretCommands-7S6REMJV.js → secretCommands-XEQLKDB4.js} +33 -47
  63. package/{spaceCommands-L537SH5I.js → spaceCommands-Z325DDJU.js} +2 -2
  64. package/{streamAgentChatTurn-HKUZ7OCA.js → streamAgentChatTurn-4ZA46AEJ.js} +19 -19
  65. package/{tools-NS37KPGT.js → tools-GWQ4POVC.js} +12 -12
  66. package/{updateCommands-BXGFH4VX.js → updateCommands-KDYX32JR.js} +3 -1
  67. package/{updateDialogTitleAction-UUZ5HDM2.js → updateDialogTitleAction-VTE36JGF.js} +6 -6
  68. package/windowsSelfUpdate-IYQK4IDS.js +14 -0
  69. package/{agentPullCommand-UXXV5KKW.js → agentPullCommand-7LHBOEYH.js} +1 -1
  70. package/{chunk-COXNBVP7.js → chunk-FLX5EYLQ.js} +4 -4
  71. package/{chunk-RV4DPEAM.js → chunk-XLQ646HU.js} +3 -3
  72. package/{workloadLifecycle-MZ2V5L43.js → workloadLifecycle-2F5YKFGW.js} +7 -7
@@ -1,4 +1,4 @@
1
- // packages/cli/tui/i18n.ts
1
+ // packages/cli/i18n/locale.ts
2
2
  var ZH_PATTERNS = /^zh/i;
3
3
  function parseCliLocale(raw) {
4
4
  const normalized = raw?.trim().toLowerCase();
@@ -19,8 +19,8 @@ function detectLocaleFromEnv(env) {
19
19
  }
20
20
  return null;
21
21
  }
22
- function detectLocale(env) {
23
- return detectLocaleFromEnv(env) ?? "zh";
22
+ function detectLocale(env, fallback = "zh") {
23
+ return detectLocaleFromEnv(env) ?? fallback;
24
24
  }
25
25
  var currentLocale = detectLocale(process.env);
26
26
  function getCliLocale() {
@@ -29,8 +29,8 @@ function getCliLocale() {
29
29
  function setCliLocale(locale) {
30
30
  currentLocale = locale;
31
31
  }
32
- function initCliLocale(env = process.env) {
33
- currentLocale = detectLocale(env);
32
+ function initCliLocale(env = process.env, fallback = "zh") {
33
+ currentLocale = detectLocale(env, fallback);
34
34
  }
35
35
  function newlineHint(platform = process.platform) {
36
36
  return platform === "win32" ? "Ctrl+J" : "Shift+Enter";
@@ -56,7 +56,9 @@ function dailyWelcomeTip(now = Date.now()) {
56
56
  const day = Math.floor(now / 864e5);
57
57
  return tips[day % tips.length];
58
58
  }
59
- var STRINGS = {
59
+
60
+ // packages/cli/i18n/strings/turn.ts
61
+ var turnStrings = {
60
62
  // Welcome hint lives in WELCOME_TIPS + dailyWelcomeTip() (rotating daily
61
63
  // tips); the composer placeholder already covers "type / for commands".
62
64
  promptLabel: {
@@ -67,98 +69,6 @@ var STRINGS = {
67
69
  en: "\u2502 ",
68
70
  zh: "\u2502 "
69
71
  },
70
- placeholder: {
71
- en: "Type a message or / for commands...",
72
- zh: "\u8F93\u5165\u6D88\u606F\uFF0C\u6216\u7528 / \u67E5\u770B\u547D\u4EE4\u2026"
73
- },
74
- newDialog: {
75
- en: "new dialog",
76
- zh: "\u65B0\u5BF9\u8BDD"
77
- },
78
- startedFreshDialog: {
79
- en: "Started a fresh dialog.",
80
- zh: "\u5DF2\u5F00\u59CB\u65B0\u5BF9\u8BDD\u3002"
81
- },
82
- clearingDialog: {
83
- en: "Clearing current dialog messages...",
84
- zh: "\u6B63\u5728\u6E05\u9664\u5F53\u524D\u5BF9\u8BDD\u6D88\u606F\u2026"
85
- },
86
- clearedDialog: {
87
- en: "Cleared current dialog messages.",
88
- zh: "\u5DF2\u6E05\u9664\u5F53\u524D\u5BF9\u8BDD\u6D88\u606F\u3002"
89
- },
90
- persistentProcessesLeft: {
91
- en: "{0} persistent process(es) left running in the background.",
92
- zh: "\u4ECD\u6709 {0} \u4E2A\u5E38\u9A7B\u540E\u53F0\u8FDB\u7A0B\u5728\u540E\u53F0\u7EE7\u7EED\u8FD0\u884C\u3002"
93
- },
94
- clearNoDialog: {
95
- en: "No current dialog messages to clear.",
96
- zh: "\u5F53\u524D\u6CA1\u6709\u53EF\u6E05\u9664\u7684\u5BF9\u8BDD\u6D88\u606F\u3002"
97
- },
98
- clearUsage: {
99
- en: "Usage: /clear",
100
- zh: "\u7528\u6CD5\uFF1A/clear"
101
- },
102
- contextNextClear: {
103
- en: "clear current dialog messages",
104
- zh: "\u6E05\u9664\u5F53\u524D\u5BF9\u8BDD\u6D88\u606F"
105
- },
106
- bye: {
107
- en: "Bye.",
108
- zh: "\u518D\u89C1\u3002"
109
- },
110
- resumedDialogPrefix: {
111
- en: "Resumed dialog",
112
- zh: "\u5DF2\u6062\u590D\u5BF9\u8BDD"
113
- },
114
- resumeInvalidId: {
115
- en: "does not look like a dialog id. Use /history to pick one.",
116
- zh: "\u770B\u8D77\u6765\u4E0D\u662F dialog id\u3002\u7528 /history \u4ECE\u5217\u8868\u91CC\u9009\u4E00\u4E2A\u3002"
117
- },
118
- dialogResumeCancelled: {
119
- en: "Dialog resume cancelled.",
120
- zh: "\u5DF2\u53D6\u6D88\u6062\u590D\u5BF9\u8BDD\u3002"
121
- },
122
- agentSwitchCancelled: {
123
- en: "Agent switch cancelled.",
124
- zh: "\u5DF2\u53D6\u6D88\u5207\u6362 agent\u3002"
125
- },
126
- agentPickerLoading: {
127
- en: "Loading agents\u2026",
128
- zh: "\u6B63\u5728\u52A0\u8F7D agent \u5217\u8868\u2026"
129
- },
130
- /**
131
- * /switch 目录视图的一行提示:收藏项 hydrate 失败时出现,让「收藏看不到」
132
- * 有任何线索;失败数为 0 时不渲染这一行。
133
- */
134
- agentCatalogUnavailableFavorites: {
135
- en: "\u26A0 {0} favorite(s) unavailable right now",
136
- zh: "\u26A0 {0} \u4E2A\u6536\u85CF\u9879\u6682\u65F6\u4E0D\u53EF\u7528"
137
- },
138
- historyPickerTitle: {
139
- en: "Resume dialog (\u2191\u2193 Enter Esc)",
140
- zh: "\u6062\u590D\u5BF9\u8BDD\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
141
- },
142
- noDialogsYet: {
143
- en: "No dialogs yet.",
144
- zh: "\u8FD8\u6CA1\u6709\u5386\u53F2\u5BF9\u8BDD\u3002"
145
- },
146
- langUsage: {
147
- en: "Usage: /lang <zh|en>",
148
- zh: "\u7528\u6CD5\uFF1A/lang <zh|en>"
149
- },
150
- stopHint: {
151
- en: "Esc to stop",
152
- zh: "Esc \u505C\u6B62\u56DE\u590D"
153
- },
154
- flushQueuedIdleHint: {
155
- en: "Flushed {0} queued messages as one.",
156
- zh: "\u5DF2\u628A {0} \u6761\u6392\u961F\u6D88\u606F\u5408\u5E76\u53D1\u9001\u3002"
157
- },
158
- flushQueuedBusyHint: {
159
- en: "Stopped this reply and flushed {0} queued messages as one.",
160
- zh: "\u5DF2\u505C\u6B62\u5F53\u524D\u56DE\u590D\uFF0C\u5E76\u628A {0} \u6761\u6392\u961F\u6D88\u606F\u5408\u5E76\u53D1\u9001\u3002"
161
- },
162
72
  turnStopped: {
163
73
  en: "Stopped this reply.",
164
74
  zh: "\u5DF2\u505C\u6B62\u672C\u6B21\u56DE\u590D\u3002"
@@ -171,86 +81,107 @@ var STRINGS = {
171
81
  en: "Stopping\u2026 press Esc again to force",
172
82
  zh: "\u6B63\u5728\u505C\u6B62\u2026\u518D\u6309\u4E00\u6B21 Esc \u5F3A\u5236\u505C\u6B62"
173
83
  },
174
- forceStopped: {
175
- en: "Force stopped. Background tasks may still be finishing.",
176
- zh: "\u5DF2\u5F3A\u5236\u505C\u6B62\uFF0C\u540E\u53F0\u4EFB\u52A1\u53EF\u80FD\u4ECD\u5728\u6536\u5C3E\u3002"
177
- },
178
84
  turnFailed: {
179
85
  en: "This reply failed. Queued messages are kept \u2014 press Enter to resend.",
180
86
  zh: "\u672C\u6B21\u56DE\u590D\u51FA\u9519\u3002\u5DF2\u6392\u961F\u7684\u6D88\u606F\u4ECD\u4FDD\u7559\uFF0C\u6309 Enter \u53EF\u91CD\u65B0\u53D1\u9001\u3002"
181
87
  },
182
- quotaExhaustedHint: {
183
- en: "This agent is temporarily unavailable (HTTP 429).\nUse /agent to switch to another agent and keep going \u2014 the dialog context is preserved.",
184
- zh: "\u5F53\u524D agent \u6682\u65F6\u4E0D\u53EF\u7528\uFF08HTTP 429\uFF09\u3002\n\u53EF\u4EE5\u7528 /agent \u5207\u6362\u5230\u5176\u4ED6 agent \u540E\u7EE7\u7EED\uFF0C\u540C\u4E00\u5BF9\u8BDD\u4F1A\u4FDD\u7559\u4E0A\u4E0B\u6587\u3002"
88
+ // 回合结束的淡色收尾行:耗时 · 输出 token · 积分(后两段可缺省)。
89
+ turnSummaryOutput: {
90
+ en: "{0} out",
91
+ zh: "\u8F93\u51FA {0}"
185
92
  },
186
- balanceExhaustedHint: {
187
- en: 'Your message is saved in this dialog \u2014 top up, then send again or say "continue" to pick up where you left off.',
188
- zh: "\u4F60\u521A\u53D1\u7684\u8BDD\u5DF2\u4FDD\u5B58\u5728\u5F53\u524D\u5BF9\u8BDD\u91CC\u2014\u2014\u5145\u503C\u540E\u76F4\u63A5\u518D\u8BF4\u4E00\u53E5\u6216\u8BF4\u300C\u7EE7\u7EED\u300D\u5373\u53EF\u63A5\u7740\u804A\uFF0C\u4E0D\u4F1A\u4E22\u4E0A\u4E0B\u6587\u3002"
93
+ // --- Ask choice (ask_user) ------------------------------------------
94
+ askChoiceTitle: {
95
+ en: "question",
96
+ zh: "\u95EE\u9898"
189
97
  },
190
- balanceInsufficientReason: {
191
- en: "Insufficient balance: requires > {required}, current balance {current}.",
192
- zh: "\u4F59\u989D\u4E0D\u8DB3\uFF1A\u9700\u8981\u4F59\u989D > {required}\uFF0C\u5F53\u524D {current}\u3002"
98
+ askChoiceScrollHint: {
99
+ en: "\u2191 Shift+wheel scrolls back terminal history",
100
+ zh: "\u2191 Shift+\u6EDA\u8F6E\u53EF\u56DE\u770B\u4E0A\u65B9\u6D88\u606F"
193
101
  },
194
- dialogPreservedHint: {
195
- en: 'This turn failed, but the dialog is kept. Send another message (or say "continue") to keep going in the same conversation.',
196
- zh: "\u672C\u8F6E\u5931\u8D25\u4E86\uFF0C\u4F46\u5BF9\u8BDD\u5DF2\u4FDD\u7559\u3002\u76F4\u63A5\u518D\u8BF4\u4E00\u53E5\uFF08\u6216\u8BF4\u300C\u7EE7\u7EED\u300D\uFF09\u5373\u53EF\u5728\u540C\u4E00\u5BF9\u8BDD\u91CC\u63A5\u7740\u804A\u3002"
102
+ askChoiceSubmit: {
103
+ en: "submit \u2193",
104
+ zh: "\u63D0\u4EA4 \u2193"
197
105
  },
198
- dialogNotSavedHint: {
199
- en: "This turn did not create a dialog. Your next message will start a new conversation \u2014 restate what you need.",
200
- zh: "\u672C\u8F6E\u6CA1\u6709\u5EFA\u6210\u5BF9\u8BDD\u3002\u4E0B\u4E00\u53E5\u4F1A\u662F\u65B0\u5BF9\u8BDD\u2014\u2014\u8BF7\u628A\u4F60\u60F3\u505A\u7684\u4E8B\u518D\u8BF4\u4E00\u904D\u3002"
106
+ askChoiceSubmitRow: {
107
+ en: "Done",
108
+ zh: "\u5B8C\u6210"
201
109
  },
202
- copiedLastReply: {
203
- en: "Copied the last reply to the clipboard.",
204
- zh: "\u5DF2\u590D\u5236\u6700\u540E\u4E00\u6761\u56DE\u590D\u5230\u526A\u8D34\u677F\u3002"
110
+ askChoiceSkipRow: {
111
+ en: "Skip",
112
+ zh: "\u8DF3\u8FC7"
205
113
  },
206
- copyNothing: {
207
- en: "Nothing to copy yet.",
208
- zh: "\u8FD8\u6CA1\u6709\u53EF\u590D\u5236\u7684\u5185\u5BB9\u3002"
114
+ askChoiceOtherLabel: {
115
+ en: "Other",
116
+ zh: "\u5176\u4ED6"
209
117
  },
210
- copyFailed: {
211
- en: "Copy failed",
212
- zh: "\u590D\u5236\u5931\u8D25"
118
+ askChoiceHintSingle: {
119
+ en: "Enter/Space picks \xB7 single question sends \xB7 multi-question jumps to the next unanswered \xB7 Enter in Other confirms and continues",
120
+ zh: "Enter/\u7A7A\u683C \u9009\u62E9\uFF1A\u5355\u9898\u76F4\u63A5\u53D1\u9001\u3001\u591A\u9898\u8DF3\u5230\u4E0B\u4E00\u672A\u7B54\u9898 \xB7 \u5176\u4ED6\u8F93\u5165\u540E Enter \u786E\u8BA4\u5E76\u7EE7\u7EED"
213
121
  },
214
- copyUnavailable: {
215
- en: "Clipboard is unavailable in this environment. The last reply was printed above for manual copy.",
216
- zh: "\u5F53\u524D\u73AF\u5883\u6CA1\u6709\u53EF\u7528\u7684\u526A\u8D34\u677F\u3002\u6700\u540E\u4E00\u6761\u56DE\u590D\u5DF2\u6253\u5370\u5728\u4E0A\u65B9\uFF0C\u53EF\u624B\u52A8\u590D\u5236\u3002"
122
+ askChoiceHintOptional: {
123
+ en: "Optional question \u2014 Enter/Space picks (one step) \xB7 skip if you don't want to answer",
124
+ zh: "\u53EF\u9009\u9898 \u2014 Enter/\u7A7A\u683C \u9009\u62E9\u5373\u5B8C\u6210 \xB7 \u4E0D\u60F3\u56DE\u7B54\u53EF\u8DF3\u8FC7"
217
125
  },
218
- copyUsage: {
219
- en: "Usage: /copy",
220
- zh: "\u7528\u6CD5\uFF1A/copy"
126
+ askChoiceHintMulti: {
127
+ en: "Enter/Space toggles \xB7 \u2193 to Done row, Enter sends",
128
+ zh: "Enter/\u7A7A\u683C \u5207\u6362\u9009\u4E2D \xB7 \u2193 \u5230\u5B8C\u6210\u884C Enter \u53D1\u9001"
221
129
  },
222
- copiedToClipboard: {
223
- en: "\u2713 Copied to clipboard.",
224
- zh: "\u2713 \u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F\u3002"
130
+ askChoiceFooterSingle: {
131
+ en: "\u21B5 pick/send \xB7 tab switch \xB7 esc cancel",
132
+ zh: "\u21B5 \u9009\u62E9/\u53D1\u9001 \xB7 tab \u5207\u6362 \xB7 esc \u53D6\u6D88"
225
133
  },
226
- copiedSelection: {
227
- en: "\u2713 Copied the selection to the clipboard.",
228
- zh: "\u2713 \u5DF2\u590D\u5236\u9009\u533A\u5230\u526A\u8D34\u677F\u3002"
134
+ askChoiceFooterSkip: {
135
+ en: "\u21B5 pick/send \xB7 \u2193 skip row \u21B5 skip \xB7 tab switch \xB7 esc cancel",
136
+ zh: "\u21B5 \u9009\u62E9/\u53D1\u9001 \xB7 \u2193 \u8DF3\u8FC7\u884C \u21B5 \u8DF3\u8FC7 \xB7 tab \u5207\u6362 \xB7 esc \u53D6\u6D88"
229
137
  },
230
- copiedSelectionBusy: {
231
- en: "\u2713 Copied the selection to the clipboard. Press Esc to stop generating.",
232
- zh: "\u2713 \u5DF2\u590D\u5236\u9009\u533A\u5230\u526A\u8D34\u677F\u3002\u6309 Esc \u505C\u6B62\u751F\u6210\u3002"
138
+ askChoiceFooterMulti: {
139
+ en: "\u21B5 toggle \xB7 \u2193 done row \u21B5 send \xB7 ctrl+s send \xB7 tab switch \xB7 esc cancel",
140
+ zh: "\u21B5 \u5207\u6362 \xB7 \u2193 \u5B8C\u6210\u884C \u21B5 \u53D1\u9001 \xB7 ctrl+s \u53D1\u9001 \xB7 tab \u5207\u6362 \xB7 esc \u53D6\u6D88"
233
141
  },
234
- copiedAllHistory: {
235
- en: "\u2713 Copied the full conversation to the clipboard.",
236
- zh: "\u2713 \u5DF2\u590D\u5236\u5B8C\u6574\u5BF9\u8BDD\u5230\u526A\u8D34\u677F\u3002"
142
+ askChoiceValidationRequired: {
143
+ en: "Required questions are unanswered \u2014 jumped to the first one.",
144
+ zh: "\u5FC5\u586B\u95EE\u9898\u5C1A\u672A\u56DE\u7B54 \u2014 \u5DF2\u8DF3\u8F6C\u5230\u7B2C\u4E00\u4E2A\u672A\u7B54\u9898\u3002"
237
145
  },
238
- copyAllNothing: {
239
- en: "No conversation to copy yet.",
240
- zh: "\u8FD8\u6CA1\u6709\u53EF\u590D\u5236\u7684\u5BF9\u8BDD\u5185\u5BB9\u3002"
146
+ askChoiceHistoryHint: {
147
+ en: "Type a number to choose, or reply directly:",
148
+ zh: "\u8BF7\u8F93\u5165\u5E8F\u53F7\u9009\u62E9\uFF0C\u6216\u76F4\u63A5\u56DE\u590D\uFF1A"
241
149
  },
242
- ctrlCExitHint: {
243
- en: "[\u63D0\u793A] \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA | \u8F93\u5165 /copy \u53EF\u590D\u5236\u6700\u65B0\u56DE\u590D",
244
- zh: "[\u63D0\u793A] \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA | \u8F93\u5165 /copy \u53EF\u590D\u5236\u6700\u65B0\u56DE\u590D"
150
+ askChoiceHistorySelected: {
151
+ en: "selected",
152
+ zh: "\u5DF2\u9009"
245
153
  },
246
- ctrlCClearedDraft: {
247
- en: "Draft cleared.",
248
- zh: "\u8F93\u5165\u8349\u7A3F\u5DF2\u6E05\u7A7A\u3002"
154
+ askChoiceHistoryCancelled: {
155
+ en: "cancelled",
156
+ zh: "\u5DF2\u53D6\u6D88"
157
+ }
158
+ };
159
+
160
+ // packages/cli/i18n/strings/session.ts
161
+ var sessionStrings = {
162
+ clearingDialog: {
163
+ en: "Clearing current dialog messages...",
164
+ zh: "\u6B63\u5728\u6E05\u9664\u5F53\u524D\u5BF9\u8BDD\u6D88\u606F\u2026"
249
165
  },
250
- // 空草稿按 Backspace 逐个撤销附件(composer 附件条)。
251
- attachmentRemovedHint: {
252
- en: "Removed attachment {0}, {1} remaining",
253
- zh: "\u5DF2\u79FB\u9664\u9644\u4EF6 {0}\uFF0C\u5269\u4F59 {1} \u5F20"
166
+ clearedDialog: {
167
+ en: "Cleared current dialog messages.",
168
+ zh: "\u5DF2\u6E05\u9664\u5F53\u524D\u5BF9\u8BDD\u6D88\u606F\u3002"
169
+ },
170
+ clearNoDialog: {
171
+ en: "No current dialog messages to clear.",
172
+ zh: "\u5F53\u524D\u6CA1\u6709\u53EF\u6E05\u9664\u7684\u5BF9\u8BDD\u6D88\u606F\u3002"
173
+ },
174
+ clearUsage: {
175
+ en: "Usage: /clear",
176
+ zh: "\u7528\u6CD5\uFF1A/clear"
177
+ },
178
+ historyPickerTitle: {
179
+ en: "Resume dialog (\u2191\u2193 Enter Esc)",
180
+ zh: "\u6062\u590D\u5BF9\u8BDD\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
181
+ },
182
+ langUsage: {
183
+ en: "Usage: /lang <zh|en>",
184
+ zh: "\u7528\u6CD5\uFF1A/lang <zh|en>"
254
185
  },
255
186
  historyNoToken: {
256
187
  en: "History requires an auth token. Run `nolo login` or set AUTH_TOKEN.",
@@ -260,30 +191,6 @@ var STRINGS = {
260
191
  en: "Could not read a user id from AUTH_TOKEN. Run `nolo login` again.",
261
192
  zh: "\u65E0\u6CD5\u4ECE AUTH_TOKEN \u89E3\u6790\u51FA\u7528\u6237 id\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C `nolo login`\u3002"
262
193
  },
263
- mouseOn: {
264
- en: "Mouse mode on: wheel scrolls the transcript; hold Shift (or Option/Fn) to select text.",
265
- zh: "\u9F20\u6807\u6A21\u5F0F\u5DF2\u5F00\u542F\uFF1A\u6EDA\u8F6E\u6EDA\u52A8\u5BF9\u8BDD\u8BB0\u5F55\uFF1B\u6309\u4F4F Shift\uFF08\u6216 Option/Fn\uFF09\u53EF\u62D6\u9009\u590D\u5236\u3002"
266
- },
267
- mouseOff: {
268
- en: "Mouse mode off: drag to select/copy freely; scroll with PageUp/PageDown.",
269
- zh: "\u9F20\u6807\u6A21\u5F0F\u5DF2\u5173\u95ED\uFF1A\u53EF\u76F4\u63A5\u62D6\u9009\u590D\u5236\uFF1B\u7528 PageUp/PageDown \u6EDA\u52A8\u5BF9\u8BDD\u8BB0\u5F55\u3002"
270
- },
271
- mouseUsage: {
272
- en: "Usage: /mouse <on|off>",
273
- zh: "\u7528\u6CD5\uFF1A/mouse <on|off>"
274
- },
275
- mathOn: {
276
- en: "Math rendering on: LaTeX formulas rendered with Unicode symbols.",
277
- zh: "\u6570\u5B66\u516C\u5F0F\u6E32\u67D3\u5DF2\u5F00\u542F\uFF1ALaTeX \u516C\u5F0F\u5C06\u8F6C\u5199\u4E3A Unicode \u7B26\u53F7\u3002"
278
- },
279
- mathOff: {
280
- en: "Math rendering off: raw LaTeX formulas preserved.",
281
- zh: "\u6570\u5B66\u516C\u5F0F\u6E32\u67D3\u5DF2\u5173\u95ED\uFF1A\u4FDD\u7559\u539F\u59CB LaTeX \u516C\u5F0F\u3002"
282
- },
283
- mathUsage: {
284
- en: "Usage: /math <on|off>",
285
- zh: "\u7528\u6CD5\uFF1A/math <on|off>"
286
- },
287
194
  altscreenOn: {
288
195
  en: "Alternate screen on: the TUI uses a private buffer so the terminal wheel no longer fights its own scroll state.",
289
196
  zh: "\u5907\u7528\u5C4F\u5DF2\u5F00\u542F\uFF1ATUI \u4F7F\u7528\u72EC\u7ACB\u7F13\u51B2\u533A\uFF0C\u7EC8\u7AEF\u6EDA\u8F6E\u4E0D\u518D\u4E0E\u81EA\u8EAB\u6EDA\u52A8\u72B6\u6001\u4E92\u76F8\u6253\u67B6\u3002"
@@ -296,8 +203,148 @@ var STRINGS = {
296
203
  en: "Usage: /altscreen <on|off>",
297
204
  zh: "\u7528\u6CD5\uFF1A/altscreen <on|off>"
298
205
  },
299
- autoUsage: {
300
- en: "Usage: /auto [local|remote] <on|off> \xB7 /auto reset (clear both)",
206
+ langSwitched: {
207
+ en: "Language switched to English.",
208
+ zh: "\u5DF2\u5207\u6362\u4E3A\u4E2D\u6587\u3002"
209
+ },
210
+ helpText: {
211
+ en: [
212
+ "Commands:",
213
+ " /help Show this help",
214
+ " /new Clear screen and start a fresh dialog",
215
+ " /compact Compact current dialog and fork a new one",
216
+ " /context Show workspace context and next actions",
217
+ " /cd <path> Change the working directory (takes effect on the next turn)",
218
+ " /runtime <mode> Use auto, local, or server runtime",
219
+ " /switch Pick an agent interactively (\u2191\u2193, Enter)",
220
+ " /switch list List agents as text",
221
+ " /switch <name> Switch directly by name, alias, or key (alias: /agent)",
222
+ " /agents List platform agent shortcuts",
223
+ " /history Pick a recent dialog to resume (\u2191\u2193, Enter)",
224
+ " /resume <dialogId> Resume a dialog directly by id",
225
+ " /lang <zh|en> Switch interface language",
226
+ ' /copy [all] Copy the last reply (or the full conversation with "all") to the clipboard',
227
+ " /paste Read the clipboard now (image \u2192 attachment, text \u2192 draft)",
228
+ " /transcribe <media> Transcribe an audio/video file; transcript attaches to your next message",
229
+ " Drag a file in Drop an image file on the terminal to attach it; audio/video transcribes; other files stay paths",
230
+ " Shift+Enter / Ctrl+J Insert a newline in the draft",
231
+ " /mouse <on|off> Toggle mouse mode (off = drag to select text)",
232
+ " /auto [local|remote] <on|off> Approve one permission bucket (local-run confirms / remote-origin shell) so it stops asking; saved to your config. /auto reset clears both",
233
+ " /shell-revoke Revoke this session's shell grant; the next shell call re-asks (works while a reply runs; does not interrupt a running command)",
234
+ " /math <on|off> Toggle math formula rendering (Unicode transcription)",
235
+ " /altscreen <on|off> Toggle the terminal alternate screen (default on; off shares shell scrollback)",
236
+ " Shift+drag Select text natively even while mouse mode is on (terminal bypass)",
237
+ " /doc List attached docs",
238
+ " /doc attach <doc> Attach a doc to this workspace",
239
+ " /skill List attached skills",
240
+ " /skill attach <ref> Attach a skill (dbKey, name, or SKILL.md path)",
241
+ " /skill detach <ref> Detach a skill",
242
+ " /skill clear Detach all skills",
243
+ " /customize Describe how you want to tune nolo",
244
+ " /tasks List background process tasks (aliases: /jobs, /procs)",
245
+ " /stop <pid|all> Stop background process tasks",
246
+ " /login Show login/profile hint (/login --server <url> to log in here)",
247
+ " /profile Show active profile",
248
+ " /update Update the nolo CLI install",
249
+ " /version Show version/update hint",
250
+ " /logs Show recent diagnostics and the log file path",
251
+ " /learn Review this dialog for reusable tool/prompt improvements",
252
+ " /learn <1-100> Triage recent Evolution candidates and deep-review one",
253
+ " /exit Leave the workspace",
254
+ "",
255
+ "You can also type normally. nolo routes simple read/status requests to CLI commands and sends the rest to the current agent."
256
+ ].join("\n"),
257
+ zh: [
258
+ "\u547D\u4EE4\uFF1A",
259
+ " /help \u663E\u793A\u672C\u5E2E\u52A9",
260
+ " /new \u6E05\u5C4F\u5E76\u5F00\u59CB\u65B0\u5BF9\u8BDD",
261
+ " /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\u5E76\u5206\u53C9\u51FA\u65B0\u5BF9\u8BDD",
262
+ " /context \u67E5\u770B\u5DE5\u4F5C\u533A\u4E0A\u4E0B\u6587\u4E0E\u540E\u7EED\u64CD\u4F5C",
263
+ " /cd <path> \u5207\u6362\u5DE5\u4F5C\u76EE\u5F55\uFF08\u4E0B\u4E2A turn \u751F\u6548\uFF09",
264
+ " /runtime <mode> \u5207\u6362 runtime\uFF1Aauto\u3001local\u3001server",
265
+ " /switch \u4EA4\u4E92\u5F0F\u9009\u62E9 agent\uFF08\u2191\u2193 \u79FB\u52A8\uFF0CEnter \u786E\u8BA4\uFF09",
266
+ " /switch list \u4EE5\u6587\u672C\u5217\u51FA\u5168\u90E8 agent",
267
+ " /switch <name> \u6309\u540D\u79F0\u3001\u522B\u540D\u6216 key \u76F4\u63A5\u5207\u6362\uFF08\u522B\u540D\uFF1A/agent\uFF09",
268
+ " /agents \u5217\u51FA\u5E73\u53F0 agent \u5FEB\u6377\u65B9\u5F0F",
269
+ " /history \u4ECE\u6700\u8FD1\u5BF9\u8BDD\u4E2D\u9009\u62E9\u5E76\u6062\u590D\uFF08\u2191\u2193\uFF0CEnter\uFF09",
270
+ " /resume <dialogId> \u6309 id \u76F4\u63A5\u6062\u590D\u5BF9\u8BDD",
271
+ " /lang <zh|en> \u5207\u6362\u754C\u9762\u8BED\u8A00",
272
+ " /copy [all] \u590D\u5236\u6700\u540E\u4E00\u6761\u56DE\u590D\u5230\u526A\u8D34\u677F\uFF08\u52A0 all \u590D\u5236\u5B8C\u6574\u5BF9\u8BDD\uFF09",
273
+ " /paste \u7ACB\u5373\u8BFB\u526A\u8D34\u677F\uFF08\u56FE\u7247\u2192\u9644\u4EF6\uFF0C\u6587\u672C\u2192\u8349\u7A3F\uFF09",
274
+ " /transcribe <\u5A92\u4F53> \u8F6C\u5199\u97F3\u89C6\u9891\u6587\u4EF6\uFF1B\u8F6C\u5199\u6587\u672C\u968F\u4E0B\u4E00\u6761\u6D88\u606F\u53D1\u7ED9\u6A21\u578B",
275
+ " \u62D6\u5165\u6587\u4EF6 \u628A\u56FE\u7247\u6587\u4EF6\u62D6\u8FDB\u7EC8\u7AEF\u5373\u6210\u4E3A\u9644\u4EF6\uFF1B\u97F3\u89C6\u9891\u81EA\u52A8\u8F6C\u5199\uFF1B\u5176\u4ED6\u6587\u4EF6\u53EA\u7559\u8DEF\u5F84",
276
+ " Shift+Enter / Ctrl+J \u5728\u8349\u7A3F\u91CC\u6362\u884C",
277
+ " /mouse <on|off> \u5207\u6362\u9F20\u6807\u6A21\u5F0F\uFF08off \u540E\u53EF\u76F4\u63A5\u62D6\u9009\u6587\u672C\uFF09",
278
+ " /auto [local|remote] <on|off> \u6388\u6743\u67D0\u4E00\u6876\uFF08\u672C\u673A run \u786E\u8BA4 / \u8FDC\u7A0B\u6765\u6E90 shell\uFF09\u4E0D\u518D\u9010\u6B21\u8BE2\u95EE\uFF0C\u5E76\u4FDD\u5B58\u5230\u914D\u7F6E\uFF1B/auto reset \u4E24\u6876\u6E05\u96F6",
279
+ " /shell-revoke \u64A4\u9500\u672C\u4F1A\u8BDD\u7684 shell \u6267\u884C\u6388\u6743\uFF0C\u4E0B\u4E00\u6B21 shell \u8C03\u7528\u91CD\u65B0\u786E\u8BA4\uFF08\u56DE\u590D\u8FDB\u884C\u4E2D\u4E5F\u53EF\u7528\uFF1B\u4E0D\u4E2D\u65AD\u5DF2\u653E\u884C\u7684\u547D\u4EE4\uFF09",
280
+ " /math <on|off> \u5207\u6362\u6570\u5B66\u516C\u5F0F\u6E32\u67D3\uFF08Unicode \u8F6C\u5199\uFF09",
281
+ " /altscreen <on|off> \u5207\u6362\u7EC8\u7AEF\u5907\u7528\u5C4F\uFF08\u9ED8\u8BA4 on\uFF1Boff \u6539\u4E3A\u4E0E shell \u5171\u7528\u56DE\u6EDA\uFF09",
282
+ " Shift+\u62D6\u62FD \u9F20\u6807\u6A21\u5F0F\u5F00\u542F\u65F6\u4E5F\u53EF\u539F\u751F\u9009\u4E2D\u6587\u672C\uFF08\u7EC8\u7AEF\u7ED5\u8FC7\u4FEE\u9970\u952E\uFF09",
283
+ " /doc \u5217\u51FA\u5DF2\u6302\u8F7D\u7684\u6587\u6863",
284
+ " /doc attach <doc> \u6302\u8F7D\u6587\u6863\u5230\u5F53\u524D\u5DE5\u4F5C\u533A",
285
+ " /skill \u5217\u51FA\u5DF2\u6302\u8F7D\u7684\u6280\u80FD",
286
+ " /skill attach <ref> \u6302\u8F7D\u6280\u80FD\uFF08dbKey\u3001\u540D\u79F0\u6216 SKILL.md \u8DEF\u5F84\uFF09",
287
+ " /skill detach <ref> \u5378\u8F7D\u6307\u5B9A\u6280\u80FD",
288
+ " /skill clear \u5378\u8F7D\u5168\u90E8\u6280\u80FD",
289
+ " /customize \u63CF\u8FF0\u4F60\u60F3\u600E\u4E48\u8C03\u6559 nolo",
290
+ " /tasks \u5217\u51FA\u540E\u53F0\u5B50\u8FDB\u7A0B\u4EFB\u52A1\uFF08\u522B\u540D\uFF1A/jobs, /procs\uFF09",
291
+ " /stop <pid|all> \u505C\u6B62\u6307\u5B9A\u7684\u540E\u53F0\u4EFB\u52A1",
292
+ " /login \u67E5\u770B\u767B\u5F55 / \u914D\u7F6E\u63D0\u793A\uFF08/login --server <url> \u53EF\u5728\u672C\u4F1A\u8BDD\u5185\u767B\u5F55\uFF09",
293
+ " /profile \u67E5\u770B\u5F53\u524D\u914D\u7F6E\u73AF\u5883",
294
+ " /update \u66F4\u65B0 nolo CLI",
295
+ " /version \u67E5\u770B\u7248\u672C\u4E0E\u66F4\u65B0\u63D0\u793A",
296
+ " /logs \u67E5\u770B\u6700\u8FD1\u8BCA\u65AD\u8BB0\u5F55\u4E0E\u65E5\u5FD7\u6587\u4EF6\u4F4D\u7F6E",
297
+ " /learn \u4ECE\u5F53\u524D\u5BF9\u8BDD\u590D\u76D8\u53EF\u590D\u7528\u7684\u5DE5\u5177/\u63D0\u793A\u8BCD\u6539\u8FDB",
298
+ " /learn <1-100> \u7B5B\u9009\u8FD1\u671F Evolution Candidate \u5E76\u6DF1\u5EA6\u590D\u76D8\u4E00\u6761",
299
+ " /exit \u9000\u51FA\u5DE5\u4F5C\u533A",
300
+ "",
301
+ "\u4E5F\u53EF\u4EE5\u76F4\u63A5\u8F93\u5165\u81EA\u7136\u8BED\u8A00\u3002\u7B80\u5355\u7684\u8BFB\u53D6/\u72B6\u6001\u8BF7\u6C42\u4F1A\u8D70 CLI \u547D\u4EE4\uFF0C\u5176\u4F59\u4EA4\u7ED9\u5F53\u524D agent\u3002"
302
+ ].join("\n")
303
+ },
304
+ themeCurrent: { en: "Current theme: {0} \xB7 {1}", zh: "\u5F53\u524D\u4E3B\u9898\uFF1A{0} \xB7 {1}" },
305
+ themeUsage: {
306
+ en: "Usage: /theme <name> | /theme terminal | /theme light | /theme dark | /theme refresh",
307
+ zh: "\u7528\u6CD5\uFF1A/theme <name> | /theme terminal | /theme light | /theme dark | /theme refresh"
308
+ },
309
+ themeAvailable: { en: "Available themes: {0}", zh: "\u53EF\u7528\u4E3B\u9898\uFF1A{0}" },
310
+ themeBrightnessSwitched: { en: "Switched to {0} background colors.", zh: "\u5DF2\u5207\u6362\u5230 {0} \u80CC\u666F\u8272\u3002" },
311
+ themeBrightnessAuto: {
312
+ en: "Theme now follows terminal colors (/theme auto is an alias).",
313
+ zh: "\u4E3B\u9898\u5DF2\u8DDF\u968F\u7EC8\u7AEF\u914D\u8272\uFF08/theme auto \u4E3A\u517C\u5BB9\u522B\u540D\uFF09\u3002"
314
+ },
315
+ themeRefreshed: {
316
+ en: "Re-detected terminal background: {0}.",
317
+ zh: "\u5DF2\u91CD\u65B0\u68C0\u6D4B\u7EC8\u7AEF\u80CC\u666F\uFF1A{0}\u3002"
318
+ },
319
+ themeRefreshFailed: {
320
+ en: "Could not detect terminal background (not a TTY or no response).",
321
+ zh: "\u65E0\u6CD5\u68C0\u6D4B\u7EC8\u7AEF\u80CC\u666F\uFF08\u975E TTY \u6216\u7EC8\u7AEF\u65E0\u54CD\u5E94\uFF09\u3002"
322
+ },
323
+ themeSwitched: { en: "Switched to theme: {0}", zh: "\u5DF2\u5207\u6362\u5230\u4E3B\u9898\uFF1A{0}" },
324
+ themeUnknown: { en: "Unknown theme: {0}. Available themes: {1}", zh: "\u672A\u77E5\u4E3B\u9898\uFF1A{0}\u3002\u53EF\u7528\u4E3B\u9898\uFF1A{1}" },
325
+ cdUsage: {
326
+ en: "Usage: /cd <path> (relative, absolute, ~, or -; takes effect on the next turn)",
327
+ zh: "\u7528\u6CD5\uFF1A/cd <path>\uFF08\u76F8\u5BF9\u3001\u7EDD\u5BF9\u3001~ \u6216 - \u8DEF\u5F84\uFF1B\u4E0B\u4E2A turn \u751F\u6548\uFF09"
328
+ },
329
+ cdCurrent: { en: "Current directory: {0}", zh: "\u5F53\u524D\u76EE\u5F55\uFF1A{0}" },
330
+ cdSwitched: { en: "Working directory: {0}", zh: "\u5DE5\u4F5C\u76EE\u5F55\uFF1A{0}" },
331
+ cdNotFound: { en: "Directory not found: {0}", zh: "\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A{0}" },
332
+ cdNotDir: { en: "Not a directory: {0}", zh: "\u4E0D\u662F\u76EE\u5F55\uFF1A{0}" },
333
+ cdNoPrevious: { en: "No previous directory.", zh: "\u6CA1\u6709\u4E0A\u4E00\u4E2A\u76EE\u5F55\u3002" },
334
+ cdSwitchedMessage: {
335
+ en: "Working directory changed: {0} \u2192 {1}. Subsequent tool execution and file operations use the new directory.",
336
+ zh: "\u5DE5\u4F5C\u76EE\u5F55\u5DF2\u5207\u6362\uFF1A{0} \u2192 {1}\u3002\u540E\u7EED\u5DE5\u5177\u6267\u884C\u4E0E\u6587\u4EF6\u64CD\u4F5C\u4EE5\u65B0\u76EE\u5F55\u4E3A\u51C6\u3002"
337
+ },
338
+ welcomeAuthGuidance: {
339
+ en: 'Not logged in to Nolo \u2014 three ways to get going:\n \xB7 Run a task on local Codex: nolo run "<task>" (no login needed)\n \xB7 Bind your own model subscription: nolo auth antigravity | claude | chatgpt | xai\n \xB7 Use the Nolo platform: type /login (gives you a browser authorization link)',
340
+ zh: '\u672A\u767B\u5F55 Nolo \u2014\u2014 \u4E09\u6761\u8DEF\u90FD\u80FD\u7528\uFF1A\n \xB7 \u7528\u672C\u5730 Codex \u8DD1\u4EFB\u52A1\uFF1Anolo run "<\u4EFB\u52A1>"\uFF08\u4E0D\u9700\u8981\u767B\u5F55\uFF09\n \xB7 \u7ED1\u5B9A\u4F60\u81EA\u5DF1\u7684\u6A21\u578B\u8BA2\u9605\uFF1Anolo auth antigravity | claude | chatgpt | xai\n \xB7 \u7528 Nolo \u5E73\u53F0\uFF1A\u76F4\u63A5\u8F93\u5165 /login\uFF08\u4F1A\u7ED9\u51FA\u6D4F\u89C8\u5668\u6388\u6743\u94FE\u63A5\uFF09'
341
+ }
342
+ };
343
+
344
+ // packages/cli/i18n/strings/tool.ts
345
+ var toolStrings = {
346
+ autoUsage: {
347
+ en: "Usage: /auto [local|remote] <on|off> \xB7 /auto reset (clear both)",
301
348
  zh: "\u7528\u6CD5\uFF1A/auto [local|remote] <on|off> \xB7 /auto reset\uFF08\u4E24\u6876\u6E05\u96F6\uFF09"
302
349
  },
303
350
  autoStateLine: {
@@ -340,153 +387,86 @@ var STRINGS = {
340
387
  en: "Approved from your saved config: {0}. Those confirmations are skipped; undo with /auto reset.",
341
388
  zh: "\u5DF2\u4ECE\u4FDD\u5B58\u7684\u914D\u7F6E\u751F\u6548\u7684\u6388\u6743\uFF1A{0}\u3002\u8FD9\u4E9B\u786E\u8BA4\u5DF2\u88AB\u8DF3\u8FC7\uFF1B\u64A4\u9500\u7528 /auto reset\u3002"
342
389
  },
343
- langSwitched: {
344
- en: "Language switched to English.",
345
- zh: "\u5DF2\u5207\u6362\u4E3A\u4E2D\u6587\u3002"
346
- },
347
- // --- Tool trace copy ------------------------------------------------------
348
- // The compact trace shows only status, never timing or output size: a line
349
- // count told the user nothing actionable and the ms figure read as noise.
350
- workingFallback: {
351
- en: "Working\u2026",
352
- zh: "\u5904\u7406\u4E2D\u2026"
390
+ toolNeedsAction: {
391
+ en: "needs action",
392
+ zh: "\u5F85\u786E\u8BA4"
353
393
  },
354
- // 回合结束的淡色收尾行:耗时 · 输出 token · 积分(后两段可缺省)。
355
- turnSummaryOutput: {
356
- en: "{0} out",
357
- zh: "\u8F93\u51FA {0}"
394
+ toolTimedOut: {
395
+ en: "timed out",
396
+ zh: "\u5DF2\u8D85\u65F6"
358
397
  },
359
- thinkingActive: {
360
- en: "Thinking\u2026",
361
- zh: "\u601D\u8003\u4E2D\u2026"
398
+ toolExitCode: {
399
+ en: "exit",
400
+ zh: "\u9000\u51FA\u7801"
362
401
  },
363
- thinkingActivePreview: {
364
- en: "Thinking: {0}",
365
- zh: "\u601D\u8003\u4E2D\uFF1A{0}"
402
+ toolFailed: {
403
+ en: "failed",
404
+ zh: "\u5931\u8D25"
366
405
  },
367
- // --- Pre-delta turn phase labels (ctx-overflow-feedback batch 3) ----------
368
- // Rendered on the spinner / activity line while the local runtime checks the
369
- // context window, compacts history, or waits for the first model delta —
370
- // the previously silent pre-delta window (batch 1/2a 修好 runtime 与 SSE,
371
- // 这里补齐 CLI/TUI 的状态行投影)。compacting 行附带可取消提示:Esc /
372
- // Ctrl+C 即 abort,语义与 localLoop 的 abortSignal 一致。
373
- contextChecking: {
374
- en: "Checking this model's context window\u2026",
375
- zh: "\u6B63\u5728\u68C0\u67E5\u5F53\u524D\u6A21\u578B\u7684\u4E0A\u4E0B\u6587\u7A97\u53E3\u2026"
406
+ // 分享 OAuth agent 的 shell 会话授权确认(块 D):首次 execShell/
407
+ // launchProcess 前弹。必须把三件事说清——这是谁的 agent / 命令在哪台
408
+ // 设备哪个工作区跑 / 任意 shell 可读写该用户可访问的资源。
409
+ // 子 run 的 per-call shell 确认(远程来源在本机跑一条命令):与会话授权同一套
410
+ // 语义,参数为 runId / agentKey / owner / device / workspace / 权限提示。
411
+ "shellPerCall.title": {
412
+ en: "Allow a remote origin to run this command on this machine?",
413
+ zh: "\u5141\u8BB8\u8FDC\u7A0B\u6765\u6E90\u5728\u672C\u673A\u6267\u884C\u8FD9\u6761\u547D\u4EE4\u5417\uFF1F"
376
414
  },
377
- contextCompacting: {
378
- en: "Compacting history\u2026 (Esc/Ctrl+C to cancel)",
379
- zh: "\u6B63\u5728\u538B\u7F29\u5386\u53F2\u8BB0\u5F55\u2026\uFF08Esc/Ctrl+C \u53D6\u6D88\uFF09"
415
+ "shellPerCall.body": {
416
+ en: "A remote origin asked to run one shell command on this device.\nRun: {0}\nAgent: {1}\nOwner: {2}\nDevice: {3}\nWorkspace: {4}\n{5}\n\nShell commands can read/write anything this user can access. Approving covers this whole class: remote-origin shell confirmations stop asking one by one (this session and future starts). Undo with /shell-revoke or /auto remote off.",
417
+ zh: "\u8FDC\u7A0B\u6765\u6E90\u8BF7\u6C42\u5728\u672C\u673A\u6267\u884C\u4E00\u6761 shell \u547D\u4EE4\u3002\nRun\uFF1A{0}\nAgent\uFF1A{1}\n\u4E3B\u4EBA\uFF1A{2}\n\u8BBE\u5907\uFF1A{3}\n\u5DE5\u4F5C\u533A\uFF1A{4}\n{5}\n\n\u4EFB\u610F shell \u547D\u4EE4\u53EF\u8BFB\u5199\u672C\u673A\u8BE5\u7528\u6237\u80FD\u8BBF\u95EE\u7684\u8D44\u6E90\u3002\u6279\u51C6\u540E\u300C\u8FDC\u7A0B\u6765\u6E90\u5728\u672C\u673A\u6267\u884C shell\u300D\u8FD9\u4E00\u7C7B\u786E\u8BA4\u4E0D\u518D\u9010\u6761\u8BE2\u95EE\uFF08\u672C\u6B21\u4E0E\u540E\u7EED\u542F\u52A8\u90FD\u751F\u6548\uFF09\u3002\u64A4\u9500\uFF1A/shell-revoke \u6216 /auto remote off\u3002"
380
418
  },
381
- waitingForModel: {
382
- en: "Waiting for the model\u2026",
383
- zh: "\u6B63\u5728\u7B49\u5F85\u6A21\u578B\u54CD\u5E94\u2026"
419
+ "shellGrant.confirmTitle": {
420
+ en: "Allow remote agent {0} to run shell commands on this machine?",
421
+ zh: "\u5141\u8BB8\u8FDC\u7A0B agent {0} \u5728\u672C\u673A\u6267\u884C shell \u547D\u4EE4\u5417\uFF1F"
384
422
  },
385
- // --- Local turn deadline failure (single actionable line) -----------------
386
- // localLoop 主请求 idle deadline(DEFAULT_LLM_REQUEST_TIMEOUT_MS 兜底或调用方
387
- // timeoutMs)到达后抛 code=LLM_REQUEST_TIMEOUT;generic 分支的「修本地
388
- // 凭据」文案在这里是错误指引(请求已发出,问题在上游无响应)。
389
- // 语义是 idle(静默窗):{0} 内没有任何新输出才放弃,不是说模型「完全没
390
- // 响应」——文案必须与这个语义一致,否则会把正在生成的用户推向重复发送
391
- // (2026-10 ctx-overflow-feedback review 修复 1)。
392
- llmRequestTimedOut: {
393
- en: "No new model output for {0}, so this turn was stopped. Your message was kept. Retry in this conversation, switch to another model, or run /compact first.",
394
- zh: "\u6A21\u578B\u5DF2 {0} \u6CA1\u6709\u65B0\u8F93\u51FA\uFF0C\u672C\u8F6E\u5DF2\u505C\u6B62\u7B49\u5F85\uFF08\u53EF\u80FD\u4ECD\u5728\u751F\u6210\uFF09\u3002\u4F60\u7684\u6D88\u606F\u5DF2\u4FDD\u7559\u3002\u53EF\u5728\u672C\u5BF9\u8BDD\u91CD\u8BD5\u3001\u5207\u6362\u5230\u5176\u4ED6\u6A21\u578B\uFF0C\u6216\u5148 /compact \u538B\u7F29\u5BF9\u8BDD\u3002"
423
+ "shellGrant.confirmBody": {
424
+ en: "Remote agent {0} (owner {1}) requested to run a shell command on this machine.\nDevice: {2} ({3})\nWorkspace: {4}\nCommand: {5}\n\nShell commands can read/write anything this user can access. Approving covers this whole class: remote-origin shell confirmations stop asking one by one (this session and future starts). Undo with /shell-revoke (this session) or /auto remote off (also clears the saved grant).",
425
+ zh: "\u8FDC\u7A0B agent {0}\uFF08\u4E3B\u4EBA {1}\uFF09\u8BF7\u6C42\u5728\u672C\u673A\u6267\u884C shell \u547D\u4EE4\u3002\n\u8BBE\u5907\uFF1A{2}\uFF08{3}\uFF09\n\u5DE5\u4F5C\u533A\uFF1A{4}\n\u547D\u4EE4\uFF1A{5}\n\n\u4EFB\u610F shell \u547D\u4EE4\u53EF\u8BFB\u5199\u672C\u673A\u8BE5\u7528\u6237\u80FD\u8BBF\u95EE\u7684\u8D44\u6E90\u3002\u6279\u51C6\u540E\u300C\u8FDC\u7A0B\u6765\u6E90\u5728\u672C\u673A\u6267\u884C shell\u300D\u8FD9\u4E00\u7C7B\u786E\u8BA4\u4E0D\u518D\u9010\u6761\u8BE2\u95EE\uFF08\u672C\u6B21\u4E0E\u540E\u7EED\u542F\u52A8\u90FD\u751F\u6548\uFF09\u3002\u64A4\u9500\uFF1A/shell-revoke\uFF08\u672C\u4F1A\u8BDD\uFF09\u6216 /auto remote off\uFF08\u540C\u65F6\u6E05\u9664\u6301\u4E45\u6388\u6743\uFF09\u3002"
395
426
  },
396
- // --- Local run 429/rate-limit display (compact 3-line block) --------------
397
- // 旧 429 文案是一条巨长英文 + 结尾拼接中文冷却说明(又长又中英混排)。现在按
398
- // locale 渲染 3 行:headline(含上游 tag 与清洗后的详情)+ 冷却/探测 + 出口。
399
- // {0} = 上游标签(antigravity · gemini-3.8-flash-tiered;取不到回退 transport 名)
400
- // {1} = 清洗后的上游原文(去 details= / 传输前缀 / 结尾复位句,折叠空白,≤140 字符)
401
- localRunRateLimitQuota: {
402
- en: "[nolo] Upstream quota exhausted ({0}): {1}",
403
- zh: "[nolo] \u4E0A\u6E38\u989D\u5EA6\u5DF2\u7528\u5C3D\uFF08{0}\uFF09\uFF1A{1}"
427
+ "shellGrant.revoked": {
428
+ en: "[nolo] Shell permission revoked for shared agents in this session.",
429
+ zh: "[nolo] \u5DF2\u64A4\u9500\u672C\u4F1A\u8BDD\u4E2D\u5206\u4EAB agent \u7684 shell \u6267\u884C\u6743\u9650\u3002"
404
430
  },
405
- localRunRateLimitThrottled: {
406
- en: "[nolo] Upstream rate limit ({0}): {1}",
407
- zh: "[nolo] \u4E0A\u6E38\u9650\u6D41\uFF08{0}\uFF09\uFF1A{1}"
431
+ "shellGrant.revokeNone": {
432
+ en: "[nolo] No shell permission is currently granted in this session.",
433
+ zh: "[nolo] \u672C\u4F1A\u8BDD\u5F53\u524D\u6CA1\u6709\u5DF2\u6388\u4E88\u7684 shell \u6743\u9650\u3002"
408
434
  },
409
- // 上游明确表示「服务容量饱和」(如 Codex 的 "is at capacity")。这与账号额度
410
- // 无关,用「额度」措辞会让人误以为是自己配额用完了。单独一档。
411
- localRunRateLimitCapacity: {
412
- en: "[nolo] Upstream service at capacity ({0}): {1}",
413
- zh: "[nolo] \u4E0A\u6E38\u670D\u52A1\u5BB9\u91CF\u9971\u548C\uFF08{0}\uFF09\uFF1A{1}"
435
+ // 运行位置展示(块 D):owner-required 场景告诉用户工具实际在哪台设备
436
+ // 哪个工作区执行。unknown 不猜、不静默标 ready。
437
+ "toolLocation.line": {
438
+ en: "[nolo] Tools execute on {0} ({1}) \xB7 workspace {2} \xB7 status: {3}",
439
+ zh: "[nolo] \u5DE5\u5177\u5728 {0}\uFF08{1}\uFF09\xB7 \u5DE5\u4F5C\u533A {2} \xB7 \u72B6\u6001\uFF1A{3} \u6267\u884C"
414
440
  },
415
- // 第 2 行复位提示:沿用 extractRateLimitResetHint 抓到的上游原文(不换算),
416
- // 只作括号补充;没抓到就没有这段括号。
417
- localRunRateLimitResetNote: {
418
- en: " (upstream reset in {0})",
419
- zh: "\uFF08\u4E0A\u6E38\u7EA6 {0}\u540E\u590D\u4F4D\uFF09"
441
+ "toolLocation.unknown": {
442
+ en: "[nolo] Tool execution location: unknown",
443
+ zh: "[nolo] \u5DE5\u5177\u6267\u884C\u4F4D\u7F6E\uFF1A\u672A\u77E5"
444
+ }
445
+ };
446
+
447
+ // packages/cli/i18n/strings/agent.ts
448
+ var agentStrings = {
449
+ agentSwitchCancelled: {
450
+ en: "Agent switch cancelled.",
451
+ zh: "\u5DF2\u53D6\u6D88\u5207\u6362 agent\u3002"
420
452
  },
421
- // 第 2 行:{0} = 冷却截止(本地时间,当天 HH:MM / 跨天 MM-DD HH:MM),
422
- // {1} = 复位提示或空串,{2} = 自动探测间隔(分钟)。无 cooldownUntil 时整行省略。
423
- localRunRateLimitCooldown: {
424
- en: " Cooldown until {0}{1}; auto-probing every {2} min meanwhile (the upstream may not be restored by then).",
425
- zh: " \u51B7\u5374\u81F3 {0}{1}\uFF1B\u671F\u95F4\u6BCF {2} \u5206\u949F\u81EA\u52A8\u8BD5\u63A2\u4E00\u6B21\uFF08\u4E0A\u6E38\u672A\u5FC5\u5C4A\u65F6\u6062\u590D\uFF09\u3002"
426
- },
427
- // 第 3 行:三个出口(换 agent / 强制走服务器 / 已充值清冷却)。
428
- localRunRateLimitExits: {
429
- en: " Switch agent: nolo agent list; force server: --server; topped up: nolo auth cooldown, then --clear <credential>",
430
- zh: " \u6362 agent\uFF1Anolo agent list\uFF1B\u5F3A\u5236\u8D70\u670D\u52A1\u5668\uFF1A--server\uFF1B\u5DF2\u5145\u503C\uFF1Anolo auth cooldown \u67E5\u51ED\u8BC1\u540D\u540E --clear <\u51ED\u8BC1\u540D>"
431
- },
432
- // --- Local run 402/余额不足 display (compact 3-line block) ----------------
433
- // 与 429 同结构:headline(余额不足 / Coding Plan 额度用尽 + 上游 tag)+ 复位
434
- // 时刻(仅当报文确实给了 reset_at)+ 出口。{0} = 上游标签(provider · model,
435
- // 取不到回退 transport 名),{1} = 清洗后的原因(或定量原因)。
436
- localRunBalanceExhausted: {
437
- en: "[nolo] Insufficient balance, cannot continue ({0}): {1}",
438
- zh: "[nolo] \u4F59\u989D\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u7EE7\u7EED\uFF08{0}\uFF09\uFF1A{1}"
439
- },
440
- // 报文带 coding_plan_exhausted 时的措辞:计划额度与钱包余额是两笔要分别充的账。
441
- localRunBalanceCodingPlan: {
442
- en: "[nolo] Coding Plan quota exhausted and the wallet balance is insufficient ({0}): {1}",
443
- zh: "[nolo] Coding Plan \u989D\u5EA6\u5DF2\u7528\u5C3D\u4E14\u94B1\u5305\u4F59\u989D\u4E0D\u8DB3\uFF08{0}\uFF09\uFF1A{1}"
444
- },
445
- // 第 2 行:{0} = 计划额度复位时刻(本地时间)。报文没给复位时刻时整行省略。
446
- localRunBalanceReset: {
447
- en: " Plan quota resets at {0} \u2014 this restores the plan quota only; it does not top up your wallet.",
448
- zh: " \u8BA1\u5212\u989D\u5EA6 {0} \u590D\u4F4D\u2014\u2014\u53EA\u6062\u590D\u8BA1\u5212\u989D\u5EA6\uFF0C\u4E0D\u4F1A\u7ED9\u94B1\u5305\u5145\u503C\u3002"
449
- },
450
- // 清洗后仍取不到原因(报文只有 `{"error":{}}` 这类空壳)时的兜底:避免悬空冒号。
451
- localRunBalanceUnknownReason: {
452
- en: "the provider returned a payment-required error without a reason line",
453
- zh: "\u4E0A\u6E38\u53EA\u8FD4\u56DE\u4E86\u300C\u9700\u8981\u4ED8\u6B3E\u300D\u9519\u8BEF\uFF0C\u6CA1\u6709\u7ED9\u51FA\u539F\u56E0"
453
+ agentPickerLoading: {
454
+ en: "Loading agents\u2026",
455
+ zh: "\u6B63\u5728\u52A0\u8F7D agent \u5217\u8868\u2026"
454
456
  },
455
- // 第 3 行:出口(充值后重发 / 换 agent / 强制走服务器)。刻意不重复 TUI 那句
456
- //「你刚发的话已保存在当前对话里」。
457
- localRunBalanceExits: {
458
- en: " Top up and send again; or switch agent: nolo agent list; force server: --server",
459
- zh: " \u5145\u503C\u540E\u91CD\u53D1\u5373\u53EF\uFF1B\u6216\u6362 agent\uFF1Anolo agent list\uFF1B\u5F3A\u5236\u8D70\u670D\u52A1\u5668\uFF1A--server"
457
+ /**
458
+ * /switch 目录视图的一行提示:收藏项 hydrate 失败时出现,让「收藏看不到」
459
+ * 有任何线索;失败数为 0 时不渲染这一行。
460
+ */
461
+ agentCatalogUnavailableFavorites: {
462
+ en: "\u26A0 {0} favorite(s) unavailable right now",
463
+ zh: "\u26A0 {0} \u4E2A\u6536\u85CF\u9879\u6682\u65F6\u4E0D\u53EF\u7528"
460
464
  },
461
465
  // 派发前的本地冷却拦截(原两行英文 → 本地化单行压缩)。
462
466
  agentCooldownBlocked: {
463
467
  en: "[nolo] Agent {0} is in 429 cooldown until {1}. This dispatch was not sent \u2014 pick another agent, or retry after the cooldown.",
464
468
  zh: "[nolo] Agent {0} \u51B7\u5374\u4E2D\uFF0C\u81F3 {1}\u3002\u672C\u6B21\u6D3E\u53D1\u672A\u53D1\u51FA\u2014\u2014\u6362\u4E00\u4E2A agent\uFF0C\u6216\u5230\u70B9\u540E\u91CD\u8BD5\u3002"
465
469
  },
466
- thinkingTraceLine: {
467
- en: "\u273B Thought for {0}",
468
- zh: "\u273B \u601D\u8003 {0}"
469
- },
470
- toolNeedsAction: {
471
- en: "needs action",
472
- zh: "\u5F85\u786E\u8BA4"
473
- },
474
- toolTimedOut: {
475
- en: "timed out",
476
- zh: "\u5DF2\u8D85\u65F6"
477
- },
478
- toolExitCode: {
479
- en: "exit",
480
- zh: "\u9000\u51FA\u7801"
481
- },
482
- toolFailed: {
483
- en: "failed",
484
- zh: "\u5931\u8D25"
485
- },
486
- usedSkillLabel: {
487
- en: "Used Skill",
488
- zh: "\u5DF2\u52A0\u8F7D\u6280\u80FD"
489
- },
490
470
  // --- Agent-run orchestration cards (injected into packages/ai helpers) ---
491
471
  runStatusLabel: {
492
472
  en: "Run status",
@@ -573,821 +553,1713 @@ var STRINGS = {
573
553
  en: "+{0} more",
574
554
  zh: "\u8FD8\u6709 {0} \u4E2A"
575
555
  },
576
- // Background-process rows in the same zone (`❯ npm run dev · 已运行 3m · pid 123`).
577
- // The pid is how the user targets /stop, so it is a fact, not decoration.
578
- procZonePid: { en: "pid {0}", zh: "pid {0}" },
579
- // 残留行(进程已退出):running 用 `已运行`,退出的说「用时」,因为它不再走秒。
580
- procZoneTook: { en: "took {0}", zh: "\u7528\u65F6 {0}" },
581
- procZoneExit: { en: "exit {0}", zh: "exit {0}" },
582
- // --- Dialog (picker / confirm) copy --------------------------------------
583
- // Key-hint wording is unified across select / multi-select / confirm so the
584
- // three dialogs read as one family: "<Label> <↑↓ move · Enter choose ·
585
- // Esc cancel> <count>". Connectors are "·" between keys, two spaces between
586
- // the label, hint, and count. zh uses full-width parentheses to match the
587
- // existing historyPickerTitle; en uses ASCII parentheses.
588
- dialogSelectLabel: {
589
- en: "Select",
590
- zh: "\u9009\u62E9"
556
+ agentsTitle: {
557
+ en: "Agents:",
558
+ zh: "\u667A\u80FD\u4F53\uFF1A"
591
559
  },
592
- dialogSelectHint: {
593
- en: "(\u2191\u2193 move \xB7 Enter choose \xB7 Esc cancel)",
594
- zh: "\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
560
+ agentsTip: {
561
+ en: "Tip: run /switch for the full picker, or /switch list for your private agents too.",
562
+ zh: "\u63D0\u793A\uFF1A\u7528 /switch \u6253\u5F00\u5B8C\u6574\u9009\u62E9\u5668\uFF0C\u6216 /switch list \u8FDE\u4F60\u7684\u79C1\u6709\u667A\u80FD\u4F53\u4E00\u8D77\u5217\u51FA\u3002"
595
563
  },
596
- dialogMultiSelectLabel: {
597
- en: "Select",
598
- zh: "\u9009\u62E9"
564
+ agentCurrent: { en: "Current agent: {0} ({1})", zh: "\u5F53\u524D agent\uFF1A{0}\uFF08{1}\uFF09" },
565
+ agentPinnedUnaudited: {
566
+ en: "No audit record for it \u2014 an older build wrote it; see agent-selection.log.",
567
+ zh: "\u8FD9\u6761\u8BB0\u5F55\u6CA1\u6709\u5BA1\u8BA1\u8BB0\u5F55\uFF0C\u662F\u65E7\u7248\u672C\u5199\u7684\uFF1B\u8BE6\u89C1 agent-selection.log\u3002"
599
568
  },
600
- dialogMultiSelectHint: {
601
- en: "(\u2191\u2193 move \xB7 Space toggle \xB7 Enter submit \xB7 Esc cancel)",
602
- zh: "\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Space \u5207\u6362 \xB7 Enter \u63D0\u4EA4 \xB7 Esc \u53D6\u6D88\uFF09"
569
+ agentPinnedAuditRotated: {
570
+ en: "The audit log has no entry for it \u2014 it aged out, or another session wrote it.",
571
+ zh: "\u5BA1\u8BA1\u65E5\u5FD7\u91CC\u6CA1\u6709\u5B83\u7684\u8BB0\u5F55\u2014\u2014\u53EF\u80FD\u5DF2\u88AB\u8F6E\u8F6C\uFF0C\u6216\u662F\u522B\u7684\u4F1A\u8BDD\u5199\u7684\u3002"
603
572
  },
604
- dialogMultiSelectSelected: {
605
- en: "selected",
606
- zh: "\u5DF2\u9009"
573
+ agentPinnedFromProfile: {
574
+ en: 'Agent "{0}" restored from {1} (saved selection). /switch nolo to go back to the default.',
575
+ zh: "agent\u201C{0}\u201D\u6765\u81EA {1} \u91CC\u4FDD\u5B58\u7684\u9009\u62E9\u3002/switch nolo \u53EF\u5207\u56DE\u9ED8\u8BA4\u6863\u3002"
607
576
  },
608
- dialogMultiSelectRequired: {
609
- en: "Pick at least one option to submit",
610
- zh: "\u81F3\u5C11\u9009\u62E9\u4E00\u9879\u624D\u80FD\u63D0\u4EA4"
577
+ agentUnknown: {
578
+ en: `I don't know agent "{0}" yet.
579
+ Use /switch, /switch list, /switch minimax-m3, or a full agent key.`,
580
+ zh: "\u8FD8\u4E0D\u8BA4\u8BC6 agent\u201C{0}\u201D\u3002\n\u53EF\u4EE5\u7528 /switch\u3001/switch list\u3001/switch minimax-m3 \u6216\u5B8C\u6574\u7684 agent key \u6765\u5207\u6362\u3002"
611
581
  },
612
- dialogConfirmHint: {
613
- en: "(\u2191\u2193 move \xB7 Enter choose \xB7 Esc cancel)",
614
- zh: "\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
582
+ // Agent catalog sources
583
+ agentSourcePlatform: {
584
+ en: "Platform",
585
+ zh: "\u5E73\u53F0"
615
586
  },
616
- dialogConfirmTitle: {
617
- en: "Allow destructive shell commands from local runs?",
618
- zh: "\u5141\u8BB8\u672C\u673A run \u6267\u884C\u7834\u574F\u6027 shell \u547D\u4EE4\u5417\uFF1F"
587
+ agentSourceSubscription: {
588
+ en: "Subscription",
589
+ zh: "\u8BA2\u9605"
619
590
  },
620
- dialogConfirmBody: {
621
- en: "This command may delete or reset user content \u2014 a local-run destructive shell command.",
622
- zh: "\u8BE5\u547D\u4EE4\u53EF\u80FD\u5220\u9664\u6216\u91CD\u7F6E\u7528\u6237\u5185\u5BB9\uFF0C\u5C5E\u4E8E\u672C\u673A run \u7684\u7834\u574F\u6027 shell \u547D\u4EE4\u3002"
591
+ agentSourceApi: {
592
+ en: "API",
593
+ zh: "API"
623
594
  },
624
- dialogConfirmExternalFileTitle: {
625
- en: "Allow reading files outside the workspace?",
626
- zh: "\u5141\u8BB8\u8BFB\u53D6\u5DE5\u4F5C\u533A\u5916\u90E8\u6587\u4EF6\u5417\uFF1F"
595
+ // ── Non-TUI CLI output: nolo agent / nolo run ─────────────────────────────
596
+ "agent.unavailableHidden": {
597
+ en: "\u26D4 {0} agent(s) temporarily unavailable (429) hidden. Use --show-unavailable to list them.\n",
598
+ zh: "\u26D4 \u5DF2\u9690\u85CF {0} \u4E2A\u6682\u65F6\u4E0D\u53EF\u7528\u7684 agent\uFF08429\uFF09\u3002\u7528 --show-unavailable \u5217\u51FA\u5B83\u4EEC\u3002\n"
627
599
  },
628
- dialogConfirmExternalFileBody: {
629
- en: "This path is outside the current workspace \u2014 a local-run outside-workspace file access.",
630
- zh: "\u8BE5\u8DEF\u5F84\u4F4D\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u4E4B\u5916\uFF0C\u5C5E\u4E8E\u672C\u673A run \u7684\u5DE5\u4F5C\u533A\u5916\u6587\u4EF6\u8BBF\u95EE\u3002"
600
+ "agent.rateLimitedRecovery": {
601
+ en: " - [429 rate-limited] {0} (id: {1}) recovers in {2}s{3}\n",
602
+ zh: " - [429 \u9650\u6D41] {0} (id: {1}) \u9884\u8BA1 {2} \u79D2\u540E\u6062\u590D{3}\n"
631
603
  },
632
- dialogConfirmFileWriteTitle: {
633
- en: "Allow writing files from local runs?",
634
- zh: "\u5141\u8BB8\u672C\u673A run \u5199\u5165\u6587\u4EF6\u5417\uFF1F"
604
+ "agentRun.autoRouteOverrideFailed": {
605
+ en: "[nolo] auto-route: could not read the source agent, running the selected agent as-is.\n",
606
+ zh: "[nolo] auto-route: \u8986\u76D6\u6E90 agent \u8BFB\u53D6\u5931\u8D25\uFF0C\u6309\u539F\u6837\u76F4\u8DD1\u6240\u9009 agent\u3002\n"
635
607
  },
636
- dialogConfirmFileWriteBody: {
637
- en: "This action writes into the workspace \u2014 a local-run file-write confirmation.",
638
- zh: "\u8BE5\u64CD\u4F5C\u4F1A\u5199\u5165\u5DE5\u4F5C\u533A\u6587\u4EF6\uFF0C\u5C5E\u4E8E\u672C\u673A run \u7684\u5199\u6587\u4EF6\u786E\u8BA4\u3002"
608
+ "agentRun.autoRouteModelOverride": {
609
+ en: "[nolo] auto-route: model override is now {0}\n",
610
+ zh: "[nolo] auto-route: model \u5C42\u8986\u76D6\u4E3A {0}\n"
639
611
  },
640
- dialogConfirmRememberLocal: {
641
- en: "Approving covers all three local-run classes (destructive shell / outside-workspace files / file writes) and is saved, so they stop asking \u2014 this session and future starts. Undo with /auto local off or /auto reset.",
642
- zh: "\u6279\u51C6\u540E\u672C\u673A run \u7684\u4E09\u7C7B\u786E\u8BA4\uFF08\u7834\u574F\u6027\u547D\u4EE4 / \u5DE5\u4F5C\u533A\u5916\u6587\u4EF6 / \u5199\u6587\u4EF6\uFF09\u90FD\u4E0D\u518D\u8BE2\u95EE\uFF0C\u5E76\u4FDD\u5B58\u5230\u914D\u7F6E\uFF08\u672C\u6B21\u4E0E\u540E\u7EED\u542F\u52A8\u90FD\u751F\u6548\uFF09\u3002\u64A4\u9500\u7528 /auto local off \u6216 /auto reset\u3002"
612
+ // ── Non-TUI CLI output: nolo agent delete ─────────────────────────────────
613
+ // Flag descriptions for `nolo agent delete --help`; the Chinese copy is the
614
+ // original wording, kept verbatim so existing users lose no information.
615
+ "agentDelete.description": {
616
+ en: "Deletes an agent's private record (agent-{userId}-{id}) and public record (agent-pub-{id}).\n",
617
+ zh: "\u5220\u9664\u4E00\u4E2A agent \u7684\u79C1\u6709\u8BB0\u5F55 (agent-{userId}-{id}) \u4E0E\u516C\u5F00\u8BB0\u5F55 (agent-pub-{id})\u3002\n"
643
618
  },
644
- dialogConfirmCommandTruncated: {
645
- en: "(truncated)",
646
- zh: "\uFF08\u5DF2\u622A\u65AD\uFF09"
619
+ "agentDelete.tombstoneNote": {
620
+ en: "The server side is a tombstone soft delete: read after DELETE returns 404.\n",
621
+ zh: "\u670D\u52A1\u5668\u7AEF\u4E3A tombstone \u8F6F\u5220\u9664\uFF0CDELETE \u540E\u518D\u6B21 read \u4F1A\u8FD4\u56DE 404\u3002\n"
647
622
  },
648
- dialogConfirmAllowLabel: {
649
- en: "Approve & remember",
650
- zh: "\u6279\u51C6\u5E76\u8BB0\u4F4F"
623
+ "agentDelete.flagYes": {
624
+ en: " --yes Actually delete; without it only the dry-run target summary is printed.\n",
625
+ zh: " --yes \u771F\u6B63\u6267\u884C\u5220\u9664\uFF1B\u7F3A\u7701\u65F6\u4EC5 dry-run \u8F93\u51FA\u76EE\u6807\u6458\u8981\u3002\n"
651
626
  },
652
- dialogConfirmAllowDetail: {
653
- en: "stop asking for this class (saved)",
654
- zh: "\u540C\u7C7B\u786E\u8BA4\u4E0D\u518D\u8BE2\u95EE\uFF08\u5DF2\u4FDD\u5B58\uFF09"
627
+ "agentDelete.flagJson": {
628
+ en: " --json Print the JSON result.\n",
629
+ zh: " --json \u8F93\u51FA JSON \u7ED3\u679C\u3002\n"
655
630
  },
656
- dialogConfirmCancelLabel: {
657
- en: "Reject",
658
- zh: "\u62D2\u7EDD"
631
+ "agentDelete.flagId": {
632
+ en: " --id <agent> Same as the positional argument: alias / dbKey / URL / 26-char id.\n",
633
+ zh: " --id <agent> \u4E0E\u4F4D\u7F6E\u53C2\u6570\u7B49\u4EF7\uFF0C\u4F20\u5165 alias / dbKey / URL / 26-char id\u3002\n"
659
634
  },
660
- dialogConfirmCancelDetail: {
661
- en: "do not run it; ask again next time",
662
- zh: "\u4E0D\u6267\u884C\uFF0C\u4E0B\u6B21\u4ECD\u4F1A\u8BE2\u95EE"
635
+ "agentDelete.flagServer": {
636
+ en: " --server / --server-url Delete only on the given server (replicas outside the fan-out are kept).\n",
637
+ zh: " --server / --server-url \u4EC5\u5220\u9664\u6307\u5B9A\u670D\u52A1\u5668\uFF08\u4ECD\u4FDD\u7559\u96C6\u7FA4 fan-out \u4E4B\u5916\u7684\u526F\u672C\uFF09\u3002\n"
663
638
  },
664
- // --- Ask choice (ask_user) ------------------------------------------
665
- askChoiceTitle: {
666
- en: "question",
667
- zh: "\u95EE\u9898"
639
+ "agentDelete.flagUser": {
640
+ en: " --user <userId> Explicitly override userId (errors when it differs from AUTH_TOKEN).\n",
641
+ zh: " --user <userId> \u663E\u5F0F\u8986\u76D6 userId\uFF08\u4E0E AUTH_TOKEN \u4E0D\u4E00\u81F4\u5219\u62A5\u9519\uFF09\u3002\n"
668
642
  },
669
- askChoiceScrollHint: {
670
- en: "\u2191 Shift+wheel scrolls back terminal history",
671
- zh: "\u2191 Shift+\u6EDA\u8F6E\u53EF\u56DE\u770B\u4E0A\u65B9\u6D88\u606F"
643
+ "agentDelete.flagToken": {
644
+ en: " --token / --machine-key Temporarily override AUTH_TOKEN.\n",
645
+ zh: " --token / --machine-key \u4E34\u65F6\u8986\u76D6 AUTH_TOKEN\u3002\n"
672
646
  },
673
- askChoiceSubmit: {
674
- en: "submit \u2193",
675
- zh: "\u63D0\u4EA4 \u2193"
647
+ // ── Non-TUI CLI output: agent-run orchestration tool errors ───────────────
648
+ "agentRunTool.missingAgentKey": {
649
+ en: "startAgentRun: missing agentKey, and the current agent cannot be identified.",
650
+ zh: "startAgentRun: \u7F3A\u5C11 agentKey \u53C2\u6570\uFF0C\u4E14\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D Agent\u3002"
676
651
  },
677
- askChoiceSubmitRow: {
678
- en: "Done",
679
- zh: "\u5B8C\u6210"
652
+ "agentRunTool.missingTask": {
653
+ en: "startAgentRun: missing a valid task description.",
654
+ zh: "startAgentRun: \u7F3A\u5C11\u6709\u6548\u7684 task \u6587\u672C\u63CF\u8FF0\u3002"
680
655
  },
681
- askChoiceSkipRow: {
682
- en: "Skip",
683
- zh: "\u8DF3\u8FC7"
656
+ "agentRunTool.noDialogToContinue": {
657
+ en: "This run has no linked dialog and cannot be continued.",
658
+ zh: "\u8BE5 run \u65E0\u5173\u8054 dialog\uFF0C\u65E0\u6CD5\u7EED\u8DD1\u3002"
684
659
  },
685
- askChoiceOtherLabel: {
686
- en: "Other",
687
- zh: "\u5176\u4ED6"
660
+ "agentRunTool.appendMissingRunId": {
661
+ en: 'controlAgentRun(action:"append"): missing runId.',
662
+ zh: 'controlAgentRun(action:"append"): \u7F3A\u5C11 runId\u3002'
688
663
  },
689
- askChoiceHintSingle: {
690
- en: "Enter/Space picks \xB7 single question sends \xB7 multi-question jumps to the next unanswered \xB7 Enter in Other confirms and continues",
691
- zh: "Enter/\u7A7A\u683C \u9009\u62E9\uFF1A\u5355\u9898\u76F4\u63A5\u53D1\u9001\u3001\u591A\u9898\u8DF3\u5230\u4E0B\u4E00\u672A\u7B54\u9898 \xB7 \u5176\u4ED6\u8F93\u5165\u540E Enter \u786E\u8BA4\u5E76\u7EE7\u7EED"
664
+ "agentRunTool.appendMissingUserInput": {
665
+ en: 'controlAgentRun(action:"append"): missing a valid userInput text.',
666
+ zh: 'controlAgentRun(action:"append"): \u7F3A\u5C11\u6709\u6548\u7684 userInput \u6587\u672C\u3002'
692
667
  },
693
- askChoiceHintOptional: {
694
- en: "Optional question \u2014 Enter/Space picks (one step) \xB7 skip if you don't want to answer",
695
- zh: "\u53EF\u9009\u9898 \u2014 Enter/\u7A7A\u683C \u9009\u62E9\u5373\u5B8C\u6210 \xB7 \u4E0D\u60F3\u56DE\u7B54\u53EF\u8DF3\u8FC7"
668
+ "agentRunTool.appendQueueUnsupported": {
669
+ en: "This run did not start with a queue channel; append while running is not supported. Wait for a terminal state first.",
670
+ zh: "\u8BE5 run \u542F\u52A8\u65F6\u4E0D\u652F\u6301\u8FD0\u884C\u4E2D\u5165\u961F\uFF08\u65E0\u961F\u5217\u901A\u9053\uFF09\uFF0C\u8BF7\u7B49\u7EC8\u6001\u540E\u518D append"
696
671
  },
697
- askChoiceHintMulti: {
698
- en: "Enter/Space toggles \xB7 \u2193 to Done row, Enter sends",
699
- zh: "Enter/\u7A7A\u683C \u5207\u6362\u9009\u4E2D \xB7 \u2193 \u5230\u5B8C\u6210\u884C Enter \u53D1\u9001"
700
- },
701
- askChoiceFooterSingle: {
702
- en: "\u21B5 pick/send \xB7 tab switch \xB7 esc cancel",
703
- zh: "\u21B5 \u9009\u62E9/\u53D1\u9001 \xB7 tab \u5207\u6362 \xB7 esc \u53D6\u6D88"
672
+ "agentRunTool.unknownAction": {
673
+ en: 'controlAgentRun: unknown action "{0}".',
674
+ zh: 'controlAgentRun: \u672A\u77E5 action "{0}"\u3002'
704
675
  },
705
- askChoiceFooterSkip: {
706
- en: "\u21B5 pick/send \xB7 \u2193 skip row \u21B5 skip \xB7 tab switch \xB7 esc cancel",
707
- zh: "\u21B5 \u9009\u62E9/\u53D1\u9001 \xB7 \u2193 \u8DF3\u8FC7\u884C \u21B5 \u8DF3\u8FC7 \xB7 tab \u5207\u6362 \xB7 esc \u53D6\u6D88"
676
+ "agentRunTool.missingRunId": {
677
+ en: 'controlAgentRun(action:"{0}"): missing runId.',
678
+ zh: 'controlAgentRun(action:"{0}"): \u7F3A\u5C11 runId\u3002'
708
679
  },
709
- askChoiceFooterMulti: {
710
- en: "\u21B5 toggle \xB7 \u2193 done row \u21B5 send \xB7 ctrl+s send \xB7 tab switch \xB7 esc cancel",
711
- zh: "\u21B5 \u5207\u6362 \xB7 \u2193 \u5B8C\u6210\u884C \u21B5 \u53D1\u9001 \xB7 ctrl+s \u53D1\u9001 \xB7 tab \u5207\u6362 \xB7 esc \u53D6\u6D88"
680
+ "agentRunTool.waitAborted": {
681
+ en: "controlAgentRun(wait) was aborted.",
682
+ zh: "controlAgentRun(wait) \u5DF2\u88AB\u4E2D\u6B62\u3002"
712
683
  },
713
- askChoiceValidationRequired: {
714
- en: "Required questions are unanswered \u2014 jumped to the first one.",
715
- zh: "\u5FC5\u586B\u95EE\u9898\u5C1A\u672A\u56DE\u7B54 \u2014 \u5DF2\u8DF3\u8F6C\u5230\u7B2C\u4E00\u4E2A\u672A\u7B54\u9898\u3002"
684
+ // ── Non-TUI CLI output: agent-run OAuth channel ownership + stream failures ──
685
+ // 用户在 TUI 选了别人的 sshare agent(跑在 agent owner 的 OAuth 订阅上):
686
+ // auto 模式下模型请求经服务端 owner-required 代理走分享者订阅、文件/shell
687
+ // 工具留在本机执行(不是转服务端跑整轮)。文案说明模型使用分享者订阅、
688
+ // 工具在本机;不展示内部 ID,也不提供未经保证的订阅切换建议。
689
+ "agentRun.oauthChannelOwnerSkip": {
690
+ en: '[nolo] Using "{0}", shared by someone else: the model uses their subscription; file operations and commands still run on your computer.',
691
+ zh: "[nolo] \u6B63\u5728\u4F7F\u7528\u5BF9\u65B9\u5206\u4EAB\u7684\u300C{0}\u300D\uFF1A\u6A21\u578B\u4F7F\u7528\u5BF9\u65B9\u7684\u8BA2\u9605\uFF0C\u6587\u4EF6\u64CD\u4F5C\u548C\u547D\u4EE4\u6267\u884C\u4ECD\u5728\u4F60\u7684\u7535\u8111\u4E0A\u8FDB\u884C\u3002"
716
692
  },
717
- askChoiceHistoryHint: {
718
- en: "Type a number to choose, or reply directly:",
719
- zh: "\u8BF7\u8F93\u5165\u5E8F\u53F7\u9009\u62E9\uFF0C\u6216\u76F4\u63A5\u56DE\u590D\uFF1A"
693
+ "agentRun.sharedAgentFallbackName": {
694
+ en: "Shared agent",
695
+ zh: "\u5171\u4EAB Agent"
720
696
  },
721
- askChoiceHistorySelected: {
722
- en: "selected",
723
- zh: "\u5DF2\u9009"
697
+ // antigravity 502 MALFORMED_FUNCTION_CALL:裸 message 是整段 provider JSON
698
+ // dump,对用户零信息量。映射成单行可操作文案;原始 JSON 只在既有
699
+ // NOLO_DEBUG / NOLO_CLI_DEBUG_DETAIL 开关下附加。
700
+ "agentRunStream.malformedToolCallRejected": {
701
+ en: "[nolo] The provider rejected the model's generated tool call, so this attempt will not retry automatically. It is usually intermittent: read dialog {0} to check progress, then resend.",
702
+ zh: "[nolo] \u6A21\u578B\u751F\u6210\u7684\u5DE5\u5177\u8C03\u7528\u88AB\u4E0A\u6E38\u62D2\u7EDD\uFF0C\u672C\u6B21\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002\u8FD9\u79CD\u60C5\u51B5\u901A\u5E38\u662F\u5076\u53D1\u7684\uFF1A\u53EF\u5148\u8BFB\u5BF9\u8BDD {0} \u770B\u8FDB\u5EA6\uFF0C\u7136\u540E\u76F4\u63A5\u91CD\u53D1\u3002"
724
703
  },
725
- askChoiceHistoryCancelled: {
726
- en: "cancelled",
727
- zh: "\u5DF2\u53D6\u6D88"
704
+ "agentRunStream.malformedToolCallRejectedNoDialog": {
705
+ en: "[nolo] The provider rejected the model's generated tool call, so this attempt will not retry automatically. It is usually intermittent: just resend your message.",
706
+ zh: "[nolo] \u6A21\u578B\u751F\u6210\u7684\u5DE5\u5177\u8C03\u7528\u88AB\u4E0A\u6E38\u62D2\u7EDD\uFF0C\u672C\u6B21\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002\u8FD9\u79CD\u60C5\u51B5\u901A\u5E38\u662F\u5076\u53D1\u7684\uFF1A\u76F4\u63A5\u91CD\u53D1\u5373\u53EF\u3002"
728
707
  },
729
- contextTitle: {
730
- en: "Workspace context",
731
- zh: "\u5DE5\u4F5C\u533A\u4E0A\u4E0B\u6587"
708
+ "agentRunStream.interruptedAfterDialog": {
709
+ en: "\n[nolo] Agent stream transport interrupted after dialog {0} was created: {1}\n",
710
+ zh: "\n[nolo] \u5BF9\u8BDD {0} \u521B\u5EFA\u540E\uFF0Cagent \u6D41\u5F0F\u8F93\u51FA\u4E2D\u65AD\uFF1A{1}\n"
732
711
  },
733
- contextNext: {
734
- en: "Next:",
735
- zh: "\u4E0B\u4E00\u6B65\uFF1A"
712
+ "agentRunStream.mayStillFinishOnServer": {
713
+ en: "[nolo] The agent run may still finish on the server; read the dialog before retrying.\n",
714
+ zh: "[nolo] \u8FD9\u6B21 agent \u8FD0\u884C\u53EF\u80FD\u4ECD\u5728\u670D\u52A1\u7AEF\u7EE7\u7EED\uFF0C\u91CD\u8BD5\u524D\u8BF7\u5148\u8BFB\u4E00\u4E0B\u8BE5\u5BF9\u8BDD\u3002\n"
736
715
  },
737
- contextFieldAgent: {
738
- en: "agent",
739
- zh: "\u667A\u80FD\u4F53"
716
+ "agentRunStream.failed": {
717
+ en: "\n[nolo] Agent stream failed: {0}\n",
718
+ zh: "\n[nolo] Agent \u6D41\u5F0F\u8FD0\u884C\u5931\u8D25\uFF1A{0}\n"
740
719
  },
741
- contextFieldTokens: {
742
- en: "tokens",
743
- zh: "\u4EE4\u724C"
720
+ "agentRunStream.rawErrorDetail": {
721
+ en: "[nolo] Raw error detail (NOLO_DEBUG=1): {0}\n",
722
+ zh: "[nolo] \u539F\u59CB\u9519\u8BEF\u8BE6\u60C5\uFF08NOLO_DEBUG=1\uFF09\uFF1A{0}\n"
723
+ }
724
+ };
725
+
726
+ // packages/cli/i18n/strings/auth.ts
727
+ var authStrings = {
728
+ /** @deprecated No longer used by `/login` (now runs the in-TUI login flow). Kept to avoid structural churn. */
729
+ loginHint: {
730
+ en: "MVP login uses profile/env auth. Set AUTH_TOKEN, NOLO_SERVER, or NOLO_PROFILE before starting nolo.",
731
+ zh: "MVP \u767B\u5F55\u8D70 profile/\u73AF\u5883\u53D8\u91CF\u8BA4\u8BC1\u3002\u542F\u52A8 nolo \u524D\u8BF7\u8BBE\u7F6E AUTH_TOKEN\u3001NOLO_SERVER \u6216 NOLO_PROFILE\u3002"
744
732
  },
745
- contextFieldDialog: {
746
- en: "dialog",
747
- zh: "\u5BF9\u8BDD"
733
+ /** @deprecated No longer used by `/login` (now runs the in-TUI login flow). Kept to avoid structural churn. */
734
+ loginTuiStart: {
735
+ en: "Or run `/login --server <url>` to log in right here (opens a browser authorization URL), or exit and run `nolo login`.",
736
+ zh: "\u4E5F\u53EF\u4EE5\u6267\u884C /login --server <url> \u76F4\u63A5\u5728\u8FD9\u91CC\u767B\u5F55\uFF08\u4F1A\u7ED9\u51FA\u6D4F\u89C8\u5668\u6388\u6743\u94FE\u63A5\uFF09\uFF0C\u6216\u9000\u51FA\u540E\u8FD0\u884C `nolo login`\u3002"
748
737
  },
749
- contextFieldDocs: {
750
- en: "docs",
751
- zh: "\u6587\u6863"
738
+ loginUsage: {
739
+ en: "Usage: /login [--server <url>]. Unsupported flags: {0}",
740
+ zh: "\u7528\u6CD5\uFF1A/login [--server <url>]\u3002\u4E0D\u652F\u6301\u7684\u53C2\u6570\uFF1A{0}"
752
741
  },
753
- contextFieldSkills: {
754
- en: "skills",
755
- zh: "\u6280\u80FD"
742
+ loginStarted: {
743
+ en: "Open this URL to authorize nolo-cli:\n{0}\nCode: {1}",
744
+ zh: "\u6253\u5F00\u8FD9\u4E2A\u94FE\u63A5\u6388\u6743 nolo-cli\uFF1A\n{0}\n\u6388\u6743\u7801\uFF1A{1}"
756
745
  },
757
- contextFieldProfile: {
758
- en: "profile",
759
- zh: "\u914D\u7F6E"
746
+ loginBrowserFailed: {
747
+ en: "Could not open a browser automatically. Paste the URL above into a browser.",
748
+ zh: "\u65E0\u6CD5\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u628A\u4E0A\u9762\u7684\u94FE\u63A5\u7C98\u8D34\u5230\u6D4F\u89C8\u5668\u91CC\u3002"
760
749
  },
761
- contextFieldRuntime: {
762
- en: "runtime",
763
- zh: "\u8FD0\u884C\u65F6"
750
+ loginWaiting: {
751
+ en: "Waiting for browser authorization ({0} remaining)... (Ctrl+C to cancel)",
752
+ zh: "\u7B49\u5F85\u6D4F\u89C8\u5668\u6388\u6743\uFF08\u5269\u4F59 {0}\uFF09\u2026\u2026\u6309 Ctrl+C \u53D6\u6D88"
764
753
  },
765
- contextFieldServer: {
766
- en: "server",
767
- zh: "\u670D\u52A1\u7AEF"
754
+ loginStillWaiting: {
755
+ en: "Still waiting... ({0} remaining)",
756
+ zh: "\u4ECD\u5728\u7B49\u5F85\u2026\u2026\uFF08\u5269\u4F59 {0}\uFF09"
768
757
  },
769
- contextNextAgents: {
770
- en: "see specialist shortcuts",
771
- zh: "\u67E5\u770B\u4E13\u7528\u667A\u80FD\u4F53\u5FEB\u6377\u65B9\u5F0F"
758
+ loginSuccess: {
759
+ en: "Logged in. Token saved to profile; this session now uses it immediately.",
760
+ zh: "\u767B\u5F55\u6210\u529F\u3002Token \u5DF2\u5199\u5165 profile\uFF0C\u5F53\u524D\u4F1A\u8BDD\u7ACB\u5373\u751F\u6548\u3002"
772
761
  },
773
- contextNextDoc: {
774
- en: "add working context",
775
- zh: "\u6DFB\u52A0\u5DE5\u4F5C\u4E0A\u4E0B\u6587"
762
+ loginFailed: {
763
+ en: "Login failed: {0}",
764
+ zh: "\u767B\u5F55\u5931\u8D25\uFF1A{0}"
776
765
  },
777
- contextNextSkill: {
778
- en: "attach a skill to this workspace",
779
- zh: "\u4E3A\u8BE5\u5DE5\u4F5C\u533A\u6302\u8F7D\u6280\u80FD"
766
+ loginTimeout: {
767
+ en: "Login timed out. Run /login again, or use `nolo login --token <jwt>` in a shell.",
768
+ zh: "\u767B\u5F55\u8D85\u65F6\u3002\u8BF7\u91CD\u65B0\u6267\u884C /login\uFF0C\u6216\u5728 shell \u91CC\u7528 nolo login --token <jwt>\u3002"
780
769
  },
781
- contextNextNew: {
782
- en: "start a clean dialog",
783
- zh: "\u5F00\u59CB\u4E00\u4E2A\u5E72\u51C0\u7684\u5BF9\u8BDD"
770
+ loginCancelled: {
771
+ en: "Login cancelled.",
772
+ zh: "\u5DF2\u53D6\u6D88\u767B\u5F55\u3002"
784
773
  },
785
- agentsTitle: {
786
- en: "Agents:",
787
- zh: "\u667A\u80FD\u4F53\uFF1A"
774
+ // ── Non-TUI CLI output: nolo auth ─────────────────────────────────────────
775
+ // User-visible copy of `nolo auth <provider>`. Params follow each en string:
776
+ // {0}=provider, {1}=server origin / saved account / raw detail,
777
+ // {2}=zone or HTTP status, {3}=optional trailing fragment.
778
+ "auth.authorizationSaved": {
779
+ en: "[nolo] {0} authorization saved{1}.",
780
+ zh: "[nolo] \u5DF2\u4FDD\u5B58 {0} \u6388\u6743{1}\u3002"
788
781
  },
789
- // --- Paste / clipboard ------------------------------------------------
790
- pasteUsage: {
791
- en: "Usage: /paste (no arguments). Reads your clipboard now: an image becomes an attachment, text lands in the draft. Tip: dragging an image file onto the terminal is the most reliable way to attach a picture.",
792
- zh: "\u7528\u6CD5\uFF1A/paste\uFF08\u65E0\u53C2\u6570\uFF09\u3002\u7ACB\u5373\u8BFB\u53D6\u526A\u8D34\u677F\uFF1A\u56FE\u7247\u53D8\u9644\u4EF6\uFF0C\u6587\u672C\u8FDB\u8349\u7A3F\u3002\u63D0\u793A\uFF1A\u628A\u56FE\u7247\u6587\u4EF6\u62D6\u8FDB\u7EC8\u7AEF\u662F\u9644\u4E0A\u56FE\u7247\u6700\u53EF\u9760\u7684\u65B9\u5F0F\u3002"
782
+ // Optional account suffix for authorizationSaved (empty when the provider
783
+ // reports no account label).
784
+ "auth.authorizationSavedForAccount": {
785
+ en: " for {0}",
786
+ zh: "\uFF08\u8D26\u53F7 {0}\uFF09"
793
787
  },
794
- pasteTextInserted: {
795
- en: "Pasted {0} characters from the clipboard into the draft.",
796
- zh: "\u5DF2\u4ECE\u526A\u8D34\u677F\u7C98\u8D34 {0} \u4E2A\u5B57\u7B26\u5230\u8349\u7A3F\u3002"
788
+ "auth.noLocalCredential": {
789
+ en: "[nolo] No local {0} credential. Run: nolo auth {0}",
790
+ zh: "[nolo] \u672C\u5730\u6CA1\u6709 {0} \u51ED\u636E\u3002\u8BF7\u8FD0\u884C\uFF1Anolo auth {0}"
797
791
  },
798
- pasteStaleDropped: {
799
- en: "Discarded a clipboard read that finished after the draft changed.",
800
- zh: "\u526A\u8D34\u677F\u8BFB\u53D6\u5B8C\u6210\u65F6\u8349\u7A3F\u5DF2\u53D8\u5316\uFF0C\u7ED3\u679C\u5DF2\u4E22\u5F03\u3002"
792
+ "auth.credentialServerManaged": {
793
+ en: "[nolo] The {0} credential is already server-managed by {1} (no local refresh token).\nTo sync it again, run: nolo auth {0} --sync-to-server",
794
+ zh: "[nolo] {0} \u51ED\u636E\u5DF2\u7531 {1} \u670D\u52A1\u7AEF\u6258\u7BA1\uFF08\u672C\u5730\u65E0 refreshToken\uFF09\u3002\n\u5982\u9700\u91CD\u65B0\u540C\u6B65\uFF0C\u8BF7\u8FD0\u884C: nolo auth {0} --sync-to-server"
801
795
  },
802
- pasteFilePathHint: {
803
- en: "file reference (path only, content not read): {0}",
804
- zh: "\u6587\u4EF6\u5F15\u7528\uFF08\u4EC5\u8DEF\u5F84\uFF0C\u672A\u8BFB\u53D6\u5185\u5BB9\uFF09\uFF1A{0}"
796
+ "auth.verifyUnsupported": {
797
+ en: '[nolo] --verify is only supported for "nolo auth antigravity".',
798
+ zh: '[nolo] --verify \u4EC5\u652F\u6301 "nolo auth antigravity"\u3002'
805
799
  },
806
- mediaFoundHint: {
807
- en: "\u{1F3A7} found media (will transcribe): {0}",
808
- zh: "\u{1F3A7} \u8BC6\u522B\u5230\u97F3\u89C6\u9891\uFF08\u5C06\u8F6C\u5199\uFF09\uFF1A{0}"
800
+ "auth.checkingVerificationChallenge": {
801
+ en: "[nolo] Checking the current verification challenge (one lightweight request)...",
802
+ zh: "[nolo] \u6B63\u5728\u68C0\u67E5\u5F53\u524D\u9A8C\u8BC1\u6311\u6218\uFF08\u4E00\u6B21\u8F7B\u91CF\u8BF7\u6C42\uFF09\u2026"
809
803
  },
810
- mediaPreprocessStart: {
811
- en: "\u{1F3A7} {0} preprocessing\u2026",
812
- zh: "\u{1F3A7} {0} \u9884\u5904\u7406\u4E2D\u2026"
804
+ "auth.refreshTokenInvalid": {
805
+ en: "[nolo] The antigravity refresh token is no longer valid ({0}). Re-run `nolo auth antigravity` to re-authorize this account.",
806
+ zh: "[nolo] antigravity \u7684 refresh token \u5DF2\u5931\u6548\uFF08{0}\uFF09\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C `nolo auth antigravity` \u91CD\u65B0\u6388\u6743\u8BE5\u8D26\u53F7\u3002"
813
807
  },
814
- mediaTranscribeProgress: {
815
- en: "\u{1F3A7} {0} transcribing\u2026 {1}",
816
- zh: "\u{1F3A7} {0} \u8F6C\u5199\u4E2D\u2026 {1}"
808
+ "auth.credentialIncomplete": {
809
+ en: "[nolo] The stored antigravity credential is incomplete ({0}). Re-run `nolo auth antigravity` to re-authorize.",
810
+ zh: "[nolo] \u672C\u5730\u4FDD\u5B58\u7684 antigravity \u51ED\u636E\u4E0D\u5B8C\u6574\uFF08{0}\uFF09\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C `nolo auth antigravity` \u91CD\u65B0\u6388\u6743\u3002"
817
811
  },
818
- mediaTranscribeDone: {
819
- en: "\u{1F3A7} {0} transcribed \u2014 saved: {1}",
820
- zh: "\u{1F3A7} {0} \u8F6C\u5199\u5B8C\u6210\u2014\u2014\u5DF2\u4FDD\u5B58\uFF1A{1}"
812
+ "auth.providerUnreachable": {
813
+ en: "[nolo] Could not reach the antigravity provider: {0}. Check your network and retry.",
814
+ zh: "[nolo] \u65E0\u6CD5\u8BBF\u95EE antigravity provider\uFF1A{0}\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002"
821
815
  },
822
- mediaTranscribeDoneAttach: {
823
- en: "\u{1F3A7} {0} transcribed \u2014 txt: {1}\n srt: {2}\n transcript will be attached to your next message.",
824
- zh: "\u{1F3A7} {0} \u8F6C\u5199\u5B8C\u6210\u2014\u2014txt\uFF1A{1}\n srt\uFF1A{2}\n \u8F6C\u5199\u5185\u5BB9\u5C06\u968F\u4F60\u4E0B\u4E00\u6761\u6D88\u606F\u53D1\u9001\u7ED9\u6A21\u578B\u3002"
816
+ "auth.credentialWorking": {
817
+ en: "[nolo] \u2713 The credential is working \u2014 no verification is required right now. You can retry your agent.",
818
+ zh: "[nolo] \u2713 \u51ED\u636E\u53EF\u7528\u2014\u2014\u5F53\u524D\u65E0\u9700\u9A8C\u8BC1\u3002\u53EF\u4EE5\u91CD\u8BD5\u4F60\u7684 agent\u3002"
825
819
  },
826
- mediaTranscribeFailed: {
827
- en: "{0} transcription failed: {1}",
828
- zh: "{0} \u8F6C\u5199\u5931\u8D25\uFF1A{1}"
820
+ "auth.googleVerificationRequired": {
821
+ en: "[nolo] Google requires a one-time account verification for {0}.",
822
+ zh: "[nolo] Google \u9700\u8981\u5BF9 {0} \u505A\u4E00\u6B21\u6027\u8D26\u53F7\u9A8C\u8BC1\u3002"
829
823
  },
830
- mediaSilenceTrimScanning: {
831
- en: "\u{1F3A7} {0} checking for trailing silence\u2026",
832
- zh: "\u{1F3A7} {0} \u68C0\u67E5\u5C3E\u90E8\u9759\u97F3\u2026"
824
+ "auth.verificationOpened": {
825
+ en: "[nolo] \u2713 Opened it in your browser \u2014 complete the verification there (sign in with the same Google account), then retry your agent.",
826
+ zh: "[nolo] \u2713 \u5DF2\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u2014\u2014\u8BF7\u5728\u90A3\u91CC\u5B8C\u6210\u9A8C\u8BC1\uFF08\u7528\u540C\u4E00\u4E2A Google \u8D26\u53F7\u767B\u5F55\uFF09\uFF0C\u7136\u540E\u91CD\u8BD5\u4F60\u7684 agent\u3002"
833
827
  },
834
- mediaSilenceTrimNotice: {
835
- en: "\u{1F3A7} {0}: about {1} min of trailing silence \u2014 suggesting cut to {2} (saves ~{1} min).",
836
- zh: "\u{1F3A7} {0}\uFF1A\u5C3E\u90E8\u7EA6 {1} \u5206\u949F\u57FA\u672C\u65E0\u4EBA\u58F0\uFF0C\u5EFA\u8BAE\u622A\u5230 {2}\uFF08\u53EF\u7701\u7EA6 {1} \u5206\u949F\uFF09\u3002"
828
+ "auth.verificationCopyUrl": {
829
+ en: "[nolo] Copy the URL above into a browser signed into {0}, complete the verification, then retry your agent.",
830
+ zh: "[nolo] \u8BF7\u628A\u4E0A\u9762\u7684 URL \u590D\u5236\u5230\u5DF2\u767B\u5F55 {0} \u7684\u6D4F\u89C8\u5668\u4E2D\uFF0C\u5B8C\u6210\u9A8C\u8BC1\u540E\u91CD\u8BD5\u4F60\u7684 agent\u3002"
837
831
  },
838
- mediaSilenceTrimTitle: {
839
- en: "Transcribe range \u2014 trailing silence detected",
840
- zh: "\u8F6C\u5199\u8303\u56F4\u2014\u2014\u68C0\u6D4B\u5230\u5C3E\u90E8\u9759\u97F3"
832
+ "auth.httpWithoutVerificationLink": {
833
+ en: "[nolo] The provider returned HTTP {0} without a verification link \u2014 this is not the one-time-verification case --verify handles.{1} Response detail: {2}",
834
+ zh: "[nolo] provider \u8FD4\u56DE HTTP {0}\uFF0C\u4F46\u6CA1\u6709\u4EFB\u4F55\u9A8C\u8BC1\u94FE\u63A5\u2014\u2014\u8FD9\u4E0D\u5C5E\u4E8E --verify \u5904\u7406\u7684\u4E00\u6B21\u6027\u9A8C\u8BC1\u573A\u666F\u3002{1}\u54CD\u5E94\u8BE6\u60C5\uFF1A{2}"
841
835
  },
842
- mediaSilenceTrimDetail: {
843
- en: "Suggestion: keep everything before {0} (saves ~{1} min of upload/transcription).",
844
- zh: "\u5EFA\u8BAE\uFF1A\u53EA\u5904\u7406 {0} \u4E4B\u524D\u7684\u5185\u5BB9\uFF08\u7701\u7EA6 {1} \u5206\u949F\u7684\u9884\u5904\u7406\u4E0E\u8F6C\u5199\uFF09\u3002"
836
+ // Optional trailing fragment spliced into httpWithoutVerificationLink when a
837
+ // token refresh also failed earlier. English keeps the leading space.
838
+ "auth.httpWithoutVerificationLink.refreshSuffix": {
839
+ en: " (token refresh also failed earlier: {0})",
840
+ zh: "\uFF08\u6B64\u524D token \u5237\u65B0\u4E5F\u5931\u8D25\uFF1A{0}\uFF09"
845
841
  },
846
- mediaSilenceTrimOptionAll: {
847
- en: "Transcribe everything",
848
- zh: "\u5168\u90E8\uFF08\u4E0D\u88C1\u526A\uFF09"
842
+ "auth.localRefreshTokenDropped": {
843
+ en: "[nolo] No local refresh token is kept: {0} is refreshed by {1} (fetched on demand).",
844
+ zh: "[nolo] \u672C\u5730\u4E0D\u518D\u4FDD\u5B58 refresh token\uFF1A{0} \u7531 {1} \u7EDF\u4E00\u5237\u65B0\uFF08\u7528\u5B8C\u5373\u53D6\uFF09\u3002"
849
845
  },
850
- mediaSilenceTrimOptionTrim: {
851
- en: "Follow the suggestion: cut to {0} (saves ~{1} min)",
852
- zh: "\u6309\u5EFA\u8BAE\uFF1A\u622A\u5230 {0}\uFF08\u7701\u7EA6 {1} \u5206\u949F\uFF09"
846
+ "auth.localStateUpdateFailed": {
847
+ en: "[nolo] Warning: failed to update the local credential state ({0}).",
848
+ zh: "[nolo] Warning: \u672C\u5730\u51ED\u636E\u72B6\u6001\u66F4\u65B0\u5931\u8D25\uFF08{0}\uFF09\u3002"
853
849
  },
854
- mediaSilenceTrimApplied: {
855
- en: "\u{1F3A7} following the suggestion \u2014 transcribing up to {0}.",
856
- zh: "\u{1F3A7} \u5DF2\u6309\u5EFA\u8BAE\u88C1\u526A\u2014\u2014\u53EA\u8F6C\u5199 {0} \u4E4B\u524D\u7684\u5185\u5BB9\u3002"
850
+ "auth.syncMissingConfig": {
851
+ en: "[nolo] Warning: server sync needs NOLO_SERVER and AUTH_TOKEN env vars, or a configured profile. Skipping server sync.",
852
+ zh: "[nolo] \u8B66\u544A\uFF1A\u670D\u52A1\u7AEF\u540C\u6B65\u9700\u8981 NOLO_SERVER \u548C AUTH_TOKEN \u73AF\u5883\u53D8\u91CF\uFF0C\u6216\u5DF2\u914D\u7F6E\u7684 profile\u3002\u5DF2\u8DF3\u8FC7\u540C\u6B65\u3002"
853
+ },
854
+ "auth.syncedTo": {
855
+ en: "[nolo] Synced to {0}",
856
+ zh: "[nolo] \u5DF2\u540C\u6B65\u5230 {0}"
857
+ },
858
+ "auth.syncDoneWebUsable": {
859
+ en: "[nolo] The web app can now use this subscription.",
860
+ zh: "[nolo] \u7F51\u9875\u7AEF\u73B0\u5728\u53EF\u4EE5\u4F7F\u7528\u8BE5\u8BA2\u9605\u4E86\u3002"
861
+ },
862
+ "auth.syncFailed": {
863
+ en: "[nolo] Warning: server sync failed ({0}). Token saved locally.",
864
+ zh: "[nolo] \u8B66\u544A\uFF1A\u670D\u52A1\u7AEF\u540C\u6B65\u5931\u8D25\uFF08{0}\uFF09\u3002Token \u5DF2\u4FDD\u5B58\u5728\u672C\u5730\u3002"
865
+ },
866
+ "auth.noServerConfigured": {
867
+ en: "[nolo] No server configured. To use this on the web, run nolo login first, then nolo auth {0} --sync-only",
868
+ zh: "[nolo] \u672A\u914D\u7F6E\u670D\u52A1\u5668\u3002\u5982\u9700\u5728\u7F51\u9875\u7AEF\u4F7F\u7528\uFF0C\u8BF7\u5148\u8FD0\u884C nolo login\uFF0C\u518D\u8FD0\u884C nolo auth {0} --sync-only"
869
+ },
870
+ // {1} is the provider name again so the --no-sync-to-server hint names the
871
+ // exact command the user would run; keep [Y/n] as the literal answer hint.
872
+ "auth.syncPrompt": {
873
+ en: "Sync to {0} so the web app can also use this {1} subscription? The credential is stored encrypted; run nolo auth {1} --no-sync-to-server to turn it off later. [Y/n] ",
874
+ zh: "\u540C\u6B65\u5230 {0}\uFF0C\u8BA9\u7F51\u9875\u7AEF\u4E5F\u80FD\u4F7F\u7528\u8FD9\u4E2A {1} \u8BA2\u9605\uFF1F\u51ED\u8BC1\u52A0\u5BC6\u5B58\u50A8\uFF0C\u53EF\u968F\u65F6 nolo auth {1} --no-sync-to-server \u5173\u95ED [Y/n] "
875
+ },
876
+ "auth.notSyncedToServer": {
877
+ en: "[nolo] Not synced to the server. For web use, run: nolo auth {0} --sync-to-server (or --sync-only)",
878
+ zh: "[nolo] \u672A\u540C\u6B65\u51ED\u636E\u5230\u670D\u52A1\u5668\u3002\u5982\u9700\u7F51\u9875\u7AEF\u4F7F\u7528\uFF0C\u8BF7\u8FD0\u884C: nolo auth {0} --sync-to-server\uFF08\u6216 --sync-only\uFF09"
879
+ },
880
+ "auth.markFailed": {
881
+ en: "[nolo] The credential was uploaded to the server, but marking it server-managed locally failed. Re-authorize so both sides cannot race each other's refresh.",
882
+ zh: "[nolo] \u51ED\u636E\u5DF2\u6210\u529F\u4E0A\u4F20\u670D\u52A1\u5668\uFF0C\u4F46\u672C\u5730\u6253\u4E0A\u6258\u7BA1\u6807\u8BB0\u5931\u8D25\u3002\u4E3A\u9632\u53CC\u65B9\u7ADE\u6001\u5237\u65B0\u5BFC\u81F4\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u6388\u6743\u3002"
883
+ },
884
+ "auth.commandFailed": {
885
+ en: "nolo auth {0} failed: {1}",
886
+ zh: "nolo auth {0} \u5931\u8D25\uFF1A{1}"
887
+ },
888
+ "auth.cloudflareTokenGenerated": {
889
+ en: "[nolo] Generated Cloudflare API token for zone {0} ({1}).\nStore it as CLOUDFLARE_EMAIL_ROUTING_API_TOKEN:\n {2}\n",
890
+ zh: "[nolo] \u5DF2\u4E3A zone {0}\uFF08{1}\uFF09\u751F\u6210 Cloudflare API token\u3002\n\u8BF7\u4FDD\u5B58\u4E3A CLOUDFLARE_EMAIL_ROUTING_API_TOKEN\uFF1A\n {2}\n"
891
+ },
892
+ "auth.envUpdated": {
893
+ en: "[nolo] Updated {0} with CLOUDFLARE_EMAIL_ROUTING_API_TOKEN.",
894
+ zh: "[nolo] \u5DF2\u66F4\u65B0 {0} \u91CC\u7684 CLOUDFLARE_EMAIL_ROUTING_API_TOKEN\u3002"
895
+ }
896
+ };
897
+
898
+ // packages/cli/i18n/strings/doc.ts
899
+ var docStrings = {
900
+ docAttachUsage: { en: "Usage: /doc attach <doc>", zh: "\u7528\u6CD5\uFF1A/doc attach <doc>" },
901
+ docList: { en: "Attached docs: {0}", zh: "\u5DF2\u6302\u8F7D\u6587\u6863\uFF1A{0}" },
902
+ docNone: { en: "No docs attached. Use /doc attach <doc>.", zh: "\u8FD8\u6CA1\u6709\u6302\u8F7D\u6587\u6863\u3002\u7528 /doc attach <doc> \u6302\u8F7D\u3002" }
903
+ };
904
+
905
+ // packages/cli/i18n/strings/update.ts
906
+ var updateStrings = {
907
+ versionInfo: {
908
+ en: "nolo {0}\nUpdate this install with: nolo update\nIf repo-local output differs, publish/install the latest npm package first.",
909
+ zh: "nolo {0}\n\u7528 nolo update \u66F4\u65B0\u5F53\u524D\u5B89\u88C5\u3002\n\u5982\u679C\u672C\u5730\u4ED3\u5E93\u8F93\u51FA\u7684\u7248\u672C\u4E0D\u540C\uFF0C\u8BF7\u5148\u53D1\u5E03/\u5B89\u88C5\u6700\u65B0\u7684 npm \u5305\u3002"
910
+ },
911
+ versionUnknown: { en: "unknown version", zh: "\u672A\u77E5\u7248\u672C" },
912
+ updateAvailable: {
913
+ // 保持短:这行在窄终端物理换行会破坏 banner 重绘的行数计算。当前版本
914
+ // 号上一行 version line 已有,不重复。
915
+ en: "\u2191 nolo {0} available \u2014 /update to upgrade",
916
+ zh: "\u2191 nolo {0} \u53EF\u7528 \u2014 /update \u5347\u7EA7"
917
+ },
918
+ updateInstallerTitle: { "en": "Nolo Agent CLI Installer & Updater", "zh": "Nolo Agent CLI \u5B89\u88C5\u4E0E\u66F4\u65B0\u5DE5\u5177" },
919
+ updateBundleTarget: { "en": "\u2713 Target channel: {0} (standalone bundle)", "zh": "\u2713 \u76EE\u6807\u6E20\u9053\uFF1A{0}\uFF08\u72EC\u7ACB\u5B89\u88C5\u5305\uFF09" },
920
+ updateNpmTarget: { "en": "\u2713 Target channel: {0} (nolo-cli@{0})", "zh": "\u2713 \u76EE\u6807\u6E20\u9053\uFF1A{0}\uFF08nolo-cli@{0}\uFF09" },
921
+ updateBundleDownloading: { "en": "\u25B8 Downloading and installing bundle...", "zh": "\u25B8 \u6B63\u5728\u4E0B\u8F7D\u5E76\u5B89\u88C5\u72EC\u7ACB\u5B89\u88C5\u5305\u2026" },
922
+ updateNpmDownloading: { "en": "\u25B8 Downloading and installing package via npm...", "zh": "\u25B8 \u6B63\u5728\u901A\u8FC7 npm \u4E0B\u8F7D\u5E76\u5B89\u88C5\u8F6F\u4EF6\u5305\u2026" },
923
+ updateCompleted: { "en": "\u2713 Update completed successfully!", "zh": "\u2713 \u66F4\u65B0\u6210\u529F\uFF01" },
924
+ updateScheduled: { "en": "\u2713 Update scheduled in background (helper pid {0}).", "zh": "\u2713 \u66F4\u65B0\u5DF2\u5B89\u6392\u5728\u540E\u53F0\u8FDB\u884C\uFF08\u8F85\u52A9\u8FDB\u7A0B PID {0}\uFF09\u3002" },
925
+ updateKeepUsing: { "en": "\u25B8 You can keep using Nolo \u2014 no need to close this or any other window.", "zh": "\u25B8 \u53EF\u4EE5\u7EE7\u7EED\u4F7F\u7528 Nolo\uFF0C\u65E0\u9700\u5173\u95ED\u5F53\u524D\u7A97\u53E3\u6216\u5176\u4ED6\u7A97\u53E3\u3002" },
926
+ updateBackground: { "en": "\u25B8 Installation continues in the background; once it finishes, the next Nolo launch uses the new version.", "zh": "\u25B8 \u5B89\u88C5\u5C06\u5728\u540E\u53F0\u7EE7\u7EED\uFF1B\u5B8C\u6210\u540E\uFF0C\u4E0B\u6B21\u542F\u52A8 Nolo \u5373\u4F7F\u7528\u65B0\u7248\u672C\u3002" },
927
+ updateCheckLog: { "en": " Check version: nolo -v Log: {0}", "zh": " \u67E5\u770B\u7248\u672C\uFF1Anolo -v \u65E5\u5FD7\uFF1A{0}" },
928
+ updateScheduleFailed: { "en": "\u2717 Could not schedule the Windows update: {0}", "zh": "\u2717 \u65E0\u6CD5\u5B89\u6392 Windows \u66F4\u65B0\uFF1A{0}" },
929
+ updateManualClose: { "en": " Manual update after closing every Nolo window: {0}", "zh": " \u5173\u95ED\u6240\u6709 Nolo \u7A97\u53E3\u540E\u624B\u52A8\u66F4\u65B0\uFF1A{0}" },
930
+ updateUnsupported: { "en": "\u2717 Standalone-bundle self-update is not supported on this platform\n (platform={0}, arch={1}).\n Only linux-x64 and darwin-arm64 bundles are published.\n Falling back is not possible from a compiled binary; reinstall via:\n {2}\n", "zh": "\u2717 \u6B64\u5E73\u53F0\u4E0D\u652F\u6301\u72EC\u7ACB\u5B89\u88C5\u5305\u81EA\u66F4\u65B0\n \uFF08platform={0}, arch={1}\uFF09\u3002\n \u4EC5\u53D1\u5E03 linux-x64 \u548C darwin-arm64 \u5B89\u88C5\u5305\u3002\n \u7F16\u8BD1\u540E\u7684\u4E8C\u8FDB\u5236\u7A0B\u5E8F\u65E0\u6CD5\u56DE\u9000\u5230\u5176\u4ED6\u66F4\u65B0\u65B9\u5F0F\uFF1B\u8BF7\u91CD\u65B0\u5B89\u88C5\uFF1A\n {2}\n" },
931
+ updateDoctorTitle: { "en": "Nolo CLI doctor", "zh": "Nolo CLI \u8BCA\u65AD" },
932
+ updateDoctorVersion: { "en": "version {0} {1}", "zh": "\u7248\u672C {0} {1}" },
933
+ updateDoctorInstall: { "en": "install {0}", "zh": "\u5B89\u88C5\u65B9\u5F0F {0}" },
934
+ updateDoctorChannel: { "en": "channel {0}", "zh": "\u6E20\u9053 {0}" },
935
+ updateDoctorEntry: { "en": "entry {0}", "zh": "\u5165\u53E3 {0}" },
936
+ updateDoctorServer: { "en": "server {0}", "zh": "\u670D\u52A1\u5668 {0}" },
937
+ updateDoctorProfile: { "en": "profile {0}", "zh": "\u914D\u7F6E {0}" },
938
+ updateDoctorCommand: { "en": "update nolo update", "zh": "\u66F4\u65B0 nolo update" },
939
+ updateDoctorDiff: { "en": "If direct `nolo` differs from repo-local `bun ./packages/cli/index.ts`,", "zh": "\u5982\u679C\u76F4\u63A5\u8FD0\u884C `nolo` \u4E0E\u4ED3\u5E93\u5185\u7684 `bun ./packages/cli/index.ts` \u8F93\u51FA\u4E0D\u540C\uFF0C" },
940
+ updateDoctorOlder: { "en": "the global install is older than this checkout.", "zh": "\u8BF4\u660E\u5168\u5C40\u5B89\u88C5\u7248\u672C\u6BD4\u5F53\u524D\u4ED3\u5E93\u7248\u672C\u65E7\u3002" },
941
+ updateDoctorManual: { "en": "Manual update: {0}", "zh": "\u624B\u52A8\u66F4\u65B0\uFF1A{0}" },
942
+ updateDescription: { "en": "Update the CLI", "zh": "\u66F4\u65B0 CLI" },
943
+ updateStatusText: { "en": "{0}\nchannel {1}\nNo background update is in progress. Updates on this platform run synchronously in the foreground.", "zh": "{0}\n\u6E20\u9053 {1}\n\u6CA1\u6709\u6B63\u5728\u8FDB\u884C\u7684\u540E\u53F0\u66F4\u65B0\u3002\u6B64\u5E73\u53F0\u7684\u66F4\u65B0\u5728\u524D\u53F0\u540C\u6B65\u6267\u884C\u3002" },
944
+ updateNotifyTitle: { "en": "Nolo", "zh": "Nolo" },
945
+ updateNotifyCurrent: { "en": "Nolo is already up to date", "zh": "Nolo \u5DF2\u662F\u6700\u65B0\u7248\u672C" },
946
+ updateNotifyFinished: { "en": "Update finished - the next Nolo launch uses the new version", "zh": "\u66F4\u65B0\u5B8C\u6210\uFF0C\u4E0B\u6B21\u542F\u52A8 Nolo \u5373\u4F7F\u7528\u65B0\u7248\u672C" },
947
+ updateUsage: { "en": "Usage:\n nolo update Install the latest CLI\n nolo update status Show version, channel, and background-update state", "zh": "\u7528\u6CD5\uFF1A\n nolo update \u5B89\u88C5\u6700\u65B0 CLI\n nolo update status \u663E\u793A\u7248\u672C\u3001channel \u4E0E\u540E\u53F0\u66F4\u65B0\u72B6\u6001" },
948
+ updateNotifyFailed: { "en": "Update failed - see log: {0}", "zh": "\u66F4\u65B0\u5931\u8D25\uFF0C\u8BF7\u67E5\u770B\u65E5\u5FD7\uFF1A{0}" },
949
+ updateVersionChanged: { "en": "\u25B8 Nolo version changed: {0} \u2192 {1}", "zh": "\u25B8 Nolo \u7248\u672C\u53D8\u5316\uFF1A{0} \u2192 {1}" }
950
+ };
951
+
952
+ // packages/cli/i18n/strings/secret.ts
953
+ var secretStrings = {
954
+ "secret.help": {
955
+ en: `Usage:
956
+ nolo secret list [--json] List saved secret names (without values; --json outputs machine-readable list)
957
+ nolo secret get <name> Print the value of a secret (for debugging; agents must not read)
958
+ nolo secret set <name> <value|json> Set a secret (string, or JSON starting with { / [)
959
+ nolo secret delete <name> Delete a secret
960
+ nolo secret run --with <names> -- <cmd> Safely inject secret environment variables and run a command
961
+ nolo secret bind <alias> <ref> [--env <ENV_NAME>] Bind a managed credential reference to an alias
962
+ nolo secret list-bindings List configured secret alias bindings
963
+ nolo secret unbind <alias> Remove a secret alias binding
964
+ `,
965
+ zh: `\u7528\u6CD5:
966
+ nolo secret list [--json] \u5217\u51FA\u5DF2\u4FDD\u5B58\u7684 secret \u540D\u79F0\uFF08\u4E0D\u663E\u793A\u503C\uFF1B--json \u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u6E05\u5355\uFF09
967
+ nolo secret get <name> \u6253\u5370\u6307\u5B9A secret \u7684\u503C\uFF08\u4F9B\u8C03\u8BD5\uFF1BAgent \u4E0D\u5F97\u8BFB\u53D6\uFF09
968
+ nolo secret set <name> <value|json> \u8BBE\u7F6E secret\uFF08\u5B57\u7B26\u4E32\uFF0C\u6216\u4EE5 { / [ \u5F00\u5934\u7684 JSON\uFF09
969
+ nolo secret delete <name> \u5220\u9664\u6307\u5B9A\u7684 secret
970
+ nolo secret run --with <names> -- <cmd> \u5B89\u5168\u6CE8\u5165 secret \u73AF\u5883\u53D8\u91CF\u5E76\u6267\u884C\u5B50\u547D\u4EE4
971
+ nolo secret bind <alias> <ref> [--env <ENV_NAME>] \u5C06\u53D7\u63A7\u51ED\u636E\u5F15\u7528\u7ED1\u5B9A\u5230\u522B\u540D
972
+ nolo secret list-bindings \u5217\u51FA\u5DF2\u914D\u7F6E\u7684 secret \u522B\u540D\u7ED1\u5B9A
973
+ nolo secret unbind <alias> \u89E3\u9664\u6307\u5B9A\u7684 secret \u522B\u540D\u7ED1\u5B9A
974
+ `
975
+ },
976
+ "secret.errorPrefix": {
977
+ en: "Error: {0}",
978
+ zh: "\u9519\u8BEF: {0}"
979
+ },
980
+ "secret.listEmpty": {
981
+ en: "(No secrets currently saved)",
982
+ zh: "\uFF08\u5F53\u524D\u672A\u4FDD\u5B58\u4EFB\u4F55 secret\uFF09"
983
+ },
984
+ "secret.listHeader": {
985
+ en: "Configured secrets:",
986
+ zh: "\u5DF2\u914D\u7F6E\u7684 secret \u5217\u8868:"
987
+ },
988
+ "secret.getNameRequired": {
989
+ en: "Error: Please provide a secret name. Example: nolo secret get amo",
990
+ zh: "\u9519\u8BEF: \u8BF7\u63D0\u4F9B secret \u540D\u79F0\u3002\u4F8B\u5982: nolo secret get amo"
991
+ },
992
+ "secret.getNotFound": {
993
+ en: 'Error: Secret "{0}" not found',
994
+ zh: '\u9519\u8BEF: \u672A\u627E\u5230\u540D\u4E3A "{0}" \u7684 secret'
995
+ },
996
+ "secret.setNameAndValueRequired": {
997
+ en: "Error: Please provide both secret name and value",
998
+ zh: "\u9519\u8BEF: \u8BF7\u63D0\u4F9B secret \u540D\u79F0\u4E0E\u503C"
999
+ },
1000
+ "secret.setValueRequired": {
1001
+ en: "Error: Please provide a secret value",
1002
+ zh: "\u9519\u8BEF: \u8BF7\u63D0\u4F9B secret \u503C"
1003
+ },
1004
+ "secret.setSuccess": {
1005
+ en: '\u2705 Successfully saved secret: "{0}" (mode 0600)',
1006
+ zh: '\u2705 \u6210\u529F\u4FDD\u5B58 secret: "{0}"\uFF08\u6743\u9650 0600\uFF09'
1007
+ },
1008
+ "secret.deleteNameRequired": {
1009
+ en: "Error: Please provide a secret name to delete",
1010
+ zh: "\u9519\u8BEF: \u8BF7\u63D0\u4F9B\u8981\u5220\u9664\u7684 secret \u540D\u79F0"
1011
+ },
1012
+ "secret.deleteSuccess": {
1013
+ en: '\u2705 Successfully deleted secret: "{0}"',
1014
+ zh: '\u2705 \u6210\u529F\u5220\u9664 secret: "{0}"'
1015
+ },
1016
+ "secret.deleteNotFound": {
1017
+ en: 'Secret "{0}" not found, nothing to delete',
1018
+ zh: '\u672A\u627E\u5230\u540D\u4E3A "{0}" \u7684 secret\uFF0C\u65E0\u9700\u5220\u9664'
1019
+ },
1020
+ "secret.runCmdRequired": {
1021
+ en: "Error: Please provide a command to run. Example: nolo secret run --with amo -- bunx web-ext sign",
1022
+ zh: "\u9519\u8BEF: \u8BF7\u63D0\u4F9B\u8981\u6267\u884C\u7684\u547D\u4EE4\u3002\u4F8B\u5982: nolo secret run --with amo -- bunx web-ext sign"
1023
+ },
1024
+ "secret.runMissingBrokerRef": {
1025
+ en: "Error: Credential reference {0} does not exist in local vault or is unauthorized.",
1026
+ zh: "\u9519\u8BEF: \u51ED\u8BC1\u5F15\u7528 {0} \u5728\u672C\u5730\u4FDD\u7BA1\u5E93\u4E2D\u4E0D\u5B58\u5728\u6216\u672A\u6388\u6743\u3002"
1027
+ },
1028
+ "secret.runMissingSecrets": {
1029
+ en: "Error: Secret not found: {0}. Use nolo secret list to check saved names.",
1030
+ zh: "\u9519\u8BEF: \u672A\u627E\u5230 secret: {0}\u3002\u7528 nolo secret list \u6838\u5BF9\u5DF2\u4FDD\u5B58\u7684\u540D\u79F0\u3002"
1031
+ },
1032
+ "secret.runNoInjectedEnvs": {
1033
+ en: "Error: --with {0} did not resolve to any environment variables (credentials cannot be mapped to variables).",
1034
+ zh: "\u9519\u8BEF: --with {0} \u6CA1\u6709\u89E3\u6790\u51FA\u4EFB\u4F55\u73AF\u5883\u53D8\u91CF\uFF08\u51ED\u636E\u65E0\u6CD5\u6620\u5C04\u6210\u53D8\u91CF\uFF09\u3002"
1035
+ },
1036
+ "secret.runCommandFailed": {
1037
+ en: "Failed to execute command: {0}",
1038
+ zh: "\u6267\u884C\u547D\u4EE4\u5931\u8D25: {0}"
1039
+ },
1040
+ "secret.bindEnvValueRequired": {
1041
+ en: "Error: --env requires an environment variable name. Example: --env DEEPINFRA_API_KEY",
1042
+ zh: "\u9519\u8BEF: --env \u9700\u8981\u6307\u5B9A\u73AF\u5883\u53D8\u91CF\u540D\u3002\u4F8B\u5982: --env DEEPINFRA_API_KEY"
1043
+ },
1044
+ "secret.bindArgsRequired": {
1045
+ en: "Error: Please provide alias and credential reference (ref). Example: nolo secret bind deepinfra_api_key vault-cred-xxx [--env DEEPINFRA_API_KEY]",
1046
+ zh: "\u9519\u8BEF: \u8BF7\u63D0\u4F9B alias \u4E0E\u51ED\u636E\u5F15\u7528 (ref)\u3002\u4F8B\u5982: nolo secret bind deepinfra_api_key vault-cred-xxx [--env DEEPINFRA_API_KEY]"
1047
+ },
1048
+ "secret.bindSuccess": {
1049
+ en: '\u2705 Successfully bound secret: "{0}" -> {1} (env: {2})',
1050
+ zh: '\u2705 \u6210\u529F\u7ED1\u5B9A secret: "{0}" -> {1} (env: {2})'
1051
+ },
1052
+ "secret.bindingsEmpty": {
1053
+ en: "(No secret alias bindings currently configured)",
1054
+ zh: "\uFF08\u5F53\u524D\u672A\u914D\u7F6E\u4EFB\u4F55 secret \u522B\u540D\u7ED1\u5B9A\uFF09"
1055
+ },
1056
+ "secret.bindingsHeader": {
1057
+ en: "Configured secret alias bindings:",
1058
+ zh: "\u5DF2\u914D\u7F6E\u7684 secret \u522B\u540D\u7ED1\u5B9A\u5217\u8868:"
1059
+ },
1060
+ "secret.unbindAliasRequired": {
1061
+ en: "Error: Please provide an alias to unbind. Example: nolo secret unbind deepinfra_api_key",
1062
+ zh: "\u9519\u8BEF: \u8BF7\u63D0\u4F9B\u8981\u89E3\u9664\u7ED1\u5B9A\u7684\u522B\u540D (alias)\u3002\u4F8B\u5982: nolo secret unbind deepinfra_api_key"
1063
+ },
1064
+ "secret.unbindSuccess": {
1065
+ en: '\u2705 Successfully unbound secret: "{0}"',
1066
+ zh: '\u2705 \u6210\u529F\u89E3\u9664 secret \u7ED1\u5B9A: "{0}"'
1067
+ },
1068
+ "secret.unbindNotFound": {
1069
+ en: 'Secret binding "{0}" not found, nothing to unbind',
1070
+ zh: '\u672A\u627E\u5230\u540D\u4E3A "{0}" \u7684 secret \u7ED1\u5B9A\uFF0C\u65E0\u9700\u89E3\u9664'
1071
+ },
1072
+ "secret.unknownSubcommand": {
1073
+ en: "Unknown subcommand: {0}. Run nolo secret --help for usage",
1074
+ zh: "\u672A\u77E5\u5B50\u547D\u4EE4: {0}\u3002\u8FD0\u884C nolo secret --help \u67E5\u770B\u7528\u6CD5"
1075
+ },
1076
+ "secret.jsonInvalid": {
1077
+ en: "value starts with { or [ but is not valid JSON",
1078
+ zh: "\u503C\u4EE5 { \u6216 [ \u5F00\u5934\u4F46\u4E0D\u662F\u5408\u6CD5\u7684 JSON"
1079
+ },
1080
+ "secret.jsonScalar": {
1081
+ en: "JSON values must be an object or an array, not a scalar",
1082
+ zh: "JSON \u503C\u5FC5\u987B\u662F\u5BF9\u8C61\u6216\u6570\u7EC4\uFF0C\u4E0D\u80FD\u662F\u6807\u91CF"
1083
+ }
1084
+ };
1085
+
1086
+ // packages/cli/i18n/strings/docCommands.ts
1087
+ var docCommandStrings = {
1088
+ // Usage texts
1089
+ "docCmd.readUsage": {
1090
+ en: `Usage:
1091
+ nolo doc read (--id <pageId> | --key <pageKey>)
1092
+
1093
+ Options:
1094
+ --id <pageId> Page id (without user prefix).
1095
+ --key <pageKey> Full dbKey, e.g. page-<userId>-<pageId>.
1096
+ --server <url> Server to read from.
1097
+ --token <jwt> Auth token. Required for reads.
1098
+ `,
1099
+ zh: `\u7528\u6CD5:
1100
+ nolo doc read (--id <pageId> | --key <pageKey>)
1101
+
1102
+ \u9009\u9879:
1103
+ --id <pageId> \u9875\u9762 ID\uFF08\u4E0D\u5E26\u7528\u6237\u524D\u7F00\uFF09\u3002
1104
+ --key <pageKey> \u5B8C\u6574 dbKey\uFF0C\u4F8B\u5982 page-<userId>-<pageId>\u3002
1105
+ --server <url> \u8BFB\u53D6\u7684\u76EE\u6807\u670D\u52A1\u5668\u3002
1106
+ --token <jwt> \u8EAB\u4EFD\u9A8C\u8BC1\u4EE4\u724C\u3002\u8BFB\u53D6\u64CD\u4F5C\u5FC5\u9700\u3002
1107
+ `
1108
+ },
1109
+ "docCmd.skillReadUsage": {
1110
+ en: `Usage:
1111
+ nolo skill-doc read (--id <skillId> | --key <pageKey>)
1112
+
1113
+ Options:
1114
+ --id <skillId> Skill id (without user prefix).
1115
+ --key <pageKey> Full dbKey, e.g. page-<userId>-<skillId>.
1116
+ --server <url> Server to read from.
1117
+ --token <jwt> Auth token. Required for reads.
1118
+ `,
1119
+ zh: `\u7528\u6CD5:
1120
+ nolo skill-doc read (--id <skillId> | --key <pageKey>)
1121
+
1122
+ \u9009\u9879:
1123
+ --id <skillId> \u6280\u80FD ID\uFF08\u4E0D\u5E26\u7528\u6237\u524D\u7F00\uFF09\u3002
1124
+ --key <pageKey> \u5B8C\u6574 dbKey\uFF0C\u4F8B\u5982 page-<userId>-<skillId>\u3002
1125
+ --server <url> \u8BFB\u53D6\u7684\u76EE\u6807\u670D\u52A1\u5668\u3002
1126
+ --token <jwt> \u8EAB\u4EFD\u9A8C\u8BC1\u4EE4\u724C\u3002\u8BFB\u53D6\u64CD\u4F5C\u5FC5\u9700\u3002
1127
+ `
1128
+ },
1129
+ "docCmd.createUsage": {
1130
+ en: `Usage:
1131
+ nolo doc create --title <title> [--body ... | --body-file path] [--id ...] [--space ...]
1132
+
1133
+ Options:
1134
+ --description <text> Optional page description stored in meta.
1135
+ --sync local,main,us Choose write targets. Values may also be full URLs.
1136
+ --local-only Write only to the local server target.
1137
+ --no-local Exclude local targets when --sync includes them.
1138
+ --dry-run Build and validate without writing.
1139
+ --json Print machine-readable JSON.
1140
+ --allow-secrets Allow bodies that look like credentials.
1141
+ --server <url> Default write target when --sync is omitted.
1142
+ --token <jwt> Auth token. Required for writes.
1143
+ `,
1144
+ zh: `\u7528\u6CD5:
1145
+ nolo doc create --title <title> [--body ... | --body-file path] [--id ...] [--space ...]
1146
+
1147
+ \u9009\u9879:
1148
+ --description <text> \u5B58\u50A8\u5728 meta \u4E2D\u7684\u53EF\u9009\u9875\u9762\u63CF\u8FF0\u3002
1149
+ --sync local,main,us \u9009\u62E9\u5199\u5165\u76EE\u6807\u3002\u503C\u4E5F\u53EF\u4EE5\u662F\u5B8C\u6574 URL\u3002
1150
+ --local-only \u4EC5\u5199\u5165\u672C\u5730\u670D\u52A1\u5668\u76EE\u6807\u3002
1151
+ --no-local \u5F53 --sync \u5305\u542B\u672C\u5730\u76EE\u6807\u65F6\u5C06\u5176\u6392\u9664\u3002
1152
+ --dry-run \u4EC5\u6784\u5EFA\u5E76\u6821\u9A8C\uFF0C\u4E0D\u6267\u884C\u5199\u5165\u3002
1153
+ --json \u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7684 JSON\u3002
1154
+ --allow-secrets \u5141\u8BB8\u5305\u542B\u7591\u4F3C\u51ED\u636E\u7684\u5185\u5BB9\u3002
1155
+ --server <url> \u7701\u7565 --sync \u65F6\u7684\u9ED8\u8BA4\u5199\u5165\u76EE\u6807\u3002
1156
+ --token <jwt> \u8EAB\u4EFD\u9A8C\u8BC1\u4EE4\u724C\u3002\u5199\u5165\u64CD\u4F5C\u5FC5\u9700\u3002
1157
+ `
1158
+ },
1159
+ "docCmd.skillCreateUsage": {
1160
+ en: `Usage:
1161
+ nolo skill-doc create --title <title> --description <text> [--body ... | --body-file path]
1162
+ nolo skill create-doc --title <title> --description <text> [--body ... | --body-file path]
1163
+
1164
+ Options:
1165
+ --tools '["readDoc"]' Tool names this skill expects.
1166
+ --required-skills '["skill-a"]' Required skill references.
1167
+ --recommended-skills '["skill-b"]' Recommended skill references.
1168
+ --trigger-mode explicit|required|recommended
1169
+ --prompt-patch <text>
1170
+ --page | --kind page Create a normal page instead of a skill-backed page.
1171
+ --sync local,main,us Choose write targets. Values may also be full URLs.
1172
+ --dry-run Build and validate without writing.
1173
+ --json Print machine-readable JSON.
1174
+ --token <jwt> Auth token. Required for writes.
1175
+ `,
1176
+ zh: `\u7528\u6CD5:
1177
+ nolo skill-doc create --title <title> --description <text> [--body ... | --body-file path]
1178
+ nolo skill create-doc --title <title> --description <text> [--body ... | --body-file path]
1179
+
1180
+ \u9009\u9879:
1181
+ --tools '["readDoc"]' \u6B64\u6280\u80FD\u671F\u671B\u8C03\u7528\u7684\u5DE5\u5177\u540D\u79F0\u5217\u8868\u3002
1182
+ --required-skills '["skill-a"]' \u5FC5\u9700\u7684\u6280\u80FD\u5F15\u7528\u3002
1183
+ --recommended-skills '["skill-b"]' \u63A8\u8350\u7684\u6280\u80FD\u5F15\u7528\u3002
1184
+ --trigger-mode explicit|required|recommended
1185
+ --prompt-patch <text>
1186
+ --page | --kind page \u521B\u5EFA\u666E\u901A\u9875\u9762\u800C\u975E\u6280\u80FD\u9875\u9762\u3002
1187
+ --sync local,main,us \u9009\u62E9\u5199\u5165\u76EE\u6807\u3002\u503C\u4E5F\u53EF\u4EE5\u662F\u5B8C\u6574 URL\u3002
1188
+ --dry-run \u4EC5\u6784\u5EFA\u5E76\u6821\u9A8C\uFF0C\u4E0D\u6267\u884C\u5199\u5165\u3002
1189
+ --json \u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7684 JSON\u3002
1190
+ --token <jwt> \u8EAB\u4EFD\u9A8C\u8BC1\u4EE4\u724C\u3002\u5199\u5165\u64CD\u4F5C\u5FC5\u9700\u3002
1191
+ `
1192
+ },
1193
+ "docCmd.updateUsage": {
1194
+ en: `Usage:
1195
+ nolo doc update (--id <pageId> | --key <pageKey>) [--title ...] [--body ... | --body-file path] [--space ...]
1196
+
1197
+ Options:
1198
+ --id <pageId> Page id (without user prefix).
1199
+ --key <pageKey> Full dbKey, e.g. page-<userId>-<pageId>.
1200
+ --title <text> New title.
1201
+ --description <text> New page description stored in meta.
1202
+ --body <text> New page body.
1203
+ --body-file <path> Read body from file.
1204
+ --space <spaceId> Move/attach the page to this space.
1205
+ --sync local,main,us Choose write targets. Values may also be full URLs.
1206
+ --local-only Write only to the local server target.
1207
+ --no-local Exclude local targets when --sync includes them.
1208
+ --dry-run Build and validate without writing.
1209
+ --json Print machine-readable JSON.
1210
+ --allow-secrets Allow bodies that look like credentials.
1211
+ --server <url> Default write target when --sync is omitted.
1212
+ --token <jwt> Auth token. Required for writes.
1213
+ `,
1214
+ zh: `\u7528\u6CD5:
1215
+ nolo doc update (--id <pageId> | --key <pageKey>) [--title ...] [--body ... | --body-file path] [--space ...]
1216
+
1217
+ \u9009\u9879:
1218
+ --id <pageId> \u9875\u9762 ID\uFF08\u4E0D\u5E26\u7528\u6237\u524D\u7F00\uFF09\u3002
1219
+ --key <pageKey> \u5B8C\u6574 dbKey\uFF0C\u4F8B\u5982 page-<userId>-<pageId>\u3002
1220
+ --title <text> \u65B0\u6807\u9898\u3002
1221
+ --description <text> \u5B58\u50A8\u5728 meta \u4E2D\u7684\u65B0\u9875\u9762\u63CF\u8FF0\u3002
1222
+ --body <text> \u65B0\u9875\u9762\u6B63\u6587\u3002
1223
+ --body-file <path> \u4ECE\u6587\u4EF6\u8BFB\u53D6\u6B63\u6587\u3002
1224
+ --space <spaceId> \u79FB\u52A8/\u5173\u8054\u9875\u9762\u81F3\u6B64\u7A7A\u95F4\u3002
1225
+ --sync local,main,us \u9009\u62E9\u5199\u5165\u76EE\u6807\u3002\u503C\u4E5F\u53EF\u4EE5\u662F\u5B8C\u6574 URL\u3002
1226
+ --local-only \u4EC5\u5199\u5165\u672C\u5730\u670D\u52A1\u5668\u76EE\u6807\u3002
1227
+ --no-local \u5F53 --sync \u5305\u542B\u672C\u5730\u76EE\u6807\u65F6\u5C06\u5176\u6392\u9664\u3002
1228
+ --dry-run \u4EC5\u6784\u5EFA\u5E76\u6821\u9A8C\uFF0C\u4E0D\u6267\u884C\u5199\u5165\u3002
1229
+ --json \u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7684 JSON\u3002
1230
+ --allow-secrets \u5141\u8BB8\u5305\u542B\u7591\u4F3C\u51ED\u636E\u7684\u5185\u5BB9\u3002
1231
+ --server <url> \u7701\u7565 --sync \u65F6\u7684\u9ED8\u8BA4\u5199\u5165\u76EE\u6807\u3002
1232
+ --token <jwt> \u8EAB\u4EFD\u9A8C\u8BC1\u4EE4\u724C\u3002\u5199\u5165\u64CD\u4F5C\u5FC5\u9700\u3002
1233
+ `
1234
+ },
1235
+ "docCmd.skillUpdateUsage": {
1236
+ en: `Usage:
1237
+ nolo skill-doc update (--id <skillId> | --key <pageKey>) [--title ...] [--description ...] [--body ... | --body-file path]
1238
+
1239
+ Options:
1240
+ --id <skillId> Skill id (without user prefix).
1241
+ --key <pageKey> Full dbKey, e.g. page-<userId>-<skillId>.
1242
+ --title <text> New page title. Also renames the skill unless --name is given.
1243
+ --name <text> New skill name only, leaving the page title untouched.
1244
+ The name is the skill's identity that other docs
1245
+ reference, so prefer this over --title when you only
1246
+ want a nicer title.
1247
+ --description <text> New skill description.
1248
+ --body <text> New skill body.
1249
+ --body-file <path> Read body from file.
1250
+ --space <spaceId> Move/attach the skill page to this space.
1251
+ --tools '["readDoc"]' Replace tool names this skill expects.
1252
+ --required-skills '["skill-a"]' Replace required skill references.
1253
+ --recommended-skills '["skill-b"]' Replace recommended skill references.
1254
+ --trigger-mode explicit|required|recommended
1255
+ --prompt-patch <text>
1256
+ --sync local,main,us Choose write targets. Values may also be full URLs.
1257
+ --local-only Write only to the local server target.
1258
+ --no-local Exclude local targets when --sync includes them.
1259
+ --dry-run Build and validate without writing.
1260
+ --json Print machine-readable JSON.
1261
+ --allow-secrets Allow bodies that look like credentials.
1262
+ --token <jwt> Auth token. Required for writes.
1263
+
1264
+ Promotion:
1265
+ If the target is a plain page whose body already contains a valid
1266
+ <!-- skill-config ... --> block, this command adopts it: the block is parsed,
1267
+ normalized and written back into record.meta (kind="skill" + skillConfig),
1268
+ keeping the same dbKey. Use --dry-run first to preview.
1269
+ `,
1270
+ zh: `\u7528\u6CD5:
1271
+ nolo skill-doc update (--id <skillId> | --key <pageKey>) [--title ...] [--description ...] [--body ... | --body-file path]
1272
+
1273
+ \u9009\u9879:
1274
+ --id <skillId> \u6280\u80FD ID\uFF08\u4E0D\u5E26\u7528\u6237\u524D\u7F00\uFF09\u3002
1275
+ --key <pageKey> \u5B8C\u6574 dbKey\uFF0C\u4F8B\u5982 page-<userId>-<skillId>\u3002
1276
+ --title <text> \u65B0\u9875\u9762\u6807\u9898\u3002\u9664\u975E\u6307\u5B9A --name\uFF0C\u5426\u5219\u4E5F\u4F1A\u91CD\u547D\u540D\u6280\u80FD\u3002
1277
+ --name <text> \u4EC5\u4FEE\u6539\u6280\u80FD\u540D\u79F0\uFF0C\u4FDD\u6301\u9875\u9762\u6807\u9898\u4E0D\u53D8\u3002
1278
+ \u540D\u79F0\u662F\u5176\u4ED6\u6587\u6863\u5F15\u7528\u6B64\u6280\u80FD\u7684\u6807\u8BC6\u7B26\uFF0C
1279
+ \u56E0\u6B64\u82E5\u4EC5\u5E0C\u671B\u66F4\u65B0\u5C55\u793A\u6807\u9898\uFF0C\u5EFA\u8BAE\u4F18\u5148\u4F7F\u7528\u6B64\u9009\u9879\u3002
1280
+ --description <text> \u65B0\u6280\u80FD\u63CF\u8FF0\u3002
1281
+ --body <text> \u65B0\u6280\u80FD\u6B63\u6587\u3002
1282
+ --body-file <path> \u4ECE\u6587\u4EF6\u8BFB\u53D6\u6B63\u6587\u3002
1283
+ --space <spaceId> \u79FB\u52A8/\u5173\u8054\u6280\u80FD\u9875\u9762\u81F3\u6B64\u7A7A\u95F4\u3002
1284
+ --tools '["readDoc"]' \u66FF\u6362\u6B64\u6280\u80FD\u671F\u671B\u8C03\u7528\u7684\u5DE5\u5177\u540D\u79F0\u5217\u8868\u3002
1285
+ --required-skills '["skill-a"]' \u66FF\u6362\u5FC5\u9700\u7684\u6280\u80FD\u5F15\u7528\u3002
1286
+ --recommended-skills '["skill-b"]' \u66FF\u6362\u63A8\u8350\u7684\u6280\u80FD\u5F15\u7528\u3002
1287
+ --trigger-mode explicit|required|recommended
1288
+ --prompt-patch <text>
1289
+ --sync local,main,us \u9009\u62E9\u5199\u5165\u76EE\u6807\u3002\u503C\u4E5F\u53EF\u4EE5\u662F\u5B8C\u6574 URL\u3002
1290
+ --local-only \u4EC5\u5199\u5165\u672C\u5730\u670D\u52A1\u5668\u76EE\u6807\u3002
1291
+ --no-local \u5F53 --sync \u5305\u542B\u672C\u5730\u76EE\u6807\u65F6\u5C06\u5176\u6392\u9664\u3002
1292
+ --dry-run \u4EC5\u6784\u5EFA\u5E76\u6821\u9A8C\uFF0C\u4E0D\u6267\u884C\u5199\u5165\u3002
1293
+ --json \u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7684 JSON\u3002
1294
+ --allow-secrets \u5141\u8BB8\u5305\u542B\u7591\u4F3C\u51ED\u636E\u7684\u5185\u5BB9\u3002
1295
+ --token <jwt> \u8EAB\u4EFD\u9A8C\u8BC1\u4EE4\u724C\u3002\u5199\u5165\u64CD\u4F5C\u5FC5\u9700\u3002
1296
+
1297
+ \u664B\u5347:
1298
+ \u5982\u679C\u76EE\u6807\u662F\u666E\u901A\u9875\u9762\uFF0C\u4E14\u6B63\u6587\u5DF2\u5305\u542B\u6709\u6548\u7684
1299
+ <!-- skill-config ... --> \u533A\u5757\uFF0C\u6B64\u547D\u4EE4\u5C06\u63A5\u7EB3\u5B83\uFF1A\u89E3\u6790\u8BE5\u533A\u5757\u3001
1300
+ \u89C4\u8303\u5316\u5E76\u5199\u56DE record.meta\uFF08kind="skill" + skillConfig\uFF09\uFF0C
1301
+ \u4FDD\u6301 dbKey \u4E0D\u53D8\u3002\u5EFA\u8BAE\u5148\u7528 --dry-run \u9884\u89C8\u3002
1302
+ `
1303
+ },
1304
+ "docCmd.deleteUsage": {
1305
+ en: `Usage:
1306
+ nolo doc delete (--id <pageId> | --key <pageKey>)
1307
+
1308
+ Options:
1309
+ --id <pageId> Page id (without user prefix).
1310
+ --key <pageKey> Full dbKey, e.g. page-<userId>-<pageId>.
1311
+ --sync local,main,us Choose delete targets. Values may also be full URLs.
1312
+ --local-only Delete only on the local server target.
1313
+ --no-local Exclude local targets when --sync includes them.
1314
+ --dry-run Show what would be deleted without deleting.
1315
+ --json Print machine-readable JSON.
1316
+ --server <url> Default target when --sync is omitted.
1317
+ --token <jwt> Auth token. Required for deletes.
1318
+ `,
1319
+ zh: `\u7528\u6CD5:
1320
+ nolo doc delete (--id <pageId> | --key <pageKey>)
1321
+
1322
+ \u9009\u9879:
1323
+ --id <pageId> \u9875\u9762 ID\uFF08\u4E0D\u5E26\u7528\u6237\u524D\u7F00\uFF09\u3002
1324
+ --key <pageKey> \u5B8C\u6574 dbKey\uFF0C\u4F8B\u5982 page-<userId>-<pageId>\u3002
1325
+ --sync local,main,us \u9009\u62E9\u5220\u9664\u76EE\u6807\u3002\u503C\u4E5F\u53EF\u4EE5\u662F\u5B8C\u6574 URL\u3002
1326
+ --local-only \u4EC5\u5728\u672C\u5730\u670D\u52A1\u5668\u76EE\u6807\u4E0A\u5220\u9664\u3002
1327
+ --no-local \u5F53 --sync \u5305\u542B\u672C\u5730\u76EE\u6807\u65F6\u5C06\u5176\u6392\u9664\u3002
1328
+ --dry-run \u4EC5\u9884\u89C8\u5C06\u8981\u5220\u9664\u7684\u5185\u5BB9\uFF0C\u4E0D\u6267\u884C\u5220\u9664\u3002
1329
+ --json \u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7684 JSON\u3002
1330
+ --server <url> \u7701\u7565 --sync \u65F6\u7684\u9ED8\u8BA4\u76EE\u6807\u3002
1331
+ --token <jwt> \u8EAB\u4EFD\u9A8C\u8BC1\u4EE4\u724C\u3002\u5220\u9664\u64CD\u4F5C\u5FC5\u9700\u3002
1332
+ `
1333
+ },
1334
+ "docCmd.skillDeleteUsage": {
1335
+ en: `Usage:
1336
+ nolo skill-doc delete (--id <skillId> | --key <pageKey>)
1337
+
1338
+ Options:
1339
+ --id <skillId> Skill id (without user prefix).
1340
+ --key <pageKey> Full dbKey, e.g. page-<userId>-<skillId>.
1341
+ --sync local,main,us Choose delete targets. Values may also be full URLs.
1342
+ --local-only Delete only on the local server target.
1343
+ --no-local Exclude local targets when --sync includes them.
1344
+ --dry-run Show what would be deleted without deleting.
1345
+ --json Print machine-readable JSON.
1346
+ --token <jwt> Auth token. Required for deletes.
1347
+ `,
1348
+ zh: `\u7528\u6CD5:
1349
+ nolo skill-doc delete (--id <skillId> | --key <pageKey>)
1350
+
1351
+ \u9009\u9879:
1352
+ --id <skillId> \u6280\u80FD ID\uFF08\u4E0D\u5E26\u7528\u6237\u524D\u7F00\uFF09\u3002
1353
+ --key <pageKey> \u5B8C\u6574 dbKey\uFF0C\u4F8B\u5982 page-<userId>-<skillId>\u3002
1354
+ --sync local,main,us \u9009\u62E9\u5220\u9664\u76EE\u6807\u3002\u503C\u4E5F\u53EF\u4EE5\u662F\u5B8C\u6574 URL\u3002
1355
+ --local-only \u4EC5\u5728\u672C\u5730\u670D\u52A1\u5668\u76EE\u6807\u4E0A\u5220\u9664\u3002
1356
+ --no-local \u5F53 --sync \u5305\u542B\u672C\u5730\u76EE\u6807\u65F6\u5C06\u5176\u6392\u9664\u3002
1357
+ --dry-run \u4EC5\u9884\u89C8\u5C06\u8981\u5220\u9664\u7684\u5185\u5BB9\uFF0C\u4E0D\u6267\u884C\u5220\u9664\u3002
1358
+ --json \u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7684 JSON\u3002
1359
+ --token <jwt> \u8EAB\u4EFD\u9A8C\u8BC1\u4EE4\u724C\u3002\u5220\u9664\u64CD\u4F5C\u5FC5\u9700\u3002
1360
+ `
1361
+ },
1362
+ // Errors
1363
+ "docCmd.noReadTargetsResolved": {
1364
+ en: "No read targets resolved. Check --server.",
1365
+ zh: "\u672A\u89E3\u6790\u5230\u4EFB\u4F55\u8BFB\u53D6\u76EE\u6807\u3002\u8BF7\u68C0\u67E5 --server\u3002"
1366
+ },
1367
+ "docCmd.docNotFound": {
1368
+ en: "doc not found: {0}",
1369
+ zh: "\u672A\u627E\u5230\u6587\u6863: {0}"
1370
+ },
1371
+ "docCmd.secretBodyWarning": {
1372
+ en: "Document body appears to contain credentials or secrets. Pass --allow-secrets to write it anyway.",
1373
+ zh: "\u6587\u6863\u6B63\u6587\u7591\u4F3C\u5305\u542B\u51ED\u636E\u6216\u5BC6\u94A5\u3002\u53EF\u4F20\u5165 --allow-secrets \u5F3A\u5236\u5199\u5165\u3002"
1374
+ },
1375
+ "docCmd.noWriteTargetsResolved": {
1376
+ en: "No write targets resolved. Check --sync / --local-only / --no-local.",
1377
+ zh: "\u672A\u89E3\u6790\u5230\u4EFB\u4F55\u5199\u5165\u76EE\u6807\u3002\u8BF7\u68C0\u67E5 --sync / --local-only / --no-local\u3002"
1378
+ },
1379
+ "docCmd.docNotFoundOnTargets": {
1380
+ en: "doc not found on any target: {0}",
1381
+ zh: "\u5728\u4EFB\u4F55\u76EE\u6807\u4E0A\u5747\u672A\u627E\u5230\u6587\u6863: {0}"
1382
+ },
1383
+ "docCmd.targetIsSkillDoc": {
1384
+ en: "Target page is a skill doc. Use nolo skill-doc update --key {0}",
1385
+ zh: "\u76EE\u6807\u9875\u9762\u662F\u6280\u80FD\u6587\u6863\u3002\u8BF7\u4F7F\u7528 nolo skill-doc update --key {0}"
1386
+ },
1387
+ "docCmd.targetNotSkillDoc": {
1388
+ en: "Target page is not a skill doc and its body has no valid skill-config block. Use nolo doc update --key {0}",
1389
+ zh: "\u76EE\u6807\u9875\u9762\u4E0D\u662F\u6280\u80FD\u6587\u6863\uFF0C\u4E14\u5176\u6B63\u6587\u6CA1\u6709\u6709\u6548\u7684 skill-config \u533A\u5757\u3002\u8BF7\u4F7F\u7528 nolo doc update --key {0}"
1390
+ },
1391
+ "docCmd.docNoTitle": {
1392
+ en: "doc has no title and none was provided: {0}",
1393
+ zh: "\u6587\u6863\u6CA1\u6709\u6807\u9898\u4E14\u672A\u63D0\u4F9B\u65B0\u6807\u9898: {0}"
1394
+ },
1395
+ "docCmd.existingSkillMissingConfig": {
1396
+ en: "existing skill doc is missing skillConfig: {0}",
1397
+ zh: "\u73B0\u6709\u6280\u80FD\u6587\u6863\u7F3A\u5C11 skillConfig: {0}"
1398
+ },
1399
+ "docCmd.nameCannotBeEmpty": {
1400
+ en: "--name cannot be empty. Omit it to keep the current skill name.",
1401
+ zh: "--name \u4E0D\u80FD\u4E3A\u7A7A\u3002\u7701\u7565\u6B64\u9009\u9879\u4EE5\u4FDD\u7559\u5F53\u524D\u6280\u80FD\u540D\u79F0\u3002"
1402
+ },
1403
+ "docCmd.noDeleteTargetsResolved": {
1404
+ en: "No delete targets resolved. Check --sync / --local-only / --no-local.",
1405
+ zh: "\u672A\u89E3\u6790\u5230\u4EFB\u4F55\u5220\u9664\u76EE\u6807\u3002\u8BF7\u68C0\u67E5 --sync / --local-only / --no-local\u3002"
1406
+ },
1407
+ "docCmd.targetIsSkillDocDelete": {
1408
+ en: "Target page is a skill doc. Use nolo skill-doc delete --key {0}",
1409
+ zh: "\u76EE\u6807\u9875\u9762\u662F\u6280\u80FD\u6587\u6863\u3002\u8BF7\u4F7F\u7528 nolo skill-doc delete --key {0}"
1410
+ },
1411
+ "docCmd.targetNotSkillDocDelete": {
1412
+ en: "Target page is not a skill doc. Use nolo doc delete --key {0}",
1413
+ zh: "\u76EE\u6807\u9875\u9762\u4E0D\u662F\u6280\u80FD\u6587\u6863\u3002\u8BF7\u4F7F\u7528 nolo doc delete --key {0}"
1414
+ },
1415
+ "docCmd.deleteFailedOnServers": {
1416
+ en: "delete {0} failed on {1}",
1417
+ zh: "\u5220\u9664 {0} \u5728\u4EE5\u4E0B\u670D\u52A1\u5668\u4E0A\u5931\u8D25: {1}"
1418
+ },
1419
+ // Output formatting
1420
+ "docCmd.readDoc": {
1421
+ en: "read {0}: {1}\n",
1422
+ zh: "\u8BFB\u53D6 {0}: {1}\n"
1423
+ },
1424
+ "docCmd.titleLine": {
1425
+ en: "title: {0}\n",
1426
+ zh: "\u6807\u9898: {0}\n"
1427
+ },
1428
+ "docCmd.spaceIdLine": {
1429
+ en: "spaceId: {0}\n",
1430
+ zh: "\u7A7A\u95F4ID: {0}\n"
1431
+ },
1432
+ "docCmd.none": {
1433
+ en: "(none)",
1434
+ zh: "(\u65E0)"
1435
+ },
1436
+ "docCmd.dryRunOk": {
1437
+ en: "dry-run ok: {0}\n",
1438
+ zh: "\u9884\u68C0\u901A\u8FC7\uFF1A{0}\n"
1439
+ },
1440
+ "docCmd.dryRunOkPromote": {
1441
+ en: "dry-run ok (promote page -> skill): {0}\n",
1442
+ zh: "\u9884\u68C0\u901A\u8FC7\uFF08\u9875\u9762\u63D0\u5347\u4E3A skill\uFF09\uFF1A{0}\n"
1443
+ },
1444
+ "docCmd.createdDoc": {
1445
+ en: "created {0}: {1}\n",
1446
+ zh: "\u5DF2\u521B\u5EFA {0}\uFF1A{1}\n"
1447
+ },
1448
+ "docCmd.promotedPageToSkill": {
1449
+ en: "promoted page to skill: {0}\n",
1450
+ zh: "\u5DF2\u63D0\u5347\u9875\u9762\u4E3A skill\uFF1A{0}\n"
1451
+ },
1452
+ "docCmd.updatedDoc": {
1453
+ en: "updated {0}: {1}\n",
1454
+ zh: "\u5DF2\u66F4\u65B0 {0}\uFF1A{1}\n"
1455
+ },
1456
+ "docCmd.deletedDoc": {
1457
+ en: "deleted {0}: {1}\n",
1458
+ zh: "\u5DF2\u5220\u9664 {0}\uFF1A{1}\n"
1459
+ }
1460
+ };
1461
+
1462
+ // packages/cli/i18n/strings/cliSurface.ts
1463
+ var cliSurfaceStrings = {
1464
+ "cliHelpTitle": {
1465
+ "en": "nolo \u2014 Agent-first terminal workspace",
1466
+ "zh": "nolo \u2014 \u4EE5 Agent \u4E3A\u6838\u5FC3\u7684\u7EC8\u7AEF\u5DE5\u4F5C\u7A7A\u95F4"
1467
+ },
1468
+ "cliExamplesLabel": {
1469
+ "en": "Examples:",
1470
+ "zh": "\u793A\u4F8B\uFF1A"
1471
+ },
1472
+ "cliUnknownCommand": {
1473
+ "en": "Unknown command: {0}",
1474
+ "zh": "\u672A\u77E5\u547D\u4EE4\uFF1A{0}"
1475
+ },
1476
+ "cliCooldownHelp": {
1477
+ "en": "Manage per-credential availability cooldowns (429 \u9650\u6D41\u51B7\u5374).\n\nUsage:\n nolo auth cooldown List all active cooldowns\n nolo auth cooldown --clear <credential> Clear one credential's cooldown\n nolo auth cooldown --clear-all Clear all cooldowns\n\nOptions:\n --clear <credential> Clear the cooldown for the given credential\n (e.g. chatgpt / claude / antigravity, or a custom API credential).\n --clear-all Clear every credential cooldown.\n --help Show this help.\n\nNo argument lists the currently cooled credentials with their human-readable\nrecovery time and remaining duration.\n",
1478
+ "zh": "\u7BA1\u7406\u5404\u51ED\u636E\u7684\u53EF\u7528\u6027\u51B7\u5374\uFF08429 \u9650\u6D41\u51B7\u5374\uFF09\u3002\n\n\u7528\u6CD5\uFF1A\n nolo auth cooldown \u5217\u51FA\u6240\u6709\u751F\u6548\u4E2D\u7684\u51B7\u5374\n nolo auth cooldown --clear <credential> \u6E05\u9664\u6307\u5B9A\u51ED\u636E\u7684\u51B7\u5374\n nolo auth cooldown --clear-all \u6E05\u9664\u6240\u6709\u51B7\u5374\n\n\u9009\u9879\uFF1A\n --clear <credential> \u6E05\u9664\u6307\u5B9A\u51ED\u636E\u7684\u51B7\u5374\n \uFF08\u4F8B\u5982 chatgpt / claude / antigravity\uFF0C\u6216\u81EA\u5B9A\u4E49 API \u51ED\u636E\uFF09\u3002\n --clear-all \u6E05\u9664\u5168\u90E8\u51ED\u636E\u51B7\u5374\u3002\n --help \u663E\u793A\u6B64\u5E2E\u52A9\u3002\n\n\u4E0D\u5E26\u53C2\u6570\u65F6\u5217\u51FA\u5904\u4E8E\u51B7\u5374\u4E2D\u7684\u51ED\u636E\u3001\u6062\u590D\u65F6\u95F4\u548C\u5269\u4F59\u65F6\u957F\u3002\n"
1479
+ },
1480
+ "cliCooldownClearedCount": {
1481
+ "en": "Cleared {0} credential cooldown(s).",
1482
+ "zh": "\u5DF2\u6E05\u9664 {0} \u4E2A\u51ED\u636E\u7684\u51B7\u5374\u3002"
1483
+ },
1484
+ "cliCooldownNoneToClear": {
1485
+ "en": "No credential cooldowns to clear.",
1486
+ "zh": "\u6CA1\u6709\u9700\u8981\u6E05\u9664\u7684\u51ED\u636E\u51B7\u5374\u3002"
1487
+ },
1488
+ "cliCooldownMissingCredential": {
1489
+ "en": "Missing credential for --clear. Usage: nolo auth cooldown --clear <credential>",
1490
+ "zh": "--clear \u7F3A\u5C11\u51ED\u636E\u3002\u7528\u6CD5\uFF1Anolo auth cooldown --clear <credential>"
1491
+ },
1492
+ "cliCooldownNotActive": {
1493
+ "en": "No active cooldown for credential: {0}",
1494
+ "zh": "\u8BE5\u51ED\u636E\u6CA1\u6709\u751F\u6548\u4E2D\u7684\u51B7\u5374\uFF1A{0}"
1495
+ },
1496
+ "cliCooldownCleared": {
1497
+ "en": "Cleared cooldown for credential: {0}",
1498
+ "zh": "\u5DF2\u6E05\u9664\u8BE5\u51ED\u636E\u7684\u51B7\u5374\uFF1A{0}"
1499
+ },
1500
+ "cliCooldownNoneActive": {
1501
+ "en": "No active credential cooldowns.",
1502
+ "zh": "\u6CA1\u6709\u751F\u6548\u4E2D\u7684\u51ED\u636E\u51B7\u5374\u3002"
1503
+ },
1504
+ "cliCooldownActive": {
1505
+ "en": "Active credential cooldowns:",
1506
+ "zh": "\u751F\u6548\u4E2D\u7684\u51ED\u636E\u51B7\u5374\uFF1A"
1507
+ },
1508
+ "cliCooldownEntry": {
1509
+ "en": " {0} recovers {1} ({2} remaining)",
1510
+ "zh": " {0} \u6062\u590D\u65F6\u95F4 {1} \uFF08\u5269\u4F59 {2}\uFF09"
1511
+ },
1512
+ "cliCooldownDays": {
1513
+ "en": "{0}d {1}h {2}m",
1514
+ "zh": "{0}\u5929 {1}\u5C0F\u65F6 {2}\u5206\u949F"
1515
+ },
1516
+ "cliCooldownHours": {
1517
+ "en": "{0}h {1}m",
1518
+ "zh": "{0}\u5C0F\u65F6 {1}\u5206\u949F"
1519
+ },
1520
+ "cliCooldownMinutes": {
1521
+ "en": "{0}m",
1522
+ "zh": "{0}\u5206\u949F"
1523
+ },
1524
+ "cliMachineAuthMissing": {
1525
+ "en": "[nolo] Machine commands require an auth token. Run `nolo login` or set AUTH_TOKEN.",
1526
+ "zh": "[nolo] \u673A\u5668\u547D\u4EE4\u9700\u8981\u8BA4\u8BC1\u4EE4\u724C\u3002\u8BF7\u8FD0\u884C `nolo login` \u6216\u8BBE\u7F6E AUTH_TOKEN\u3002"
1527
+ },
1528
+ "cliBrowserInvalidNumber": {
1529
+ "en": "Invalid {0} <N>. Usage: {1}",
1530
+ "zh": "\u65E0\u6548\u7684 {0} <N>\u3002\u7528\u6CD5\uFF1A{1}"
1531
+ },
1532
+ "cliBrowserMissingTab": {
1533
+ "en": "Missing required --tab <id>. Usage: {0}",
1534
+ "zh": "\u7F3A\u5C11\u5FC5\u9700\u7684 --tab <id>\u3002\u7528\u6CD5\uFF1A{0}"
1535
+ },
1536
+ "cliBrowserMissingTarget": {
1537
+ "en": "Provide --ref <elementRef> (from read-page) or --selector <css>. Usage: {0}",
1538
+ "zh": "\u8BF7\u63D0\u4F9B --ref <elementRef>\uFF08\u6765\u81EA read-page\uFF09\u6216 --selector <css>\u3002\u7528\u6CD5\uFF1A{0}"
1539
+ },
1540
+ "cliBrowserMissingUrl": {
1541
+ "en": "Missing required --url <url>. Usage: {0}",
1542
+ "zh": "\u7F3A\u5C11\u5FC5\u9700\u7684 --url <url>\u3002\u7528\u6CD5\uFF1A{0}"
1543
+ },
1544
+ "cliBrowserMissingText": {
1545
+ "en": "Missing required --text <text>. Usage: {0}",
1546
+ "zh": "\u7F3A\u5C11\u5FC5\u9700\u7684 --text <text>\u3002\u7528\u6CD5\uFF1A{0}"
1547
+ },
1548
+ "cliBrowserMissingFile": {
1549
+ "en": "Missing required --file <path>. Usage: {0}",
1550
+ "zh": "\u7F3A\u5C11\u5FC5\u9700\u7684 --file <path>\u3002\u7528\u6CD5\uFF1A{0}"
1551
+ },
1552
+ "cliBrowserMissingKey": {
1553
+ "en": "Missing required --key <key>. Usage: {0}",
1554
+ "zh": "\u7F3A\u5C11\u5FC5\u9700\u7684 --key <key>\u3002\u7528\u6CD5\uFF1A{0}"
1555
+ },
1556
+ "cliBrowserAction": {
1557
+ "en": "Invalid or missing --action <click|type|press>. Usage: {0}",
1558
+ "zh": "--action <click|type|press> \u65E0\u6548\u6216\u7F3A\u5931\u3002\u7528\u6CD5\uFF1A{0}"
1559
+ },
1560
+ "cliBrowserRefUnsupported": {
1561
+ "en": "--ref is not supported for action preparation; use --selector or --active. Usage: {0}",
1562
+ "zh": "\u52A8\u4F5C\u51C6\u5907\u4E0D\u652F\u6301 --ref\uFF1B\u8BF7\u4F7F\u7528 --selector \u6216 --active\u3002\u7528\u6CD5\uFF1A{0}"
1563
+ },
1564
+ "cliBrowserSelector": {
1565
+ "en": "Provide --selector <css> or --active. Usage: {0}",
1566
+ "zh": "\u8BF7\u63D0\u4F9B --selector <css> \u6216 --active\u3002\u7528\u6CD5\uFF1A{0}"
1567
+ },
1568
+ "cliBrowserTypeText": {
1569
+ "en": "Missing required --text <text> for type action. Usage: {0}",
1570
+ "zh": "type \u52A8\u4F5C\u7F3A\u5C11\u5FC5\u9700\u7684 --text <text>\u3002\u7528\u6CD5\uFF1A{0}"
1571
+ },
1572
+ "cliBrowserPressKey": {
1573
+ "en": "Missing required --key <key> for press action. Usage: {0}",
1574
+ "zh": "press \u52A8\u4F5C\u7F3A\u5C11\u5FC5\u9700\u7684 --key <key>\u3002\u7528\u6CD5\uFF1A{0}"
1575
+ },
1576
+ "cliBrowserBrowser": {
1577
+ "en": 'Invalid --browser value: expected "chrome" or "firefox". Usage: {0}',
1578
+ "zh": '--browser \u503C\u65E0\u6548\uFF1A\u5E94\u4E3A "chrome" \u6216 "firefox"\u3002\u7528\u6CD5\uFF1A{0}'
1579
+ },
1580
+ "cliBrowserUnknown": {
1581
+ "en": 'Unknown browser subcommand "{0}".',
1582
+ "zh": '\u672A\u77E5\u6D4F\u89C8\u5668\u5B50\u547D\u4EE4 "{0}"\u3002'
1583
+ },
1584
+ "cliBrowserHelpIntro": {
1585
+ "en": "Operate the user's browser (Chrome or Firefox) through the Nolo Browser Connector\n(the desktop bridge; the same RPC the browser_* agent tools use \u2014 legacy `chrome_*` names still work).\n\nUsage:\n nolo browser <subcommand> [flags]\n nolo chrome <subcommand> [flags] # compatibility alias\n\nSubcommands:",
1586
+ "zh": "\u901A\u8FC7 Nolo Browser Connector \u64CD\u4F5C\u7528\u6237\u7684\u6D4F\u89C8\u5668\uFF08Chrome \u6216 Firefox\uFF09\n\uFF08\u684C\u9762\u6865\u63A5\uFF1B\u4E0E browser_* agent \u5DE5\u5177\u4F7F\u7528\u76F8\u540C RPC\uFF0C\u4ECD\u517C\u5BB9\u65E7\u540D\u79F0 `chrome_*`\uFF09\u3002\n\n\u7528\u6CD5\uFF1A\n nolo browser <subcommand> [flags]\n nolo chrome <subcommand> [flags] # \u517C\u5BB9\u522B\u540D\n\n\u5B50\u547D\u4EE4\uFF1A"
1587
+ },
1588
+ "cliBrowserHelpNotes": {
1589
+ "en": '\nNotes:\n --ref takes an elementRef copied from `nolo browser read-page` (revision-scoped,\n preferred over --selector); --selector takes a CSS selector.\n Actions the connector classifies as irreversible (pay / send / delete / publish / permission)\n open a confirmation request in the browser and return USER_APPROVAL_PENDING with an approvalId:\n the user clicks "Allow once" there, then rerun the same command with --approval-id <id>.\n That id is not an authorization \u2014 only the lookup key for the decision the user already made.\n prepare-action prepares an immutable action challenge binding for host consent verification;\n it is strictly read-only, never executes mutations, and does not grant approval.\n read-console / read-network / upload work on Chrome only (Firefox lacks chrome.debugger).\n --browser chrome|firefox selects which connector endpoint serves the call (default\n auto-detects single online browser: chrome = 127.0.0.1:38947, firefox = 127.0.0.1:38948);\n the wrong browser is refused.\n Every subcommand prints the connector\'s raw JSON result; failures exit 1.\n Endpoint: NOLO_CHROME_CONNECTOR_RPC_URL or per-browser NOLO_CHROME_CONNECTOR_PORT /\n NOLO_FIREFOX_CONNECTOR_PORT (default http://127.0.0.1:38947/rpc).',
1590
+ "zh": "\n\u8BF4\u660E\uFF1A\n --ref \u4F7F\u7528\u4ECE `nolo browser read-page` \u590D\u5236\u7684 elementRef\uFF08\u4EC5\u9002\u7528\u4E8E\u5BF9\u5E94\u4FEE\u8BA2\uFF0C\n \u4F18\u5148\u4E8E --selector\uFF09\uFF1B--selector \u4F7F\u7528 CSS \u9009\u62E9\u5668\u3002\n \u8FDE\u63A5\u5668\u5224\u5B9A\u4E3A\u4E0D\u53EF\u9006\u7684\u52A8\u4F5C\uFF08\u4ED8\u6B3E / \u53D1\u9001 / \u5220\u9664 / \u53D1\u5E03 / \u6388\u6743\uFF09\u4F1A\u5728\u6D4F\u89C8\u5668\u91CC\u53D1\u8D77\u786E\u8BA4\u8BF7\u6C42\uFF0C\n \u8FD4\u56DE USER_APPROVAL_PENDING \u4E0E\u4E00\u4E2A approvalId\uFF1A\n \u7528\u6237\u5728\u90A3\u91CC\u70B9\u300C\u5141\u8BB8\u4E00\u6B21\u300D\u540E\uFF0C\u518D\u7528 --approval-id <id> \u91CD\u8DD1\u540C\u4E00\u6761\u547D\u4EE4\u3002\n \u8BE5 id \u4E0D\u662F\u6388\u6743\u51ED\u8BC1\u2014\u2014\u53EA\u662F\u7528\u6237\u5DF2\u505A\u51B3\u5B9A\u7684\u67E5\u8BE2\u952E\u3002\n prepare-action \u4E3A\u5BBF\u4E3B\u540C\u610F\u6821\u9A8C\u51C6\u5907\u4E0D\u53EF\u53D8\u7684\u52A8\u4F5C\u6311\u6218\u7ED1\u5B9A\uFF1B\n \u5B83\u4E25\u683C\u53EA\u8BFB\uFF0C\u4E0D\u6267\u884C\u4FEE\u6539\uFF0C\u4E5F\u4E0D\u6388\u4E88\u6279\u51C6\u3002\n read-console / read-network / upload \u4EC5\u652F\u6301 Chrome\uFF08Firefox \u7F3A\u5C11 chrome.debugger\uFF09\u3002\n --browser chrome|firefox \u9009\u62E9\u8FDE\u63A5\u5668\u7AEF\u70B9\uFF08\u9ED8\u8BA4\u81EA\u52A8\u63A2\u6D4B\u552F\u4E00\u5728\u7EBF\u6D4F\u89C8\u5668\uFF1A\n chrome = 127.0.0.1:38947\uFF0Cfirefox = 127.0.0.1:38948\uFF09\uFF1B\n \u6D4F\u89C8\u5668\u4E0D\u5339\u914D\u65F6\u4F1A\u62D2\u7EDD\u8C03\u7528\u3002\n \u6BCF\u4E2A\u5B50\u547D\u4EE4\u8F93\u51FA\u8FDE\u63A5\u5668\u7684\u539F\u59CB JSON \u7ED3\u679C\uFF1B\u5931\u8D25\u65F6\u9000\u51FA\u7801\u4E3A 1\u3002\n \u7AEF\u70B9\uFF1ANOLO_CHROME_CONNECTOR_RPC_URL \u6216\u6309\u6D4F\u89C8\u5668\u8BBE\u7F6E NOLO_CHROME_CONNECTOR_PORT /\n NOLO_FIREFOX_CONNECTOR_PORT\uFF08\u9ED8\u8BA4 http://127.0.0.1:38947/rpc\uFF09\u3002"
1591
+ }
1592
+ };
1593
+
1594
+ // packages/cli/i18n/strings/common.ts
1595
+ var commonStrings = {
1596
+ placeholder: {
1597
+ en: "Type a message or / for commands...",
1598
+ zh: "\u8F93\u5165\u6D88\u606F\uFF0C\u6216\u7528 / \u67E5\u770B\u547D\u4EE4\u2026"
1599
+ },
1600
+ newDialog: {
1601
+ en: "new dialog",
1602
+ zh: "\u65B0\u5BF9\u8BDD"
1603
+ },
1604
+ startedFreshDialog: {
1605
+ en: "Started a fresh dialog.",
1606
+ zh: "\u5DF2\u5F00\u59CB\u65B0\u5BF9\u8BDD\u3002"
1607
+ },
1608
+ persistentProcessesLeft: {
1609
+ en: "{0} persistent process(es) left running in the background.",
1610
+ zh: "\u4ECD\u6709 {0} \u4E2A\u5E38\u9A7B\u540E\u53F0\u8FDB\u7A0B\u5728\u540E\u53F0\u7EE7\u7EED\u8FD0\u884C\u3002"
1611
+ },
1612
+ contextNextClear: {
1613
+ en: "clear current dialog messages",
1614
+ zh: "\u6E05\u9664\u5F53\u524D\u5BF9\u8BDD\u6D88\u606F"
1615
+ },
1616
+ bye: {
1617
+ en: "Bye.",
1618
+ zh: "\u518D\u89C1\u3002"
1619
+ },
1620
+ resumedDialogPrefix: {
1621
+ en: "Resumed dialog",
1622
+ zh: "\u5DF2\u6062\u590D\u5BF9\u8BDD"
1623
+ },
1624
+ resumeInvalidId: {
1625
+ en: "does not look like a dialog id. Use /history to pick one.",
1626
+ zh: "\u770B\u8D77\u6765\u4E0D\u662F dialog id\u3002\u7528 /history \u4ECE\u5217\u8868\u91CC\u9009\u4E00\u4E2A\u3002"
1627
+ },
1628
+ dialogResumeCancelled: {
1629
+ en: "Dialog resume cancelled.",
1630
+ zh: "\u5DF2\u53D6\u6D88\u6062\u590D\u5BF9\u8BDD\u3002"
1631
+ },
1632
+ noDialogsYet: {
1633
+ en: "No dialogs yet.",
1634
+ zh: "\u8FD8\u6CA1\u6709\u5386\u53F2\u5BF9\u8BDD\u3002"
1635
+ },
1636
+ stopHint: {
1637
+ en: "Esc to stop",
1638
+ zh: "Esc \u505C\u6B62\u56DE\u590D"
1639
+ },
1640
+ flushQueuedIdleHint: {
1641
+ en: "Flushed {0} queued messages as one.",
1642
+ zh: "\u5DF2\u628A {0} \u6761\u6392\u961F\u6D88\u606F\u5408\u5E76\u53D1\u9001\u3002"
1643
+ },
1644
+ flushQueuedBusyHint: {
1645
+ en: "Stopped this reply and flushed {0} queued messages as one.",
1646
+ zh: "\u5DF2\u505C\u6B62\u5F53\u524D\u56DE\u590D\uFF0C\u5E76\u628A {0} \u6761\u6392\u961F\u6D88\u606F\u5408\u5E76\u53D1\u9001\u3002"
1647
+ },
1648
+ forceStopped: {
1649
+ en: "Force stopped. Background tasks may still be finishing.",
1650
+ zh: "\u5DF2\u5F3A\u5236\u505C\u6B62\uFF0C\u540E\u53F0\u4EFB\u52A1\u53EF\u80FD\u4ECD\u5728\u6536\u5C3E\u3002"
1651
+ },
1652
+ quotaExhaustedHint: {
1653
+ en: "This agent is temporarily unavailable (HTTP 429).\nUse /agent to switch to another agent and keep going \u2014 the dialog context is preserved.",
1654
+ zh: "\u5F53\u524D agent \u6682\u65F6\u4E0D\u53EF\u7528\uFF08HTTP 429\uFF09\u3002\n\u53EF\u4EE5\u7528 /agent \u5207\u6362\u5230\u5176\u4ED6 agent \u540E\u7EE7\u7EED\uFF0C\u540C\u4E00\u5BF9\u8BDD\u4F1A\u4FDD\u7559\u4E0A\u4E0B\u6587\u3002"
1655
+ },
1656
+ balanceExhaustedHint: {
1657
+ en: 'Your message is saved in this dialog \u2014 top up, then send again or say "continue" to pick up where you left off.',
1658
+ zh: "\u4F60\u521A\u53D1\u7684\u8BDD\u5DF2\u4FDD\u5B58\u5728\u5F53\u524D\u5BF9\u8BDD\u91CC\u2014\u2014\u5145\u503C\u540E\u76F4\u63A5\u518D\u8BF4\u4E00\u53E5\u6216\u8BF4\u300C\u7EE7\u7EED\u300D\u5373\u53EF\u63A5\u7740\u804A\uFF0C\u4E0D\u4F1A\u4E22\u4E0A\u4E0B\u6587\u3002"
1659
+ },
1660
+ balanceInsufficientReason: {
1661
+ en: "Insufficient balance: requires > {required}, current balance {current}.",
1662
+ zh: "\u4F59\u989D\u4E0D\u8DB3\uFF1A\u9700\u8981\u4F59\u989D > {required}\uFF0C\u5F53\u524D {current}\u3002"
1663
+ },
1664
+ dialogPreservedHint: {
1665
+ en: 'This turn failed, but the dialog is kept. Send another message (or say "continue") to keep going in the same conversation.',
1666
+ zh: "\u672C\u8F6E\u5931\u8D25\u4E86\uFF0C\u4F46\u5BF9\u8BDD\u5DF2\u4FDD\u7559\u3002\u76F4\u63A5\u518D\u8BF4\u4E00\u53E5\uFF08\u6216\u8BF4\u300C\u7EE7\u7EED\u300D\uFF09\u5373\u53EF\u5728\u540C\u4E00\u5BF9\u8BDD\u91CC\u63A5\u7740\u804A\u3002"
1667
+ },
1668
+ dialogNotSavedHint: {
1669
+ en: "This turn did not create a dialog. Your next message will start a new conversation \u2014 restate what you need.",
1670
+ zh: "\u672C\u8F6E\u6CA1\u6709\u5EFA\u6210\u5BF9\u8BDD\u3002\u4E0B\u4E00\u53E5\u4F1A\u662F\u65B0\u5BF9\u8BDD\u2014\u2014\u8BF7\u628A\u4F60\u60F3\u505A\u7684\u4E8B\u518D\u8BF4\u4E00\u904D\u3002"
1671
+ },
1672
+ copiedLastReply: {
1673
+ en: "Copied the last reply to the clipboard.",
1674
+ zh: "\u5DF2\u590D\u5236\u6700\u540E\u4E00\u6761\u56DE\u590D\u5230\u526A\u8D34\u677F\u3002"
1675
+ },
1676
+ copyNothing: {
1677
+ en: "Nothing to copy yet.",
1678
+ zh: "\u8FD8\u6CA1\u6709\u53EF\u590D\u5236\u7684\u5185\u5BB9\u3002"
1679
+ },
1680
+ copyFailed: {
1681
+ en: "Copy failed",
1682
+ zh: "\u590D\u5236\u5931\u8D25"
1683
+ },
1684
+ copyUnavailable: {
1685
+ en: "Clipboard is unavailable in this environment. The last reply was printed above for manual copy.",
1686
+ zh: "\u5F53\u524D\u73AF\u5883\u6CA1\u6709\u53EF\u7528\u7684\u526A\u8D34\u677F\u3002\u6700\u540E\u4E00\u6761\u56DE\u590D\u5DF2\u6253\u5370\u5728\u4E0A\u65B9\uFF0C\u53EF\u624B\u52A8\u590D\u5236\u3002"
1687
+ },
1688
+ copyUsage: {
1689
+ en: "Usage: /copy",
1690
+ zh: "\u7528\u6CD5\uFF1A/copy"
1691
+ },
1692
+ copiedToClipboard: {
1693
+ en: "\u2713 Copied to clipboard.",
1694
+ zh: "\u2713 \u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F\u3002"
1695
+ },
1696
+ copiedSelection: {
1697
+ en: "\u2713 Copied the selection to the clipboard.",
1698
+ zh: "\u2713 \u5DF2\u590D\u5236\u9009\u533A\u5230\u526A\u8D34\u677F\u3002"
1699
+ },
1700
+ copiedSelectionBusy: {
1701
+ en: "\u2713 Copied the selection to the clipboard. Press Esc to stop generating.",
1702
+ zh: "\u2713 \u5DF2\u590D\u5236\u9009\u533A\u5230\u526A\u8D34\u677F\u3002\u6309 Esc \u505C\u6B62\u751F\u6210\u3002"
1703
+ },
1704
+ copiedAllHistory: {
1705
+ en: "\u2713 Copied the full conversation to the clipboard.",
1706
+ zh: "\u2713 \u5DF2\u590D\u5236\u5B8C\u6574\u5BF9\u8BDD\u5230\u526A\u8D34\u677F\u3002"
1707
+ },
1708
+ copyAllNothing: {
1709
+ en: "No conversation to copy yet.",
1710
+ zh: "\u8FD8\u6CA1\u6709\u53EF\u590D\u5236\u7684\u5BF9\u8BDD\u5185\u5BB9\u3002"
1711
+ },
1712
+ ctrlCExitHint: {
1713
+ en: "[hint] Press Ctrl+C again to exit | Type /copy to copy the latest reply",
1714
+ zh: "[\u63D0\u793A] \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA | \u8F93\u5165 /copy \u53EF\u590D\u5236\u6700\u65B0\u56DE\u590D"
1715
+ },
1716
+ ctrlCClearedDraft: {
1717
+ en: "Draft cleared.",
1718
+ zh: "\u8F93\u5165\u8349\u7A3F\u5DF2\u6E05\u7A7A\u3002"
1719
+ },
1720
+ // 空草稿按 Backspace 逐个撤销附件(composer 附件条)。
1721
+ attachmentRemovedHint: {
1722
+ en: "Removed attachment {0}, {1} remaining",
1723
+ zh: "\u5DF2\u79FB\u9664\u9644\u4EF6 {0}\uFF0C\u5269\u4F59 {1} \u5F20"
1724
+ },
1725
+ mouseOn: {
1726
+ en: "Mouse mode on: wheel scrolls the transcript; hold Shift (or Option/Fn) to select text.",
1727
+ zh: "\u9F20\u6807\u6A21\u5F0F\u5DF2\u5F00\u542F\uFF1A\u6EDA\u8F6E\u6EDA\u52A8\u5BF9\u8BDD\u8BB0\u5F55\uFF1B\u6309\u4F4F Shift\uFF08\u6216 Option/Fn\uFF09\u53EF\u62D6\u9009\u590D\u5236\u3002"
1728
+ },
1729
+ mouseOff: {
1730
+ en: "Mouse mode off: drag to select/copy freely; scroll with PageUp/PageDown.",
1731
+ zh: "\u9F20\u6807\u6A21\u5F0F\u5DF2\u5173\u95ED\uFF1A\u53EF\u76F4\u63A5\u62D6\u9009\u590D\u5236\uFF1B\u7528 PageUp/PageDown \u6EDA\u52A8\u5BF9\u8BDD\u8BB0\u5F55\u3002"
1732
+ },
1733
+ mouseUsage: {
1734
+ en: "Usage: /mouse <on|off>",
1735
+ zh: "\u7528\u6CD5\uFF1A/mouse <on|off>"
1736
+ },
1737
+ mathOn: {
1738
+ en: "Math rendering on: LaTeX formulas rendered with Unicode symbols.",
1739
+ zh: "\u6570\u5B66\u516C\u5F0F\u6E32\u67D3\u5DF2\u5F00\u542F\uFF1ALaTeX \u516C\u5F0F\u5C06\u8F6C\u5199\u4E3A Unicode \u7B26\u53F7\u3002"
1740
+ },
1741
+ mathOff: {
1742
+ en: "Math rendering off: raw LaTeX formulas preserved.",
1743
+ zh: "\u6570\u5B66\u516C\u5F0F\u6E32\u67D3\u5DF2\u5173\u95ED\uFF1A\u4FDD\u7559\u539F\u59CB LaTeX \u516C\u5F0F\u3002"
1744
+ },
1745
+ mathUsage: {
1746
+ en: "Usage: /math <on|off>",
1747
+ zh: "\u7528\u6CD5\uFF1A/math <on|off>"
1748
+ },
1749
+ // --- Tool trace copy ------------------------------------------------------
1750
+ // The compact trace shows only status, never timing or output size: a line
1751
+ // count told the user nothing actionable and the ms figure read as noise.
1752
+ workingFallback: {
1753
+ en: "Working\u2026",
1754
+ zh: "\u5904\u7406\u4E2D\u2026"
857
1755
  },
858
- mediaSilenceTrimHintOnly: {
859
- en: "\u{1F3A7} keeping the full file (can't ask right now). To trim, rerun /transcribe with --to {0}.",
860
- zh: "\u{1F3A7} \u5F53\u524D\u65E0\u6CD5\u4EA4\u4E92\uFF0C\u6309\u5168\u7247\u8F6C\u5199\uFF1B\u5982\u9700\u88C1\u526A\uFF0C\u8BF7\u7528 --to {0} \u91CD\u8DD1 /transcribe\u3002"
1756
+ thinkingActive: {
1757
+ en: "Thinking\u2026",
1758
+ zh: "\u601D\u8003\u4E2D\u2026"
861
1759
  },
862
- transcribeUsage: {
863
- en: "Usage: /transcribe <path> [--from ss|mm:ss|hh:mm:ss] [--to ss|mm:ss|hh:mm:ss] [--lang zh|en|...] [--denoise off|light|strong]",
864
- zh: "\u7528\u6CD5\uFF1A/transcribe <\u8DEF\u5F84> [--from \u79D2|\u5206:\u79D2|\u65F6:\u5206:\u79D2] [--to \u79D2|\u5206:\u79D2|\u65F6:\u5206:\u79D2] [--lang zh|en|...] [--denoise off|light|strong]"
1760
+ thinkingActivePreview: {
1761
+ en: "Thinking: {0}",
1762
+ zh: "\u601D\u8003\u4E2D\uFF1A{0}"
865
1763
  },
866
- transcribeArgError: {
867
- en: "Invalid /transcribe argument: {0}",
868
- zh: "/transcribe \u53C2\u6570\u9519\u8BEF\uFF1A{0}"
1764
+ // --- Pre-delta turn phase labels (ctx-overflow-feedback batch 3) ----------
1765
+ // Rendered on the spinner / activity line while the local runtime checks the
1766
+ // context window, compacts history, or waits for the first model delta —
1767
+ // the previously silent pre-delta window (batch 1/2a 修好 runtime 与 SSE,
1768
+ // 这里补齐 CLI/TUI 的状态行投影)。compacting 行附带可取消提示:Esc /
1769
+ // Ctrl+C 即 abort,语义与 localLoop 的 abortSignal 一致。
1770
+ contextChecking: {
1771
+ en: "Checking this model's context window\u2026",
1772
+ zh: "\u6B63\u5728\u68C0\u67E5\u5F53\u524D\u6A21\u578B\u7684\u4E0A\u4E0B\u6587\u7A97\u53E3\u2026"
869
1773
  },
870
- transcribeNotMedia: {
871
- en: "Not a media file: {0}",
872
- zh: "\u4E0D\u662F\u97F3\u89C6\u9891\u6587\u4EF6\uFF1A{0}"
1774
+ contextCompacting: {
1775
+ en: "Compacting history\u2026 (Esc/Ctrl+C to cancel)",
1776
+ zh: "\u6B63\u5728\u538B\u7F29\u5386\u53F2\u8BB0\u5F55\u2026\uFF08Esc/Ctrl+C \u53D6\u6D88\uFF09"
873
1777
  },
874
- transcribeBusyHint: {
875
- en: "/transcribe is unavailable while a reply is running \u2014 it attaches to your next message. Wait for the reply to finish, then run it.",
876
- zh: "\u56DE\u590D\u8FDB\u884C\u4E2D\u4E0D\u80FD\u6267\u884C /transcribe\u2014\u2014\u8F6C\u5199\u4EA7\u7269\u8981\u968F\u4E0B\u4E00\u6761\u6D88\u606F\u53D1\u9001\u3002\u7B49\u672C\u8F6E\u56DE\u590D\u7ED3\u675F\u540E\u518D\u6267\u884C\u3002"
1778
+ waitingForModel: {
1779
+ en: "Waiting for the model\u2026",
1780
+ zh: "\u6B63\u5728\u7B49\u5F85\u6A21\u578B\u54CD\u5E94\u2026"
877
1781
  },
878
- busyAttachmentsBlocked: {
879
- en: "can't queue a message with {0} clipboard image(s) while a turn is running \u2014 draft kept. Send again after this turn ends, or press Backspace to drop the attachment and send text only.",
880
- zh: "\u5FD9\u788C\u4E2D\u65E0\u6CD5\u6392\u961F\u5E26 {0} \u5F20\u526A\u8D34\u677F\u56FE\u7247\u7684\u6D88\u606F\uFF0C\u8349\u7A3F\u5DF2\u4FDD\u7559\uFF1B\u7B49\u672C\u8F6E\u7ED3\u675F\u540E\u518D\u6309 Enter \u53D1\u9001\uFF0C\u6216 Backspace \u64A4\u9500\u9644\u4EF6\u540E\u6539\u53D1\u7EAF\u6587\u5B57\u3002"
1782
+ // --- Local turn deadline failure (single actionable line) -----------------
1783
+ // localLoop 主请求 idle deadline(DEFAULT_LLM_REQUEST_TIMEOUT_MS 兜底或调用方
1784
+ // timeoutMs)到达后抛 code=LLM_REQUEST_TIMEOUT;generic 分支的「修本地
1785
+ // 凭据」文案在这里是错误指引(请求已发出,问题在上游无响应)。
1786
+ // 语义是 idle(静默窗):{0} 内没有任何新输出才放弃,不是说模型「完全没
1787
+ // 响应」——文案必须与这个语义一致,否则会把正在生成的用户推向重复发送
1788
+ // (2026-10 ctx-overflow-feedback review 修复 1)。
1789
+ llmRequestTimedOut: {
1790
+ en: "No new model output for {0}, so this turn was stopped. Your message was kept. Retry in this conversation, switch to another model, or run /compact first.",
1791
+ zh: "\u6A21\u578B\u5DF2 {0} \u6CA1\u6709\u65B0\u8F93\u51FA\uFF0C\u672C\u8F6E\u5DF2\u505C\u6B62\u7B49\u5F85\uFF08\u53EF\u80FD\u4ECD\u5728\u751F\u6210\uFF09\u3002\u4F60\u7684\u6D88\u606F\u5DF2\u4FDD\u7559\u3002\u53EF\u5728\u672C\u5BF9\u8BDD\u91CD\u8BD5\u3001\u5207\u6362\u5230\u5176\u4ED6\u6A21\u578B\uFF0C\u6216\u5148 /compact \u538B\u7F29\u5BF9\u8BDD\u3002"
881
1792
  },
882
- agentsTip: {
883
- en: "Tip: run /switch for the full picker, or /switch list for your private agents too.",
884
- zh: "\u63D0\u793A\uFF1A\u7528 /switch \u6253\u5F00\u5B8C\u6574\u9009\u62E9\u5668\uFF0C\u6216 /switch list \u8FDE\u4F60\u7684\u79C1\u6709\u667A\u80FD\u4F53\u4E00\u8D77\u5217\u51FA\u3002"
1793
+ // --- Local run 429/rate-limit display (compact 3-line block) --------------
1794
+ // 旧 429 文案是一条巨长英文 + 结尾拼接中文冷却说明(又长又中英混排)。现在按
1795
+ // locale 渲染 3 行:headline(含上游 tag 与清洗后的详情)+ 冷却/探测 + 出口。
1796
+ // {0} = 上游标签(antigravity · gemini-3.8-flash-tiered;取不到回退 transport 名)
1797
+ // {1} = 清洗后的上游原文(去 details= / 传输前缀 / 结尾复位句,折叠空白,≤140 字符)
1798
+ localRunRateLimitQuota: {
1799
+ en: "[nolo] Upstream quota exhausted ({0}): {1}",
1800
+ zh: "[nolo] \u4E0A\u6E38\u989D\u5EA6\u5DF2\u7528\u5C3D\uFF08{0}\uFF09\uFF1A{1}"
885
1801
  },
886
- helpText: {
887
- en: [
888
- "Commands:",
889
- " /help Show this help",
890
- " /new Clear screen and start a fresh dialog",
891
- " /compact Compact current dialog and fork a new one",
892
- " /context Show workspace context and next actions",
893
- " /cd <path> Change the working directory (takes effect on the next turn)",
894
- " /runtime <mode> Use auto, local, or server runtime",
895
- " /switch Pick an agent interactively (\u2191\u2193, Enter)",
896
- " /switch list List agents as text",
897
- " /switch <name> Switch directly by name, alias, or key (alias: /agent)",
898
- " /agents List platform agent shortcuts",
899
- " /history Pick a recent dialog to resume (\u2191\u2193, Enter)",
900
- " /resume <dialogId> Resume a dialog directly by id",
901
- " /lang <zh|en> Switch interface language",
902
- ' /copy [all] Copy the last reply (or the full conversation with "all") to the clipboard',
903
- " /paste Read the clipboard now (image \u2192 attachment, text \u2192 draft)",
904
- " /transcribe <media> Transcribe an audio/video file; transcript attaches to your next message",
905
- " Drag a file in Drop an image file on the terminal to attach it; audio/video transcribes; other files stay paths",
906
- " Shift+Enter / Ctrl+J Insert a newline in the draft",
907
- " /mouse <on|off> Toggle mouse mode (off = drag to select text)",
908
- " /auto [local|remote] <on|off> Approve one permission bucket (local-run confirms / remote-origin shell) so it stops asking; saved to your config. /auto reset clears both",
909
- " /shell-revoke Revoke this session's shell grant; the next shell call re-asks (works while a reply runs; does not interrupt a running command)",
910
- " /math <on|off> Toggle math formula rendering (Unicode transcription)",
911
- " /altscreen <on|off> Toggle the terminal alternate screen (default on; off shares shell scrollback)",
912
- " Shift+drag Select text natively even while mouse mode is on (terminal bypass)",
913
- " /doc List attached docs",
914
- " /doc attach <doc> Attach a doc to this workspace",
915
- " /skill List attached skills",
916
- " /skill attach <ref> Attach a skill (dbKey, name, or SKILL.md path)",
917
- " /skill detach <ref> Detach a skill",
918
- " /skill clear Detach all skills",
919
- " /customize Describe how you want to tune nolo",
920
- " /tasks List background process tasks (aliases: /jobs, /procs)",
921
- " /stop <pid|all> Stop background process tasks",
922
- " /login Show login/profile hint (/login --server <url> to log in here)",
923
- " /profile Show active profile",
924
- " /update Update the nolo CLI install",
925
- " /version Show version/update hint",
926
- " /logs Show recent diagnostics and the log file path",
927
- " /learn Review this dialog for reusable tool/prompt improvements",
928
- " /learn <1-100> Triage recent Evolution candidates and deep-review one",
929
- " /exit Leave the workspace",
930
- "",
931
- "You can also type normally. nolo routes simple read/status requests to CLI commands and sends the rest to the current agent."
932
- ].join("\n"),
933
- zh: [
934
- "\u547D\u4EE4\uFF1A",
935
- " /help \u663E\u793A\u672C\u5E2E\u52A9",
936
- " /new \u6E05\u5C4F\u5E76\u5F00\u59CB\u65B0\u5BF9\u8BDD",
937
- " /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\u5E76\u5206\u53C9\u51FA\u65B0\u5BF9\u8BDD",
938
- " /context \u67E5\u770B\u5DE5\u4F5C\u533A\u4E0A\u4E0B\u6587\u4E0E\u540E\u7EED\u64CD\u4F5C",
939
- " /cd <path> \u5207\u6362\u5DE5\u4F5C\u76EE\u5F55\uFF08\u4E0B\u4E2A turn \u751F\u6548\uFF09",
940
- " /runtime <mode> \u5207\u6362 runtime\uFF1Aauto\u3001local\u3001server",
941
- " /switch \u4EA4\u4E92\u5F0F\u9009\u62E9 agent\uFF08\u2191\u2193 \u79FB\u52A8\uFF0CEnter \u786E\u8BA4\uFF09",
942
- " /switch list \u4EE5\u6587\u672C\u5217\u51FA\u5168\u90E8 agent",
943
- " /switch <name> \u6309\u540D\u79F0\u3001\u522B\u540D\u6216 key \u76F4\u63A5\u5207\u6362\uFF08\u522B\u540D\uFF1A/agent\uFF09",
944
- " /agents \u5217\u51FA\u5E73\u53F0 agent \u5FEB\u6377\u65B9\u5F0F",
945
- " /history \u4ECE\u6700\u8FD1\u5BF9\u8BDD\u4E2D\u9009\u62E9\u5E76\u6062\u590D\uFF08\u2191\u2193\uFF0CEnter\uFF09",
946
- " /resume <dialogId> \u6309 id \u76F4\u63A5\u6062\u590D\u5BF9\u8BDD",
947
- " /lang <zh|en> \u5207\u6362\u754C\u9762\u8BED\u8A00",
948
- " /copy [all] \u590D\u5236\u6700\u540E\u4E00\u6761\u56DE\u590D\u5230\u526A\u8D34\u677F\uFF08\u52A0 all \u590D\u5236\u5B8C\u6574\u5BF9\u8BDD\uFF09",
949
- " /paste \u7ACB\u5373\u8BFB\u526A\u8D34\u677F\uFF08\u56FE\u7247\u2192\u9644\u4EF6\uFF0C\u6587\u672C\u2192\u8349\u7A3F\uFF09",
950
- " /transcribe <\u5A92\u4F53> \u8F6C\u5199\u97F3\u89C6\u9891\u6587\u4EF6\uFF1B\u8F6C\u5199\u6587\u672C\u968F\u4E0B\u4E00\u6761\u6D88\u606F\u53D1\u7ED9\u6A21\u578B",
951
- " \u62D6\u5165\u6587\u4EF6 \u628A\u56FE\u7247\u6587\u4EF6\u62D6\u8FDB\u7EC8\u7AEF\u5373\u6210\u4E3A\u9644\u4EF6\uFF1B\u97F3\u89C6\u9891\u81EA\u52A8\u8F6C\u5199\uFF1B\u5176\u4ED6\u6587\u4EF6\u53EA\u7559\u8DEF\u5F84",
952
- " Shift+Enter / Ctrl+J \u5728\u8349\u7A3F\u91CC\u6362\u884C",
953
- " /mouse <on|off> \u5207\u6362\u9F20\u6807\u6A21\u5F0F\uFF08off \u540E\u53EF\u76F4\u63A5\u62D6\u9009\u6587\u672C\uFF09",
954
- " /auto [local|remote] <on|off> \u6388\u6743\u67D0\u4E00\u6876\uFF08\u672C\u673A run \u786E\u8BA4 / \u8FDC\u7A0B\u6765\u6E90 shell\uFF09\u4E0D\u518D\u9010\u6B21\u8BE2\u95EE\uFF0C\u5E76\u4FDD\u5B58\u5230\u914D\u7F6E\uFF1B/auto reset \u4E24\u6876\u6E05\u96F6",
955
- " /shell-revoke \u64A4\u9500\u672C\u4F1A\u8BDD\u7684 shell \u6267\u884C\u6388\u6743\uFF0C\u4E0B\u4E00\u6B21 shell \u8C03\u7528\u91CD\u65B0\u786E\u8BA4\uFF08\u56DE\u590D\u8FDB\u884C\u4E2D\u4E5F\u53EF\u7528\uFF1B\u4E0D\u4E2D\u65AD\u5DF2\u653E\u884C\u7684\u547D\u4EE4\uFF09",
956
- " /math <on|off> \u5207\u6362\u6570\u5B66\u516C\u5F0F\u6E32\u67D3\uFF08Unicode \u8F6C\u5199\uFF09",
957
- " /altscreen <on|off> \u5207\u6362\u7EC8\u7AEF\u5907\u7528\u5C4F\uFF08\u9ED8\u8BA4 on\uFF1Boff \u6539\u4E3A\u4E0E shell \u5171\u7528\u56DE\u6EDA\uFF09",
958
- " Shift+\u62D6\u62FD \u9F20\u6807\u6A21\u5F0F\u5F00\u542F\u65F6\u4E5F\u53EF\u539F\u751F\u9009\u4E2D\u6587\u672C\uFF08\u7EC8\u7AEF\u7ED5\u8FC7\u4FEE\u9970\u952E\uFF09",
959
- " /doc \u5217\u51FA\u5DF2\u6302\u8F7D\u7684\u6587\u6863",
960
- " /doc attach <doc> \u6302\u8F7D\u6587\u6863\u5230\u5F53\u524D\u5DE5\u4F5C\u533A",
961
- " /skill \u5217\u51FA\u5DF2\u6302\u8F7D\u7684\u6280\u80FD",
962
- " /skill attach <ref> \u6302\u8F7D\u6280\u80FD\uFF08dbKey\u3001\u540D\u79F0\u6216 SKILL.md \u8DEF\u5F84\uFF09",
963
- " /skill detach <ref> \u5378\u8F7D\u6307\u5B9A\u6280\u80FD",
964
- " /skill clear \u5378\u8F7D\u5168\u90E8\u6280\u80FD",
965
- " /customize \u63CF\u8FF0\u4F60\u60F3\u600E\u4E48\u8C03\u6559 nolo",
966
- " /tasks \u5217\u51FA\u540E\u53F0\u5B50\u8FDB\u7A0B\u4EFB\u52A1\uFF08\u522B\u540D\uFF1A/jobs, /procs\uFF09",
967
- " /stop <pid|all> \u505C\u6B62\u6307\u5B9A\u7684\u540E\u53F0\u4EFB\u52A1",
968
- " /login \u67E5\u770B\u767B\u5F55 / \u914D\u7F6E\u63D0\u793A\uFF08/login --server <url> \u53EF\u5728\u672C\u4F1A\u8BDD\u5185\u767B\u5F55\uFF09",
969
- " /profile \u67E5\u770B\u5F53\u524D\u914D\u7F6E\u73AF\u5883",
970
- " /update \u66F4\u65B0 nolo CLI",
971
- " /version \u67E5\u770B\u7248\u672C\u4E0E\u66F4\u65B0\u63D0\u793A",
972
- " /logs \u67E5\u770B\u6700\u8FD1\u8BCA\u65AD\u8BB0\u5F55\u4E0E\u65E5\u5FD7\u6587\u4EF6\u4F4D\u7F6E",
973
- " /learn \u4ECE\u5F53\u524D\u5BF9\u8BDD\u590D\u76D8\u53EF\u590D\u7528\u7684\u5DE5\u5177/\u63D0\u793A\u8BCD\u6539\u8FDB",
974
- " /learn <1-100> \u7B5B\u9009\u8FD1\u671F Evolution Candidate \u5E76\u6DF1\u5EA6\u590D\u76D8\u4E00\u6761",
975
- " /exit \u9000\u51FA\u5DE5\u4F5C\u533A",
976
- "",
977
- "\u4E5F\u53EF\u4EE5\u76F4\u63A5\u8F93\u5165\u81EA\u7136\u8BED\u8A00\u3002\u7B80\u5355\u7684\u8BFB\u53D6/\u72B6\u6001\u8BF7\u6C42\u4F1A\u8D70 CLI \u547D\u4EE4\uFF0C\u5176\u4F59\u4EA4\u7ED9\u5F53\u524D agent\u3002"
978
- ].join("\n")
1802
+ localRunRateLimitThrottled: {
1803
+ en: "[nolo] Upstream rate limit ({0}): {1}",
1804
+ zh: "[nolo] \u4E0A\u6E38\u9650\u6D41\uFF08{0}\uFF09\uFF1A{1}"
979
1805
  },
980
- // --- Slash-command output ---------------------------------------------
981
- // Command results that used to be hardcoded English. Usage lines keep the
982
- // command literal untouched; only the surrounding words are translated.
983
- unknownCommand: {
984
- en: "Unknown command: {0}\n\n",
985
- zh: "\u672A\u77E5\u547D\u4EE4\uFF1A{0}\n\n"
1806
+ // 上游明确表示「服务容量饱和」(如 Codex 的 "is at capacity")。这与账号额度
1807
+ // 无关,用「额度」措辞会让人误以为是自己配额用完了。单独一档。
1808
+ localRunRateLimitCapacity: {
1809
+ en: "[nolo] Upstream service at capacity ({0}): {1}",
1810
+ zh: "[nolo] \u4E0A\u6E38\u670D\u52A1\u5BB9\u91CF\u9971\u548C\uFF08{0}\uFF09\uFF1A{1}"
986
1811
  },
987
- noConversationLinks: {
988
- en: "No links in this conversation yet.",
989
- zh: "\u672C\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u51FA\u73B0\u94FE\u63A5\u3002"
1812
+ // 第 2 行复位提示:沿用 extractRateLimitResetHint 抓到的上游原文(不换算),
1813
+ // 只作括号补充;没抓到就没有这段括号。
1814
+ localRunRateLimitResetNote: {
1815
+ en: " (upstream reset in {0})",
1816
+ zh: "\uFF08\u4E0A\u6E38\u7EA6 {0}\u540E\u590D\u4F4D\uFF09"
990
1817
  },
991
- conversationLinksCopyHint: {
992
- en: "Open one by copying its URL (Cmd/Ctrl + click, or select and copy).",
993
- zh: "\u590D\u5236\u5BF9\u5E94 URL \u5373\u53EF\u6253\u5F00\uFF08Cmd/Ctrl + \u70B9\u51FB\uFF0C\u6216\u9009\u4E2D\u590D\u5236\uFF09\u3002"
1818
+ // 第 2 行:{0} = 冷却截止(本地时间,当天 HH:MM / 跨天 MM-DD HH:MM),
1819
+ // {1} = 复位提示或空串,{2} = 自动探测间隔(分钟)。无 cooldownUntil 时整行省略。
1820
+ localRunRateLimitCooldown: {
1821
+ en: " Cooldown until {0}{1}; auto-probing every {2} min meanwhile (the upstream may not be restored by then).",
1822
+ zh: " \u51B7\u5374\u81F3 {0}{1}\uFF1B\u671F\u95F4\u6BCF {2} \u5206\u949F\u81EA\u52A8\u8BD5\u63A2\u4E00\u6B21\uFF08\u4E0A\u6E38\u672A\u5FC5\u5C4A\u65F6\u6062\u590D\uFF09\u3002"
994
1823
  },
995
- conversationLinksShowing: {
996
- en: "Links in this conversation (showing first {0} of {1}):",
997
- zh: "\u672C\u4F1A\u8BDD\u51FA\u73B0\u7684\u94FE\u63A5\uFF08\u663E\u793A\u524D {0} \u4E2A\uFF0C\u5171 {1} \u4E2A\uFF09\uFF1A"
1824
+ // 第 3 行:三个出口(换 agent / 强制走服务器 / 已充值清冷却)。
1825
+ localRunRateLimitExits: {
1826
+ en: " Switch agent: nolo agent list; force server: --server; topped up: nolo auth cooldown, then --clear <credential>",
1827
+ zh: " \u6362 agent\uFF1Anolo agent list\uFF1B\u5F3A\u5236\u8D70\u670D\u52A1\u5668\uFF1A--server\uFF1B\u5DF2\u5145\u503C\uFF1Anolo auth cooldown \u67E5\u51ED\u8BC1\u540D\u540E --clear <\u51ED\u8BC1\u540D>"
998
1828
  },
999
- runtimeUsage: { en: "Usage: /runtime <auto|local|server>", zh: "\u7528\u6CD5\uFF1A/runtime <auto|local|server>" },
1000
- runtimeSet: { en: "Runtime: {0}", zh: "\u8FD0\u884C\u6A21\u5F0F\uFF1A{0}" },
1001
- logsEmpty: {
1002
- en: "No diagnostics recorded in this session.",
1003
- zh: "\u672C\u6B21\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u8BCA\u65AD\u8BB0\u5F55\u3002"
1829
+ // --- Local run 402/余额不足 display (compact 3-line block) ----------------
1830
+ // 与 429 同结构:headline(余额不足 / Coding Plan 额度用尽 + 上游 tag)+ 复位
1831
+ // 时刻(仅当报文确实给了 reset_at)+ 出口。{0} = 上游标签(provider · model,
1832
+ // 取不到回退 transport 名),{1} = 清洗后的原因(或定量原因)。
1833
+ localRunBalanceExhausted: {
1834
+ en: "[nolo] Insufficient balance, cannot continue ({0}): {1}",
1835
+ zh: "[nolo] \u4F59\u989D\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u7EE7\u7EED\uFF08{0}\uFF09\uFF1A{1}"
1836
+ },
1837
+ // 报文带 coding_plan_exhausted 时的措辞:计划额度与钱包余额是两笔要分别充的账。
1838
+ localRunBalanceCodingPlan: {
1839
+ en: "[nolo] Coding Plan quota exhausted and the wallet balance is insufficient ({0}): {1}",
1840
+ zh: "[nolo] Coding Plan \u989D\u5EA6\u5DF2\u7528\u5C3D\u4E14\u94B1\u5305\u4F59\u989D\u4E0D\u8DB3\uFF08{0}\uFF09\uFF1A{1}"
1841
+ },
1842
+ // 第 2 行:{0} = 计划额度复位时刻(本地时间)。报文没给复位时刻时整行省略。
1843
+ localRunBalanceReset: {
1844
+ en: " Plan quota resets at {0} \u2014 this restores the plan quota only; it does not top up your wallet.",
1845
+ zh: " \u8BA1\u5212\u989D\u5EA6 {0} \u590D\u4F4D\u2014\u2014\u53EA\u6062\u590D\u8BA1\u5212\u989D\u5EA6\uFF0C\u4E0D\u4F1A\u7ED9\u94B1\u5305\u5145\u503C\u3002"
1846
+ },
1847
+ // 清洗后仍取不到原因(报文只有 `{"error":{}}` 这类空壳)时的兜底:避免悬空冒号。
1848
+ localRunBalanceUnknownReason: {
1849
+ en: "the provider returned a payment-required error without a reason line",
1850
+ zh: "\u4E0A\u6E38\u53EA\u8FD4\u56DE\u4E86\u300C\u9700\u8981\u4ED8\u6B3E\u300D\u9519\u8BEF\uFF0C\u6CA1\u6709\u7ED9\u51FA\u539F\u56E0"
1851
+ },
1852
+ // 第 3 行:出口(充值后重发 / 换 agent / 强制走服务器)。刻意不重复 TUI 那句
1853
+ //「你刚发的话已保存在当前对话里」。
1854
+ localRunBalanceExits: {
1855
+ en: " Top up and send again; or switch agent: nolo agent list; force server: --server",
1856
+ zh: " \u5145\u503C\u540E\u91CD\u53D1\u5373\u53EF\uFF1B\u6216\u6362 agent\uFF1Anolo agent list\uFF1B\u5F3A\u5236\u8D70\u670D\u52A1\u5668\uFF1A--server"
1857
+ },
1858
+ thinkingTraceLine: {
1859
+ en: "\u273B Thought for {0}",
1860
+ zh: "\u273B \u601D\u8003 {0}"
1861
+ },
1862
+ usedSkillLabel: {
1863
+ en: "Used Skill",
1864
+ zh: "\u5DF2\u52A0\u8F7D\u6280\u80FD"
1865
+ },
1866
+ // Background-process rows in the same zone (`❯ npm run dev · 已运行 3m · pid 123`).
1867
+ // The pid is how the user targets /stop, so it is a fact, not decoration.
1868
+ procZonePid: { en: "pid {0}", zh: "pid {0}" },
1869
+ // 残留行(进程已退出):running 用 `已运行`,退出的说「用时」,因为它不再走秒。
1870
+ procZoneTook: { en: "took {0}", zh: "\u7528\u65F6 {0}" },
1871
+ procZoneExit: { en: "exit {0}", zh: "exit {0}" },
1872
+ // --- Dialog (picker / confirm) copy --------------------------------------
1873
+ // Key-hint wording is unified across select / multi-select / confirm so the
1874
+ // three dialogs read as one family: "<Label> <↑↓ move · Enter choose ·
1875
+ // Esc cancel> <count>". Connectors are "·" between keys, two spaces between
1876
+ // the label, hint, and count. zh uses full-width parentheses to match the
1877
+ // existing historyPickerTitle; en uses ASCII parentheses.
1878
+ dialogSelectLabel: {
1879
+ en: "Select",
1880
+ zh: "\u9009\u62E9"
1881
+ },
1882
+ dialogSelectHint: {
1883
+ en: "(\u2191\u2193 move \xB7 Enter choose \xB7 Esc cancel)",
1884
+ zh: "\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
1885
+ },
1886
+ dialogMultiSelectLabel: {
1887
+ en: "Select",
1888
+ zh: "\u9009\u62E9"
1889
+ },
1890
+ dialogMultiSelectHint: {
1891
+ en: "(\u2191\u2193 move \xB7 Space toggle \xB7 Enter submit \xB7 Esc cancel)",
1892
+ zh: "\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Space \u5207\u6362 \xB7 Enter \u63D0\u4EA4 \xB7 Esc \u53D6\u6D88\uFF09"
1004
1893
  },
1005
- logsHeader: {
1006
- en: "Recent diagnostics ({0} of {1}) \xB7 full log: {2}",
1007
- zh: "\u6700\u8FD1\u8BCA\u65AD\uFF08{0}/{1} \u6761\uFF09\xB7 \u5B8C\u6574\u65E5\u5FD7\uFF1A{2}"
1894
+ dialogMultiSelectSelected: {
1895
+ en: "selected",
1896
+ zh: "\u5DF2\u9009"
1008
1897
  },
1009
- tasksRunning: { en: "Running processes ({0}):", zh: "\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\uFF08{0}\uFF09\uFF1A" },
1010
- tasksStopped: { en: "Stopped/exited ({0}):", zh: "\u5DF2\u505C\u6B62/\u5DF2\u9000\u51FA\uFF08{0}\uFF09\uFF1A" },
1011
- tasksNone: { en: "No processes.", zh: "\u6CA1\u6709\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\u3002" },
1012
- stopUsage: { en: "Usage: /stop <pid|label|all>", zh: "\u7528\u6CD5\uFF1A/stop <pid|label|all>" },
1013
- stopAllDone: { en: "Stopped {0} processes", zh: "\u5DF2\u505C\u6B62 {0} \u4E2A\u8FDB\u7A0B" },
1014
- stopNoPid: { en: "No running process with pid {0}", zh: "\u6CA1\u6709 pid \u4E3A {0} \u7684\u8FD0\u884C\u4E2D\u8FDB\u7A0B" },
1015
- stopPidDone: { en: "Stopped pid {0} ({1})", zh: "\u5DF2\u505C\u6B62 pid {0}\uFF08{1}\uFF09" },
1016
- stopNoLabel: { en: "No running process labeled '{0}'", zh: "\u6CA1\u6709\u540D\u4E3A\u201C{0}\u201D\u7684\u8FD0\u884C\u4E2D\u8FDB\u7A0B" },
1017
- stopLabelsDone: { en: "Stopped {0}", zh: "\u5DF2\u505C\u6B62 {0}" },
1018
- compactNothing: {
1019
- en: "Current dialog: new (nothing to compact yet)",
1020
- zh: "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u662F\u65B0\u7684\uFF08\u8FD8\u6CA1\u6709\u53EF\u538B\u7F29\u7684\u5185\u5BB9\uFF09"
1898
+ dialogMultiSelectRequired: {
1899
+ en: "Pick at least one option to submit",
1900
+ zh: "\u81F3\u5C11\u9009\u62E9\u4E00\u9879\u624D\u80FD\u63D0\u4EA4"
1021
1901
  },
1022
- compactingDialog: {
1023
- en: "Compacting current dialog...",
1024
- zh: "\u6B63\u5728\u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\u2026"
1902
+ dialogConfirmHint: {
1903
+ en: "(\u2191\u2193 move \xB7 Enter choose \xB7 Esc cancel)",
1904
+ zh: "\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
1025
1905
  },
1026
- compactPhaseReading: {
1027
- en: "Reading dialog messages\u2026",
1028
- zh: "\u6B63\u5728\u8BFB\u53D6\u5BF9\u8BDD\u6D88\u606F\u2026"
1906
+ dialogConfirmTitle: {
1907
+ en: "Allow destructive shell commands from local runs?",
1908
+ zh: "\u5141\u8BB8\u672C\u673A run \u6267\u884C\u7834\u574F\u6027 shell \u547D\u4EE4\u5417\uFF1F"
1029
1909
  },
1030
- compactPhaseSummarizing: {
1031
- en: "Generating summary\u2026",
1032
- zh: "\u6B63\u5728\u751F\u6210\u603B\u7ED3\u2026"
1910
+ dialogConfirmBody: {
1911
+ en: "This command may delete or reset user content \u2014 a local-run destructive shell command.",
1912
+ zh: "\u8BE5\u547D\u4EE4\u53EF\u80FD\u5220\u9664\u6216\u91CD\u7F6E\u7528\u6237\u5185\u5BB9\uFF0C\u5C5E\u4E8E\u672C\u673A run \u7684\u7834\u574F\u6027 shell \u547D\u4EE4\u3002"
1033
1913
  },
1034
- compactPhaseForking: {
1035
- en: "Forking dialog\u2026",
1036
- zh: "\u6B63\u5728\u5206\u53C9\u65B0\u5BF9\u8BDD\u2026"
1914
+ dialogConfirmExternalFileTitle: {
1915
+ en: "Allow reading files outside the workspace?",
1916
+ zh: "\u5141\u8BB8\u8BFB\u53D6\u5DE5\u4F5C\u533A\u5916\u90E8\u6587\u4EF6\u5417\uFF1F"
1037
1917
  },
1038
- compactFailed: {
1039
- en: "Compact failed: {0}",
1040
- zh: "\u538B\u7F29\u5931\u8D25\uFF1A{0}"
1918
+ dialogConfirmExternalFileBody: {
1919
+ en: "This path is outside the current workspace \u2014 a local-run outside-workspace file access.",
1920
+ zh: "\u8BE5\u8DEF\u5F84\u4F4D\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u4E4B\u5916\uFF0C\u5C5E\u4E8E\u672C\u673A run \u7684\u5DE5\u4F5C\u533A\u5916\u6587\u4EF6\u8BBF\u95EE\u3002"
1041
1921
  },
1042
- contextLengthExceeded: {
1043
- en: "Model context limit reached (requested {0} tokens / limit {1}). Suggest using /compact to compact current dialog, or /new to start a fresh dialog.",
1044
- zh: "\u5DF2\u8FBE\u6A21\u578B\u4E0A\u4E0B\u6587\u4E0A\u9650\uFF08\u8BF7\u6C42 {0} tokens / \u4E0A\u9650 {1}\uFF09\u3002\u5EFA\u8BAE\u4F7F\u7528 /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\uFF0C\u6216\u4F7F\u7528 /new \u5F00\u59CB\u65B0\u5BF9\u8BDD\u3002"
1922
+ dialogConfirmFileWriteTitle: {
1923
+ en: "Allow writing files from local runs?",
1924
+ zh: "\u5141\u8BB8\u672C\u673A run \u5199\u5165\u6587\u4EF6\u5417\uFF1F"
1045
1925
  },
1046
- contextLengthExceededLimitOnly: {
1047
- en: "Model context limit reached (limit {0}). Suggest using /compact to compact current dialog, or /new to start a fresh dialog.",
1048
- zh: "\u5DF2\u8FBE\u6A21\u578B\u4E0A\u4E0B\u6587\u4E0A\u9650\uFF08\u4E0A\u9650 {0}\uFF09\u3002\u5EFA\u8BAE\u4F7F\u7528 /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\uFF0C\u6216\u4F7F\u7528 /new \u5F00\u59CB\u65B0\u5BF9\u8BDD\u3002"
1926
+ dialogConfirmFileWriteBody: {
1927
+ en: "This action writes into the workspace \u2014 a local-run file-write confirmation.",
1928
+ zh: "\u8BE5\u64CD\u4F5C\u4F1A\u5199\u5165\u5DE5\u4F5C\u533A\u6587\u4EF6\uFF0C\u5C5E\u4E8E\u672C\u673A run \u7684\u5199\u6587\u4EF6\u786E\u8BA4\u3002"
1049
1929
  },
1050
- contextLengthExceededGeneric: {
1051
- en: "Model context limit reached. Suggest using /compact to compact current dialog, or /new to start a fresh dialog.",
1052
- zh: "\u5DF2\u8FBE\u6A21\u578B\u4E0A\u4E0B\u6587\u4E0A\u9650\u3002\u5EFA\u8BAE\u4F7F\u7528 /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\uFF0C\u6216\u4F7F\u7528 /new \u5F00\u59CB\u65B0\u5BF9\u8BDD\u3002"
1930
+ dialogConfirmRememberLocal: {
1931
+ en: "Approving covers all three local-run classes (destructive shell / outside-workspace files / file writes) and is saved, so they stop asking \u2014 this session and future starts. Undo with /auto local off or /auto reset.",
1932
+ zh: "\u6279\u51C6\u540E\u672C\u673A run \u7684\u4E09\u7C7B\u786E\u8BA4\uFF08\u7834\u574F\u6027\u547D\u4EE4 / \u5DE5\u4F5C\u533A\u5916\u6587\u4EF6 / \u5199\u6587\u4EF6\uFF09\u90FD\u4E0D\u518D\u8BE2\u95EE\uFF0C\u5E76\u4FDD\u5B58\u5230\u914D\u7F6E\uFF08\u672C\u6B21\u4E0E\u540E\u7EED\u542F\u52A8\u90FD\u751F\u6548\uFF09\u3002\u64A4\u9500\u7528 /auto local off \u6216 /auto reset\u3002"
1053
1933
  },
1054
- compactDone: {
1055
- en: "Compacted dialog {0} \u2192 {1}.",
1056
- zh: "\u5DF2\u538B\u7F29\u5BF9\u8BDD {0} \u2192 {1}\u3002"
1934
+ dialogConfirmCommandTruncated: {
1935
+ en: "(truncated)",
1936
+ zh: "\uFF08\u5DF2\u622A\u65AD\uFF09"
1057
1937
  },
1058
- compactDoneNoSummary: {
1059
- en: "Forked dialog {0} \u2192 {1} (no summary needed).",
1060
- zh: "\u5DF2\u5206\u53C9\u5BF9\u8BDD {0} \u2192 {1}\uFF08\u65E0\u9700\u538B\u7F29\uFF09\u3002"
1938
+ dialogConfirmAllowLabel: {
1939
+ en: "Approve & remember",
1940
+ zh: "\u6279\u51C6\u5E76\u8BB0\u4F4F"
1061
1941
  },
1062
- compactSuccess: {
1063
- en: "\u2713 Compacted dialog {0} \u2192 {1} in {2}.",
1064
- zh: "\u2713 \u5DF2\u538B\u7F29\u5BF9\u8BDD {0} \u2192 {1}\uFF0C\u8017\u65F6 {2}\u3002"
1942
+ dialogConfirmAllowDetail: {
1943
+ en: "stop asking for this class (saved)",
1944
+ zh: "\u540C\u7C7B\u786E\u8BA4\u4E0D\u518D\u8BE2\u95EE\uFF08\u5DF2\u4FDD\u5B58\uFF09"
1065
1945
  },
1066
- compactSuccessWithCount: {
1067
- en: "\u2713 Compacted dialog {0} \u2192 {1} in {2} ({3} messages compressed).",
1068
- zh: "\u2713 \u5DF2\u538B\u7F29\u5BF9\u8BDD {0} \u2192 {1}\uFF0C\u8017\u65F6 {2}\uFF08\u538B\u7F29 {3} \u6761\u6D88\u606F\uFF09\u3002"
1946
+ dialogConfirmCancelLabel: {
1947
+ en: "Reject",
1948
+ zh: "\u62D2\u7EDD"
1069
1949
  },
1070
- compactForked: {
1071
- en: "\u2713 Forked dialog {0} \u2192 {1} in {2} (no summary needed).",
1072
- zh: "\u2713 \u5DF2\u5206\u53C9\u5BF9\u8BDD {0} \u2192 {1}\uFF0C\u8017\u65F6 {2}\uFF08\u65E0\u9700\u538B\u7F29\uFF09\u3002"
1950
+ dialogConfirmCancelDetail: {
1951
+ en: "do not run it; ask again next time",
1952
+ zh: "\u4E0D\u6267\u884C\uFF0C\u4E0B\u6B21\u4ECD\u4F1A\u8BE2\u95EE"
1073
1953
  },
1074
- agentCurrent: { en: "Current agent: {0} ({1})", zh: "\u5F53\u524D agent\uFF1A{0}\uFF08{1}\uFF09" },
1075
- agentPinnedUnaudited: {
1076
- en: "No audit record for it \u2014 an older build wrote it; see agent-selection.log.",
1077
- zh: "\u8FD9\u6761\u8BB0\u5F55\u6CA1\u6709\u5BA1\u8BA1\u8BB0\u5F55\uFF0C\u662F\u65E7\u7248\u672C\u5199\u7684\uFF1B\u8BE6\u89C1 agent-selection.log\u3002"
1954
+ contextTitle: {
1955
+ en: "Workspace context",
1956
+ zh: "\u5DE5\u4F5C\u533A\u4E0A\u4E0B\u6587"
1078
1957
  },
1079
- agentPinnedAuditRotated: {
1080
- en: "The audit log has no entry for it \u2014 it aged out, or another session wrote it.",
1081
- zh: "\u5BA1\u8BA1\u65E5\u5FD7\u91CC\u6CA1\u6709\u5B83\u7684\u8BB0\u5F55\u2014\u2014\u53EF\u80FD\u5DF2\u88AB\u8F6E\u8F6C\uFF0C\u6216\u662F\u522B\u7684\u4F1A\u8BDD\u5199\u7684\u3002"
1958
+ contextNext: {
1959
+ en: "Next:",
1960
+ zh: "\u4E0B\u4E00\u6B65\uFF1A"
1082
1961
  },
1083
- agentPinnedFromProfile: {
1084
- en: 'Agent "{0}" restored from {1} (saved selection). /switch nolo to go back to the default.',
1085
- zh: "agent\u201C{0}\u201D\u6765\u81EA {1} \u91CC\u4FDD\u5B58\u7684\u9009\u62E9\u3002/switch nolo \u53EF\u5207\u56DE\u9ED8\u8BA4\u6863\u3002"
1962
+ contextFieldAgent: {
1963
+ en: "agent",
1964
+ zh: "\u667A\u80FD\u4F53"
1086
1965
  },
1087
- agentUnknown: {
1088
- en: `I don't know agent "{0}" yet.
1089
- Use /switch, /switch list, /switch minimax-m3, or a full agent key.`,
1090
- zh: "\u8FD8\u4E0D\u8BA4\u8BC6 agent\u201C{0}\u201D\u3002\n\u53EF\u4EE5\u7528 /switch\u3001/switch list\u3001/switch minimax-m3 \u6216\u5B8C\u6574\u7684 agent key \u6765\u5207\u6362\u3002"
1966
+ contextFieldTokens: {
1967
+ en: "tokens",
1968
+ zh: "\u4EE4\u724C"
1091
1969
  },
1092
- themeCurrent: { en: "Current theme: {0} \xB7 {1}", zh: "\u5F53\u524D\u4E3B\u9898\uFF1A{0} \xB7 {1}" },
1093
- themeUsage: {
1094
- en: "Usage: /theme <name> | /theme terminal | /theme light | /theme dark | /theme refresh",
1095
- zh: "\u7528\u6CD5\uFF1A/theme <name> | /theme terminal | /theme light | /theme dark | /theme refresh"
1970
+ contextFieldDialog: {
1971
+ en: "dialog",
1972
+ zh: "\u5BF9\u8BDD"
1096
1973
  },
1097
- themeAvailable: { en: "Available themes: {0}", zh: "\u53EF\u7528\u4E3B\u9898\uFF1A{0}" },
1098
- themeBrightnessSwitched: { en: "Switched to {0} background colors.", zh: "\u5DF2\u5207\u6362\u5230 {0} \u80CC\u666F\u8272\u3002" },
1099
- themeBrightnessAuto: {
1100
- en: "Theme now follows terminal colors (/theme auto is an alias).",
1101
- zh: "\u4E3B\u9898\u5DF2\u8DDF\u968F\u7EC8\u7AEF\u914D\u8272\uFF08/theme auto \u4E3A\u517C\u5BB9\u522B\u540D\uFF09\u3002"
1974
+ contextFieldDocs: {
1975
+ en: "docs",
1976
+ zh: "\u6587\u6863"
1102
1977
  },
1103
- themeRefreshed: {
1104
- en: "Re-detected terminal background: {0}.",
1105
- zh: "\u5DF2\u91CD\u65B0\u68C0\u6D4B\u7EC8\u7AEF\u80CC\u666F\uFF1A{0}\u3002"
1978
+ contextFieldSkills: {
1979
+ en: "skills",
1980
+ zh: "\u6280\u80FD"
1106
1981
  },
1107
- themeRefreshFailed: {
1108
- en: "Could not detect terminal background (not a TTY or no response).",
1109
- zh: "\u65E0\u6CD5\u68C0\u6D4B\u7EC8\u7AEF\u80CC\u666F\uFF08\u975E TTY \u6216\u7EC8\u7AEF\u65E0\u54CD\u5E94\uFF09\u3002"
1982
+ contextFieldProfile: {
1983
+ en: "profile",
1984
+ zh: "\u914D\u7F6E"
1110
1985
  },
1111
- themeSwitched: { en: "Switched to theme: {0}", zh: "\u5DF2\u5207\u6362\u5230\u4E3B\u9898\uFF1A{0}" },
1112
- themeUnknown: { en: "Unknown theme: {0}. Available themes: {1}", zh: "\u672A\u77E5\u4E3B\u9898\uFF1A{0}\u3002\u53EF\u7528\u4E3B\u9898\uFF1A{1}" },
1113
- cdUsage: {
1114
- en: "Usage: /cd <path> (relative, absolute, ~, or -; takes effect on the next turn)",
1115
- zh: "\u7528\u6CD5\uFF1A/cd <path>\uFF08\u76F8\u5BF9\u3001\u7EDD\u5BF9\u3001~ \u6216 - \u8DEF\u5F84\uFF1B\u4E0B\u4E2A turn \u751F\u6548\uFF09"
1986
+ contextFieldRuntime: {
1987
+ en: "runtime",
1988
+ zh: "\u8FD0\u884C\u65F6"
1116
1989
  },
1117
- cdCurrent: { en: "Current directory: {0}", zh: "\u5F53\u524D\u76EE\u5F55\uFF1A{0}" },
1118
- cdSwitched: { en: "Working directory: {0}", zh: "\u5DE5\u4F5C\u76EE\u5F55\uFF1A{0}" },
1119
- cdNotFound: { en: "Directory not found: {0}", zh: "\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A{0}" },
1120
- cdNotDir: { en: "Not a directory: {0}", zh: "\u4E0D\u662F\u76EE\u5F55\uFF1A{0}" },
1121
- cdNoPrevious: { en: "No previous directory.", zh: "\u6CA1\u6709\u4E0A\u4E00\u4E2A\u76EE\u5F55\u3002" },
1122
- cdSwitchedMessage: {
1123
- en: "Working directory changed: {0} \u2192 {1}. Subsequent tool execution and file operations use the new directory.",
1124
- zh: "\u5DE5\u4F5C\u76EE\u5F55\u5DF2\u5207\u6362\uFF1A{0} \u2192 {1}\u3002\u540E\u7EED\u5DE5\u5177\u6267\u884C\u4E0E\u6587\u4EF6\u64CD\u4F5C\u4EE5\u65B0\u76EE\u5F55\u4E3A\u51C6\u3002"
1990
+ contextFieldServer: {
1991
+ en: "server",
1992
+ zh: "\u670D\u52A1\u7AEF"
1125
1993
  },
1126
- docAttachUsage: { en: "Usage: /doc attach <doc>", zh: "\u7528\u6CD5\uFF1A/doc attach <doc>" },
1127
- docList: { en: "Attached docs: {0}", zh: "\u5DF2\u6302\u8F7D\u6587\u6863\uFF1A{0}" },
1128
- docNone: { en: "No docs attached. Use /doc attach <doc>.", zh: "\u8FD8\u6CA1\u6709\u6302\u8F7D\u6587\u6863\u3002\u7528 /doc attach <doc> \u6302\u8F7D\u3002" },
1129
- skillAttachUsage: { en: "Usage: /skill attach <skill-ref>", zh: "\u7528\u6CD5\uFF1A/skill attach <skill-ref>" },
1130
- skillAttached: { en: "Attached skill: {0}", zh: "\u5DF2\u6302\u8F7D\u6280\u80FD\uFF1A{0}" },
1131
- skillDetachUsage: { en: "Usage: /skill detach <skill-ref>", zh: "\u7528\u6CD5\uFF1A/skill detach <skill-ref>" },
1132
- skillDetached: { en: "Detached skill: {0}", zh: "\u5DF2\u5378\u8F7D\u6280\u80FD\uFF1A{0}" },
1133
- skillNotAttached: { en: "Skill not attached: {0}", zh: "\u6280\u80FD\u672A\u6302\u8F7D\uFF1A{0}" },
1134
- skillNone: { en: "No skills attached.", zh: "\u8FD8\u6CA1\u6709\u6302\u8F7D\u6280\u80FD\u3002" },
1135
- skillCleared: { en: "Cleared {0} skill(s).", zh: "\u5DF2\u6E05\u7A7A {0} \u4E2A\u6280\u80FD\u3002" },
1136
- skillList: {
1137
- en: "Attached skills: {0}\nUsage: /skill attach <ref> | /skill detach <ref> | /skill clear",
1138
- zh: "\u5DF2\u6302\u8F7D\u6280\u80FD\uFF1A{0}\n\u7528\u6CD5\uFF1A/skill attach <ref> | /skill detach <ref> | /skill clear"
1994
+ contextNextAgents: {
1995
+ en: "see specialist shortcuts",
1996
+ zh: "\u67E5\u770B\u4E13\u7528\u667A\u80FD\u4F53\u5FEB\u6377\u65B9\u5F0F"
1139
1997
  },
1140
- skillNoneHint: {
1141
- en: "No skills attached. Use /skill attach <skill-ref> to attach a skill.\nSkill refs can be a dbKey (page-xxx), a skill name (searched in .agents/skills/), or a direct path.",
1142
- zh: "\u8FD8\u6CA1\u6709\u6302\u8F7D\u6280\u80FD\u3002\u7528 /skill attach <skill-ref> \u6302\u8F7D\u6280\u80FD\u3002\n\u6280\u80FD\u5F15\u7528\u53EF\u4EE5\u662F dbKey\uFF08page-xxx\uFF09\u3001\u6280\u80FD\u540D\uFF08\u4F1A\u5728 .agents/skills/ \u4E2D\u67E5\u627E\uFF09\u6216\u76F4\u63A5\u8DEF\u5F84\u3002"
1998
+ contextNextDoc: {
1999
+ en: "add working context",
2000
+ zh: "\u6DFB\u52A0\u5DE5\u4F5C\u4E0A\u4E0B\u6587"
1143
2001
  },
1144
- customizeHint: {
1145
- en: "Tell nolo what to change, for example: /customize make my default agent more concise.",
1146
- zh: "\u544A\u8BC9 nolo \u4F60\u60F3\u6539\u4EC0\u4E48\uFF0C\u4F8B\u5982\uFF1A/customize make my default agent more concise\u3002"
2002
+ contextNextSkill: {
2003
+ en: "attach a skill to this workspace",
2004
+ zh: "\u4E3A\u8BE5\u5DE5\u4F5C\u533A\u6302\u8F7D\u6280\u80FD"
1147
2005
  },
1148
- /** @deprecated No longer used by `/login` (now runs the in-TUI login flow). Kept to avoid structural churn. */
1149
- loginHint: {
1150
- en: "MVP login uses profile/env auth. Set AUTH_TOKEN, NOLO_SERVER, or NOLO_PROFILE before starting nolo.",
1151
- zh: "MVP \u767B\u5F55\u8D70 profile/\u73AF\u5883\u53D8\u91CF\u8BA4\u8BC1\u3002\u542F\u52A8 nolo \u524D\u8BF7\u8BBE\u7F6E AUTH_TOKEN\u3001NOLO_SERVER \u6216 NOLO_PROFILE\u3002"
2006
+ contextNextNew: {
2007
+ en: "start a clean dialog",
2008
+ zh: "\u5F00\u59CB\u4E00\u4E2A\u5E72\u51C0\u7684\u5BF9\u8BDD"
1152
2009
  },
1153
- /** @deprecated No longer used by `/login` (now runs the in-TUI login flow). Kept to avoid structural churn. */
1154
- loginTuiStart: {
1155
- en: "Or run `/login --server <url>` to log in right here (opens a browser authorization URL), or exit and run `nolo login`.",
1156
- zh: "\u4E5F\u53EF\u4EE5\u6267\u884C /login --server <url> \u76F4\u63A5\u5728\u8FD9\u91CC\u767B\u5F55\uFF08\u4F1A\u7ED9\u51FA\u6D4F\u89C8\u5668\u6388\u6743\u94FE\u63A5\uFF09\uFF0C\u6216\u9000\u51FA\u540E\u8FD0\u884C `nolo login`\u3002"
2010
+ // --- Paste / clipboard ------------------------------------------------
2011
+ pasteUsage: {
2012
+ en: "Usage: /paste (no arguments). Reads your clipboard now: an image becomes an attachment, text lands in the draft. Tip: dragging an image file onto the terminal is the most reliable way to attach a picture.",
2013
+ zh: "\u7528\u6CD5\uFF1A/paste\uFF08\u65E0\u53C2\u6570\uFF09\u3002\u7ACB\u5373\u8BFB\u53D6\u526A\u8D34\u677F\uFF1A\u56FE\u7247\u53D8\u9644\u4EF6\uFF0C\u6587\u672C\u8FDB\u8349\u7A3F\u3002\u63D0\u793A\uFF1A\u628A\u56FE\u7247\u6587\u4EF6\u62D6\u8FDB\u7EC8\u7AEF\u662F\u9644\u4E0A\u56FE\u7247\u6700\u53EF\u9760\u7684\u65B9\u5F0F\u3002"
1157
2014
  },
1158
- loginUsage: {
1159
- en: "Usage: /login [--server <url>]. Unsupported flags: {0}",
1160
- zh: "\u7528\u6CD5\uFF1A/login [--server <url>]\u3002\u4E0D\u652F\u6301\u7684\u53C2\u6570\uFF1A{0}"
2015
+ pasteTextInserted: {
2016
+ en: "Pasted {0} characters from the clipboard into the draft.",
2017
+ zh: "\u5DF2\u4ECE\u526A\u8D34\u677F\u7C98\u8D34 {0} \u4E2A\u5B57\u7B26\u5230\u8349\u7A3F\u3002"
1161
2018
  },
1162
- loginStarted: {
1163
- en: "Open this URL to authorize nolo-cli:\n{0}\nCode: {1}",
1164
- zh: "\u6253\u5F00\u8FD9\u4E2A\u94FE\u63A5\u6388\u6743 nolo-cli\uFF1A\n{0}\n\u6388\u6743\u7801\uFF1A{1}"
2019
+ pasteStaleDropped: {
2020
+ en: "Discarded a clipboard read that finished after the draft changed.",
2021
+ zh: "\u526A\u8D34\u677F\u8BFB\u53D6\u5B8C\u6210\u65F6\u8349\u7A3F\u5DF2\u53D8\u5316\uFF0C\u7ED3\u679C\u5DF2\u4E22\u5F03\u3002"
1165
2022
  },
1166
- loginBrowserFailed: {
1167
- en: "Could not open a browser automatically. Paste the URL above into a browser.",
1168
- zh: "\u65E0\u6CD5\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u628A\u4E0A\u9762\u7684\u94FE\u63A5\u7C98\u8D34\u5230\u6D4F\u89C8\u5668\u91CC\u3002"
2023
+ pasteFilePathHint: {
2024
+ en: "file reference (path only, content not read): {0}",
2025
+ zh: "\u6587\u4EF6\u5F15\u7528\uFF08\u4EC5\u8DEF\u5F84\uFF0C\u672A\u8BFB\u53D6\u5185\u5BB9\uFF09\uFF1A{0}"
1169
2026
  },
1170
- loginWaiting: {
1171
- en: "Waiting for browser authorization ({0} remaining)... (Ctrl+C to cancel)",
1172
- zh: "\u7B49\u5F85\u6D4F\u89C8\u5668\u6388\u6743\uFF08\u5269\u4F59 {0}\uFF09\u2026\u2026\u6309 Ctrl+C \u53D6\u6D88"
2027
+ mediaFoundHint: {
2028
+ en: "\u{1F3A7} found media (will transcribe): {0}",
2029
+ zh: "\u{1F3A7} \u8BC6\u522B\u5230\u97F3\u89C6\u9891\uFF08\u5C06\u8F6C\u5199\uFF09\uFF1A{0}"
1173
2030
  },
1174
- loginStillWaiting: {
1175
- en: "Still waiting... ({0} remaining)",
1176
- zh: "\u4ECD\u5728\u7B49\u5F85\u2026\u2026\uFF08\u5269\u4F59 {0}\uFF09"
2031
+ mediaPreprocessStart: {
2032
+ en: "\u{1F3A7} {0} preprocessing\u2026",
2033
+ zh: "\u{1F3A7} {0} \u9884\u5904\u7406\u4E2D\u2026"
1177
2034
  },
1178
- loginSuccess: {
1179
- en: "Logged in. Token saved to profile; this session now uses it immediately.",
1180
- zh: "\u767B\u5F55\u6210\u529F\u3002Token \u5DF2\u5199\u5165 profile\uFF0C\u5F53\u524D\u4F1A\u8BDD\u7ACB\u5373\u751F\u6548\u3002"
2035
+ mediaTranscribeProgress: {
2036
+ en: "\u{1F3A7} {0} transcribing\u2026 {1}",
2037
+ zh: "\u{1F3A7} {0} \u8F6C\u5199\u4E2D\u2026 {1}"
2038
+ },
2039
+ mediaTranscribeDone: {
2040
+ en: "\u{1F3A7} {0} transcribed \u2014 saved: {1}",
2041
+ zh: "\u{1F3A7} {0} \u8F6C\u5199\u5B8C\u6210\u2014\u2014\u5DF2\u4FDD\u5B58\uFF1A{1}"
1181
2042
  },
1182
- loginFailed: {
1183
- en: "Login failed: {0}",
1184
- zh: "\u767B\u5F55\u5931\u8D25\uFF1A{0}"
2043
+ mediaTranscribeDoneAttach: {
2044
+ en: "\u{1F3A7} {0} transcribed \u2014 txt: {1}\n srt: {2}\n transcript will be attached to your next message.",
2045
+ zh: "\u{1F3A7} {0} \u8F6C\u5199\u5B8C\u6210\u2014\u2014txt\uFF1A{1}\n srt\uFF1A{2}\n \u8F6C\u5199\u5185\u5BB9\u5C06\u968F\u4F60\u4E0B\u4E00\u6761\u6D88\u606F\u53D1\u9001\u7ED9\u6A21\u578B\u3002"
1185
2046
  },
1186
- loginTimeout: {
1187
- en: "Login timed out. Run /login again, or use `nolo login --token <jwt>` in a shell.",
1188
- zh: "\u767B\u5F55\u8D85\u65F6\u3002\u8BF7\u91CD\u65B0\u6267\u884C /login\uFF0C\u6216\u5728 shell \u91CC\u7528 nolo login --token <jwt>\u3002"
2047
+ mediaTranscribeFailed: {
2048
+ en: "{0} transcription failed: {1}",
2049
+ zh: "{0} \u8F6C\u5199\u5931\u8D25\uFF1A{1}"
1189
2050
  },
1190
- loginCancelled: {
1191
- en: "Login cancelled.",
1192
- zh: "\u5DF2\u53D6\u6D88\u767B\u5F55\u3002"
2051
+ mediaSilenceTrimScanning: {
2052
+ en: "\u{1F3A7} {0} checking for trailing silence\u2026",
2053
+ zh: "\u{1F3A7} {0} \u68C0\u67E5\u5C3E\u90E8\u9759\u97F3\u2026"
1193
2054
  },
1194
- welcomeAuthGuidance: {
1195
- en: 'Not logged in to Nolo \u2014 three ways to get going:\n \xB7 Run a task on local Codex: nolo run "<task>" (no login needed)\n \xB7 Bind your own model subscription: nolo auth antigravity | claude | chatgpt | xai\n \xB7 Use the Nolo platform: type /login (gives you a browser authorization link)',
1196
- zh: '\u672A\u767B\u5F55 Nolo \u2014\u2014 \u4E09\u6761\u8DEF\u90FD\u80FD\u7528\uFF1A\n \xB7 \u7528\u672C\u5730 Codex \u8DD1\u4EFB\u52A1\uFF1Anolo run "<\u4EFB\u52A1>"\uFF08\u4E0D\u9700\u8981\u767B\u5F55\uFF09\n \xB7 \u7ED1\u5B9A\u4F60\u81EA\u5DF1\u7684\u6A21\u578B\u8BA2\u9605\uFF1Anolo auth antigravity | claude | chatgpt | xai\n \xB7 \u7528 Nolo \u5E73\u53F0\uFF1A\u76F4\u63A5\u8F93\u5165 /login\uFF08\u4F1A\u7ED9\u51FA\u6D4F\u89C8\u5668\u6388\u6743\u94FE\u63A5\uFF09'
2055
+ mediaSilenceTrimNotice: {
2056
+ en: "\u{1F3A7} {0}: about {1} min of trailing silence \u2014 suggesting cut to {2} (saves ~{1} min).",
2057
+ zh: "\u{1F3A7} {0}\uFF1A\u5C3E\u90E8\u7EA6 {1} \u5206\u949F\u57FA\u672C\u65E0\u4EBA\u58F0\uFF0C\u5EFA\u8BAE\u622A\u5230 {2}\uFF08\u53EF\u7701\u7EA6 {1} \u5206\u949F\uFF09\u3002"
1197
2058
  },
1198
- versionInfo: {
1199
- en: "nolo {0}\nUpdate this install with: nolo update\nIf repo-local output differs, publish/install the latest npm package first.",
1200
- zh: "nolo {0}\n\u7528 nolo update \u66F4\u65B0\u5F53\u524D\u5B89\u88C5\u3002\n\u5982\u679C\u672C\u5730\u4ED3\u5E93\u8F93\u51FA\u7684\u7248\u672C\u4E0D\u540C\uFF0C\u8BF7\u5148\u53D1\u5E03/\u5B89\u88C5\u6700\u65B0\u7684 npm \u5305\u3002"
2059
+ mediaSilenceTrimTitle: {
2060
+ en: "Transcribe range \u2014 trailing silence detected",
2061
+ zh: "\u8F6C\u5199\u8303\u56F4\u2014\u2014\u68C0\u6D4B\u5230\u5C3E\u90E8\u9759\u97F3"
1201
2062
  },
1202
- versionUnknown: { en: "unknown version", zh: "\u672A\u77E5\u7248\u672C" },
1203
- updateAvailable: {
1204
- // 保持短:这行在窄终端物理换行会破坏 banner 重绘的行数计算。当前版本
1205
- // 号上一行 version line 已有,不重复。
1206
- en: "\u2191 nolo {0} available \u2014 /update to upgrade",
1207
- zh: "\u2191 nolo {0} \u53EF\u7528 \u2014 /update \u5347\u7EA7"
2063
+ mediaSilenceTrimDetail: {
2064
+ en: "Suggestion: keep everything before {0} (saves ~{1} min of upload/transcription).",
2065
+ zh: "\u5EFA\u8BAE\uFF1A\u53EA\u5904\u7406 {0} \u4E4B\u524D\u7684\u5185\u5BB9\uFF08\u7701\u7EA6 {1} \u5206\u949F\u7684\u9884\u5904\u7406\u4E0E\u8F6C\u5199\uFF09\u3002"
1208
2066
  },
1209
- // --- Dialog list / timestamps -----------------------------------------
1210
- recentDialogs: { en: "Recent dialogs:", zh: "\u6700\u8FD1\u5BF9\u8BDD\uFF1A" },
1211
- dialogListTip: {
1212
- en: "Tip: run /history to pick one interactively, or paste an id after /resume.",
1213
- zh: "\u63D0\u793A\uFF1A\u7528 /history \u4EA4\u4E92\u5F0F\u9009\u62E9\uFF0C\u6216\u628A id \u7C98\u5230 /resume \u540E\u9762\u3002"
2067
+ mediaSilenceTrimOptionAll: {
2068
+ en: "Transcribe everything",
2069
+ zh: "\u5168\u90E8\uFF08\u4E0D\u88C1\u526A\uFF09"
1214
2070
  },
1215
- timeJustNow: { en: "just now", zh: "\u521A\u521A" },
1216
- timeMinutesAgo: { en: "{0}m ago", zh: "{0} \u5206\u949F\u524D" },
1217
- timeHoursAgo: { en: "{0}h ago", zh: "{0} \u5C0F\u65F6\u524D" },
1218
- timeDaysAgo: { en: "{0}d ago", zh: "{0} \u5929\u524D" },
1219
- // Overflow hints shared by select / multi-select / ask-choice. The arrows
1220
- // and count are part of the copy so each locale can order them naturally.
1221
- dialogMoreAbove: { en: "\u2191 {0} more", zh: "\u2191 {0} \u66F4\u591A" },
1222
- dialogMoreBelow: { en: "\u2193 {0} more", zh: "\u2193 {0} \u66F4\u591A" },
1223
- // Action gate handoff
1224
- actionGateNeeded: {
1225
- en: "Action needed in your terminal",
1226
- zh: "\u7EC8\u7AEF\u9700\u8981\u4F60\u7684\u64CD\u4F5C"
2071
+ mediaSilenceTrimOptionTrim: {
2072
+ en: "Follow the suggestion: cut to {0} (saves ~{1} min)",
2073
+ zh: "\u6309\u5EFA\u8BAE\uFF1A\u622A\u5230 {0}\uFF08\u7701\u7EA6 {1} \u5206\u949F\uFF09"
1227
2074
  },
1228
- actionGateEnterHint: {
1229
- en: "Press Enter to run it now. Follow any prompts below, or Ctrl+C to cancel.",
1230
- zh: "\u6309 Enter \u7ACB\u5373\u6267\u884C\uFF0C\u6309\u4E0B\u65B9\u63D0\u793A\u64CD\u4F5C\uFF0C\u6216\u6309 Ctrl+C \u53D6\u6D88\u3002"
2075
+ mediaSilenceTrimApplied: {
2076
+ en: "\u{1F3A7} following the suggestion \u2014 transcribing up to {0}.",
2077
+ zh: "\u{1F3A7} \u5DF2\u6309\u5EFA\u8BAE\u88C1\u526A\u2014\u2014\u53EA\u8F6C\u5199 {0} \u4E4B\u524D\u7684\u5185\u5BB9\u3002"
1231
2078
  },
1232
- actionGateConfirmHint: { en: "Enter=approve, n=cancel (or type y/yes).", zh: "Enter=\u6279\u51C6\uFF0Cn=\u53D6\u6D88\uFF08\u4E5F\u53EF\u8F93\u5165 y/yes\uFF09\u3002" },
1233
- actionGateInteractiveTitle: {
1234
- en: "This command requires an interactive terminal.",
1235
- zh: "\u8BE5\u547D\u4EE4\u9700\u8981\u4EA4\u4E92\u5F0F\u7EC8\u7AEF"
2079
+ mediaSilenceTrimHintOnly: {
2080
+ en: "\u{1F3A7} keeping the full file (can't ask right now). To trim, rerun /transcribe with --to {0}.",
2081
+ zh: "\u{1F3A7} \u5F53\u524D\u65E0\u6CD5\u4EA4\u4E92\uFF0C\u6309\u5168\u7247\u8F6C\u5199\uFF1B\u5982\u9700\u88C1\u526A\uFF0C\u8BF7\u7528 --to {0} \u91CD\u8DD1 /transcribe\u3002"
1236
2082
  },
1237
- actionGateInteractiveBody: {
1238
- en: "Complete it in the terminal, then nolo will continue.",
1239
- zh: "\u5728\u7EC8\u7AEF\u4E2D\u5B8C\u6210\u64CD\u4F5C\u540E\uFF0Cnolo \u5C06\u7EE7\u7EED\u3002"
2083
+ transcribeUsage: {
2084
+ en: "Usage: /transcribe <path> [--from ss|mm:ss|hh:mm:ss] [--to ss|mm:ss|hh:mm:ss] [--lang zh|en|...] [--denoise off|light|strong]",
2085
+ zh: "\u7528\u6CD5\uFF1A/transcribe <\u8DEF\u5F84> [--from \u79D2|\u5206:\u79D2|\u65F6:\u5206:\u79D2] [--to \u79D2|\u5206:\u79D2|\u65F6:\u5206:\u79D2] [--lang zh|en|...] [--denoise off|light|strong]"
1240
2086
  },
1241
- // Compact memory-tool trace
1242
- memoryDeleteRequestedCount: {
1243
- en: "requested deletion of {0}",
1244
- zh: "\u5DF2\u8BF7\u6C42\u5220\u9664 {0} \u6761"
2087
+ transcribeArgError: {
2088
+ en: "Invalid /transcribe argument: {0}",
2089
+ zh: "/transcribe \u53C2\u6570\u9519\u8BEF\uFF1A{0}"
1245
2090
  },
1246
- // Agent catalog sources
1247
- agentSourcePlatform: {
1248
- en: "Platform",
1249
- zh: "\u5E73\u53F0"
2091
+ transcribeNotMedia: {
2092
+ en: "Not a media file: {0}",
2093
+ zh: "\u4E0D\u662F\u97F3\u89C6\u9891\u6587\u4EF6\uFF1A{0}"
1250
2094
  },
1251
- agentSourceSubscription: {
1252
- en: "Subscription",
1253
- zh: "\u8BA2\u9605"
2095
+ transcribeBusyHint: {
2096
+ en: "/transcribe is unavailable while a reply is running \u2014 it attaches to your next message. Wait for the reply to finish, then run it.",
2097
+ zh: "\u56DE\u590D\u8FDB\u884C\u4E2D\u4E0D\u80FD\u6267\u884C /transcribe\u2014\u2014\u8F6C\u5199\u4EA7\u7269\u8981\u968F\u4E0B\u4E00\u6761\u6D88\u606F\u53D1\u9001\u3002\u7B49\u672C\u8F6E\u56DE\u590D\u7ED3\u675F\u540E\u518D\u6267\u884C\u3002"
1254
2098
  },
1255
- agentSourceApi: {
1256
- en: "API",
1257
- zh: "API"
2099
+ busyAttachmentsBlocked: {
2100
+ en: "can't queue a message with {0} clipboard image(s) while a turn is running \u2014 draft kept. Send again after this turn ends, or press Backspace to drop the attachment and send text only.",
2101
+ zh: "\u5FD9\u788C\u4E2D\u65E0\u6CD5\u6392\u961F\u5E26 {0} \u5F20\u526A\u8D34\u677F\u56FE\u7247\u7684\u6D88\u606F\uFF0C\u8349\u7A3F\u5DF2\u4FDD\u7559\uFF1B\u7B49\u672C\u8F6E\u7ED3\u675F\u540E\u518D\u6309 Enter \u53D1\u9001\uFF0C\u6216 Backspace \u64A4\u9500\u9644\u4EF6\u540E\u6539\u53D1\u7EAF\u6587\u5B57\u3002"
1258
2102
  },
1259
- // ── Non-TUI CLI output: shared command-group help ─────────────────────────
1260
- // `nolo <group> --help` renders from the command registry; the frame lines
1261
- // are localized here while per-command copy lives in cliCommandDescription().
1262
- "cli.groupCommandsTitle": {
1263
- en: "nolo {0} commands",
1264
- zh: "nolo {0} \u547D\u4EE4"
2103
+ // --- Slash-command output ---------------------------------------------
2104
+ // Command results that used to be hardcoded English. Usage lines keep the
2105
+ // command literal untouched; only the surrounding words are translated.
2106
+ unknownCommand: {
2107
+ en: "Unknown command: {0}\n\n",
2108
+ zh: "\u672A\u77E5\u547D\u4EE4\uFF1A{0}\n\n"
1265
2109
  },
1266
- "cli.usageLabel": {
1267
- en: "Usage:",
1268
- zh: "\u7528\u6CD5\uFF1A"
2110
+ noConversationLinks: {
2111
+ en: "No links in this conversation yet.",
2112
+ zh: "\u672C\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u51FA\u73B0\u94FE\u63A5\u3002"
1269
2113
  },
1270
- // ── Non-TUI CLI output: nolo auth ─────────────────────────────────────────
1271
- // User-visible copy of `nolo auth <provider>`. Params follow each en string:
1272
- // {0}=provider, {1}=server origin / saved account / raw detail,
1273
- // {2}=zone or HTTP status, {3}=optional trailing fragment.
1274
- "auth.authorizationSaved": {
1275
- en: "[nolo] {0} authorization saved{1}.",
1276
- zh: "[nolo] \u5DF2\u4FDD\u5B58 {0} \u6388\u6743{1}\u3002"
2114
+ conversationLinksCopyHint: {
2115
+ en: "Open one by copying its URL (Cmd/Ctrl + click, or select and copy).",
2116
+ zh: "\u590D\u5236\u5BF9\u5E94 URL \u5373\u53EF\u6253\u5F00\uFF08Cmd/Ctrl + \u70B9\u51FB\uFF0C\u6216\u9009\u4E2D\u590D\u5236\uFF09\u3002"
1277
2117
  },
1278
- // Optional account suffix for authorizationSaved (empty when the provider
1279
- // reports no account label).
1280
- "auth.authorizationSavedForAccount": {
1281
- en: " for {0}",
1282
- zh: "\uFF08\u8D26\u53F7 {0}\uFF09"
2118
+ conversationLinksShowing: {
2119
+ en: "Links in this conversation (showing first {0} of {1}):",
2120
+ zh: "\u672C\u4F1A\u8BDD\u51FA\u73B0\u7684\u94FE\u63A5\uFF08\u663E\u793A\u524D {0} \u4E2A\uFF0C\u5171 {1} \u4E2A\uFF09\uFF1A"
1283
2121
  },
1284
- "auth.noLocalCredential": {
1285
- en: "[nolo] No local {0} credential. Run: nolo auth {0}",
1286
- zh: "[nolo] \u672C\u5730\u6CA1\u6709 {0} \u51ED\u636E\u3002\u8BF7\u8FD0\u884C\uFF1Anolo auth {0}"
2122
+ runtimeUsage: { en: "Usage: /runtime <auto|local|server>", zh: "\u7528\u6CD5\uFF1A/runtime <auto|local|server>" },
2123
+ runtimeSet: { en: "Runtime: {0}", zh: "\u8FD0\u884C\u6A21\u5F0F\uFF1A{0}" },
2124
+ logsEmpty: {
2125
+ en: "No diagnostics recorded in this session.",
2126
+ zh: "\u672C\u6B21\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u8BCA\u65AD\u8BB0\u5F55\u3002"
1287
2127
  },
1288
- "auth.credentialServerManaged": {
1289
- en: "[nolo] The {0} credential is already server-managed by {1} (no local refresh token).\nTo sync it again, run: nolo auth {0} --sync-to-server",
1290
- zh: "[nolo] {0} \u51ED\u636E\u5DF2\u7531 {1} \u670D\u52A1\u7AEF\u6258\u7BA1\uFF08\u672C\u5730\u65E0 refreshToken\uFF09\u3002\n\u5982\u9700\u91CD\u65B0\u540C\u6B65\uFF0C\u8BF7\u8FD0\u884C: nolo auth {0} --sync-to-server"
2128
+ logsHeader: {
2129
+ en: "Recent diagnostics ({0} of {1}) \xB7 full log: {2}",
2130
+ zh: "\u6700\u8FD1\u8BCA\u65AD\uFF08{0}/{1} \u6761\uFF09\xB7 \u5B8C\u6574\u65E5\u5FD7\uFF1A{2}"
1291
2131
  },
1292
- "auth.verifyUnsupported": {
1293
- en: '[nolo] --verify is only supported for "nolo auth antigravity".',
1294
- zh: '[nolo] --verify \u4EC5\u652F\u6301 "nolo auth antigravity"\u3002'
2132
+ tasksRunning: { en: "Running processes ({0}):", zh: "\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\uFF08{0}\uFF09\uFF1A" },
2133
+ tasksStopped: { en: "Stopped/exited ({0}):", zh: "\u5DF2\u505C\u6B62/\u5DF2\u9000\u51FA\uFF08{0}\uFF09\uFF1A" },
2134
+ tasksNone: { en: "No processes.", zh: "\u6CA1\u6709\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\u3002" },
2135
+ stopUsage: { en: "Usage: /stop <pid|label|all>", zh: "\u7528\u6CD5\uFF1A/stop <pid|label|all>" },
2136
+ stopAllDone: { en: "Stopped {0} processes", zh: "\u5DF2\u505C\u6B62 {0} \u4E2A\u8FDB\u7A0B" },
2137
+ stopNoPid: { en: "No running process with pid {0}", zh: "\u6CA1\u6709 pid \u4E3A {0} \u7684\u8FD0\u884C\u4E2D\u8FDB\u7A0B" },
2138
+ stopPidDone: { en: "Stopped pid {0} ({1})", zh: "\u5DF2\u505C\u6B62 pid {0}\uFF08{1}\uFF09" },
2139
+ stopNoLabel: { en: "No running process labeled '{0}'", zh: "\u6CA1\u6709\u540D\u4E3A\u201C{0}\u201D\u7684\u8FD0\u884C\u4E2D\u8FDB\u7A0B" },
2140
+ stopLabelsDone: { en: "Stopped {0}", zh: "\u5DF2\u505C\u6B62 {0}" },
2141
+ compactNothing: {
2142
+ en: "Current dialog: new (nothing to compact yet)",
2143
+ zh: "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u662F\u65B0\u7684\uFF08\u8FD8\u6CA1\u6709\u53EF\u538B\u7F29\u7684\u5185\u5BB9\uFF09"
1295
2144
  },
1296
- "auth.checkingVerificationChallenge": {
1297
- en: "[nolo] Checking the current verification challenge (one lightweight request)...",
1298
- zh: "[nolo] \u6B63\u5728\u68C0\u67E5\u5F53\u524D\u9A8C\u8BC1\u6311\u6218\uFF08\u4E00\u6B21\u8F7B\u91CF\u8BF7\u6C42\uFF09\u2026"
2145
+ compactingDialog: {
2146
+ en: "Compacting current dialog...",
2147
+ zh: "\u6B63\u5728\u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\u2026"
1299
2148
  },
1300
- "auth.refreshTokenInvalid": {
1301
- en: "[nolo] The antigravity refresh token is no longer valid ({0}). Re-run `nolo auth antigravity` to re-authorize this account.",
1302
- zh: "[nolo] antigravity \u7684 refresh token \u5DF2\u5931\u6548\uFF08{0}\uFF09\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C `nolo auth antigravity` \u91CD\u65B0\u6388\u6743\u8BE5\u8D26\u53F7\u3002"
2149
+ compactPhaseReading: {
2150
+ en: "Reading dialog messages\u2026",
2151
+ zh: "\u6B63\u5728\u8BFB\u53D6\u5BF9\u8BDD\u6D88\u606F\u2026"
1303
2152
  },
1304
- "auth.credentialIncomplete": {
1305
- en: "[nolo] The stored antigravity credential is incomplete ({0}). Re-run `nolo auth antigravity` to re-authorize.",
1306
- zh: "[nolo] \u672C\u5730\u4FDD\u5B58\u7684 antigravity \u51ED\u636E\u4E0D\u5B8C\u6574\uFF08{0}\uFF09\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C `nolo auth antigravity` \u91CD\u65B0\u6388\u6743\u3002"
2153
+ compactPhaseSummarizing: {
2154
+ en: "Generating summary\u2026",
2155
+ zh: "\u6B63\u5728\u751F\u6210\u603B\u7ED3\u2026"
1307
2156
  },
1308
- "auth.providerUnreachable": {
1309
- en: "[nolo] Could not reach the antigravity provider: {0}. Check your network and retry.",
1310
- zh: "[nolo] \u65E0\u6CD5\u8BBF\u95EE antigravity provider\uFF1A{0}\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002"
2157
+ compactPhaseForking: {
2158
+ en: "Forking dialog\u2026",
2159
+ zh: "\u6B63\u5728\u5206\u53C9\u65B0\u5BF9\u8BDD\u2026"
1311
2160
  },
1312
- "auth.credentialWorking": {
1313
- en: "[nolo] \u2713 The credential is working \u2014 no verification is required right now. You can retry your agent.",
1314
- zh: "[nolo] \u2713 \u51ED\u636E\u53EF\u7528\u2014\u2014\u5F53\u524D\u65E0\u9700\u9A8C\u8BC1\u3002\u53EF\u4EE5\u91CD\u8BD5\u4F60\u7684 agent\u3002"
2161
+ compactFailed: {
2162
+ en: "Compact failed: {0}",
2163
+ zh: "\u538B\u7F29\u5931\u8D25\uFF1A{0}"
1315
2164
  },
1316
- "auth.googleVerificationRequired": {
1317
- en: "[nolo] Google requires a one-time account verification for {0}.",
1318
- zh: "[nolo] Google \u9700\u8981\u5BF9 {0} \u505A\u4E00\u6B21\u6027\u8D26\u53F7\u9A8C\u8BC1\u3002"
2165
+ contextLengthExceeded: {
2166
+ en: "Model context limit reached (requested {0} tokens / limit {1}). Suggest using /compact to compact current dialog, or /new to start a fresh dialog.",
2167
+ zh: "\u5DF2\u8FBE\u6A21\u578B\u4E0A\u4E0B\u6587\u4E0A\u9650\uFF08\u8BF7\u6C42 {0} tokens / \u4E0A\u9650 {1}\uFF09\u3002\u5EFA\u8BAE\u4F7F\u7528 /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\uFF0C\u6216\u4F7F\u7528 /new \u5F00\u59CB\u65B0\u5BF9\u8BDD\u3002"
1319
2168
  },
1320
- "auth.verificationOpened": {
1321
- en: "[nolo] \u2713 Opened it in your browser \u2014 complete the verification there (sign in with the same Google account), then retry your agent.",
1322
- zh: "[nolo] \u2713 \u5DF2\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u2014\u2014\u8BF7\u5728\u90A3\u91CC\u5B8C\u6210\u9A8C\u8BC1\uFF08\u7528\u540C\u4E00\u4E2A Google \u8D26\u53F7\u767B\u5F55\uFF09\uFF0C\u7136\u540E\u91CD\u8BD5\u4F60\u7684 agent\u3002"
2169
+ contextLengthExceededLimitOnly: {
2170
+ en: "Model context limit reached (limit {0}). Suggest using /compact to compact current dialog, or /new to start a fresh dialog.",
2171
+ zh: "\u5DF2\u8FBE\u6A21\u578B\u4E0A\u4E0B\u6587\u4E0A\u9650\uFF08\u4E0A\u9650 {0}\uFF09\u3002\u5EFA\u8BAE\u4F7F\u7528 /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\uFF0C\u6216\u4F7F\u7528 /new \u5F00\u59CB\u65B0\u5BF9\u8BDD\u3002"
1323
2172
  },
1324
- "auth.verificationCopyUrl": {
1325
- en: "[nolo] Copy the URL above into a browser signed into {0}, complete the verification, then retry your agent.",
1326
- zh: "[nolo] \u8BF7\u628A\u4E0A\u9762\u7684 URL \u590D\u5236\u5230\u5DF2\u767B\u5F55 {0} \u7684\u6D4F\u89C8\u5668\u4E2D\uFF0C\u5B8C\u6210\u9A8C\u8BC1\u540E\u91CD\u8BD5\u4F60\u7684 agent\u3002"
2173
+ contextLengthExceededGeneric: {
2174
+ en: "Model context limit reached. Suggest using /compact to compact current dialog, or /new to start a fresh dialog.",
2175
+ zh: "\u5DF2\u8FBE\u6A21\u578B\u4E0A\u4E0B\u6587\u4E0A\u9650\u3002\u5EFA\u8BAE\u4F7F\u7528 /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\uFF0C\u6216\u4F7F\u7528 /new \u5F00\u59CB\u65B0\u5BF9\u8BDD\u3002"
1327
2176
  },
1328
- "auth.httpWithoutVerificationLink": {
1329
- en: "[nolo] The provider returned HTTP {0} without a verification link \u2014 this is not the one-time-verification case --verify handles.{1} Response detail: {2}",
1330
- zh: "[nolo] provider \u8FD4\u56DE HTTP {0}\uFF0C\u4F46\u6CA1\u6709\u4EFB\u4F55\u9A8C\u8BC1\u94FE\u63A5\u2014\u2014\u8FD9\u4E0D\u5C5E\u4E8E --verify \u5904\u7406\u7684\u4E00\u6B21\u6027\u9A8C\u8BC1\u573A\u666F\u3002{1}\u54CD\u5E94\u8BE6\u60C5\uFF1A{2}"
2177
+ compactDone: {
2178
+ en: "Compacted dialog {0} \u2192 {1}.",
2179
+ zh: "\u5DF2\u538B\u7F29\u5BF9\u8BDD {0} \u2192 {1}\u3002"
1331
2180
  },
1332
- // Optional trailing fragment spliced into httpWithoutVerificationLink when a
1333
- // token refresh also failed earlier. English keeps the leading space.
1334
- "auth.httpWithoutVerificationLink.refreshSuffix": {
1335
- en: " (token refresh also failed earlier: {0})",
1336
- zh: "\uFF08\u6B64\u524D token \u5237\u65B0\u4E5F\u5931\u8D25\uFF1A{0}\uFF09"
2181
+ compactDoneNoSummary: {
2182
+ en: "Forked dialog {0} \u2192 {1} (no summary needed).",
2183
+ zh: "\u5DF2\u5206\u53C9\u5BF9\u8BDD {0} \u2192 {1}\uFF08\u65E0\u9700\u538B\u7F29\uFF09\u3002"
1337
2184
  },
1338
- "auth.localRefreshTokenDropped": {
1339
- en: "[nolo] No local refresh token is kept: {0} is refreshed by {1} (fetched on demand).",
1340
- zh: "[nolo] \u672C\u5730\u4E0D\u518D\u4FDD\u5B58 refresh token\uFF1A{0} \u7531 {1} \u7EDF\u4E00\u5237\u65B0\uFF08\u7528\u5B8C\u5373\u53D6\uFF09\u3002"
2185
+ compactSuccess: {
2186
+ en: "\u2713 Compacted dialog {0} \u2192 {1} in {2}.",
2187
+ zh: "\u2713 \u5DF2\u538B\u7F29\u5BF9\u8BDD {0} \u2192 {1}\uFF0C\u8017\u65F6 {2}\u3002"
1341
2188
  },
1342
- "auth.localStateUpdateFailed": {
1343
- en: "[nolo] Warning: failed to update the local credential state ({0}).",
1344
- zh: "[nolo] Warning: \u672C\u5730\u51ED\u636E\u72B6\u6001\u66F4\u65B0\u5931\u8D25\uFF08{0}\uFF09\u3002"
2189
+ compactSuccessWithCount: {
2190
+ en: "\u2713 Compacted dialog {0} \u2192 {1} in {2} ({3} messages compressed).",
2191
+ zh: "\u2713 \u5DF2\u538B\u7F29\u5BF9\u8BDD {0} \u2192 {1}\uFF0C\u8017\u65F6 {2}\uFF08\u538B\u7F29 {3} \u6761\u6D88\u606F\uFF09\u3002"
1345
2192
  },
1346
- "auth.syncMissingConfig": {
1347
- en: "[nolo] Warning: server sync needs NOLO_SERVER and AUTH_TOKEN env vars, or a configured profile. Skipping server sync.",
1348
- zh: "[nolo] \u8B66\u544A\uFF1A\u670D\u52A1\u7AEF\u540C\u6B65\u9700\u8981 NOLO_SERVER \u548C AUTH_TOKEN \u73AF\u5883\u53D8\u91CF\uFF0C\u6216\u5DF2\u914D\u7F6E\u7684 profile\u3002\u5DF2\u8DF3\u8FC7\u540C\u6B65\u3002"
2193
+ compactForked: {
2194
+ en: "\u2713 Forked dialog {0} \u2192 {1} in {2} (no summary needed).",
2195
+ zh: "\u2713 \u5DF2\u5206\u53C9\u5BF9\u8BDD {0} \u2192 {1}\uFF0C\u8017\u65F6 {2}\uFF08\u65E0\u9700\u538B\u7F29\uFF09\u3002"
2196
+ },
2197
+ skillAttachUsage: { en: "Usage: /skill attach <skill-ref>", zh: "\u7528\u6CD5\uFF1A/skill attach <skill-ref>" },
2198
+ skillAttached: { en: "Attached skill: {0}", zh: "\u5DF2\u6302\u8F7D\u6280\u80FD\uFF1A{0}" },
2199
+ skillDetachUsage: { en: "Usage: /skill detach <skill-ref>", zh: "\u7528\u6CD5\uFF1A/skill detach <skill-ref>" },
2200
+ skillDetached: { en: "Detached skill: {0}", zh: "\u5DF2\u5378\u8F7D\u6280\u80FD\uFF1A{0}" },
2201
+ skillNotAttached: { en: "Skill not attached: {0}", zh: "\u6280\u80FD\u672A\u6302\u8F7D\uFF1A{0}" },
2202
+ skillNone: { en: "No skills attached.", zh: "\u8FD8\u6CA1\u6709\u6302\u8F7D\u6280\u80FD\u3002" },
2203
+ skillCleared: { en: "Cleared {0} skill(s).", zh: "\u5DF2\u6E05\u7A7A {0} \u4E2A\u6280\u80FD\u3002" },
2204
+ skillList: {
2205
+ en: "Attached skills: {0}\nUsage: /skill attach <ref> | /skill detach <ref> | /skill clear",
2206
+ zh: "\u5DF2\u6302\u8F7D\u6280\u80FD\uFF1A{0}\n\u7528\u6CD5\uFF1A/skill attach <ref> | /skill detach <ref> | /skill clear"
1349
2207
  },
1350
- "auth.syncedTo": {
1351
- en: "[nolo] Synced to {0}",
1352
- zh: "[nolo] \u5DF2\u540C\u6B65\u5230 {0}"
2208
+ skillNoneHint: {
2209
+ en: "No skills attached. Use /skill attach <skill-ref> to attach a skill.\nSkill refs can be a dbKey (page-xxx), a skill name (searched in .agents/skills/), or a direct path.",
2210
+ zh: "\u8FD8\u6CA1\u6709\u6302\u8F7D\u6280\u80FD\u3002\u7528 /skill attach <skill-ref> \u6302\u8F7D\u6280\u80FD\u3002\n\u6280\u80FD\u5F15\u7528\u53EF\u4EE5\u662F dbKey\uFF08page-xxx\uFF09\u3001\u6280\u80FD\u540D\uFF08\u4F1A\u5728 .agents/skills/ \u4E2D\u67E5\u627E\uFF09\u6216\u76F4\u63A5\u8DEF\u5F84\u3002"
1353
2211
  },
1354
- "auth.syncDoneWebUsable": {
1355
- en: "[nolo] The web app can now use this subscription.",
1356
- zh: "[nolo] \u7F51\u9875\u7AEF\u73B0\u5728\u53EF\u4EE5\u4F7F\u7528\u8BE5\u8BA2\u9605\u4E86\u3002"
2212
+ customizeHint: {
2213
+ en: "Tell nolo what to change, for example: /customize make my default agent more concise.",
2214
+ zh: "\u544A\u8BC9 nolo \u4F60\u60F3\u6539\u4EC0\u4E48\uFF0C\u4F8B\u5982\uFF1A/customize make my default agent more concise\u3002"
1357
2215
  },
1358
- "auth.syncFailed": {
1359
- en: "[nolo] Warning: server sync failed ({0}). Token saved locally.",
1360
- zh: "[nolo] \u8B66\u544A\uFF1A\u670D\u52A1\u7AEF\u540C\u6B65\u5931\u8D25\uFF08{0}\uFF09\u3002Token \u5DF2\u4FDD\u5B58\u5728\u672C\u5730\u3002"
2216
+ // --- Dialog list / timestamps -----------------------------------------
2217
+ recentDialogs: { en: "Recent dialogs:", zh: "\u6700\u8FD1\u5BF9\u8BDD\uFF1A" },
2218
+ dialogListTip: {
2219
+ en: "Tip: run /history to pick one interactively, or paste an id after /resume.",
2220
+ zh: "\u63D0\u793A\uFF1A\u7528 /history \u4EA4\u4E92\u5F0F\u9009\u62E9\uFF0C\u6216\u628A id \u7C98\u5230 /resume \u540E\u9762\u3002"
1361
2221
  },
1362
- "auth.noServerConfigured": {
1363
- en: "[nolo] No server configured. To use this on the web, run nolo login first, then nolo auth {0} --sync-only",
1364
- zh: "[nolo] \u672A\u914D\u7F6E\u670D\u52A1\u5668\u3002\u5982\u9700\u5728\u7F51\u9875\u7AEF\u4F7F\u7528\uFF0C\u8BF7\u5148\u8FD0\u884C nolo login\uFF0C\u518D\u8FD0\u884C nolo auth {0} --sync-only"
2222
+ timeJustNow: { en: "just now", zh: "\u521A\u521A" },
2223
+ timeMinutesAgo: { en: "{0}m ago", zh: "{0} \u5206\u949F\u524D" },
2224
+ timeHoursAgo: { en: "{0}h ago", zh: "{0} \u5C0F\u65F6\u524D" },
2225
+ timeDaysAgo: { en: "{0}d ago", zh: "{0} \u5929\u524D" },
2226
+ // Overflow hints shared by select / multi-select / ask-choice. The arrows
2227
+ // and count are part of the copy so each locale can order them naturally.
2228
+ dialogMoreAbove: { en: "\u2191 {0} more", zh: "\u2191 {0} \u66F4\u591A" },
2229
+ dialogMoreBelow: { en: "\u2193 {0} more", zh: "\u2193 {0} \u66F4\u591A" },
2230
+ // Action gate handoff
2231
+ actionGateNeeded: {
2232
+ en: "Action needed in your terminal",
2233
+ zh: "\u7EC8\u7AEF\u9700\u8981\u4F60\u7684\u64CD\u4F5C"
1365
2234
  },
1366
- // {1} is the provider name again so the --no-sync-to-server hint names the
1367
- // exact command the user would run; keep [Y/n] as the literal answer hint.
1368
- "auth.syncPrompt": {
1369
- en: "Sync to {0} so the web app can also use this {1} subscription? The credential is stored encrypted; run nolo auth {1} --no-sync-to-server to turn it off later. [Y/n] ",
1370
- zh: "\u540C\u6B65\u5230 {0}\uFF0C\u8BA9\u7F51\u9875\u7AEF\u4E5F\u80FD\u4F7F\u7528\u8FD9\u4E2A {1} \u8BA2\u9605\uFF1F\u51ED\u8BC1\u52A0\u5BC6\u5B58\u50A8\uFF0C\u53EF\u968F\u65F6 nolo auth {1} --no-sync-to-server \u5173\u95ED [Y/n] "
2235
+ actionGateEnterHint: {
2236
+ en: "Press Enter to run it now. Follow any prompts below, or Ctrl+C to cancel.",
2237
+ zh: "\u6309 Enter \u7ACB\u5373\u6267\u884C\uFF0C\u6309\u4E0B\u65B9\u63D0\u793A\u64CD\u4F5C\uFF0C\u6216\u6309 Ctrl+C \u53D6\u6D88\u3002"
1371
2238
  },
1372
- "auth.notSyncedToServer": {
1373
- en: "[nolo] Not synced to the server. For web use, run: nolo auth {0} --sync-to-server (or --sync-only)",
1374
- zh: "[nolo] \u672A\u540C\u6B65\u51ED\u636E\u5230\u670D\u52A1\u5668\u3002\u5982\u9700\u7F51\u9875\u7AEF\u4F7F\u7528\uFF0C\u8BF7\u8FD0\u884C: nolo auth {0} --sync-to-server\uFF08\u6216 --sync-only\uFF09"
2239
+ actionGateConfirmHint: { en: "Enter=approve, n=cancel (or type y/yes).", zh: "Enter=\u6279\u51C6\uFF0Cn=\u53D6\u6D88\uFF08\u4E5F\u53EF\u8F93\u5165 y/yes\uFF09\u3002" },
2240
+ actionGateInteractiveTitle: {
2241
+ en: "This command requires an interactive terminal.",
2242
+ zh: "\u8BE5\u547D\u4EE4\u9700\u8981\u4EA4\u4E92\u5F0F\u7EC8\u7AEF"
1375
2243
  },
1376
- "auth.markFailed": {
1377
- en: "[nolo] The credential was uploaded to the server, but marking it server-managed locally failed. Re-authorize so both sides cannot race each other's refresh.",
1378
- zh: "[nolo] \u51ED\u636E\u5DF2\u6210\u529F\u4E0A\u4F20\u670D\u52A1\u5668\uFF0C\u4F46\u672C\u5730\u6253\u4E0A\u6258\u7BA1\u6807\u8BB0\u5931\u8D25\u3002\u4E3A\u9632\u53CC\u65B9\u7ADE\u6001\u5237\u65B0\u5BFC\u81F4\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u6388\u6743\u3002"
2244
+ actionGateInteractiveBody: {
2245
+ en: "Complete it in the terminal, then nolo will continue.",
2246
+ zh: "\u5728\u7EC8\u7AEF\u4E2D\u5B8C\u6210\u64CD\u4F5C\u540E\uFF0Cnolo \u5C06\u7EE7\u7EED\u3002"
1379
2247
  },
1380
- "auth.commandFailed": {
1381
- en: "nolo auth {0} failed: {1}",
1382
- zh: "nolo auth {0} \u5931\u8D25\uFF1A{1}"
2248
+ // Compact memory-tool trace
2249
+ memoryDeleteRequestedCount: {
2250
+ en: "requested deletion of {0}",
2251
+ zh: "\u5DF2\u8BF7\u6C42\u5220\u9664 {0} \u6761"
1383
2252
  },
1384
- "auth.cloudflareTokenGenerated": {
1385
- en: "[nolo] Generated Cloudflare API token for zone {0} ({1}).\nStore it as CLOUDFLARE_EMAIL_ROUTING_API_TOKEN:\n {2}\n",
1386
- zh: "[nolo] \u5DF2\u4E3A zone {0}\uFF08{1}\uFF09\u751F\u6210 Cloudflare API token\u3002\n\u8BF7\u4FDD\u5B58\u4E3A CLOUDFLARE_EMAIL_ROUTING_API_TOKEN\uFF1A\n {2}\n"
2253
+ // ── Non-TUI CLI output: shared command-group help ─────────────────────────
2254
+ // `nolo <group> --help` renders from the command registry; the frame lines
2255
+ // are localized here while per-command copy lives in cliCommandDescription().
2256
+ "cli.groupCommandsTitle": {
2257
+ en: "nolo {0} commands",
2258
+ zh: "nolo {0} \u547D\u4EE4"
1387
2259
  },
1388
- "auth.envUpdated": {
1389
- en: "[nolo] Updated {0} with CLOUDFLARE_EMAIL_ROUTING_API_TOKEN.",
1390
- zh: "[nolo] \u5DF2\u66F4\u65B0 {0} \u91CC\u7684 CLOUDFLARE_EMAIL_ROUTING_API_TOKEN\u3002"
2260
+ "cli.usageLabel": {
2261
+ en: "Usage:",
2262
+ zh: "\u7528\u6CD5\uFF1A"
1391
2263
  },
1392
2264
  // ── Non-TUI CLI output: nolo app ──────────────────────────────────────────
1393
2265
  "app.noApps": {
@@ -1462,58 +2334,6 @@ Use /switch, /switch list, /switch minimax-m3, or a full agent key.`,
1462
2334
  en: "provide one of --code / --code-file / --files",
1463
2335
  zh: "\u5FC5\u987B\u63D0\u4F9B --code / --code-file / --files \u4E4B\u4E00"
1464
2336
  },
1465
- // ── Non-TUI CLI output: nolo agent / nolo run ─────────────────────────────
1466
- "agent.unavailableHidden": {
1467
- en: "\u26D4 {0} agent(s) temporarily unavailable (429) hidden. Use --show-unavailable to list them.\n",
1468
- zh: "\u26D4 \u5DF2\u9690\u85CF {0} \u4E2A\u6682\u65F6\u4E0D\u53EF\u7528\u7684 agent\uFF08429\uFF09\u3002\u7528 --show-unavailable \u5217\u51FA\u5B83\u4EEC\u3002\n"
1469
- },
1470
- "agent.rateLimitedRecovery": {
1471
- en: " - [429 rate-limited] {0} (id: {1}) recovers in {2}s{3}\n",
1472
- zh: " - [429 \u9650\u6D41] {0} (id: {1}) \u9884\u8BA1 {2} \u79D2\u540E\u6062\u590D{3}\n"
1473
- },
1474
- "agentRun.autoRouteOverrideFailed": {
1475
- en: "[nolo] auto-route: could not read the source agent, running the selected agent as-is.\n",
1476
- zh: "[nolo] auto-route: \u8986\u76D6\u6E90 agent \u8BFB\u53D6\u5931\u8D25\uFF0C\u6309\u539F\u6837\u76F4\u8DD1\u6240\u9009 agent\u3002\n"
1477
- },
1478
- "agentRun.autoRouteModelOverride": {
1479
- en: "[nolo] auto-route: model override is now {0}\n",
1480
- zh: "[nolo] auto-route: model \u5C42\u8986\u76D6\u4E3A {0}\n"
1481
- },
1482
- // ── Non-TUI CLI output: nolo agent delete ─────────────────────────────────
1483
- // Flag descriptions for `nolo agent delete --help`; the Chinese copy is the
1484
- // original wording, kept verbatim so existing users lose no information.
1485
- "agentDelete.description": {
1486
- en: "Deletes an agent's private record (agent-{userId}-{id}) and public record (agent-pub-{id}).\n",
1487
- zh: "\u5220\u9664\u4E00\u4E2A agent \u7684\u79C1\u6709\u8BB0\u5F55 (agent-{userId}-{id}) \u4E0E\u516C\u5F00\u8BB0\u5F55 (agent-pub-{id})\u3002\n"
1488
- },
1489
- "agentDelete.tombstoneNote": {
1490
- en: "The server side is a tombstone soft delete: read after DELETE returns 404.\n",
1491
- zh: "\u670D\u52A1\u5668\u7AEF\u4E3A tombstone \u8F6F\u5220\u9664\uFF0CDELETE \u540E\u518D\u6B21 read \u4F1A\u8FD4\u56DE 404\u3002\n"
1492
- },
1493
- "agentDelete.flagYes": {
1494
- en: " --yes Actually delete; without it only the dry-run target summary is printed.\n",
1495
- zh: " --yes \u771F\u6B63\u6267\u884C\u5220\u9664\uFF1B\u7F3A\u7701\u65F6\u4EC5 dry-run \u8F93\u51FA\u76EE\u6807\u6458\u8981\u3002\n"
1496
- },
1497
- "agentDelete.flagJson": {
1498
- en: " --json Print the JSON result.\n",
1499
- zh: " --json \u8F93\u51FA JSON \u7ED3\u679C\u3002\n"
1500
- },
1501
- "agentDelete.flagId": {
1502
- en: " --id <agent> Same as the positional argument: alias / dbKey / URL / 26-char id.\n",
1503
- zh: " --id <agent> \u4E0E\u4F4D\u7F6E\u53C2\u6570\u7B49\u4EF7\uFF0C\u4F20\u5165 alias / dbKey / URL / 26-char id\u3002\n"
1504
- },
1505
- "agentDelete.flagServer": {
1506
- en: " --server / --server-url Delete only on the given server (replicas outside the fan-out are kept).\n",
1507
- zh: " --server / --server-url \u4EC5\u5220\u9664\u6307\u5B9A\u670D\u52A1\u5668\uFF08\u4ECD\u4FDD\u7559\u96C6\u7FA4 fan-out \u4E4B\u5916\u7684\u526F\u672C\uFF09\u3002\n"
1508
- },
1509
- "agentDelete.flagUser": {
1510
- en: " --user <userId> Explicitly override userId (errors when it differs from AUTH_TOKEN).\n",
1511
- zh: " --user <userId> \u663E\u5F0F\u8986\u76D6 userId\uFF08\u4E0E AUTH_TOKEN \u4E0D\u4E00\u81F4\u5219\u62A5\u9519\uFF09\u3002\n"
1512
- },
1513
- "agentDelete.flagToken": {
1514
- en: " --token / --machine-key Temporarily override AUTH_TOKEN.\n",
1515
- zh: " --token / --machine-key \u4E34\u65F6\u8986\u76D6 AUTH_TOKEN\u3002\n"
1516
- },
1517
2337
  // ── Non-TUI CLI output: shared API error printing ─────────────────────────
1518
2338
  "api.requestFailed": {
1519
2339
  en: "Request failed: {0}",
@@ -1559,126 +2379,25 @@ Use /switch, /switch list, /switch minimax-m3, or a full agent key.`,
1559
2379
  "chatgptWebImage.missingPrompt": {
1560
2380
  en: "Missing image prompt (payload.meta.prompt is required)",
1561
2381
  zh: "\u7F3A\u5C11\u751F\u56FE prompt\uFF08payload.meta.prompt \u5FC5\u586B\uFF09"
1562
- },
1563
- // ── Non-TUI CLI output: agent-run orchestration tool errors ───────────────
1564
- "agentRunTool.missingAgentKey": {
1565
- en: "startAgentRun: missing agentKey, and the current agent cannot be identified.",
1566
- zh: "startAgentRun: \u7F3A\u5C11 agentKey \u53C2\u6570\uFF0C\u4E14\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D Agent\u3002"
1567
- },
1568
- "agentRunTool.missingTask": {
1569
- en: "startAgentRun: missing a valid task description.",
1570
- zh: "startAgentRun: \u7F3A\u5C11\u6709\u6548\u7684 task \u6587\u672C\u63CF\u8FF0\u3002"
1571
- },
1572
- "agentRunTool.noDialogToContinue": {
1573
- en: "This run has no linked dialog and cannot be continued.",
1574
- zh: "\u8BE5 run \u65E0\u5173\u8054 dialog\uFF0C\u65E0\u6CD5\u7EED\u8DD1\u3002"
1575
- },
1576
- "agentRunTool.appendMissingRunId": {
1577
- en: 'controlAgentRun(action:"append"): missing runId.',
1578
- zh: 'controlAgentRun(action:"append"): \u7F3A\u5C11 runId\u3002'
1579
- },
1580
- "agentRunTool.appendMissingUserInput": {
1581
- en: 'controlAgentRun(action:"append"): missing a valid userInput text.',
1582
- zh: 'controlAgentRun(action:"append"): \u7F3A\u5C11\u6709\u6548\u7684 userInput \u6587\u672C\u3002'
1583
- },
1584
- "agentRunTool.appendQueueUnsupported": {
1585
- en: "This run did not start with a queue channel; append while running is not supported. Wait for a terminal state first.",
1586
- zh: "\u8BE5 run \u542F\u52A8\u65F6\u4E0D\u652F\u6301\u8FD0\u884C\u4E2D\u5165\u961F\uFF08\u65E0\u961F\u5217\u901A\u9053\uFF09\uFF0C\u8BF7\u7B49\u7EC8\u6001\u540E\u518D append"
1587
- },
1588
- "agentRunTool.unknownAction": {
1589
- en: 'controlAgentRun: unknown action "{0}".',
1590
- zh: 'controlAgentRun: \u672A\u77E5 action "{0}"\u3002'
1591
- },
1592
- "agentRunTool.missingRunId": {
1593
- en: 'controlAgentRun(action:"{0}"): missing runId.',
1594
- zh: 'controlAgentRun(action:"{0}"): \u7F3A\u5C11 runId\u3002'
1595
- },
1596
- "agentRunTool.waitAborted": {
1597
- en: "controlAgentRun(wait) was aborted.",
1598
- zh: "controlAgentRun(wait) \u5DF2\u88AB\u4E2D\u6B62\u3002"
1599
- },
1600
- // ── Non-TUI CLI output: agent-run OAuth channel ownership + stream failures ──
1601
- // 用户在 TUI 选了别人的 sshare agent(跑在 agent owner 的 OAuth 订阅上):
1602
- // auto 模式下模型请求经服务端 owner-required 代理走分享者订阅、文件/shell
1603
- // 工具留在本机执行(不是转服务端跑整轮)。文案说明模型使用分享者订阅、
1604
- // 工具在本机;不展示内部 ID,也不提供未经保证的订阅切换建议。
1605
- "agentRun.oauthChannelOwnerSkip": {
1606
- en: '[nolo] Using "{0}", shared by someone else: the model uses their subscription; file operations and commands still run on your computer.',
1607
- zh: "[nolo] \u6B63\u5728\u4F7F\u7528\u5BF9\u65B9\u5206\u4EAB\u7684\u300C{0}\u300D\uFF1A\u6A21\u578B\u4F7F\u7528\u5BF9\u65B9\u7684\u8BA2\u9605\uFF0C\u6587\u4EF6\u64CD\u4F5C\u548C\u547D\u4EE4\u6267\u884C\u4ECD\u5728\u4F60\u7684\u7535\u8111\u4E0A\u8FDB\u884C\u3002"
1608
- },
1609
- "agentRun.sharedAgentFallbackName": {
1610
- en: "Shared agent",
1611
- zh: "\u5171\u4EAB Agent"
1612
- },
1613
- // 分享 OAuth agent 的 shell 会话授权确认(块 D):首次 execShell/
1614
- // launchProcess 前弹。必须把三件事说清——这是谁的 agent / 命令在哪台
1615
- // 设备哪个工作区跑 / 任意 shell 可读写该用户可访问的资源。
1616
- // 子 run 的 per-call shell 确认(远程来源在本机跑一条命令):与会话授权同一套
1617
- // 语义,参数为 runId / agentKey / owner / device / workspace / 权限提示。
1618
- "shellPerCall.title": {
1619
- en: "Allow a remote origin to run this command on this machine?",
1620
- zh: "\u5141\u8BB8\u8FDC\u7A0B\u6765\u6E90\u5728\u672C\u673A\u6267\u884C\u8FD9\u6761\u547D\u4EE4\u5417\uFF1F"
1621
- },
1622
- "shellPerCall.body": {
1623
- en: "A remote origin asked to run one shell command on this device.\nRun: {0}\nAgent: {1}\nOwner: {2}\nDevice: {3}\nWorkspace: {4}\n{5}\n\nShell commands can read/write anything this user can access. Approving covers this whole class: remote-origin shell confirmations stop asking one by one (this session and future starts). Undo with /shell-revoke or /auto remote off.",
1624
- zh: "\u8FDC\u7A0B\u6765\u6E90\u8BF7\u6C42\u5728\u672C\u673A\u6267\u884C\u4E00\u6761 shell \u547D\u4EE4\u3002\nRun\uFF1A{0}\nAgent\uFF1A{1}\n\u4E3B\u4EBA\uFF1A{2}\n\u8BBE\u5907\uFF1A{3}\n\u5DE5\u4F5C\u533A\uFF1A{4}\n{5}\n\n\u4EFB\u610F shell \u547D\u4EE4\u53EF\u8BFB\u5199\u672C\u673A\u8BE5\u7528\u6237\u80FD\u8BBF\u95EE\u7684\u8D44\u6E90\u3002\u6279\u51C6\u540E\u300C\u8FDC\u7A0B\u6765\u6E90\u5728\u672C\u673A\u6267\u884C shell\u300D\u8FD9\u4E00\u7C7B\u786E\u8BA4\u4E0D\u518D\u9010\u6761\u8BE2\u95EE\uFF08\u672C\u6B21\u4E0E\u540E\u7EED\u542F\u52A8\u90FD\u751F\u6548\uFF09\u3002\u64A4\u9500\uFF1A/shell-revoke \u6216 /auto remote off\u3002"
1625
- },
1626
- "shellGrant.confirmTitle": {
1627
- en: "Allow remote agent {0} to run shell commands on this machine?",
1628
- zh: "\u5141\u8BB8\u8FDC\u7A0B agent {0} \u5728\u672C\u673A\u6267\u884C shell \u547D\u4EE4\u5417\uFF1F"
1629
- },
1630
- "shellGrant.confirmBody": {
1631
- en: "Remote agent {0} (owner {1}) requested to run a shell command on this machine.\nDevice: {2} ({3})\nWorkspace: {4}\nCommand: {5}\n\nShell commands can read/write anything this user can access. Approving covers this whole class: remote-origin shell confirmations stop asking one by one (this session and future starts). Undo with /shell-revoke (this session) or /auto remote off (also clears the saved grant).",
1632
- zh: "\u8FDC\u7A0B agent {0}\uFF08\u4E3B\u4EBA {1}\uFF09\u8BF7\u6C42\u5728\u672C\u673A\u6267\u884C shell \u547D\u4EE4\u3002\n\u8BBE\u5907\uFF1A{2}\uFF08{3}\uFF09\n\u5DE5\u4F5C\u533A\uFF1A{4}\n\u547D\u4EE4\uFF1A{5}\n\n\u4EFB\u610F shell \u547D\u4EE4\u53EF\u8BFB\u5199\u672C\u673A\u8BE5\u7528\u6237\u80FD\u8BBF\u95EE\u7684\u8D44\u6E90\u3002\u6279\u51C6\u540E\u300C\u8FDC\u7A0B\u6765\u6E90\u5728\u672C\u673A\u6267\u884C shell\u300D\u8FD9\u4E00\u7C7B\u786E\u8BA4\u4E0D\u518D\u9010\u6761\u8BE2\u95EE\uFF08\u672C\u6B21\u4E0E\u540E\u7EED\u542F\u52A8\u90FD\u751F\u6548\uFF09\u3002\u64A4\u9500\uFF1A/shell-revoke\uFF08\u672C\u4F1A\u8BDD\uFF09\u6216 /auto remote off\uFF08\u540C\u65F6\u6E05\u9664\u6301\u4E45\u6388\u6743\uFF09\u3002"
1633
- },
1634
- "shellGrant.revoked": {
1635
- en: "[nolo] Shell permission revoked for shared agents in this session.",
1636
- zh: "[nolo] \u5DF2\u64A4\u9500\u672C\u4F1A\u8BDD\u4E2D\u5206\u4EAB agent \u7684 shell \u6267\u884C\u6743\u9650\u3002"
1637
- },
1638
- "shellGrant.revokeNone": {
1639
- en: "[nolo] No shell permission is currently granted in this session.",
1640
- zh: "[nolo] \u672C\u4F1A\u8BDD\u5F53\u524D\u6CA1\u6709\u5DF2\u6388\u4E88\u7684 shell \u6743\u9650\u3002"
1641
- },
1642
- // 运行位置展示(块 D):owner-required 场景告诉用户工具实际在哪台设备
1643
- // 哪个工作区执行。unknown 不猜、不静默标 ready。
1644
- "toolLocation.line": {
1645
- en: "[nolo] Tools execute on {0} ({1}) \xB7 workspace {2} \xB7 status: {3}",
1646
- zh: "[nolo] \u5DE5\u5177\u5728 {0}\uFF08{1}\uFF09\xB7 \u5DE5\u4F5C\u533A {2} \xB7 \u72B6\u6001\uFF1A{3} \u6267\u884C"
1647
- },
1648
- "toolLocation.unknown": {
1649
- en: "[nolo] Tool execution location: unknown",
1650
- zh: "[nolo] \u5DE5\u5177\u6267\u884C\u4F4D\u7F6E\uFF1A\u672A\u77E5"
1651
- },
1652
- // antigravity 502 MALFORMED_FUNCTION_CALL:裸 message 是整段 provider JSON
1653
- // dump,对用户零信息量。映射成单行可操作文案;原始 JSON 只在既有
1654
- // NOLO_DEBUG / NOLO_CLI_DEBUG_DETAIL 开关下附加。
1655
- "agentRunStream.malformedToolCallRejected": {
1656
- en: "[nolo] The provider rejected the model's generated tool call, so this attempt will not retry automatically. It is usually intermittent: read dialog {0} to check progress, then resend.",
1657
- zh: "[nolo] \u6A21\u578B\u751F\u6210\u7684\u5DE5\u5177\u8C03\u7528\u88AB\u4E0A\u6E38\u62D2\u7EDD\uFF0C\u672C\u6B21\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002\u8FD9\u79CD\u60C5\u51B5\u901A\u5E38\u662F\u5076\u53D1\u7684\uFF1A\u53EF\u5148\u8BFB\u5BF9\u8BDD {0} \u770B\u8FDB\u5EA6\uFF0C\u7136\u540E\u76F4\u63A5\u91CD\u53D1\u3002"
1658
- },
1659
- "agentRunStream.malformedToolCallRejectedNoDialog": {
1660
- en: "[nolo] The provider rejected the model's generated tool call, so this attempt will not retry automatically. It is usually intermittent: just resend your message.",
1661
- zh: "[nolo] \u6A21\u578B\u751F\u6210\u7684\u5DE5\u5177\u8C03\u7528\u88AB\u4E0A\u6E38\u62D2\u7EDD\uFF0C\u672C\u6B21\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002\u8FD9\u79CD\u60C5\u51B5\u901A\u5E38\u662F\u5076\u53D1\u7684\uFF1A\u76F4\u63A5\u91CD\u53D1\u5373\u53EF\u3002"
1662
- },
1663
- "agentRunStream.interruptedAfterDialog": {
1664
- en: "\n[nolo] Agent stream transport interrupted after dialog {0} was created: {1}\n",
1665
- zh: "\n[nolo] \u5BF9\u8BDD {0} \u521B\u5EFA\u540E\uFF0Cagent \u6D41\u5F0F\u8F93\u51FA\u4E2D\u65AD\uFF1A{1}\n"
1666
- },
1667
- "agentRunStream.mayStillFinishOnServer": {
1668
- en: "[nolo] The agent run may still finish on the server; read the dialog before retrying.\n",
1669
- zh: "[nolo] \u8FD9\u6B21 agent \u8FD0\u884C\u53EF\u80FD\u4ECD\u5728\u670D\u52A1\u7AEF\u7EE7\u7EED\uFF0C\u91CD\u8BD5\u524D\u8BF7\u5148\u8BFB\u4E00\u4E0B\u8BE5\u5BF9\u8BDD\u3002\n"
1670
- },
1671
- "agentRunStream.failed": {
1672
- en: "\n[nolo] Agent stream failed: {0}\n",
1673
- zh: "\n[nolo] Agent \u6D41\u5F0F\u8FD0\u884C\u5931\u8D25\uFF1A{0}\n"
1674
- },
1675
- "agentRunStream.rawErrorDetail": {
1676
- en: "[nolo] Raw error detail (NOLO_DEBUG=1): {0}\n",
1677
- zh: "[nolo] \u539F\u59CB\u9519\u8BEF\u8BE6\u60C5\uFF08NOLO_DEBUG=1\uFF09\uFF1A{0}\n"
1678
2382
  }
1679
2383
  };
2384
+
2385
+ // packages/cli/i18n/index.ts
2386
+ var STRINGS = {
2387
+ ...turnStrings,
2388
+ ...sessionStrings,
2389
+ ...toolStrings,
2390
+ ...agentStrings,
2391
+ ...authStrings,
2392
+ ...docStrings,
2393
+ ...updateStrings,
2394
+ ...secretStrings,
2395
+ ...docCommandStrings,
2396
+ ...cliSurfaceStrings,
2397
+ ...commonStrings
2398
+ };
1680
2399
  function t(key, ...params) {
1681
- const text = STRINGS[key][currentLocale];
2400
+ const text = STRINGS[key][getCliLocale()];
1682
2401
  if (params.length === 0) return text;
1683
2402
  return text.replace(/\{(\d+|required|current)\}/g, (match, name) => {
1684
2403
  const index = name === "required" ? 0 : name === "current" ? 1 : Number(name);
@@ -1744,7 +2463,7 @@ var TOOL_LABELS = {
1744
2463
  controlAgentRun: { en: "Control agent", zh: "\u63A7\u5236\u667A\u80FD\u4F53" }
1745
2464
  };
1746
2465
  function toolLabel(name) {
1747
- return TOOL_LABELS[name]?.[currentLocale] ?? name;
2466
+ return TOOL_LABELS[name]?.[getCliLocale()] ?? name;
1748
2467
  }
1749
2468
  var COMMAND_DESCRIPTIONS = {
1750
2469
  "auth cooldown": {
@@ -1781,7 +2500,7 @@ var COMMAND_DESCRIPTIONS = {
1781
2500
  }
1782
2501
  };
1783
2502
  function cliCommandDescription(commandPath) {
1784
- return COMMAND_DESCRIPTIONS[commandPath]?.[currentLocale] ?? null;
2503
+ return COMMAND_DESCRIPTIONS[commandPath]?.[getCliLocale()] ?? null;
1785
2504
  }
1786
2505
  function toolLabelVariants(name) {
1787
2506
  const entry = TOOL_LABELS[name];