feat(highlight): preset overhaul, categories, stats, theme colours, per-host profiles

Rules & engine:
- 22 presets (was 11): split status into okstate/warnstate/badstate, add delop,
  createop, danger, secret, level, exitcode, percent, http; status words are
  case-insensitive and cover the ✓ ✔ ✅ ✗ ✘ ✖ ❌ ⚠ symbol set
- value bands: the first number in a match picks the colour
  (percent: <20% red / 20-50% yellow / 50-80% light green / >=80% green)
- optional per-rule `caseInsensitive`, `category`, `bands`; load-time
  `refreshBuiltinRules` upgrades untouched built-in patterns in place

Settings page:
- three-way master switch `highlightMode` (all / basic / off); `basic` runs only
  the five safety+status rules and `off` empties the rule set rather than
  bypassing HighlightStream (which would drop the held tail)
- category column + grouping (`highlightGroupByCategory`), per-rule hit/duration
  stats (`highlightStats`, opt-in sink, snapshot once a second), theme-following
  colours (`highlightThemeColors`, hue-bucket mapping onto the ANSI palette),
  import/export JSON envelope, live preview through the real engine
- named rule subsets bound per host (`highlightPerHost` + `highlightProfiles`
  + `SshConnection.highlightProfileId`); empty ruleIds = every rule

Tests: new tests/hl-rules.mjs (word boundaries, case flag, negative words,
bands, import/export, preview, basic mode, categories, stats, theme colours,
profiles) + profile round-trip in tests/settings-store.mjs
This commit is contained in:
Bill committed 2026-09-23 11:14:31 +08:00
1 parent 41b1cb1b25
commit e08e1cfec4
39 files changed
+3164 -89

No files matched your search

+71 -1
View File
@@ -111,6 +111,66 @@ const settings: Record<string, string> = {
'settings.highlight.palette': '色盤',
'settings.highlight.note': '備註',
'settings.highlight.notePlaceholder': '規則說明(選填)',
'settings.highlight.caseInsensitive': '忽略大小寫',
'settings.highlight.caseInsensitiveHint': '字母不區分大小寫(OK 也能匹配 ok)',
'settings.highlight.bands': '數值分級',
'settings.highlight.bandsHint': '依匹配到的第一個數字取色;沒有數字或低於最小分級時用前景色',
'settings.highlight.bandMin': '下限',
'settings.highlight.addBand': '+ 新增分級',
'settings.highlight.removeBand': '刪除分級',
'settings.highlight.importExport': '匯入 / 匯出',
'settings.highlight.importExportTitle': '匯入 / 匯出高亮規則',
'settings.highlight.exportSection': '匯出(複製或儲存下面的 JSON 分享給別人)',
'settings.highlight.copy': '複製',
'settings.highlight.copied': '已複製',
'settings.highlight.download': '儲存為檔案',
'settings.highlight.importSection': '匯入(貼上 JSON,或選擇 .json 檔案)',
'settings.highlight.chooseFile': '選擇檔案',
'settings.highlight.importMode': '匯入方式',
'settings.highlight.importReplace': '取代現有規則',
'settings.highlight.importAppend': '附加到現有規則',
'settings.highlight.importOk': '匯入',
'settings.highlight.importEmpty': '沒有解析到可用規則',
'settings.highlight.importBadJson': '不是有效的 JSON',
'settings.highlight.importWrongKind': '這份 JSON 不是高亮規則檔案',
'settings.highlight.importSkipped': '已略過 {n} 條:{list}',
'settings.highlight.imported': '已匯入 {n} 條規則',
'settings.highlight.testText': '測試文字',
'settings.highlight.testHint': '改完正規表示式立刻看到效果(僅預覽前 2000 字元)',
'settings.highlight.mode': '高亮模式',
'settings.highlight.modeAll': '全部',
'settings.highlight.modeBasic': '僅基礎',
'settings.highlight.modeOff': '關閉',
'settings.highlight.modeDesc': '僅基礎:只保留錯誤/成功/警告/危險命令/密鑰等關鍵規則,開銷更小;關閉:完全不注入顏色(規則與顏色都保留)',
'settings.highlight.category': '分類',
'settings.highlight.groupByCategory': '依分類分組',
'settings.highlight.category.safety': '安全',
'settings.highlight.category.status': '狀態',
'settings.highlight.category.file': '檔案',
'settings.highlight.category.net': '網路',
'settings.highlight.category.text': '文字',
'settings.highlight.category.metric': '數值',
'settings.highlight.category.none': '未分類',
'settings.highlight.stats': '統計命中與耗時',
'settings.highlight.statsHint': '開啟後統計每條規則的命中次數與耗時(設定頁顯示,關閉時零開銷)',
'settings.highlight.statsHits': '命中',
'settings.highlight.statsMs': '耗時',
'settings.highlight.statsReset': '重設統計',
'settings.highlight.statsEmpty': '還沒有統計資料,先去終端機跑點輸出',
'settings.highlight.themeColors': '跟隨主題配色',
'settings.highlight.themeColorsHint': '依色相把高亮顏色對應到目前終端機主題的調色盤(灰階色保持原樣)',
'settings.highlight.perHost': '依主機規則集',
'settings.highlight.perHostHint': '開啟後,綁定了規則集的 SSH 連線只跑該子集;關閉時所有工作階段都用全部規則',
'settings.highlight.profiles': '主機規則集',
'settings.highlight.profilesHint': '把規則的子集存成命名規則集,在「編輯連線」裡綁定給某台主機',
'settings.highlight.profileNew': '+ 新增規則集',
'settings.highlight.profileEdit': '編輯規則集',
'settings.highlight.profileName': '名稱',
'settings.highlight.profileNamePlaceholder': '例如:正式機(只看錯誤)',
'settings.highlight.profileRules': '包含的規則',
'settings.highlight.profileRulesHint': '未勾選的規則在這台主機上不生效',
'settings.highlight.profileEmpty': '尚未建立規則集',
'settings.highlight.profileDeleteTitle': '刪除規則集',
'settings.highlight.actions': '操作',
'settings.highlight.addRule': '+ 新增規則',
'settings.highlight.empty': '尚無高亮規則,點擊「+ 新增規則」建立',
@@ -123,8 +183,18 @@ const settings: Record<string, string> = {
'settings.highlight.builtin.perm': 'Linux 權限與使用者',
'settings.highlight.builtin.path': 'Linux 檔案路徑',
'settings.highlight.builtin.shellkw': 'Shell 關鍵字與流程',
'settings.highlight.builtin.danger': '危險/破壞性命令',
'settings.highlight.builtin.secret': '疑似密鑰/權杖',
'settings.highlight.builtin.loglevel': '日誌等級',
'settings.highlight.builtin.rootat': '管理員提示字元 root@',
'settings.highlight.builtin.exitcode': '結束碼',
'settings.highlight.builtin.http': 'HTTP 狀態碼',
'settings.highlight.builtin.latency': '耗時(毫秒)',
'settings.highlight.builtin.delop': '刪除/移動/覆蓋操作',
'settings.highlight.builtin.createop': '新建/建立操作',
'settings.highlight.builtin.okstate': '成功狀態',
'settings.highlight.builtin.badstate': '錯誤/警告狀態',
'settings.highlight.builtin.warnstate': '警告與待辦標記',
'settings.highlight.builtin.badstate': '錯誤/失敗狀態',
'settings.highlight.builtin.quoted': '字串與引號',
'settings.highlight.builtin.envvar': '環境變數與參數',
'settings.highlight.builtin.ipv4': '網路與 IP 位址',
+2
View File
@@ -41,6 +41,8 @@ const ssh: Record<string, string> = {
'ssh.dialog.keepalive': 'Keepalive 間隔(秒)',
'ssh.dialog.keepaliveTooltip': '0 表示關閉 keepalive',
'ssh.dialog.keepaliveMin': '不能為負數',
'ssh.dialog.highlightProfile': '高亮規則集',
'ssh.dialog.highlightProfileDefault': '預設(全部規則)',
// 連線側欄
'ssh.sidebar.defaultGroup': '預設',