codexmate 0.1.27 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +53 -44
  2. package/README.vi.md +45 -36
  3. package/README.zh.md +51 -42
  4. package/cli/config-bootstrap.js +2 -9
  5. package/cli/session-usage.js +2 -2
  6. package/cli.js +407 -40
  7. package/package.json +1 -1
  8. package/web-ui/app.js +7 -0
  9. package/web-ui/index.html +12 -0
  10. package/web-ui/logic.sessions.mjs +6 -4
  11. package/web-ui/modules/app.computed.session.mjs +52 -33
  12. package/web-ui/modules/app.methods.agents.mjs +36 -0
  13. package/web-ui/modules/app.methods.codex-config.mjs +3 -1
  14. package/web-ui/modules/app.methods.index.mjs +2 -0
  15. package/web-ui/modules/app.methods.providers.mjs +12 -4
  16. package/web-ui/modules/app.methods.session-actions.mjs +10 -8
  17. package/web-ui/modules/app.methods.session-browser.mjs +3 -1
  18. package/web-ui/modules/app.methods.session-trash.mjs +16 -16
  19. package/web-ui/modules/app.methods.theme.mjs +39 -0
  20. package/web-ui/modules/app.methods.web-ui-preferences.mjs +9 -0
  21. package/web-ui/modules/i18n/locales/en.mjs +80 -2
  22. package/web-ui/modules/i18n/locales/ja.mjs +80 -2
  23. package/web-ui/modules/i18n/locales/vi.mjs +80 -2
  24. package/web-ui/modules/i18n/locales/zh-tw.mjs +80 -2
  25. package/web-ui/modules/i18n/locales/zh.mjs +80 -2
  26. package/web-ui/modules/i18n.mjs +7 -0
  27. package/web-ui/partials/index/modal-config-template-agents.html +1 -1
  28. package/web-ui/partials/index/modal-health-check.html +1 -1
  29. package/web-ui/partials/index/modal-openclaw-config.html +50 -50
  30. package/web-ui/partials/index/panel-dashboard.html +1 -1
  31. package/web-ui/partials/index/panel-prompts.html +2 -2
  32. package/web-ui/partials/index/panel-sessions.html +47 -30
  33. package/web-ui/partials/index/panel-settings.html +30 -0
  34. package/web-ui/res/web-ui-render.precompiled.js +244 -157
  35. package/web-ui/session-helpers.mjs +3 -0
  36. package/web-ui/styles/base-theme.css +3 -2
  37. package/web-ui/styles/bridge-pool.css +1 -1
  38. package/web-ui/styles/controls-forms.css +1 -1
  39. package/web-ui/styles/layout-shell.css +0 -1
  40. package/web-ui/styles/sessions-preview.css +77 -0
  41. package/web-ui/styles/sessions-toolbar-trash.css +1 -1
  42. package/web-ui/styles/sessions-usage.css +1 -1
  43. package/web-ui/styles/settings-panel.css +2 -2
  44. package/web-ui/styles/theme-dark-tokens.css +83 -0
  45. package/web-ui/styles/theme-dark.css +1355 -0
  46. package/web-ui/styles/theme-ocean-tokens.css +88 -0
  47. package/web-ui/styles/theme-ocean.css +920 -0
  48. package/web-ui/styles.css +2 -0
@@ -520,6 +520,11 @@ const en = Object.freeze({
520
520
  'toast.provider.updateFail': 'Failed to update',
521
521
  'toast.provider.resetSuccess': 'Config reset{backup}',
522
522
  'toast.provider.resetFail': 'Reset failed',
523
+
524
+ 'toast.provider.resetBackup': ' (backup: {file})',
525
+ 'toast.provider.modelRequired': 'Please enter model',
526
+ 'toast.provider.addModelFail': 'Failed to add model',
527
+ 'toast.provider.deleteModelFail': 'Failed to delete model',
523
528
  'toast.provider.fieldsRequired': 'Name, URL, API Key and model are required',
524
529
  'toast.provider.urlRequired': 'URL is required',
525
530
  'toast.claude.modelRequired': 'Please enter model',
@@ -690,12 +695,13 @@ const en = Object.freeze({
690
695
  'sessions.source.workbuddy': 'WorkBuddy AI',
691
696
  'sessions.source.pi': 'Pi',
692
697
  'sessions.source.opencode': 'OpenCode',
698
+ 'sessions.source.zed': 'Zed',
693
699
  'sessions.loadingList': 'Loading sessions...',
694
700
  'sessions.empty': 'No sessions found',
695
701
  'sessions.unknownTime': 'unknown time',
696
702
 
697
703
 
698
- 'sessions.query.placeholder.enabled': 'Search keywords (Codex/Claude/Gemini/CodeBuddy, e.g. claude code)',
704
+ 'sessions.query.placeholder.enabled': "Search keywords (e.g. claude code)",
699
705
  'sessions.query.placeholder.disabled': 'Keyword search is not available for this source',
700
706
  'sessions.pin': 'Pin',
701
707
  'sessions.unpin': 'Unpin',
@@ -706,7 +712,7 @@ const en = Object.freeze({
706
712
  'sessions.preview.loading': 'Loading...',
707
713
  'sessions.batch.select': 'Batch delete',
708
714
  'sessions.batch.exit': 'Exit selection',
709
- 'sessions.batch.selectAll': 'Select all',
715
+ 'sessions.batch.selectAllVisibleN': 'Select {count} visible',
710
716
  'sessions.batch.unselectAll': 'Clear selection',
711
717
  'sessions.batch.deleteSelected': 'Delete selected',
712
718
  'sessions.batch.deleteSelectedN': 'Delete selected ({count})',
@@ -721,6 +727,17 @@ const en = Object.freeze({
721
727
  'sessions.preview.moveToTrash': 'Move to trash',
722
728
  'sessions.preview.deleting': 'Deleting...',
723
729
  'sessions.preview.moving': 'Moving...',
730
+ 'sessions.export.range': "Export range",
731
+ 'sessions.export.default': "Latest 1000 messages",
732
+ 'sessions.export.all': "All extractable messages",
733
+ 'sessions.export.scopeHint': "All removes the message limit; it is not a complete state backup.",
734
+ 'sessions.export.truncated': "This export was truncated. Choose all and export again for earlier messages.",
735
+ 'sessions.search.coverage': "Scanned {scanned} / {candidates} candidate sessions",
736
+ 'sessions.search.partial': "Some candidates remain unscanned. Narrow the source or project.",
737
+ 'sessions.search.scopeHint': "Covers this candidate set only, not all historical records.",
738
+ 'sessions.empty.filtered': "No records match the current filters.",
739
+ 'sessions.empty.source': "No displayable records found for this source. Check local sessions and refresh.",
740
+ 'sessions.empty.clearFilters': "Clear filters",
724
741
  'sessions.preview.export': 'Export',
725
742
  'sessions.preview.exporting': 'Exporting...',
726
743
  'sessions.preview.convert': 'Create derived',
@@ -1133,6 +1150,12 @@ const en = Object.freeze({
1133
1150
  'settings.language.meta': 'Choose the Web UI display language',
1134
1151
  'settings.language.label': 'Interface language',
1135
1152
  'settings.language.hint': 'Language preference is saved in this browser.',
1153
+ 'settings.theme.title': 'Appearance',
1154
+ 'settings.theme.meta': 'Choose the Web UI color theme',
1155
+ 'settings.theme.light': 'Light',
1156
+ 'settings.theme.dark': 'Dark',
1157
+ 'settings.theme.ocean': 'Ocean',
1158
+ 'settings.theme.hint': 'Theme preference is saved automatically and persists across reloads.',
1136
1159
  'settings.sharePrefix.title': 'Share command prefix',
1137
1160
  'settings.sharePrefix.meta': 'Used as the prefix for “Copy share command” in the Web UI',
1138
1161
  'settings.sharePrefix.label': 'Prefix',
@@ -1208,6 +1231,20 @@ const en = Object.freeze({
1208
1231
  'settings.trash.retentionLabel': 'Retention days',
1209
1232
  'settings.trash.retentionUnit': 'days',
1210
1233
  'settings.trash.retentionHint': 'Range 1-365 days, default 30. Expired entries are purged on each trash load.',
1234
+
1235
+ 'settings.trash.loadCountFail': 'Failed to load trash count',
1236
+ 'settings.trash.loadFail': 'Failed to load trash',
1237
+ 'settings.trash.restored': 'Session restored',
1238
+ 'settings.trash.restoreFail': 'Restore failed',
1239
+ 'settings.trash.purged': 'Purged',
1240
+ 'settings.trash.purgeFail': 'Purge failed',
1241
+ 'settings.trash.cleared': 'Trash emptied',
1242
+ 'settings.trash.clearFail': 'Failed to empty trash',
1243
+ 'settings.trash.purgeConfirmTitle': 'Purge trash entry',
1244
+ 'settings.trash.purgeConfirmMessage': 'This session will be permanently deleted from the trash and cannot be restored.',
1245
+ 'settings.trash.clearConfirmTitle': 'Empty trash',
1246
+ 'settings.trash.clearConfirmMessage': 'All sessions in the trash will be permanently deleted and cannot be restored.',
1247
+ 'settings.trash.clearConfirmButton': 'Empty all',
1211
1248
  'settings.trash.count': '{count} item(s)',
1212
1249
  'settings.trash.retentionShort': 'Kept {days} days',
1213
1250
  'settings.trash.disabled': 'Trash is disabled',
@@ -1248,6 +1285,9 @@ const en = Object.freeze({
1248
1285
  'settings.reset.button': 'Reset config',
1249
1286
  'settings.reset.loading': 'Resetting...',
1250
1287
 
1288
+ 'settings.reset.confirmTitle': 'Confirm config reset',
1289
+ 'settings.reset.confirmMessage': 'This will back up config.toml, then overwrite the current config with defaults. Continue?',
1290
+
1251
1291
  // Market (Skills)
1252
1292
  'market.title': 'Skills Overview',
1253
1293
  'market.subtitle': 'Switch target and inspect local skills.',
@@ -1358,6 +1398,44 @@ const en = Object.freeze({
1358
1398
  'modal.openclaw.quick.subtitle': '3 steps: fill provider/model, write to editor, save & apply.',
1359
1399
  'modal.openclaw.quick.step2': 'Write to editor',
1360
1400
  'modal.openclaw.structured.writeHint': 'Writing to editor may reformat JSON and drop comments.',
1401
+
1402
+ 'modal.openclaw.next': 'Next →',
1403
+ 'modal.openclaw.prev': '← Previous',
1404
+ 'modal.openclaw.finish': 'Finish ✓',
1405
+ 'modal.openclaw.quick.advancedOptions': 'Advanced options',
1406
+ 'modal.openclaw.quick.providerNamePlaceholder': 'e.g. custom-myapi',
1407
+ 'modal.openclaw.quick.modelIdHint': 'Required, e.g. gpt-4',
1408
+ 'modal.openclaw.quick.modelNameHint': 'Optional, used for display',
1409
+ 'modal.openclaw.structured.title': 'Structured config (advanced)',
1410
+ 'modal.openclaw.structured.primaryModel': 'Primary model',
1411
+ 'modal.openclaw.structured.fallbackModels': 'Fallback models',
1412
+ 'modal.openclaw.structured.providerModelPlaceholder': 'e.g. provider/model',
1413
+ 'modal.openclaw.structured.addFallback': 'Add fallback',
1414
+ 'modal.openclaw.structured.workspacePlaceholder': 'e.g. ~/.openclaw/workspace',
1415
+ 'modal.openclaw.structured.timeoutPlaceholder': 'e.g. 600',
1416
+ 'modal.openclaw.structured.contextTokensPlaceholder': 'e.g. 4096',
1417
+ 'modal.openclaw.structured.maxConcurrentPlaceholder': 'e.g. 2',
1418
+ 'modal.openclaw.structured.envVars': 'Environment variables',
1419
+ 'modal.openclaw.structured.addEnvVar': 'Add variable',
1420
+ 'modal.openclaw.structured.addAllow': 'Add allow',
1421
+ 'modal.openclaw.structured.addDeny': 'Add deny',
1422
+ 'modal.openclaw.structured.allowPlaceholder': 'e.g. fs.read*',
1423
+ 'modal.openclaw.structured.denyPlaceholder': 'e.g. net.*',
1424
+ 'modal.openclaw.structured.providersTitle': 'Providers (read-only)',
1425
+ 'modal.openclaw.structured.noProviders': 'No providers config found (may use environment variables or external config).',
1426
+ 'modal.openclaw.structured.sourceLabel': 'Source',
1427
+ 'modal.openclaw.structured.active': 'Active',
1428
+ 'modal.openclaw.structured.noFields': 'No fields configured',
1429
+ 'modal.openclaw.structured.missingProviders': 'Active providers not shown in config: {list}.',
1430
+ 'modal.openclaw.structured.agentsTitle': 'Agents (read-only)',
1431
+ 'modal.openclaw.structured.noAgents': 'No agents.list config found.',
1432
+ 'modal.openclaw.structured.themeLabel': 'Theme',
1433
+ 'modal.openclaw.structured.emojiLabel': 'Emoji',
1434
+ 'modal.openclaw.structured.avatarLabel': 'Avatar',
1435
+ 'modal.openclaw.editorLabel': 'OpenClaw config (JSON5)',
1436
+ 'modal.openclaw.editorPlaceholder': 'Edit OpenClaw config here (JSON5)',
1437
+ 'modal.openclaw.defaultConfigHint': 'The default config always maps to the current openclaw.json. Use "Save & apply" directly.',
1438
+ 'modal.openclaw.saveOnlyHint': 'Saving only writes to the local config library. Click "Save & apply" to write openclaw.json.',
1361
1439
  'openclaw.action.applyAria': 'Apply OpenClaw config: {name}',
1362
1440
  'openclaw.action.editAria': 'Edit OpenClaw config: {name}',
1363
1441
  'openclaw.action.deleteAria': 'Delete OpenClaw config: {name}'
@@ -526,6 +526,11 @@ const ja = Object.freeze({
526
526
  'toast.provider.updateFail': '更新に失敗しました',
527
527
  'toast.provider.resetSuccess': '設定をリセットしました{backup}',
528
528
  'toast.provider.resetFail': 'リセットに失敗しました',
529
+
530
+ 'toast.provider.resetBackup': '(バックアップ: {file})',
531
+ 'toast.provider.modelRequired': 'モデル名を入力してください',
532
+ 'toast.provider.addModelFail': 'モデルの追加に失敗しました',
533
+ 'toast.provider.deleteModelFail': 'モデルの削除に失敗しました',
529
534
  'toast.provider.fieldsRequired': '名前、URL、API Key、モデル名は必須です',
530
535
  'toast.provider.urlRequired': 'URL は必須です',
531
536
  'toast.claude.modelRequired': 'モデルを入力してください',
@@ -692,12 +697,13 @@ const ja = Object.freeze({
692
697
  'sessions.source.workbuddy': 'WorkBuddy AI',
693
698
  'sessions.source.pi': 'Pi',
694
699
  'sessions.source.opencode': 'OpenCode',
700
+ 'sessions.source.zed': 'Zed',
695
701
  'sessions.loadingList': 'セッション一覧を読み込み中...',
696
702
  'sessions.empty': 'セッションがありません',
697
703
  'sessions.unknownTime': '不明な時間',
698
704
 
699
705
 
700
- 'sessions.query.placeholder.enabled': 'セッションを検索...',
706
+ 'sessions.query.placeholder.enabled': "キーワードで検索",
701
707
  'sessions.query.placeholder.disabled': '現在のソースでは検索は利用できません',
702
708
  'sessions.pin': 'ピン留め',
703
709
  'sessions.unpin': 'ピン留め解除',
@@ -708,7 +714,7 @@ const ja = Object.freeze({
708
714
  'sessions.preview.loading': 'プレビュー読み込み中...',
709
715
  'sessions.batch.select': '一括削除',
710
716
  'sessions.batch.exit': '選択を終了',
711
- 'sessions.batch.selectAll': 'すべて選択',
717
+ 'sessions.batch.selectAllVisibleN': '表示中の {count} 件を選択',
712
718
  'sessions.batch.unselectAll': '選択を解除',
713
719
  'sessions.batch.deleteSelected': '選択を削除',
714
720
  'sessions.batch.deleteSelectedN': '選択を削除({count})',
@@ -723,6 +729,17 @@ const ja = Object.freeze({
723
729
  'sessions.preview.moveToTrash': 'ゴミ箱に移動',
724
730
  'sessions.preview.deleting': '削除中...',
725
731
  'sessions.preview.moving': '移動中...',
732
+ 'sessions.export.range': "出力範囲",
733
+ 'sessions.export.default': "直近1000件",
734
+ 'sessions.export.all': "抽出可能な全メッセージ",
735
+ 'sessions.export.scopeHint': "全件は件数制限の解除です。完全な状態バックアップではありません。",
736
+ 'sessions.export.truncated': "出力は切り詰められました。以前の内容が必要な場合は全件を選び再出力してください。",
737
+ 'sessions.search.coverage': "候補 {candidates} 件中 {scanned} 件を検索",
738
+ 'sessions.search.partial': "未検索の候補があります。ソースやプロジェクトを絞り込んでください。",
739
+ 'sessions.search.scopeHint': "今回の候補範囲のみで、全履歴を表すものではありません。",
740
+ 'sessions.empty.filtered': "現在のフィルターに一致する記録がありません。",
741
+ 'sessions.empty.source': "表示可能な記録が見つかりません。ローカルの会話を確認して更新してください。",
742
+ 'sessions.empty.clearFilters': "フィルターを解除",
726
743
  'sessions.preview.export': 'エクスポート',
727
744
  'sessions.preview.exporting': 'エクスポート中...',
728
745
  'sessions.preview.importNative': 'ネイティブディレクトリへインポート',
@@ -1136,6 +1153,12 @@ const ja = Object.freeze({
1136
1153
  'settings.language.meta': 'Web UI の表示言語を選択',
1137
1154
  'settings.language.label': 'インターフェース言語',
1138
1155
  'settings.language.hint': '言語設定はこのブラウザに保存されます。',
1156
+ 'settings.theme.title': '外観テーマ',
1157
+ 'settings.theme.meta': 'Web UI のカラーテーマを選択します',
1158
+ 'settings.theme.light': 'ライト',
1159
+ 'settings.theme.dark': 'ダーク',
1160
+ 'settings.theme.ocean': 'オーシャン',
1161
+ 'settings.theme.hint': 'テーマ設定は自動保存され、再読み込み後も保持されます。',
1139
1162
  'settings.sharePrefix.title': '共有コマンドプレフィックス',
1140
1163
  'settings.sharePrefix.meta': 'Web UI の「共有コマンドをコピー」のプレフィックスに影響',
1141
1164
  'settings.sharePrefix.label': 'プレフィックス',
@@ -1210,6 +1233,20 @@ const ja = Object.freeze({
1210
1233
  'settings.trash.retentionLabel': '保持日数',
1211
1234
  'settings.trash.retentionUnit': '日',
1212
1235
  'settings.trash.retentionHint': '範囲 1-365 日、デフォルト 30 日。ゴミ箱読み込み時に期限切れレコードを自動クリーンアップします。',
1236
+
1237
+ 'settings.trash.loadCountFail': 'ゴミ箱数の読み込みに失敗しました',
1238
+ 'settings.trash.loadFail': 'ゴミ箱の読み込みに失敗しました',
1239
+ 'settings.trash.restored': 'セッションを復元しました',
1240
+ 'settings.trash.restoreFail': '復元に失敗しました',
1241
+ 'settings.trash.purged': '完全に削除しました',
1242
+ 'settings.trash.purgeFail': '完全削除に失敗しました',
1243
+ 'settings.trash.cleared': 'ゴミ箱を空にしました',
1244
+ 'settings.trash.clearFail': 'ゴミ箱を空にできませんでした',
1245
+ 'settings.trash.purgeConfirmTitle': 'ゴミ箱の記録を完全削除',
1246
+ 'settings.trash.purgeConfirmMessage': 'このセッションはゴミ箱から完全に削除され、復元できません。',
1247
+ 'settings.trash.clearConfirmTitle': 'ゴミ箱を空にする',
1248
+ 'settings.trash.clearConfirmMessage': 'ゴミ箱内のすべてのセッションが完全に削除され、復元できません。',
1249
+ 'settings.trash.clearConfirmButton': 'すべて空にする',
1213
1250
  'settings.trash.count': '全 {count} 件',
1214
1251
  'settings.trash.retentionShort': '保持 {days} 日',
1215
1252
  'settings.trash.disabled': 'ゴミ箱は無効です',
@@ -1250,6 +1287,9 @@ const ja = Object.freeze({
1250
1287
  'settings.reset.button': '設定を再インストール',
1251
1288
  'settings.reset.loading': '再インストール中...',
1252
1289
 
1290
+ 'settings.reset.confirmTitle': '設定リセットの確認',
1291
+ 'settings.reset.confirmMessage': 'config.toml をバックアップした後、現在の設定をデフォルトで上書きします。続行しますか?',
1292
+
1253
1293
  // Market (Skills)
1254
1294
  'market.title': 'Skills 概要',
1255
1295
  'market.subtitle': 'ターゲットを切り替えてローカル Skills を表示。',
@@ -1360,6 +1400,44 @@ const ja = Object.freeze({
1360
1400
  'modal.openclaw.quick.subtitle': '3ステップで完了:Provider とモデルを入力、エディタに書き込み、保存して適用。',
1361
1401
  'modal.openclaw.quick.step2': 'エディタに書き込みをクリック',
1362
1402
  'modal.openclaw.structured.writeHint': 'エディタに書き込むと JSON が再配置され、コメントが失われる可能性があります。',
1403
+
1404
+ 'modal.openclaw.next': '次へ →',
1405
+ 'modal.openclaw.prev': '← 前へ',
1406
+ 'modal.openclaw.finish': '完了 ✓',
1407
+ 'modal.openclaw.quick.advancedOptions': '詳細オプション',
1408
+ 'modal.openclaw.quick.providerNamePlaceholder': '例: custom-myapi',
1409
+ 'modal.openclaw.quick.modelIdHint': '必須、例: gpt-4',
1410
+ 'modal.openclaw.quick.modelNameHint': '任意、表示用',
1411
+ 'modal.openclaw.structured.title': '構造化設定(詳細)',
1412
+ 'modal.openclaw.structured.primaryModel': 'メインモデル',
1413
+ 'modal.openclaw.structured.fallbackModels': 'フォールバックモデル',
1414
+ 'modal.openclaw.structured.providerModelPlaceholder': '例: provider/model',
1415
+ 'modal.openclaw.structured.addFallback': 'フォールバックを追加',
1416
+ 'modal.openclaw.structured.workspacePlaceholder': '例: ~/.openclaw/workspace',
1417
+ 'modal.openclaw.structured.timeoutPlaceholder': '例: 600',
1418
+ 'modal.openclaw.structured.contextTokensPlaceholder': '例: 4096',
1419
+ 'modal.openclaw.structured.maxConcurrentPlaceholder': '例: 2',
1420
+ 'modal.openclaw.structured.envVars': '環境変数',
1421
+ 'modal.openclaw.structured.addEnvVar': '変数を追加',
1422
+ 'modal.openclaw.structured.addAllow': 'allow を追加',
1423
+ 'modal.openclaw.structured.addDeny': 'deny を追加',
1424
+ 'modal.openclaw.structured.allowPlaceholder': '例: fs.read*',
1425
+ 'modal.openclaw.structured.denyPlaceholder': '例: net.*',
1426
+ 'modal.openclaw.structured.providersTitle': 'Providers(読み取り専用)',
1427
+ 'modal.openclaw.structured.noProviders': 'providers 設定が見つかりません(環境変数または外部設定の可能性があります)。',
1428
+ 'modal.openclaw.structured.sourceLabel': 'ソース',
1429
+ 'modal.openclaw.structured.active': '使用中',
1430
+ 'modal.openclaw.structured.noFields': 'フィールド未設定',
1431
+ 'modal.openclaw.structured.missingProviders': '使用中の provider が設定に表示されていません:{list}。',
1432
+ 'modal.openclaw.structured.agentsTitle': 'Agents(読み取り専用)',
1433
+ 'modal.openclaw.structured.noAgents': 'agents.list 設定が見つかりません。',
1434
+ 'modal.openclaw.structured.themeLabel': 'テーマ',
1435
+ 'modal.openclaw.structured.emojiLabel': '絵文字',
1436
+ 'modal.openclaw.structured.avatarLabel': 'アバター',
1437
+ 'modal.openclaw.editorLabel': 'OpenClaw 設定(JSON5)',
1438
+ 'modal.openclaw.editorPlaceholder': 'ここで OpenClaw 設定(JSON5)を編集します',
1439
+ 'modal.openclaw.defaultConfigHint': 'デフォルト設定は常に現在の openclaw.json にマッピングされます。「保存して適用」を直接使用してください。',
1440
+ 'modal.openclaw.saveOnlyHint': '保存はローカル設定ライブラリのみに書き込まれます。「保存して適用」を押すと openclaw.json に書き込まれます。',
1363
1441
  'openclaw.action.applyAria': 'OpenClaw 設定を適用:{name}',
1364
1442
  'openclaw.action.editAria': 'OpenClaw 設定を編集:{name}',
1365
1443
  'openclaw.action.deleteAria': 'OpenClaw 設定を削除:{name}',
@@ -397,6 +397,12 @@ const vi = Object.freeze({
397
397
  'settings.language.meta': 'Chọn ngôn ngữ hiển thị cho Web UI',
398
398
  'settings.language.label': 'Ngôn ngữ giao diện',
399
399
  'settings.language.hint': 'Tùy chọn ngôn ngữ được lưu trong trình duyệt này.',
400
+ 'settings.theme.title': 'Chủ đề giao diện',
401
+ 'settings.theme.meta': 'Chọn chủ đề màu cho Web UI',
402
+ 'settings.theme.light': 'Sáng',
403
+ 'settings.theme.dark': 'Tối',
404
+ 'settings.theme.ocean': 'Đại dương',
405
+ 'settings.theme.hint': 'Tùy chọn chủ đề được tự động lưu và giữ nguyên sau khi tải lại.',
400
406
 
401
407
  'settings.webhook.title': 'Webhook',
402
408
  'settings.webhook.meta': 'Gửi thông báo sự kiện tới dịch vụ bên ngoài',
@@ -464,6 +470,11 @@ const vi = Object.freeze({
464
470
  'toast.provider.updateFail': 'Cập nhật thất bại',
465
471
  'toast.provider.resetSuccess': 'Đã cài đặt lại cấu hình{backup}',
466
472
  'toast.provider.resetFail': 'Cài đặt lại thất bại',
473
+
474
+ 'toast.provider.resetBackup': ' (đã sao lưu: {file})',
475
+ 'toast.provider.modelRequired': 'Vui lòng nhập mô hình',
476
+ 'toast.provider.addModelFail': 'Thêm mô hình thất bại',
477
+ 'toast.provider.deleteModelFail': 'Xóa mô hình thất bại',
467
478
  'toast.provider.fieldsRequired': 'Tên, URL, API Key và tên mô hình là bắt buộc',
468
479
  'toast.provider.urlRequired': 'URL là bắt buộc',
469
480
  'toast.claude.modelRequired': 'Vui lòng nhập mô hình',
@@ -867,10 +878,11 @@ const vi = Object.freeze({
867
878
  'sessions.source.workbuddy': 'WorkBuddy AI',
868
879
  'sessions.source.pi': 'Pi',
869
880
  'sessions.source.opencode': 'OpenCode',
881
+ 'sessions.source.zed': 'Zed',
870
882
  'sessions.loadingList': 'Đang tải phiên làm việc...',
871
883
  'sessions.empty': 'Không tìm thấy phiên nào',
872
884
  'sessions.unknownTime': 'thời gian không rõ',
873
- 'sessions.query.placeholder.enabled': 'Tìm kiếm từ khóa (Codex/Claude/Gemini/CodeBuddy)',
885
+ 'sessions.query.placeholder.enabled': "Tìm kiếm từ khóa",
874
886
  'sessions.query.placeholder.disabled': 'Tìm kiếm từ khóa không khả dụng cho nguồn này',
875
887
  'sessions.pin': 'Ghim',
876
888
  'sessions.unpin': 'Bỏ ghim',
@@ -881,7 +893,7 @@ const vi = Object.freeze({
881
893
  'sessions.preview.loading': 'Đang tải...',
882
894
  'sessions.batch.select': 'Xóa hàng loạt',
883
895
  'sessions.batch.exit': 'Thoát chọn',
884
- 'sessions.batch.selectAll': 'Chọn tất cả',
896
+ 'sessions.batch.selectAllVisibleN': 'Chọn {count} mục hiển thị',
885
897
  'sessions.batch.unselectAll': 'Bỏ chọn tất cả',
886
898
  'sessions.batch.deleteSelected': 'Xóa đã chọn',
887
899
  'sessions.batch.deleteSelectedN': 'Xóa đã chọn ({count})',
@@ -896,6 +908,17 @@ const vi = Object.freeze({
896
908
  'sessions.preview.moveToTrash': 'Chuyển vào thùng rác',
897
909
  'sessions.preview.deleting': 'Đang xóa...',
898
910
  'sessions.preview.moving': 'Đang chuyển...',
911
+ 'sessions.export.range': "Phạm vi xuất",
912
+ 'sessions.export.default': "1000 tin nhắn gần nhất",
913
+ 'sessions.export.all': "Tất cả tin nhắn có thể trích xuất",
914
+ 'sessions.export.scopeHint': "Tất cả chỉ bỏ giới hạn số tin nhắn, không phải bản sao lưu toàn bộ trạng thái.",
915
+ 'sessions.export.truncated': "Bản xuất đã bị cắt bớt. Chọn tất cả và xuất lại để lấy tin nhắn cũ hơn.",
916
+ 'sessions.search.coverage': "Đã quét {scanned} / {candidates} phiên ứng viên",
917
+ 'sessions.search.partial': "Vẫn còn phiên chưa quét. Hãy thu hẹp nguồn hoặc dự án.",
918
+ 'sessions.search.scopeHint': "Chỉ phản ánh tập ứng viên hiện tại, không phải toàn bộ lịch sử.",
919
+ 'sessions.empty.filtered': "Không có bản ghi khớp bộ lọc hiện tại.",
920
+ 'sessions.empty.source': "Không tìm thấy bản ghi có thể hiển thị. Kiểm tra phiên cục bộ và làm mới.",
921
+ 'sessions.empty.clearFilters': "Xóa bộ lọc",
899
922
  'sessions.preview.export': 'Xuất',
900
923
  'sessions.preview.exporting': 'Đang xuất...',
901
924
  'sessions.preview.convert': 'Tạo phiên dẫn xuất',
@@ -1225,6 +1248,20 @@ const vi = Object.freeze({
1225
1248
  'settings.trash.retentionMeta': 'Mục trong thùng rác cũ hơn số ngày lưu giữ sẽ tự động bị xóa',
1226
1249
  'settings.trash.retentionLabel': 'Số ngày lưu giữ',
1227
1250
  'settings.trash.retentionHint': 'Phạm vi 1-365 ngày, mặc định 30. Mục hết hạn bị xóa khi tải thùng rác.',
1251
+
1252
+ 'settings.trash.loadCountFail': 'Không tải được số lượng thùng rác',
1253
+ 'settings.trash.loadFail': 'Không tải được thùng rác',
1254
+ 'settings.trash.restored': 'Đã khôi phục phiên',
1255
+ 'settings.trash.restoreFail': 'Khôi phục thất bại',
1256
+ 'settings.trash.purged': 'Đã xóa vĩnh viễn',
1257
+ 'settings.trash.purgeFail': 'Xóa vĩnh viễn thất bại',
1258
+ 'settings.trash.cleared': 'Đã làm trống thùng rác',
1259
+ 'settings.trash.clearFail': 'Không làm trống được thùng rác',
1260
+ 'settings.trash.purgeConfirmTitle': 'Xóa vĩnh viễn bản ghi thùng rác',
1261
+ 'settings.trash.purgeConfirmMessage': 'Phiên này sẽ bị xóa vĩnh viễn khỏi thùng rác và không thể khôi phục.',
1262
+ 'settings.trash.clearConfirmTitle': 'Làm trống thùng rác',
1263
+ 'settings.trash.clearConfirmMessage': 'Tất cả phiên trong thùng rác sẽ bị xóa vĩnh viễn và không thể khôi phục.',
1264
+ 'settings.trash.clearConfirmButton': 'Làm trống tất cả',
1228
1265
  'settings.trash.count': 'Tổng {count} mục',
1229
1266
  'settings.trash.retentionShort': 'Lưu {days} ngày',
1230
1267
  'settings.trash.disabled': 'Thùng rác đã tắt',
@@ -1240,6 +1277,9 @@ const vi = Object.freeze({
1240
1277
  'settings.reset.hint': 'Sao lưu config.toml, rồi ghi cấu hình mặc định.',
1241
1278
  'settings.reset.button': 'Đặt lại cấu hình',
1242
1279
  'settings.reset.loading': 'Đang đặt lại...',
1280
+
1281
+ 'settings.reset.confirmTitle': 'Xác nhận đặt lại cấu hình',
1282
+ 'settings.reset.confirmMessage': 'Thao tác này sẽ sao lưu config.toml, sau đó ghi đè cấu hình hiện tại bằng cấu hình mặc định. Tiếp tục?',
1243
1283
  'market.title': 'Tổng quan Skills',
1244
1284
  'market.subtitle': 'Chuyển đích và xem skills cục bộ.',
1245
1285
  'market.refresh': 'Làm mới tổng quan',
@@ -1328,6 +1368,44 @@ const vi = Object.freeze({
1328
1368
  'openclaw.action.edit': 'Chỉnh sửa',
1329
1369
  'openclaw.action.delete': 'Xóa',
1330
1370
  'modal.openclaw.structured.writeHint': 'Ghi vào editor có thể định dạng lại JSON và bỏ comment.',
1371
+
1372
+ 'modal.openclaw.next': 'Tiếp →',
1373
+ 'modal.openclaw.prev': '← Trước',
1374
+ 'modal.openclaw.finish': 'Hoàn tất ✓',
1375
+ 'modal.openclaw.quick.advancedOptions': 'Tùy chọn nâng cao',
1376
+ 'modal.openclaw.quick.providerNamePlaceholder': 'vd: custom-myapi',
1377
+ 'modal.openclaw.quick.modelIdHint': 'Bắt buộc, vd: gpt-4',
1378
+ 'modal.openclaw.quick.modelNameHint': 'Không bắt buộc, dùng để hiển thị',
1379
+ 'modal.openclaw.structured.title': 'Cấu hình có cấu trúc (nâng cao)',
1380
+ 'modal.openclaw.structured.primaryModel': 'Mô hình chính',
1381
+ 'modal.openclaw.structured.fallbackModels': 'Mô hình dự phòng',
1382
+ 'modal.openclaw.structured.providerModelPlaceholder': 'vd: provider/model',
1383
+ 'modal.openclaw.structured.addFallback': 'Thêm dự phòng',
1384
+ 'modal.openclaw.structured.workspacePlaceholder': 'vd: ~/.openclaw/workspace',
1385
+ 'modal.openclaw.structured.timeoutPlaceholder': 'vd: 600',
1386
+ 'modal.openclaw.structured.contextTokensPlaceholder': 'vd: 4096',
1387
+ 'modal.openclaw.structured.maxConcurrentPlaceholder': 'vd: 2',
1388
+ 'modal.openclaw.structured.envVars': 'Biến môi trường',
1389
+ 'modal.openclaw.structured.addEnvVar': 'Thêm biến',
1390
+ 'modal.openclaw.structured.addAllow': 'Thêm allow',
1391
+ 'modal.openclaw.structured.addDeny': 'Thêm deny',
1392
+ 'modal.openclaw.structured.allowPlaceholder': 'vd: fs.read*',
1393
+ 'modal.openclaw.structured.denyPlaceholder': 'vd: net.*',
1394
+ 'modal.openclaw.structured.providersTitle': 'Providers (chỉ đọc)',
1395
+ 'modal.openclaw.structured.noProviders': 'Không tìm thấy cấu hình providers (có thể dùng biến môi trường hoặc cấu hình bên ngoài).',
1396
+ 'modal.openclaw.structured.sourceLabel': 'Nguồn',
1397
+ 'modal.openclaw.structured.active': 'Đang dùng',
1398
+ 'modal.openclaw.structured.noFields': 'Chưa cấu hình trường nào',
1399
+ 'modal.openclaw.structured.missingProviders': 'Provider đang dùng không hiển thị trong cấu hình: {list}.',
1400
+ 'modal.openclaw.structured.agentsTitle': 'Agents (chỉ đọc)',
1401
+ 'modal.openclaw.structured.noAgents': 'Không tìm thấy cấu hình agents.list.',
1402
+ 'modal.openclaw.structured.themeLabel': 'Chủ đề',
1403
+ 'modal.openclaw.structured.emojiLabel': 'Biểu tượng',
1404
+ 'modal.openclaw.structured.avatarLabel': 'Ảnh đại diện',
1405
+ 'modal.openclaw.editorLabel': 'Cấu hình OpenClaw (JSON5)',
1406
+ 'modal.openclaw.editorPlaceholder': 'Chỉnh sửa cấu hình OpenClaw (JSON5) tại đây',
1407
+ 'modal.openclaw.defaultConfigHint': 'Cấu hình mặc định luôn ánh xạ tới openclaw.json hiện tại, hãy dùng "Lưu & áp dụng" trực tiếp.',
1408
+ 'modal.openclaw.saveOnlyHint': 'Lưu chỉ ghi vào thư viện cấu hình cục bộ. Nhấn "Lưu & áp dụng" sẽ ghi vào openclaw.json.',
1331
1409
  'openclaw.action.applyAria': 'Áp dụng cấu hình OpenClaw: {name}',
1332
1410
  'openclaw.action.editAria': 'Chỉnh sửa cấu hình OpenClaw: {name}',
1333
1411
  'openclaw.action.deleteAria': 'Xóa cấu hình OpenClaw: {name}',
@@ -524,6 +524,11 @@ const zhTw = Object.freeze({
524
524
  'toast.provider.updateFail': '更新失敗',
525
525
  'toast.provider.resetSuccess': '設定已重裝{backup}',
526
526
  'toast.provider.resetFail': '重裝失敗',
527
+
528
+ 'toast.provider.resetBackup': '(已備份: {file})',
529
+ 'toast.provider.modelRequired': '請輸入模型',
530
+ 'toast.provider.addModelFail': '新增模型失敗',
531
+ 'toast.provider.deleteModelFail': '刪除模型失敗',
527
532
  'toast.provider.fieldsRequired': '名稱、URL、API Key 和模型名稱必填',
528
533
  'toast.provider.urlRequired': 'URL 必填',
529
534
  'toast.claude.modelRequired': '請輸入模型',
@@ -690,11 +695,12 @@ const zhTw = Object.freeze({
690
695
  'sessions.source.workbuddy': 'WorkBuddy AI',
691
696
  'sessions.source.pi': 'Pi',
692
697
  'sessions.source.opencode': 'OpenCode',
698
+ 'sessions.source.zed': 'Zed',
693
699
  'sessions.loadingList': '會話載入中...',
694
700
  'sessions.empty': '暫無可用會話記錄',
695
701
  'sessions.unknownTime': '未知時間',
696
702
 
697
- 'sessions.query.placeholder.enabled': '關鍵詞檢索(支持 Codex/Claude/Gemini/CodeBuddy,例:claude code)',
703
+ 'sessions.query.placeholder.enabled': "關鍵詞檢索(例:claude code)",
698
704
  'sessions.query.placeholder.disabled': '目前來源暫不支持關鍵詞檢索',
699
705
  'sessions.pin': '置頂',
700
706
  'sessions.unpin': '取消置頂',
@@ -705,7 +711,7 @@ const zhTw = Object.freeze({
705
711
  'sessions.preview.loading': '載入中...',
706
712
  'sessions.batch.select': '批次刪除',
707
713
  'sessions.batch.exit': '退出選擇',
708
- 'sessions.batch.selectAll': '全選',
714
+ 'sessions.batch.selectAllVisibleN': '全選可見 {count} 項',
709
715
  'sessions.batch.unselectAll': '取消全選',
710
716
  'sessions.batch.deleteSelected': '刪除選中',
711
717
  'sessions.batch.deleteSelectedN': '刪除選中({count})',
@@ -720,6 +726,17 @@ const zhTw = Object.freeze({
720
726
  'sessions.preview.moveToTrash': '移入回收站',
721
727
  'sessions.preview.deleting': '刪除中...',
722
728
  'sessions.preview.moving': '移入中...',
729
+ 'sessions.export.range': "匯出範圍",
730
+ 'sessions.export.default': "最近 1000 則",
731
+ 'sessions.export.all': "全部可擷取訊息",
732
+ 'sessions.export.scopeHint': "全部僅取消訊息數量上限,並非完整狀態備份。",
733
+ 'sessions.export.truncated': "本次匯出已截斷;需要較早內容可選擇全部後重新匯出。",
734
+ 'sessions.search.coverage': "已掃描 {scanned} / {candidates} 筆候選對話",
735
+ 'sessions.search.partial': "本次候選尚未掃描完,請縮小來源或專案範圍。",
736
+ 'sessions.search.scopeHint': "僅反映本次候選範圍,不代表全部歷史記錄。",
737
+ 'sessions.empty.filtered': "目前篩選沒有相符記錄。",
738
+ 'sessions.empty.source': "目前來源未發現可顯示記錄,請確認本機已有對話並重新整理。",
739
+ 'sessions.empty.clearFilters': "清除篩選",
723
740
  'sessions.preview.export': '匯出記錄',
724
741
  'sessions.preview.exporting': '匯出中...',
725
742
  'sessions.preview.convert': '生成派生會話',
@@ -1132,6 +1149,12 @@ const zhTw = Object.freeze({
1132
1149
  'settings.language.meta': '選擇 Web UI 的顯示語言',
1133
1150
  'settings.language.label': '界面語言',
1134
1151
  'settings.language.hint': '語言偏好會保存在目前瀏覽器。',
1152
+ 'settings.theme.title': '外觀主題',
1153
+ 'settings.theme.meta': '選擇 Web UI 的配色主題',
1154
+ 'settings.theme.light': '淺色',
1155
+ 'settings.theme.dark': '深色',
1156
+ 'settings.theme.ocean': '海洋藍',
1157
+ 'settings.theme.hint': '主題偏好會自動儲存,重新整理後保持不變。',
1135
1158
  'settings.sharePrefix.title': '分享命令前綴',
1136
1159
  'settings.sharePrefix.meta': '影響 Web UI 裡“複製分享命令”的前綴',
1137
1160
  'settings.sharePrefix.label': '前綴',
@@ -1206,6 +1229,20 @@ const zhTw = Object.freeze({
1206
1229
  'settings.trash.retentionLabel': '保留天數',
1207
1230
  'settings.trash.retentionUnit': '天',
1208
1231
  'settings.trash.retentionHint': '範圍 1-365 天,預設 30 天。每次載入回收站時自動清理過期記錄。',
1232
+
1233
+ 'settings.trash.loadCountFail': '載入回收站數量失敗',
1234
+ 'settings.trash.loadFail': '載入回收站失敗',
1235
+ 'settings.trash.restored': '會話已恢復',
1236
+ 'settings.trash.restoreFail': '恢復失敗',
1237
+ 'settings.trash.purged': '已徹底刪除',
1238
+ 'settings.trash.purgeFail': '徹底刪除失敗',
1239
+ 'settings.trash.cleared': '回收站已清空',
1240
+ 'settings.trash.clearFail': '清空回收站失敗',
1241
+ 'settings.trash.purgeConfirmTitle': '徹底刪除回收站記錄',
1242
+ 'settings.trash.purgeConfirmMessage': '該會話將從回收站永久刪除,且無法恢復。',
1243
+ 'settings.trash.clearConfirmTitle': '清空回收站',
1244
+ 'settings.trash.clearConfirmMessage': '該操作會永久刪除回收站中的全部會話,且無法恢復。',
1245
+ 'settings.trash.clearConfirmButton': '全部清空',
1209
1246
  'settings.trash.count': '共 {count} 項',
1210
1247
  'settings.trash.retentionShort': '保留 {days} 天',
1211
1248
  'settings.trash.disabled': '回收站已關閉',
@@ -1246,6 +1283,9 @@ const zhTw = Object.freeze({
1246
1283
  'settings.reset.button': '重裝設定',
1247
1284
  'settings.reset.loading': '重裝中...',
1248
1285
 
1286
+ 'settings.reset.confirmTitle': '確認重置配置',
1287
+ 'settings.reset.confirmMessage': '將先備份 config.toml,再用預設配置覆蓋當前配置。確定繼續嗎?',
1288
+
1249
1289
  // Market (Skills)
1250
1290
  'market.title': 'Skills 概覽',
1251
1291
  'market.subtitle': '切換目標並查看本地 Skills。',
@@ -1356,6 +1396,44 @@ const zhTw = Object.freeze({
1356
1396
  'modal.openclaw.quick.subtitle': '按 3 步完成:填 Provider 和模型,寫入編輯器,保存並應用。',
1357
1397
  'modal.openclaw.quick.step2': '點擊寫入編輯器',
1358
1398
  'modal.openclaw.structured.writeHint': '寫入編輯器會重排 JSON,註釋可能丟失。',
1399
+
1400
+ 'modal.openclaw.next': '下一步 →',
1401
+ 'modal.openclaw.prev': '← 上一步',
1402
+ 'modal.openclaw.finish': '完成 ✓',
1403
+ 'modal.openclaw.quick.advancedOptions': '進階選項',
1404
+ 'modal.openclaw.quick.providerNamePlaceholder': '例如: custom-myapi',
1405
+ 'modal.openclaw.quick.modelIdHint': '必填,例如: gpt-4',
1406
+ 'modal.openclaw.quick.modelNameHint': '可選,用於顯示',
1407
+ 'modal.openclaw.structured.title': '結構化配置(進階)',
1408
+ 'modal.openclaw.structured.primaryModel': '主模型',
1409
+ 'modal.openclaw.structured.fallbackModels': '備選模型',
1410
+ 'modal.openclaw.structured.providerModelPlaceholder': '例如: provider/model',
1411
+ 'modal.openclaw.structured.addFallback': '新增備選',
1412
+ 'modal.openclaw.structured.workspacePlaceholder': '例如: ~/.openclaw/workspace',
1413
+ 'modal.openclaw.structured.timeoutPlaceholder': '例如: 600',
1414
+ 'modal.openclaw.structured.contextTokensPlaceholder': '例如: 4096',
1415
+ 'modal.openclaw.structured.maxConcurrentPlaceholder': '例如: 2',
1416
+ 'modal.openclaw.structured.envVars': '環境變數',
1417
+ 'modal.openclaw.structured.addEnvVar': '新增變數',
1418
+ 'modal.openclaw.structured.addAllow': '新增 allow',
1419
+ 'modal.openclaw.structured.addDeny': '新增 deny',
1420
+ 'modal.openclaw.structured.allowPlaceholder': '例如: fs.read*',
1421
+ 'modal.openclaw.structured.denyPlaceholder': '例如: net.*',
1422
+ 'modal.openclaw.structured.providersTitle': 'Providers(唯讀)',
1423
+ 'modal.openclaw.structured.noProviders': '未發現 providers 配置(可能使用環境變數或外部配置)。',
1424
+ 'modal.openclaw.structured.sourceLabel': '來源',
1425
+ 'modal.openclaw.structured.active': '使用中',
1426
+ 'modal.openclaw.structured.noFields': '未配置欄位',
1427
+ 'modal.openclaw.structured.missingProviders': '使用中的 provider 未在配置中顯示:{list}。',
1428
+ 'modal.openclaw.structured.agentsTitle': 'Agents(唯讀)',
1429
+ 'modal.openclaw.structured.noAgents': '未發現 agents.list 配置。',
1430
+ 'modal.openclaw.structured.themeLabel': '主題',
1431
+ 'modal.openclaw.structured.emojiLabel': '表情',
1432
+ 'modal.openclaw.structured.avatarLabel': '頭像',
1433
+ 'modal.openclaw.editorLabel': 'OpenClaw 配置(JSON5)',
1434
+ 'modal.openclaw.editorPlaceholder': '在這裡編輯 OpenClaw 配置(JSON5)',
1435
+ 'modal.openclaw.defaultConfigHint': '預設配置始終映射當前 openclaw.json,請直接使用「保存並應用」。',
1436
+ 'modal.openclaw.saveOnlyHint': '保存僅寫入本地配置庫。點擊「保存並應用」後會寫入 openclaw.json。',
1359
1437
  'openclaw.action.applyAria': '應用 OpenClaw 設定:{name}',
1360
1438
  'openclaw.action.editAria': '編輯 OpenClaw 設定:{name}',
1361
1439
  'openclaw.action.deleteAria': '刪除 OpenClaw 設定:{name}'