Skip to content

feat(stream): custom replacements (0.7.1) - #113

Merged
HowmationFr merged 2 commits into
mainfrom
feat/custom-replacements
Oct 30, 2026
Merged

HowmationFr merged 2 commits into
mainfrom
feat/custom-replacements

Conversation

@HowmationFr

Copy link
Copy Markdown
Owner

What

New Stream Mode feature: Remplacements personnalisés. It works like "Mots-clés personnalisés", except the user picks the text shown instead of bullets. Each pair replaces every case-insensitive match of from with to, and to can be empty. Version bumped to 0.7.1.

It applies everywhere custom keywords already apply:

  • pages and subframes, including the fallback masker;
  • link previews and the browser UI;
  • the Go-Live preflight;
  • frame-guard activation.

How

  • maskText / hasAnyMask take the pairs as a new optional argument, customReplacements.
    • Replacements run first, on the raw text, so 192.168.1.10 → mon-serveur shows the chosen text and not the IP placeholder. A replacement that itself looks like an email or IP is still masked: the safe outcome wins.
    • Everything happens in one regex pass, so a replacement is never re-scanned (to may contain from).
    • The longest match wins at a given position, and the first pair wins on a duplicate from.
    • from is trimmed and needs at least 2 characters, as for keywords. Malformed entries are ignored, since settings and IPC patches are not validated.
  • The page and fallback maskers re-mask their own write from the original. Before, a masker re-masked whatever text it found. Bullets made that harmless, but a replacement containing its from would grow on every mutation (my-my-my-server). An edited or removed pair would also never reach nodes that were already rewritten.
  • sameMaskingConfig compares arrays by value, because the pairs are objects rebuilt on every settings load.
  • UI: a new card on voksa://stream (FR + EN). While Stream Mode is live, the from side is concealed and the to side stays readable. Re-adding the same from updates its pair.

Tests

  • npm run typecheck: OK.
  • npm run lint: 0 errors, 4 pre-existing warnings.
  • npx vitest run: 458/458 passed. New tests cover replacement behaviour and sameMaskingConfig value comparison.
  • npm run build: OK.
  • node scripts/smoke.mjs: OK on Windows. New scenario 6b, STREAM CUSTOM REPLACEMENTS:
    1. A live page shows the replacement.
    2. New content is replaced too.
    3. There is no self-feeding growth.
    4. Removing the pair restores the original text, with the IP still masked.

🤖 Generated with Claude Code

…ode (0.7.1)

Like custom keywords, but the user picks what is displayed instead of
bullets: each pair replaces every case-insensitive match of `from` with
`to` (possibly empty), in pages, subframes, link previews, the browser UI
and the Go-Live preflight.

- maskText/hasAnyMask take the pairs as a new optional argument. They run
  first, on the raw text, in one pass (a replacement is never re-scanned),
  longest match first; the built-in masks still apply to the result.
- The page and fallback maskers now re-mask their own write from the
  original: a replacement holding its `from` would otherwise grow on every
  mutation, and an edited list would never reach rewritten nodes.
- sameMaskingConfig compares arrays by value (pairs are objects).
- New "Remplacements personnalisés" card on voksa://stream (FR/EN), the
  `from` side concealed while Stream Mode is live.
- Unit tests and smoke scenario 6b (STREAM CUSTOM REPLACEMENTS).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@HowmationFr
HowmationFr enabled auto-merge October 30, 2026 08:26
This was the one call on the popup that was not retried, and it failed
once on macOS CI with "CDP socket closed (popup level 1)". Only CDP errors
are retried: a popup that is really gone still fails on the deadline, and
a call that landed before its socket closed is not repeated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@HowmationFr
HowmationFr merged commit 4f9f8bf into main Oct 30, 2026
5 checks passed
@HowmationFr
HowmationFr deleted the feat/custom-replacements branch October 30, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant