{"_id":"@daviddh/llm-markdown-whatsapp","_rev":"6-01be61b6ffeb39cc48533512bfb5411f","name":"@daviddh/llm-markdown-whatsapp","dist-tags":{"latest":"0.0.6"},"versions":{"0.0.1":{"name":"@daviddh/llm-markdown-whatsapp","version":"0.0.1","keywords":["llm","whatsapp","markdown","formatter","styling","utils","strs","strings","converter","transformer"],"author":{"name":"David Dominguez"},"license":"MIT","_id":"@daviddh/llm-markdown-whatsapp@0.0.1","maintainers":[{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"}],"homepage":"https://github.com/daviddominguezh/llm-markdown-whatsapp#readme","bugs":{"url":"https://github.com/daviddominguezh/llm-markdown-whatsapp/issues"},"dist":{"shasum":"73232ae733fe2b7dd233219002e7d3ed57362500","tarball":"https://registry.npmjs.org/@daviddh/llm-markdown-whatsapp/-/llm-markdown-whatsapp-0.0.1.tgz","fileCount":138,"integrity":"sha512-qD8FH80CPcBOjSKmYt9pCFSf76WzbSuG69AMIBVs2jmU/jEUMaYwuzEUJLn75PyQhNkdYSNZCuZ7t57MpVJSWg==","signatures":[{"sig":"MEUCIQDB1TeKlTjkJxt4an299PCf7+Z7czNXDSiLjrmwFhFXRAIgY95H9ZCEBPXY0WTFxraaw5q3DMlZgoEYIK6w6fyJO8c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":419210},"main":"packages/core/dist/index.js","type":"module","types":"./packages/core/dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"0185a36494f3ea19d9da6ceb60cc6586d51c86a0","private":false,"scripts":{"lint":"eslint .","test":"npm run test --workspaces --if-present","build":"npm run build --workspaces","check":"npm run format && npm run lint && npm run typecheck","format":"prettier --write \"**/*.{js,ts,json}\"","test:core":"npm run test -w @llm-markdown-whatsapp/core","typecheck":"tsc -b","build:core":"npm run build -w @llm-markdown-whatsapp/core"},"_npmUser":{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"},"repository":{"url":"git+https://github.com/daviddominguezh/llm-markdown-whatsapp.git","type":"git"},"workspaces":["packages/*"],"_npmVersion":"11.6.2","description":"Transforms Markdown into WhatsApp text format monorepo","directories":{},"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","jest":"^30.0.5","eslint":"^9.28.0","globals":"^16.2.0","ts-jest":"^29.4.4","prettier":"^3.8.1","tsc-alias":"^1.8.10","@eslint/js":"^9.28.0","typescript":"^5.8.3","@types/jest":"^30.0.0","typescript-eslint":"^8.33.1","eslint-config-love":"^144.0.0","@trivago/prettier-plugin-sort-imports":"^5.2.2"},"_npmOperationalInternal":{"tmp":"tmp/llm-markdown-whatsapp_0.0.1_1770397679294_0.68429868870139","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@daviddh/llm-markdown-whatsapp","version":"0.0.2","keywords":["llm","whatsapp","markdown","chat","split","chunking","formatter","converter","transformer"],"author":{"name":"David Dominguez"},"license":"MIT","_id":"@daviddh/llm-markdown-whatsapp@0.0.2","maintainers":[{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"}],"homepage":"https://github.com/daviddominguezh/llm-markdown-whatsapp#readme","bugs":{"url":"https://github.com/daviddominguezh/llm-markdown-whatsapp/issues"},"dist":{"shasum":"b30476440948aee1e0b0c54162c895955b4037a0","tarball":"https://registry.npmjs.org/@daviddh/llm-markdown-whatsapp/-/llm-markdown-whatsapp-0.0.2.tgz","fileCount":41,"integrity":"sha512-NmO7rfU0/j+zm0yHGVhOc/oPU6jXujdngR6SnYoi8cOZG1s/0ZXikLdiRryw5rLcApk1Vx+kjWdTHBkB6NJ20A==","signatures":[{"sig":"MEUCIFv2WSkPmS68sNyui72x6DZ6gqmGrqkq5VHv5EZiHKMvAiEA9HtNteXw1AO5FkB53D9sgjG8YbSrNHSt6NATrijbVwU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94875},"main":"packages/core/dist/index.js","type":"module","types":"packages/core/dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"},"./core":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"}},"gitHead":"7af5529433bd0e3531d9f4b6c4f1d9c890e95e12","private":false,"scripts":{"lint":"eslint .","test":"npm run test --workspaces --if-present","build":"npm run build --workspaces","check":"npm run format && npm run lint && npm run typecheck","format":"prettier --write \"**/*.{js,ts,json}\"","test:core":"npm run test -w @llm-markdown-whatsapp/core","typecheck":"tsc -b","build:core":"npm run build -w @llm-markdown-whatsapp/core"},"_npmUser":{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"},"repository":{"url":"git+https://github.com/daviddominguezh/llm-markdown-whatsapp.git","type":"git"},"workspaces":["packages/*"],"_npmVersion":"11.6.2","description":"Transforms Markdown into WhatsApp text format","directories":{},"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","jest":"^30.0.5","eslint":"^9.28.0","globals":"^16.2.0","ts-jest":"^29.4.4","prettier":"^3.8.1","tsc-alias":"^1.8.10","@eslint/js":"^9.28.0","typescript":"^5.8.3","@types/jest":"^30.0.0","typescript-eslint":"^8.33.1","eslint-config-love":"^144.0.0","@trivago/prettier-plugin-sort-imports":"^5.2.2"},"_npmOperationalInternal":{"tmp":"tmp/llm-markdown-whatsapp_0.0.2_1770403149314_0.26962544803885","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@daviddh/llm-markdown-whatsapp","version":"0.0.3","keywords":["llm","whatsapp","markdown","chat","split","chunking","formatter","converter","transformer"],"author":{"name":"David Dominguez"},"license":"MIT","_id":"@daviddh/llm-markdown-whatsapp@0.0.3","maintainers":[{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"}],"homepage":"https://github.com/daviddominguezh/llm-markdown-whatsapp#readme","bugs":{"url":"https://github.com/daviddominguezh/llm-markdown-whatsapp/issues"},"dist":{"shasum":"28cc5c37d0f2cebd429fb93cd9f512243c7cffdd","tarball":"https://registry.npmjs.org/@daviddh/llm-markdown-whatsapp/-/llm-markdown-whatsapp-0.0.3.tgz","fileCount":41,"integrity":"sha512-J9viz+WeUUWe9Lr425LpkP7ihJETnxeMRgvtew+l3FjXLa7Gdt0YCG/L6pXr+OCLYW0QQJ2NT29b1eWqTLzzhg==","signatures":[{"sig":"MEUCIQDeZ7/6z+g8pRbfmfpq7hpAx2FSnZYeawIjBxcfnKfiRwIgFe+g7tRuhigqZfTARbmhhrKP5L1hFSN2g5qLXOSZf68=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94915},"main":"packages/core/dist/index.js","type":"module","types":"packages/core/dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"},"./core":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"}},"gitHead":"9613b0387f9f55bb3b2133472e89dc8887571d56","private":false,"scripts":{"lint":"eslint .","test":"npm run test --workspaces --if-present","build":"npm run build --workspaces","check":"npm run format && npm run lint && npm run typecheck","format":"prettier --write \"**/*.{js,ts,json}\"","test:core":"npm run test -w @daviddh/llm-markdown-whatsapp/core","typecheck":"tsc -b","build:core":"npm run build -w @daviddh/llm-markdown-whatsapp/core"},"_npmUser":{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"},"repository":{"url":"git+https://github.com/daviddominguezh/llm-markdown-whatsapp.git","type":"git"},"workspaces":["packages/*"],"_npmVersion":"11.6.2","description":"Transforms Markdown into WhatsApp text format","directories":{},"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","jest":"^30.0.5","eslint":"^9.28.0","globals":"^16.2.0","ts-jest":"^29.4.4","prettier":"^3.8.1","tsc-alias":"^1.8.10","@eslint/js":"^9.28.0","typescript":"^5.8.3","@types/jest":"^30.0.0","typescript-eslint":"^8.33.1","eslint-config-love":"^144.0.0","@trivago/prettier-plugin-sort-imports":"^5.2.2"},"_npmOperationalInternal":{"tmp":"tmp/llm-markdown-whatsapp_0.0.3_1770403838294_0.1984786935676135","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@daviddh/llm-markdown-whatsapp","version":"0.0.4","keywords":["llm","whatsapp","markdown","chat","split","chunking","formatter","converter","transformer"],"author":{"name":"David Dominguez"},"license":"MIT","_id":"@daviddh/llm-markdown-whatsapp@0.0.4","maintainers":[{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"}],"homepage":"https://github.com/daviddominguezh/llm-markdown-whatsapp#readme","bugs":{"url":"https://github.com/daviddominguezh/llm-markdown-whatsapp/issues"},"dist":{"shasum":"9c3809e1d0559e2a488a4293dcda2aabb1b5a585","tarball":"https://registry.npmjs.org/@daviddh/llm-markdown-whatsapp/-/llm-markdown-whatsapp-0.0.4.tgz","fileCount":41,"integrity":"sha512-PYS+RIlnVOnfRvznAjPuWs/2W/WxD04MI8cwLNLph2tI/Gy7AlbeFhwDZEBTe4TWhKtlV3p5HgMcQGYGw2jrrA==","signatures":[{"sig":"MEQCIH924hjmt8RUfwe2GYG+MsJW44iuS83JokEyskH2CJ6OAiAR2bb7CjSqQFX6MorOXN7fFFUzYP913abIRXpgpCpd5A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":95572},"main":"packages/core/dist/index.js","type":"module","types":"packages/core/dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"},"./core":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"}},"gitHead":"ac02ba86be101b003d0071da9a5950ab0c276656","private":false,"scripts":{"lint":"eslint .","test":"npm run test --workspaces --if-present","build":"npm run build --workspaces","check":"npm run format && npm run lint && npm run typecheck","format":"prettier --write \"**/*.{js,ts,json}\"","test:core":"npm run test -w @daviddh/llm-markdown-whatsapp/core","typecheck":"tsc -b","build:core":"npm run build -w @daviddh/llm-markdown-whatsapp/core"},"_npmUser":{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"},"repository":{"url":"git+https://github.com/daviddominguezh/llm-markdown-whatsapp.git","type":"git"},"workspaces":["packages/*"],"_npmVersion":"11.6.2","description":"Transforms Markdown into WhatsApp text format","directories":{},"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","jest":"^30.0.5","eslint":"^9.28.0","globals":"^16.2.0","ts-jest":"^29.4.4","prettier":"^3.8.1","tsc-alias":"^1.8.10","@eslint/js":"^9.28.0","typescript":"^5.8.3","@types/jest":"^30.0.0","typescript-eslint":"^8.33.1","eslint-config-love":"^144.0.0","@trivago/prettier-plugin-sort-imports":"^5.2.2"},"_npmOperationalInternal":{"tmp":"tmp/llm-markdown-whatsapp_0.0.4_1770650983756_0.7066604124492326","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@daviddh/llm-markdown-whatsapp","version":"0.0.5","keywords":["llm","whatsapp","markdown","chat","split","chunking","formatter","converter","transformer"],"author":{"name":"David Dominguez"},"license":"MIT","_id":"@daviddh/llm-markdown-whatsapp@0.0.5","maintainers":[{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"}],"homepage":"https://github.com/daviddominguezh/llm-markdown-whatsapp#readme","bugs":{"url":"https://github.com/daviddominguezh/llm-markdown-whatsapp/issues"},"dist":{"shasum":"42a79800e1c953932c3a09d4dfb96a68f6d3f4e5","tarball":"https://registry.npmjs.org/@daviddh/llm-markdown-whatsapp/-/llm-markdown-whatsapp-0.0.5.tgz","fileCount":47,"integrity":"sha512-QtmHqYTKhGR0jcbZbdGaN7fpcPz81glIR9VDQyh076XyKLheWWVz+gzh2s9sPpWmnhIwIGqjvr5Ytsf7rITWGA==","signatures":[{"sig":"MEYCIQC+fQIimMwkzTPousHAZUXi8xP01MYI5L8Fn+rowG4cPAIhAJhDvMpAbMKu+4NIvkZSqGp5IC/v0qJ6EP5I/jjx1AOA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108421},"main":"packages/core/dist/index.js","type":"module","types":"packages/core/dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"},"./core":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"}},"gitHead":"cd76255c0c4983810f98f963456db71c10573925","private":false,"scripts":{"lint":"eslint .","test":"npm run test --workspaces --if-present","build":"npm run build --workspaces","check":"npm run format && npm run lint && npm run typecheck","format":"prettier --write \"**/*.{js,ts,json}\"","test:core":"npm run test -w @daviddh/llm-markdown-whatsapp/core","typecheck":"tsc -b","build:core":"npm run build -w @daviddh/llm-markdown-whatsapp/core"},"_npmUser":{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"},"repository":{"url":"git+https://github.com/daviddominguezh/llm-markdown-whatsapp.git","type":"git"},"workspaces":["packages/*"],"_npmVersion":"11.6.2","description":"Transforms Markdown into WhatsApp text format","directories":{},"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","jest":"^30.0.5","eslint":"^9.28.0","globals":"^16.2.0","ts-jest":"^29.4.4","prettier":"^3.8.1","tsc-alias":"^1.8.10","@eslint/js":"^9.28.0","typescript":"^5.8.3","@types/jest":"^30.0.0","typescript-eslint":"^8.33.1","eslint-config-love":"^144.0.0","@trivago/prettier-plugin-sort-imports":"^5.2.2"},"_npmOperationalInternal":{"tmp":"tmp/llm-markdown-whatsapp_0.0.5_1770824044261_0.4882630395556402","host":"s3://npm-registry-packages-npm-production"}},"0.0.6":{"name":"@daviddh/llm-markdown-whatsapp","version":"0.0.6","private":false,"description":"Transforms Markdown into WhatsApp text format","keywords":["llm","whatsapp","markdown","chat","split","chunking","formatter","converter","transformer"],"homepage":"https://github.com/daviddominguezh/llm-markdown-whatsapp#readme","bugs":{"url":"https://github.com/daviddominguezh/llm-markdown-whatsapp/issues"},"repository":{"type":"git","url":"git+https://github.com/daviddominguezh/llm-markdown-whatsapp.git"},"license":"MIT","author":{"name":"David Dominguez"},"type":"module","main":"packages/core/dist/index.js","types":"packages/core/dist/index.d.ts","exports":{".":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"},"./core":{"types":"./packages/core/dist/index.d.ts","import":"./packages/core/dist/index.js","default":"./packages/core/dist/index.js"}},"workspaces":["packages/*"],"scripts":{"typecheck":"tsc -b","lint":"eslint .","format":"prettier --write \"**/*.{js,ts,json}\"","check":"npm run format && npm run lint && npm run typecheck","build":"npm run build --workspaces","build:core":"npm run build -w @daviddh/llm-markdown-whatsapp/core","test":"npm run test --workspaces --if-present","test:core":"npm run test -w @daviddh/llm-markdown-whatsapp/core"},"devDependencies":{"@eslint/js":"^9.28.0","@trivago/prettier-plugin-sort-imports":"^5.2.2","@types/jest":"^30.0.0","eslint":"^9.28.0","eslint-config-love":"^144.0.0","globals":"^16.2.0","jest":"^30.0.5","prettier":"^3.8.1","ts-jest":"^29.4.4","tsc-alias":"^1.8.10","tsx":"^4.19.4","typescript":"^5.8.3","typescript-eslint":"^8.33.1"},"engines":{"node":">=18.0.0"},"gitHead":"0608018db72d3900800a11743a87fe430409c53d","_id":"@daviddh/llm-markdown-whatsapp@0.0.6","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-GdbONNhH9nwKpTvqkJTL2aEp+BThh8WQ6hIIIfqXoykohPuDyHilKxo0XvZov/qX/MybxcjY3VS+aVY11Cu3Jw==","shasum":"d5a55f9ff76acf4fbd31f827616a4c210c733ed2","tarball":"https://registry.npmjs.org/@daviddh/llm-markdown-whatsapp/-/llm-markdown-whatsapp-0.0.6.tgz","fileCount":47,"unpackedSize":109707,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHiZCF7qhjfo0IUG37+lESndMoevtNYC1pMRm8SbicKzAiEAsCX/dV6zTNKmjkO5+nVbZRlQGuIayKtXuXGFb31U+3c="}]},"_npmUser":{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"},"directories":{},"maintainers":[{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/llm-markdown-whatsapp_0.0.6_1770833284746_0.6272378341552836"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-06T17:07:59.215Z","modified":"2026-02-11T18:08:04.998Z","0.0.1":"2026-02-06T17:07:59.464Z","0.0.2":"2026-02-06T18:39:09.493Z","0.0.3":"2026-02-06T18:50:38.493Z","0.0.4":"2026-02-09T15:29:43.898Z","0.0.5":"2026-02-11T15:34:04.422Z","0.0.6":"2026-02-11T18:08:04.887Z"},"bugs":{"url":"https://github.com/daviddominguezh/llm-markdown-whatsapp/issues"},"author":{"name":"David Dominguez"},"license":"MIT","homepage":"https://github.com/daviddominguezh/llm-markdown-whatsapp#readme","keywords":["llm","whatsapp","markdown","chat","split","chunking","formatter","converter","transformer"],"repository":{"type":"git","url":"git+https://github.com/daviddominguezh/llm-markdown-whatsapp.git"},"description":"Transforms Markdown into WhatsApp text format","maintainers":[{"name":"daviddh","email":"l.david.dominguez.12@gmail.com"}],"readme":"<p align=\"center\">\n  <h1 align=\"center\">LLM Markdown WhatsApp</h1>\n  <p align=\"center\">\n    A TypeScript library that splits LLM-generated markdown into WhatsApp-friendly chat message chunks.\n  </p>\n</p>\n\n<div align=\"center\">\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178C6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n[![Node.js](https://img.shields.io/badge/Node.js-18+-339933?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](https://opensource.org/licenses/MIT)\n\n</div>\n\n<p align=\"center\">\n  <a href=\"#the-problem\">Problem</a> •\n  <a href=\"#quickstart\">Quickstart</a> •\n  <a href=\"#features\">Features</a> •\n  <a href=\"#splitting-rules\">Splitting Rules</a> •\n  <a href=\"#api-reference\">API Reference</a>\n</p>\n\n---\n\n## The Problem\n\nLLMs generate long, structured markdown responses—paragraphs, numbered lists, product cards, nested bullet points. Sending these as a single WhatsApp message creates a wall of text that users won't read.\n\nNaively splitting at character limits breaks mid-sentence, mid-list, or mid-URL. Splitting at every period creates fragmented messages that feel robotic. Neither approach understands the structure of the content.\n\nAdditionally:\n\n- **URLs, emails, and numbers contain periods.** Splitting at `Nike.com.co` or `$1.000.000` or `juan.perez@gmail.com` produces broken fragments.\n- **Lists should stay together.** A numbered list of products or a bullet list of options is a single logical unit—splitting inside an item destroys readability.\n- **Questions need context.** A short trailing question like \"¿Te interesa?\" should stay attached to the preceding sentence, not become its own tiny message.\n\nThis library handles all of this. One function call, zero configuration. Pass in the LLM's markdown output, get back an array of WhatsApp-ready message chunks.\n\n## How It Works\n\nThe library takes a markdown string and splits it into an array of smaller chunks optimized for chat readability. It applies a priority-ordered chain of processors:\n\n1. Pre-processes text (normalizes inline lists, removes periods after URLs)\n2. Tries structural splits first (intro + list, product cards, markdown sections, double newlines)\n3. Falls back to semantic splits (question marks, periods) with intelligent protection\n4. Merges chunks that are too small (<20 chars) with their neighbors\n5. Normalizes Spanish punctuation (¿/¡ capitalization rules)\n\n## Features\n\n| Feature                       | Description                                                                    |\n| ----------------------------- | ------------------------------------------------------------------------------ |\n| **Smart Question Splitting**  | Splits at question marks while keeping contiguous questions together            |\n| **List Preservation**         | Keeps numbered and bullet lists intact, splits only when items are very long    |\n| **Product Card Detection**    | Recognizes product card patterns (with emojis or markdown) and splits per card  |\n| **URL/Email/Number Safety**   | Never splits inside URLs, emails, domain names, or formatted numbers           |\n| **Parentheses Protection**    | Avoids splitting inside parenthetical expressions                              |\n| **Abbreviation Awareness**    | Protects periods in `etc.`, `Dr.`, `D.C.`, `S.A.`, version numbers            |\n| **Spanish Punctuation**       | Normalizes capitalization after mid-sentence ¿ and ¡ marks                     |\n| **Small Chunk Merging**       | Prevents tiny fragments by merging small chunks with adjacent ones             |\n| **Markdown Table Support**    | Converts tables to monospace blocks (small) or row-per-chunk format (wide)     |\n| **Markdown Section Support**  | Splits at markdown headers (`*Title*` or `_Title_`) as natural boundaries      |\n| **Zero Configuration**        | Single function, no setup required—just pass text, get chunks                  |\n\n## Quickstart\n\n```bash\nnpm install @daviddh/llm-markdown-whatsapp\n```\n\n### Basic Usage\n\n```typescript\nimport { splitChatText } from '@daviddh/llm-markdown-whatsapp';\n\nconst llmResponse = 'Thanks for reaching out. I understand your situation and I want to help you resolve it in the best way possible. You can send your product back at no extra cost. Would you prefer a full refund or an exchange for a different model?';\n\nconst chunks = splitChatText(llmResponse);\nconsole.log(chunks);\n// [\n//   'Thanks for reaching out.',\n//   'I understand your situation and I want to help you resolve it in the best way possible.',\n//   'You can send your product back at no extra cost.',\n//   'Would you prefer a full refund or an exchange for a different model?',\n// ]\n```\n\n### Lists Stay Together\n\n```typescript\nconst llmResponse = `I found these options:\n\n- Nike Pegasus Plus – High-performance running shoes for marathons and daily runs, featuring ZoomX Foam cushioning and a Flyknit upper that adapts to your foot. Available in black and a multicolor combination.\n- Nike Air Max 90 – Classic model with a waffle sole and the iconic visible Air cushioning, in neutral tones like light bone/olive/university grey.\nWhich of these models interests you the most? 😊`;\n\nconst chunks = splitChatText(llmResponse);\n// [\n//   'I found these options:',\n//   '- Nike Pegasus Plus – High-performance running shoes for marathons...',\n//   '- Nike Air Max 90 – Classic model with a waffle sole...',\n//   'Which of these models interests you the most? 😊',\n// ]\n```\n\n### Product Cards Split Per Card\n\n```typescript\nconst llmResponse = `I found these options:\n\n1. 🛍️  Pegasus Plus Shoes: 💵 $1.015.000\n📏 Color: Black, Glacier Blue/Mint Foam/Impact Green/Black.\n📏 Shoe Size: 43, 41, 38.\n✅ Ultra-lightweight, with ZoomX cushioning and great breathability.\n\n2. 🛍️  ISPA Sense Shoes: 💵 $804.900\n📏 Shoe Size: 38, 39, 40, 41, 42, 43.\n✅ Casual style with great comfort for daily use.\n\nWhich of these products do you like?`;\n\nconst chunks = splitChatText(llmResponse);\n// [\n//   'I found these options:',\n//   '🛍️  Pegasus Plus Shoes: 💵 $1.015.000\\n📏 Color: ...\\n✅ Ultra-lightweight...',\n//   '🛍️  ISPA Sense Shoes: 💵 $804.900\\n📏 Shoe Size: ...\\n✅ Casual style...',\n//   'Which of these products do you like?',\n// ]\n```\n\n### Markdown Tables\n\nTables are automatically detected and converted into WhatsApp-friendly formats. Small tables render as monospace blocks, while wide tables split each row into its own chunk.\n\n**Small table (monospace format)** — when total width is ≤ 45 characters:\n\n```typescript\nconst llmResponse = `Here are the sizes:\n\n| Size | Stock |\n| --- | --- |\n| 38 | 5 |\n| 40 | 12 |\n| 42 | 3 |`;\n\nconst chunks = splitChatText(llmResponse);\n// [\n//   'Here are the sizes:',\n//   '```\\nSize  Stock\\n38    5\\n40    12\\n42    3\\n```',\n// ]\n```\n\n**Wide table (row-per-chunk format)** — when total width exceeds 45 characters:\n\n```typescript\nconst llmResponse = `Here is the comparison:\n\n| Model | Description | Price |\n| --- | --- | --- |\n| Nike Pegasus | Lightweight running shoe with ZoomX | $1.015.000 |\n| Nike Air Max | Classic design with visible Air unit | $804.900 |`;\n\nconst chunks = splitChatText(llmResponse);\n// [\n//   'Here is the comparison:',\n//   '*Model:* Nike Pegasus\\n*Description:* Lightweight running shoe with ZoomX\\n*Price:* $1.015.000',\n//   '*Model:* Nike Air Max\\n*Description:* Classic design with visible Air unit\\n*Price:* $804.900',\n// ]\n```\n\n---\n\n## Splitting Rules\n\nThe library applies processors in priority order. The first processor that finds a valid split point wins, and the remaining text is re-evaluated from the top.\n\n### Structural Splits (highest priority)\n\n| Pattern                    | Behavior                                                                             |\n| -------------------------- | ------------------------------------------------------------------------------------ |\n| **Intro + List**           | Text ending with `:` followed by a numbered/bullet list splits after the intro       |\n| **Question + Numbered List** | Short question followed by numbered options stays together as one chunk             |\n| **Product Cards**          | Numbered items with `🛍️` or `*Title*` formatting split into one chunk per card       |\n| **List Sections**          | Numbered/bullet lists kept as one chunk; split per-item only when items are >150 chars |\n| **Markdown Sections**      | `*Header*` or `_Header_` with content splits at section boundaries                   |\n| **Section Breaks**         | Double newlines (`\\n\\n`) act as natural split points                                 |\n\n### Semantic Splits (fallback)\n\n| Pattern                    | Behavior                                                                             |\n| -------------------------- | ------------------------------------------------------------------------------------ |\n| **Question Marks**         | Splits after `?` unless followed by lowercase (sentence continuation) or emoji       |\n| **Contiguous Questions**   | Multiple questions without periods between them stay together                        |\n| **Period Splits**          | Splits at `.` for text >100 chars, skipping protected positions                      |\n\n### Protected Content (never split inside)\n\n| Content                    | Examples                                                                             |\n| -------------------------- | ------------------------------------------------------------------------------------ |\n| **URLs**                   | `https://example.com/path`, `www.site.com`                                           |\n| **Plain Domains**          | `Nike.com.co`, `shop.example.co.uk`                                                  |\n| **Emails**                 | `john.perez@gmail.com`                                                               |\n| **Formatted Numbers**      | `$1.000.000`, `2.5.1`, `15.5`                                                       |\n| **Abbreviations**          | `etc.`, `Dr.`, `D.C.`, `S.A.`, `E.U.A.`                                             |\n| **Parenthetical Expressions** | `(street, number, ref, etc.)`                                               |\n| **Bullet Point Content**   | Content within `- item` or `• item` lines                                            |\n\n### Post-processing\n\n- **Small Chunk Merging:** Chunks under 20 characters merge with the next chunk (or previous, if last).\n- **Spanish Punctuation:** After mid-sentence `¿` or `¡` (not at start or after `.`/`!`/`?`), the following letter is lowercased. Example: `ayudarte ¿Cómo estás?` becomes `ayudarte ¿cómo estás?`.\n\n---\n\n## API Reference\n\n### `splitChatText(text)`\n\n```typescript\nfunction splitChatText(text: string | null | undefined): string[]\n```\n\nSplits a markdown text string into an array of chat-ready chunks.\n\n- **Input:** A string of markdown text (typically an LLM response). Accepts `null` or `undefined` safely.\n- **Output:** An array of strings, each suitable for sending as an individual WhatsApp message.\n- Returns `[]` for `null`, `undefined`, or empty string.\n\n```typescript\nimport { splitChatText } from '@daviddh/llm-markdown-whatsapp';\n\nconst chunks = splitChatText(llmMarkdownText);\n```\n\n## Project Structure\n\n```\nllm-markdown-whatsapp/\n├── packages/\n│   └── core/                    # Core splitting library\n│       └── src/\n│           ├── index.ts         # Public API — exports splitChatText\n│           └── chatSplit/\n│               ├── splitChatText.ts          # Main orchestrator\n│               ├── splitProcessors.ts        # Intro + list processors\n│               ├── productCardProcessor.ts   # Product card detection and splitting\n│               ├── listProcessor.ts          # Numbered/bullet list processing\n│               ├── paragraphProcessor.ts     # Long paragraph and markdown sections\n│               ├── breakProcessor.ts         # Double newline section breaks\n│               ├── questionProcessor.ts      # Question mark splitting logic\n│               ├── periodProcessor.ts        # Period splitting with protected ranges\n│               ├── mergeProcessor.ts         # Small chunk merging\n│               ├── sections.ts              # Markdown/list section detection\n│               ├── textHelpers.ts           # Smart trim, emoji detection, text utilities\n│               ├── positionHelpers.ts       # Parentheses/bullet position checks\n│               ├── listNormalization.ts     # Inline list normalization\n│               ├── urlNormalization.ts       # URL period removal\n│               ├── punctuationNormalization.ts  # Spanish ¿/¡ capitalization\n│               ├── constants.ts             # Threshold constants\n│               └── splitConstants.ts        # Split-specific constants\n└── README.md\n```\n\n\n\n## Architecture\n\n```mermaid\nflowchart TB\n    subgraph Input[\"Input\"]\n        T[\"LLM markdown text\"]\n    end\n\n    Input --> Pre\n\n    subgraph Pre[\"Pre-processing\"]\n        direction LR\n        A[\"Normalize<br/>inline lists\"]\n        B[\"Normalize<br/>product cards\"]\n        C[\"Remove periods<br/>after URLs\"]\n    end\n\n    Pre --> Processors\n\n    subgraph Processors[\"Processor Chain (priority order)\"]\n        direction TB\n        P1[\"Intro + List<br/>Question + List<br/>Intro + Long Paragraphs\"]\n        P2[\"Product Cards<br/>List Sections<br/>Long Paragraphs\"]\n        P3[\"Markdown Sections<br/>Section Breaks (double newlines)\"]\n        P4[\"Question Marks<br/>Period Splits\"]\n    end\n\n    Processors --> Post\n\n    subgraph Post[\"Post-processing\"]\n        direction LR\n        D[\"Merge small<br/>chunks\"]\n        E[\"Normalize Spanish<br/>punctuation\"]\n    end\n\n    Post --> Output\n\n    subgraph Output[\"Output\"]\n        O[\"string[ ] — array of chat-ready chunks\"]\n    end\n```\n\n---\n\n## Contributing\n\nContributions are welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Write tests for your changes\n4. Ensure all tests pass (`npm test`)\n5. Ensure types check (`npm run typecheck`)\n6. Commit with a clear message\n7. Open a Pull Request\n\n## Development\n\n```bash\ngit clone <repository-url>\ncd llm-markdown-whatsapp\nnpm install\n\nnpm run build          # Build all packages\nnpm test               # Run tests\nnpm run typecheck      # Type check\nnpm run lint           # Lint\nnpm run check          # Format + lint + typecheck\n```\n\n## License\n\nMIT License - see [LICENSE](LICENSE) for details.\n\n---\n\n<p align=\"center\">\n  Built with TypeScript • Zero Dependencies • WhatsApp-Optimized Chat Splitting\n</p>\n","readmeFilename":"README.md"}