# Business Process & System Mapper

This directory contains the new Essential Tools implementation, built on Mermaid 11.17.2. It does not contain the private corporate site frame or a fork of Mermaid Live Editor.

`mount(root: HTMLElement): () => void` in `index.ts` mounts the vanilla TypeScript editor and returns its cleanup function. Repeated mounting of the same element reuses the existing instance. The host supplies the `.essential-tools` wrapper and the licensed font asset at `/tools-assets/fonts/NotoSans-Regular.ttf`.

## Shared browser and local CLI APIs

- `processSchema`: Zod 4 schema, compatible with `z.toJSONSchema`.
- `validateProcess(input: unknown)`: `{ok:true,value,warnings}` or `{ok:false,errors,warnings}`. Pure validation, no DOM or network.
- `parseProcessJson(text: string)`: bounded JSON parsing and validation.
- `processExamples`: fictional `onboarding`, `approval`, `service`, and `systems` examples.
- `compileGuided(graph)`: deterministic Mermaid source. Labels are encoded through one conversion layer; IDs are separate from labels.
- `validateSource(source: string)`: checks the deliberately supported source subset. `renderProcess` also runs the actual Mermaid parser.
- `renderProcess(state)`: browser-only asynchronous rendering, returning `{svg,source,width,height}`.
- `svgToPng(svg)`: converts a current, sanitized render result to PNG bytes in the browser.
- `processPdf(rendered)`: converts a current render result to a real PDF with its complete diagram.

The CLI uses these same adapters in its local headless browser. It does not call a rendering service. Do not pass arbitrary uploaded SVG to `svgToPng`: SVG upload is not part of this tool's input surface.

## Source subset

Flowcharts begin with `flowchart TB`, `flowchart LR`, or equivalent `graph` syntax. `TD`, `RL`, and `BT` are also accepted in source mode. Use one statement per line, safe alphanumeric IDs, quoted labels, and `-->`, `-.->`, or `==>` arrows. Arrow labels use `-->|"Yes"|`. Supported node forms are `["Step"]`, `(["Start or end"])`, `{"Decision"}`, `[["System"]]`, and `[("Data store")]`. Arbitrary raw HTML, links, click actions, user CSS, configuration, images, icons and additional Mermaid diagram types are rejected.

Sequence diagrams begin with `sequenceDiagram`. The subset supports participant/actor declarations, optional `as` labels, messages, notes, activation/deactivation, `autonumber`, and bounded `alt`, `opt`, `loop`, and `par` blocks. Configuration and external-resource features remain disabled.

Editing generated source requires confirmation and preserves a copy of the previous guided graph. Returning to guided mode requires explicit restoration or a new map. Source is never claimed to be automatically convertible back into editable steps. JSON identifies the authoritative mode and keeps the recoverable graph when present.

## Safety and limits

Inputs are limited to 100 nodes/participants, 200 edges/messages, 30 KB of UTF-8 source, 150 KB of process JSON, 420 source statements and eight sequence block levels. Guided labels have a 160-character limit, optional team names 100 characters and descriptions 400 characters. Graph loops are allowed; missing links and disconnected components receive appropriate errors or warnings.

Mermaid uses fixed strict configuration with HTML labels and interactions disabled. Renderer calls are serialized; the editor coalesces changes and checks revisions before showing or exporting results. Imported input cannot set engine options. DOMPurify applies an SVG allowlist; a second attribute pass removes external references. Renderer-provided CSS is removed and replaced with trusted local styling. One layer of numeric entities is decoded into sanitized text nodes, never interpreted as HTML, because Mermaid strict SVG labels otherwise display encoded business punctuation literally.

The preview displays the sanitized SVG as an image, which has no script or link interaction. This isolates the displayed output; the parser itself still runs in the page. Pause stops pending/replacement updates, but cannot interrupt already executing synchronous renderer code. The UI makes this limitation explicit.

Exports embed the same locally loaded Noto Sans font used for measurement, with its preserved OFL licence in the source kit. Exact font coverage is checked through the shared font helper. Unsupported glyphs produce an actionable error; JSON and Mermaid exports still preserve the original text. No glyphs are silently substituted.

SVG output is limited to 5 MB, 20,000 SVG elements and 20,000 pixels on either axis. PNG rasterization is bounded to 4,096 pixels on the longest edge and 12 million pixels. When a map would need to shrink below half size, PNG/PDF export refuses with an explanation rather than silently producing unreadable output; SVG and editable formats remain available. Printed PDF uses a complete A4 portrait/landscape diagram with margins. Large maps should be split for readable printing.

Working state stays in memory. Remembering is off until explicitly selected. Only valid drafts are saved; disabling remembering deletes the stored copy where browser settings permit. Clear-map/template/import actions confirm before replacement. The current map is preserved if import/storage operations fail. Source and labels never enter URLs or requests.

Team and description fields appear in the accessible text view and editable JSON. Diagram exports use step names and branch labels. This is a map of a process, not an automation engine, system connector, or freeform drag-and-drop canvas.

## Verification

Run `node --import tsx --test tests/tools/mapper.test.ts tests/tools/mapper.browser.test.ts` with the repository's pinned dependencies and installed Playwright Chromium. `TOOLS_BROWSER_CHANNEL=chrome` selects installed Chrome for local checks when the bundled browser is unavailable.

Tests cover all examples, safe punctuation/accented text, valid loops, IDs/connections, prototype-pollution payloads, malformed/oversized input, source mode recovery, JSON round trips, real Mermaid/SVG/PNG/PDF generation, inactive sanitized output, no external rendering requests, opt-in storage, stale-export disabling, mobile overflow, unsupported glyphs, and the 100-node/200-edge limit. Tests use an isolated loopback server and fictional inputs. Whole-site privacy, consent, CSP, navigation, accessibility and production integration require the separate host acceptance checks.
