Files
chatwoot/package.json
Sivin Varghese 720ef3f6e9 fix: stray backslash and vanishing signature separator in replies (#15639)
# Pull Request Template

## Description

This PR fixes stray `\` characters and missing `--` signature separators
when replies contain empty lines above the email signature. Empty lines
and Shift+Enter line breaks are now preserved as composed across
delivered emails, dashboard bubbles, text channels, and webhook
payloads.

### https://github.com/chatwoot/prosemirror-schema/pull/59

### What changed

* Bump `@chatwoot/prosemirror-schema` to 1.4.5, which fixes markdown
serialization of empty lines, hard breaks, and setext underline escaping
at the source.
* Strip the escaped signature delimiter cleanly when toggling or
removing the signature, so it never leaves a trailing `\`.
* Unescape the serializer's underline escape (`\--` → `--`) in
`WebhookContentNormalizer`, so API-channel and webhook consumers receive
the original text.
* Add end-to-end rendering specs covering every editor output shape with
23 byte-exact fixtures across cmark, both email modes, and all channel
renderers.

Fixes
https://linear.app/chatwoot/issue/CW-8062/email-replies-show-a-stray-backslash-instead-of-the-signature

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

### How to reproduce

On an email inbox with a message signature enabled, type a reply and
press Enter at the end, leaving an empty line above the `--` separator,
then send. The delivered email and email bubble show a stray `\` where
the empty line should be, and the `--` separator disappears.

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
2026-09-08 15:03:45 +05:30

182 lines
5.6 KiB
JSON

{
"name": "@chatwoot/chatwoot",
"version": "4.17.1",
"license": "MIT",
"scripts": {
"eslint": "eslint app/**/*.{js,vue}",
"eslint:fix": "eslint app/**/*.{js,vue} --fix",
"test": "TZ=UTC vitest --no-watch --no-cache --no-coverage --logHeapUsage",
"test:watch": "TZ=UTC vitest --no-cache --no-coverage",
"test:coverage": "TZ=UTC vitest --no-watch --no-cache --coverage",
"start:dev": "foreman start -f ./Procfile.dev",
"start:test": "RAILS_ENV=test foreman start -f ./Procfile.test",
"dev": "overmind start -f ./Procfile.dev",
"ruby:prettier": "bundle exec rubocop -a",
"build:sdk": "vite build --config vite.lib.config.ts",
"analyze:bundles": "pnpm analyze:bundle:sdk && pnpm analyze:bundle:widget",
"analyze:bundle:sdk": "vite build --config vite.sdk.analyze.config.mts",
"analyze:bundle:widget": "vite build --config vite.widget.analyze.config.mts",
"prepare": "husky install",
"size": "size-limit",
"story:dev": "histoire dev",
"story:build": "histoire build",
"story:preview": "histoire preview",
"sync:i18n": "bin/sync_i18n_file_change"
},
"size-limit": [
{
"path": "public/vite/assets/widget-*.js",
"limit": "300 KB"
},
{
"path": "public/packs/js/sdk.js",
"limit": "40 KB"
}
],
"dependencies": {
"@amplitude/analytics-browser": "^2.11.10",
"@breezystack/lamejs": "^1.2.7",
"@chatwoot/ninja-keys": "1.2.3",
"@chatwoot/prosemirror-schema": "1.4.5",
"@chatwoot/utils": "^0.0.57",
"@chatwoot/viz": "^0.1.5",
"@formkit/core": "^1.7.2",
"@formkit/vue": "^1.7.2",
"@hcaptcha/vue3-hcaptcha": "^1.3.0",
"@highlightjs/vue-plugin": "^2.1.0",
"@hotwired/turbo-rails": "^8.0.13",
"@iconify-json/fluent": "^1.2.32",
"@iconify-json/material-symbols": "^1.2.10",
"@lk77/vue3-color": "^3.0.6",
"@radix-ui/colors": "^3.0.0",
"@rails/actioncable": "6.1.3",
"@rails/ujs": "^7.1.400",
"@chatwoot/pico-search": "0.6.2",
"@sentry/vue": "^8.55.0",
"@sindresorhus/slugify": "2.2.1",
"@tailwindcss/typography": "^0.5.19",
"@tanstack/vue-table": "^8.20.5",
"@twilio/voice-sdk": "^2.12.4",
"@vitejs/plugin-vue": "^5.2.4",
"@vue/compiler-sfc": "^3.5.8",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.4",
"@vueuse/components": "^12.0.0",
"@vueuse/core": "^12.0.0",
"activestorage": "^5.2.6",
"axios": "^1.15.0",
"camelcase-keys": "^9.1.3",
"color2k": "^2.0.2",
"company-email-validator": "^1.1.0",
"core-js": "3.38.1",
"countries-and-timezones": "^3.6.0",
"date-fns": "2.21.1",
"date-fns-tz": "^1.3.3",
"dompurify": "3.4.13",
"flag-icons": "^7.2.3",
"floating-vue": "^5.2.2",
"highlight.js": "^11.10.0",
"html-to-image": "^1.11.13",
"html2canvas": "^1.4.1",
"idb": "^8.0.0",
"js-cookie": "^3.0.5",
"json-logic-js": "^2.0.5",
"lettersanitizer": "^1.0.8",
"libphonenumber-js": "^1.11.9",
"markdown-it": "^14.1.1",
"markdown-it-link-attributes": "^4.0.1",
"mitt": "^3.0.1",
"opus-recorder": "^8.0.5",
"pinia": "^3.0.4",
"qrcode": "^1.5.4",
"semver": "7.6.3",
"snakecase-keys": "^8.0.1",
"timezone-phone-codes": "^0.0.2",
"tinykeys": "^3.0.0",
"urlpattern-polyfill": "^10.0.0",
"video.js": "7.21.1",
"videojs-record": "4.5.0",
"videojs-wavesurfer": "3.8.0",
"virtua": "^0.48.6",
"vue": "^3.5.12",
"vue-datepicker-next": "^1.0.3",
"vue-dompurify-html": "^5.3.0",
"vue-i18n": "9.14.5",
"vue-letter": "^0.2.2",
"vue-router": "~4.4.5",
"vue-upload-component": "^3.1.17",
"vue3-click-away": "^1.2.4",
"vuedraggable": "^4.1.0",
"vuex": "~4.1.0",
"vuex-router-sync": "6.0.0-rc.1",
"wavesurfer.js": "7.8.6"
},
"devDependencies": {
"@egoist/tailwindcss-icons": "^1.9.2",
"@histoire/plugin-vue": "0.17.15",
"@iconify-json/logos": "^1.2.10",
"@iconify-json/lucide": "^1.2.82",
"@iconify-json/ph": "^1.2.2",
"@iconify-json/ri": "^1.2.6",
"@iconify-json/teenyicons": "^1.2.2",
"@intlify/eslint-plugin-vue-i18n": "^3.2.0",
"@rollup/plugin-yaml": "^4.1.2",
"@size-limit/file": "^8.2.4",
"@vitest/coverage-v8": "3.0.5",
"@vue/test-utils": "^2.4.6",
"autoprefixer": "^10.4.20",
"eslint": "^8.57.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-interactive": "^11.1.0",
"eslint-plugin-html": "7.1.0",
"eslint-plugin-import": "2.30.0",
"eslint-plugin-prettier": "5.2.1",
"eslint-plugin-vitest-globals": "^1.5.0",
"eslint-plugin-vue": "^9.28.0",
"fake-indexeddb": "^6.0.0",
"histoire": "0.17.15",
"husky": "^7.0.0",
"jsdom": "^27.2.0",
"lint-staged": "^16.2.7",
"postcss": "^8.5.23",
"postcss-preset-env": "^8.5.1",
"prettier": "^3.3.3",
"prosemirror-model": "^1.22.3",
"rollup-plugin-visualizer": "7.0.1",
"size-limit": "^8.2.4",
"tailwindcss": "^3.4.19",
"vite": "6.4.2",
"vite-plugin-ruby": "^5.2.1",
"vitest": "3.0.5"
},
"engines": {
"node": "24.x",
"pnpm": "10.x"
},
"husky": {
"hooks": {
"pre-push": "sh bin/validate_push"
}
},
"pnpm": {
"overrides": {
"vite": "6.4.2",
"vitest": "3.0.5",
"minimatch@<4": "3.1.5",
"minimatch@>=9.0.0 <9.0.7": "9.0.9",
"rollup": ">=4.59.0"
}
},
"lint-staged": {
"app/**/*.{js,vue}": [
"eslint --fix",
"git add"
],
"*.scss": [
"scss-lint"
]
},
"packageManager": "pnpm@10.2.0+sha512.0d27364e0139c6aadeed65ada153135e0ca96c8da42123bd50047f961339dc7a758fc2e944b428f52be570d1bd3372455c1c65fa2e7aa0bfbf931190f9552001"
}