privateboard 0.1.9 → 0.1.11

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/public/i18n.js ADDED
@@ -0,0 +1,1990 @@
1
+ /* ═══════════════════════════════════════════
2
+ UI i18n · en / zh-CN
3
+ Storage: boardroom.uiLocale ("en" | "zh")
4
+ Event: document "boardroom:locale" · detail.locale
5
+ ═══════════════════════════════════════════ */
6
+ (function (root) {
7
+ const STORAGE_KEY = "boardroom.uiLocale";
8
+
9
+ const STR = {
10
+ en: {
11
+ locale_en: "EN",
12
+ locale_zh: "中文",
13
+ aria_language: "Language",
14
+
15
+ brand_privateboard: "PRIVATEBOARD",
16
+ brand_control: "CONTROL",
17
+ classification: "PRIVATE ACCESS",
18
+ topbar_sync: "SYNC:",
19
+ topbar_uid: "UID:",
20
+ topbar_room: "ROOM:",
21
+
22
+ sidebar_head: "// CONTROL",
23
+ sidebar_tab_rooms: "Rooms",
24
+ sidebar_tab_agents: "Agents",
25
+ sidebar_new_room: "New room",
26
+ sidebar_all_reports: "All Reports",
27
+ sidebar_all_notes: "All Notes",
28
+ sidebar_new_agent: "New agent",
29
+ sidebar_host: "// host",
30
+ sidebar_collapse: "Collapse sidebar",
31
+ sidebar_expand: "Expand sidebar",
32
+ sidebar_summary: "{live} LIVE / {agents} AGENTS",
33
+
34
+ queue_speaking_queue: "speaking queue",
35
+ queue_mode: "mode:",
36
+ queue_toggle: "collapse / expand",
37
+ queue_foot_hint:
38
+ "type to interject · <kbd>@</kbd> to direct · the chair files the round-end vote in chat",
39
+ send_placeholder: "interject anytime · @first_p to direct a director...",
40
+ send_button: "[ Send ]",
41
+ ib_pause_label: "Pause discussion",
42
+ ib_pause_tip: "Pause · you can resume later",
43
+ ib_adjourn_label: "Adjourn the room",
44
+ ib_adjourn_tip: "Adjourn · file the report and end",
45
+
46
+ paused_bar_template: "// discussion paused.",
47
+ adjourned_strong: "// room adjourned.",
48
+ adjourned_deck: "the brief is filed above.",
49
+
50
+ adj_title_file: "File the report?",
51
+ adj_title_generate: "Generate the report",
52
+ adj_classify_adjourn: "room · adjourn",
53
+ adj_classify_generate: "room · generate report",
54
+ adj_classify_right_terminal: "// terminal",
55
+ adj_classify_right_posthoc: "// post-hoc",
56
+ adj_confirm_file: "[ Adjourn & file ]",
57
+ adj_confirm_generate: "[ Generate ]",
58
+ adj_meta_room_kicker: "// room #",
59
+ adj_meta_sep: " · ",
60
+ adj_meta_status_live: "live",
61
+ adj_meta_status_paused: "paused",
62
+ adj_meta_status_adjourned: "adjourned",
63
+ adj_meta_turns: "{n} turns",
64
+ adj_key_subject: "// subject",
65
+ adj_key_authors: "// authors",
66
+ adj_key_turns: "// turns",
67
+ adj_agents_count: "{n} agents",
68
+ adj_note_adjourn:
69
+ "The chair compiles a standard report from the room's transcript — situation, key findings, and implications. The room is marked adjourned and the report is filed in the chat.",
70
+ adj_note_generate:
71
+ "The chair compiles a standard report from the room's transcript — situation, key findings, and implications. The report is filed in the chat.",
72
+ adj_skip: "End without report",
73
+ adj_cancel: "[ Cancel ]",
74
+ adj_close_aria: "Close",
75
+ adj_busy_generate: "[ Generating… ]",
76
+ adj_busy_adjourn: "[ Adjourning… ]",
77
+ adj_err_generate: "Generate failed: ",
78
+ adj_err_adjourn: "Adjourn failed: ",
79
+
80
+ export_btn: "[↓] Export",
81
+ followup_btn: "[→] Convene Follow-up",
82
+
83
+ sys_notice_dismiss: "Dismiss",
84
+
85
+ rep_title: "All Reports",
86
+ rep_kicker: "// archive",
87
+ rep_meta: "{n} reports",
88
+ rep_meta_room: " · {n} rooms",
89
+ rep_filter_all: "All",
90
+ rep_filter_today: "Today",
91
+ rep_filter_week: "This week",
92
+ rep_filter_earlier: "Earlier",
93
+ rep_filter_archive_label: "the archive",
94
+ rep_group_today: "Today",
95
+ rep_group_yesterday: "Yesterday",
96
+ rep_group_week: "This week",
97
+ rep_group_earlier: "Earlier",
98
+ rep_empty_kicker_archive: "// archive empty",
99
+ rep_empty_kicker_window: "// window empty",
100
+ rep_empty_title_none: "No reports filed yet",
101
+ rep_empty_title_window: "No reports in {window}",
102
+ rep_empty_deck_all:
103
+ "Run a session and adjourn — once the chair files, every brief across every room lands here.",
104
+ rep_empty_deck_window:
105
+ "Run a session and adjourn — once the chair files, briefs in this window land here. Or jump back to the full archive.",
106
+ rep_empty_deck_filter: "Pick a different filter, or jump back to the full archive.",
107
+ rep_cta_convene: "Convene a new room",
108
+ rep_cta_show_all: "Show all reports",
109
+ rep_aria_filters: "Filter reports by recency",
110
+ rep_sentinel_more: "+ {n} more · scroll or click to load",
111
+ rep_total_one: "1 report",
112
+ rep_total_n: "{n} reports",
113
+ rep_meta_room_one: " · 1 room",
114
+ rep_meta_room_n: " · {n} rooms",
115
+ rep_showing: " · showing {n}",
116
+ rep_load_more: "Load {load} more · {remaining} remaining",
117
+
118
+ notes_title: "All Notes",
119
+ notes_kicker: "// chairman · saved excerpts",
120
+ notes_meta: "{n} notes",
121
+ notes_meta_room: " · {n} rooms",
122
+ notes_one: "1 note",
123
+ notes_many: "{n} notes",
124
+ rooms_one: "1 room",
125
+ rooms_many: "{n} rooms",
126
+
127
+ picker_no_directors: "no directors",
128
+ notes_filter_all: "All",
129
+ notes_empty_title: "no saved notes yet",
130
+ notes_empty_deck:
131
+ 'While reading a director\'s reply, select an interesting passage and hit <span class="kbd">S</span> or click <span class="kbd">⌖ Save</span> on the floating bar to bookmark it here.',
132
+ notes_empty_window: "No notes in {window}",
133
+ notes_empty_filter_deck: "Pick a different filter, or jump back to the full archive.",
134
+ notes_cta_show_all: "Show all notes",
135
+ notes_aria_filters: "Filter notes by recency",
136
+ notes_director_fallback: "Director",
137
+ notes_item_room: "ROOM",
138
+
139
+ room_meeting_room: "Meeting Room",
140
+ room_meta_tone: "tone",
141
+ room_meta_intensity: "intensity",
142
+ room_meta_report: "report",
143
+ room_stamp_paused: "paused {ago} ago",
144
+ room_stamp_adjourned: "adjourned {ago} ago",
145
+ room_stamp_opened: "opened {ago} ago",
146
+ room_cast_title_1: "1 director",
147
+ room_cast_n: "{n} directors",
148
+ room_settings: "Room settings",
149
+ room_pause_verb: "Pause",
150
+ room_resume_verb: "Resume",
151
+ room_view_report: "[ View Report ]",
152
+ room_view_report_multi: "[ View Report · {n} ▾ ]",
153
+ room_view_report_title_multi: "{n} reports · click to choose",
154
+ room_generate_report: "Generate Report",
155
+ room_generate_report_title: "File a brief from this session",
156
+ room_chair_pick_title: "Chair picked {name} for this turn",
157
+ msg_chair_pick: "▸ chair · {body}",
158
+
159
+ chat_banner: "room opened · {when} · {n} directors · {mode}",
160
+
161
+ round_end_vote_above: "Round wrapped · vote above",
162
+ round_clarifying: "Clarifying — wait for chair",
163
+ round_end_open_vote: "End round · open key-point vote",
164
+
165
+ rp_spent_round: "round #{n}",
166
+ rp_spent_label: "closed · room moved on",
167
+ rp_chair_recommends: "chair recommends",
168
+ rp_continue_next: "Continue · next round",
169
+ rp_adjourn_room_file: "⊘ Adjourn the room & file the brief",
170
+
171
+ kp_eyebrow_drafting: "▸ key points · drafting",
172
+ kp_pending_drafting: "Chair is drafting key points…",
173
+ kp_eyebrow_degraded: "▸ key points · couldn't be parsed from this round",
174
+ kp_eyebrow_vote: "▸ key points · vote what you want pursued",
175
+ kp_ctas_spent: "// continued",
176
+ kp_btn_continue_next: "[ ▶ Continue · next round ]",
177
+ kp_btn_adjourn_brief: "[ ⊘ Adjourn & file brief ]",
178
+ kp_btn_adjourn: "[ ⊘ adjourn ]",
179
+ kp_shift_eyebrow_prefix: "▸ chair suggests · switch tone to ",
180
+ kp_switch_to: "[ ↻ switch to {mode} ]",
181
+ kp_keep_mode: "[ keep {mode} ]",
182
+ kp_mode_current_fallback: "current",
183
+ kp_vote_more: "more",
184
+ kp_vote_drop: "drop",
185
+ kp_vote_aria_up: "Interested",
186
+ kp_vote_aria_down: "Not interested",
187
+
188
+ agent_role_tag_moderator: "Moderator",
189
+
190
+ ap_track_record: "Track Record",
191
+ ap_track_tag_model_usage: "model · usage",
192
+ ap_voice_section: "Voice Setup",
193
+ ap_voice_section_tag: "tts · provider · voice",
194
+ ap_skills: "Skills",
195
+ ap_skills_installed: "{current} / {cap} installed",
196
+ ap_skills_cap_reached: "cap reached ({current}/{cap}) · uninstall to make room",
197
+ ap_skills_drop_hint: "install skill · drop a <code>.md</code> file or click",
198
+ ap_skills_load_fail: "couldn't load skills · {detail}",
199
+ ap_stat_rooms: "rooms",
200
+ ap_stat_rounds: "rounds",
201
+ ap_stat_tokens: "tokens",
202
+ ap_intel: "Intel",
203
+ ap_instruction: "Instruction",
204
+ ap_rules: "Rules",
205
+ ap_memory: "Memory",
206
+ ap_edit: "edit",
207
+ ap_cancel: "cancel",
208
+ ap_save: "save",
209
+ ap_rules_add: "+ add rule",
210
+ ap_rules_max: "max {n}",
211
+ ap_rules_empty_list: "no rules yet · use the + add rule button above",
212
+ ap_memory_add: "+ add note",
213
+ ap_dream_consolidate_btn: "☾ run consolidation",
214
+ ap_dream_consolidate_title: "Consolidate · drop stale notes, keep stable patterns",
215
+ ap_show_more: "show more",
216
+ ap_show_less: "show less",
217
+ ap_intel_empty: "no description yet · click edit to add one",
218
+ ap_instr_empty: "no instruction yet · click edit to write one in markdown",
219
+ ap_instr_placeholder_editor:
220
+ "Use markdown · ### headings · **bold** · *italic* · - lists · `code`",
221
+ ap_instr_edit_hint: "markdown supported · esc to cancel",
222
+ ap_intel_placeholder: "One sentence on how this director thinks · {min}–{max} chars",
223
+ ap_intel_hint: "{min}–{max} chars · esc to cancel",
224
+ ap_status_intern: "INTERN · TRIAL",
225
+ ap_status_active: "ACTIVE",
226
+ ap_role_director_upper: "DIRECTOR",
227
+ ap_aria_id_menu: "more",
228
+ ap_live_agent_director: "Director",
229
+
230
+ ap_voice_browser_default: "Browser default",
231
+ ap_voice_engine_browser: "browser TTS",
232
+ ap_voice_speed: "Speed",
233
+ ap_voice_pitch: "Pitch",
234
+ ap_voice_emotion_label: "Emotion",
235
+ ap_voice_emotion_hint: "Sets the emotional tone of the synthesized voice — auto lets the model pick.",
236
+ ap_voice_advanced: "advanced tuning",
237
+ ap_voice_locked_tag: "// locked",
238
+ ap_voice_locked_title: "Configure a voice provider to let this director speak with their own register.",
239
+ ap_voice_locked_body: "Configure a voice provider to unlock TTS — your director will be able to speak in their own register, with adjustable pitch, speed and emotion.",
240
+ ap_voice_locked_cta: "Unlock voice",
241
+ ap_voice_locked_providers: "supports <b>MiniMax</b> · <b>ElevenLabs</b>",
242
+ ap_voice_modify_pitch: "pitch trim",
243
+ ap_voice_modify_intensity: "intensity trim",
244
+ ap_voice_modify_timbre: "timbre trim",
245
+ ap_voice_preview_btn_title: "Preview sample",
246
+ ap_voice_no_provider: "No voice provider configured.",
247
+ ap_voice_loading: "loading voices…",
248
+ ap_voice_fallback_voice: "voice",
249
+ ap_voice_save_err: "Couldn't save voice: {msg}",
250
+ ap_voice_preview_need_voice: "Select a voice first.",
251
+ ap_voice_preview_failed: "Preview failed: {msg}",
252
+ ap_voice_preview_playback_blocked: "Playback blocked: {msg}",
253
+ ap_voice_preview_err: "Preview error: {msg}",
254
+ ap_voice_emotion_auto: "Auto",
255
+ ap_voice_emotion_happy: "happy",
256
+ ap_voice_emotion_sad: "sad",
257
+ ap_voice_emotion_angry: "angry",
258
+ ap_voice_emotion_fearful: "fearful",
259
+ ap_voice_emotion_disgusted: "disgusted",
260
+ ap_voice_emotion_surprised: "surprised",
261
+ ap_voice_emotion_calm: "calm",
262
+ ap_voice_emotion_fluent: "fluent",
263
+
264
+ ap_model_stale_title: "This model is not reachable with your current API keys. Runtime calls fall back to the global default.",
265
+ ap_model_stale_text: "unreachable · falls back at runtime",
266
+
267
+ ao_personnel_kicker: "agent · personnel file",
268
+ ao_classified_mark: "// classified",
269
+ ao_lens: "Lens",
270
+ ao_model: "Model",
271
+ ao_style: "Style",
272
+ ao_memory_room: "In-Room Memory",
273
+ ao_badge_this_room: "this room",
274
+ ao_badge_classified: "⊘ classified",
275
+ ao_lock_blurb_html:
276
+ 'in-room notes are private to each thinker. <a href="/" class="lock-link">sign in →</a> to see what they have said and where their stance shifted.',
277
+ ao_tenure_meta: "tenure ·",
278
+ ao_first_room_meta: "first room ·",
279
+ ao_free: "free",
280
+ ao_convene_cta: "[ ◆ Convene with them ]",
281
+ ao_signin_cta: "[ → Sign in to convene ]",
282
+ ao_room_notes_empty: "no live room. open a room to see this director's in-room notes.",
283
+ ao_room_notes_waiting: "no turns yet — once they speak, claims and stance shifts land here.",
284
+
285
+ convene_show_more: "Show more ↓",
286
+ convene_show_less: "Show less ↑",
287
+ convene_eyebrow: "▸ Convene · Initial Question",
288
+ convene_meta_to: "to",
289
+
290
+ msg_model_title: "model · {label}",
291
+ msg_skills_used: "skills used: {list}",
292
+ msg_ws_title: "web search: {query} · {n} sources",
293
+ msg_ws_btn: "web search · {n} sources",
294
+ msg_ws_btn_one: "web search · 1 source",
295
+ msg_ws_searching: "searching…",
296
+ msg_ws_done: "{n} sources{tail}",
297
+ msg_ws_done_one: "1 source{tail}",
298
+ msg_ws_failed: "failed",
299
+ msg_ws_failed_elapsed: "failed · {elapsed}",
300
+ msg_ws_banner: "// web-search",
301
+ msg_ws_toggle: "Toggle sources",
302
+ msg_ws_expand_show: "Show all {n} sources",
303
+ msg_ws_query_label: "query",
304
+ msg_ws_expand_hide: "Collapse",
305
+ msg_ws_secs: "{n}s",
306
+ msg_chair_direct_kicker: "▸ chair · responding to you",
307
+ msg_chair_intervention_kicker: "▸ chair note",
308
+ msg_chair_billing_kicker: "▸ billing · attention needed",
309
+ msg_chair_display_fallback: "Chair",
310
+ msg_ctx_title: "{n} prior turns sent as context to {name}",
311
+ msg_ctx_inline: "· {n} ctx",
312
+ msg_tag_you: "// you",
313
+ msg_tag_chair: "// chair",
314
+
315
+ sa_head: "// session analytics",
316
+ sa_stamp: "closed",
317
+ sa_tokens: "tokens",
318
+ sa_messages: "msgs",
319
+ sa_rounds: "rounds",
320
+ sa_minutes: "min",
321
+ sa_model_head: "Model usage",
322
+ sa_value_head: "What you valued",
323
+ sa_value_empty: "No ▲ key-point votes, probes, or seconds in this session.",
324
+ sa_voted: "▲ voted",
325
+ sa_seconded: "★ seconded",
326
+ sa_probed: "✎ probed",
327
+ sa_seg_title: "{model} · {tokens} tokens",
328
+
329
+ nk_title: "Configure a model API key",
330
+ nk_deck:
331
+ "The chair and directors run on a large language model. Configure at least one provider key (Anthropic / OpenAI / Google / xAI / DeepSeek / OpenRouter) before AI features will work.",
332
+ nk_primary: "[ Open settings ▸ ]",
333
+ nk_dismiss: "[ Dismiss ]",
334
+ nk_classification: "ai · no model key",
335
+ nk_tag: "▸ Configure API key",
336
+ nk_primary_deck: "Jump to Preferences → API Key. Paste any one provider's key to unlock the room.",
337
+ nk_frontend_gate: "// frontend gate",
338
+
339
+ sc_send_class: "send · choose",
340
+ sc_send_right: "// {name} is speaking",
341
+ sc_send_tag: "▸ Send while mid-turn",
342
+ sc_send_title: "{name} is in the middle of a turn.",
343
+ sc_send_deck: "Cut in now, or queue your message until they finish?",
344
+ sc_interrupt_mark: "▸ Interrupt and send now",
345
+ sc_interrupt_deck: "Drops into the room immediately. {name} keeps going on top of your message.",
346
+ sc_queue_mark: "→ Wait until {name} finishes",
347
+ sc_queue_deck: "Your message lines up after the current turn and posts as soon as it ends.",
348
+ sc_cancel_mark: "✕ Cancel",
349
+ sc_cancel_deck: "Keep typing and decide later.",
350
+ sc_speaker_fallback: "a director",
351
+
352
+ pause_class: "pause · choose",
353
+ pause_right: "// the room is mid-turn",
354
+ pause_tag: "▸ Pause discussion",
355
+ pause_title: "{name} is speaking right now.",
356
+ pause_deck: "How would you like to pause?",
357
+ pause_hard_mark: "▍ Stop immediately",
358
+ pause_hard_deck: "Cut their reply mid-sentence. The partial response is dropped.",
359
+ pause_soft_mark: "⌛ After they finish",
360
+ pause_soft_deck: "Let {name} complete this turn, then pause the queue.",
361
+ pause_cancel_mark: "↩ Cancel",
362
+ pause_cancel_deck: "Keep the discussion running.",
363
+
364
+ pause_bar_add_input: "[ + Add input ]",
365
+ pause_bar_adjourn: "[ ▸ Adjourn & File Brief ]",
366
+ pause_bar_resume: "[ ▸ Resume Discussion ]",
367
+ pause_bar_paused: "paused",
368
+ pause_bar_next: "next",
369
+
370
+ cmp_tone_label: "Tone",
371
+ cmp_intensity_label: "Intensity",
372
+ cmp_voice_tooltip: "Enable voice meeting",
373
+ cmp_voice_label: "Voice Mode",
374
+
375
+ conv_stage_analyzing_title: "Analyzing topic",
376
+ conv_stage_analyzing_deck: "Routing your topic to the right perspectives",
377
+ conv_stage_seating_title: "Seating directors",
378
+ conv_stage_seating_deck: "Picking the right perspectives for this question",
379
+ conv_stage_preparing_title: "Chair preparing remarks",
380
+ conv_stage_preparing_deck: "Drafting the convening speech",
381
+ conv_seated_label: "seated",
382
+ conv_banner_convening: "▸ CONVENING",
383
+
384
+ chair_pend_banner: "▸ chair",
385
+ chair_pend_clarify: "{name} is reading your question…",
386
+ chair_pend_chair_direct: "{name} is preparing a response…",
387
+ chair_pend_round_end: "{name} is wrapping up this round…",
388
+ chair_pend_convening: "{name} is convening the room…",
389
+ chair_pend_next_speaker: "{name} is reading the room…",
390
+ chair_pend_default: "{name} is preparing…",
391
+
392
+ brief_regen_timeout: "regeneration timed out",
393
+ brief_regen_interrupted: "regeneration interrupted",
394
+ brief_regen_failed: "regeneration failed",
395
+ brief_retry: "Retry",
396
+ brief_dismiss: "Dismiss",
397
+
398
+ brief_tab_initial: "Initial",
399
+ brief_tab_tooltip_initial: "Initial brief · generated from the session",
400
+ brief_tab_supplement_prefix: "Supplement: ",
401
+ brief_tab_delete_title: "Delete this report",
402
+
403
+ brief_err_stamp_timeout: "timed out",
404
+ brief_err_kicker_timeout: "// generation timed out",
405
+ brief_err_detail_timeout:
406
+ "No completion signal after 8 minutes — the model may be slow, the connection dropped, or the pipeline stalled. Click below to start a fresh run.",
407
+ brief_err_stamp_interrupted: "interrupted",
408
+ brief_err_kicker_interrupted: "// generation interrupted",
409
+ brief_err_detail_interrupted:
410
+ "The previous generation was cut short — likely by a browser refresh or a server restart. Click below to start a fresh report.",
411
+ brief_err_cta_regenerate: "Regenerate report",
412
+ brief_err_stamp_failed: "failed",
413
+ brief_err_kicker_failed: "// brief generation failed",
414
+ brief_err_hint_failed_html:
415
+ "The brief writer needs an LLM key (OpenRouter, or a direct Anthropic / OpenAI / Google / xAI key). Add one in <strong>Preference → API Key</strong> and try again.",
416
+ brief_err_hint_scaffold_html:
417
+ 'The chair model must emit valid JSON for the internal <strong>scaffold</strong> step before the final prose. Typical causes: very little usable signal in the thread, truncation or malformed output, upstream rate limits, or billing — <strong>not necessarily</strong> a missing Preference key when keys already show as configured. Try <strong>Regenerate</strong>, shorten the transcript, switch the chair to another reachable model, or grep server stderr for <code>[brief.stage2]</code>.',
418
+ brief_err_hint_generic_html:
419
+ 'Use the red English line above as the primary clue. If it mentions keys, billing, or <code>401</code>/<code>403</code>, check <strong>Preference → API Key</strong> and quotas; otherwise inspect server logs.',
420
+
421
+ brief_output_head: "▼ session output ▼",
422
+ brief_report_tag: "// report",
423
+ brief_filed_generating: "GENERATING…",
424
+ brief_filed_stamp: "FILED · {when}",
425
+ brief_filed_by: "// filed by {name}",
426
+ brief_untitled: "(untitled)",
427
+ brief_meta_authors: "{n} authors",
428
+ brief_open_report: "open report",
429
+ brief_chair_fallback: "the chair",
430
+
431
+ brief_hard_timeout_msg: "Brief generation timed out (no completion after 8 minutes).",
432
+ brief_stage_kicker: "// {chair} is preparing the minutes · {total}",
433
+ brief_stage_extract_label: "Reading what each director said",
434
+ brief_stage_extract_pip: "read",
435
+ brief_stage_compose_label: "Picking the report shape",
436
+ brief_stage_compose_pip: "pick",
437
+ brief_stage_scaffold_anchor_label: "Setting the anchor",
438
+ brief_stage_scaffold_anchor_pip: "anchor",
439
+ brief_stage_scaffold_findings_label: "Sketching findings",
440
+ brief_stage_scaffold_findings_pip: "find",
441
+ brief_stage_scaffold_cluster_label: "Mapping consensus + dissent",
442
+ brief_stage_scaffold_cluster_pip: "split",
443
+ brief_stage_scaffold_actions_label: "Drafting actions + risks",
444
+ brief_stage_scaffold_actions_pip: "act",
445
+ brief_stage_write_label: "Writing the report",
446
+ brief_stage_write_pip: "write",
447
+
448
+ brief_sub_extract_0: "Re-reading each director's contributions",
449
+ brief_sub_extract_1: "Tagging signals by lens (data / dissent / narrative / structural / first-principle)",
450
+ brief_sub_extract_2: "Tightening to 2–4 signals per director",
451
+ brief_sub_compose_0: "Picking the spine for this brief",
452
+ brief_sub_compose_1: "Choosing which component blocks fit",
453
+ brief_sub_compose_2: "Sizing density and rhythm",
454
+ brief_sub_scaffold_anchor_0: "Reading the takeaway",
455
+ brief_sub_scaffold_anchor_1: "Sizing the confidence call",
456
+ brief_sub_scaffold_anchor_2: "Setting the working hypothesis",
457
+ brief_sub_scaffold_findings_0: "Pulling out the headline findings",
458
+ brief_sub_scaffold_findings_1: "Cross-checking each finding to the anchor",
459
+ brief_sub_scaffold_findings_2: "Tightening 3 → 2 if a finding wobbles",
460
+ brief_sub_scaffold_cluster_0: "Mapping where the directors converged",
461
+ brief_sub_scaffold_cluster_1: "Surfacing the central tension",
462
+ brief_sub_scaffold_cluster_2: "Spotting positions that didn't quite resolve",
463
+ brief_sub_scaffold_actions_0: "Drafting recommendations",
464
+ brief_sub_scaffold_actions_1: "Mapping the pre-mortem",
465
+ brief_sub_scaffold_actions_2: "Surfacing the new questions the room opened",
466
+ brief_sub_write_0: "Writing the Bottom Line",
467
+ brief_sub_write_1: "Composing the Frame Shift section",
468
+ brief_sub_write_2: "Writing the 3 Headline Findings",
469
+ brief_sub_write_3: "Drafting Convergence + Divergence sections",
470
+ brief_sub_write_4: "Composing Recommendations",
471
+ brief_sub_write_5: "Writing the Pre-mortem",
472
+ brief_sub_write_6: "Surfacing New Questions",
473
+ brief_sub_write_7: "Drafting the Strategic Planning Assumption",
474
+ brief_sub_write_8: "Polishing the final pass",
475
+
476
+ brief_prog_directors_one: "{cur}/{tot} director",
477
+ brief_prog_directors: "{cur}/{tot} directors",
478
+ brief_prog_words_one: "1 word",
479
+ brief_prog_words: "{n} words",
480
+ brief_timing_inband: "{e}s · ~{lo}–{hi}s",
481
+ brief_timing_eta: "~{lo}–{hi}s",
482
+ brief_timing_over: "{n}s elapsed",
483
+ brief_range_sec: "~{lo}–{hi}s",
484
+ brief_range_min: "~{lo}-{hi}m",
485
+ brief_total_line: "{elapsed} elapsed · {range} left",
486
+ brief_fmt_sec: "{n}s",
487
+ brief_fmt_min: "{n}m",
488
+ brief_fmt_min_sec: "{m}m {r}s",
489
+ brief_harvest_claims: "claims",
490
+ brief_harvest_evidence: "evidence",
491
+ brief_harvest_tensions: "tensions",
492
+ brief_harvest_assumptions: "assumptions",
493
+ brief_harvest_risks: "risks",
494
+ brief_harvest_opportunities: "opportunities",
495
+ brief_harvest_actions: "actions",
496
+ brief_harvest_quotes: "quotes",
497
+ brief_harvest_open_questions: "open-q",
498
+ brief_stat_writing: "{n} words · still writing",
499
+ brief_supplement_btn: "Add a perspective · regenerate",
500
+ brief_delete_label: "Delete report",
501
+ ending_session_foot: "// end of session",
502
+ brief_wc_approx_chars: "~{n} 字",
503
+ brief_wc_one_word: "1 word",
504
+ brief_wc_words: "{n} words",
505
+
506
+ na_class_left: "directors · new",
507
+ na_class_right: "// shape the role",
508
+ na_step_kicker_html: '// new <span class="hl">director</span> · manual setup',
509
+ na_step_title: "shape the role",
510
+ na_close_aria: "Close",
511
+ na_avatar_regen: "generate 8-bit avatar",
512
+ na_field_name: "Name",
513
+ na_field_intro: "Intro",
514
+ na_field_instruction: "Instruction",
515
+ na_field_model: "model",
516
+ na_instr_meta: "chars · markdown",
517
+ na_name_ph: "Aurelia · The Long-Cycle Strategist",
518
+ na_intro_ph:
519
+ "One or two sentences · how this director shows up in a room. Reads everything on a hundred-year scale. Knows which patterns repeat and which never do.",
520
+ na_instr_ph: `### Role
521
+ You are __, the room's __. Your job is to ___.
522
+
523
+ ### Voice
524
+ Demand ___. Don't ___. Cite ___ when ___.
525
+
526
+ ### Boundaries
527
+ When the room ___, raise an objection.`,
528
+ na_hint_handle: "handle:",
529
+ na_hint_bio: "becomes their public bio",
530
+ na_hint_instr: "applies to every room they join · skills and rules are configured later in the profile",
531
+ na_foot_meta: "configure skills · rules after creation",
532
+ na_cancel: "cancel",
533
+ na_create: "create director",
534
+ na_rule_empty: "no rules yet · directors will follow only their instruction",
535
+ na_rule_ph: "never preface · cite the load-bearing claim with **bold** · ...",
536
+ na_rule_rm: "Remove",
537
+ na_skill_install: "Install ability",
538
+ na_skill_empty: "empty",
539
+ na_key_direct: "direct",
540
+ na_key_via: "via openrouter",
541
+ na_key_none: "no key",
542
+ na_avatar_thinking: "thinking…",
543
+ na_creating: "[ creating… ]",
544
+ na_create_fail: "Couldn't create the director: {msg}",
545
+
546
+ convene_followup_label: "Following up on",
547
+ convene_room_label: "Room #",
548
+ convene_parent_session_title: "Open the prior session · {subject}",
549
+
550
+ ro_round: "round #{n}",
551
+ ro_mode_parallel: "parallel · independent perspectives",
552
+ ro_mode_reactive: "reactive · directors react to one another",
553
+
554
+ nb_cta: "Generate report now",
555
+ nb_eyebrow: "adjourned · no brief filed",
556
+ nb_body: "declared no report is needed for this session.",
557
+ nb_chair_fallback: "The chair",
558
+
559
+ note_tag_origin: "input",
560
+ note_tag_obs: "obs",
561
+ note_tag_insight: "claim",
562
+ note_tag_warn: "drop",
563
+ note_tag_crux: "crux",
564
+ note_tag_soln: "pursue",
565
+ note_tag_open: "ask",
566
+
567
+ migrate_head: "Storage upgraded",
568
+ migrate_body: "{count} new migrations applied · your existing rooms, agents, briefs, and settings were preserved.",
569
+ migrate_body_one:
570
+ "1 new migration applied · your existing rooms, agents, briefs, and settings were preserved.",
571
+
572
+ ag_gen_elapsed: "{n} s elapsed",
573
+ ag_gen_step: "step {current} of {total}",
574
+ ag_gen_header: "Summoning director",
575
+
576
+ // Note · the canonical `ag_cmp_*` keys for this language live in
577
+ // the second en block below (around line ~780). The duplicate
578
+ // copies that used to sit here were overridden by JS object-
579
+ // literal duplicate-key rules (the LATER definition wins) and
580
+ // were a maintenance trap — editing here did nothing visible.
581
+ // The block has been removed; future edits go to the live keys.
582
+
583
+ ag_err_kicker_timeout: "// generation timed out",
584
+ ag_err_kicker_fail: "// generation failed",
585
+ ag_err_title_timeout: "Generation didn't complete after 5 minutes",
586
+ ag_err_title_fail: "Generation failed",
587
+ ag_err_hint_timeout:
588
+ "The model may be slow, the network flaky, or the backend pipeline stalled. Click retry to start a fresh run.",
589
+ ag_err_hint_fail:
590
+ "Check your API key configuration and model reachability. Retry often clears transient failures.",
591
+ ag_err_desc: "Your description (re-used on retry)",
592
+ ag_err_retry: "Retry",
593
+ ag_err_discard: "Discard",
594
+ ag_err_prompt: "What kind of director do you want?",
595
+
596
+ ag_preview_kicker: "// generated director · edit and save",
597
+ ag_preview_avatar: "Avatar",
598
+ ag_preview_reroll: "Reroll",
599
+ ag_preview_name: "Name",
600
+ ag_preview_handle: "Handle",
601
+ ag_preview_role: "Role tag",
602
+ ag_preview_bio: "Bio",
603
+ ag_preview_quote: "Cover quote",
604
+ ag_preview_instruction: "Instruction",
605
+ ag_preview_model: "Model",
606
+ ag_preview_save: "Save director",
607
+ ag_preview_discard: "Discard",
608
+ ag_preview_redo: "Regenerate",
609
+
610
+ ag_preview_radar_aria: "Ability radar",
611
+
612
+ ag_ws_needs_key: "needs key",
613
+ ag_ws_enabled: "enabled",
614
+ ag_ws_disabled: "disabled",
615
+ ag_ws_title_needs: "Web search needs Brave Search or Tavily keys · click to configure",
616
+ ag_ws_need_key_confirm:
617
+ "Web Search needs Brave Search or Tavily API credentials.\n\nBrave Search · ≈ $5 per 1000 queries · privacy-oriented. Tavily · per Tavily API credits · LLM-focused results.\n\nOpen Preferences now?",
618
+ ag_ws_configure_key: "Configure web search API keys ↗",
619
+ ag_ws_title_on: "Search the web for real domain references during generation · click to disable",
620
+ ag_ws_title_off: "Generation runs offline · click to enable web search",
621
+ ag_ws_label: "web search",
622
+
623
+ greet_en_0: "// Up late, {name}",
624
+ greet_en_1: "// Good morning, {name}",
625
+ greet_en_2: "// Good afternoon, {name}",
626
+ greet_en_3: "// Good evening, {name}",
627
+ greet_zh_0: "// 凌晨好,{name}",
628
+ greet_zh_1: "// 早上好,{name}",
629
+ greet_zh_2: "// 中午好,{name}",
630
+ greet_zh_3: "// 下午好,{name}",
631
+ greet_zh_4: "// 晚上好,{name}",
632
+ greet_zh_5: "// 夜深了,{name}",
633
+
634
+ brief_generating_title: "Generating…",
635
+
636
+ q_idle: "queue idle",
637
+ q_speaking: "●●● speaking",
638
+ q_pending_vote: "pending · waits for vote",
639
+ q_pending_chair: "pending · waits for chair",
640
+ q_queued: "queued",
641
+ q_more_queued: "+{n} queued",
642
+ q_user_queued: "queued · \"{preview}\"",
643
+ q_cancel: "Cancel",
644
+ q_state_speaking: "speaking · reading {n} turn(s)",
645
+ q_pending_your_vote: "pending · waits for your vote",
646
+ q_pending_waits_chair: "pending · waits for chair",
647
+
648
+ sidebar_live: "Live",
649
+ sidebar_paused: "paused",
650
+ sidebar_section_live: "Live",
651
+ sidebar_section_paused: "Paused",
652
+ sidebar_section_adjourned: "Adjourned",
653
+ sidebar_no_adjourned_title: "no adjourned rooms",
654
+ sidebar_no_adjourned_deck: "conclude a discussion to file it here.",
655
+ sidebar_delete_room: "Delete room",
656
+ sidebar_pin: "Pin",
657
+ sidebar_unpin: "Unpin",
658
+ sidebar_role_director: "director",
659
+ sidebar_status_active: "active",
660
+ sidebar_chair_badge: "CHAIR",
661
+ sidebar_chair_badge_title: "Moderator · structural agent, not user-managed",
662
+ sidebar_chair_role_fallback: "Moderator",
663
+ sidebar_chair_note: "in every room",
664
+ sidebar_sec_chair: "Chair",
665
+ sidebar_sec_pinned: "Pinned",
666
+ sidebar_sec_custom: "Custom",
667
+ sidebar_sec_core: "Core",
668
+
669
+ note_saved: "Saved to Notes",
670
+
671
+ tone_tip_brainstorm:
672
+ "Co-creator. Directors stand with you and push the idea outward — yes-and a contribution, name a concrete adjacent variant (\"what if we instead…\"), borrow pieces from another director's turn into new combinations. May end with one curious question, never a defense-demanding one.",
673
+ tone_tip_constructive:
674
+ "Sympathetic interrogator. They want you to win, but only via the strongest version. Each turn picks ONE load-bearing assumption and proposes the candidate stronger version that would stand. Disagreement is allowed, but every objection comes packaged with a forward path.",
675
+ tone_tip_research:
676
+ "Collaborative inquiry. The room mines the materials in front of it (your brief, web-search results, prior turns) for what's actually there. Each turn must cite a specific source piece, label it OBSERVATION / INFERENCE / SPECULATION, then extract the insight your lens makes salient. Defaults web search ON when a Brave key is configured.",
677
+ tone_tip_debate:
678
+ "Peer reviewer. Each turn opens by steelmanning your strongest claim (\"the strongest read of your point is…\") and only then attacks THAT version — naming a specific risk, demanding evidence, exposing the trade-off you're hiding. Sharp but professional. Skipping the steelman is a protocol violation.",
679
+ tone_tip_critique:
680
+ "Review board. The room audits a finished deliverable systematically — each turn names the dimension being audited (logic / evidence / scope / risk / etc.), surfaces 2–3 specific flaws labelled BLOCKER · MAJOR · MINOR, points at the load-bearing piece, and indicates the direction a fix would lie. At least one BLOCKER or MAJOR per turn is mandatory.",
681
+
682
+ col_resize: "drag to resize",
683
+ settings_title: "Settings",
684
+
685
+ us_nav_user: "User",
686
+ us_nav_theme: "Theme",
687
+ us_nav_usage: "Usage",
688
+ us_nav_keys: "API Keys",
689
+ us_nav_default: "Default model",
690
+ us_user_tag: "▸ User",
691
+ us_user_deck: "how the boardroom addresses you and what it knows about your context.",
692
+ us_avatar: "Avatar",
693
+ us_regen_avatar: "generate 8-bit avatar",
694
+ us_name: "Name",
695
+ us_about: "About you",
696
+ us_intro_ph: "A line or two about your role, what you tend to think about, what you're working on. Directors will keep this in mind across rooms.",
697
+ us_intro_meta: "{n} / 320 chars",
698
+ us_intro_meta_rest: "/ 320 chars",
699
+ us_theme_tag: "▸ Theme",
700
+ us_theme_deck: "global · zsh-inspired palettes. Applied instantly across all rooms.",
701
+ us_usage_tag: "▸ Usage",
702
+ us_usage_deck: "cumulative LLM-call accounting · billed across every director / chair turn since this boardroom was opened.",
703
+ us_usage_loading: "measuring…",
704
+ us_usage_empty: "no LLM calls billed yet · open a room and let the directors speak.",
705
+ us_usage_agents: "{n} agent(s)",
706
+ us_usage_silent: "+ {n} agent(s) not yet billed",
707
+ us_keys_tag: "▸ API Key",
708
+ us_keys_add_label: "+ add provider:",
709
+ us_keys_group_skill: "Skill Services",
710
+ us_keys_skill_deck: "enables system skills that need an outside service. Each agent can opt in or out per-profile.",
711
+ us_ws_backend_tag: "WEB SEARCH BACKEND",
712
+ us_ws_backend_deck:
713
+ "Both Brave Search and Tavily keys are set. Pick which backs the Web Search system skill.",
714
+ us_ws_backend_brave: "Brave Search",
715
+ us_ws_backend_tavily: "Tavily Search",
716
+ us_pref_title: "Preference",
717
+ us_modal_kicker_left: "user · settings",
718
+ us_modal_kicker_right: "// local",
719
+ us_close: "Close",
720
+ us_nav_api_key: "API Key",
721
+ us_nav_other_settings: "Other settings",
722
+ us_locale_label: "Interface language",
723
+ us_locale_deck:
724
+ "Sidebar labels, dialogs, and app chrome follow this locale. Room messages and briefs still mirror the language you write in.",
725
+ us_default_model_title: "Default Model",
726
+ us_default_deck_long:
727
+ "new agents inherit this. when an agent's saved model becomes unreachable (key removed / model retired), it falls back here too. flagship tier uses this as the deep-write model.",
728
+ us_keys_deck: "Paste keys once — the boardroom stores them locally and never sends them to us. Keys power director turns, not telemetry.",
729
+ us_default_tag: "▸ Default model",
730
+ us_default_deck: "Fallback when a director has no per-agent override. Reachable models only.",
731
+ us_foot_saved: "changes save automatically",
732
+ us_foot_website: "website ↗",
733
+ us_done: "[ Done ]",
734
+ us_usage_chair: "chair",
735
+ us_usage_director: "director",
736
+
737
+ onb_next: "[ Next ▸ ]",
738
+ onb_skip: "[ I'll explore on my own ]",
739
+ onb_name_ph: "e.g. Kay",
740
+ onb_key_field: "{label} API key",
741
+ onb_generate_at: "Generate at {host} →",
742
+ onb_show: "show",
743
+ onb_hide: "hide",
744
+
745
+ /* ─── Backfill · keys referenced by app.js but not yet defined
746
+ in the i18n bundle. The PR introducing i18n was based on an
747
+ older fork that didn't include the v0.1.9 session-analytics
748
+ card / brief retry banner / various adjourn + composer paths.
749
+ English-only for now · the Chinese block falls back here via
750
+ the `STR[loc][key] ?? STR.en[key] ?? key` lookup chain. */
751
+
752
+ // Adjourn modal
753
+ adj_classify_adjourn: "room · adjourn",
754
+ adj_classify_generate: "room · generate report",
755
+ adj_classify_right_terminal: "// terminal",
756
+ adj_classify_right_posthoc: "// post-hoc",
757
+ adj_title_file: "File the report?",
758
+ adj_title_generate: "Generate a report",
759
+ adj_close_aria: "Close",
760
+ adj_meta_room_kicker: "// room #",
761
+ adj_meta_sep: "·",
762
+ adj_meta_turns: "turns",
763
+ adj_key_subject: "// subject",
764
+ adj_key_authors: "// authors",
765
+ adj_key_turns: "// turns",
766
+ adj_agents_count: "{n} agents",
767
+ adj_note_adjourn:
768
+ "The chair compiles a report from the room's transcript. Pick the format below — the room is marked adjourned and the report is filed in the chat once it's ready.",
769
+ adj_note_generate:
770
+ "Generate a report for this adjourned room. Pick the format below — the report lands in the chat once it's ready.",
771
+ adj_skip: "End without report",
772
+ adj_cancel: "[ Cancel ]",
773
+ adj_confirm_file: "[ Adjourn & file ]",
774
+ adj_confirm_generate: "[ Generate ]",
775
+ adj_busy_adjourn: "[ Adjourning… ]",
776
+ adj_busy_generate: "[ Generating… ]",
777
+ adj_err_adjourn: "Adjourn failed: ",
778
+ adj_err_generate: "Generate failed: ",
779
+
780
+ // Agent composer
781
+ ag_cmp_prompt: "Describe the director you want",
782
+ ag_cmp_placeholder:
783
+ "A custom director can be your hard contrarian, your domain specialist, your missing senior advisor — anyone you keep wishing was at the table.",
784
+ ag_cmp_cta: "[ ✦ Generate director ]",
785
+ ag_cmp_cta_hint: "⌘+Enter",
786
+ ag_cmp_starter_caption: "or start from a seed:",
787
+ ag_cmp_manual: "or configure manually",
788
+ ag_cmp_model_label: "model",
789
+ ag_cmp_generating: "drafting…",
790
+ ag_gen_header: "drafting your director",
791
+ ag_gen_step: "step {n} of 5",
792
+ ag_gen_elapsed: "{s}s elapsed",
793
+ ag_preview_kicker: "// preview · review and save",
794
+ ag_preview_name: "name",
795
+ ag_preview_role: "role",
796
+ ag_preview_bio: "bio",
797
+ ag_preview_quote: "cover quote",
798
+ ag_preview_instruction: "instruction",
799
+ ag_preview_radar_aria: "ability radar",
800
+ ag_preview_save: "[ Save director ]",
801
+ ag_preview_reroll: "↻ reroll avatar",
802
+ ag_preview_redo: "↻ redo from scratch",
803
+ ag_preview_discard: "✕ discard",
804
+ ag_err_title_fail: "Generation failed",
805
+ ag_err_title_timeout: "Generation timed out",
806
+ ag_err_kicker_fail: "// error",
807
+ ag_err_kicker_timeout: "// timeout",
808
+ ag_err_desc:
809
+ "Your description didn't make it through — the model returned an error.",
810
+ ag_err_hint_fail:
811
+ "Could be a transient API issue. Retry, or simplify the description.",
812
+ ag_err_hint_timeout:
813
+ "The request took longer than 90 seconds. Try a shorter description, or pick a faster model.",
814
+ ag_err_prompt: "what you described:",
815
+ ag_err_retry: "[ ↻ Retry ]",
816
+ ag_err_discard: "[ ✕ Discard ]",
817
+ ag_ws_label: "web search",
818
+ ag_ws_enabled: "ON",
819
+ ag_ws_disabled: "OFF",
820
+ ag_ws_needs_key: "needs key",
821
+ ag_ws_title_on: "Web search enabled · this director can search the web during rooms",
822
+ ag_ws_title_off: "Web search disabled · enable to let this director search the web",
823
+ ag_ws_title_needs:
824
+ "Web search needs a Brave Search API key · configure in user settings",
825
+
826
+ // Sidebar
827
+ sidebar_host: "// host",
828
+ sidebar_expand: "Expand sidebar",
829
+ sidebar_chair_badge: "chair",
830
+ sidebar_chair_badge_title: "Chair · the moderator agent",
831
+ sidebar_chair_note: "// the chair convenes every room",
832
+ sidebar_chair_role_fallback: "Moderator",
833
+ sidebar_paused: "paused",
834
+ sidebar_pin: "Pin",
835
+ sidebar_unpin: "Unpin",
836
+ sidebar_role_director: "Director",
837
+ sidebar_status_active: "active",
838
+ sidebar_section_live: "// live",
839
+ sidebar_section_paused: "// paused",
840
+ sidebar_section_adjourned: "// adjourned",
841
+ sidebar_sec_chair: "// chair",
842
+ sidebar_sec_pinned: "// pinned",
843
+ sidebar_sec_core: "// core",
844
+ sidebar_sec_custom: "// custom",
845
+ sidebar_no_adjourned_title: "No adjourned rooms yet",
846
+ sidebar_no_adjourned_deck: "Adjourned rooms with filed briefs land here.",
847
+ sidebar_delete_room: "Delete room",
848
+
849
+ // Room header (system chrome · English-only)
850
+ room_settings: "Room settings",
851
+ room_pause_verb: "Pause",
852
+ room_resume_verb: "Resume",
853
+ room_view_report: "[ View Report ]",
854
+ room_view_report_multi: "[ View Report · {n} ▾ ]",
855
+ room_view_report_title_multi: "{n} reports · click to choose",
856
+ room_generate_report: "Generate Report",
857
+ room_generate_report_title: "File a brief from this session",
858
+ room_stamp_paused: "paused {ago}",
859
+ room_stamp_adjourned: "adjourned {ago}",
860
+ room_stamp_opened: "opened {ago}",
861
+ room_chair_pick_title: "Chair has selected the next speaker",
862
+ room_cast_n: "{n} directors",
863
+ rooms_one: "{n} room",
864
+ rooms_many: "{n} rooms",
865
+
866
+ // Composer (new room)
867
+ cmp_tone_label: "tone",
868
+ cmp_intensity_label: "intensity",
869
+ cmp_voice_label: "Voice Mode",
870
+ cmp_voice_tooltip: "Voice mode · directors speak aloud during the room",
871
+
872
+ // Convene · seating + opener
873
+ conv_banner_convening: "Convening directors…",
874
+ conv_seated_label: "seated",
875
+ conv_stage_preparing_title: "preparing room",
876
+ conv_stage_preparing_deck: "the chair is gathering context…",
877
+ conv_stage_analyzing_title: "analyzing your question",
878
+ conv_stage_analyzing_deck: "the chair is reading the room's seed…",
879
+ conv_stage_seating_title: "seating directors",
880
+ conv_stage_seating_deck: "the cast is taking their places…",
881
+ convene_eyebrow: "▸ Convene · Initial Question",
882
+ convene_followup_label: "follow-up",
883
+ convene_room_label: "room #{number}",
884
+ convene_meta_to: "to {names}",
885
+ convene_parent_session_title: "from session #{number}",
886
+ convene_show_more: "Show more ↓",
887
+ convene_show_less: "Show less ↑",
888
+
889
+ // Round-open (RO) + round-prompt (RP)
890
+ ro_round: "round {n}",
891
+ ro_mode_parallel: "parallel",
892
+ ro_mode_reactive: "reactive",
893
+ rp_chair_recommends: "the chair recommends:",
894
+ rp_continue_next: "▸ Continue to next round",
895
+ rp_adjourn_room_file: "▸ Adjourn & file brief",
896
+ rp_spent_label: "spent",
897
+ rp_spent_round: "this round",
898
+ round_clarifying: "the chair is clarifying your question…",
899
+ round_end_open_vote: "open the round-end vote",
900
+ round_end_vote_above: "vote on the highlights above",
901
+
902
+ // Key points (KP) round-end card
903
+ kp_eyebrow_drafting: "// chair · drafting recap",
904
+ kp_eyebrow_vote: "// chair · round recap",
905
+ kp_eyebrow_degraded: "// chair · partial recap",
906
+ kp_pending_drafting: "the chair is drafting…",
907
+ kp_btn_continue_next: "[ ▸ Continue ]",
908
+ kp_btn_adjourn: "[ ⊘ Adjourn ]",
909
+ kp_btn_adjourn_brief: "[ ⊘ Adjourn & file brief ]",
910
+ kp_ctas_spent: "spent {tokens} this round",
911
+ kp_keep_mode: "keep current",
912
+ kp_mode_current_fallback: "current",
913
+ kp_shift_eyebrow_prefix: "the chair suggests shifting →",
914
+ kp_switch_to: "switch to {mode}",
915
+ kp_vote_aria_up: "Upvote",
916
+ kp_vote_aria_down: "Downvote",
917
+ kp_vote_drop: "drop",
918
+ kp_vote_more: "more",
919
+
920
+ // Brief card / tabs / banners
921
+ brief_chair_fallback: "Chair",
922
+ brief_filed_by: "filed by {name}",
923
+ brief_filed_stamp: "filed {ago}",
924
+ brief_filed_generating: "generating…",
925
+ brief_meta_authors: "authors",
926
+ brief_open_report: "[ ▸ Open report ]",
927
+ brief_supplement_btn: "[ + Add a perspective ]",
928
+ brief_report_tag: "report",
929
+ brief_untitled: "(untitled)",
930
+ brief_total_line: "{count} {unit}",
931
+ brief_output_head: "// output",
932
+ brief_stage_kicker: "// composing",
933
+ brief_stat_writing: "writing",
934
+ brief_timing_eta: "{s}s remaining",
935
+ brief_timing_inband: "in band",
936
+ brief_timing_over: "{s}s over",
937
+ brief_fmt_min: "{m}m",
938
+ brief_fmt_min_sec: "{m}m {s}s",
939
+ brief_fmt_sec: "{s}s",
940
+ brief_range_min: "{lo}–{hi} min",
941
+ brief_range_sec: "{lo}–{hi}s",
942
+ brief_hard_timeout_msg:
943
+ "the brief writer didn't finish in {minutes} minutes — likely a stuck stream.",
944
+ brief_wc_words: "{n} words",
945
+ brief_wc_one_word: "1 word",
946
+ brief_wc_approx_chars: "~{n} chars",
947
+ brief_tab_initial: "initial",
948
+ brief_tab_supplement_prefix: "supplement: ",
949
+ brief_tab_tooltip_initial: "Initial brief filed at adjourn",
950
+ brief_tab_delete_title: "Delete this brief",
951
+ brief_delete_label: "Delete",
952
+ brief_retry: "Retry",
953
+ brief_dismiss: "Dismiss",
954
+ brief_regen_failed: "Regeneration failed.",
955
+ brief_regen_timeout: "Regeneration took too long and was cancelled.",
956
+ brief_regen_interrupted: "Regeneration was interrupted before it finished.",
957
+ brief_err_stamp_failed: "// failed",
958
+ brief_err_stamp_timeout: "// timed out",
959
+ brief_err_stamp_interrupted: "// interrupted",
960
+ brief_err_kicker_failed: "couldn't compose",
961
+ brief_err_kicker_timeout: "took too long",
962
+ brief_err_kicker_interrupted: "stopped mid-write",
963
+ brief_err_detail_timeout:
964
+ "The brief writer didn't finish in time. This is usually a slow / stuck model — retrying often works.",
965
+ brief_err_detail_interrupted:
966
+ "The previous attempt was interrupted before it finished — likely a server restart while the brief was streaming.",
967
+ brief_err_hint_failed_html: "Pick a different model in your <a href=\"#\" data-open-user-settings>user settings</a>, then retry.",
968
+ brief_err_hint_generic_html: "Make sure your model API key is configured in <a href=\"#\" data-open-user-settings>user settings</a>.",
969
+ brief_err_hint_scaffold_html: "The structured spine couldn't compose. Switch to the report mode in <a href=\"#\" data-open-user-settings>settings</a> or retry.",
970
+ brief_err_cta_regenerate: "[ ↻ Regenerate ]",
971
+
972
+ // Brief harvest categories (sectioned brief composer)
973
+ brief_harvest_claims: "claims",
974
+ brief_harvest_evidence: "evidence",
975
+ brief_harvest_assumptions: "assumptions",
976
+ brief_harvest_risks: "risks",
977
+ brief_harvest_open_questions: "open questions",
978
+ brief_harvest_actions: "actions",
979
+ brief_harvest_quotes: "quotes",
980
+ brief_harvest_tensions: "tensions",
981
+ brief_harvest_opportunities: "opportunities",
982
+
983
+ // No-brief panel + nudge card on adjourned-no-brief rooms
984
+ nb_eyebrow: "adjourned · no brief filed",
985
+ nb_body:
986
+ "this room ended without filing a report. you can generate one now — the chair will compile from the transcript.",
987
+ nb_cta: "[ ▸ Generate Report ]",
988
+ nb_chair_fallback: "Chair",
989
+ nk_classification: "ROOM · ADJOURNED",
990
+ nk_tag: "// no report",
991
+ nk_title: "Walk away with a report",
992
+ nk_deck:
993
+ "the room is closed but no report was filed. compile one now — the chair will draft from the transcript.",
994
+ nk_primary: "[ ▸ Generate Report ]",
995
+ nk_primary_deck: "compile a report from this transcript",
996
+ nk_dismiss: "[ ✕ Dismiss ]",
997
+ nk_frontend_gate: "// generation in flight…",
998
+
999
+ // Session-analytics card · post-adjourn summary
1000
+ sa_head: "// session",
1001
+ sa_stamp: "completed {ago}",
1002
+ sa_seg_title: "this session",
1003
+ sa_tokens: "tokens",
1004
+ sa_messages: "messages",
1005
+ sa_rounds: "rounds",
1006
+ sa_minutes: "min",
1007
+ sa_model_head: "model usage",
1008
+ sa_value_head: "what stuck",
1009
+ sa_value_empty: "no upvoted highlights · the chair's recap stood unchallenged.",
1010
+ sa_voted: "{n} ▲ voted",
1011
+ sa_seconded: "{n} seconded",
1012
+ sa_probed: "{n} probed",
1013
+
1014
+ // Pause / send-confirm modals
1015
+ pause_class: "ROOM · PAUSE",
1016
+ pause_right: "// confirm",
1017
+ pause_tag: "// pause room",
1018
+ pause_title: "Pause the room?",
1019
+ pause_deck:
1020
+ "the room state is preserved — you can resume from this exact spot later.",
1021
+ pause_soft_mark: "soft pause",
1022
+ pause_soft_deck: "queue stays · directors finish their current turn",
1023
+ pause_hard_mark: "hard stop",
1024
+ pause_hard_deck: "abort streams immediately · no graceful finish",
1025
+ pause_cancel_mark: "✕",
1026
+ pause_cancel_deck: "keep the room running",
1027
+ pause_bar_paused: "// discussion paused.",
1028
+ pause_bar_resume: "[ ▶ Resume Discussion ]",
1029
+ pause_bar_adjourn: "[ ⏏ Adjourn ]",
1030
+ pause_bar_next: "next turn:",
1031
+ pause_bar_add_input: "add a prompt for resume",
1032
+
1033
+ sc_send_class: "ROOM · INPUT",
1034
+ sc_send_right: "// dispatch",
1035
+ sc_send_tag: "// send",
1036
+ sc_send_title: "How should this land?",
1037
+ sc_send_deck: "the queue is mid-turn · pick how your input enters the room.",
1038
+ sc_queue_mark: "▼ queue",
1039
+ sc_queue_deck: "your message lands after {speaker} finishes speaking.",
1040
+ sc_interrupt_mark: "⊘ interrupt",
1041
+ sc_interrupt_deck: "stop the current speaker · your message takes the floor.",
1042
+ sc_cancel_mark: "✕",
1043
+ sc_cancel_deck: "back out · don't send.",
1044
+ sc_speaker_fallback: "the current speaker",
1045
+
1046
+ // Queue
1047
+ q_speaking: "speaking",
1048
+ q_state_speaking: "speaking",
1049
+ q_queued: "queued · {n}",
1050
+ q_pending_chair: "the chair is preparing…",
1051
+ q_pending_vote: "round-end vote pending",
1052
+ q_pending_waits_chair: "waiting on the chair…",
1053
+ q_pending_your_vote: "your vote · cast above",
1054
+ q_user_queued: "you · queued",
1055
+ q_more_queued: "+{n} more queued",
1056
+ q_idle: "idle · type to interject",
1057
+ q_cancel: "cancel",
1058
+
1059
+ // Reports list (All Reports view)
1060
+ rep_kicker: "// archive",
1061
+ rep_title: "All Reports",
1062
+ rep_meta: "{total} {unit}{rooms}",
1063
+ rep_meta_room_n: "{n} rooms",
1064
+ rep_meta_room_one: "{n} room",
1065
+ rep_total_n: "{n} reports",
1066
+ rep_total_one: "{n} report",
1067
+ rep_showing: "showing {n}",
1068
+ rep_filter_all: "All",
1069
+ rep_filter_today: "Today",
1070
+ rep_filter_week: "This week",
1071
+ rep_filter_earlier: "Earlier",
1072
+ rep_filter_archive_label: "the archive",
1073
+ rep_aria_filters: "Filter reports by recency",
1074
+ rep_group_today: "Today",
1075
+ rep_group_yesterday: "Yesterday",
1076
+ rep_group_week: "This week",
1077
+ rep_group_earlier: "Earlier",
1078
+ rep_empty_kicker_archive: "// archive empty",
1079
+ rep_empty_kicker_window: "// window empty",
1080
+ rep_empty_title_none:
1081
+ "Run a session and adjourn — once the chair files, every brief across every room lands here.",
1082
+ rep_empty_title_window:
1083
+ "Run a session and adjourn — once the chair files, briefs in this window land here.",
1084
+ rep_empty_deck_all: "Nothing's been filed yet.",
1085
+ rep_empty_deck_window: "No reports in this window.",
1086
+ rep_empty_deck_filter: "No reports in {label}.",
1087
+ rep_cta_show_all: "Show all reports",
1088
+ rep_cta_convene: "[ + Convene a room ]",
1089
+ rep_load_more: "Load {batch} more · {remaining} remaining",
1090
+
1091
+ // Notes (All Notes view + per-room notes)
1092
+ notes_kicker: "// chairman · saved excerpts",
1093
+ notes_title: "All Notes",
1094
+ notes_meta: "{total} {unit}{rooms}",
1095
+ notes_one: "1 note",
1096
+ notes_many: "{n} notes",
1097
+ notes_aria_filters: "Filter notes by recency",
1098
+ notes_filter_all: "All",
1099
+ notes_director_fallback: "Director",
1100
+ notes_item_room: "from {room}",
1101
+ notes_empty_window: "this window",
1102
+ notes_empty_title: "No notes in {label}",
1103
+ notes_empty_deck: "Pick a different filter, or jump back to the full archive.",
1104
+ notes_empty_filter_deck: "No notes in {label}",
1105
+ notes_cta_show_all: "Show all notes",
1106
+ note_saved: "Note saved",
1107
+
1108
+ // Messages · chair / web-search / context bubble
1109
+ msg_tag_you: "you",
1110
+ msg_tag_chair: "chair",
1111
+ msg_chair_pick: "the chair picked the next speaker",
1112
+ msg_chair_billing_kicker: "// chair",
1113
+ msg_chair_direct_kicker: "// directed",
1114
+ msg_chair_intervention_kicker: "// chair · stepping in",
1115
+ msg_chair_display_fallback: "Chair",
1116
+ msg_ctx_title: "Context",
1117
+ msg_ctx_inline: "with context",
1118
+ msg_model_title: "Model · {modelV}",
1119
+ msg_skills_used: "skills · {names}",
1120
+ msg_ws_banner: "web search",
1121
+ msg_ws_btn: "{n} sources",
1122
+ msg_ws_btn_one: "1 source",
1123
+ msg_ws_done: "{n} sources fetched",
1124
+ msg_ws_done_one: "1 source fetched",
1125
+ msg_ws_query_label: "query:",
1126
+ msg_ws_searching: "searching…",
1127
+ msg_ws_failed: "search failed",
1128
+ msg_ws_failed_elapsed: "search failed after {s}s",
1129
+ msg_ws_secs: "{s}s",
1130
+ msg_ws_title: "Web search results",
1131
+ msg_ws_toggle: "toggle results",
1132
+ msg_ws_expand_show: "show",
1133
+ msg_ws_expand_hide: "hide",
1134
+
1135
+ // Chat-level chrome
1136
+ chat_banner: "// chat",
1137
+ chair_pend_banner: "the chair is preparing the next move…",
1138
+ ending_session_foot: "// session ended",
1139
+
1140
+ // Structured-mode write-stage labels · used by renderBriefStages
1141
+ // when the brief is magazine / newspaper / ppt. The write step
1142
+ // for these modes is one chair-LLM call producing the full
1143
+ // BentoScaffold (no per-section chapters), so the label needs
1144
+ // to read as one composing pass, not a chapter-by-chapter write.
1145
+ brief_stage_magazine_write_label: "Composing the magazine",
1146
+ brief_stage_newspaper_write_label: "Composing the newspaper",
1147
+ brief_stage_ppt_write_label: "Composing the deck",
1148
+ brief_stage_magazine_write_pip: "compose",
1149
+ brief_stage_newspaper_write_pip: "compose",
1150
+ brief_stage_ppt_write_pip: "compose",
1151
+
1152
+ // Misc
1153
+ agent_role_tag_moderator: "Moderator",
1154
+ picker_no_directors: "No directors available · convene one first.",
1155
+ migrate_head: "// migrating",
1156
+ },
1157
+ zh: {
1158
+ locale_en: "EN",
1159
+ locale_zh: "中文",
1160
+ aria_language: "语言",
1161
+
1162
+ brand_privateboard: "PRIVATEBOARD",
1163
+ brand_control: "控制台",
1164
+ classification: "私有访问",
1165
+ topbar_sync: "同步:",
1166
+ topbar_uid: "用户:",
1167
+ topbar_room: "会议室:",
1168
+
1169
+ sidebar_head: "// 控制台",
1170
+ sidebar_tab_rooms: "会议室",
1171
+ sidebar_tab_agents: "智能体",
1172
+ sidebar_new_room: "新会议",
1173
+ sidebar_all_reports: "全部报告",
1174
+ sidebar_all_notes: "全部笔记",
1175
+ sidebar_new_agent: "新智能体",
1176
+ sidebar_host: "// 主持人",
1177
+ sidebar_collapse: "收起侧栏",
1178
+ sidebar_expand: "展开侧栏",
1179
+ sidebar_summary: "{live} 进行中 / {agents} 个智能体",
1180
+
1181
+ queue_speaking_queue: "发言队列",
1182
+ queue_mode: "模式:",
1183
+ queue_toggle: "收起 / 展开",
1184
+ queue_foot_hint: "随时插话 · <kbd>@</kbd> 指定董事 · 主席在回合结束时发起关键点评投票",
1185
+ send_placeholder: "随时插话 · @handle 指定某位董事…",
1186
+ send_button: "[ 发送 ]",
1187
+ ib_pause_label: "暂停讨论",
1188
+ ib_pause_tip: "暂停 · 可稍后继续",
1189
+ ib_adjourn_label: "结束会议",
1190
+ ib_adjourn_tip: "散会 · 归档报告并结束",
1191
+
1192
+ paused_bar_template: "// 讨论已暂停。",
1193
+ adjourned_strong: "// 会议已结束。",
1194
+ adjourned_deck: "报告已归档在上方。",
1195
+
1196
+ adj_title_file: "归档简报?",
1197
+ adj_title_generate: "生成简报",
1198
+ adj_classify_adjourn: "会议 · 散会",
1199
+ adj_classify_generate: "会议 · 生成简报",
1200
+ adj_classify_right_terminal: "// 收尾",
1201
+ adj_classify_right_posthoc: "// 事后补写",
1202
+ adj_confirm_file: "[ 散会并归档 ]",
1203
+ adj_confirm_generate: "[ 生成 ]",
1204
+ adj_meta_room_kicker: "// 会议 ",
1205
+ adj_meta_sep: " · ",
1206
+ adj_meta_status_live: "进行中",
1207
+ adj_meta_status_paused: "已暂停",
1208
+ adj_meta_status_adjourned: "已归档",
1209
+ adj_meta_turns: "{n} 轮",
1210
+ adj_key_subject: "// 主题",
1211
+ adj_key_authors: "// 智能体",
1212
+ adj_key_turns: "// 轮次",
1213
+ adj_agents_count: "{n} 个智能体",
1214
+ adj_note_adjourn:
1215
+ "主席将根据会议记录整理标准简报(情境、要点与启示)。会议将标记为已归档,简报会出现在对话中。",
1216
+ adj_note_generate:
1217
+ "主席将根据会议记录整理标准简报(情境、要点与启示),并写入对话。",
1218
+ adj_skip: "不生成简报,直接结束",
1219
+ adj_cancel: "[ 取消 ]",
1220
+ adj_close_aria: "关闭",
1221
+ adj_busy_generate: "[ 生成中… ]",
1222
+ adj_busy_adjourn: "[ 归档中… ]",
1223
+ adj_err_generate: "生成失败:",
1224
+ adj_err_adjourn: "归档失败:",
1225
+
1226
+ export_btn: "[↓] 导出",
1227
+ followup_btn: "[→] 召开跟进会",
1228
+
1229
+ sys_notice_dismiss: "关闭",
1230
+
1231
+ rep_title: "全部报告",
1232
+ rep_kicker: "// 归档",
1233
+ rep_meta: "{n} 份报告",
1234
+ rep_meta_room: " · {n} 间会议室",
1235
+ rep_filter_all: "全部",
1236
+ rep_filter_today: "今天",
1237
+ rep_filter_week: "本周",
1238
+ rep_filter_earlier: "更早",
1239
+ rep_filter_archive_label: "归档",
1240
+ rep_group_today: "今天",
1241
+ rep_group_yesterday: "昨天",
1242
+ rep_group_week: "本周",
1243
+ rep_group_earlier: "更早",
1244
+ rep_empty_kicker_archive: "// 归档为空",
1245
+ rep_empty_kicker_window: "// 当前范围为空",
1246
+ rep_empty_title_none: "暂无报告",
1247
+ rep_empty_title_window: "{window}内暂无报告",
1248
+ rep_empty_deck_all:
1249
+ "进行一场会议并散会 — 主席归档后,所有会议室的简报都会出现在这里。",
1250
+ rep_empty_deck_window:
1251
+ "进行一场会议并散会 — 该时间范围内的简报会出现在这里。或返回查看全部归档。",
1252
+ rep_empty_deck_filter: "换个筛选条件,或返回完整归档。",
1253
+ rep_cta_convene: "召开新会议",
1254
+ rep_cta_show_all: "显示全部报告",
1255
+ rep_aria_filters: "按时间筛选报告",
1256
+ rep_sentinel_more: "另有 {n} 条 · 滚动或点击加载",
1257
+ rep_total_one: "1 份报告",
1258
+ rep_total_n: "{n} 份报告",
1259
+ rep_meta_room_one: " · 1 间会议室",
1260
+ rep_meta_room_n: " · {n} 间会议室",
1261
+ rep_showing: " · 显示 {n} 条",
1262
+ rep_load_more: "再加载 {load} 条 · 剩余 {remaining} 条",
1263
+
1264
+ notes_title: "全部笔记",
1265
+ notes_kicker: "// 主席摘录",
1266
+ notes_meta: "{n} 条笔记",
1267
+ notes_meta_room: " · {n} 间会议室",
1268
+ notes_one: "1 条笔记",
1269
+ notes_many: "{n} 条笔记",
1270
+ rooms_one: "1 间会议室",
1271
+ rooms_many: "{n} 间会议室",
1272
+
1273
+ picker_no_directors: "暂无董事",
1274
+ notes_filter_all: "全部",
1275
+ notes_empty_title: "暂无保存的笔记",
1276
+ notes_empty_deck:
1277
+ "阅读董事回复时,选中一段文字并按 <span class=\"kbd\">S</span> 或点击浮动条上的 <span class=\"kbd\">⌖ 保存</span>,即可收藏到此。",
1278
+ notes_empty_window: "{window}内暂无笔记",
1279
+ notes_empty_filter_deck: "换个筛选条件,或返回完整归档。",
1280
+ notes_cta_show_all: "显示全部笔记",
1281
+ notes_aria_filters: "按时间筛选笔记",
1282
+ notes_director_fallback: "董事",
1283
+ notes_item_room: "会议室",
1284
+
1285
+ room_meeting_room: "会议室",
1286
+ room_meta_tone: "模式",
1287
+ room_meta_intensity: "强度",
1288
+ room_meta_report: "报告",
1289
+ room_stamp_paused: "{ago} 前暂停",
1290
+ room_stamp_adjourned: "{ago} 前散会",
1291
+ room_stamp_opened: "{ago} 前开始",
1292
+ room_cast_title_1: "1 位董事",
1293
+ room_cast_n: "{n} 位董事",
1294
+ room_settings: "会议室设置",
1295
+ room_pause_verb: "暂停",
1296
+ room_resume_verb: "继续",
1297
+ room_view_report: "[ 查看报告 ]",
1298
+ room_view_report_multi: "[ 查看报告 · {n} ▾ ]",
1299
+ room_view_report_title_multi: "{n} 份报告 · 点击选择",
1300
+ room_generate_report: "生成报告",
1301
+ room_generate_report_title: "为本场会议补出报告",
1302
+ room_chair_pick_title: "本回合由主席点名 {name}",
1303
+ msg_chair_pick: "▸ 主席 · {body}",
1304
+
1305
+ chat_banner: "会议开始 · {when} · {n} 位董事 · {mode}",
1306
+
1307
+ round_end_vote_above: "本回合已结束 · 请在上方投票",
1308
+ round_clarifying: "澄清中 — 等待主席",
1309
+ round_end_open_vote: "结束回合 · 开启关键点评投票",
1310
+
1311
+ rp_spent_round: "第 {n} 轮",
1312
+ rp_spent_label: "已关闭 · 会议已继续",
1313
+ rp_chair_recommends: "主席建议",
1314
+ rp_continue_next: "继续 · 下一回合",
1315
+ rp_adjourn_room_file: "⊘ 散会并归档简报",
1316
+
1317
+ kp_eyebrow_drafting: "▸ 关键观点 · 生成中",
1318
+ kp_pending_drafting: "主席正在整理关键观点…",
1319
+ kp_eyebrow_degraded: "▸ 关键观点 · 未能从本轮发言中解析",
1320
+ kp_eyebrow_vote: "▸ 关键观点 · 投票决定跟进方向",
1321
+ kp_ctas_spent: "// 已继续",
1322
+ kp_btn_continue_next: "[ ▶ 继续 · 下一回合 ]",
1323
+ kp_btn_adjourn_brief: "[ ⊘ 散会并归档简报 ]",
1324
+ kp_btn_adjourn: "[ ⊘ 散会 ]",
1325
+ kp_shift_eyebrow_prefix: "▸ 主席建议 · 将语气切换为 ",
1326
+ kp_switch_to: "[ ↻ 切换为 {mode} ]",
1327
+ kp_keep_mode: "[ 保持 {mode} ]",
1328
+ kp_mode_current_fallback: "当前",
1329
+ kp_vote_more: "跟进",
1330
+ kp_vote_drop: "舍去",
1331
+ kp_vote_aria_up: "感兴趣",
1332
+ kp_vote_aria_down: "不感兴趣",
1333
+
1334
+ agent_role_tag_moderator: "主持人",
1335
+
1336
+ ap_track_record: "履历",
1337
+ ap_track_tag_model_usage: "模型 · 用量",
1338
+ ap_voice_section: "说话配置",
1339
+ ap_voice_section_tag: "tts · 服务商 · 音色",
1340
+ ap_skills: "技能",
1341
+ ap_skills_installed: "已装 {current} / 上限 {cap}",
1342
+ ap_skills_cap_reached: "已达上限 ({current}/{cap}) · 需先卸载再安装",
1343
+ ap_skills_drop_hint: "安装技能 · 拖入 <code>.md</code> 或点击上传",
1344
+ ap_skills_load_fail: "技能加载失败 · {detail}",
1345
+ ap_stat_rooms: "会议室",
1346
+ ap_stat_rounds: "回合",
1347
+ ap_stat_tokens: "tokens",
1348
+ ap_intel: "情报",
1349
+ ap_instruction: "指令",
1350
+ ap_rules: "规则",
1351
+ ap_memory: "记忆",
1352
+ ap_edit: "编辑",
1353
+ ap_cancel: "取消",
1354
+ ap_save: "保存",
1355
+ ap_rules_add: "+ 添加规则",
1356
+ ap_rules_max: "上限 {n} 条",
1357
+ ap_rules_empty_list: "暂无规则 · 点击上方「+ 添加规则」",
1358
+ ap_memory_add: "+ 添加笔记",
1359
+ ap_dream_consolidate_btn: "☾ 整理记忆",
1360
+ ap_dream_consolidate_title: "整理记忆:丢下过时笔记,保留稳定模式",
1361
+ ap_show_more: "展开",
1362
+ ap_show_less: "收起",
1363
+ ap_intel_empty: "尚无简介 · 点击编辑添加",
1364
+ ap_instr_empty: "尚无指令 · 点击编辑以 Markdown 撰写",
1365
+ ap_instr_placeholder_editor:
1366
+ "使用 Markdown · ### 标题 · **粗体** · *斜体* · - 列表 · `代码`",
1367
+ ap_instr_edit_hint: "支持 Markdown · Esc 取消",
1368
+ ap_intel_placeholder: "用一句话描述这位董事如何思考 · {min}–{max} 字",
1369
+ ap_intel_hint: "{min}–{max} 字 · Esc 取消",
1370
+ ap_status_intern: "实习 · 试用",
1371
+ ap_status_active: "可用",
1372
+ ap_role_director_upper: "董事",
1373
+ ap_aria_id_menu: "更多",
1374
+ ap_live_agent_director: "董事",
1375
+
1376
+ ap_voice_browser_default: "浏览器默认",
1377
+ ap_voice_engine_browser: "浏览器合成",
1378
+ ap_voice_speed: "语速",
1379
+ ap_voice_pitch: "语调",
1380
+ ap_voice_emotion_label: "情绪",
1381
+ ap_voice_emotion_hint: "为合成语音设定情绪基调;选「自动」交由模型决定。",
1382
+ ap_voice_advanced: "高级调节",
1383
+ ap_voice_locked_tag: "// 待解锁",
1384
+ ap_voice_locked_title: "配置一个语音服务商,董事就能以自己的音色发声。",
1385
+ ap_voice_locked_body: "配置一个语音服务商即可解锁 TTS — 董事将以自己的音色发声,可调语速、语调与情绪。",
1386
+ ap_voice_locked_cta: "解锁声音",
1387
+ ap_voice_locked_providers: "已接入 <b>MiniMax</b> · <b>ElevenLabs</b>",
1388
+ ap_voice_modify_pitch: "音高",
1389
+ ap_voice_modify_intensity: "力度",
1390
+ ap_voice_modify_timbre: "音色",
1391
+ ap_voice_preview_btn_title: "试听",
1392
+ ap_voice_no_provider: "尚未配置可用的语音提供商。",
1393
+ ap_voice_loading: "加载音色中…",
1394
+ ap_voice_fallback_voice: "语音",
1395
+ ap_voice_save_err: "未能保存语音设置:{msg}",
1396
+ ap_voice_preview_need_voice: "请先选择一个音色。",
1397
+ ap_voice_preview_failed: "试听失败:{msg}",
1398
+ ap_voice_preview_playback_blocked: "无法播放音频:{msg}",
1399
+ ap_voice_preview_err: "试听出错:{msg}",
1400
+ ap_voice_emotion_auto: "自动",
1401
+ ap_voice_emotion_happy: "愉快",
1402
+ ap_voice_emotion_sad: "悲伤",
1403
+ ap_voice_emotion_angry: "愤怒",
1404
+ ap_voice_emotion_fearful: "胆怯",
1405
+ ap_voice_emotion_disgusted: "厌恶",
1406
+ ap_voice_emotion_surprised: "惊讶",
1407
+ ap_voice_emotion_calm: "平静",
1408
+ ap_voice_emotion_fluent: "流畅",
1409
+
1410
+ ap_model_stale_title: "当前 API 密钥无法使用该模型,运行时将回退到全局默认。",
1411
+ ap_model_stale_text: "不可达 · 运行时使用默认模型",
1412
+
1413
+ ao_personnel_kicker: "董事 · 人事档案",
1414
+ ao_classified_mark: "// 机密",
1415
+ ao_lens: "视角",
1416
+ ao_model: "模型",
1417
+ ao_style: "风格",
1418
+ ao_memory_room: "场内笔记",
1419
+ ao_badge_this_room: "本场",
1420
+ ao_badge_classified: "⊘ 机密",
1421
+ ao_lock_blurb_html:
1422
+ '场内笔记对每位董事私密。<a href="/" class="lock-link">登录 →</a>以查看其发言与立场变化。',
1423
+ ao_tenure_meta: "任期 ·",
1424
+ ao_first_room_meta: "首场 ·",
1425
+ ao_free: "免费",
1426
+ ao_convene_cta: "[ ◆ 与其开会 ]",
1427
+ ao_signin_cta: "[ → 登录后召开 ]",
1428
+ ao_room_notes_empty: "当前无进行中的会议 · 打开会议室后可查看该董事的场内笔记。",
1429
+ ao_room_notes_waiting: "尚未发言 · 发言后关键论断与立场变化会出现在此。",
1430
+
1431
+ convene_show_more: "展开全文 ↓",
1432
+ convene_show_less: "收起 ↑",
1433
+ convene_eyebrow: "▸ 召开 · 初始问题",
1434
+ convene_meta_to: "致",
1435
+
1436
+ msg_model_title: "模型 · {label}",
1437
+ msg_skills_used: "所用技能:{list}",
1438
+ msg_ws_title: "联网搜索:{query} · {n} 条来源",
1439
+ msg_ws_btn: "联网搜索 · {n} 条来源",
1440
+ msg_ws_btn_one: "联网搜索 · 1 条来源",
1441
+ msg_ws_searching: "检索中…",
1442
+ msg_ws_done: "{n} 条来源{tail}",
1443
+ msg_ws_done_one: "1 条来源{tail}",
1444
+ msg_ws_failed: "失败",
1445
+ msg_ws_failed_elapsed: "失败 · {elapsed}",
1446
+ msg_ws_banner: "// 联网搜索",
1447
+ msg_ws_toggle: "展开/收起来源",
1448
+ msg_ws_expand_show: "显示全部 {n} 条来源",
1449
+ msg_ws_query_label: "查询",
1450
+ msg_ws_expand_hide: "收起",
1451
+ msg_ws_secs: "{n} 秒",
1452
+ msg_chair_direct_kicker: "▸ 主席 · 直接回复你",
1453
+ msg_chair_intervention_kicker: "▸ 主席说明",
1454
+ msg_chair_billing_kicker: "▸ 计费 · 需要处理",
1455
+ msg_chair_display_fallback: "主席",
1456
+ msg_ctx_title: "已向 {name} 附 {n} 轮上文",
1457
+ msg_ctx_inline: "· {n} 上文",
1458
+ msg_tag_you: "// 你",
1459
+ msg_tag_chair: "// 主席",
1460
+
1461
+ sa_head: "// 会议数据",
1462
+ sa_stamp: "已结束",
1463
+ sa_tokens: "tokens",
1464
+ sa_messages: "条消息",
1465
+ sa_rounds: "轮讨论",
1466
+ sa_minutes: "分钟",
1467
+ sa_model_head: "模型用量",
1468
+ sa_value_head: "你认为有价值的",
1469
+ sa_value_empty: "本次没有 ▲ key point 投票,也没有用 probe / second。",
1470
+ sa_voted: "▲ 投票",
1471
+ sa_seconded: "★ 附议",
1472
+ sa_probed: "✎ 追问",
1473
+ sa_seg_title: "{model} · {tokens} tokens",
1474
+
1475
+ nk_title: "需要配置模型 API key",
1476
+ nk_deck:
1477
+ "董事会的话主席与董事都依赖大模型。请先配置至少一个供应商的 API key(Anthropic / OpenAI / Google / xAI / DeepSeek / OpenRouter)。",
1478
+ nk_primary: "[ 打开设置 ▸ ]",
1479
+ nk_dismiss: "[ 取消 ]",
1480
+ nk_classification: "ai · 缺少模型 key",
1481
+ nk_tag: "▸ 配置 API key",
1482
+ nk_primary_deck: "前往 Preferences → API Key,粘贴任意一家供应商的 key 即可解锁房间。",
1483
+ nk_frontend_gate: "// 前端门禁",
1484
+
1485
+ sc_send_class: "发送 · 选择",
1486
+ sc_send_right: "// {name} 正在发言",
1487
+ sc_send_tag: "▸ 回合中发送",
1488
+ sc_send_title: "{name} 这一轮尚未说完。",
1489
+ sc_send_deck: "立即插话,还是等对方说完再发?",
1490
+ sc_interrupt_mark: "▸ 打断并立即发送",
1491
+ sc_interrupt_deck: "立刻进入房间。{name} 会继续在你之后输出。",
1492
+ sc_queue_mark: "→ 等 {name} 说完再发",
1493
+ sc_queue_deck: "消息排队在本回合结束后自动发出。",
1494
+ sc_cancel_mark: "✕ 取消",
1495
+ sc_cancel_deck: "继续输入,稍后决定。",
1496
+ sc_speaker_fallback: "某位董事",
1497
+
1498
+ pause_class: "暂停 · 选择",
1499
+ pause_right: "// 回合进行中",
1500
+ pause_tag: "▸ 暂停讨论",
1501
+ pause_title: "{name} 正在发言。",
1502
+ pause_deck: "希望如何暂停?",
1503
+ pause_hard_mark: "▍ 立即停止",
1504
+ pause_hard_deck: "中途截断回复,已生成部分丢弃。",
1505
+ pause_soft_mark: "⌛ 等本轮结束",
1506
+ pause_soft_deck: "让 {name} 说完本轮,再暂停队列。",
1507
+ pause_cancel_mark: "↩ 取消",
1508
+ pause_cancel_deck: "不暂停,继续讨论。",
1509
+
1510
+ pause_bar_add_input: "[ + 补充观点 ]",
1511
+ pause_bar_adjourn: "[ ▸ 结束并存档 ]",
1512
+ pause_bar_resume: "[ ▶ 恢复讨论 ]",
1513
+ pause_bar_paused: "已暂停",
1514
+ pause_bar_next: "下一位",
1515
+
1516
+ cmp_tone_label: "语气",
1517
+ cmp_intensity_label: "强度",
1518
+ cmp_voice_tooltip: "开启语音会议",
1519
+ cmp_voice_label: "Voice Mode",
1520
+
1521
+ conv_stage_analyzing_title: "分析议题",
1522
+ conv_stage_analyzing_deck: "haiku 路由器在拆解你提的话题",
1523
+ conv_stage_seating_title: "邀请董事",
1524
+ conv_stage_seating_deck: "依据议题匹配的董事正在入席",
1525
+ conv_stage_preparing_title: "主席组织开场陈词",
1526
+ conv_stage_preparing_deck: "主席正在准备介绍发言",
1527
+ conv_seated_label: "已入席",
1528
+ conv_banner_convening: "▸ 召集中",
1529
+
1530
+ chair_pend_banner: "▸ 主席",
1531
+ chair_pend_clarify: "{name}正在整理你的问题…",
1532
+ chair_pend_chair_direct: "{name}正在准备回应…",
1533
+ chair_pend_round_end: "{name}正在收束这一轮…",
1534
+ chair_pend_convening: "{name}正在召集会议…",
1535
+ chair_pend_next_speaker: "{name}正在判断接下来的发言…",
1536
+ chair_pend_default: "{name}正在准备…",
1537
+
1538
+ brief_regen_timeout: "重新生成超时",
1539
+ brief_regen_interrupted: "重新生成被中断",
1540
+ brief_regen_failed: "重新生成失败",
1541
+ brief_retry: "重试",
1542
+ brief_dismiss: "关闭",
1543
+
1544
+ brief_tab_initial: "初版",
1545
+ brief_tab_tooltip_initial: "初版报告 · 由会议本身生成",
1546
+ brief_tab_supplement_prefix: "补充视角:",
1547
+ brief_tab_delete_title: "删除这份报告",
1548
+
1549
+ brief_err_stamp_timeout: "超时",
1550
+ brief_err_kicker_timeout: "// 报告生成超时",
1551
+ brief_err_detail_timeout:
1552
+ "已超过 8 分钟仍未收到完成信号 · 可能是模型回应过慢、网络中断,或后端流水线卡住了。点击下方按钮重试,或检查 LLM key 与网络后再试。",
1553
+ brief_err_stamp_interrupted: "已中断",
1554
+ brief_err_kicker_interrupted: "// 报告生成被中断了",
1555
+ brief_err_detail_interrupted: "上一次生成在浏览器刷新或服务重启时中止了。点击下方按钮重新生成一份报告。",
1556
+ brief_err_cta_regenerate: "重新生成报告",
1557
+ brief_err_stamp_failed: "失败",
1558
+ brief_err_kicker_failed: "// 报告生成失败",
1559
+ brief_err_hint_failed_html:
1560
+ "Brief writer 需要一个 LLM key(OpenRouter,或 Anthropic / OpenAI / Google / xAI 直连)。在 <strong>Preference → API Key</strong> 中添加后再试。",
1561
+ brief_err_hint_scaffold_html:
1562
+ "报错来自<strong>内部脚手架步骤</strong>:主席所用模型需要先产出可被解析的结构化 JSON。常见原因是会话里几乎没有可抽取的要点、输出被截断或格式错乱、上游限流/计费报错——若在 Preference 里已显示配置了 Key,<strong>通常不是</strong>「没填 Key」。可尝试<strong>重新生成</strong>、缩短对话、把主席换成当前 Key 下可用的其他模型,或在服务端 stderr 搜索 <code>[brief.stage2]</code>。",
1563
+ brief_err_hint_generic_html:
1564
+ "请以<strong>上行红色英文原文</strong>为准。若其中提到 Key、计费或 <code>401</code>/<code>403</code>,请核对 <strong>Preference → API Key</strong> 与配额;否则请查看服务端日志中的上游错误。",
1565
+
1566
+ brief_output_head: "▼ 会议产出 ▼",
1567
+ brief_report_tag: "// 报告",
1568
+ brief_filed_generating: "生成中…",
1569
+ brief_filed_stamp: "已归档 · {when}",
1570
+ brief_filed_by: "// 归档人 {name}",
1571
+ brief_untitled: "(无标题)",
1572
+ brief_meta_authors: "{n} 位作者",
1573
+ brief_open_report: "打开报告",
1574
+ brief_chair_fallback: "主席",
1575
+
1576
+ brief_hard_timeout_msg: "报告生成超时(超过 8 分钟仍未完成)。",
1577
+ brief_stage_kicker: "// {chair} 正在整理纪要 · {total}",
1578
+ brief_stage_extract_label: "读完房间里每个人的发言",
1579
+ brief_stage_extract_pip: "听",
1580
+ brief_stage_compose_label: "选定报告骨架与组件",
1581
+ brief_stage_compose_pip: "选",
1582
+ brief_stage_scaffold_anchor_label: "敲定核心判断 (anchor)",
1583
+ brief_stage_scaffold_anchor_pip: "锚",
1584
+ brief_stage_scaffold_findings_label: "勾勒主张与发现",
1585
+ brief_stage_scaffold_findings_pip: "见",
1586
+ brief_stage_scaffold_cluster_label: "梳理共识与分歧",
1587
+ brief_stage_scaffold_cluster_pip: "辨",
1588
+ brief_stage_scaffold_actions_label: "拟动作 · 推演风险",
1589
+ brief_stage_scaffold_actions_pip: "拟",
1590
+ brief_stage_write_label: "撰写最终报告",
1591
+ brief_stage_write_pip: "写",
1592
+
1593
+ brief_sub_extract_0: "重读每位董事的发言",
1594
+ brief_sub_extract_1: "按视角标签(data / dissent / narrative / structural / first-principle)整理信号",
1595
+ brief_sub_extract_2: "压缩到每位董事 2-4 条关键信号",
1596
+ brief_sub_compose_0: "选定本份报告的 spine 风格",
1597
+ brief_sub_compose_1: "决定要纳入哪些组件块",
1598
+ brief_sub_compose_2: "估算密度与节奏",
1599
+ brief_sub_scaffold_anchor_0: "读出 takeaway",
1600
+ brief_sub_scaffold_anchor_1: "校准 confidence",
1601
+ brief_sub_scaffold_anchor_2: "落定 working hypothesis",
1602
+ brief_sub_scaffold_findings_0: "提炼 3 条 headline findings",
1603
+ brief_sub_scaffold_findings_1: "复核每条是否撑住 anchor",
1604
+ brief_sub_scaffold_findings_2: "如有勉强,3 → 2 收敛",
1605
+ brief_sub_scaffold_cluster_0: "定位董事们达成共识的地方",
1606
+ brief_sub_scaffold_cluster_1: "标记核心张力",
1607
+ brief_sub_scaffold_cluster_2: "辨认未消化的立场",
1608
+ brief_sub_scaffold_actions_0: "起草 recommendations",
1609
+ brief_sub_scaffold_actions_1: "推演 pre-mortem",
1610
+ brief_sub_scaffold_actions_2: "梳理会议长出的新问题",
1611
+ brief_sub_write_0: "撰写 Bottom Line",
1612
+ brief_sub_write_1: "撰写 Frame Shift 段落",
1613
+ brief_sub_write_2: "撰写 3 条 Headline Findings",
1614
+ brief_sub_write_3: "起草 Convergence 与 Divergence 段落",
1615
+ brief_sub_write_4: "撰写 Recommendations",
1616
+ brief_sub_write_5: "撰写 Pre-mortem",
1617
+ brief_sub_write_6: "梳理 New Questions",
1618
+ brief_sub_write_7: "起草 Strategic Planning Assumption",
1619
+ brief_sub_write_8: "通读润色,准备交稿",
1620
+
1621
+ brief_prog_directors_one: "{cur}/{tot} 位董事",
1622
+ brief_prog_directors: "{cur}/{tot} 位董事",
1623
+ brief_prog_words_one: "1 词",
1624
+ brief_prog_words: "{n} 词",
1625
+ brief_timing_inband: "{e}s · ~{lo}–{hi}s",
1626
+ brief_timing_eta: "~{lo}–{hi}s",
1627
+ brief_timing_over: "已耗时 {n}s",
1628
+ brief_range_sec: "约 {lo}–{hi}s",
1629
+ brief_range_min: "约 {lo}–{hi} 分钟",
1630
+ brief_total_line: "已 {elapsed} · 还需{range}",
1631
+ brief_fmt_sec: "{n}秒",
1632
+ brief_fmt_min: "{n}分",
1633
+ brief_fmt_min_sec: "{m}分{r}秒",
1634
+ brief_harvest_claims: "判断",
1635
+ brief_harvest_evidence: "证据",
1636
+ brief_harvest_tensions: "分歧",
1637
+ brief_harvest_assumptions: "假设",
1638
+ brief_harvest_risks: "风险",
1639
+ brief_harvest_opportunities: "机会",
1640
+ brief_harvest_actions: "动作",
1641
+ brief_harvest_quotes: "原话",
1642
+ brief_harvest_open_questions: "悬而未决",
1643
+ brief_stat_writing: "{n} 词 · 还在落笔",
1644
+ brief_supplement_btn: "补充视角,再生成一版报告",
1645
+ brief_delete_label: "删除报告",
1646
+ ending_session_foot: "// 会议结束",
1647
+ brief_wc_approx_chars: "约 {n} 字",
1648
+ brief_wc_one_word: "1 词",
1649
+ brief_wc_words: "{n} 词",
1650
+
1651
+ na_class_left: "董事库 · 新建",
1652
+ na_class_right: "// 人工塑造角色",
1653
+ na_step_kicker_html: '// 新建<span class="hl">董事</span> · 手动配置',
1654
+ na_step_title: "塑造角色",
1655
+ na_close_aria: "关闭",
1656
+ na_avatar_regen: "生成 8-bit 头像",
1657
+ na_field_name: "姓名",
1658
+ na_field_intro: "简介",
1659
+ na_field_instruction: "指令",
1660
+ na_field_model: "模型",
1661
+ na_instr_meta: "字 · Markdown",
1662
+ na_name_ph: "Aurelia · 长线战略家",
1663
+ na_intro_ph:
1664
+ "一两句话说明这位董事在场里如何开口。用百年尺度读材料,分得清哪些是重复的模式、哪些是例外。",
1665
+ na_instr_ph: `### 角色
1666
+ 你是 __,在本场负责 __。你的任务是 ___。
1667
+
1668
+ ### 语气
1669
+ 要求 ___。不要 ___。在 ___ 时引用 ___。
1670
+
1671
+ ### 边界
1672
+ 当房间 ___ 时,要明确提出反对。`,
1673
+ na_hint_handle: "handle:",
1674
+ na_hint_bio: "会成为对外展示的 bio",
1675
+ na_hint_instr: "适用于其加入的每一场会议 · 技能与规则稍后在档案中配置",
1676
+ na_foot_meta: "创建后再配置技能 · 规则",
1677
+ na_cancel: "取消",
1678
+ na_create: "创建董事",
1679
+ na_rule_empty: "暂无规则 · 董事仅遵循其指令",
1680
+ na_rule_ph: "不要废话开场 · 用 **加粗** 标出承重论断 · ...",
1681
+ na_rule_rm: "删除",
1682
+ na_skill_install: "安装能力",
1683
+ na_skill_empty: "空",
1684
+ na_key_direct: "直连",
1685
+ na_key_via: "经 OpenRouter",
1686
+ na_key_none: "无 key",
1687
+ na_avatar_thinking: "思考中…",
1688
+ na_creating: "[ 创建中… ]",
1689
+ na_create_fail: "未能创建董事:{msg}",
1690
+
1691
+ convene_followup_label: "继续自",
1692
+ convene_room_label: "Room #",
1693
+ convene_parent_session_title: "返回上一场会议 · {subject}",
1694
+
1695
+ ro_round: "第 {n} 轮",
1696
+ ro_mode_parallel: "并行 · 独立视角",
1697
+ ro_mode_reactive: "接力 · 董事互评",
1698
+
1699
+ nb_cta: "生成报告",
1700
+ nb_eyebrow: "已散会 · 未归档简报",
1701
+ nb_body: "在结束时跳过了报告。",
1702
+ nb_chair_fallback: "主席",
1703
+
1704
+ note_tag_origin: "输入",
1705
+ note_tag_obs: "观察",
1706
+ note_tag_insight: "论断",
1707
+ note_tag_warn: "风险",
1708
+ note_tag_crux: "关键",
1709
+ note_tag_soln: "跟进",
1710
+ note_tag_open: "追问",
1711
+
1712
+ migrate_head: "存储结构已升级",
1713
+ migrate_body: "已应用 {count} 个新迁移 · 你已有的房间、智能体、报告、设置都已保留。",
1714
+ migrate_body_one: "已应用 1 个新迁移 · 你已有的房间、智能体、报告、设置都已保留。",
1715
+
1716
+ ag_gen_elapsed: "已耗时 {n} 秒",
1717
+ ag_gen_step: "第 {current} / {total} 步",
1718
+ ag_gen_header: "正在生成 director",
1719
+
1720
+ ag_cmp_prompt: "想招一位什么样的董事?",
1721
+ ag_cmp_placeholder:
1722
+ "自建 director 可以是你的反对派、领域专家、缺席的资深顾问——任何你一直希望坐在桌前的人。",
1723
+ ag_cmp_cta: "生成",
1724
+ ag_cmp_cta_hint: "AI 会生成一份完整 spec,你可以再调",
1725
+ ag_cmp_manual: "手动配置",
1726
+ ag_cmp_generating: "生成中…",
1727
+ ag_cmp_model_label: "模型",
1728
+ ag_cmp_starter_caption: "或者从一个 archetype 起手",
1729
+
1730
+ ag_err_kicker_timeout: "// 生成超时",
1731
+ ag_err_kicker_fail: "// 生成失败",
1732
+ ag_err_title_timeout: "生成超过 5 分钟仍未完成",
1733
+ ag_err_title_fail: "生成失败",
1734
+ ag_err_hint_timeout: "可能是模型过慢、网络波动或后端卡住。可点击重试。",
1735
+ ag_err_hint_fail: "请确认 API key 与模型可用性,重试常能解决临时故障。",
1736
+ ag_err_desc: "你的描述(重试时会复用)",
1737
+ ag_err_retry: "重试",
1738
+ ag_err_discard: "放弃",
1739
+ ag_err_prompt: "想招一位什么样的董事?",
1740
+
1741
+ ag_preview_kicker: "// 生成的 director · 编辑后保存",
1742
+ ag_preview_avatar: "头像",
1743
+ ag_preview_reroll: "换一个",
1744
+ ag_preview_name: "姓名",
1745
+ ag_preview_handle: "Handle",
1746
+ ag_preview_role: "角色标签",
1747
+ ag_preview_bio: "简介",
1748
+ ag_preview_quote: "封面引用",
1749
+ ag_preview_instruction: "指令",
1750
+ ag_preview_model: "模型",
1751
+ ag_preview_save: "保存董事",
1752
+ ag_preview_discard: "丢弃",
1753
+ ag_preview_redo: "重新生成",
1754
+
1755
+ ag_preview_radar_aria: "能力雷达",
1756
+
1757
+ ag_ws_needs_key: "未配置",
1758
+ ag_ws_enabled: "已开启",
1759
+ ag_ws_disabled: "已关闭",
1760
+ ag_ws_title_needs: "联网搜索需要 Brave Search 或 Tavily 密钥 · 点击配置",
1761
+ ag_ws_need_key_confirm:
1762
+ "联网搜索需要在偏好设置中添加 Brave Search 或 Tavily API 密钥。\n\nBrave Search · 约 $5 / 1000 次查询 · 侧重隐私;Tavily · 按官方额度计费 · 更适合 LLM。\n\n现在打开密钥设置页?",
1763
+ ag_ws_configure_key: "配置联网搜索密钥 ↗",
1764
+ ag_ws_title_on: "生成时联网检索领域真实案例 · 点击关闭",
1765
+ ag_ws_title_off: "生成时不联网 · 点击开启",
1766
+ ag_ws_label: "联网搜索",
1767
+
1768
+ greet_en_0: "// Up late, {name}",
1769
+ greet_en_1: "// Good morning, {name}",
1770
+ greet_en_2: "// Good afternoon, {name}",
1771
+ greet_en_3: "// Good evening, {name}",
1772
+ greet_zh_0: "// 凌晨好,{name}",
1773
+ greet_zh_1: "// 早上好,{name}",
1774
+ greet_zh_2: "// 中午好,{name}",
1775
+ greet_zh_3: "// 下午好,{name}",
1776
+ greet_zh_4: "// 晚上好,{name}",
1777
+ greet_zh_5: "// 夜深了,{name}",
1778
+
1779
+ brief_generating_title: "正在生成…",
1780
+
1781
+ q_idle: "队列空闲",
1782
+ q_speaking: "●●● 发言中",
1783
+ q_pending_vote: "等待 · 待投票",
1784
+ q_pending_chair: "等待 · 待主席",
1785
+ q_queued: "排队中",
1786
+ q_more_queued: "+{n} 人排队",
1787
+ q_user_queued: "排队 · 「{preview}」",
1788
+ q_cancel: "取消",
1789
+ q_state_speaking: "发言中 · 已读 {n} 轮上下文",
1790
+ q_pending_your_vote: "等待 · 待你投票",
1791
+ q_pending_waits_chair: "等待 · 待主席",
1792
+
1793
+ sidebar_live: "进行中",
1794
+ sidebar_paused: "已暂停",
1795
+ sidebar_section_live: "进行中",
1796
+ sidebar_section_paused: "已暂停",
1797
+ sidebar_section_adjourned: "已归档",
1798
+ sidebar_no_adjourned_title: "暂无已归档会议",
1799
+ sidebar_no_adjourned_deck: "结束一场讨论后,记录会出现在这里。",
1800
+ sidebar_delete_room: "删除会议",
1801
+ sidebar_pin: "置顶",
1802
+ sidebar_unpin: "取消置顶",
1803
+ sidebar_role_director: "董事",
1804
+ sidebar_status_active: "可用",
1805
+ sidebar_chair_badge: "主席",
1806
+ sidebar_chair_badge_title: "主持人 · 系统角色,不可由用户管理",
1807
+ sidebar_chair_role_fallback: "主持人",
1808
+ sidebar_chair_note: "每场会议都在",
1809
+ sidebar_sec_chair: "主席",
1810
+ sidebar_sec_pinned: "已置顶",
1811
+ sidebar_sec_custom: "自定义",
1812
+ sidebar_sec_core: "核心",
1813
+
1814
+ note_saved: "已存入笔记",
1815
+
1816
+ tone_tip_brainstorm:
1817
+ "共同创作者。董事与你并肩,把点子往外推——承接并延伸你的贡献,提出具体的「要是我们换一条路…」变体,或把另一位董事方才的发言拆借成新组合。可以以一句好奇的追问收尾,但不要逼你 defensive。",
1818
+ tone_tip_constructive:
1819
+ "善意的追问者。希望你赢,但只接受最强版本。每一轮只抓一个关键假设,并提出能站得住脚的加强版。可以反对,但每次反对都要附带可行路径。",
1820
+ tone_tip_research:
1821
+ "协作式探究。房间只依据眼前材料(你的 brief、联网检索结果、先前发言)挖掘事实。每一轮必须引用具体出处,并标注 OBSERVATION / INFERENCE / SPECULATION,再抽出你视角下最显著的洞察。若配置了 Brave key,默认开启联网搜索。",
1822
+ tone_tip_debate:
1823
+ "同行评审。每一轮先用最强版本复述你的核心主张(「对你观点最有利的读法是…」),再去攻击这个版本——指出具体风险、要求证据、揭示你回避的取舍。尖锐但专业;跳过「先善意复述」属于流程违规。",
1824
+ tone_tip_critique:
1825
+ "评审委员会。房间系统审计成品——每轮点名审计维度(逻辑/证据/范围/风险等),列出 2–3 条具体问题并标注 BLOCKER · MAJOR · MINOR,指向承重句,并提示修复方向。每轮至少一条 BLOCKER 或 MAJOR。",
1826
+
1827
+ col_resize: "拖动调整宽度",
1828
+ settings_title: "设置",
1829
+
1830
+ us_nav_user: "用户",
1831
+ us_nav_theme: "主题",
1832
+ us_nav_usage: "用量",
1833
+ us_nav_keys: "API 密钥",
1834
+ us_nav_default: "默认模型",
1835
+ us_user_tag: "▸ 用户",
1836
+ us_user_deck: "董事会如何称呼你,以及它需要知道的背景。",
1837
+ us_avatar: "头像",
1838
+ us_regen_avatar: "生成 8-bit 头像",
1839
+ us_name: "姓名",
1840
+ us_about: "关于你",
1841
+ us_intro_ph: "一两句话写下你的角色、常思考的问题、手头项目。董事在每场会议里都会参考。",
1842
+ us_intro_meta: "{n} / 320 字",
1843
+ us_intro_meta_rest: "/ 320 字",
1844
+ us_theme_tag: "▸ 主题",
1845
+ us_theme_deck: "全局配色 · 受 zsh 启发。会立即应用到所有会议室。",
1846
+ us_usage_tag: "▸ 用量",
1847
+ us_usage_deck: "累计 LLM 用量统计 · 自本董事会话启动以来,主席与各位董事的每次调用都会计入。",
1848
+ us_usage_loading: "统计中…",
1849
+ us_usage_empty: "尚无计费调用 · 打开一场会议,让董事发言即可产生记录。",
1850
+ us_usage_agents: "{n} 个智能体",
1851
+ us_usage_silent: "+ {n} 个智能体尚未产生计费",
1852
+ us_keys_group_llm: "大模型服务商",
1853
+ us_keys_add_label: "+ 添加服务商:",
1854
+ us_keys_group_skill: "技能服务",
1855
+ us_keys_skill_deck: "为需要外部服务的系统技能授权。每位董事可在档案中单独开关。",
1856
+ us_ws_backend_tag: "联网搜索后端",
1857
+ us_ws_backend_deck:
1858
+ "已同时配置 Brave Search 与 Tavily。请选择由哪一个为「联网搜索」系统技能提供服务。",
1859
+ us_ws_backend_brave: "Brave Search",
1860
+ us_ws_backend_tavily: "Tavily Search",
1861
+ us_pref_title: "偏好设置",
1862
+ us_modal_kicker_left: "用户 · 设置",
1863
+ us_modal_kicker_right: "// 本地",
1864
+ us_close: "关闭",
1865
+ us_nav_api_key: "API 密钥",
1866
+ us_nav_other_settings: "其他设置",
1867
+ us_locale_label: "界面语言",
1868
+ us_locale_deck: "侧边栏、对话框和应用外壳使用该语言;房间消息与简报仍会以你书写的内容为准。",
1869
+ us_default_model_title: "默认模型",
1870
+ us_default_deck_long:
1871
+ "新创建的董事默认继承此项;若已保存的模型因密钥变更或下线而不可达,也会回退到这里。旗舰档位的深度写作同样使用该模型。",
1872
+ us_keys_tag: "▸ API 密钥",
1873
+ us_keys_deck: "粘贴一次即可 — 密钥仅存于本机,不会上传给我们。密钥只用于驱动董事推理,不含遥测。",
1874
+ us_default_tag: "▸ 默认模型",
1875
+ us_default_deck: "当董事未单独指定模型时的回退项。仅显示当前可达模型。",
1876
+ us_foot_saved: "更改会自动保存",
1877
+ us_foot_website: "官网 ↗",
1878
+ us_done: "[ 完成 ]",
1879
+ us_usage_chair: "主席",
1880
+ us_usage_director: "董事",
1881
+
1882
+ onb_next: "[ 下一步 ▸ ]",
1883
+ onb_skip: "[ 我先自己逛逛 ]",
1884
+ onb_name_ph: "例如:Kay",
1885
+ onb_key_field: "{label} API 密钥",
1886
+ onb_generate_at: "在 {host} 获取 →",
1887
+ onb_show: "显示",
1888
+ onb_hide: "隐藏",
1889
+ },
1890
+ };
1891
+
1892
+ function detectLocale() {
1893
+ const nav = (root.navigator && root.navigator.language) || "";
1894
+ const l = nav.toLowerCase();
1895
+ if (l.startsWith("zh")) return "zh";
1896
+ return "en";
1897
+ }
1898
+
1899
+ function getLocale() {
1900
+ try {
1901
+ const s = root.localStorage.getItem(STORAGE_KEY);
1902
+ if (s === "en" || s === "zh") return s;
1903
+ } catch (_) { /* */ }
1904
+ return detectLocale();
1905
+ }
1906
+
1907
+ function setLocale(loc) {
1908
+ if (loc !== "en" && loc !== "zh") return;
1909
+ try {
1910
+ root.localStorage.setItem(STORAGE_KEY, loc);
1911
+ } catch (_) { /* */ }
1912
+ document.documentElement.lang = loc === "zh" ? "zh-CN" : "en";
1913
+ applyDom(document);
1914
+ syncLocaleControls();
1915
+ document.dispatchEvent(new CustomEvent("boardroom:locale", { detail: { locale: loc } }));
1916
+ }
1917
+
1918
+ function t(key, vars) {
1919
+ const loc = getLocale();
1920
+ let s = (STR[loc] && STR[loc][key]) ?? STR.en[key] ?? key;
1921
+ if (vars && typeof s === "string") {
1922
+ for (const k of Object.keys(vars)) {
1923
+ s = s.split("{" + k + "}").join(String(vars[k]));
1924
+ }
1925
+ }
1926
+ return s;
1927
+ }
1928
+
1929
+ function applyDom(scope) {
1930
+ const el = scope || document;
1931
+ el.querySelectorAll("[data-i18n-html]").forEach((node) => {
1932
+ const k = node.getAttribute("data-i18n-html");
1933
+ if (k) node.innerHTML = t(k);
1934
+ });
1935
+ el.querySelectorAll("[data-i18n]").forEach((node) => {
1936
+ const k = node.getAttribute("data-i18n");
1937
+ if (k) node.textContent = t(k);
1938
+ });
1939
+ el.querySelectorAll("[data-i18n-placeholder]").forEach((node) => {
1940
+ const k = node.getAttribute("data-i18n-placeholder");
1941
+ if (k) node.setAttribute("placeholder", t(k));
1942
+ });
1943
+ el.querySelectorAll("[data-i18n-tip]").forEach((node) => {
1944
+ const k = node.getAttribute("data-i18n-tip");
1945
+ if (k) node.setAttribute("data-tip", t(k));
1946
+ });
1947
+ el.querySelectorAll("[data-i18n-title]").forEach((node) => {
1948
+ const k = node.getAttribute("data-i18n-title");
1949
+ if (k) node.setAttribute("title", t(k));
1950
+ });
1951
+ el.querySelectorAll("[data-i18n-aria]").forEach((node) => {
1952
+ const k = node.getAttribute("data-i18n-aria");
1953
+ if (k) node.setAttribute("aria-label", t(k));
1954
+ });
1955
+ }
1956
+
1957
+ function syncLocaleControls() {
1958
+ const cur = getLocale();
1959
+ document.querySelectorAll("[data-locale]").forEach((btn) => {
1960
+ const loc = btn.getAttribute("data-locale");
1961
+ const on = loc === cur;
1962
+ btn.classList.toggle("active", on);
1963
+ btn.setAttribute("aria-pressed", on ? "true" : "false");
1964
+ });
1965
+ }
1966
+
1967
+ function onLocaleClick(e) {
1968
+ const btn = e.target && e.target.closest && e.target.closest("[data-locale]");
1969
+ if (!btn) return;
1970
+ e.preventDefault();
1971
+ const loc = btn.getAttribute("data-locale");
1972
+ if (loc === "en" || loc === "zh") setLocale(loc);
1973
+ }
1974
+
1975
+ function init() {
1976
+ const loc = getLocale();
1977
+ document.documentElement.lang = loc === "zh" ? "zh-CN" : "en";
1978
+ document.addEventListener("click", onLocaleClick);
1979
+ applyDom(document);
1980
+ syncLocaleControls();
1981
+ }
1982
+
1983
+ if (document.readyState === "loading") {
1984
+ document.addEventListener("DOMContentLoaded", init);
1985
+ } else {
1986
+ init();
1987
+ }
1988
+
1989
+ root.I18n = { t, getLocale, setLocale, applyDom, init, syncLocaleControls, STR };
1990
+ })(typeof window !== "undefined" ? window : globalThis);