Skip to content

feat(vscode): draw the diagram in the pilot's style, filled from a server palette - #390

Merged
HuiJun merged 4 commits into
developfrom
feature/diagram-pilot-style
Sep 19, 2026
Merged

HuiJun merged 4 commits into
developfrom
feature/diagram-pilot-style

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

What and why

The diagram panel drew every diagram in the VS Code colour theme, while the DOT and PlantUML forms of the same view follow the pilot visualizer's Standard B&W and can be filled from eight colourblind-safe palettes. This PR gives the panel the same looks, selectable.

Style list. A Style <select> in the panel toolbar, backed by a new opensysml.diagram.style setting, picks the look of every diagram:

  • theme (default) — as before, colours from the VS Code theme.
  • pilot — the pilot's Standard B&W as docs/project/view-rendering-forms.md#style specifies it: white canvas, black sans-serif text, 0.5 px #181818 borders, square definitions / rounded usages, 1.5 px packages, dashed regions, bold name over a small italic «kind», 3 px arrowless connections, dashed flows, filled black pseudo-states.
  • okabe-ito, tol-bright, tol-muted, tol-light, brewer-set2, brewer-dark2, viridis, cividis — that look filled by keyword family; a usage a lighter tint of its definition's colour, text black.

Changing the list writes the setting (at the level that set the value in force) and every open panel restyles and re-renders; the choice survives a panel restore.

Colour comes from the server, not the webview. Rather than reimplement the palette algorithm (family assignment, usage tint, WCAG-AA lightening, control-node exclusions) in TypeScript where it would drift, the render result carries it:

// internal/ir/view
type Fill struct{ Fill, Border string }
func (r *Rendering) Fills(palette Palette) (map[string]Fill, error)   // by node ID; absent = left B&W
// opensysml/render
{ "textDocument": , "view": , "palette": "okabe-ito" }          // request
{ "nodes": [{ "id": "n3", "kind": "part def", …, "fill": "#F6D9B1", "border": "#E69F00" }] }

Fills reads the same familyFills the DOT and PlantUML writers use, so the panel, a DOT export and a PlantUML export of one view agree hex for hex. The server advertises experimental.openSysmlRenderPalette; the panel asks for a palette only when it does, and against an older sysml-lsp draws pilot with a hint under the diagram saying why.

Canvas. Each box gets a class from its kind (package / definition / region / usage) so CSS can draw the pilot's shape rules, and a node's fill/border land as --node-fill / --node-border custom properties on its shape. Editing attributes (data-opensysml-id, data-kind), drag, drop-to-re-parent, waypoints and the context menu are untouched.

Not in scope. The pilot's -[thickness=5]- binding connectors: the renderer has no binding edge kind to style.

How it was verified

Go:

  • internal/ir/view: TestFillsMatchDOT pins every fill/border to the colour the DOT form writes for the same node, across palettes and view kinds; TestFillsOutsideThePalette pins that B&W nodes, unfilled containers, tables and an empty palette yield nothing, and an unknown palette the registry's error.
  • internal/frontend/lsp: render tests for a named palette (fields present, matching the artifact), no palette (fields absent from the JSON), and the capability in initialize.

Extension (npm run typecheck, npm test — 166 tests):

  • style.test.ts: registry order, labels for every style, fallback of unknown setting/saved values, paletteOf/pilotLook.
  • manifest.test.ts: the setting's default, enum and descriptions match the registry.
  • protocol.test.ts: fill/border pass through normalizeRender; an older server's nodes carry neither.
  • canvas.test.ts: box classes by kind, rounded usages, custom properties set only when both colours are present, identity attributes preserved, control nodes unfilled.

Gates run locally: go build ./..., go vet ./..., gofmt -l . (empty), make lint, go test ./... with OPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1, TestPilotLibraryXMI with the corpus downloaded, make docs-check, go run -C tools ./cmd/doc-counts -check, npm run build -- --production.

GUI verification in a real VS Code (Linux), against this branch's server and a v0.7.0 one for the fallback, is recorded in the comment below.

Checklist

  • make test and make lint pass locally
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (docs/reference/lsp.md, editors/vscode/README.md, docs/project/view-rendering-forms.md, docs/internals/design/vscode-visual-modeling.md)
  • Changelog entry added as changes/unreleased/diagram-pilot-style.added.md
  • No gate count moved
  • No internal work-item labels in the body, docs, or changelog

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Verified in VS Code (Linux)

Recorded run of the extension built from this branch against its sysml-lsp, and against a v0.7.0 server for the fallback:

  • Default is theme; the Style list offers all ten looks.
  • pilot: white canvas, black text, bold names over a small italic kind, square definitions and rounded usages, thicker package border, dashed regions, thick arrowless connections, dashed flows; initial/final/choice/history nodes stay black and white, the final's ring intact.
  • Okabe–Ito and viridis fill by family with visibly different colours; a usage is a lighter tint of its definition's; text stays black and legible.
  • Choosing from the list writes opensysml.diagram.style to user settings; editing the setting restyles both open panels; Reload Window restores both in the chosen style.
  • Editing under a palette: drag writes DiagramLayout coordinates, click reveals the source with the selection highlight, context-menu Rename rewrites references and labels.
  • v0.7.0 server with viridis chosen: draws black and white with the hint "This language server draws no palette; update sysml-lsp to colour the diagram."; switching to theme clears it.
Theme Pilot
Theme Pilot
Okabe–Ito Viridis
Okabe–Ito Viridis
Older server, palette chosen State machine, viridis
Fallback State machine

Not exercised: macOS; the other six palettes beyond their list entries.

Seen, not from this PR: automatic interconnection routing can run an edge across a label (below). The layout and routing code is untouched here; worth its own issue.

Routing overlap

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review September 18, 2026 07:18
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 3 commits September 19, 2026 18:29
…rver palette

A Style list in the diagram panel, backed by `opensysml.diagram.style`, picks the
look of every diagram: `theme` follows the VS Code colour theme as before, `pilot`
is the pilot visualizer's Standard B&W that the DOT and PlantUML forms follow, and
each of the eight palettes is that look filled by keyword family.

The colours come from the server: `opensysml/render` with a `palette` gives each
node its `fill` and `border` (`Rendering.Fills`), the same hex the DOT and PlantUML
forms of that view take, advertised as `openSysmlRenderPalette`. The canvas sets
them as custom properties and computes no colour itself; against an older server
a palette draws as `pilot` and the panel says why.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…seded style

The box class the pilot look reads no longer changes what the theme look
draws: every non-definition box keeps its rounded corners as before, and
the pilot rules square packages and regions in CSS.

A render request captures the style it was asked in; when the setting has
moved by the time the server answers, the drawing is dropped rather than
restyling the panel back, since the change already queued a render in the
new style.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration
devin-ai-integration Bot force-pushed the feature/diagram-pilot-style branch from f33e66e to 267a22a Compare September 19, 2026 18:34
devin-ai-integration[bot]

This comment was marked as resolved.

Fills gave every filled node the family colour as its border, but the
PlantUML form draws no border colour on a participant, so a sequence panel
coloured its participants' outlines while the export did not. A rendering
of KindSequence now carries the fill alone, through the same predicate the
PlantUML writer uses, and the canvas sets --node-fill and --node-border
independently so a fill without a border still applies. Fills is pinned to
the PlantUML form of every golden rendering, sequences included.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit 8a2b612 into develop Sep 19, 2026
12 checks passed
@HuiJun
HuiJun deleted the feature/diagram-pilot-style branch September 19, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant