hermes-agent/plugins
briandevans 8e6d1a9a53 fix(slack): stop double-decoding HTML entities when escaping message text
format_message unescapes already-escaped input before re-escaping, so that
pre-escaped text doesn't get double-escaped. That unescape was three
sequential str.replace calls, which re-scan each other's output:

    "&amp;lt;"  --(&amp; -> &)-->  "&lt;"  --(&lt; -> <)-->  "<"

The & produced by the first replace pairs with the following "lt;" and
decodes a second time. "&amp;lt;" is the wire form of the literal text
"&lt;", so the text is silently destroyed: Slack receives "&lt;" and renders
"<". Anyone writing about HTML or markup ("&amp;lt;b&amp;gt;" -> "<b>")
loses their literal text, with no error.

re.sub scans left-to-right and never re-scans its own replacements, so a
single pass fixes it. The escape pass on the next line is left untouched --
it is correctly ordered (& first, so the &s it inserts aren't re-escaped).

Only the double-decode cases change; every other input is byte-identical
before and after. This is the same round-trip invariant the neighbouring
test_pre_escaped_{ampersand,lt,gt}_not_double_escaped tests already assert,
extended to the case they miss. Affects the plain mrkdwn path (send,
edit_message) and Block Kit sections, which route section text through
format_message.
2026-07-23 11:50:28 -07:00
..
browser fix: guard int(os.getenv()) casts against malformed env vars (#40598) 2026-06-07 06:14:24 -07:00
context_engine feat(context-engine): host contract for external context engines 2026-05-28 01:45:30 -07:00
cron_providers fix(cron): harden execution attempt ledger 2026-07-17 04:58:35 -07:00
dashboard_auth feat(dashboard_auth): support confidential clients (client_secret) in self-hosted OIDC (#55344) 2026-06-30 13:32:51 +10:00
disk-cleanup docs(disk-cleanup): clarify cron output-root protection is exact-match 2026-07-01 15:42:04 +05:30
google_meet refactor(setup): route dependency installs through the canonical uv→pip→ensurepip ladder 2026-07-07 04:09:35 -07:00
hermes-achievements fix(achievements): stop card hover click loop 2026-07-16 04:34:57 -07:00
image_gen fix(deepinfra): harden multimodal provider routing 2026-07-14 02:59:39 +05:30
kanban feat(kanban): per-task model dropdown — set/override worker model+provider from the board (#69876) 2026-07-22 22:23:24 -07:00
memory fix(memory): preserve genuine pre-delimiter content in merged compaction rows 2026-07-22 06:59:14 -07:00
model-providers feat(nous): send top-level session_id for provider sticky routing (#69253) 2026-07-22 04:39:20 -07:00
observability fix(nemo-relay): align dynamic plugin configuration 2026-07-13 17:01:08 -06:00
platforms fix(slack): stop double-decoding HTML entities when escaping message text 2026-07-23 11:50:28 -07:00
security-guidance plugins: add security-guidance — pattern-matched warnings on dangerous code writes (#33131) 2026-05-27 02:07:21 -07:00
spotify chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
teams_pipeline fix(teams-pipeline): reject dot-only recording display_name 2026-07-01 02:03:48 -07:00
video_gen fix(video-gen): omit duration for range-based FAL families when unspecified 2026-07-16 04:24:10 -07:00
web fix: sanitize subprocess env for DDGS worker 2026-07-21 11:51:01 +05:30
__init__.py feat(memory): pluggable memory provider interface with profile isolation, review fixes, and honcho CLI restoration (#4623) 2026-04-02 15:33:51 -07:00
plugin_utils.py fix(plugins): thread-safe lazy-singleton helpers; fix honcho TOCTOU (#24759) (#42150) 2026-06-08 09:35:22 -07:00