dsh-ask-from-text 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +2 -2
- package/client.js +426 -79
- package/locale/de.json +6 -0
- package/locale/es.json +6 -0
- package/locale/fr.json +6 -0
- package/locale/ja.json +6 -0
- package/locale/pt.json +6 -0
- package/locale/ru.json +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@ All notable changes to `dsh-ask-from-text` are documented here. The format is
|
|
|
4
4
|
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
|
|
5
5
|
project follows [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.1.21] - 2026-11-13
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Runtime dictionaries and Plugin Manager metadata for Japanese, Spanish,
|
|
12
|
+
French, German, Russian, and Brazilian Portuguese, completing the eight DSH
|
|
13
|
+
languages. Unsupported locales fall back to English.
|
|
14
|
+
|
|
15
|
+
## [0.1.20] - 2026-11-13
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Runtime UI localization for Chinese and English. The active DSH language is
|
|
20
|
+
read through `ctx.locale`; other languages fall back to English. Native
|
|
21
|
+
conversation and Plugin Manager metadata continue to follow DSH.
|
|
22
|
+
|
|
7
23
|
## [0.1.19] - 2026-11-13
|
|
8
24
|
|
|
9
25
|
### Fixed
|
|
@@ -55,6 +71,22 @@ project follows [Semantic Versioning](https://semver.org/).
|
|
|
55
71
|
|
|
56
72
|
- README screenshots now use absolute CDN URLs so they render on the npm package page.
|
|
57
73
|
|
|
74
|
+
## [0.1.21] - 2026-11-13
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
- Runtime dictionaries and Plugin Manager metadata for Japanese, Spanish,
|
|
79
|
+
French, German, Russian, and Brazilian Portuguese, completing the eight DSH
|
|
80
|
+
languages. Unsupported locales fall back to English.
|
|
81
|
+
|
|
82
|
+
## [0.1.20] - 2026-11-13
|
|
83
|
+
|
|
84
|
+
### Added
|
|
85
|
+
|
|
86
|
+
- Runtime UI localization for Chinese and English. The active DSH language is
|
|
87
|
+
read through `ctx.locale`; other languages fall back to English. Native
|
|
88
|
+
conversation and Plugin Manager metadata continue to follow DSH.
|
|
89
|
+
|
|
58
90
|
## [0.1.19] - 2026-11-13
|
|
59
91
|
|
|
60
92
|
### Fixed
|
|
@@ -194,6 +226,8 @@ project follows [Semantic Versioning](https://semver.org/).
|
|
|
194
226
|
[0.1.17]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.17
|
|
195
227
|
[0.1.18]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.18
|
|
196
228
|
[0.1.19]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.19
|
|
229
|
+
[0.1.20]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.20
|
|
230
|
+
[0.1.21]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.21
|
|
197
231
|
[0.1.13]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.13
|
|
198
232
|
[0.1.14]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.14
|
|
199
233
|
[0.1.15]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.15
|
|
@@ -201,3 +235,5 @@ project follows [Semantic Versioning](https://semver.org/).
|
|
|
201
235
|
[0.1.17]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.17
|
|
202
236
|
[0.1.18]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.18
|
|
203
237
|
[0.1.19]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.19
|
|
238
|
+
[0.1.20]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.20
|
|
239
|
+
[0.1.21]: https://github.com/gbn0219/dsh-ask-from-text/releases/tag/v0.1.21
|
package/README.md
CHANGED
|
@@ -103,7 +103,7 @@ dsh plugin --profile web add /absolute/path/to/dsh-ask-from-text
|
|
|
103
103
|
- 追问回答是真实的 DSH Session,可以使用思考、工具调用、Stop 和原生输入框。
|
|
104
104
|
- 分支只看到父级和祖先内容,不看到兄弟分支,也不会自动获得父级后来新增的内容。
|
|
105
105
|
- 分支对话会出现在普通 Session 列表中,这是正常现象。
|
|
106
|
-
-
|
|
106
|
+
- 界面文案跟随 DSH 语言,内置中文、英文、日语、西班牙语、法语、德语、俄语、巴西葡萄牙语;其他语言回退英文。原生对话区域继续跟随 DSH 自身的语言。
|
|
107
107
|
- 目前主要面向 DSH Desktop;Web 共用同一套 UI,窄屏体验尚未专门优化。
|
|
108
108
|
|
|
109
109
|
## 常见问题
|
|
@@ -225,7 +225,7 @@ These sessions are grouped under a `追问分支` header. Click the header to co
|
|
|
225
225
|
- A follow-up is a real DSH Session. It can use reasoning, tool calls, Stop, and the native composer.
|
|
226
226
|
- A branch sees its parent and ancestors, not siblings, and does not automatically receive later turns added to its parent.
|
|
227
227
|
- Branch conversations also appear in the normal Session list. This is expected.
|
|
228
|
-
- Runtime UI
|
|
228
|
+
- Runtime UI follows the DSH language: Chinese, English, Japanese, Spanish, French, German, Russian, and Brazilian Portuguese are bundled; other languages fall back to English. The native conversation follows DSH.
|
|
229
229
|
- DSH Desktop is the primary target. The Web client shares the same UI, but narrow-screen behavior has not been specifically polished.
|
|
230
230
|
|
|
231
231
|
### FAQ
|
package/client.js
CHANGED
|
@@ -78,6 +78,13 @@ window.__ModuleLoader__.load({
|
|
|
78
78
|
stages: '个节点',
|
|
79
79
|
collapseDock: '收起列表',
|
|
80
80
|
expandDock: '展开列表',
|
|
81
|
+
sidebarGroup: '追问分支',
|
|
82
|
+
context: '上下文',
|
|
83
|
+
contextStart: '上下文起点',
|
|
84
|
+
waiting: '待提问',
|
|
85
|
+
treeNote: '当前模型上下文:{context}。兄弟分支不在其中。',
|
|
86
|
+
anchorMissing: '#{n} 的原文当前不可见,可能已被折叠或尚未加载',
|
|
87
|
+
draftWait: '在下方输入浮窗中提问',
|
|
81
88
|
},
|
|
82
89
|
en: {
|
|
83
90
|
chip: 'Ask',
|
|
@@ -126,8 +133,339 @@ window.__ModuleLoader__.load({
|
|
|
126
133
|
stages: 'nodes',
|
|
127
134
|
collapseDock: 'Collapse list',
|
|
128
135
|
expandDock: 'Expand list',
|
|
136
|
+
sidebarGroup: 'Branches',
|
|
137
|
+
context: 'Context',
|
|
138
|
+
contextStart: 'Context root',
|
|
139
|
+
waiting: 'Waiting for question',
|
|
140
|
+
treeNote: 'Current model context: {context}. Sibling branches are not included.',
|
|
141
|
+
anchorMissing: 'Source text for #{n} is not visible; it may be folded or not loaded yet',
|
|
142
|
+
draftWait: 'Ask in the input window below',
|
|
129
143
|
},
|
|
130
|
-
|
|
144
|
+
ja: {
|
|
145
|
+
chip: '質問',
|
|
146
|
+
chipHint: '選択したテキストについて独立したブランチで質問',
|
|
147
|
+
branch: 'ブランチ',
|
|
148
|
+
branchN: 'ブランチ',
|
|
149
|
+
basedOn: '基準',
|
|
150
|
+
main: 'メイン会話',
|
|
151
|
+
independent: '独立ブランチ',
|
|
152
|
+
draft: '下書き',
|
|
153
|
+
sending: '作成中',
|
|
154
|
+
running: '実行中',
|
|
155
|
+
ready: '作成済み',
|
|
156
|
+
failed: '失敗',
|
|
157
|
+
send: '送信',
|
|
158
|
+
sendingAction: '送信中…',
|
|
159
|
+
quote: '引用済み',
|
|
160
|
+
defaultQuestion: 'この内容についてさらに説明してください。',
|
|
161
|
+
empty: 'ここに質問を追加…',
|
|
162
|
+
sendHint: 'Enter で送信 · Shift + Enter で改行',
|
|
163
|
+
collapse: '折りたたむ',
|
|
164
|
+
input: '入力',
|
|
165
|
+
deleteDraft: '下書きを削除',
|
|
166
|
+
close: '閉じる',
|
|
167
|
+
expand: '拡大',
|
|
168
|
+
restore: 'パネルに戻す',
|
|
169
|
+
back: '戻る',
|
|
170
|
+
forward: '進む',
|
|
171
|
+
stageHint: '戻る / 進むは表示中のブランチを切り替えるだけで、モデルのコンテキストは変わりません。',
|
|
172
|
+
path: 'パス',
|
|
173
|
+
all: 'すべて',
|
|
174
|
+
tree: 'ブランチツリー',
|
|
175
|
+
current: '現在',
|
|
176
|
+
dock: '折りたたんだブランチ',
|
|
177
|
+
open: '開く',
|
|
178
|
+
retry: '再試行',
|
|
179
|
+
error: '送信に失敗しました',
|
|
180
|
+
forkError: 'ブランチを作成できません',
|
|
181
|
+
noSession: '現在のセッションは利用できません',
|
|
182
|
+
tooLong: '選択が長すぎます。短くしてもう一度お試しください',
|
|
183
|
+
content: '本文',
|
|
184
|
+
quoteLabel: '引用元',
|
|
185
|
+
showQuote: '引用を表示',
|
|
186
|
+
hideQuote: '引用を隠す',
|
|
187
|
+
switchBranch: 'このブランチに切り替え',
|
|
188
|
+
stages: '個のノード',
|
|
189
|
+
collapseDock: 'リストを折りたたむ',
|
|
190
|
+
expandDock: 'リストを展開',
|
|
191
|
+
sidebarGroup: '質問ブランチ',
|
|
192
|
+
context: 'コンテキスト',
|
|
193
|
+
contextStart: 'コンテキストの起点',
|
|
194
|
+
waiting: '質問待ち',
|
|
195
|
+
treeNote: '現在のモデルコンテキスト:{context}。兄弟ブランチは含まれません。',
|
|
196
|
+
anchorMissing: '#{n} の原文は現在表示できません。折りたたまれているか、まだ読み込まれていない可能性があります',
|
|
197
|
+
draftWait: '下の入力ウィンドウで質問してください',
|
|
198
|
+
}, es: {
|
|
199
|
+
chip: 'Preguntar',
|
|
200
|
+
chipHint: 'Pregunta sobre el texto seleccionado en una rama independiente',
|
|
201
|
+
branch: 'Rama',
|
|
202
|
+
branchN: 'Rama',
|
|
203
|
+
basedOn: 'basado en',
|
|
204
|
+
main: 'Chat principal',
|
|
205
|
+
independent: 'Rama independiente',
|
|
206
|
+
draft: 'Borrador',
|
|
207
|
+
sending: 'Creando',
|
|
208
|
+
running: 'En ejecución',
|
|
209
|
+
ready: 'Creado',
|
|
210
|
+
failed: 'Falló',
|
|
211
|
+
send: 'Enviar',
|
|
212
|
+
sendingAction: 'Enviando…',
|
|
213
|
+
quote: 'Citado',
|
|
214
|
+
defaultQuestion: 'Explica este contenido con más detalle.',
|
|
215
|
+
empty: 'Añade tu pregunta…',
|
|
216
|
+
sendHint: 'Enter para enviar · Shift + Enter para nueva línea',
|
|
217
|
+
collapse: 'Contraer',
|
|
218
|
+
input: 'Entrada',
|
|
219
|
+
deleteDraft: 'Eliminar borrador',
|
|
220
|
+
close: 'Cerrar',
|
|
221
|
+
expand: 'Ampliar',
|
|
222
|
+
restore: 'Restaurar panel',
|
|
223
|
+
back: 'Atrás',
|
|
224
|
+
forward: 'Adelante',
|
|
225
|
+
stageHint: 'Atrás / Adelante solo cambia la rama que estás viendo; no cambia el contexto del modelo.',
|
|
226
|
+
path: 'Ruta',
|
|
227
|
+
all: 'Todo',
|
|
228
|
+
tree: 'Árbol de ramas',
|
|
229
|
+
current: 'Actual',
|
|
230
|
+
dock: 'Ramas contraídas',
|
|
231
|
+
open: 'Abrir',
|
|
232
|
+
retry: 'Reintentar',
|
|
233
|
+
error: 'Error al enviar',
|
|
234
|
+
forkError: 'No se pudo crear la rama',
|
|
235
|
+
noSession: 'Sesión no disponible',
|
|
236
|
+
tooLong: 'La selección es demasiado larga',
|
|
237
|
+
content: 'Texto',
|
|
238
|
+
quoteLabel: 'Citado de',
|
|
239
|
+
showQuote: 'Mostrar cita',
|
|
240
|
+
hideQuote: 'Ocultar cita',
|
|
241
|
+
switchBranch: 'Cambiar a esta rama',
|
|
242
|
+
stages: 'nodos',
|
|
243
|
+
collapseDock: 'Contraer lista',
|
|
244
|
+
expandDock: 'Expandir lista',
|
|
245
|
+
sidebarGroup: 'Ramas de seguimiento',
|
|
246
|
+
context: 'Contexto',
|
|
247
|
+
contextStart: 'Inicio del contexto',
|
|
248
|
+
waiting: 'Esperando pregunta',
|
|
249
|
+
treeNote: 'Contexto actual del modelo: {context}. Las ramas hermanas no están incluidas.',
|
|
250
|
+
anchorMissing: 'El texto original de #{n} no está visible; puede estar plegado o no haberse cargado',
|
|
251
|
+
draftWait: 'Pregunta en la ventana de entrada de abajo',
|
|
252
|
+
}, fr: {
|
|
253
|
+
chip: 'Demander',
|
|
254
|
+
chipHint: 'Posez une question sur le texte sélectionné dans une branche indépendante',
|
|
255
|
+
branch: 'Branche',
|
|
256
|
+
branchN: 'Branche',
|
|
257
|
+
basedOn: 'basé sur',
|
|
258
|
+
main: 'Conversation principale',
|
|
259
|
+
independent: 'Branche indépendante',
|
|
260
|
+
draft: 'Brouillon',
|
|
261
|
+
sending: 'Création',
|
|
262
|
+
running: 'En cours',
|
|
263
|
+
ready: 'Créé',
|
|
264
|
+
failed: 'Échec',
|
|
265
|
+
send: 'Envoyer',
|
|
266
|
+
sendingAction: 'Envoi…',
|
|
267
|
+
quote: 'Cité',
|
|
268
|
+
defaultQuestion: 'Explique ce passage plus en détail.',
|
|
269
|
+
empty: 'Ajoutez votre question…',
|
|
270
|
+
sendHint: 'Entrée pour envoyer · Maj + Entrée pour un saut de ligne',
|
|
271
|
+
collapse: 'Réduire',
|
|
272
|
+
input: 'Saisie',
|
|
273
|
+
deleteDraft: 'Supprimer le brouillon',
|
|
274
|
+
close: 'Fermer',
|
|
275
|
+
expand: 'Agrandir',
|
|
276
|
+
restore: 'Restaurer le panneau',
|
|
277
|
+
back: 'Retour',
|
|
278
|
+
forward: 'Suivant',
|
|
279
|
+
stageHint: 'Retour / Suivant change uniquement la branche affichée ; cela ne modifie pas le contexte du modèle.',
|
|
280
|
+
path: 'Chemin',
|
|
281
|
+
all: 'Tout',
|
|
282
|
+
tree: 'Arbre des branches',
|
|
283
|
+
current: 'Actuel',
|
|
284
|
+
dock: 'Branches réduites',
|
|
285
|
+
open: 'Ouvrir',
|
|
286
|
+
retry: 'Réessayer',
|
|
287
|
+
error: 'Échec de l\'envoi',
|
|
288
|
+
forkError: 'Impossible de créer la branche',
|
|
289
|
+
noSession: 'Session indisponible',
|
|
290
|
+
tooLong: 'La sélection est trop longue',
|
|
291
|
+
content: 'Texte',
|
|
292
|
+
quoteLabel: 'Cité de',
|
|
293
|
+
showQuote: 'Afficher la citation',
|
|
294
|
+
hideQuote: 'Masquer la citation',
|
|
295
|
+
switchBranch: 'Passer à cette branche',
|
|
296
|
+
stages: 'nœuds',
|
|
297
|
+
collapseDock: 'Réduire la liste',
|
|
298
|
+
expandDock: 'Développer la liste',
|
|
299
|
+
sidebarGroup: 'Branches de suivi',
|
|
300
|
+
context: 'Contexte',
|
|
301
|
+
contextStart: 'Racine du contexte',
|
|
302
|
+
waiting: 'En attente de question',
|
|
303
|
+
treeNote: 'Contexte actuel du modèle : {context}. Les branches sœurs ne sont pas incluses.',
|
|
304
|
+
anchorMissing: 'Le texte source de #{n} n\'est pas visible ; il est peut-être replié ou pas encore chargé',
|
|
305
|
+
draftWait: 'Posez votre question dans la fenêtre de saisie ci-dessous',
|
|
306
|
+
}, de: {
|
|
307
|
+
chip: 'Fragen',
|
|
308
|
+
chipHint: 'Frage zum ausgewählten Text in einem unabhängigen Zweig stellen',
|
|
309
|
+
branch: 'Zweig',
|
|
310
|
+
branchN: 'Zweig',
|
|
311
|
+
basedOn: 'basierend auf',
|
|
312
|
+
main: 'Hauptchat',
|
|
313
|
+
independent: 'Unabhängiger Zweig',
|
|
314
|
+
draft: 'Entwurf',
|
|
315
|
+
sending: 'Wird erstellt',
|
|
316
|
+
running: 'Läuft',
|
|
317
|
+
ready: 'Erstellt',
|
|
318
|
+
failed: 'Fehlgeschlagen',
|
|
319
|
+
send: 'Senden',
|
|
320
|
+
sendingAction: 'Wird gesendet…',
|
|
321
|
+
quote: 'Zitiert',
|
|
322
|
+
defaultQuestion: 'Erkläre diesen Inhalt genauer.',
|
|
323
|
+
empty: 'Frage hier ergänzen…',
|
|
324
|
+
sendHint: 'Enter zum Senden · Umschalt + Enter für neue Zeile',
|
|
325
|
+
collapse: 'Einklappen',
|
|
326
|
+
input: 'Eingabe',
|
|
327
|
+
deleteDraft: 'Entwurf löschen',
|
|
328
|
+
close: 'Schließen',
|
|
329
|
+
expand: 'Vergrößern',
|
|
330
|
+
restore: 'Panel wiederherstellen',
|
|
331
|
+
back: 'Zurück',
|
|
332
|
+
forward: 'Weiter',
|
|
333
|
+
stageHint: 'Zurück / Weiter wechselt nur den angezeigten Zweig; der Modellkontext bleibt unverändert.',
|
|
334
|
+
path: 'Pfad',
|
|
335
|
+
all: 'Alle',
|
|
336
|
+
tree: 'Zweigbaum',
|
|
337
|
+
current: 'Aktuell',
|
|
338
|
+
dock: 'Eingeklappte Zweige',
|
|
339
|
+
open: 'Öffnen',
|
|
340
|
+
retry: 'Erneut versuchen',
|
|
341
|
+
error: 'Senden fehlgeschlagen',
|
|
342
|
+
forkError: 'Zweig konnte nicht erstellt werden',
|
|
343
|
+
noSession: 'Sitzung nicht verfügbar',
|
|
344
|
+
tooLong: 'Auswahl ist zu lang',
|
|
345
|
+
content: 'Text',
|
|
346
|
+
quoteLabel: 'Zitiert aus',
|
|
347
|
+
showQuote: 'Zitat anzeigen',
|
|
348
|
+
hideQuote: 'Zitat ausblenden',
|
|
349
|
+
switchBranch: 'Zu diesem Zweig wechseln',
|
|
350
|
+
stages: 'Knoten',
|
|
351
|
+
collapseDock: 'Liste einklappen',
|
|
352
|
+
expandDock: 'Liste ausklappen',
|
|
353
|
+
sidebarGroup: 'Folgezweige',
|
|
354
|
+
context: 'Kontext',
|
|
355
|
+
contextStart: 'Kontextwurzel',
|
|
356
|
+
waiting: 'Warte auf Frage',
|
|
357
|
+
treeNote: 'Aktueller Modellkontext: {context}. Geschwisterzweige sind nicht enthalten.',
|
|
358
|
+
anchorMissing: 'Der Quelltext von #{n} ist nicht sichtbar; er ist möglicherweise eingeklappt oder noch nicht geladen',
|
|
359
|
+
draftWait: 'Stelle deine Frage im Eingabefenster unten',
|
|
360
|
+
}, ru: {
|
|
361
|
+
chip: 'Спросить',
|
|
362
|
+
chipHint: 'Задать вопрос по выделенному тексту в отдельной ветке',
|
|
363
|
+
branch: 'Ветка',
|
|
364
|
+
branchN: 'Ветка',
|
|
365
|
+
basedOn: 'на основе',
|
|
366
|
+
main: 'Основной чат',
|
|
367
|
+
independent: 'Независимая ветка',
|
|
368
|
+
draft: 'Черновик',
|
|
369
|
+
sending: 'Создание',
|
|
370
|
+
running: 'Выполняется',
|
|
371
|
+
ready: 'Создано',
|
|
372
|
+
failed: 'Ошибка',
|
|
373
|
+
send: 'Отправить',
|
|
374
|
+
sendingAction: 'Отправка…',
|
|
375
|
+
quote: 'Цитата',
|
|
376
|
+
defaultQuestion: 'Объясните этот фрагмент подробнее.',
|
|
377
|
+
empty: 'Добавьте вопрос…',
|
|
378
|
+
sendHint: 'Enter — отправить · Shift + Enter — новая строка',
|
|
379
|
+
collapse: 'Свернуть',
|
|
380
|
+
input: 'Ввод',
|
|
381
|
+
deleteDraft: 'Удалить черновик',
|
|
382
|
+
close: 'Закрыть',
|
|
383
|
+
expand: 'Развернуть',
|
|
384
|
+
restore: 'Вернуть панель',
|
|
385
|
+
back: 'Назад',
|
|
386
|
+
forward: 'Вперёд',
|
|
387
|
+
stageHint: 'Назад / Вперёд переключает только просматриваемую ветку; контекст модели не меняется.',
|
|
388
|
+
path: 'Путь',
|
|
389
|
+
all: 'Все',
|
|
390
|
+
tree: 'Дерево веток',
|
|
391
|
+
current: 'Текущая',
|
|
392
|
+
dock: 'Свёрнутые ветки',
|
|
393
|
+
open: 'Открыть',
|
|
394
|
+
retry: 'Повторить',
|
|
395
|
+
error: 'Не удалось отправить',
|
|
396
|
+
forkError: 'Не удалось создать ветку',
|
|
397
|
+
noSession: 'Сеанс недоступен',
|
|
398
|
+
tooLong: 'Выделение слишком длинное',
|
|
399
|
+
content: 'Текст',
|
|
400
|
+
quoteLabel: 'Цитата из',
|
|
401
|
+
showQuote: 'Показать цитату',
|
|
402
|
+
hideQuote: 'Скрыть цитату',
|
|
403
|
+
switchBranch: 'Перейти к этой ветке',
|
|
404
|
+
stages: 'узлов',
|
|
405
|
+
collapseDock: 'Свернуть список',
|
|
406
|
+
expandDock: 'Развернуть список',
|
|
407
|
+
sidebarGroup: 'Ветки вопросов',
|
|
408
|
+
context: 'Контекст',
|
|
409
|
+
contextStart: 'Начало контекста',
|
|
410
|
+
waiting: 'Ожидание вопроса',
|
|
411
|
+
treeNote: 'Текущий контекст модели: {context}. Ветки-сестры не включены.',
|
|
412
|
+
anchorMissing: 'Исходный текст #{n} не отображается; возможно, он свёрнут или ещё не загружен',
|
|
413
|
+
draftWait: 'Задайте вопрос в окне ввода ниже',
|
|
414
|
+
}, pt: {
|
|
415
|
+
chip: 'Perguntar',
|
|
416
|
+
chipHint: 'Pergunte sobre o texto selecionado em um ramo independente',
|
|
417
|
+
branch: 'Ramo',
|
|
418
|
+
branchN: 'Ramo',
|
|
419
|
+
basedOn: 'com base em',
|
|
420
|
+
main: 'Conversa principal',
|
|
421
|
+
independent: 'Ramo independente',
|
|
422
|
+
draft: 'Rascunho',
|
|
423
|
+
sending: 'Criando',
|
|
424
|
+
running: 'Em execução',
|
|
425
|
+
ready: 'Criado',
|
|
426
|
+
failed: 'Falhou',
|
|
427
|
+
send: 'Enviar',
|
|
428
|
+
sendingAction: 'Enviando…',
|
|
429
|
+
quote: 'Citado',
|
|
430
|
+
defaultQuestion: 'Explique este conteúdo com mais detalhes.',
|
|
431
|
+
empty: 'Adicione sua pergunta…',
|
|
432
|
+
sendHint: 'Enter para enviar · Shift + Enter para nova linha',
|
|
433
|
+
collapse: 'Recolher',
|
|
434
|
+
input: 'Entrada',
|
|
435
|
+
deleteDraft: 'Excluir rascunho',
|
|
436
|
+
close: 'Fechar',
|
|
437
|
+
expand: 'Ampliar',
|
|
438
|
+
restore: 'Restaurar painel',
|
|
439
|
+
back: 'Voltar',
|
|
440
|
+
forward: 'Avançar',
|
|
441
|
+
stageHint: 'Voltar / Avançar apenas altera o ramo exibido; não altera o contexto do modelo.',
|
|
442
|
+
path: 'Caminho',
|
|
443
|
+
all: 'Tudo',
|
|
444
|
+
tree: 'Árvore de ramos',
|
|
445
|
+
current: 'Atual',
|
|
446
|
+
dock: 'Ramos recolhidos',
|
|
447
|
+
open: 'Abrir',
|
|
448
|
+
retry: 'Tentar novamente',
|
|
449
|
+
error: 'Falha ao enviar',
|
|
450
|
+
forkError: 'Não foi possível criar o ramo',
|
|
451
|
+
noSession: 'Sessão indisponível',
|
|
452
|
+
tooLong: 'A seleção é muito longa',
|
|
453
|
+
content: 'Texto',
|
|
454
|
+
quoteLabel: 'Citado de',
|
|
455
|
+
showQuote: 'Mostrar citação',
|
|
456
|
+
hideQuote: 'Ocultar citação',
|
|
457
|
+
switchBranch: 'Mudar para este ramo',
|
|
458
|
+
stages: 'nós',
|
|
459
|
+
collapseDock: 'Recolher lista',
|
|
460
|
+
expandDock: 'Expandir lista',
|
|
461
|
+
sidebarGroup: 'Ramos de acompanhamento',
|
|
462
|
+
context: 'Contexto',
|
|
463
|
+
contextStart: 'Raiz do contexto',
|
|
464
|
+
waiting: 'Aguardando pergunta',
|
|
465
|
+
treeNote: 'Contexto atual do modelo: {context}. Os ramos irmãos não estão incluídos.',
|
|
466
|
+
anchorMissing: 'O texto original de #{n} não está visível; pode estar recolhido ou ainda não carregado',
|
|
467
|
+
draftWait: 'Faça sua pergunta na janela de entrada abaixo',
|
|
468
|
+
}, }
|
|
131
469
|
|
|
132
470
|
let app = null
|
|
133
471
|
|
|
@@ -342,21 +680,21 @@ window.__ModuleLoader__.load({
|
|
|
342
680
|
}
|
|
343
681
|
|
|
344
682
|
function pathLabel(state, branch) {
|
|
345
|
-
return `${
|
|
683
|
+
return `${app.t('main')}${pathOf(state, branch).map(item => ` › #${item.number}`).join('')}`
|
|
346
684
|
}
|
|
347
685
|
|
|
348
686
|
function branchBasis(state, branch) {
|
|
349
|
-
if (!branch.parentBranchId) return `${
|
|
687
|
+
if (!branch.parentBranchId) return `${app.t('basedOn')} ${app.t('main')}`
|
|
350
688
|
const parent = state.branches[branch.parentBranchId]
|
|
351
|
-
return parent ? `${
|
|
689
|
+
return parent ? `${app.t('basedOn')} #${parent.number}` : `${app.t('basedOn')} ${app.t('main')}`
|
|
352
690
|
}
|
|
353
691
|
|
|
354
692
|
function statusLabel(branch) {
|
|
355
|
-
if (branch.status === 'sending') return
|
|
356
|
-
if (branch.status === 'running') return
|
|
357
|
-
if (branch.status === 'error') return
|
|
358
|
-
if (branch.prompted) return
|
|
359
|
-
return
|
|
693
|
+
if (branch.status === 'sending') return app.t('sending')
|
|
694
|
+
if (branch.status === 'running') return app.t('running')
|
|
695
|
+
if (branch.status === 'error') return app.t('failed')
|
|
696
|
+
if (branch.prompted) return app.t('ready')
|
|
697
|
+
return app.t('draft')
|
|
360
698
|
}
|
|
361
699
|
|
|
362
700
|
function colorVars(color) {
|
|
@@ -422,7 +760,15 @@ window.__ModuleLoader__.load({
|
|
|
422
760
|
refs,
|
|
423
761
|
chats,
|
|
424
762
|
get main() { return main },
|
|
425
|
-
t(key) {
|
|
763
|
+
t(key, params) {
|
|
764
|
+
if (ctx.locale) {
|
|
765
|
+
const value = ctx.locale.bind(NS)(key, params)
|
|
766
|
+
if (value && value !== key) return value
|
|
767
|
+
}
|
|
768
|
+
const template = DICT.en[key] ?? key
|
|
769
|
+
if (!params) return template
|
|
770
|
+
return template.replace(/\{(\w+)\}/g, (match, name) => name in params ? String(params[name]) : match)
|
|
771
|
+
},
|
|
426
772
|
subscribe(listener) {
|
|
427
773
|
listeners.add(listener)
|
|
428
774
|
return () => { listeners.delete(listener) }
|
|
@@ -902,7 +1248,7 @@ window.__ModuleLoader__.load({
|
|
|
902
1248
|
const quote = ranges.map(part => part.quote).join('\n').trim()
|
|
903
1249
|
if (!quote) { clearChip(); return }
|
|
904
1250
|
if (quote.length > MAX_QUOTE) {
|
|
905
|
-
notify(
|
|
1251
|
+
notify(app.t('tooLong'))
|
|
906
1252
|
clearChip()
|
|
907
1253
|
return
|
|
908
1254
|
}
|
|
@@ -1102,7 +1448,7 @@ window.__ModuleLoader__.load({
|
|
|
1102
1448
|
|
|
1103
1449
|
function serialize(quote, question) {
|
|
1104
1450
|
const body = String(quote || '').trim().split(/\r?\n/).map(line => `> ${line}`).join('\n')
|
|
1105
|
-
const text = String(question || '').trim() ||
|
|
1451
|
+
const text = String(question || '').trim() || app.t('defaultQuestion')
|
|
1106
1452
|
return `${body}\n\n${text}`
|
|
1107
1453
|
}
|
|
1108
1454
|
|
|
@@ -1160,7 +1506,7 @@ window.__ModuleLoader__.load({
|
|
|
1160
1506
|
await ensureReference(branch)
|
|
1161
1507
|
}
|
|
1162
1508
|
const reference = refs.get(branch.id)
|
|
1163
|
-
if (!reference) throw new Error(
|
|
1509
|
+
if (!reference) throw new Error(app.t('noSession'))
|
|
1164
1510
|
const text = serialize(branch.anchor.quote, branch.question)
|
|
1165
1511
|
const echo = reference.binding.session.beginSubmission({
|
|
1166
1512
|
mode: 'queue',
|
|
@@ -1175,7 +1521,7 @@ window.__ModuleLoader__.load({
|
|
|
1175
1521
|
)
|
|
1176
1522
|
if (!result.ok) {
|
|
1177
1523
|
branch.status = 'error'
|
|
1178
|
-
branch.error = result.error?.message ||
|
|
1524
|
+
branch.error = result.error?.message || app.t('error')
|
|
1179
1525
|
emit()
|
|
1180
1526
|
return false
|
|
1181
1527
|
}
|
|
@@ -1204,7 +1550,7 @@ window.__ModuleLoader__.load({
|
|
|
1204
1550
|
try {
|
|
1205
1551
|
await ensureReference(branch)
|
|
1206
1552
|
const reference = refs.get(branch.id)
|
|
1207
|
-
if (!reference) throw new Error(
|
|
1553
|
+
if (!reference) throw new Error(app.t('noSession'))
|
|
1208
1554
|
const echo = reference.binding.session.beginSubmission({
|
|
1209
1555
|
mode: 'queue',
|
|
1210
1556
|
text,
|
|
@@ -1218,7 +1564,7 @@ window.__ModuleLoader__.load({
|
|
|
1218
1564
|
)
|
|
1219
1565
|
if (!result.ok) {
|
|
1220
1566
|
branch.status = 'error'
|
|
1221
|
-
branch.error = result.error?.message ||
|
|
1567
|
+
branch.error = result.error?.message || app.t('error')
|
|
1222
1568
|
emit()
|
|
1223
1569
|
return false
|
|
1224
1570
|
}
|
|
@@ -1310,7 +1656,7 @@ window.__ModuleLoader__.load({
|
|
|
1310
1656
|
if (other !== header) other.remove()
|
|
1311
1657
|
}
|
|
1312
1658
|
if (header.nextSibling !== first) firstParent.insertBefore(header, first)
|
|
1313
|
-
const label = `${state.sidebarCollapsed ? '▸' : '▾'}
|
|
1659
|
+
const label = `${state.sidebarCollapsed ? '▸' : '▾'} ${app.t('sidebarGroup')} · ${rows.length}`
|
|
1314
1660
|
if (header.textContent !== label) header.textContent = label
|
|
1315
1661
|
for (const row of rows) row.classList.toggle('ifu-sidebar-hidden', state.sidebarCollapsed)
|
|
1316
1662
|
|
|
@@ -1424,7 +1770,7 @@ window.__ModuleLoader__.load({
|
|
|
1424
1770
|
// giving up on this attempt.
|
|
1425
1771
|
if (navigator && attempt === 0) navigator.click()
|
|
1426
1772
|
if (attempt < 14) setTimeout(() => scrollBranchIntoView(branch, attempt + 1), 100)
|
|
1427
|
-
else notify(
|
|
1773
|
+
else notify(app.t('anchorMissing', { n: branch.number }))
|
|
1428
1774
|
return
|
|
1429
1775
|
}
|
|
1430
1776
|
if (navigator && attempt === 0) navigator.click()
|
|
@@ -1852,14 +2198,14 @@ window.__ModuleLoader__.load({
|
|
|
1852
2198
|
}
|
|
1853
2199
|
return h('div', { className: 'ifu-compose' },
|
|
1854
2200
|
h('div', { className: 'ifu-quote', title: branch.anchor.quote },
|
|
1855
|
-
h('div', { className: 'ifu-quote-label' }, `${
|
|
2201
|
+
h('div', { className: 'ifu-quote-label' }, `${app.t('quote')} · ${app.t('basedOn')} ${branch.parentBranchId ? `#${app.state.branches[branch.parentBranchId]?.number ?? ''}` : app.t('main')}`),
|
|
1856
2202
|
h('div', { className: 'ifu-quote-text' }, branch.anchor.quote.length > 220 ? `${branch.anchor.quote.slice(0, 219)}…` : branch.anchor.quote),
|
|
1857
2203
|
),
|
|
1858
2204
|
h('textarea', {
|
|
1859
2205
|
ref: areaRef,
|
|
1860
2206
|
className: 'ifu-textarea',
|
|
1861
2207
|
value: text,
|
|
1862
|
-
placeholder:
|
|
2208
|
+
placeholder: app.t('empty'),
|
|
1863
2209
|
rows: 3,
|
|
1864
2210
|
onChange: event => { setText(event.target.value); app.setDraftText(branch.id, event.target.value) },
|
|
1865
2211
|
onKeyDown: event => {
|
|
@@ -1871,14 +2217,14 @@ window.__ModuleLoader__.load({
|
|
|
1871
2217
|
}),
|
|
1872
2218
|
branch.error ? h('div', { className: 'ifu-error', role: 'alert' }, branch.error) : null,
|
|
1873
2219
|
h('div', { className: 'ifu-compose-foot' },
|
|
1874
|
-
h('span', { className: 'ifu-hint' },
|
|
2220
|
+
h('span', { className: 'ifu-hint' }, app.t('sendHint')),
|
|
1875
2221
|
h('div', { className: 'ifu-grow' }),
|
|
1876
2222
|
h('button', {
|
|
1877
2223
|
type: 'button',
|
|
1878
2224
|
className: 'ifu-send',
|
|
1879
2225
|
disabled: sending,
|
|
1880
2226
|
onClick: submit,
|
|
1881
|
-
}, sending ?
|
|
2227
|
+
}, sending ? app.t('sendingAction') : (branch.error ? app.t('retry') : app.t('send'))),
|
|
1882
2228
|
),
|
|
1883
2229
|
)
|
|
1884
2230
|
}
|
|
@@ -1887,7 +2233,7 @@ window.__ModuleLoader__.load({
|
|
|
1887
2233
|
const { branch, SessionProvider, renderSlot } = props
|
|
1888
2234
|
const reference = app.refs.get(branch.id)
|
|
1889
2235
|
if (!reference) {
|
|
1890
|
-
return h('div', { className: 'ifu-loading' }, branch.error ||
|
|
2236
|
+
return h('div', { className: 'ifu-loading' }, branch.error || app.t('sending'))
|
|
1891
2237
|
}
|
|
1892
2238
|
return h(SessionProvider, { session: reference },
|
|
1893
2239
|
h('div', {
|
|
@@ -1935,18 +2281,18 @@ window.__ModuleLoader__.load({
|
|
|
1935
2281
|
...colorVars(branch.color),
|
|
1936
2282
|
},
|
|
1937
2283
|
role: 'dialog',
|
|
1938
|
-
'aria-label': `${
|
|
2284
|
+
'aria-label': `${app.t('branchN')} #${branch.number} ${app.t('input')}`,
|
|
1939
2285
|
},
|
|
1940
2286
|
h('header', { className: 'ifu-head', onPointerDown: event => app.startPanelDrag(branch.id, event, 'input') },
|
|
1941
2287
|
h('span', { className: 'ifu-dot' }),
|
|
1942
2288
|
h('div', { className: 'ifu-title-wrap' },
|
|
1943
|
-
h('div', { className: 'ifu-title' }, `${
|
|
2289
|
+
h('div', { className: 'ifu-title' }, `${app.t('input')} · #${branch.number}`),
|
|
1944
2290
|
h('div', { className: 'ifu-sub' }, statusLabel(branch)),
|
|
1945
2291
|
),
|
|
1946
2292
|
h('div', { className: 'ifu-grow' }),
|
|
1947
|
-
h(IconButton, { title:
|
|
2293
|
+
h(IconButton, { title: app.t('collapse'), onClick: () => app.collapse(branch.id) }, '—'),
|
|
1948
2294
|
branch.sessionId ? null : h(IconButton, {
|
|
1949
|
-
title:
|
|
2295
|
+
title: app.t('deleteDraft'),
|
|
1950
2296
|
className: 'ifu-danger',
|
|
1951
2297
|
onClick: () => app.deleteDraft(branch.id),
|
|
1952
2298
|
}, '⌫'),
|
|
@@ -1956,7 +2302,7 @@ window.__ModuleLoader__.load({
|
|
|
1956
2302
|
ref: areaRef,
|
|
1957
2303
|
className: 'ifu-textarea',
|
|
1958
2304
|
value: text,
|
|
1959
|
-
placeholder:
|
|
2305
|
+
placeholder: app.t('empty'),
|
|
1960
2306
|
rows: 3,
|
|
1961
2307
|
onChange: event => { setText(event.target.value); app.setInputText(branch.id, event.target.value) },
|
|
1962
2308
|
onKeyDown: event => {
|
|
@@ -1968,14 +2314,14 @@ window.__ModuleLoader__.load({
|
|
|
1968
2314
|
}),
|
|
1969
2315
|
branch.error ? h('div', { className: 'ifu-error', role: 'alert' }, branch.error) : null,
|
|
1970
2316
|
h('div', { className: 'ifu-compose-foot' },
|
|
1971
|
-
h('span', { className: 'ifu-hint' },
|
|
2317
|
+
h('span', { className: 'ifu-hint' }, app.t('sendHint')),
|
|
1972
2318
|
h('div', { className: 'ifu-grow' }),
|
|
1973
2319
|
h('button', {
|
|
1974
2320
|
type: 'button',
|
|
1975
2321
|
className: 'ifu-send',
|
|
1976
2322
|
disabled: sending,
|
|
1977
2323
|
onClick: submit,
|
|
1978
|
-
}, sending ?
|
|
2324
|
+
}, sending ? app.t('sendingAction') : app.t('send')),
|
|
1979
2325
|
),
|
|
1980
2326
|
),
|
|
1981
2327
|
...['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'].map(direction => h('div', {
|
|
@@ -1991,7 +2337,7 @@ window.__ModuleLoader__.load({
|
|
|
1991
2337
|
useVersion()
|
|
1992
2338
|
if (!branch.prompted) return h(InputWindow, { key: `${branch.id}-input`, branch })
|
|
1993
2339
|
const parent = branch.parentBranchId ? app.state.branches[branch.parentBranchId] : null
|
|
1994
|
-
const basis = parent ? `${
|
|
2340
|
+
const basis = parent ? `${app.t('basedOn')} #${parent.number}` : `${app.t('basedOn')} ${app.t('main')}`
|
|
1995
2341
|
const reference = app.refs.get(branch.id)
|
|
1996
2342
|
const showThread = branch.prompted && reference && !branch.loading
|
|
1997
2343
|
const showDraft = !branch.prompted
|
|
@@ -2012,20 +2358,20 @@ window.__ModuleLoader__.load({
|
|
|
2012
2358
|
...colorVars(branch.color),
|
|
2013
2359
|
},
|
|
2014
2360
|
role: 'dialog',
|
|
2015
|
-
'aria-label': `${
|
|
2361
|
+
'aria-label': `${app.t('branchN')} #${branch.number}`,
|
|
2016
2362
|
},
|
|
2017
2363
|
h('header', { className: 'ifu-head', onPointerDown: event => app.startPanelDrag(branch.id, event) },
|
|
2018
2364
|
h('span', { className: 'ifu-dot' }),
|
|
2019
2365
|
h('div', { className: 'ifu-title-wrap' },
|
|
2020
|
-
h('div', { className: 'ifu-title' }, `${
|
|
2366
|
+
h('div', { className: 'ifu-title' }, `${app.t('branchN')} #${branch.number}`),
|
|
2021
2367
|
h('div', { className: 'ifu-sub' }, `${basis} · ${statusLabel(branch)}`),
|
|
2022
2368
|
),
|
|
2023
2369
|
h('div', { className: 'ifu-grow' }),
|
|
2024
|
-
h(IconButton, { title:
|
|
2025
|
-
h(IconButton, { title:
|
|
2370
|
+
h(IconButton, { title: app.t('expand'), onClick: () => app.promote(branch.id), disabled: !branch.prompted || !branch.sessionId }, '↗'),
|
|
2371
|
+
h(IconButton, { title: app.t('collapse'), onClick: () => app.collapse(branch.id) }, '—'),
|
|
2026
2372
|
branch.sessionId || branch.prompted
|
|
2027
|
-
? h(IconButton, { title:
|
|
2028
|
-
: h(IconButton, { title:
|
|
2373
|
+
? h(IconButton, { title: app.t('close'), onClick: () => app.collapse(branch.id) }, '✕')
|
|
2374
|
+
: h(IconButton, { title: app.t('deleteDraft'), className: 'ifu-danger', onClick: () => app.deleteDraft(branch.id) }, '⌫'),
|
|
2029
2375
|
),
|
|
2030
2376
|
h('div', { className: 'ifu-panel-body' },
|
|
2031
2377
|
showThread
|
|
@@ -2033,12 +2379,12 @@ window.__ModuleLoader__.load({
|
|
|
2033
2379
|
: showDraft
|
|
2034
2380
|
? h('div', { className: 'ifu-compose-center' },
|
|
2035
2381
|
h('div', { className: 'ifu-draft-quote' },
|
|
2036
|
-
h('div', { className: 'ifu-quote-label' }, `${
|
|
2382
|
+
h('div', { className: 'ifu-quote-label' }, `${app.t('quote')} · ${basis}`),
|
|
2037
2383
|
h('div', { className: 'ifu-quote-text' }, branch.anchor.quote),
|
|
2038
|
-
h('div', { className: 'ifu-draft-wait' }, '
|
|
2384
|
+
h('div', { className: 'ifu-draft-wait' }, app.t('draftWait')),
|
|
2039
2385
|
),
|
|
2040
2386
|
)
|
|
2041
|
-
: h('div', { className: 'ifu-loading' }, branch.error ||
|
|
2387
|
+
: h('div', { className: 'ifu-loading' }, branch.error || app.t('sending')),
|
|
2042
2388
|
),
|
|
2043
2389
|
...['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'].map(direction => h('div', {
|
|
2044
2390
|
key: direction,
|
|
@@ -2053,11 +2399,11 @@ window.__ModuleLoader__.load({
|
|
|
2053
2399
|
function StageQuote(props) {
|
|
2054
2400
|
const { branch } = props
|
|
2055
2401
|
const parent = branch.parentBranchId ? app.state.branches[branch.parentBranchId] : null
|
|
2056
|
-
const basis = parent ? `#${parent.number}` :
|
|
2402
|
+
const basis = parent ? `#${parent.number}` : app.t('main')
|
|
2057
2403
|
return h('div', { className: 'ifu-stage-quote', title: branch.anchor.quote },
|
|
2058
2404
|
h('div', { className: 'ifu-stage-quote-label' },
|
|
2059
2405
|
h('span', { className: 'ifu-dot' }),
|
|
2060
|
-
`${
|
|
2406
|
+
`${app.t('quote')} · ${app.t('basedOn')} ${basis}`,
|
|
2061
2407
|
),
|
|
2062
2408
|
h('div', { className: 'ifu-stage-quote-text' }, branch.anchor.quote),
|
|
2063
2409
|
)
|
|
@@ -2079,7 +2425,7 @@ window.__ModuleLoader__.load({
|
|
|
2079
2425
|
observer.observe(host, { childList: true, subtree: true, characterData: true })
|
|
2080
2426
|
return () => observer.disconnect()
|
|
2081
2427
|
}, [branch.id])
|
|
2082
|
-
if (!reference) return h('div', { className: 'ifu-loading' }, branch.error ||
|
|
2428
|
+
if (!reference) return h('div', { className: 'ifu-loading' }, branch.error || app.t('sending'))
|
|
2083
2429
|
return h(SessionProvider, { session: reference },
|
|
2084
2430
|
h('div', {
|
|
2085
2431
|
ref: hostRef,
|
|
@@ -2106,24 +2452,24 @@ window.__ModuleLoader__.load({
|
|
|
2106
2452
|
? rows.filter(row => pathIds.has(row.branch.id))
|
|
2107
2453
|
: rows
|
|
2108
2454
|
const contextText = path.length > 0
|
|
2109
|
-
? `${
|
|
2110
|
-
:
|
|
2455
|
+
? `${app.t('main')}${path.map(branch => ` → #${branch.number}`).join('')}`
|
|
2456
|
+
: app.t('main')
|
|
2111
2457
|
return h('aside', { className: 'ifu-tree', 'data-ifu-no-select': '' },
|
|
2112
2458
|
h('div', { className: 'ifu-tree-head' },
|
|
2113
|
-
h('span', null,
|
|
2459
|
+
h('span', null, app.t('tree')),
|
|
2114
2460
|
h('div', { className: 'ifu-tree-tabs' },
|
|
2115
2461
|
h('button', {
|
|
2116
2462
|
type: 'button',
|
|
2117
2463
|
className: `ifu-tree-tab ${scope === 'path' ? 'is-active' : ''}`,
|
|
2118
2464
|
onClick: () => setScope('path'),
|
|
2119
|
-
}, '
|
|
2465
|
+
}, app.t('path')),
|
|
2120
2466
|
h('button', {
|
|
2121
2467
|
type: 'button',
|
|
2122
2468
|
className: `ifu-tree-tab ${scope === 'all' ? 'is-active' : ''}`,
|
|
2123
2469
|
onClick: () => setScope('all'),
|
|
2124
|
-
}, '
|
|
2470
|
+
}, app.t('all')),
|
|
2125
2471
|
),
|
|
2126
|
-
h('button', { type: 'button', className: 'ifu-icon', title:
|
|
2472
|
+
h('button', { type: 'button', className: 'ifu-icon', title: app.t('close'), onClick: () => app.toggleTree() }, '✕'),
|
|
2127
2473
|
),
|
|
2128
2474
|
h('div', { className: 'ifu-tree-list' },
|
|
2129
2475
|
h('div', {
|
|
@@ -2138,15 +2484,15 @@ window.__ModuleLoader__.load({
|
|
|
2138
2484
|
},
|
|
2139
2485
|
},
|
|
2140
2486
|
h('span', { className: 'ifu-dot' }),
|
|
2141
|
-
h('span', { className: 'ifu-tree-root-name' },
|
|
2487
|
+
h('span', { className: 'ifu-tree-root-name' }, app.t('main')),
|
|
2142
2488
|
h('span', { className: 'ifu-tree-root-tag' }, 'ROOT'),
|
|
2143
|
-
h('span', { className: 'ifu-tree-root-meta' }, '
|
|
2489
|
+
h('span', { className: 'ifu-tree-root-meta' }, app.t('contextStart')),
|
|
2144
2490
|
),
|
|
2145
2491
|
visibleRows.map(({ branch, depth }) => {
|
|
2146
2492
|
const isDraft = !branch.sessionId && !branch.prompted
|
|
2147
2493
|
const parent = branch.parentBranchId ? state.branches[branch.parentBranchId] : null
|
|
2148
|
-
const parentLabel = parent ? `${
|
|
2149
|
-
const title = branch.question || branch.anchor.quote || '
|
|
2494
|
+
const parentLabel = parent ? `${app.t('main')} · #${parent.number}` : app.t('main')
|
|
2495
|
+
const title = branch.question || branch.anchor.quote || app.t('waiting')
|
|
2150
2496
|
const inPath = pathIds.has(branch.id)
|
|
2151
2497
|
return h('div', {
|
|
2152
2498
|
key: branch.id,
|
|
@@ -2172,34 +2518,34 @@ window.__ModuleLoader__.load({
|
|
|
2172
2518
|
} else if (branch.prompted && branch.sessionId) app.promote(branch.id)
|
|
2173
2519
|
else app.openPanel(branch.id)
|
|
2174
2520
|
},
|
|
2175
|
-
title: `${
|
|
2521
|
+
title: `${app.t('switchBranch')} #${branch.number}`,
|
|
2176
2522
|
},
|
|
2177
2523
|
h('div', { className: 'ifu-tree-top' },
|
|
2178
2524
|
h('span', { className: 'ifu-dot' }),
|
|
2179
2525
|
h('span', { className: 'ifu-tree-num' }, `#${branch.number}`),
|
|
2180
2526
|
h('span', { className: 'ifu-tree-title' }, snippet(title, 36)),
|
|
2181
2527
|
branch.id === activeId
|
|
2182
|
-
? h('span', { className: 'ifu-tree-tag' },
|
|
2528
|
+
? h('span', { className: 'ifu-tree-tag' }, app.t('current'))
|
|
2183
2529
|
: inPath
|
|
2184
|
-
? h('span', { className: 'ifu-tree-tag is-context' }, '
|
|
2530
|
+
? h('span', { className: 'ifu-tree-tag is-context' }, app.t('context'))
|
|
2185
2531
|
: null,
|
|
2186
2532
|
isDraft ? h('button', {
|
|
2187
2533
|
type: 'button',
|
|
2188
2534
|
className: 'ifu-tree-delete',
|
|
2189
|
-
title:
|
|
2535
|
+
title: app.t('deleteDraft'),
|
|
2190
2536
|
onClick: (event) => { event.stopPropagation(); app.deleteDraft(branch.id) },
|
|
2191
2537
|
}, '⌫') : null,
|
|
2192
2538
|
),
|
|
2193
2539
|
h('div', { className: 'ifu-tree-quote' }, snippet(branch.anchor.quote, 72)),
|
|
2194
2540
|
h('div', { className: 'ifu-tree-meta' },
|
|
2195
|
-
h('span', null, `${
|
|
2541
|
+
h('span', null, `${app.t('basedOn')} ${parentLabel}`),
|
|
2196
2542
|
h('span', null, statusLabel(branch)),
|
|
2197
2543
|
),
|
|
2198
2544
|
)
|
|
2199
2545
|
}),
|
|
2200
2546
|
),
|
|
2201
2547
|
h('div', { className: 'ifu-tree-note' },
|
|
2202
|
-
|
|
2548
|
+
app.t('treeNote', { context: contextText }),
|
|
2203
2549
|
),
|
|
2204
2550
|
)
|
|
2205
2551
|
}
|
|
@@ -2223,23 +2569,23 @@ window.__ModuleLoader__.load({
|
|
|
2223
2569
|
type: 'button',
|
|
2224
2570
|
className: 'ifu-stage-back',
|
|
2225
2571
|
onClick: () => index <= 0 ? app.stageClose() : app.stageGo(-1),
|
|
2226
|
-
title: index <= 0 ?
|
|
2227
|
-
}, `← ${
|
|
2572
|
+
title: index <= 0 ? app.t('main') : app.t('back'),
|
|
2573
|
+
}, `← ${app.t('back')}`),
|
|
2228
2574
|
h('span', { className: 'ifu-stage-count' }, `${index + 1}/${total}`),
|
|
2229
2575
|
h('button', {
|
|
2230
2576
|
type: 'button',
|
|
2231
2577
|
className: 'ifu-stage-back',
|
|
2232
2578
|
disabled: index >= total - 1,
|
|
2233
2579
|
onClick: () => app.stageGo(1),
|
|
2234
|
-
},
|
|
2580
|
+
}, app.t('forward'), ' →'),
|
|
2235
2581
|
h('span', { className: 'ifu-stage-divider' }),
|
|
2236
2582
|
h('div', { className: 'ifu-crumbs' },
|
|
2237
2583
|
h('button', {
|
|
2238
2584
|
type: 'button',
|
|
2239
2585
|
className: 'ifu-crumb-btn',
|
|
2240
2586
|
onClick: () => app.stageClose(),
|
|
2241
|
-
title:
|
|
2242
|
-
},
|
|
2587
|
+
title: app.t('main'),
|
|
2588
|
+
}, app.t('main')),
|
|
2243
2589
|
...path.flatMap(item => [
|
|
2244
2590
|
h('span', { key: `sep-${item.id}`, className: 'ifu-crumb-sep' }, '›'),
|
|
2245
2591
|
h('button', {
|
|
@@ -2250,23 +2596,23 @@ window.__ModuleLoader__.load({
|
|
|
2250
2596
|
if (item.id === branch.id) return
|
|
2251
2597
|
app.promote(item.id)
|
|
2252
2598
|
},
|
|
2253
|
-
title: `${
|
|
2599
|
+
title: `${app.t('switchBranch')} #${item.number}`,
|
|
2254
2600
|
}, `#${item.number}`),
|
|
2255
2601
|
]),
|
|
2256
2602
|
),
|
|
2257
|
-
h('span', { className: 'ifu-context-chip' },
|
|
2603
|
+
h('span', { className: 'ifu-context-chip' }, `${app.t('context')} · ${path.length} ${app.t('stages')}`),
|
|
2258
2604
|
h('div', { className: 'ifu-grow' }),
|
|
2259
2605
|
h('span', { className: 'ifu-stage-status' }, statusLabel(branch)),
|
|
2260
|
-
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.toggleTree() }, '▤ ',
|
|
2261
|
-
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.stageRestore() }, '↘ ',
|
|
2262
|
-
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.stageClose() }, '✕ ',
|
|
2606
|
+
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.toggleTree() }, '▤ ', app.t('tree')),
|
|
2607
|
+
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.stageRestore() }, '↘ ', app.t('restore')),
|
|
2608
|
+
h('button', { type: 'button', className: 'ifu-stage-action', onClick: () => app.stageClose() }, '✕ ', app.t('close')),
|
|
2263
2609
|
),
|
|
2264
|
-
h('div', { className: 'ifu-stage-tip' },
|
|
2610
|
+
h('div', { className: 'ifu-stage-tip' }, app.t('stageHint')),
|
|
2265
2611
|
h('div', { className: 'ifu-stage-body' },
|
|
2266
2612
|
h(StageQuote, { branch }),
|
|
2267
2613
|
reference && !branch.loading
|
|
2268
2614
|
? h(StageThread, { key: branch.id, branch, SessionProvider, renderSlot })
|
|
2269
|
-
: h('div', { className: 'ifu-loading' }, branch.error ||
|
|
2615
|
+
: h('div', { className: 'ifu-loading' }, branch.error || app.t('sending')),
|
|
2270
2616
|
),
|
|
2271
2617
|
h(BranchTree),
|
|
2272
2618
|
)
|
|
@@ -2403,7 +2749,7 @@ window.__ModuleLoader__.load({
|
|
|
2403
2749
|
className: 'ifu-dock-collapsed',
|
|
2404
2750
|
'data-ifu-dock': '',
|
|
2405
2751
|
onClick: () => app.toggleDock(),
|
|
2406
|
-
}, `◉ ${
|
|
2752
|
+
}, `◉ ${app.t('dock')} · ${branches.length}`)
|
|
2407
2753
|
}
|
|
2408
2754
|
const dockStyle = state.dock
|
|
2409
2755
|
? {
|
|
@@ -2417,11 +2763,11 @@ window.__ModuleLoader__.load({
|
|
|
2417
2763
|
: {}
|
|
2418
2764
|
return h('aside', { className: 'ifu-dock', 'data-ifu-dock': '', style: dockStyle },
|
|
2419
2765
|
h('div', { className: 'ifu-dock-head', onPointerDown: event => app.startDockDrag(event) },
|
|
2420
|
-
h('span', null, `${
|
|
2766
|
+
h('span', null, `${app.t('dock')} · ${branches.length}`),
|
|
2421
2767
|
h('button', {
|
|
2422
2768
|
type: 'button',
|
|
2423
2769
|
className: 'ifu-dock-toggle',
|
|
2424
|
-
title:
|
|
2770
|
+
title: app.t('collapseDock'),
|
|
2425
2771
|
onClick: () => app.closeDock(),
|
|
2426
2772
|
}, '—'),
|
|
2427
2773
|
),
|
|
@@ -2440,7 +2786,7 @@ window.__ModuleLoader__.load({
|
|
|
2440
2786
|
event.preventDefault()
|
|
2441
2787
|
app.revealBranch(branch.id)
|
|
2442
2788
|
},
|
|
2443
|
-
title: `${
|
|
2789
|
+
title: `${app.t('switchBranch')}: #${branch.number}`,
|
|
2444
2790
|
},
|
|
2445
2791
|
h('span', { className: 'ifu-dot', style: colorVars(branch.color) }),
|
|
2446
2792
|
h('span', { className: 'ifu-dock-num' }, `#${branch.number}`),
|
|
@@ -2449,7 +2795,7 @@ window.__ModuleLoader__.load({
|
|
|
2449
2795
|
isDraft ? h('button', {
|
|
2450
2796
|
type: 'button',
|
|
2451
2797
|
className: 'ifu-dock-delete',
|
|
2452
|
-
title:
|
|
2798
|
+
title: app.t('deleteDraft'),
|
|
2453
2799
|
onClick: (event) => { event.stopPropagation(); app.deleteDraft(branch.id) },
|
|
2454
2800
|
}, '⌫') : null,
|
|
2455
2801
|
)
|
|
@@ -2471,14 +2817,14 @@ window.__ModuleLoader__.load({
|
|
|
2471
2817
|
className: 'ifu-chip',
|
|
2472
2818
|
'data-ifu-chip': '',
|
|
2473
2819
|
style: { left: `${chip.x}px`, top: `${chip.y}px` },
|
|
2474
|
-
title:
|
|
2820
|
+
title: app.t('chipHint'),
|
|
2475
2821
|
onMouseDown: event => event.preventDefault(),
|
|
2476
2822
|
onClick: () => {
|
|
2477
2823
|
const x = clamp(chip.x - 120, 12, window.innerWidth - PANEL_WIDTH - 12)
|
|
2478
2824
|
const y = clamp(chip.y + 38, 12, window.innerHeight - 320)
|
|
2479
2825
|
app.openDraft(chip.anchor, x, y)
|
|
2480
2826
|
},
|
|
2481
|
-
}, '✦ ',
|
|
2827
|
+
}, '✦ ', app.t('chip'))
|
|
2482
2828
|
}
|
|
2483
2829
|
|
|
2484
2830
|
function Notice() {
|
|
@@ -2706,7 +3052,8 @@ window.__ModuleLoader__.load({
|
|
|
2706
3052
|
apply(ctx) {
|
|
2707
3053
|
app = createApp(ctx)
|
|
2708
3054
|
app.load()
|
|
2709
|
-
ctx.effect(() => ctx.locale.register(NS,
|
|
3055
|
+
ctx.effect(() => ctx.locale.register(NS, DICT), 'inline-followup: locale')
|
|
3056
|
+
ctx.effect(() => ctx.on('locale/change', () => app.emit()), 'inline-followup: locale-change')
|
|
2710
3057
|
ctx.effect(() => app.install(), 'inline-followup: lifetime')
|
|
2711
3058
|
ctx.slots.inject('shell.overlay', () => ctx.slots.register({
|
|
2712
3059
|
name: 'shell.overlay',
|
package/locale/de.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "Aus Text nachfragen",
|
|
4
|
+
"description": "Text in einer abgeschlossenen Assistant-Antwort auswählen, in einem unabhängigen Eingabefenster nachfragen und in einem echten Session-Zweig weiterarbeiten. Farbige Markierungen, Zweigbaum, Bühne und einklappbare Seitenleisten-Gruppe. Zweige sind echte Sessions; gesendete Zweige können nur archiviert werden."
|
|
5
|
+
}
|
|
6
|
+
}
|
package/locale/es.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "Preguntar desde el texto",
|
|
4
|
+
"description": "Selecciona texto en una respuesta completa del assistant, pregunta en una ventana de entrada independiente y continúa en una rama de Session real. Incluye marcas de color, árbol de ramas, escenario y un grupo plegable en la barra lateral. Las ramas son Sessions reales; las ramas enviadas solo se pueden archivar."
|
|
5
|
+
}
|
|
6
|
+
}
|
package/locale/fr.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "Demander depuis le texte",
|
|
4
|
+
"description": "Sélectionnez du texte dans une réponse finalisée de l’assistant, posez votre question dans une fenêtre de saisie indépendante et continuez dans une branche de Session réelle. Marques colorées, arbre des branches, scène et groupe repliable dans la barre latérale. Les branches sont de vraies Sessions ; les branches envoyées ne peuvent être qu’archivées."
|
|
5
|
+
}
|
|
6
|
+
}
|
package/locale/ja.json
ADDED
package/locale/pt.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "Perguntar a partir do texto",
|
|
4
|
+
"description": "Selecione texto em uma resposta concluída do assistant, pergunte em uma janela de entrada independente e continue em um ramo de Session real. Marcas coloridas, árvore de ramos, palco e grupo recolhível na barra lateral. Os ramos são Sessions reais; ramos enviados só podem ser arquivados."
|
|
5
|
+
}
|
|
6
|
+
}
|
package/locale/ru.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "Спросить по тексту",
|
|
4
|
+
"description": "Выделите текст в завершённом ответе assistant, задайте вопрос в отдельном окне ввода и продолжите в настоящей ветке Session. Цветные метки, дерево веток, сцена и сворачиваемая группа в боковой панели. Ветки — это реальные Sessions; отправленные ветки можно только архивировать."
|
|
5
|
+
}
|
|
6
|
+
}
|
package/package.json
CHANGED