The headless half
Everything Stemma could do, it could only do with a mouse in it. This release is the other authoring surface: a model written as text, rendered by a command, and checked by a build that has never opened the app.
-
stemma render— A workspace and a view become an image, with no browser of your own open and no mouse. It runs a short-lived backend of its own, so two renders can run at once and neither disturbs a workspace you have open. - A publication profile — Outline boxes, no kind chip, no icon, no shadow, no background grid, no status badge. Transparent by default; scale, padding and palette are options. Rendering for a screen and rendering for a page are different jobs, and Stemma only had the first.
-
Layout as a constraint —
grid,row,columnandstack, solved to coordinates. A view can now say two columns, these four, 56 apart instead of carrying the residue of somebody’s mouse. A later drag records an offset against the constraint rather than replacing it, so the arrangement survives being corrected. Authorable as text, or from the canvas selection. -
stemma validate— Ids are strings and nothing checks them: a typo produces a missing node or a missing arrow, silently. This reports dangling endpoints, view members that do not exist, links with one end outside the view, and a warning past seven boxes.--jsonfor something acting on the answer rather than reading it. -
A render manifest, and
--check— Every render writes a sibling manifest fingerprinting the model, the view, the layout and the profile it was drawn from.--checkre-computes it and exits non-zero when a committed image has stopped matching its source — the drift guarantee, extended past the app window. -
True vector SVG — The publication profile emits SVG primitives out of the same component tree the canvas renders, instead of wrapping serialised HTML in a
foreignObject. The old export opened in Chrome and essentially nowhere else. -
ConceptandRelation— A box that asserts nothing about a system, and an arrow that claims nothing beyond its label. Drawing an argument previously meant declaring something like “what the repository can answer” as a bounded context — which compiles, validates, and is false. -
A published schema, and a protocol reference —
stemma.layout.jsonhas a JSON Schema, and every sidecar now carries a pointer to it. The protocol document explains the whole chain to someone who will never open the app, with three worked examples that were built and rendered exactly as written. -
Diagnostics — A leveled, structured record of what the engine did, as JSON lines under
~/.stemma/logs/, capped and rotated without being asked. Shareable bundles are redacted by default. There is no network sink and none can be configured: a log record contains element names, ownership and sometimes your source. - fix The sidecar stopped dropping what it did not model — Free-form shapes and edge dock handles were discarded on their way to disk, so both survived only until reload. Unknown sections now round-trip verbatim.
- fix Node titles wrap — They clipped at around thirty characters, which was quietly shaping what things could be called.
- fix The draw.io export became usable — It ignored the view and the layout and emitted the whole model on a grid in default pastel. It now honours both. Six further defects, found by auditing the render pipeline end to end, went with it.