@foxden-app/foxclaw 0.2.6 → 0.3.0

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.
@@ -893,6 +893,11 @@ export class BridgeSessionCore {
893
893
  await this.handleThreadNewCallback(event, locale);
894
894
  return;
895
895
  }
896
+ const threadNewMatch = /^thread:new:(.+)$/.exec(event.data);
897
+ if (threadNewMatch) {
898
+ await this.handleThreadNewFromThreadCallback(event, threadNewMatch[1], locale);
899
+ return;
900
+ }
896
901
  const newCwdMatch = /^thread:newcwd:(create|cancel)$/.exec(event.data);
897
902
  if (newCwdMatch) {
898
903
  await this.handleThreadNewCwdCallback(event, newCwdMatch[1], locale);
@@ -4683,6 +4688,18 @@ export class BridgeSessionCore {
4683
4688
  await this.messaging.answerCallback(event.callbackQueryId, t(locale, 'thread_new_prompt_short'));
4684
4689
  await this.sendMessage(event.scopeId, t(locale, 'thread_new_prompt', { cwd: this.config.defaultCwd }));
4685
4690
  }
4691
+ async handleThreadNewFromThreadCallback(event, threadId, locale) {
4692
+ const scopeId = event.scopeId;
4693
+ const cached = this.store.listCachedThreads(scopeId).find(thread => thread.threadId === threadId);
4694
+ if (!cached) {
4695
+ await this.messaging.answerCallback(event.callbackQueryId, t(locale, 'cached_thread_unavailable'));
4696
+ return;
4697
+ }
4698
+ this.pendingThreadRenames.delete(scopeId);
4699
+ this.pendingThreadNewCwds.delete(scopeId);
4700
+ await this.messaging.answerCallback(event.callbackQueryId, t(locale, 'thread_new_started_short'));
4701
+ await this.startNewThreadForRequestedCwd(scopeId, locale, cached.cwd || this.config.defaultCwd, event.messageId);
4702
+ }
4686
4703
  async handleThreadNewCwdCallback(event, action, locale) {
4687
4704
  const pending = this.pendingThreadNewCwds.get(event.scopeId);
4688
4705
  if (!pending || !pending.cwdToCreate) {
@@ -6980,11 +6997,11 @@ function renderAuthListMessage(locale, state, includeWeixinCopyPaste = false) {
6980
6997
  function authChoiceKeyboard(locale, record) {
6981
6998
  const rows = record.candidates.map((candidate, index) => [
6982
6999
  {
6983
- text: clipButtonText(`${candidate.isCurrent ? '* ' : ''}${candidate.name}${candidate.disabled ? ' off' : ''}`),
7000
+ text: clipButtonText(`${candidate.isCurrent ? ' ' : '🔐 '}${candidate.name}${candidate.disabled ? ' · off' : ''}`),
6984
7001
  callback_data: `auth:${record.localId}:${index}`,
6985
7002
  },
6986
7003
  {
6987
- text: t(locale, candidate.disabled ? 'button_auth_enable' : 'button_auth_disable'),
7004
+ text: t(locale, candidate.disabled ? 'button_auth_disable' : 'button_auth_enable'),
6988
7005
  callback_data: `auth:${record.localId}:toggle:${index}`,
6989
7006
  },
6990
7007
  ]);
@@ -38,7 +38,7 @@ export function buildThreadsKeyboard(locale, threads) {
38
38
  return threads.flatMap((thread, index) => {
39
39
  const ordinal = typeof thread.index === 'number' ? thread.index : index + 1;
40
40
  const openRow = [{
41
- text: `${ordinal}. ${truncate(compactWhitespace(thread.name || thread.preview || t(locale, 'empty')), 28)}`,
41
+ text: `🧵 ${ordinal}. ${truncate(compactWhitespace(thread.name || thread.preview || t(locale, 'empty')), 28)}`,
42
42
  callback_data: `thread:open:${thread.threadId}`,
43
43
  }];
44
44
  const actionRow = thread.archived
@@ -47,6 +47,7 @@ export function buildThreadsKeyboard(locale, threads) {
47
47
  { text: t(locale, 'button_thread_rename'), callback_data: `thread:rename:${thread.threadId}` },
48
48
  { text: t(locale, 'button_thread_watch'), callback_data: `thread:watch:${thread.threadId}` },
49
49
  { text: t(locale, 'button_thread_archive'), callback_data: `thread:archive:${thread.threadId}` },
50
+ { text: t(locale, 'button_thread_new'), callback_data: `thread:new:${thread.threadId}` },
50
51
  ];
51
52
  return [openRow, actionRow];
52
53
  });
@@ -110,15 +111,15 @@ export function buildAccessSettingsKeyboard(locale, access) {
110
111
  const currentPreset = access.preset;
111
112
  const buttons = [
112
113
  {
113
- text: `${currentPreset === 'read-only' ? '• ' : ''}${t(locale, 'access_preset_read_only')}`,
114
+ text: selectedButtonText(currentPreset === 'read-only', accessPresetButtonLabel(locale, 'read-only')),
114
115
  callback_data: 'settings:access:read-only',
115
116
  },
116
117
  {
117
- text: `${currentPreset === 'default' ? '• ' : ''}${t(locale, 'access_preset_default')}`,
118
+ text: selectedButtonText(currentPreset === 'default', accessPresetButtonLabel(locale, 'default')),
118
119
  callback_data: 'settings:access:default',
119
120
  },
120
121
  {
121
- text: `${currentPreset === 'full-access' ? '• ' : ''}${t(locale, 'access_preset_full_access')}`,
122
+ text: selectedButtonText(currentPreset === 'full-access', accessPresetButtonLabel(locale, 'full-access')),
122
123
  callback_data: 'settings:access:full-access',
123
124
  },
124
125
  ];
@@ -250,23 +251,24 @@ export function buildSetupPanelKeyboard(locale, ctx) {
250
251
  const currentMode = resolveCollaborationMode(ctx.settings?.collaborationMode ?? null);
251
252
  const activeTurnMessageMode = resolveActiveTurnMessageMode(ctx.settings?.activeTurnMessageMode ?? null);
252
253
  const rows = [];
254
+ const autoLabel = setupAutoButtonLabel(locale);
253
255
  rows.push(...chunkButtons([
254
256
  {
255
- text: currentModel === null ? `• ${t(locale, 'button_auto')}` : t(locale, 'button_auto'),
257
+ text: currentModel === null ? `• ${autoLabel}` : autoLabel,
256
258
  callback_data: 'setup:model:default',
257
259
  },
258
260
  ...ctx.models.map((model) => ({
259
- text: `${currentModel === model.model ? '• ' : ''}${truncate(model.model, 14)}`,
261
+ text: selectedButtonText(currentModel === model.model, truncate(model.model, 14)),
260
262
  callback_data: `setup:model:${encodeURIComponent(model.model)}`,
261
263
  })),
262
264
  ], 2));
263
265
  rows.push(...chunkButtons([
264
266
  {
265
- text: (ctx.settings?.reasoningEffort ?? null) === null ? `• ${t(locale, 'button_auto')}` : t(locale, 'button_auto'),
267
+ text: (ctx.settings?.reasoningEffort ?? null) === null ? `• ${autoLabel}` : autoLabel,
266
268
  callback_data: 'setup:effort:default',
267
269
  },
268
270
  ...efforts.map((effort) => ({
269
- text: `${ctx.settings?.reasoningEffort === effort ? '• ' : ''}${effort}`,
271
+ text: selectedButtonText(ctx.settings?.reasoningEffort === effort, effort),
270
272
  callback_data: `setup:effort:${effort}`,
271
273
  })),
272
274
  ], 3));
@@ -287,35 +289,35 @@ export function buildSetupPanelKeyboard(locale, ctx) {
287
289
  }
288
290
  rows.push([
289
291
  {
290
- text: `${ctx.access.preset === 'read-only' ? '• ' : ''}${t(locale, 'access_preset_read_only')}`,
292
+ text: selectedButtonText(ctx.access.preset === 'read-only', accessPresetButtonLabel(locale, 'read-only')),
291
293
  callback_data: 'setup:access:read-only',
292
294
  },
293
295
  {
294
- text: `${ctx.access.preset === 'default' ? '• ' : ''}${t(locale, 'access_preset_default')}`,
296
+ text: selectedButtonText(ctx.access.preset === 'default', accessPresetButtonLabel(locale, 'default')),
295
297
  callback_data: 'setup:access:default',
296
298
  },
297
299
  {
298
- text: `${ctx.access.preset === 'full-access' ? '• ' : ''}${t(locale, 'access_preset_full_access')}`,
300
+ text: selectedButtonText(ctx.access.preset === 'full-access', accessPresetButtonLabel(locale, 'full-access')),
299
301
  callback_data: 'setup:access:full-access',
300
302
  },
301
303
  ]);
302
304
  rows.push([
303
305
  {
304
- text: `${currentMode === 'default' ? '• ' : ''}${t(locale, 'collaboration_mode_default')}`,
306
+ text: selectedButtonText(currentMode === 'default', t(locale, 'collaboration_mode_default')),
305
307
  callback_data: 'setup:mode:default',
306
308
  },
307
309
  {
308
- text: `${currentMode === 'plan' ? '• ' : ''}${t(locale, 'collaboration_mode_plan')}`,
310
+ text: selectedButtonText(currentMode === 'plan', `📝 ${t(locale, 'collaboration_mode_plan')}`),
309
311
  callback_data: 'setup:mode:plan',
310
312
  },
311
313
  ]);
312
314
  rows.push([
313
315
  {
314
- text: `${activeTurnMessageMode === 'steer' ? '• ' : ''}${t(locale, 'active_turn_message_mode_steer')}`,
316
+ text: selectedButtonText(activeTurnMessageMode === 'steer', t(locale, 'active_turn_message_mode_steer')),
315
317
  callback_data: 'setup:active:steer',
316
318
  },
317
319
  {
318
- text: `${activeTurnMessageMode === 'queue' ? '• ' : ''}${t(locale, 'active_turn_message_mode_queue')}`,
320
+ text: selectedButtonText(activeTurnMessageMode === 'queue', t(locale, 'active_turn_message_mode_queue')),
319
321
  callback_data: 'setup:active:queue',
320
322
  },
321
323
  ]);
@@ -382,6 +384,19 @@ function formatFastSetupLabel(locale, supported, enabled, tierName) {
382
384
  function resolveCollaborationMode(mode) {
383
385
  return mode === 'plan' ? 'plan' : 'default';
384
386
  }
387
+ function selectedButtonText(selected, label) {
388
+ return `${selected ? '• ' : ''}${label}`;
389
+ }
390
+ function accessPresetButtonLabel(locale, preset) {
391
+ if (preset === 'read-only')
392
+ return `👁️ ${formatAccessPresetLabel(locale, preset)}`;
393
+ if (preset === 'full-access')
394
+ return `🔓 ${formatAccessPresetLabel(locale, preset)}`;
395
+ return `🛡️ ${formatAccessPresetLabel(locale, preset)}`;
396
+ }
397
+ function setupAutoButtonLabel(locale) {
398
+ return locale === 'zh' ? '自动' : 'Auto';
399
+ }
385
400
  export function formatModelSettingsMessage(locale, models, settings) {
386
401
  const selectedModel = resolveCurrentModel(models, settings?.model ?? null);
387
402
  const selectedModelLabel = settings?.model ?? t(locale, 'server_default');
@@ -417,7 +432,7 @@ export function buildModelSettingsKeyboard(locale, models, settings) {
417
432
  callback_data: 'settings:model:default',
418
433
  },
419
434
  ...models.map((model) => ({
420
- text: `${currentModel === model.model ? '• ' : ''}${truncate(model.model, 14)}`,
435
+ text: selectedButtonText(currentModel === model.model, `🤖 ${truncate(model.model, 14)}`),
421
436
  callback_data: `settings:model:${encodeURIComponent(model.model)}`,
422
437
  })),
423
438
  ];
@@ -427,7 +442,7 @@ export function buildModelSettingsKeyboard(locale, models, settings) {
427
442
  callback_data: 'settings:effort:default',
428
443
  },
429
444
  ...efforts.map((effort) => ({
430
- text: `${settings?.reasoningEffort === effort ? '• ' : ''}${effort}`,
445
+ text: selectedButtonText(settings?.reasoningEffort === effort, `🧠 ${effort}`),
431
446
  callback_data: `settings:effort:${effort}`,
432
447
  })),
433
448
  ];
package/dist/i18n.d.ts CHANGED
@@ -148,10 +148,10 @@ declare const MESSAGES: {
148
148
  readonly auth_add_cancelled: "New auth login cancelled. Restored previous auth.";
149
149
  readonly auth_add_reverted: "Restored previous auth.";
150
150
  readonly auth_add_missing_file: "Login completed, but the new auth file was not created: {value}";
151
- readonly button_login_device: "Login device";
152
- readonly button_auth_reload: "Reload auth";
153
- readonly button_auth_enable: "Enable";
154
- readonly button_auth_disable: "Disable";
151
+ readonly button_login_device: "🔑 Login";
152
+ readonly button_auth_reload: "🔄 Reload auth";
153
+ readonly button_auth_enable: "";
154
+ readonly button_auth_disable: "⏸️";
155
155
  readonly another_turn_running: "Another turn is already running. Use /interrupt, /takeover, /queue, or wait.";
156
156
  readonly working: "Working...";
157
157
  readonly usage_open: "Usage: /open <n>";
@@ -175,6 +175,7 @@ declare const MESSAGES: {
175
175
  readonly codex_sync_failed: "Codex.app sync failed: {error}";
176
176
  readonly opened_in_codex: "Opened in Codex.app.";
177
177
  readonly started_new_thread: "Started new thread {threadId}";
178
+ readonly thread_new_started_short: "Starting new thread";
178
179
  readonly thread_new_prompt_short: "Send PWD";
179
180
  readonly thread_new_prompt: "Send the PWD for the new thread. Send \".\" to use the default:\n{cwd}";
180
181
  readonly thread_new_cwd_missing: "PWD does not exist:\n{cwd}\nCreate it and start the new thread there?";
@@ -295,16 +296,17 @@ declare const MESSAGES: {
295
296
  readonly approval_decision_accept: "allow";
296
297
  readonly approval_decision_session: "allow for session";
297
298
  readonly approval_decision_deny: "deny";
298
- readonly button_allow: "Allow";
299
- readonly button_allow_session: "Allow Session";
300
- readonly button_deny: "Deny";
301
- readonly button_interrupt: "Interrupt";
302
- readonly button_permissions: "Access";
303
- readonly button_models: "Models";
304
- readonly button_threads: "Threads";
305
- readonly button_reveal: "Reveal";
306
- readonly button_auto: "Auto";
307
- readonly button_new_thread: "New";
299
+ readonly button_allow: "Allow";
300
+ readonly button_allow_session: " Session";
301
+ readonly button_deny: "🚫 Deny";
302
+ readonly button_interrupt: "⏹️ Interrupt";
303
+ readonly button_permissions: "🛡️ Access";
304
+ readonly button_models: "🤖 Models";
305
+ readonly button_threads: "🧵 Threads";
306
+ readonly button_reveal: "↗️ Reveal";
307
+ readonly button_auto: "⚙️ Auto";
308
+ readonly button_new_thread: "New";
309
+ readonly button_thread_new: "➕";
308
310
  readonly threads_no_matches: "<b>No threads matched</b>\n<code>{searchTerm}</code>";
309
311
  readonly threads_no_recent: "<b>No recent threads.</b>";
310
312
  readonly threads_recent_title: "<b>Recent threads</b>";
@@ -313,15 +315,15 @@ declare const MESSAGES: {
313
315
  readonly threads_filter: "Filter: <code>{searchTerm}</code>";
314
316
  readonly threads_range: "Showing {start}-{end}";
315
317
  readonly threads_filter_cleared_short: "Filter cleared";
316
- readonly button_prev_page: "Prev";
317
- readonly button_next_page: "Next";
318
- readonly button_clear_filter: "Clear filter";
319
- readonly button_recent_threads: "Recent";
320
- readonly button_archived_threads: "Archived";
321
- readonly button_thread_rename: "Rename";
322
- readonly button_thread_watch: "Watch";
323
- readonly button_thread_archive: "Archive/Delete";
324
- readonly button_thread_unarchive: "Unarchive";
318
+ readonly button_prev_page: "⬅️ Prev";
319
+ readonly button_next_page: "➡️ Next";
320
+ readonly button_clear_filter: "🧹 Clear";
321
+ readonly button_recent_threads: "🕘 Recent";
322
+ readonly button_archived_threads: "🗄️ Archived";
323
+ readonly button_thread_rename: "✏️";
324
+ readonly button_thread_watch: "👀";
325
+ readonly button_thread_archive: "🗑️";
326
+ readonly button_thread_unarchive: "♻️ Unarchive";
325
327
  readonly threads_current: "Current: <b>{title}</b>";
326
328
  readonly where_no_thread_bound: "No thread is currently bound.";
327
329
  readonly where_send_message_or_new: "Send a message or use /new.";
@@ -506,10 +508,10 @@ declare const MESSAGES: {
506
508
  readonly permission_read_paths: "Read paths: {value}";
507
509
  readonly permission_write_paths: "Write paths: {value}";
508
510
  readonly permission_entries: "File entries: {value}";
509
- readonly button_accept: "Accept";
510
- readonly button_decline: "Decline";
511
- readonly button_cancel: "Cancel";
512
- readonly button_create_dir: "Create";
511
+ readonly button_accept: "Accept";
512
+ readonly button_decline: "🚫 Decline";
513
+ readonly button_cancel: "✖️ Cancel";
514
+ readonly button_create_dir: "📁 Create";
513
515
  readonly thread_name_updated: "Thread renamed: {name}";
514
516
  readonly thread_archived_notification: "Thread archived: {threadId}";
515
517
  readonly thread_unarchived_notification: "Thread unarchived: {threadId}";
@@ -696,10 +698,10 @@ declare const MESSAGES: {
696
698
  readonly auth_add_cancelled: "新 auth 登录已取消,已恢复之前的 auth。";
697
699
  readonly auth_add_reverted: "已恢复之前的 auth。";
698
700
  readonly auth_add_missing_file: "登录已完成,但没有创建新的 auth 文件:{value}";
699
- readonly button_login_device: "设备登录";
700
- readonly button_auth_reload: "重载 auth";
701
- readonly button_auth_enable: "启用";
702
- readonly button_auth_disable: "禁用";
701
+ readonly button_login_device: "🔑 设备登录";
702
+ readonly button_auth_reload: "🔄 重载 auth";
703
+ readonly button_auth_enable: "";
704
+ readonly button_auth_disable: "⏸️";
703
705
  readonly another_turn_running: "已经有一个回复在进行中。请先等待,或使用 /interrupt、/takeover、/queue。";
704
706
  readonly working: "处理中...";
705
707
  readonly usage_open: "用法:/open <编号>";
@@ -723,6 +725,7 @@ declare const MESSAGES: {
723
725
  readonly codex_sync_failed: "同步到 Codex.app 失败:{error}";
724
726
  readonly opened_in_codex: "已在 Codex.app 中打开。";
725
727
  readonly started_new_thread: "已新建线程 {threadId}";
728
+ readonly thread_new_started_short: "正在新建线程";
726
729
  readonly thread_new_prompt_short: "发送 PWD";
727
730
  readonly thread_new_prompt: "请发送新线程的 PWD。发送 \".\" 使用默认目录:\n{cwd}";
728
731
  readonly thread_new_cwd_missing: "PWD 不存在:\n{cwd}\n是否新建这个目录,并在其中启动新线程?";
@@ -843,16 +846,17 @@ declare const MESSAGES: {
843
846
  readonly approval_decision_accept: "允许";
844
847
  readonly approval_decision_session: "本会话内允许";
845
848
  readonly approval_decision_deny: "拒绝";
846
- readonly button_allow: "允许";
847
- readonly button_allow_session: "本会话允许";
848
- readonly button_deny: "拒绝";
849
- readonly button_interrupt: "中断";
850
- readonly button_permissions: "权限";
851
- readonly button_models: "模型";
852
- readonly button_threads: "线程";
853
- readonly button_reveal: "打开";
854
- readonly button_auto: "自动";
855
- readonly button_new_thread: "新建";
849
+ readonly button_allow: "允许";
850
+ readonly button_allow_session: "✅ 本会话";
851
+ readonly button_deny: "🚫 拒绝";
852
+ readonly button_interrupt: "⏹️ 中断";
853
+ readonly button_permissions: "🛡️ 权限";
854
+ readonly button_models: "🤖 模型";
855
+ readonly button_threads: "🧵 线程";
856
+ readonly button_reveal: "↗️ 打开";
857
+ readonly button_auto: "⚙️ 自动";
858
+ readonly button_new_thread: "新建";
859
+ readonly button_thread_new: "➕";
856
860
  readonly threads_no_matches: "<b>没有匹配的线程</b>\n<code>{searchTerm}</code>";
857
861
  readonly threads_no_recent: "<b>暂无最近线程。</b>";
858
862
  readonly threads_recent_title: "<b>最近线程</b>";
@@ -861,15 +865,15 @@ declare const MESSAGES: {
861
865
  readonly threads_filter: "筛选:<code>{searchTerm}</code>";
862
866
  readonly threads_range: "显示第 {start}-{end} 条";
863
867
  readonly threads_filter_cleared_short: "已清除筛选";
864
- readonly button_prev_page: "上一页";
865
- readonly button_next_page: "下一页";
866
- readonly button_clear_filter: "清除筛选";
867
- readonly button_recent_threads: "最近线程";
868
- readonly button_archived_threads: "已归档";
869
- readonly button_thread_rename: "重命名";
870
- readonly button_thread_watch: "观察";
871
- readonly button_thread_archive: "归档/删除";
872
- readonly button_thread_unarchive: "取消归档";
868
+ readonly button_prev_page: "⬅️ 上一页";
869
+ readonly button_next_page: "➡️ 下一页";
870
+ readonly button_clear_filter: "🧹 清除";
871
+ readonly button_recent_threads: "🕘 最近线程";
872
+ readonly button_archived_threads: "🗄️ 已归档";
873
+ readonly button_thread_rename: "✏️";
874
+ readonly button_thread_watch: "👀";
875
+ readonly button_thread_archive: "🗑️";
876
+ readonly button_thread_unarchive: "♻️ 取消归档";
873
877
  readonly threads_current: "当前:<b>{title}</b>";
874
878
  readonly where_no_thread_bound: "当前没有绑定线程。";
875
879
  readonly where_send_message_or_new: "直接发一条消息,或者使用 /new。";
@@ -1054,10 +1058,10 @@ declare const MESSAGES: {
1054
1058
  readonly permission_read_paths: "可读路径:{value}";
1055
1059
  readonly permission_write_paths: "可写路径:{value}";
1056
1060
  readonly permission_entries: "文件条目:{value}";
1057
- readonly button_accept: "接受";
1058
- readonly button_decline: "拒绝";
1059
- readonly button_cancel: "取消";
1060
- readonly button_create_dir: "新建";
1061
+ readonly button_accept: "接受";
1062
+ readonly button_decline: "🚫 拒绝";
1063
+ readonly button_cancel: "✖️ 取消";
1064
+ readonly button_create_dir: "📁 新建";
1061
1065
  readonly thread_name_updated: "线程已重命名:{name}";
1062
1066
  readonly thread_archived_notification: "线程已归档:{threadId}";
1063
1067
  readonly thread_unarchived_notification: "线程已取消归档:{threadId}";
package/dist/i18n.js CHANGED
@@ -146,10 +146,10 @@ const MESSAGES = {
146
146
  auth_add_cancelled: 'New auth login cancelled. Restored previous auth.',
147
147
  auth_add_reverted: 'Restored previous auth.',
148
148
  auth_add_missing_file: 'Login completed, but the new auth file was not created: {value}',
149
- button_login_device: 'Login device',
150
- button_auth_reload: 'Reload auth',
151
- button_auth_enable: 'Enable',
152
- button_auth_disable: 'Disable',
149
+ button_login_device: '🔑 Login',
150
+ button_auth_reload: '🔄 Reload auth',
151
+ button_auth_enable: '',
152
+ button_auth_disable: '⏸️',
153
153
  another_turn_running: 'Another turn is already running. Use /interrupt, /takeover, /queue, or wait.',
154
154
  working: 'Working...',
155
155
  usage_open: 'Usage: /open <n>',
@@ -173,6 +173,7 @@ const MESSAGES = {
173
173
  codex_sync_failed: 'Codex.app sync failed: {error}',
174
174
  opened_in_codex: 'Opened in Codex.app.',
175
175
  started_new_thread: 'Started new thread {threadId}',
176
+ thread_new_started_short: 'Starting new thread',
176
177
  thread_new_prompt_short: 'Send PWD',
177
178
  thread_new_prompt: 'Send the PWD for the new thread. Send "." to use the default:\n{cwd}',
178
179
  thread_new_cwd_missing: 'PWD does not exist:\n{cwd}\nCreate it and start the new thread there?',
@@ -293,16 +294,17 @@ const MESSAGES = {
293
294
  approval_decision_accept: 'allow',
294
295
  approval_decision_session: 'allow for session',
295
296
  approval_decision_deny: 'deny',
296
- button_allow: 'Allow',
297
- button_allow_session: 'Allow Session',
298
- button_deny: 'Deny',
299
- button_interrupt: 'Interrupt',
300
- button_permissions: 'Access',
301
- button_models: 'Models',
302
- button_threads: 'Threads',
303
- button_reveal: 'Reveal',
304
- button_auto: 'Auto',
305
- button_new_thread: 'New',
297
+ button_allow: 'Allow',
298
+ button_allow_session: ' Session',
299
+ button_deny: '🚫 Deny',
300
+ button_interrupt: '⏹️ Interrupt',
301
+ button_permissions: '🛡️ Access',
302
+ button_models: '🤖 Models',
303
+ button_threads: '🧵 Threads',
304
+ button_reveal: '↗️ Reveal',
305
+ button_auto: '⚙️ Auto',
306
+ button_new_thread: 'New',
307
+ button_thread_new: '➕',
306
308
  threads_no_matches: '<b>No threads matched</b>\n<code>{searchTerm}</code>',
307
309
  threads_no_recent: '<b>No recent threads.</b>',
308
310
  threads_recent_title: '<b>Recent threads</b>',
@@ -311,15 +313,15 @@ const MESSAGES = {
311
313
  threads_filter: 'Filter: <code>{searchTerm}</code>',
312
314
  threads_range: 'Showing {start}-{end}',
313
315
  threads_filter_cleared_short: 'Filter cleared',
314
- button_prev_page: 'Prev',
315
- button_next_page: 'Next',
316
- button_clear_filter: 'Clear filter',
317
- button_recent_threads: 'Recent',
318
- button_archived_threads: 'Archived',
319
- button_thread_rename: 'Rename',
320
- button_thread_watch: 'Watch',
321
- button_thread_archive: 'Archive/Delete',
322
- button_thread_unarchive: 'Unarchive',
316
+ button_prev_page: '⬅️ Prev',
317
+ button_next_page: '➡️ Next',
318
+ button_clear_filter: '🧹 Clear',
319
+ button_recent_threads: '🕘 Recent',
320
+ button_archived_threads: '🗄️ Archived',
321
+ button_thread_rename: '✏️',
322
+ button_thread_watch: '👀',
323
+ button_thread_archive: '🗑️',
324
+ button_thread_unarchive: '♻️ Unarchive',
323
325
  threads_current: 'Current: <b>{title}</b>',
324
326
  where_no_thread_bound: 'No thread is currently bound.',
325
327
  where_send_message_or_new: 'Send a message or use /new.',
@@ -504,10 +506,10 @@ const MESSAGES = {
504
506
  permission_read_paths: 'Read paths: {value}',
505
507
  permission_write_paths: 'Write paths: {value}',
506
508
  permission_entries: 'File entries: {value}',
507
- button_accept: 'Accept',
508
- button_decline: 'Decline',
509
- button_cancel: 'Cancel',
510
- button_create_dir: 'Create',
509
+ button_accept: 'Accept',
510
+ button_decline: '🚫 Decline',
511
+ button_cancel: '✖️ Cancel',
512
+ button_create_dir: '📁 Create',
511
513
  thread_name_updated: 'Thread renamed: {name}',
512
514
  thread_archived_notification: 'Thread archived: {threadId}',
513
515
  thread_unarchived_notification: 'Thread unarchived: {threadId}',
@@ -694,10 +696,10 @@ const MESSAGES = {
694
696
  auth_add_cancelled: '新 auth 登录已取消,已恢复之前的 auth。',
695
697
  auth_add_reverted: '已恢复之前的 auth。',
696
698
  auth_add_missing_file: '登录已完成,但没有创建新的 auth 文件:{value}',
697
- button_login_device: '设备登录',
698
- button_auth_reload: '重载 auth',
699
- button_auth_enable: '启用',
700
- button_auth_disable: '禁用',
699
+ button_login_device: '🔑 设备登录',
700
+ button_auth_reload: '🔄 重载 auth',
701
+ button_auth_enable: '',
702
+ button_auth_disable: '⏸️',
701
703
  another_turn_running: '已经有一个回复在进行中。请先等待,或使用 /interrupt、/takeover、/queue。',
702
704
  working: '处理中...',
703
705
  usage_open: '用法:/open <编号>',
@@ -721,6 +723,7 @@ const MESSAGES = {
721
723
  codex_sync_failed: '同步到 Codex.app 失败:{error}',
722
724
  opened_in_codex: '已在 Codex.app 中打开。',
723
725
  started_new_thread: '已新建线程 {threadId}',
726
+ thread_new_started_short: '正在新建线程',
724
727
  thread_new_prompt_short: '发送 PWD',
725
728
  thread_new_prompt: '请发送新线程的 PWD。发送 "." 使用默认目录:\n{cwd}',
726
729
  thread_new_cwd_missing: 'PWD 不存在:\n{cwd}\n是否新建这个目录,并在其中启动新线程?',
@@ -841,16 +844,17 @@ const MESSAGES = {
841
844
  approval_decision_accept: '允许',
842
845
  approval_decision_session: '本会话内允许',
843
846
  approval_decision_deny: '拒绝',
844
- button_allow: '允许',
845
- button_allow_session: '本会话允许',
846
- button_deny: '拒绝',
847
- button_interrupt: '中断',
848
- button_permissions: '权限',
849
- button_models: '模型',
850
- button_threads: '线程',
851
- button_reveal: '打开',
852
- button_auto: '自动',
853
- button_new_thread: '新建',
847
+ button_allow: '允许',
848
+ button_allow_session: '✅ 本会话',
849
+ button_deny: '🚫 拒绝',
850
+ button_interrupt: '⏹️ 中断',
851
+ button_permissions: '🛡️ 权限',
852
+ button_models: '🤖 模型',
853
+ button_threads: '🧵 线程',
854
+ button_reveal: '↗️ 打开',
855
+ button_auto: '⚙️ 自动',
856
+ button_new_thread: '新建',
857
+ button_thread_new: '➕',
854
858
  threads_no_matches: '<b>没有匹配的线程</b>\n<code>{searchTerm}</code>',
855
859
  threads_no_recent: '<b>暂无最近线程。</b>',
856
860
  threads_recent_title: '<b>最近线程</b>',
@@ -859,15 +863,15 @@ const MESSAGES = {
859
863
  threads_filter: '筛选:<code>{searchTerm}</code>',
860
864
  threads_range: '显示第 {start}-{end} 条',
861
865
  threads_filter_cleared_short: '已清除筛选',
862
- button_prev_page: '上一页',
863
- button_next_page: '下一页',
864
- button_clear_filter: '清除筛选',
865
- button_recent_threads: '最近线程',
866
- button_archived_threads: '已归档',
867
- button_thread_rename: '重命名',
868
- button_thread_watch: '观察',
869
- button_thread_archive: '归档/删除',
870
- button_thread_unarchive: '取消归档',
866
+ button_prev_page: '⬅️ 上一页',
867
+ button_next_page: '➡️ 下一页',
868
+ button_clear_filter: '🧹 清除',
869
+ button_recent_threads: '🕘 最近线程',
870
+ button_archived_threads: '🗄️ 已归档',
871
+ button_thread_rename: '✏️',
872
+ button_thread_watch: '👀',
873
+ button_thread_archive: '🗑️',
874
+ button_thread_unarchive: '♻️ 取消归档',
871
875
  threads_current: '当前:<b>{title}</b>',
872
876
  where_no_thread_bound: '当前没有绑定线程。',
873
877
  where_send_message_or_new: '直接发一条消息,或者使用 /new。',
@@ -1052,10 +1056,10 @@ const MESSAGES = {
1052
1056
  permission_read_paths: '可读路径:{value}',
1053
1057
  permission_write_paths: '可写路径:{value}',
1054
1058
  permission_entries: '文件条目:{value}',
1055
- button_accept: '接受',
1056
- button_decline: '拒绝',
1057
- button_cancel: '取消',
1058
- button_create_dir: '新建',
1059
+ button_accept: '接受',
1060
+ button_decline: '🚫 拒绝',
1061
+ button_cancel: '✖️ 取消',
1062
+ button_create_dir: '📁 新建',
1059
1063
  thread_name_updated: '线程已重命名:{name}',
1060
1064
  thread_archived_notification: '线程已归档:{threadId}',
1061
1065
  thread_unarchived_notification: '线程已取消归档:{threadId}',