fhgs-pi-rich-markdown
Display-only rich Markdown, equations, diagrams and private previews for Pi 1.3.0 and 1.4.0.
Package details
Install fhgs-pi-rich-markdown from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:fhgs-pi-rich-markdown- Package
fhgs-pi-rich-markdown- Version
0.0.9- Published
- Oct 27, 2026
- Downloads
- 334/mo · 334/wk
- Author
- fhxgs
- License
- MIT
- Types
- extension
- Size
- 592.1 KB
- Dependencies
- 12 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
Rich Markdown for Pi
English | 简体中文
Rich Markdown (richmd) 0.0.9 provides richer Markdown and locally typeset LaTeX to Pi 1.3.0 and 1.4.0, including completed formulas while an answer is still streaming. It does not modify Pi's installed source or rewrite messages, saved conversations or tool results. An optional, enabled-by-default prompt guideline asks the model to write mathematics as LaTeX rather than Unicode/plain-text substitutions. Rendering makes no model calls and uses no cloud service.
GitHub release 0.0.7 — 2026-10-19: live Markdown/LaTeX inside the input field, with whole-block source reveal on caret entry and deterministic local typing assistance, plus full-engine Mermaid/image previews and a zoom/pan viewer. Defaults are input: "rich", assist: true and draft: false; the separate live draft dock, local image cards and compact path labels remain available. This is the first GitHub 0.0.7 release, incorporating and superseding the earlier local candidates recorded in the changelog.
Distribution release 0.0.9 — 2026-10-28: prepare the first public npm distribution under the existing name fhgs-pi-rich-markdown, with an explicit file allowlist, a bundled MIT license and packaging regressions. Native workers use the same raster validator as plain ESM so they can run under npm's node_modules path, where Node refuses TypeScript stripping. This release changes distribution and documentation, not rendering features, commands, preferences or dependency pins. The npm/tag commands below require the corresponding publication; preparing a source release is not proof it is already available in either registry.
Existing installations never upgrade automatically. Choose npm installation/migration or the fresh-directory source upgrade, not both. Earlier local snapshots labeled 0.0.7 are not the final GitHub release; the version string alone does not identify the installed snapshot. Neither preparing nor publishing a release modifies an active local installation.
For typeset equations like a mathematical document, run Pi directly in Ghostty or Kitty. Apple Terminal cannot display those pixels; no Pi setting can add an image protocol to it. Prose remains terminal text, not proportional browser typography. Other terminals retain readable structural text and an explicit private browser preview.
Requirements and installation
Release 0.0.9 retains the exact Pi 1.3.0/1.4.0 compatibility introduced in 0.0.8. The unchanged rich-markdown-v0.0.7 tag supports only Pi 1.3.0. Upgrade 0.0.8, earlier published versions or local candidates using one of the procedures below; replace only the existing registration, then reload/restart Pi. Existing installations are not modified automatically; dependencies and preferences are unchanged.
Requires Node.js 22.19+ and a matching Pi SDK/TUI pair at exactly 1.3.0 or 1.4.0. The guarded, reversible adapters use private Markdown and default-editor layout, hit-test and editing helpers; other Pi versions retain native rendering with a warning. Pi supplies its peers: do not install a second SDK/TUI copy. Direct dependency versions are pinned in package.json; source installations also use the complete package-lock.json. npm does not ship that lockfile, so npm installations resolve transitive dependencies normally; use a tagged source installation when the complete locked tree is required. No build, system TeX or dependency lifecycle scripts are required. Full Mermaid and static WebP rendering additionally require an already installed Chrome/Chromium on macOS/Linux. The pinned puppeteer-core driver does not download a browser. Fixed application/system locations are checked; set RICH_MARKDOWN_BROWSER to an absolute native browser executable for another location. No personal browser profile is opened.
npm installation and upgrades
After fhgs-pi-rich-markdown@0.0.9 is published, a first installation can use Pi's package manager. Review the package source first: extensions execute with Pi's OS permissions. Check pi list and both personal/project settings, explicit -e paths and auto-discovered extension directories before installing. Do not load an npm copy alongside a local, Git or legacy extension copy.
pi list
npm_config_ignore_scripts=true pi install npm:fhgs-pi-rich-markdown@0.0.9
These examples use Pi's default npm backend and disable dependency lifecycle scripts for that invocation. If you customized npmCommand, use the equivalent no-lifecycle option for that manager or use the source installer. Pi supplies the SDK/TUI peers and suppresses duplicate peer installation. There is no plugin install/postinstall hook, browser download, model call or automatic Ghostty installation. The personal package declaration goes into <agent-dir>/settings.json and the package into Pi-managed npm storage outside the checkout. Use --local only for an intentionally project-scoped installation, subject to Pi's project-trust rules. Restart Pi or /reload, then run /rich-markdown status, /rich-markdown setup and /rich-markdown demo math.
Migrate an existing source/legacy installation before adding npm:
- Record the exact current source, scope and any object-form resource filters privately. Keep the old stable source directory and
rich-markdown.jsonfor rollback. Stop sessions using the old copy before changing its registration; do not overwrite its files or dependencies. - Remove only the old registration in its own scope. For a personal local package,
pi remove /absolute/path/to/old/copyremoves the declaration, not the local source directory; use--localfor a project declaration. Anextensionsentry, wildcard, auto-discovered copy/symlink or explicit-eargument must instead be removed/disabled at its actual source. Do not replace the whole settings file or remove unrelated extensions. Pi treats npm, Git and local paths as different identities and does not deduplicate them just because their manifests have the same name. - Install the pinned npm source above in the chosen scope, retaining any previous resource filters (including disabled ones), then verify with
pi listandpi config. If installation fails, restore only the old registration and its filters; never keep both entries active. Resume/reload only after exactly one copy is selected.
Later npm upgrades: stop sessions using the managed copy first. Re-run pi install npm:fhgs-pi-rich-markdown@<chosen-version> in the same scope with lifecycle scripts disabled. On the supported hosts, Pi replaces the same npm-name entry and preserves object-form filters rather than appending a second version. The explicit @0.0.9 pin does not advance with pi update --extensions; select a new version deliberately. Do not use bare pi update to upgrade this extension: that updates Pi itself and can move outside the exact supported host versions.
The npm tarball contains only explicit runtime modules/workers, the synthetic demo image, both complete guides/changelogs, design/provenance documents, package metadata and LICENSE. It excludes tests, developer/installer scripts, lockfiles, credentials, settings, conversation/history files, logs and dependency trees. The setup, check, test and test:package npm scripts are source-checkout tools, not commands for the installed npm tarball. /rich-markdown setup and /rich-markdown setup install remain available and unchanged inside Pi.
Guided installation
The guided installer is included in source snapshots starting with 0.0.6, not in the npm tarball. Choose it instead of npm registration. From the tagged source checkout, run:
cd Pi/rich-markdown
./install.sh --check
./install.sh
For an unpacked standalone archive, run the same commands from its root instead. node scripts/install.mjs is equivalent to ./install.sh; npm run setup -- --check is also supported. There is deliberately no npm install/postinstall hook, startup prompt, or automatic installation when Pi loads the plugin.
The installer detects and explains the plan before asking for approval:
- Node.js and Pi: require Node.js 22.19+ and an existing matching Pi SDK/TUI pair at exactly 1.3.0 or 1.4.0. Missing/incompatible hosts stop setup; it never installs or upgrades Pi or Node.
PI_SDK_PATHcan select a nonstandard host installation. - Renderer libraries: inspect the pinned dependency metadata and native Resvg package. Missing/incompatible dependencies are installed with npm from
package-lock.json, without lifecycle scripts, development dependencies or duplicate Pi peers. Complete dependencies are reused; a synthetic PNG smoke check must pass before registration. npm must already be available. - Ghostty / Kitty: inspect executable PATH entries and macOS system/user application bundles. An existing Ghostty or Kitty, or evidence of a direct compatible terminal session, skips additional terminal installation. Environment hints are not a graphics test; uncommon application locations may need manual setup.
- Optional Ghostty: on a local Mac with neither terminal found and Homebrew available, offer
brew install --cask ghosttyseparately. It repackages the official signed macOS DMG. Homebrew itself is never installed. Missing Homebrew, SSH, Linux distro differences and unsupported platforms receive official installation guidance, not downloaded shell scripts, new repositories or automatic privilege escalation. The plugin installer supports macOS/Linux; native Windows stays manual. - Other Pi plugins: none are required. MathJax, KaTeX and Resvg are package dependencies, not separate Pi extensions. Competing math renderers are not installed or removed.
Approved installation copies only this package and its license into <agent-dir>/local/rich-markdown-<version> by default, outside Git. An identical copy is reused; a different/incomplete source copy is never overwritten. Every bundle path component must be a real directory or regular file, not a symlink into a checkout or elsewhere. Use --dir to choose a fresh directory, including when upgrading published 0.0.8 or an earlier release/local candidate to release 0.0.9. Broken dependencies in a registered copy are not repaired in place. Only the personal Rich Markdown package entry is added/replaced, preserving object-form resource filters and unrelated settings under Pi's settings lock. Existing settings are backed up with mode 0600 under <agent-dir>/backups/. Concurrent changes to this package's registration stop the update. Local file:// registrations are recognized too. Multiple known personal registrations or a known personal extensions entry must be resolved/migrated first; project, command-line, wildcard and automatically discovered extension copies remain your responsibility. Preserved disabled filters stay disabled; review them in pi config if needed.
# Non-interactive: approve only the plugin, not an external terminal.
./install.sh --yes --without-ghostty
# Separately approve Ghostty if missing, supported, and Homebrew is available.
./install.sh --yes --with-ghostty
# Preview a different destination; never modify an active source directory.
./install.sh --check --dir "$HOME/.local/share/pi-extensions/rich-markdown-next"
--check makes no writes, network requests, command executions or consent prompts. Without --yes, non-interactive use cancels without changes. --yes alone does not approve Ghostty; --with-ghostty is separate, invocation-local consent. Both approvals skip an already installed compatible terminal. Each package-manager command has a 15-minute deadline; failures leave the copy for inspection, never register a failed renderer, and do not roll back package-manager changes. A failed optional terminal install does not undo a successfully installed plugin. Ctrl+C cancels installer subprocesses. Open Ghostty/Kitty yourself, return to the same folder, and run pi --continue; installing it does not upgrade Apple Terminal or move a running session. Run /reload, then /rich-markdown setup and /rich-markdown demo math. Text math and browser preview remain available when optional installation is declined.
Upgrading from 0.0.6 or a local 0.0.7 snapshot
This source-only procedure also covers published 0.0.8. For npm migration, use the separate procedure instead.
- Published 0.0.6, 0.0.7 or 0.0.8: install the GitHub 0.0.9 source snapshot, not an older local candidate. Keep the previous source directory intact until no session uses it and rollback is no longer needed.
- Earlier local 0.0.7: the unchanged version number does not mean the release features and fixes are installed. A different snapshot at the default
rich-markdown-0.0.7path is deliberately not overwritten; choose an unused--diroutside Git for 0.0.9, regardless of the old version label.
Use the release source's Pi/rich-markdown directory (or the standalone archive root). Review the read-only plan, then explicitly approve installation into the same fresh destination. If the example destination already exists, choose another; never target the active copy or run dependency repair in it.
./install.sh --check --dir "$HOME/.local/share/pi-extensions/rich-markdown-0.0.9-release"
./install.sh --dir "$HOME/.local/share/pi-extensions/rich-markdown-0.0.9-release" --without-ghostty
The approved installer verifies the new copy before replacing only the recognized personal Rich Markdown registration, preserving unrelated settings and resource filters. Resolve duplicate/legacy registrations first; do not add a second pi install entry for another path or load two copies. Keep the old copy for rollback, then /reload or restart Pi to activate the new registration. This source installer performs no automatic upgrade, active-copy overwrite or npm publication.
Missing input and assist preferences now select rich input and typing assistance; a missing draft defaults to false, while an explicitly saved draft: true stays enabled. Use input source for native editing, assist off to disable only typing help, or draft on to restore the separate dock. None rewrites the existing draft. Full Mermaid/static WebP additionally need installed Chrome/Chromium; setup does not download that browser.
Manual installation and development
Try one invocation from an Orbit Tools checkout, without another Rich Markdown copy loaded:
npm --prefix Pi/rich-markdown ci --ignore-scripts --legacy-peer-deps
pi -e ./Pi/rich-markdown/index.ts
For a first installation, install a tagged snapshot in a fresh stable directory outside the branch-switching checkout. Do not run this registration example if Rich Markdown is already registered: use the upgrade procedure, or manually replace only its existing package entry after testing a fresh copy. From the repository root after fetching the release tag:
(
set -eu
install_dir="$HOME/.local/share/pi-extensions/rich-markdown-0.0.9"
test ! -e "$install_dir" || { printf 'Choose a new installation directory.\n' >&2; exit 1; }
git rev-parse --verify 'rich-markdown-v0.0.9^{commit}' >/dev/null
mkdir -p "$install_dir"
git archive rich-markdown-v0.0.9 Pi/rich-markdown | tar -x -C "$install_dir" --strip-components=2
npm --prefix "$install_dir" ci --ignore-scripts --legacy-peer-deps
pi install "$install_dir"
)
The tag-based example requires the published rich-markdown-v0.0.9 tag. Earlier local candidates identified themselves as 0.0.7, but are not the final 0.0.7 release or this 0.0.9 release; do not reuse their source directories. Test development snapshots in a fresh directory, never over an active copy.
pi install registers a personal local package; it does not publish anything. When upgrading, replace only the existing Rich Markdown package entry after testing the new copy. Never register two copies, overwrite the whole settings file, or overwrite the active source directory. Keep the old copy for rollback. Run /reload or restart Pi to activate the new registration. Source installation does not publish to npm.
Commands and configuration
/rich-markdown status
/rich-markdown setup
/rich-markdown setup install
/rich-markdown demo
/rich-markdown demo math
/rich-markdown demo blocks
/rich-markdown view
/rich-markdown view demo
/rich-markdown source
/rich-markdown preview
/rich-markdown preview demo
/rich-markdown export
/rich-markdown export demo
/rich-markdown on
/rich-markdown off
/rich-markdown input rich
/rich-markdown input source
/rich-markdown assist on
/rich-markdown assist off
/rich-markdown draft on
/rich-markdown draft off
/rich-markdown math auto
/rich-markdown math text
/rich-markdown images on
/rich-markdown images off
/rich-markdown prompt on
/rich-markdown prompt off
/rich-markdown clear-images
status(also/rich-markdownwith no argument): a theme-aware, read-only status overlay. The summary groups effective rendering, terminal capability and preferences; pressdfor worker/image diagnostics and configuration commands. See Reading the status screen.setup: terminal-specific guidance and installed Ghostty/Kitty/Homebrew detection, without changing anything. In Apple Terminal it explains the Ghostty/Kitty requirement. Never forcePI_IMAGE_PROTOCOLon an unsupported terminal; Pi settings override environment variables.setup install: the same optional Ghostty offer for existing users, with a native confirmation dialog displaying the exact command. Already installed compatible terminals are skipped. No other Pi plugins or runtimes are installed; no terminal/Pi settings or package registrations are changed. Start only while Pi is idle; duplicate setup commands are rejected. Reload/exit cancels an active installer process. This is TUI-only and is never invoked automatically.demo,demo math,demo blocks: synthetic, display-only samples, including the Gaussian integral, Basel sum, small-angle approximation, matrices, code, Mermaid and pink/blue/green surfaces. No model request or context entry is made.view/view demo: open the diagram/image viewer for the last completed assistant answer or synthetic demo. Ctrl+Alt+V opens the current unsent draft's visuals without submitting or replacing the editor. Multiple visuals use a picker.source: opens the last completed assistant answer's original Markdown/LaTeX in Pi's native editor for selection/copy. Edits are discarded; nothing is sent. This is the source-copy alternative to selecting raster placeholders.preview/export: generate a private temporary HTML document from only the last completed assistant answer, excluding user messages, thinking and tools.previewalso opens it on macOS; other platforms report its path.demoselects synthetic content. This is not a permanent export.on/off: enable Rich Markdown or restore native rendering and input.offalso disables typing assistance and clears the separate dock, without rewriting the draft.math autouses images when supported;math text(also the compatible aliasmath unicode) selects text math.input rich|source: select in-field live preview or native source editing.input sourcealso bypasses Rich Markdown typing assistance; it does not change the separate dock preference or transcript rendering. This is distinct fromsource, which opens the last assistant answer for copying.assist on|off: enable or disable local typing assistance in rich input.assist offkeeps in-field rendering but forwards typing to Pi unchanged. Enter still submits; configured newline keys continue lists/tasks/quotes.draft on|off: show or clear only the separate, read-only live draft preview above the editor. It no longer controls the input field's rendering or assistance. Ctrl+Alt+I separately opens exact-file confirmation for blocked local images used by rich input or the dock; it does not approve a folder or attach images to a model request.images on|off: explicitly saves Pi's nativeterminal.showImagespreference and reloads Pi, so native image components and this plugin agree. Busy/compacting sessions reject this command before saving; retry when idle. Other commands do not change that preference.prompt on|off: controls the one stable LaTeX guideline added to interactive TUI turns. It requests$...$inline and$$...$$display syntax. It cannot force provider compliance and never rewrites an existing answer. Code, currency and literal symbols are not guessed into formulas.clear-images: frees owned Kitty images and visual caches, then renders current content again; useful after an external terminal-side clear or a failed image snapshot.
Preferences live in <agent-dir>/rich-markdown.json (normally ~/.pi/agent/rich-markdown.json). Release 0.0.9 retains the 0.0.7/0.0.8 defaults: enabled: true, math: "auto", prompt: true, input: "rich", assist: true and draft: false. An explicitly saved draft boolean is respected, including an existing true; a missing draft now defaults to false. Missing input and assist default to rich input and enabled assistance. Rich input/assistance require the compatible default editor; source mode, custom editors and an off/unavailable renderer retain native input. The dock remains independent and can accompany either input view. Existing math: "unicode" configurations remain valid. Pi's terminal.showImages, markdown.mermaid, theme and project-trust settings are respected; closed input/dock Mermaid fences can now render, while entering their source block still reveals editable code. RPC, JSON and print mode get no input assistance, draft views, rendering hooks or prompt guideline.
Reading the status screen
The default summary fits a typical 80-column terminal and separates four groups:
- Overview: whether the renderer is on, off or unavailable; the effective math mode; and a short reason for that choice. Off/unavailable means native Pi rendering, not an active Rich Markdown image path. A stopped math worker is a visible warning; cached images may remain.
- Terminal & capability: terminal name, regular/fullscreen TUI mode, detected protocol and potential image support. Capability is not a claim that images are enabled or that a formula has already rendered.
- Preferences: automatic/text math, Pi's
terminal.showImages, the effective input view with typing-help state, the independent draft dock preference, and the LaTeX prompt guideline for future TUI turns. Input reports native source when explicitly selected or when a custom/incompatible editor is in use. The dock is inactive when the renderer is off or unavailable; an enabled guideline is labeled inactive when the renderer is off or not initialized. - Commands: terminal guidance and a formula demo to run after closing the overlay. Diagnostics also lists the existing preference and image-recovery commands; the screen itself never runs them.
Default keys:
| Key | Action |
|---|---|
d |
Switch between summary and diagnostics; start at the top of the selected view |
Esc, Enter, Ctrl+C or q |
Close and return focus to Pi |
Up / Down |
Scroll one row when content does not fit |
PageUp / PageDown |
Scroll a page |
Home / End |
Go to the top / bottom |
Pi's configured tui.select.* cancel, confirm and navigation keys are respected; q, d, Home and End are local shortcuts. The footer shows the configured keys and visible row range when scrolling is needed. Narrow screens wrap labels/values using Unicode terminal widths; short screens scroll with a fixed footer. Extremely small screens shorten the frame/hints, but keyboard close and navigation remain available. Only ordinary terminal text, box drawing and arrows are used—no Nerd Font or proprietary font is required. Colors follow Pi's theme, including changes while the overlay is open.
Diagnostics separates runtime versions/cell size, MathJax jobs, retained Kitty images and local thumbnails. Unavailable is not zero; Not measured is not 0 ms. Last-job time is client-side worker time, not end-to-end display latency. Pi's reported cell dimensions may be defaults, not a confirmed measurement. Retained image counts do not prove current image rendering. State is read from memory on host redraws, without a polling timer.
Opening, navigating and closing status does not save preferences, edit terminal settings, add session/model-context entries, call a model or start rendering jobs. The status screen never invokes setup install; guided installation remains a separate, explicitly approved action.
Live rich input
With input: "rich", formatted Markdown and completed LaTeX appear inside Pi's default input field, not only in a separate dock. This is block-oriented live preview, not arbitrary rendered-formula-glyph-to-TeX caret mapping or a full WYSIWYG document editor.
- A completed whole Markdown block renders when the caret is outside its source range or at the block end. Moving into that range reveals the entire original block for editing; leaving it or returning to its end restores preview. Headings, emphasis, lists/tasks, quotes, tables, closed code fences and completed formulas use the existing renderer. Ordinary plain text stays native.
- Clicking any rendered block anchors to its source start, not the glyph under the pointer. Vertical entry from above reveals its first source position; entry from below reveals its last source character position. Pi's fullscreen mouse routing is required for clicks; keyboard entry remains available in regular mode.
- Incomplete formulas/fences remain source. Ordinary code, including
tex/latexfences, retains literal contents even when framed/highlighted; only closedmathfences are formula candidates. Closed Mermaid fences can use full-engine previews; unclosed fences remain code. Unknown or unsafe projections fall back to native source. - Complete LaTeX follows
math auto|text: supported direct Ghostty/Kitty paths use separately owned Kitty placeholder placements, with structural text/source elsewhere. Input placements are independent of dock/transcript placements; rendering a dock cannot delete an input formula. - The field retains Pi's native cursor-following viewport: its visible-row limit is 30% of terminal height, with a minimum limit of five rows, not the dock's 18-row/35% bounds. Projection is bounded to 16,384 source characters, 128 blocks and 256 rendered rows per block. Oversized documents or unsuitable blocks retain editable/submittable source rather than a truncated source replacement.
The adapter keeps the same native CustomEditor instance. Guarded Pi 1.3.0/1.4.0 layout, hit-test and private editing-method wrappers do not replace the editor factory or swap projected text into live state. Pi retains its paste registry/expansion, undo, history, application/extension shortcuts and cursor/IME marker. Rendering never rewrites source or submission; Pi submits source, not rendered rows, under its native paste/submission rules. Only the explicit local typing assistance below edits draft text. Native autocomplete temporarily retains source rendering and typing. Custom editors and competing/incompatible overrides retain native input; an optional dock can still be used above them. Physical-terminal and IME behavior remain unverified.
Local typing assistance
assist: true enables bounded, deterministic editing only in compatible rich input. Use assist off to keep the live view without typing changes, or input source to use native source editing without either feature. Neither command rewrites the existing draft.
| Input | Behavior |
|---|---|
| Enter | Pi's native submit action; not a list-continuation key |
Configured newline (tui.input.newLine, Shift+Enter / Ctrl+J by default) |
Continue list/task/quote markers, preserving indentation and marker spacing; increment ordered lists and reset continued tasks to unchecked |
| Newline on an empty marker | Remove the list/task marker or innermost quote level to exit it, rather than submit |
| Paired delimiters | Insert matching brackets, emphasis/backticks or explicit math delimiters in unambiguous contexts; repeated openers can form double delimiters or a standalone code fence |
| Typed closer / Backspace | Type through a closer generated by this assistance, or remove an empty owned pair; never adopt existing/pasted delimiters as owned pairs |
| Tab in recognized math | Complete an unambiguous local frac, sqrt or Greek-letter command prefix; for example, \fra → \frac{}{}, \sq → \sqrt{}, \alp → \alpha |
A completion with arguments places the caret in its first argument; there is no snippet placeholder/Tab-stop navigation. Ambiguous/unknown prefixes and ordinary Tab retain native behavior. Assistance makes no model calls and performs no semantic prose inference. Code/literal regions, slash/shell commands, bracketed paste, multi-character paste/IME batches and native autocomplete are not assisted. Existing shortcuts run first; unsupported input is forwarded to Pi. Assisted source edits are native undo transactions, not changes made during rendering.
Local images and consent
Rich input and the optional dock reuse the same bounded image loader and exact-file consent. Up to four distinct local images are candidates: standalone paths (including quoted paths, backslash-escaped spaces, @ prefixes, ~/ and local file:/// URLs) and Markdown image references such as . For example, "./my plot.png" and ./my\ plot.png are path spellings, not shell commands; no shell expansion is executed. Code spans/fences are not scanned for attachments. Blocks containing math delimiters conservatively retain their image references as source; put an image on its own paragraph to preview it.
In-field and dock image cards use compact [Image · filename] labels and scroll-safe Kitty pixel placeholders on direct Ghostty/Kitty, with ANSI previews or explanatory labels elsewhere; neither path needs opaque native image reservation rows. Static WebP uses the local browser decoder when available. Entering the source block reveals its paths/Markdown syntax for editing; labels are not stored attachment tokens. PNG/JPEG/GIF/WebP structure and embedded frame dimensions are validated before display; PNG ancillary metadata is stripped and GIF uses its first frame. APNG and animated WebP stay unavailable. With terminal.showImages: false, references remain labels and neither view reads draft image bytes.
Local-file consent: with image display enabled, verified files whose canonical targets are inside the current working directory can be read automatically. Outside targets—including symlinks escaping that directory and Pi's clipboard temporary image paths—remain labeled until you press Ctrl+Alt+I and approve the listed exact canonical files. Consent is bound to their verified file identity/metadata, not a folder, home directory or temporary-directory root. The loader may inspect paths and metadata before consent, but does not read outside image contents until approved; changed identities, denied/unverifiable files and failures retain blocked/unavailable labels. No remote fetches, network/UNC paths or input data: URLs are allowed in this draft path. This permission does not expand the transcript's automatic-thumbnail policy or the browser preview's separate consent.
Draft Markdown image tokens never use the transcript image loader, including references that remain as source; only the shared exact-file loader can supply authorized image-card bytes. Draft-derived visual data stays in a cache separate from transcript visuals, not merely in separate terminal placements.
Removing a reference forgets its cached bytes and exact-file permission; adding it back requires new outside-file consent. Stale reads or confirmation results cannot repopulate a removed draft; removing its references also cancels an open approval dialog. Loaded images are snapshots, not file watches; remove/re-add a reference to retry a changed or failed file. Emptying/submitting the editor, disabling all draft views, turning off image display or unloading clears applicable bytes/consent. Turning off only the dock does not revoke previews still used by rich input, and source input can retain an enabled dock.
Rendering uploads nothing, makes no model calls and adds no session entries or prompt content; the existing optional LaTeX prompt guideline is separate. An image card is not proof that image bytes are attached to the model request. Pi inserts file paths when pasting clipboard images; Rich Markdown only previews those references. Attachment metadata, uploads and Pi's model-attachment/submission behavior are unchanged. See Privacy and resource limits for read and rendering bounds.
Live draft preview
The older, separate read-only dock remains available above the editor, but now defaults to off. Use /rich-markdown draft on to show it with either rich input or source editing, including above an existing custom editor. An explicitly saved draft: true is preserved; missing draft means false. draft off controls only this dock, not in-field rendering or typing assistance.
The dock samples text on host redraws without polling. Its viewport follows the tail of the draft, capped at 18 rows and 35% of terminal height. Earlier omitted content is labeled; short terminals can show fewer cards or just a heading. Above 16,384 source characters, a paused notice replaces the dock preview; full source remains editable and submittable. Slash/shell commands are not previewed as Markdown prompts. Emptying/submitting the editor, draft off or off clears the dock.
Completed dock formulas use Kitty placeholders or structural text/source fallback. Local image cards and closed Mermaid fences use fitted Kitty placeholders on direct Ghostty/Kitty when terminal.showImages allows, with bounded ANSI previews or explanatory labels elsewhere. The same local-image consent applies to both draft views.
Rendering and terminal support
The table describes transcript formulas. In-field and dock formulas use only Kitty placeholder graphics on supported direct Ghostty/Kitty paths, or structural text/source elsewhere; they do not use native formula-image reservation rows. Local image cards have the separate input/dock behavior described above.
| Terminal path | Inline LaTeX | Display LaTeX |
|---|---|---|
| Direct Ghostty / Kitty | Baseline-aligned one-row images when legible | Centered images, including quotes, lists and real custom/Translator cards |
| Other Kitty-protocol terminals | Text | Native images in top-level, uncolored blocks |
| iTerm2 protocol, regular mode | Text | Native images in top-level, uncolored blocks |
| iTerm2 protocol, fullscreen | Text | Text; Pi disables this protocol in fullscreen |
| Apple Terminal, tmux/screen, unsupported path | Text | Structural text or intact source |
This is capability-gated, not a promise that every terminal version works identically. Too-tall inline formulas retain text instead of shrinking into illegibility; tables keep inline text. Use display math for large fractions and matrices. An inline image that native wrapping would split across rows also falls back to text. Rasters are not selectable mathematical text: use source or the browser preview. Terminal-owned scrollback is already printed output and cannot be retroactively repaired. Pixel appearance, font changes and GPU behavior require a physical-terminal check.
Completed $...$, \(...\), $$...$$, \[...\] and closed math fences can render before the answer finishes. Incomplete tokens/fences stay readable and do not enqueue transient typesetting jobs. Ordinary code, including tex/latex fences, stays literal. No second terminal renderer or Pi-source patch is installed.
MathJax produces SVG paths in a bounded worker; Resvg makes transparent PNGs on exact terminal-cell canvases, normally at double density. Geometry is cached separately from width/theme-specific rasters. Worker completions coalesce repaint requests over 32 ms; this is not a fixed latency guarantee. No timer polls the transcript. Supported image sessions prewarm the worker; text-only sessions do not pay that startup cost. A pending image shows text, then upgrades in place.
Kitty Unicode placeholder cells carry the grid and a stable per-session image ID. Pixel uploads travel through the existing host terminal writer after the frame, not inside visible Markdown lines, preserving wrapping and card backgrounds. A reversible instance-level observer handles same-size clears, forced redraws and stop/start recovery as well as geometry changes. Uploads are deduplicated. Only owned image IDs are deleted; budgets refuse new images rather than evicting pixels still referenced by cached rows. No SGR underline-color encoding is used, avoiding Pi 1.3.0's ANSI tracker incompatibility. The rendering design and research explains the trade-offs, bounds and primary references.
Diagrams, images and zoom
The TUI now uses the bundled Mermaid 12.2.0 full engine, not only the smaller text-diagram converter. This was the registry's latest version when checked; it remains pinned, not automatically upgraded. Regression fixtures cover all 37 registered diagram variants, including flowcharts/ELK, sequence, class/state/ER, Gantt, pie, journey, Git, mindmap, timeline, quadrant/XY/radar charts, requirements, Sankey, block/packet, architecture, Kanban, treemap, C4, agent flow, swimlane, tree view, event modeling, Ishikawa, Venn, use case, Wardley, Cynefin and railroad grammars. This is coverage of registered variants, not a claim that every possible input or third-party plugin works.
Complete diagrams fit both width and height, preserving their entire drawing rather than truncating labels or falling back to source solely because they are wide/tall. Fitting a large drawing can make labels small: open /rich-markdown view, or press Ctrl+Alt+V for the unsent draft. The viewer rerasterizes the original SVG or authorized full-resolution image at the selected camera, not an enlarged thumbnail. Zoomed views intentionally show a pannable portion; Fit restores the whole drawing. Invalid syntax, missing Chrome, security restrictions and resource exhaustion show an unavailable notice, not a raw-code dump. Incomplete fences, explicit Mermaid-off mode and source editing remain source by design.
| Control | Action |
|---|---|
+ / = / -, or [+] / [-] |
Zoom in/out |
f / 0, or [Fit] |
Fit the complete drawing |
1, or [1:1] |
Original pixel scale, within camera bounds |
| Arrow keys | Pan |
Esc, configured cancel, q, or [Close] |
Close and restore focus |
| Ctrl+wheel; two-finger scrolling when forwarded | Pointer-anchored zoom |
| Wheel / Shift+wheel; left drag | Vertical / horizontal pan; drag to pan |
Pointer controls require Pi fullscreen mode and terminal event forwarding. Regular mode retains keyboard controls. Pi 1.3.0/1.4.0 expose no native trackpad pinch gesture; a terminal may instead use pinch to change its font. Direct Ghostty/Kitty provide pixel previews; other paths, including this viewer in iTerm2, use a labeled ANSI preview of at most 64 columns × 20 rows. ANSI is not equivalent to readable full-resolution graphics. Pi's image preference is authoritative.
Standalone transcript images can render from local files inside cwd or bounded embedded raster data; remote images and inline prose images remain references. Draft cards retain their existing exact-file consent. The explicit viewer can request fresh, invocation-local consent for a selected outside file; it never approves a directory or uploads an attachment. Remote TUI images are not fetched—use the separately confirmed browser preview. PNG/JPEG/GIF work without Chrome, GIF uses its first frame, static WebP requires Chrome, and animated APNG/WebP are rejected.
Mermaid rendering lazily starts a sandboxed headless browser through a private DevTools pipe, with a temporary 0700 profile, protected strict-mode configuration, CSP and blocked requests. No listening server, browser download, external fonts/icons/images, diagram callbacks or model requests are used. Safe titles/frontmatter and normal diagram syntax are supported; active HTML/resource directives and unsafe configuration are not. The browser closes after 30 seconds idle and on normal shutdown; temporary profiles may survive a crash and should be inspected before removal. Browser-owned caches and terminal logging are outside an in-memory-only guarantee.
Rich Markdown beyond formulas
- Six heading levels, nested lists/tasks and preserved ordered markers; bordered, aligned, wrapping tables that become stacked records at narrow widths.
- Framed syntax-highlighted code with language labels, preserving indentation, repeated spaces, blank lines and literal contents.
- Native emphasis, strikethrough, quotes and rules; safe OSC 8 links when supported, visible targets otherwise. Executable link schemes are not activated; raw HTML is source, not executed.
- Full-row backgrounds on Markdown, Box and Text surfaces, including padding, nested backgrounds, resets and cached/theme/resize redraws. Text/log output is not reinterpreted as Markdown. Existing native image reservation rows remain untouched.
- A narrow display-only recovery for short translated CJK colon labels such as
**说明:**正文and**说明: **正文. Code, escapes, longer delimiter runs, tokens and saved source stay unchanged. Prefer portable source**说明**:正文or**说明:** 正文. - Structural text equations use public KaTeX MathML for fractions, radicals, scripts, limits, matrices, cases and alignment. Unsupported semantics keep native/compact/source fallbacks rather than discarding notation. Whole structures are centered, not individual rows; overflow never wraps a two-dimensional fraction into nonsense.
- Full-engine Mermaid and bounded local raster previews, including live closed draft fences, with automatic fitting and the zoom/pan viewer. The native text-only Mermaid transform is bypassed only for display; source, saved messages and Pi settings remain unchanged.
- Independent transcript/input/dock/viewer image placements. Remote and inline prose images remain references; no TUI image fetch or model upload is introduced.
Privacy and resource limits
Explicit, approved installation contacts the configured npm registry or Homebrew/application download services and uses their normal caches; it does not send conversation content or make model calls. Package-manager output is discarded by the guided source installer rather than saved in Pi's transcript; Pi-managed npm installs use Pi/npm's normal output and logs. Package managers may retain their own logs/caches and install their own dependencies. Homebrew auto-update, analytics and sudo use (HOMEBREW_NO_SUDO=1) are disabled for the installer subprocess, not as global preferences. Subprocesses have no interactive stdin; password/authentication requirements fail rather than being automated. Cancellation sends SIGINT and then SIGKILL to owned process groups and observed descendants, including Homebrew's separate command groups. Before each signal, a bounded ps snapshot rechecks process IDs, groups and start times, never arguments or environment. Missing or changed metadata prevents descendant/group signals; only the still-live direct child has a fallback signal. Inspection and POSIX signalling are not atomic, and start-time precision is platform-limited, so cleanup remains best-effort if processes escape or cannot be verified. This is not an OS sandbox. Setup does not launch apps, change shell profiles, force graphics protocols, or install anything on session startup. Local settings backups can contain private settings: keep them private and remove them yourself when no longer needed.
Formula source and TUI rasters stay in memory, apart from the graphics stream sent to the terminal. They are not added to messages or deliberately logged/saved. Terminal logging, scrollback and terminal-managed image caches are outside the plugin's control. Worker diagnostics are discarded. A renderer is not an OS sandbox.
Automatic local transcript image reads remain confined to the working directory. Unsupported platforms and network/UNC paths are rejected before filesystem access. Symlinks and opened descriptors are checked using /usr/sbin/lsof on macOS or /proc/self/fd on Linux; missing verification retains references. FIFOs/non-regular files are rejected. Unsupported platforms, including native Windows, do not read unverifiable local images.
The draft uses a separate, exact-file loader with the same supported-platform/descriptor requirements, not a broader transcript allowlist. Outside-file consent is memory-only and pinned to canonical paths plus device/inode, mode, size and modification/change timestamps; these are rechecked around opening and reading. Path substitution or file mutation fails closed. Removing a reference, clearing/submitting the draft, disabling all draft views or image display, or unloading revokes the applicable consent. Input and dock share this loader: draft off alone does not revoke files still used by rich input. Draft text and image bytes are not deliberately logged, saved or uploaded by either preview; terminal output/caches still fall outside its control. No input remote or data: image is fetched/decoded. Internally generated raster data for an already authorized local file is only a rendering handoff, not permission to load arbitrary embedded input.
The adapter never routes draft image tokens through the transcript loader. Changing the selected draft-image references, emptying/submitting the draft, disabling all draft views or image display, or disposing the draft service also clears its shared visual cache and input/dock placements and retires its worker/browser; stale results cannot restore revoked data. Cursor/layout changes clear only affected placements, not cached visual data or file consent. The explicit viewer retains its own independent, invocation-local authorized snapshot until dismissed.
Browser previews are explicit. Remote images require per-preview confirmation, listing hosts rather than private query parameters. Approval permits bounded public HTTPS requests/redirects, not sending the conversation; URLs themselves may contain sensitive parameters. Credentials, custom ports, LAN/loopback/link-local destinations and unsafe schemes are rejected; DNS is pinned and every redirect revalidated. No cookies, auth headers or referrers are forwarded.
Preview HTML embeds local fonts, KaTeX CSS, Highlight.js and Mermaid; no CDN is used. CSP blocks external connections, frames, forms and arbitrary scripts. Only nonce-authorized bundled Mermaid runs in strict mode, without initialization directives, click handlers or external icon packs. External SVG/HTML images are not loaded. Ordinary clickable links can contact their destinations when followed. Heading slugs handle duplicates and the preview includes an outline and footnotes.
Limits include:
- Rich input: 16,384 source characters, 128 blocks, 256 rendered rows per block; native viewport limit
max(5, floor(terminalRows * 0.30)). Oversized/unsafe projections fall back to source. Typing assistance has the same source cap and retains at most 32 owned delimiter pairs. - Separate dock: 16,384 source characters; a tail viewport capped at 18 rows / 35% terminal height, with a paused notice above the source limit. These are dock bounds, not rich-field bounds.
- Shared draft images: at most four local references, 8 MiB per file / 16 MiB total original file bytes (not base64 string length), four million pixels and 8,192 pixels per side. Reads are serial with five-second deadlines; a timed-out OS operation must retire and close its descriptor before another reader starts. Unchanged failed entries do not retry on every repaint.
- Transient input/dock math shares one bounded lazy worker/cache, separate from transcript math. Input admits at most eight image requests across all blocks per projection pass; the dock admits eight per component pass. Input, dock and transcript each own independent Kitty placements/transport budgets. The worker/cache bounds below apply per cache and transport bounds per transport.
- Transcript math: 8,192 source characters, 64 image requests per component pass, 32 queued/active jobs and 256 KB request storage, five-second job deadlines, one active/retiring worker. A broken worker or three consecutive timeouts disables new workers until reload.
- SVG geometry: 128 entries / 4 MB / 4,096 attempts. Rasters: 96 entries / 16 MB / 4,096 attempts. Evicted/failed requests do not restart endlessly during repaint. Kitty transport: 128 retained images / 16 MB encoded / 32 million decoded pixels; 4,096 bounded ID keys. A PNG is at most 2 MB / four million pixels; cell canvases at most 4,096 pixels per side, display images at most 32 rows.
- Structural math: 2,048 source characters, 1,024 nodes, depth 48, 256 × 64 cells, 8,192 occupied cells and a cumulative work budget; 128 cached results / approximately 512 KiB. The legacy text-only Mermaid adapter retains its 8,192-character/160-line bounds only when the full visual callback is unavailable.
- Thumbnails: 8 MiB input, four million pixels, maximum side 8,192; output at most 64 × 40 pixels / 20 rows, no upscaling. Eight jobs / 24 MiB request text, five-second deadlines, 96 cached entries / 512 KiB RGBA, 4,096 attempts. Same-path files and failed/evicted results retry only after reload.
- Full-visual ownership: one transcript cache, a separate
draftCacheshared by rich input and the dock, and another independent cache for each explicit viewer. Queue, worker, result-cache and browser-layout budgets apply per cache, not once per session or per draft block. Each surface retains independent placements; draft-data revocation does not clear transcript or viewer caches. Each viewer closes its own cache on dismissal. - Per full-visual cache: 64,000 Mermaid source characters, 1,000 edges/vector primitives, 20,000 DOM nodes; 15-second jobs and 10-second browser launch. Eight pending jobs / 24 MiB request storage; 64 completed entries / 16 MiB, 128 negative entries / 30 seconds; 16 SVG layouts / 4 MB. Viewports are at most 240 columns × 100 rows, 4,096 pixels per side / four million pixels / 2 MB PNG. Camera zoom is 0.25–4,096 times fit, with latest-camera coalescing. Inline transcript previews use up to 24 rows / 60% terminal height; draft previews fit their smaller viewports. Automatic transcript image snapshots retain at most 64 references / 24 MiB encoded-string storage;
clear-imagesretries them. Visual selection is limited to 256 KB Markdown / 64 items; embedded references to 256,000 characters. Original raster inputs retain the 8 MiB / four-million-pixel / 8,192-side bounds. - Preview: 256 KB Markdown, 128 formulas of at most 8,192 characters, 24 diagrams of at most 50,000 characters / 500 edges, 12 distinct images, 8 MB per image / 24 MB embedded total including repetitions; 20-second total network deadline, five seconds per request, two redirects.
Preview directories are private (0700), HTML files 0600; at most eight previews are retained and removed on normal reload/shutdown. A crash can leave temporary files; browser memory/history and user-saved copies are not cleaned by the plugin.
Verification
cd Pi/rich-markdown
npm ci --ignore-scripts --legacy-peer-deps
npm run check
npm test
npm run test:package
npm audit --omit=dev
bash -n install.sh
node --check scripts/install.mjs
Run these developer checks from a source checkout, not the npm tarball. For a standalone source snapshot, omit cd Pi/rich-markdown and run from the snapshot root. Release metadata checks validate the complete package-local MIT notice without repository ancestors; an isolated regression also rejects missing or damaged notices without recursively running tests. In an Orbit Tools repository checkout only, additionally run cmp LICENSE Pi/rich-markdown/LICENSE from the repository root to check equality with the root notice. That repository-only comparison is separate from standalone npm test.
test:package also runs as part of npm test: it packs an isolated tree with synthetic privacy probes, checks exact tarball paths/bytes, and loads the extracted package from a real node_modules path through the selected real Pi host with the checkout's locked libraries. It exercises native math/thumbnail/visual workers, bundled preview assets and Pi's npm-name/filter registration semantics without contacting a registry or changing live settings.
The full suite requires macOS/Linux, a matching Pi SDK/TUI pair at exactly 1.3.0 or 1.4.0 and the repository Translator card. Run it once for each supported host using PI_SDK_PATH; tests and benchmarks pass the actual loaded SDK version to the compatibility guards. Unknown versions (including other patch, prerelease and build-suffixed versions) and mismatched SDK/TUI pairs are rejected. Real-browser visual tests also need installed Chrome/Chromium; they explicitly skip when it is absent, which is not a browser-verification pass. RICH_MARKDOWN_BROWSER selects a nonstandard executable. Host discovery does not depend on the author's home directory. Set PI_SDK_PATH to the desired SDK's dist/index.js; TUI resolves from that same installation. A standalone copy needs PI_TRANSLATOR_CARD_PATH pointing to Translator's pi/card.mjs. Missing dependencies fail, not silently skip. Type checking resolves declarations in memory, without generated host files. Native Windows full-suite execution is unsupported; its no-filesystem fallback is tested with mocks, never a real network share.
0.0.9 verification (2026-10-28, macOS, Node.js 26.12.0): post-fix npm run check and npm test -- --test-concurrency=2 passed on the official matching SDK/TUI pairs: 687 tests on Pi 1.3.0 and 691 on Pi 1.4.0, with zero failures/skips. Locked dependency installation and all 31 release-policy tests passed. Both the source dependency tree and a clean isolated npm-tarball installation audited with zero production vulnerabilities. The real installed package passed native worker/preview loading and isolated Pi CLI install/repeat/list/remove fixtures on both hosts; no live settings or installations were used. The plain-ESM raster validator produces byte-identical JavaScript to the previous TypeScript implementation after type erasure. Release approval requires the commit-based validator on the committed 0.0.9 candidate against then-current origin/main, followed by validation of the release merge against its first parent before tagging/publication. These are separate release gates, not claims of approval or publication. Physical-terminal graphics, IME and Linux execution remain unverified.
Previous 0.0.8 Pi compatibility verification (2026-10-22, macOS, Node.js 26.12.0): the updated source passed npm run check and npm test with 688 tests, zero skips on Pi 1.4.0, and 684 tests, zero skips on Pi 1.3.0, each selected explicitly with PI_SDK_PATH. The four additional 1.4.0 cases cover native CJK emphasis, incomplete-math/table parsing and cancellation with another real Pi dialog above/below draft consent. Locked dependency installation, npm audit --omit=dev (zero vulnerabilities), shell syntax and installer syntax checks passed. These are local synthetic/host checks, not physical-terminal or Linux acceptance.
The draft regressions cover literal source/code and incomplete math, path parsing, commands/defaults, empty/submitted/off cleanup, stale-result rejection, exact-file consent/revocation, symlink/metadata races, serial deadlines and size/pixel limits. test/editor.test.mjs and test/editor-assist.test.mjs cover in-field whole-block rendering/reveal, cursor/mouse navigation, native paste/undo/submission and shortcuts, Unicode widths, custom-editor/autocomplete fallback, independent graphics placements, reversible hooks, list/task/quote continuation, owned pairs and unambiguous math completions. These describe regression scope, not a final test-run result. Final release verification requires measured post-fix checks; earlier measurements in the changelog's local-candidate history apply only to those snapshots, not to the final release.
Physical-terminal graphics, IME behavior and Linux execution remain unverified. Manual checks still need typing, undo, autocomplete/history, IME positioning, clipboard/path paste, consent deny/approve, resize and both TUI modes in graphics and text-only terminals. Confirm whole-block source reveal and exact native source submission, undo of explicit assistance, and that disabling only the dock leaves rich input active. Automated cursor-marker/protocol tests cannot establish real composition-window or pixel behavior.
Tests use synthetic content, isolated configuration, real Pi components/extension loading, xterm cell emulation and mocked HTTPS; no credentials or paid model calls. Coverage includes streaming closure, real custom/Translator cards, immutable source, literal code, source-copy/prompt controls, image-setting reload, wrapping/ANSI attributes, both TUI modes, same-size redraw/resume, resize/overlays, status command loading and keyboard focus/scroll/close, status theme/Unicode/narrow-screen handling and inactive/fallback states, cache/worker limits, containment/SSRF, preview consent and cleanup. See the release notes for actual counts and unresolved platform checks. Automated protocol/cell tests do not establish physical graphics quality or browser appearance. Installer tests use synthetic package/app inventories, isolated settings and mocked npm/Homebrew commands; real Node child processes test cancellation and argument handling. They do not install a desktop terminal or prove a live Homebrew/distro download succeeds.
Run node scripts/benchmark.mjs for synthetic closed-formula-to-placeholder timing through the real assistant component, worker and 32 ms repaint scheduler (no terminal transport/GPU). Optional synthetic proofs: node test/kitty-proof.mjs composites actual transmitted PNGs into a cell grid; FORCE_COLOR=3 node test/render-proof.mjs makes text-cell proofs (--math / --inline variants). Both print a private temporary directory; remove it when finished. These are not live screenshots. System-font fallback can differ from a terminal. Manually check all demos in Ghostty/Kitty and Apple Terminal, and preview demo in a browser. If a browser harness blocks local files, do not bypass it with a server.
Versions, rollback and removal
Version 0.0.9 prepares the first npm distribution; earlier versions were GitHub/source releases, not npm rollback targets. The GitHub 0.0.7 release dated 2026-10-19 follows published 0.0.6. Earlier snapshots already labeled 0.0.7 remain explicitly recorded as local-candidate history, not a second GitHub release or an additional tag. Version 0.0.4 was the first repository source release. The earlier local sequence 0.0.1 → 0.0.2 → 0.0.3 is documented history, not independently recoverable Git releases. See the changelog and import provenance. Development uses rich-markdown; release tags are rich-markdown-v<version>. Existing package identity, commands and persisted entry IDs are retained. Dependency/Pi versions are independent of the plugin version; old demo entries are not migrated.
Use off for immediate native rendering/input fallback and to clear the dock. input source disables rich input and its assistance while leaving transcript rendering and the dock preference unchanged; assist off disables only typing help; draft off disables only the separate dock. All leave existing editor source intact. To roll back from npm, first stop sessions using it and remove only its npm registration, then register the previous stable source path with its original filters and reload. Do not attempt to install an unpublished older npm version or keep two copies. To remove this npm version, run pi remove npm:fhgs-pi-rich-markdown@0.0.9 (add --local for project scope), then restart/reload Pi. To uninstall a stable source copy, run pi remove /absolute/path/to/that/copy, then /reload. For legacy local/rich-markdown, remove only that package entry from Pi settings. After unloading, optionally remove that package directory and <agent-dir>/rich-markdown.json (including its input, assist and draft preferences). Exact-file draft consent is memory-only; there is no separate permission file to remove. Do not remove other extensions, settings or conversations. Inspect leftover pi-rich-preview- and pi-rich-visual- temporary directories after a crash before deleting them. Remove any RICH_MARKDOWN_BROWSER override yourself if no longer needed; Chrome/Chromium is not uninstalled by removing this package. Saved synthetic demo entries remain. Ghostty/Kitty and Homebrew are independent applications: removing Rich Markdown does not uninstall them or their dependencies. Installer-created settings backups and failed stable copies are retained for deliberate inspection/cleanup; do not restore an old settings backup over newer unrelated changes.
License
MIT. Dependency licenses/notices remain with their packages. The design references credit related Pi extensions and the graphics specification; this package neither installs nor depends on those competing renderers.