puml-vscode Extension Specification
Mirror of
docs/specs/puml_vscode_extension_spec(1).md— the in-repo file is the source of truth.
A first-class VS Code extension for native puml sequence diagrams: syntax highlighting, diagnostics, a limited current LSP language-service surface, live preview, Markdown preview rendering, exports, and visual editing hooks. Family-aware autocomplete, hover, rename, semantic tokens, formatting, references, and code actions remain target-state unless called out in the current runtime snapshot.
This is not a thin grammar extension. This is the desktop surface for the whole product.
Runtime contract snapshot (Current, audited in issue #24)
The sections below define the target extension surface. The current shipped VS Code runtime surface that is implemented today is:
- language id
pumlwith extensions.puml,.plantuml,.iuml - starter TextMate grammar + language configuration + snippets
- activation events:
onLanguage:pumlonCommand:puml.preview.openonCommand:puml.lsp.restart
- commands:
puml.preview.open(PUML: Open Preview)puml.lsp.restart(PUML: Restart Language Server)
- thin
puml-lspclient startup controlled by:puml.lsp.enabledpuml.lsp.pathpuml.lsp.trace- empty
puml.lsp.pathresolves in order: bundledbin/puml-lsp(.exe)when present, otherwisepuml-lspfromPATH
- preview path delegates to LSP
workspace/executeCommandusingpuml.renderSvg(no private parser in extension host/webview) - render-scene inspection delegates to LSP
workspace/executeCommandusingpuml.renderScene - export adapters can delegate to LSP
workspace/executeCommandusingpuml.exportand fall back to the CLI path - diagnostic help adapters use
puml.explainDiagnosticwhen the server advertises the command - editor surface adapters can request
puml.languageServicefor the shared family/completion/syntax catalog
Current baseline guardrails:
./scripts/vscode-smoke.shchecks--dump-capabilitiesincludespuml.applyFormat,puml.renderSvg,puml.renderScene,puml.export, andpuml.explainDiagnostic, andpuml.languageService.- extension smoke script verifies preview stays LSP-backed, build artifact exists, and LSP startup fallback logic remains in place.
- completion, hover, references, rename, semantic tokens, formatting, and code actions are only shipped to the limited scope described by
--dump-capabilities; advanced VS Code features listed later in this spec stay target-state until landed in source + tests.
Name
Marketplace name:
puml
Extension ID:
puml.puml-vscode
Display name:
puml — Instant PlantUML Sequence Diagrams
Language ID:
puml
Supported files:
*.puml
*.plantuml
*.iuml
Supported Markdown fences:
puml
plantuml
puml-sequence
uml-sequence
Product position
VS Code is where a large share of diagram authoring happens. puml-vscode makes sequence diagrams feel like code:
- instant syntax highlighting
- semantic highlighting from the real language server once the semantic-token surface is promoted beyond the current limited tokenizer stream
- diagnostics while typing
- family-aware autocomplete for every primitive
- hover docs for directives, arrows, and family-specific constructs
- go-to-definition and rename for participants and aliases
- live SVG preview
- Markdown preview rendering for
pumlfences - export current file, selection, or Markdown fence to SVG/PNG/PDF
- open a visual designer without losing source-of-truth text
No Java. No Graphviz. No hidden renderer. No syntax drift.
Dependencies
puml-vscode depends on these product layers:
puml-core parser, model, layout, SVG renderer
puml-language completions, hover, symbols, semantic tokens
puml-lsp desktop LSP server
puml-syntax TextMate grammar, Tree-sitter grammar, token taxonomy
puml-markdown Markdown fence renderer contract
puml-wasm web extension and webview rendering path
puml-studio components optional visual designer surface
The extension is not allowed to implement a private parser.
Non-negotiables
- No Java.
- No Graphviz.
- No Mermaid fallback.
- No duplicate parser in TypeScript.
- No duplicate renderer in TypeScript.
- No network download on activation.
- No postinstall binary fetch.
- No telemetry unless explicitly added later with opt-in product review.
- No arbitrary shell execution.
- No remote includes by default.
- No raw SVG from untrusted source injected into webviews without renderer safety guarantees and CSP.
- No preview that disagrees with CLI output.
- No Markdown preview renderer that disagrees with
puml-markdown. - No syntax highlighter that disagrees with
puml-syntaxfixtures. - Extension host stays responsive.
- Webview rendering does not block the extension host.
- 90% coverage minimum for extension logic.
- Desktop and web behavior are both specified, even when web has reduced capability.
Architecture religion
Use a shell-and-services architecture and treat it as law.
VS Code extension host
-> language registration
-> TextMate grammar from puml-syntax
-> puml-lsp native server over stdio on desktop
-> puml-wasm worker fallback for web extension
-> preview webview using puml renderer
-> Markdown preview adapter using puml-markdown
-> command/export adapters
Rules:
- The VS Code extension is a shell.
- The LSP server owns language intelligence.
- The renderer owns SVG.
- The Markdown adapter owns fence discovery/rendering in Markdown preview.
- The webview owns presentation and interaction.
- The extension host owns command routing and VS Code integration.
- The extension host does not parse source except to locate active editor selections/fences when delegating to services.
- The preview never renders stale source intentionally.
- The preview and export commands use the same engine.
- Every command has an integration test.
- Every UI state has a deterministic backing model.
Workspace layout
extensions/
vscode/
package.json
README.md
CHANGELOG.md
LICENSE
src/
extension.ts
client/
lsp.ts
commands.ts
config.ts
language.ts
markdownPreview.ts
previewPanel.ts
export.ts
workspaceTrust.ts
web/
extension.web.ts
wasmLanguageService.ts
webview/
preview.ts
preview.css
preview.html
designerBridge.ts
test/
unit/
integration/
e2e/
syntaxes/
puml.tmLanguage.json
language-configuration.json
snippets/
puml.json
media/
preview.js
preview.css
bin/
darwin-arm64/puml-lsp
darwin-x64/puml-lsp
linux-x64/puml-lsp
linux-arm64/puml-lsp
win32-x64/puml-lsp.exe
wasm/
puml_wasm_bg.wasm
puml_wasm.js
Platform-specific packaging may split binaries into platform VSIX packages, but the source layout remains explicit.
VS Code contribution points
Required package.json contributions:
Rules:
- Contribution declarations are exhaustive and documented.
- Commands use stable IDs under
puml.*. - Settings use stable IDs under
puml.*. - Markdown preview integration activates lazily when Markdown preview opens.
Language configuration
language-configuration.json must support:
- comment toggling with
' - word pattern for participant aliases and quoted names
- bracket/paired token awareness where useful
- indentation for blocks
- folding markers for diagram blocks and sequence blocks
Required block pairs:
@startuml / @enduml
note / end note
hnote / end note
rnote / end note
ref / end ref
title / end title
legend / end legend
skinparam sequence { / }
box / end box
alt / end
opt / end
loop / end
par / end
break / end
critical / end
group / end
Rules:
- Language configuration gives basic editing behavior before LSP starts.
- Folding from LSP overrides or augments declarative folding when available.
Syntax highlighting
Required layers:
- TextMate grammar from
puml-syntaxfor immediate lexical highlighting. - Semantic tokens from
puml-lspfor participant identity, aliases, unresolved refs, lifecycle state, and primitive semantics.
Rules:
- TextMate grammar is copied or generated from
puml-syntax, never edited privately in the extension. - Semantic token legend matches
puml-syntaxspec. - Themes can style
pumlscopes without requiring custom extension themes. - Highlighting works before the LSP server finishes starting.
- Semantic highlighting improves correctness after the server is ready.
LSP client
Desktop mode launches puml-lsp over stdio.
Target capabilities. Current shipped scope is the runtime snapshot above and the limited scopes emitted by --dump-capabilities:
textDocument/didOpen
textDocument/didChange
textDocument/didSave
textDocument/didClose
textDocument/publishDiagnostics
textDocument/completion
completionItem/resolve
textDocument/hover
textDocument/definition
textDocument/references
textDocument/documentSymbol
workspace/symbol
textDocument/rename
textDocument/prepareRename
textDocument/codeAction
workspace/executeCommand
textDocument/formatting
textDocument/rangeFormatting
textDocument/foldingRange
textDocument/selectionRange
textDocument/semanticTokens/full
textDocument/semanticTokens/range
textDocument/inlayHint
Required custom LSP commands:
puml.renderSvg
puml.renderScene
puml.export
puml.explainDiagnostic
puml.applyStyle
puml.insertParticipant
puml.convertSelectionToDiagram
puml.listDiagramsInMarkdown
Rules:
- LSP process is restarted on crash with backoff.
- Crashes are visible in output channel.
- Stale responses are discarded.
- Workspace configuration changes are sent to the server.
- The extension does not hide server diagnostics.
Web extension mode
VS Code for the Web cannot spawn a native puml-lsp process.
Required web behavior:
- Use
puml-wasmin a worker for parse, diagnostics, render, and limited completions. - Use TextMate grammar for highlighting.
- Use semantic tokens if WASM language service exposes them cheaply.
- Disable filesystem includes unless virtual workspace support is explicit.
- Disable native binary configuration.
- Keep preview/export for SVG and source.
- PNG/PDF export depends on browser APIs.
Rules:
- Web mode is a first-class reduced mode, not an afterthought.
- Unsupported commands produce explicit messages.
- Desktop and web share test fixtures.
Commands
Required commands:
puml.preview.open
puml.preview.openToSide
puml.preview.refresh
puml.preview.lockToFile
puml.export.svg
puml.export.png
puml.export.pdf
puml.export.source
puml.export.jsonModel
puml.copy.svg
puml.copy.png
puml.copy.source
puml.check.currentFile
puml.check.workspace
puml.render.selection
puml.create.newDiagram
puml.insert.participant
puml.insert.message
puml.insert.note
puml.insert.group
puml.open.visualDesigner
puml.markdown.renderFence
puml.markdown.exportFence
puml.restartLanguageServer
puml.showOutput
puml.showAst
puml.showModel
puml.showScene
Rules:
- Every command is available from Command Palette where appropriate.
- Editor context menu exposes preview/export/check commands for
.pumlfiles. - Markdown editor context menu exposes render/export fence commands when cursor is inside a supported fence.
- Explorer context menu exposes export/check for
.pumlfiles.
Live preview
Preview panel behavior:
- Opens beside active editor by default.
- Updates on edit with debounce.
- Supports manual update mode.
- Shows inline diagnostics when render fails.
- Supports pan and zoom.
- Supports fit-to-screen.
- Supports theme selection.
- Supports export buttons.
- Supports copy buttons.
- Supports source-position mapping.
Preview pipeline:
active document version
-> render request
-> LSP or WASM renderer
-> SVG + scene metadata
-> webview render
-> click/hover maps scene node to source range
Rules:
- The preview webview has a strict CSP.
- SVG is treated as a render artifact, not arbitrary HTML.
- No external scripts.
- No external images.
- No source text embedded in comments.
- Preview update cancels stale render requests.
- Large diagrams show progress only when rendering is measurably slow.
Markdown preview support
Required behavior:
- Render
puml,plantuml,puml-sequence, anduml-sequencefences in VS Code Markdown preview. - Preserve optional source display according to settings.
- Render inline at the fence location.
- Show diagnostics inline for invalid diagrams.
- Support export/copy controls when enabled.
- Support theme selection through settings.
- Re-render changed fences on Markdown preview update.
Implementation:
- Register
markdown.markdownItPlugins. - Contribute preview CSS with
markdown.previewStyles. - Use preview script only for controls/hydration that cannot be done statically.
- Reuse
puml-markdownrenderer contract.
Rules:
- The Markdown adapter does not parse diagrams itself.
- The Markdown adapter must not break non-
pumlfences. - Invalid diagrams do not break the whole Markdown preview.
- Workspace trust controls include behavior.
Visual designer
Required command:
puml.open.visualDesigner
Behavior:
- Opens a webview designer for the current
.pumldocument. - Uses
puml-studiocomponents where possible. - Source text remains canonical.
- Visual edits generate source patches.
- The user can inspect source diffs before applying destructive rewrites.
- Designer supports participants, messages, notes, groups, lifecycle, and styling presets.
Rules:
- No hidden diagram JSON stored beside source.
- No visual edit creates syntax outside the language spec.
- Designer cannot save an invalid diagram unless user explicitly chooses to keep invalid source.
Autocomplete
Completion sources:
- sequence primitives
- participant names
- aliases
- note placements
- group kinds
- lifecycle commands
- skinparam names
- arrow operators
- theme names
- include paths
- snippets
Rules:
- Context-aware completions come from LSP.
- Snippets provide fast templates before LSP resolves context.
- Completion labels are concise.
- Completion docs explain syntax and include examples.
- Completions never insert unsupported syntax.
Hover
Hover required for:
- directives
- participant declarations
- aliases
- participant references
- arrows
- note directives
- group directives
- lifecycle commands
- skinparams
- diagnostics
Participant hover includes:
- display name
- alias
- kind
- declaration location
- lifecycle state when meaningful
- references count when cheaply available
Rename and refactor
Required:
- Rename participant alias.
- Rename participant display name where safe.
- Rename updates references across diagram block and includes when enabled.
- Code action to add explicit participant declaration for implicit participant.
- Code action to resolve ambiguous reference.
- Code action to fix common arrow typos.
- Code action to wrap selected messages in
alt,loop,opt, orgroup. - Code action to extract selected messages to a
refblock.
Rules:
- Rename refuses ambiguous edits.
- Refactors preserve comments where possible.
- Refactors are backed by source spans from parser/model.
Export
Required export formats:
SVG
PNG
PDF
PUML source
JSON model
Export surfaces:
- current
.pumlfile - active selection
- active Markdown fence
- all Markdown fences in current file
- all
.pumlfiles in workspace
Rules:
- SVG is canonical.
- PNG/PDF use renderer output, not a second drawing path.
- Exports never overwrite without confirmation unless explicit setting allows it.
- Exports fail with precise diagnostics.
- Batch export reports per-file status.
Settings
Required settings:
Rules:
- Defaults are secure.
- Remote includes default to false permanently.
- Settings are documented in the extension README.
- Settings changes apply without reload when possible.
Snippets
Required snippets:
startuml/enduml
participant
participant alias
actor/control/database
message
async message
dashed return
self message
note left/right/over
alt/else/end
loop/end
opt/end
par/else/end
activate/deactivate
create/destroy
ref block
title block
skinparam sequence block
Snippets must use valid syntax from the language spec only.
Workspace trust and security
Rules:
- In untrusted workspaces, includes are disabled.
- In untrusted workspaces, export still works for the active in-memory document.
- No arbitrary command execution.
- No automatic binary download.
- No remote renderer.
- Webview CSP blocks inline scripts except nonce-controlled extension scripts.
- Webview cannot read local files directly.
- Markdown preview scripts only hydrate known
pumlelements. - SVG output contains no script tags.
- File writes require explicit command or configured export path.
Packaging
Desktop packaging:
- Publish platform-specific VSIX packages where native
puml-lspsize requires it. - Include native
puml-lspbinaries in platform packages. - Include no postinstall downloader.
- Include checksums for bundled binaries.
Web packaging:
- Publish web-compatible extension bundle.
- Include
puml-wasm. - No native binary assumptions.
Marketplace targets:
Visual Studio Marketplace
Open VSX Registry
Rules:
- Marketplace README shows live preview, Markdown preview, completions, diagnostics, and exports.
- Release notes list bundled
puml-coreandpuml-lspversions. - Extension versioning tracks product compatibility, not just extension wrapper changes.
Testing contract
Unit tests:
- configuration parsing
- command routing
- export path generation
- Markdown fence detection delegation
- webview message validation
- workspace trust behavior
- LSP client lifecycle
Integration tests:
- extension activates for
.puml - syntax grammar loads
- LSP starts on desktop
- diagnostics appear for invalid source
- completions appear for primitives and participants
- hover appears for participant and arrow
- rename updates aliases
- preview opens and renders SVG
- export SVG writes file
- Markdown preview renders
pumlfence - invalid Markdown fence shows inline diagnostic
- web mode loads WASM fallback
E2E tests:
- create new diagram from command
- edit source and preview updates
- click preview element and source range is revealed
- export current file to SVG/PNG/PDF
- export Markdown fence
- run check workspace
- restart LSP after crash
- open visual designer and apply source patch
Snapshot tests:
- generated package.json contributions
- language configuration
- snippets
- preview webview HTML shell
- Markdown preview rendered HTML
- extension diagnostics rendering
Coverage:
npm test --workspace puml-vscode
npm run test:integration --workspace puml-vscode
npm run test:e2e --workspace puml-vscode
npm run coverage --workspace puml-vscode -- --coverage.threshold.lines=90
Do not lower coverage. Add tests.
Performance
Targets:
- Extension activation under 100ms excluding LSP process startup.
- Preview update under 50ms for small diagrams after server is warm.
- Markdown preview with 20 small fences remains responsive.
- LSP diagnostics debounce avoids flooding during typing.
- Extension host never performs heavy rendering synchronously.
Benchmarks:
scripts/bench-vscode-extension.sh
Scenarios:
- activate extension
- open hello.puml
- render preview
- edit message line and update preview
- Markdown preview with 100 fences
- export 100 diagrams
README contract
The extension README must read like a product, not a wrapper.
Required sections:
-
One-line pitch:
PlantUML sequence diagrams in VS Code, but instant: no JVM, no Graphviz, live SVG preview. -
GIF or screenshot placeholders:
- diagnostics while typing
- autocomplete
- live preview
- Markdown preview rendering
- export menu
-
Features checklist:
- syntax highlighting
- semantic highlighting
- autocomplete
- diagnostics
- hover
- rename
- live preview
- Markdown preview support
- export SVG/PNG/PDF
- visual designer
-
Security stance:
- no Java
- no Graphviz
- no remote renderer
- remote includes disabled
-
Settings table.
-
Troubleshooting:
- LSP binary missing
- workspace trust
- Markdown preview disabled
- web extension reduced mode
Definition of done
- Extension activates for
.puml,.plantuml, and.iuml. - TextMate syntax highlighting works immediately.
- Semantic highlighting works through LSP after the semantic-token surface is promoted beyond the current limited tokenizer stream.
- Native LSP starts on desktop.
- WASM fallback works in VS Code Web.
- Diagnostics report line/column and update while typing.
- Completion, hover, definition, references, rename, code actions, folding, symbols, and semantic tokens work at the target depth defined in the LSP spec and #190.
- Live preview renders SVG and updates on edit.
- Markdown preview renders
pumlandplantumlfences inline. - Export commands work for SVG, PNG, PDF, source, and JSON model where supported.
- Visual designer opens and writes source patches.
- Workspace trust restrictions are enforced.
- No remote renderer or postinstall binary download exists.
- All commands have integration tests.
- E2E suite covers authoring, preview, Markdown, export, and failure paths.
- 90% coverage passes.
- Marketplace package includes README, changelog, license, and screenshots/GIF placeholders.
Reference docs checked
- VS Code language server extensions use a TypeScript/JavaScript language client that communicates with a separate language server process over LSP.
- VS Code uses TextMate grammars for main tokenization and semantic tokens as an additional semantic layer.
- VS Code Markdown preview can be extended with markdown-it plugins, preview styles, and preview scripts.
- VS Code supports platform-specific extension packages.
- VS Code web extensions run in a browser sandbox and cannot rely on Node APIs/native process spawning.
Reference URLs:
- https://code.visualstudio.com/api/language-extensions/language-server-extension-guide
- https://code.visualstudio.com/api/language-extensions/semantic-highlight-guide
- https://code.visualstudio.com/api/language-extensions/language-configuration-guide
- https://code.visualstudio.com/api/extension-guides/markdown-extension
- https://code.visualstudio.com/api/extension-guides/web-extensions
- https://code.visualstudio.com/api/working-with-extensions/publishing-extension