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:
1 parent
41b1cb1b25
commit
e08e1cfec4
39 files changed
+3164
-89
No files matched your search
@@ -117,6 +117,72 @@ const settings: Record<string, string> = {
|
||||
'settings.highlight.palette': 'Palette',
|
||||
'settings.highlight.note': 'Note',
|
||||
'settings.highlight.notePlaceholder': 'Rule description (optional)',
|
||||
'settings.highlight.caseInsensitive': 'Ignore case',
|
||||
'settings.highlight.caseInsensitiveHint': 'letters match in any case (OK also matches ok)',
|
||||
'settings.highlight.bands': 'Value bands',
|
||||
'settings.highlight.bandsHint':
|
||||
'Colour by the first number in the match; no number (or below the lowest band) keeps the foreground colour',
|
||||
'settings.highlight.bandMin': 'Min',
|
||||
'settings.highlight.addBand': '+ Add band',
|
||||
'settings.highlight.removeBand': 'Remove band',
|
||||
'settings.highlight.importExport': 'Import / export',
|
||||
'settings.highlight.importExportTitle': 'Import / export highlight rules',
|
||||
'settings.highlight.exportSection': 'Export — copy or save this JSON to share the set',
|
||||
'settings.highlight.copy': 'Copy',
|
||||
'settings.highlight.copied': 'Copied',
|
||||
'settings.highlight.download': 'Save as file',
|
||||
'settings.highlight.importSection': 'Import — paste JSON, or pick a .json file',
|
||||
'settings.highlight.chooseFile': 'Choose file',
|
||||
'settings.highlight.importMode': 'Mode',
|
||||
'settings.highlight.importReplace': 'Replace current rules',
|
||||
'settings.highlight.importAppend': 'Append to current rules',
|
||||
'settings.highlight.importOk': 'Import',
|
||||
'settings.highlight.importEmpty': 'No usable rules found',
|
||||
'settings.highlight.importBadJson': 'Not valid JSON',
|
||||
'settings.highlight.importWrongKind': 'This JSON is not a highlight-rule file',
|
||||
'settings.highlight.importSkipped': 'Skipped {n}: {list}',
|
||||
'settings.highlight.imported': 'Imported {n} rule(s)',
|
||||
'settings.highlight.testText': 'Test text',
|
||||
'settings.highlight.testHint': 'see the effect as you edit the pattern (first 2000 characters only)',
|
||||
'settings.highlight.mode': 'Highlighting',
|
||||
'settings.highlight.modeAll': 'All',
|
||||
'settings.highlight.modeBasic': 'Basic only',
|
||||
'settings.highlight.modeOff': 'Off',
|
||||
'settings.highlight.modeDesc':
|
||||
'Basic only: keeps just the key rules (errors, success, warnings, dangerous commands, secrets) — cheaper and quieter. Off: no colour injection at all (rules and colours are kept).',
|
||||
'settings.highlight.category': 'Category',
|
||||
'settings.highlight.groupByCategory': 'Group by category',
|
||||
'settings.highlight.category.safety': 'Safety',
|
||||
'settings.highlight.category.status': 'Status',
|
||||
'settings.highlight.category.file': 'Files',
|
||||
'settings.highlight.category.net': 'Network',
|
||||
'settings.highlight.category.text': 'Text',
|
||||
'settings.highlight.category.metric': 'Metrics',
|
||||
'settings.highlight.category.none': 'Uncategorised',
|
||||
'settings.highlight.stats': 'Count hits and time',
|
||||
'settings.highlight.statsHint':
|
||||
'Collect per-rule hit counts and durations for this page (zero cost while off)',
|
||||
'settings.highlight.statsHits': 'Hits',
|
||||
'settings.highlight.statsMs': 'Time',
|
||||
'settings.highlight.statsReset': 'Reset stats',
|
||||
'settings.highlight.statsEmpty': 'No stats yet — run some output in a terminal first',
|
||||
'settings.highlight.themeColors': 'Follow theme colours',
|
||||
'settings.highlight.themeColorsHint':
|
||||
'Map highlight colours onto the active terminal palette by hue (neutral greys are kept as-is)',
|
||||
'settings.highlight.perHost': 'Per-host rule sets',
|
||||
'settings.highlight.perHostHint':
|
||||
'When on, an SSH connection bound to a rule set runs only that subset; when off every session uses all rules',
|
||||
'settings.highlight.profiles': 'Host rule sets',
|
||||
'settings.highlight.profilesHint':
|
||||
'Save a subset of the rules under a name, then bind it to a host in the connection editor',
|
||||
'settings.highlight.profileNew': '+ New rule set',
|
||||
'settings.highlight.profileEdit': 'Edit rule set',
|
||||
'settings.highlight.profileName': 'Name',
|
||||
'settings.highlight.profileNamePlaceholder': 'e.g. production (errors only)',
|
||||
'settings.highlight.profileRules': 'Included rules',
|
||||
'settings.highlight.profileRulesHint': 'Unchecked rules stay off on that host',
|
||||
'settings.highlight.profileEmpty': 'No rule sets yet',
|
||||
'settings.highlight.profileDeleteTitle': 'Delete rule set',
|
||||
'settings.highlight.actions': 'Actions',
|
||||
'settings.highlight.addRule': '+ Add rule',
|
||||
'settings.highlight.empty': 'No highlight rules yet — click "+ Add rule" to create one',
|
||||
@@ -129,8 +195,18 @@ const settings: Record<string, string> = {
|
||||
'settings.highlight.builtin.perm': 'Linux permissions and user/group',
|
||||
'settings.highlight.builtin.path': 'Linux file paths',
|
||||
'settings.highlight.builtin.shellkw': 'Shell keywords and control flow',
|
||||
'settings.highlight.builtin.danger': 'Dangerous / destructive commands',
|
||||
'settings.highlight.builtin.secret': 'Possible secret / token',
|
||||
'settings.highlight.builtin.loglevel': 'Log levels',
|
||||
'settings.highlight.builtin.rootat': 'Root prompt (root@)',
|
||||
'settings.highlight.builtin.exitcode': 'Exit codes',
|
||||
'settings.highlight.builtin.http': 'HTTP status codes',
|
||||
'settings.highlight.builtin.latency': 'Durations (milliseconds)',
|
||||
'settings.highlight.builtin.delop': 'Delete / move / overwrite operations',
|
||||
'settings.highlight.builtin.createop': 'Create / add operations',
|
||||
'settings.highlight.builtin.okstate': 'Success states',
|
||||
'settings.highlight.builtin.badstate': 'Error/warning states',
|
||||
'settings.highlight.builtin.warnstate': 'Warnings and TODO markers',
|
||||
'settings.highlight.builtin.badstate': 'Error / failure states',
|
||||
'settings.highlight.builtin.quoted': 'Strings and quotes',
|
||||
'settings.highlight.builtin.envvar': 'Environment variables and arguments',
|
||||
'settings.highlight.builtin.ipv4': 'Network and IP addresses',
|
||||
|
||||
@@ -43,6 +43,8 @@ const ssh: Record<string, string> = {
|
||||
'ssh.dialog.keepalive': 'Keepalive interval (seconds)',
|
||||
'ssh.dialog.keepaliveTooltip': '0 disables keepalive',
|
||||
'ssh.dialog.keepaliveMin': 'Cannot be negative',
|
||||
'ssh.dialog.highlightProfile': 'Highlight rule set',
|
||||
'ssh.dialog.highlightProfileDefault': 'Default (all rules)',
|
||||
|
||||
// Connection sidebar
|
||||
'ssh.sidebar.defaultGroup': 'Default',
|
||||
|
||||
Reference in new issue
Block a user