Extensions overview
Extensions are manifest-driven fence-block renderers. They add new rendered output to Sigla without modifying the app itself — a directory with a sigla.json manifest plus, optionally, some assets and a process binary spec.
This page explains what’s already there, how user extensions get loaded, and what to expect when you install one. For authoring your own, see Extensions — authoring.
Bundled extensions
Three extensions ship inside the signed Sigla.app:
| Extension | Fence labels | Render kind | Needs external binary? |
|---|---|---|---|
| PlantUML | plantuml | process | Yes — brew install plantuml |
| Graphviz | dot, graphviz | process | Yes — brew install graphviz |
| Gherkin | gherkin | template | No |
Each appears in Settings (⌘,) → Renderers with a bundled (blue) badge. They load even when you have no ~/.config/sigla/extensions/ directory.
When a process-backed extension’s binary isn’t installed, the fence renders a placeholder telling you the brew install command. The source stays visible — nothing disappears.
Two render kinds
template— pure HTML substitution. The manifest declares an HTML template with{{SOURCE_ATTR}}and{{SOURCE_BODY}}placeholders, which Sigla fills with attribute-escaped and body-escaped versions of the fence contents. Gherkin works this way.process— Sigla spawns a configured binary, pipes the fence body to its stdin, and renders the binary’s stdout as SVG, HTML, or plain text. PlantUML and Graphviz work this way.
User extensions
Drop a directory into ~/.config/sigla/extensions/<id>/ with a sigla.json manifest inside, then press ⌘⇧R (View → Reload Extensions). The extension shows up in Settings → Renderers with a user (green) badge.
[!NOTE] Sigla respects
$XDG_CONFIG_HOMEif set. If you’ve moved your XDG config root, extensions live at$XDG_CONFIG_HOME/sigla/extensions/.
Quick install path
For an extension shared as a directory (zip, git clone, copy-paste from /Applications/Sigla.app/Contents/Resources/Extensions/):
# 1. Drop the directory into place.
cp -R ~/Downloads/my-extension ~/.config/sigla/extensions/my-extension
# 2. Tell Sigla to rescan.
# In Sigla: press ⌘⇧R (or View → Reload Extensions).
# 3. Verify it loaded.
# Settings → Renderers should list it with a green `user` badge.
The directory name must match the id field in sigla.json exactly — they’re cross-checked at load.
Override warning
If you install a user extension with the same id as a bundled one, the user copy wins (that’s the whole point of being able to override). Sigla:
- Surfaces an amber
overridechip in Settings → Renderers. - Prompts once, on first appearance, asking you to confirm the replacement.
[!WARNING] A user-installed extension can declare a different binary, different assets, and different HTML. Id-shadowing is the highest-value attack surface for extensions, so the override is deliberately friction-y. Accept only if you actively chose to override the bundled version.
The kill switch
Settings (⌘,) → Renderers → Enable extensions turns off all extensions, bundled and user alike. Built-in renderers (Mermaid, Vega-Lite, CSV/TSV) stay on. Useful for:
- Confirming a rendering bug isn’t extension-induced.
- Temporarily disabling everything while debugging a broken user extension.
- Running Sigla in a known-minimum-surface mode.
Per-extension toggles let you disable a single extension without affecting the others.
Security model (high level)
User-installed extensions go through extra guarding that bundled extensions don’t need:
- HTML strings (
render.html,missing.html,error.html) pass through an allowlist sanitizer. No<script>, noon*handlers, nojavascript:URLs, no unknown tags. - Process spawns are constrained: absolute binary paths only (no
PATHlookup), literal args (no source-body templating into args), stdin-only input, enforced timeouts, environment-variable allowlist. - Manifest hard limits: 64 KB manifest, 32 assets per extension, 2 MB per asset file, 50 MB per directory, 16 KB per HTML slot. Violations are reported in the Diagnostics section.
Bundled extensions bypass HTML sanitization — trust derives from the app’s code signature, and the bundled sigla.json files are SHA-256-verified at load.
For the full schema and limits reference, see Extensions — authoring.
Reload semantics
⌘⇧R (View → Reload Extensions) re-scans both directories and:
- Picks up new extensions you’ve just dropped in.
- Picks up edits to existing manifests and assets.
- Re-runs validation. An extension that broke between reloads moves into Diagnostics; one that was fixed moves back into Installed.
- Re-resolves process binaries — useful after
brew upgrade plantumlmid-session.
The currently open document re-renders automatically after a reload.
Where extensions come from
- Personal: write your own, drop it in
~/.config/sigla/extensions/. - Shared: open a PR to github.com/slantedt/sigla/extensions/. Curated extensions will surface in an in-app catalog in a follow-up phase, once a few entries exist.
- Bundled: contribute upstream via the main repo if your extension belongs in the default install.
Cross-references
- Settings — Renderers — the per-row controls in detail
- Extensions — authoring — manifest schema, asset rules, sanitizer allowlist
- CLI reference —
SIGLA_BINARY_*env vars for redirecting process binaries