{"id":"advanced-markdown","repo":"custyhs/paseo-advanced-markdown","url":"https://github.com/custyhs/paseo-advanced-markdown","package":"paseo-advanced-markdown","npm":{"package":"paseo-advanced-markdown","version":"0.2.1","integrity":"sha512-OD5TuYvmXEpH0z3ep7bHCcW/0p3HfZjmPF6J62zKqWPYwdLpYHRVKH6SvKOeysjQJkAEQrsigMmw/cBzbcNoIg==","publishedAt":"2026-09-22T03:30:46.604Z","downloadsLast30Days":0},"name":"advanced-markdown","description":"Advanced Markdown rendering for Paseo 0.8 and 0.9: math formulas and Mermaid diagrams in assistant messages","categories":["productivity"],"platforms":[],"caveats":["Requires Paseo app and daemon >=0.8.0 <0.10.0.","Requires Node.js >=22.22, npm and Git on the daemon host, with about 700 MiB of cache space.","Daemon-host validation is on macOS arm64; Windows is untested, and Linux needs the dependencies listed in the README.","The latest iPhone layout and Android UI are not yet device-verified.","Downloads the Mermaid worker and Chrome during setup; message rendering stays on the selected daemon host.","Avoid enabling another plugin that claims the same assistant messages containing math or Mermaid."],"images":[],"themes":[],"health":{"manifestValid":true,"hasReadme":true,"hasLicense":true,"hasTests":true,"hasTypecheckScript":true,"updatedRecently":true},"scannedAt":"2026-09-22T12:46:12.277Z","addedAt":"2026-09-22T12:43:19Z","npmSecurity":{"status":"passed","blockingFindings":0,"advisoryFindings":0,"scannedAt":"2026-09-22T12:46:04.923Z","version":"0.2.1","integrity":"sha512-OD5TuYvmXEpH0z3ep7bHCcW/0p3HfZjmPF6J62zKqWPYwdLpYHRVKH6SvKOeysjQJkAEQrsigMmw/cBzbcNoIg=="},"version":"0.2.1","security":{"status":"passed","blockingFindings":0,"advisoryFindings":0,"scannedAt":"2026-09-22T12:46:04.923Z","commit":"dc107748be91a9a1c90b5162b546e2e095d65571"},"license":"Apache-2.0","paseoVersionRequirement":">=0.8.0 <0.10.0","descriptionNodes":[{"type":"text","text":"Advanced Markdown rendering for Paseo 0.8 and 0.9: math formulas and Mermaid diagrams in assistant messages"}],"caveatNodes":[[{"type":"text","text":"Requires Paseo app and daemon >=0.8.0 <0.10.0."}],[{"type":"text","text":"Requires Node.js >=22.22, npm and Git on the daemon host, with about 700 MiB of cache space."}],[{"type":"text","text":"Daemon-host validation is on macOS arm64; Windows is untested, and Linux needs the dependencies listed in the README."}],[{"type":"text","text":"The latest iPhone layout and Android UI are not yet device-verified."}],[{"type":"text","text":"Downloads the Mermaid worker and Chrome during setup; message rendering stays on the selected daemon host."}],[{"type":"text","text":"Avoid enabling another plugin that claims the same assistant messages containing math or Mermaid."}]],"manifest":{"id":"advanced-markdown","requirements":{"paseo":">=0.8.0 <0.10.0"},"build":[["npm","ci"],["npm","run","build"],["npm","run","prepare-browser"]]},"repoMeta":{"stars":1,"defaultBranch":"main","pushedAt":"2026-09-22T03:15:45Z"},"owner":{"login":"custyhs","avatarUrl":"https://avatars.githubusercontent.com/u/55645731?v=4"},"installNotesHtml":"<p>From Git, pinned to a tag (recommended):</p>\n<pre><code class=\"language-bash\">paseo plugin add custyhs/paseo-advanced-markdown --ref v0.2.1\npaseo plugin ls\n</code></pre>\n<p>Paseo runs the manifest's preparation commands on the daemon host:\n<code>npm ci</code>, <code>npm run build</code>, and <code>npm run prepare-browser</code>. The last one prepares\nthe formula assets and installs the pinned Mermaid CLI runtime and Chrome headless shell into\n<code>~/.cache/paseo-advanced-markdown</code> (or <code>$XDG_CACHE_HOME/paseo-advanced-markdown</code>,\n<code>%LOCALAPPDATA%\\paseo-advanced-markdown</code> on Windows; override with\n<code>PASEO_ADVANCED_MARKDOWN_CACHE</code>, which must be an absolute path). Relative\n<code>XDG_CACHE_HOME</code> and <code>LOCALAPPDATA</code> values are ignored. That directory is outside Paseo's managed\ncheckouts, so plugin updates reuse it and a removed plugin can be cleaned up by\ndeleting it.</p>\n<p>From a local checkout:</p>\n<pre><code class=\"language-bash\">git clone https://github.com/custyhs/paseo-advanced-markdown.git\ncd paseo-advanced-markdown\nnpm ci &#x26;&#x26; npm run build &#x26;&#x26; npm run prepare-browser\npaseo plugin install \"$PWD\"\n</code></pre>\n<p>Put <code>--host &#x3C;host:port></code> before <code>plugin</code> to target a daemon other than the\nCLI's default one. <code>paseo plugin add</code> and <code>plugin install</code> mean you trust this\ncodebase: its server side runs unsandboxed on the daemon host.</p>","limitationsNotesHtml":"<table>\n<thead>\n<tr>\n<th>Limit</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Formula</td>\n<td>4096 characters</td>\n</tr>\n<tr>\n<td>Mermaid definition</td>\n<td>32 KiB</td>\n</tr>\n<tr>\n<td>Image</td>\n<td>2,000,000 base64 characters; 8 M raster pixels and 4096 px longest edge (large diagrams are re-rendered at a lower scale, down to 0.5x)</td>\n</tr>\n<tr>\n<td>Math raster</td>\n<td>Density 1/2/3/4/6/8; logical size independent of density; lower detail is used when an image budget is reached</td>\n</tr>\n<tr>\n<td>Math queue</td>\n<td>1 rendering, up to 128 waiting inputs; duplicate requests share work</td>\n</tr>\n<tr>\n<td>Mermaid queue</td>\n<td>1 running, 8 waiting per plugin process; 15 s per task</td>\n</tr>\n<tr>\n<td>Caches</td>\n<td>128 images / 8 MiB on the host and in each client</td>\n</tr>\n</tbody>\n</table>\n<p>Rendering happens on the selected daemon host only. Message content never\nleaves it; the render browser runs with networking disabled.</p>","readmeText":"# Advanced Markdown for Paseo\n\nRenders math formulas and Mermaid diagrams inside assistant messages in\n[Paseo](https://paseo.sh) 0.8.x and 0.9.x, as an installable plugin. No Paseo fork, no\npatch: the official app, daemon, and plugin SDK are the only dependencies.\n\n- Math: `$…$`, `\\(…\\)`, `$$…$$`, `\\[…\\]`, and ```` ```math ```` fences,\n  typeset on the host with MathJax and rasterized with resvg.\n- Mermaid: ```` ```mermaid ```` fences rendered on the host with the pinned\n  Mermaid CLI and a plugin-managed Chrome headless shell.\n- Both in one message, mixed with ordinary Markdown (headings, emphasis,\n  lists, quotes, tables, code, HTTP(S) links).\n- Chinese bold text and boxed equation borders are preserved.\n- Copy TeX and original source, formula/diagram inspection, light and dark themes,\n  and per-host size/module settings.\n\n**v0.2.1** prepares the plugin for npm distribution with prebuilt rendering code,\nverified offline assets, and a complete package source-size check. See the\n[release notes](docs/release/0.2.1.md) and [package validation](docs/qa/npm-package.md).\n\nv0.2.0 added a shared formula/diagram viewer, mouse dragging for overflowing\nformulas and code, and fixes for footnote rendering and native inline formula\nlayout. See the [release notes](docs/release/0.2.0.md) and\n[validation record](docs/qa/click-viewer.md). The latest iPhone layout adjustment\nstill needs device confirmation; Android UI validation remains pending.\n\n## Requirements\n\n| Side | Requirement |\n| --- | --- |\n| Paseo | app and daemon **>=0.8.0 <0.10.0**; compiler/SDK checks cover 0.8.0 and 0.9.0-beta.2 (see the [compatibility record](docs/qa/paseo-0.9-compatibility.md)) |\n| Daemon host | Node ≥ 22.22 and npm on `PATH` for the preparation step, Git, about 700 MiB of disk in the plugin cache, network access during installation only |\n| Text font | A font covering any non-Latin characters used inside formulas (Chinese, Japanese, Korean, …). macOS and most desktop Linux installs already have one; see [Text inside formulas](#text-inside-formulas) |\n| Daemon host OS | verified on macOS arm64; Linux needs a CJK font (`fonts-noto-cjk`), `ps` (`procps`), the usual Chrome shared libraries, and either unprivileged user namespaces or `PASEO_ADVANCED_MARKDOWN_NO_SANDBOX=1` in the daemon's environment (Ubuntu 24.04 restricts them by default); Windows is untested |\n| Clients | official browser web UI verified in detail; prior rendering flow verified by the maintainer on official iOS/Paseo 0.8.0 (2026-09-14) and another Mac; v0.2.0's latest iPhone layout and Android UI remain unverified (see `docs/qa/`) |\n\nPlugins must be enabled on the daemon (Settings → Plugins, or `pluginsEnabled`\nin `config.json`).\n\nPaseo also checks prereleases against their stable core, so `0.9.0-beta.2`\nmeets this range. This is a bounded compatibility policy, not a claim that every\n0.8/0.9 build has received device QA. **v0.1.5** adds this compatibility range;\ntags through v0.1.4 still require exactly 0.8.0. Install v0.2.1 for the current release.\n\n## Install\n\nFrom Git, pinned to a tag (recommended):\n\n```bash\npaseo plugin add custyhs/paseo-advanced-markdown --ref v0.2.1\npaseo plugin ls\n```\n\nPaseo runs the manifest's preparation commands on the daemon host:\n`npm ci`, `npm run build`, and `npm run prepare-browser`. The last one prepares\nthe formula assets and installs the pinned Mermaid CLI runtime and Chrome headless shell into\n`~/.cache/paseo-advanced-markdown` (or `$XDG_CACHE_HOME/paseo-advanced-markdown`,\n`%LOCALAPPDATA%\\paseo-advanced-markdown` on Windows; override with\n`PASEO_ADVANCED_MARKDOWN_CACHE`, which must be an absolute path). Relative\n`XDG_CACHE_HOME` and `LOCALAPPDATA` values are ignored. That directory is outside Paseo's managed\ncheckouts, so plugin updates reuse it and a removed plugin can be cleaned up by\ndeleting it.\n\nFrom a local checkout:\n\n```bash\ngit clone https://github.com/custyhs/paseo-advanced-markdown.git\ncd paseo-advanced-markdown\nnpm ci && npm run build && npm run prepare-browser\npaseo plugin install \"$PWD\"\n```\n\nPut `--host <host:port>` before `plugin` to target a daemon other than the\nCLI's default one. `paseo plugin add` and `plugin install` mean you trust this\ncodebase: its server side runs unsandboxed on the daemon host.\n\n## Update and roll back\n\n```bash\npaseo plugin update advanced-markdown        # tracks the ref you installed\n```\n\nA fixed tag does not advance to the next release. If `paseo plugin update --help`\nlists `--ref`, switch an existing Git installation without removing its settings:\n\n```bash\npaseo plugin update advanced-markdown --ref v0.2.1\n```\n\nOlder CLIs require removing and adding the plugin with the new tag; record your\nplugin settings before removal, because removal deletes them. To roll back, use\n`v0.2.0`, which supports the same Paseo version range. Tags through v0.1.4 require\nexactly Paseo 0.8.0 and cannot be used to roll back on 0.9.\n\nA failed preparation during `plugin update` keeps the installed version running. Updates never touch\nchat history, Drafts, or other plugins.\n\n## What is rendered, and what is not\n\n| Content | Behavior |\n| --- | --- |\n| Complete inline or display math, closed `math` fence | image; click or tap to inspect and copy |\n| A `math` fence whose body is itself wrapped in `\\[…\\]`, `$$…$$`, `\\(…\\)`, or `$…$` | the redundant wrapper is ignored, the formula renders |\n| Complete `mermaid` fence: flowchart, sequence, class, state, ER, Gantt (verified); other types on a best-effort basis | image; click or tap to inspect and copy |\n| Unclosed delimiters or fences while streaming | readable source until closed |\n| Prices (`$5 and $10`), `\\$`, inline code, other fences | plain text / code |\n| Footnote markers and definitions (`[^note]`, `[^note]: …`) | readable text; formulas in definition lines render, without footnote navigation |\n| Invalid TeX, invalid Mermaid, oversized input | source with a short reason; other content still renders |\n| Messages with inline images or links requiring host file navigation | left to Paseo's renderer |\n| User messages, tool output, other timeline rows | unchanged |\n\nBare `$$` display math that contains a blank line is split by Paseo while\nstreaming; each half stays readable source. Use a ```` ```math ```` fence for\nmulti-paragraph display math.\n\nCopy scopes: copying happens inside the viewer. In **Preview**, **Copy LaTeX** or\n**Copy Mermaid** copies the original expression or diagram body. In **Source**,\n**Copy Markdown** copies the exact block, including its delimiters or fence.\n**More** offers the other copy format and **Copy fragment Markdown**,\nwhich copies the timeline row's text. Paseo may split one long reply into several\nrows while it streams; this last action copies only the row containing the entry.\n\n## Reading code blocks\n\nIn messages rendered by this plugin, overflowing code blocks support mouse dragging\non desktop. **Select text** switches to text selection; **Drag to scroll** switches\nback. **Copy source** copies the entire original block body in either mode. Short\ncode blocks and native clients keep their usual text selection and scrolling.\n\n## Reading formulas\n\nFormula size offers 75%, 100%, 125%, 150%, and 200%, relative to the text size.\nThis preference is shared by clients of the selected host and affects only math.\nReset formula size restores 100% without changing prose, Mermaid, or module switches.\n\nEach paragraph/list/table cell measures its own width. A formula can shrink by\nup to 15% to fit; longer formulas keep their reading size and scroll horizontally.\nAn oversized inline formula moves into a scrollable block at the same source\nposition. Short formulas do not stretch to fill the available width.\nOn native clients, ordinary fractions, sums, and scripts stay inline, with line\nheight reserved from their image metrics across the text run. Formulas requiring\nmore than two normal lines move into a separate block, with adjacent closing\npunctuation kept beside the image. The latest native layout still needs iPhone\nand Android device validation.\nOn desktop, drag an overflowing formula left or right to pan; releasing a drag\ndoes not open the viewer. Trackpad and touch scrolling remain available.\n\nClick or tap a formula, diagram, or its source placeholder to open the shared\nviewer. Keyboard users can activate the same entries. The conversation shows no\nhover toolbar or tap-to-reveal action row. Source remains selectable, and dragging\nor selecting text does not open the viewer.\n\nThe viewer has **Preview** and **Source** modes. **Fit** shows the complete image\ninside the available width and height; **−** and **+** adjust temporary zoom, with\nscrolling for larger images. The percentage is relative to the saved reading size\nand does not change the Formula size setting. Diagrams start fitted within the\nviewer without enlargement. Use the modal's close control to return to reading.\nOverflowing previews also support mouse dragging. Source mode retains text selection.\n\nLoading, failed, and disabled-module entries open on readable source. **Preview**\nbecomes available when an image is ready. Recoverable failures expose **Retry**\ninside the viewer. Copy actions stay available in either mode; **Copy LaTeX**\npreserves the original expression body, excluding a redundant outer wrapper.\n\nSharper PNGs are requested by display density and scale, up to 8×. Available\nimages stay visible while more detail loads. Image/payload limits can cap detail;\nzoom cannot provide unlimited resolution. Images have source accessibility labels,\nnot semantic MathML navigation or selectable mathematical glyphs.\n\nThe reviewed TeX profile adds `mathtools` and `cancel`, including `\\mathclap`,\n`\\coloneqq`, `\\cancel`, and `\\cancelto`. Undefined macros fail locally; custom\nmacro definitions do not carry across formulas. Markdown link labels keep their\nexisting literal behavior. See the [host limitations](docs/qa/math-reading-gaps.md).\n\n## Text inside formulas\n\nMathJax's math fonts cover Latin, Greek, and mathematical symbols. Anything else,\nincluding Chinese, Japanese, and Korean in `\\text{…}`, needs a text font on the\ndaemon host. The plugin reads a font collection, plus a matching bold companion when needed, and hands them to the rasterizer; it\nlooks for these, in order, and the first parseable font covering all required fallback characters wins:\n\n| Platform | Looked for |\n| --- | --- |\n| macOS | PingFang, Hiragino Sans GB, STHeiti Light, Songti, Arial Unicode |\n| Linux | Noto Sans/Serif CJK, WenQuanYi Zen Hei, AR PL UMing |\n| Windows | Microsoft YaHei, SimSun, Microsoft JhengHei, Arial Unicode MS |\n\nSet `PASEO_ADVANCED_MARKDOWN_FONT` in the daemon's environment to use a specific\nfont file instead. On a minimal Linux host, install one first, for example\n`apt-get install fonts-noto-cjk`. When no usable font is found the formula keeps\nits source and says so; installing a font takes effect on the next render, with\nno plugin reload. For font and renderer failures, open the source placeholder and\nuse **Retry** in the viewer. A damaged font or missing glyph returns source with\nan error instead of a successful blank image. If bold text is requested,\nthe font must include a matching bold face; common sibling filenames such as\n`NotoSansCJK-Bold.ttc` are discovered automatically.\n\n## Settings\n\nSettings → Plugins → Advanced Markdown, per host:\n\n- Math formulas on/off, Mermaid diagrams on/off. A disabled module shows its\n  source. A message whose enabled content is exhausted returns to Paseo's own\n  renderer the next time it is displayed; rows already on screen update after a\n  reload or when the conversation is reopened.\n- Text size inside plugin rows.\n- Formula size and its independent reset.\n- Runtime status: engine versions, browser, cache directory, queue and cache\n  counts.\n\nThese switches do not change Paseo's built-in Mermaid rendering for rows the\nplugin does not own.\n\n## Limitations\n\n| Limit | Value |\n| --- | --- |\n| Formula | 4096 characters |\n| Mermaid definition | 32 KiB |\n| Image | 2,000,000 base64 characters; 8 M raster pixels and 4096 px longest edge (large diagrams are re-rendered at a lower scale, down to 0.5x) |\n| Math raster | Density 1/2/3/4/6/8; logical size independent of density; lower detail is used when an image budget is reached |\n| Math queue | 1 rendering, up to 128 waiting inputs; duplicate requests share work |\n| Mermaid queue | 1 running, 8 waiting per plugin process; 15 s per task |\n| Caches | 128 images / 8 MiB on the host and in each client |\n\nRendering happens on the selected daemon host only. Message content never\nleaves it; the render browser runs with networking disabled.\n\n## Other timeline plugins\n\nPaseo gives an assistant row to the first plugin whose transformer claims it.\nDo not enable this plugin together with another plugin that replaces assistant\nrows containing math or Mermaid (for example a separate math plugin); disable\none of them.\n\n## Development\n\n```bash\nnpm ci\nnpm run build            # Markdown/MathJax bundles, formula assets, runtime manifest\nnpm run prepare-browser  # formula assets, Mermaid runtime and browser into the cache\nnpm run typecheck && npm run lint && npm run format:check\nnpm test                 # parser, renderer, cache, Mermaid, fault injection\nnpm run paseo-source     # official Paseo 0.8.0 app sources for the smoke\nnpm run smoke            # 0.8 compiler + official projection + RPCs\nHERMES_BIN=… npm run smoke:hermes\n```\n\nTo check a newer compiler/SDK without changing the 0.8 development lockfile:\n\n```bash\nnpm install --prefix .compat-runtime --no-save --package-lock=false @getpaseo/server@0.9.0-beta.2 @getpaseo/plugin@0.9.0-beta.2\nPASEO_COMPAT_RUNTIME=.compat-runtime npm run smoke\n```\n\nThe app projection/stream fixtures remain pinned to 0.8.0. The selected compiler,\nmanifest validator, SDK registrations and RPC handlers use the selected runtime;\nthis smoke does not replace a real 0.9 client/device check.\n\n### Prepare an npm package\n\n```bash\nnpm run pack\nnpm run smoke:package\nPASEO_COMPAT_RUNTIME=.compat-runtime npm run smoke:package\n```\n\n`npm run pack` builds the generated modules and writes\n`.smoke/npm/paseo-advanced-markdown-<version>.tgz`, plus a file inventory and integrity\nhash in `.smoke/npm/pack.json`. It does not publish anything. The generated package\ncontains the runtime sources, original resvg WASM, precompiled MathJax renderer,\nstatic MathJax SVG font data, preparation scripts,\nworker lockfile, and a production `npm-shrinkwrap.json`. Host libraries and build\ntools are excluded from its dependencies. The precompiled renderer uses the same\nMathJax 3.2.2 profile as the Git source and includes its license. Unused MathJax\nspeech/XML dependencies are not installed; dependency overrides in a published\npackage do not reliably control the consuming application's dependency graph.\n\nThe repository stays private in npm metadata because its manifest prepares a Git\ncheckout with `npm ci` and a source build. The generated npm package is public-ready\nand its manifest prepares the formula assets, Mermaid worker and browser. Publish the\ngenerated `.tgz`, not the repository directory; do not use bare `npm pack` here.\nKeep the package and GitHub source versions aligned before publication.\n\nThe WASM and font JSON are data files, not embedded JavaScript. Preparation checks\ntheir SHA256 and size and copies them to content-addressed paths under the cache's\n`assets/` directory. Runtime reads verify the same bytes without network access.\nOld asset versions are retained for running processes and rollback. For formula-only\ndevelopment or to repair damaged assets, run `npm run prepare-assets` after building,\nusing the same cache environment as the daemon. Prepare before reloading a local\ndirectory installation; directory reloads do not run manifest build commands.\n\nPackaging counts every JS/TS source file shipped under `client/`, `server/`,\n`shared/`, and `scripts/`, plus the root entries, including generated modules and\ndeclarations. It fails a"}