Add direct diagram connections, movable ports, and contextual authoring

This commit is contained in:
2026-09-06 02:13:49 +03:00
parent 35133de650
commit fef2e0dbce
39 changed files with 7076 additions and 499 deletions
+45 -5
View File
@@ -638,7 +638,7 @@ generalization links. Decomposition and Overview retain general containment;
Overview also exposes all relationships. Changing the projection hides
inapplicable placements without deleting them or changing semantic records.
Ports are calculated boundary anchors of visible owners, with their existing
Ports are boundary anchors of visible owners, with their existing
semantic identity. An explicitly placed port is not rendered as a separate
large node. Functional exchanges use their declared source/target ports;
boundary exchanges attach to their participant ports even if those ports have
@@ -648,13 +648,52 @@ may terminate at a visible ancestor without creating a new port or exchange.
``node`` has an alias and identity but no display-name string. Required fields
are ``diagram`` and ``element`` references. Optional fields are ``position``
(record with x/y, default 0/0), ``size`` (width/height, default 224/94), and
``collapsed`` (false). Node identity is independent of its semantic element.
``collapsed`` (false), and ``port_anchors`` (empty list). Node identity is
independent of its semantic element.
Coordinates are absolute diagram coordinates. Placement does not alter parent,
allocation, or realization. Hiding an element from a diagram must remain
distinguishable from deleting it from the model.
Changing a node's diagram preserves the placement identity, alias, coordinates,
size, collapse state, and attached artifacts. The destination must accept the
element's layer and must not already contain another placement of that element.
size, collapse state, manual port anchors, and attached artifacts. The destination
must accept the element's layer and must not already contain another placement
of that element.
Each ``port_anchors`` entry is a PortAnchor record with required ``port``
reference, ``side`` (Left, Right, Top, or Bottom), and ``offset`` (finite
binary32 from 0 through 1). It has no separate identity or alias. The port MUST
be an existing Port directly owned by the placement's ``element``. A port MAY
have one manual anchor per placement; different diagrams MAY position it
independently. List order is preserved but has no positional meaning.
``offset`` measures a fraction of the complete projected owner edge, from top
on Left/Right or from left on Top/Bottom. Zero and one denote its corners.
The side is presentation data and MUST NOT change the port's contract,
orientation, ownership, allocations, or connected exchanges. Absent anchors use
automatic positioning. Empty lists are omitted in canonical JSON/source;
earlier schema-3 input without this field hydrates as ``[]``.
.. code-block:: text
node actor_view {
diagram @architecture; element @vessel;
port_anchors [{ port @communication; side Top; offset 0.25; }];
}
``SetPortAnchor { diagram, node, anchor }`` upserts by port identity and retains
unrelated entries. ``RemovePortAnchor { diagram, node, port }`` restores
automatic positioning; it is a no-op only for an existing direct child port
of that placement. Unknown fields, duplicate port references, non-port or
foreign-owner references, and invalid offsets are structural errors. Each
anchor counts as one record against ``ParseLimits.max_records``.
These commands use the same atomic history, conditional REST transactions, and
source writeback as other presentation edits. Source references resolve across
files, and anchor comments follow port identity. Reidentifying a port updates
anchor references; deleting it removes its anchors. Reparenting MUST repair
old-owner anchors in the same transaction, for example by removing them before
the Reparent command. Moving, resizing, arranging, or folding an owner retains
its authored sides and fractions. Frozen schema-1/schema-2 readers do not accept
``port_anchors``; their explicit migration supplies an empty list.
Each ``routes`` entry is an EdgeRoute record with a required ``edge`` reference
to an existing Relation or Trace, ``waypoints`` (default ``[]``), and ``label``
@@ -986,7 +1025,8 @@ preserve authored comments and whitespace on Apply while inserting missing
identities. Explicit canonical export remains a separate operation. Project
update/export distinctions are described below.
Camera position, selection, source cursor, and undo history are not stored
model fields. Layout and collapse state inside NodePlacement are model data.
model fields. Layout, collapse state, and manual port anchors inside
NodePlacement are model data.
The pure ``format_bundle`` exporter uses the same typed declaration writer as
``format``. It creates a small entry file, layer/category modules, separate