Skip to content

fix(twitch): preserve intraword underscores in outbound text#108548

Merged
steipete merged 9 commits into
openclaw:mainfrom
VectorPeak:fix/twitch-intraword-underscores
Jul 16, 2026
Merged

fix(twitch): preserve intraword underscores in outbound text#108548
steipete merged 9 commits into
openclaw:mainfrom
VectorPeak:fix/twitch-intraword-underscores

Conversation

@VectorPeak

@VectorPeak VectorPeak commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where Twitch users could receive altered outbound text when an identifier, filename, or URL contained single underscores inside a word. The Markdown stripping step interpreted pairs such as _bar_ in foo_bar_baz as emphasis, so the delivered text became foobarbaz; https://cdn.example/my_file_name.png became https://cdn.example/myfilename.png.

This is reachable before the Twitch transport is called:

message, media URL, or assistant reply
-> Twitch outbound chunker / direct send / monitor reply
-> stripMarkdownForTwitch()
-> Twitch client transport

Why This Change Was Made

The Twitch-local Markdown stripper now recognizes single-underscore emphasis only when the markers are not adjacent to Unicode letters, numbers, or combining marks. It retains the previous underscore-free capture behavior so standalone emphasis can still span input lines before Twitch's existing newline normalization runs.

The change stays inside the Twitch helper. Double underscores continue to follow the existing bold-markup path; changing that behavior is outside this PR. Shared Markdown parsing, Twitch authentication, message transport, and chunk-size behavior are unchanged.

User Impact

Twitch chat messages can now carry single-underscore identifiers and URL paths such as foo_bar_baz and my_file_name.png without silently losing underscores. Standalone _italic_, multiline underscore emphasis, and existing __bold__ markup are still converted to plain text.

Evidence

Actual pre-transport behavior on main versus this branch:

input:  foo_bar_baz
before: foobarbaz
after:  foo_bar_baz

input:  https://cdn.example/my_file_name.png
before: https://cdn.example/myfilename.png
after:  https://cdn.example/my_file_name.png

The exported Twitch chunker also preserves the adjacent behaviors that bound this fix:

_line one\nline two_ -> line one line two
e\u0301_mail_.txt    -> e\u0301_mail_.txt
_italic_             -> italic

The focused regression test covers ASCII, URL paths, Cyrillic, CJK, NFD combining marks, multiline emphasis, and unchanged standalone italic/bold behavior. Validation on Node v24.15.0 and pnpm 11.2.2:

  • node scripts/run-vitest.mjs run extensions/twitch/src/utils/markdown.test.ts - 1 file, 8/8 tests passed
  • pnpm exec vitest run --config test/vitest/vitest.extension-messaging.config.ts extensions/twitch - 19 files, 203/203 tests passed
  • pnpm exec oxlint extensions/twitch/src/utils/markdown.ts extensions/twitch/src/utils/markdown.test.ts - passed
  • pnpm exec oxfmt --check extensions/twitch/src/utils/markdown.ts extensions/twitch/src/utils/markdown.test.ts - passed
  • git diff --check - passed

Local limitation: the pnpm test:extension twitch wrapper previously did not complete within the Windows command timeout. Its resolved Vitest command is listed above and passed all Twitch tests. codex review --base upstream/main was also attempted, but the local codex.exe could not start because Windows returned Access is denied.

AI-assisted: this patch and its tests were prepared with Codex. The author reviewed the production change, caller paths, edge-case probes, diff, and validation output.

@openclaw-barnacle openclaw-barnacle Bot added channel: twitch Channel integration: twitch size: XS labels Jul 16, 2026
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
@VectorPeak
VectorPeak force-pushed the fix/twitch-intraword-underscores branch from 44957e8 to 12cb70a Compare July 16, 2026 01:38
@steipete steipete self-assigned this Jul 16, 2026
@clawsweeper

clawsweeper Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 16, 2026, 1:21 AM ET / 05:21 UTC.

Summary
The PR tightens Twitch’s single-underscore Markdown stripping and adds regression coverage for identifiers, URLs, Unicode text, combining marks, multiline emphasis, italic, and bold text.

PR surface: Source 0, Tests +20. Total +20 across 2 files.

Reproducibility: yes. Current main’s formatter and production caller establish the failing path, and the PR provides direct before/after production-chunker output for intraword identifiers and URL paths.

Review metrics: none identified.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • No automated repair is needed; the proposed patch is correct and should proceed through ordinary maintainer review and merge gating.

Security
Cleared: The diff changes one local text-normalization expression and tests, with no dependency, credential, permission, workflow, artifact, or supply-chain surface added.

Review details

Best possible solution:

Land the Twitch-local Unicode-boundary fix with its focused regression tests, keeping shared Markdown parsing, configuration, transport, and double-underscore behavior unchanged.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main’s formatter and production caller establish the failing path, and the PR provides direct before/after production-chunker output for intraword identifiers and URL paths.

Is this the best way to solve the issue?

Yes. Tightening the existing Twitch-local emphasis boundary is the narrowest maintainable fix and avoids introducing shared-parser, transport, configuration, or compatibility surface.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8c95491039db.

Label changes

Label changes:

  • add P2: This fixes silent outbound text corruption in one bundled channel with limited blast radius and strong focused coverage.
  • add proof: sufficient: Contributor real behavior proof is sufficient. Copied before/after output from the actual production Twitch chunker demonstrates the corrected pre-transport behavior, and the changed pure formatter is exercised without mocks.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🦞 diamond lobster.

Label justifications:

  • P2: This fixes silent outbound text corruption in one bundled channel with limited blast radius and strong focused coverage.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🦞 diamond lobster.
  • proof: sufficient: Contributor real behavior proof is sufficient. Copied before/after output from the actual production Twitch chunker demonstrates the corrected pre-transport behavior, and the changed pure formatter is exercised without mocks.
Evidence reviewed

PR surface:

Source 0, Tests +20. Total +20 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 1 1 0
Tests 1 20 0 +20
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 21 1 +20

What I checked:

Likely related people:

What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-07-16T03:55:33.704Z sha 9e92063 :: needs maintainer review before merge. :: none

@steipete
steipete merged commit eb31350 into openclaw:main Jul 16, 2026
76 of 82 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 17, 2026
…w#108548)

* fix(twitch): preserve intraword underscores

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

* fix(twitch): tighten underscore emphasis boundaries

Preserve multiline emphasis stripping and combining-mark identifiers.

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

---------

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: twitch Channel integration: twitch size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants