← Files SavvyARCHIVED FILE
skills/savvy/scripts/workflow/geometry.py
1.85 KB · Oct 2, 2026 · 00:28 UTC
"""Shared approximate Savant canvas geometry for builders and validators.
These values model the rendered node body closely enough for deterministic
layout and preflight checks. They are not a replacement for screenshot review.
"""
from __future__ import annotations
from typing import Any
NODE_WIDTH = 130
NODE_HEIGHT = 145
NODE_BODY_HEIGHT = 96
OUTPUT_Y = NODE_BODY_HEIGHT / 2
INPUT_SINGLE_Y = NODE_BODY_HEIGHT / 2
INPUT_MULTI_TOP_Y = 32
INPUT_MULTI_BOTTOM_Y = NODE_BODY_HEIGHT - 32
PORT_ALIGNMENT_TOLERANCE = 16
PORT_NEAR_MISS_TOLERANCE = 72
EXTERNAL_INPUT_LANDING_MIN = 180
LABEL_AVG_CHAR_WIDTH = 6.5
LABEL_WIDTH_MIN = 130
LABEL_WIDTH_MAX = 260
def inlet_index(inlet_id: str | None) -> int:
if not inlet_id:
return 0
digits = ""
for ch in reversed(inlet_id):
if ch.isdigit():
digits = ch + digits
elif digits:
break
return int(digits) if digits else 0
def multi_port_y_offset(index: int, count: int) -> float:
if count <= 1:
return INPUT_SINGLE_Y
if count == 2:
return INPUT_MULTI_TOP_Y if index <= 0 else INPUT_MULTI_BOTTOM_Y
usable_height = NODE_BODY_HEIGHT - (2 * INPUT_MULTI_TOP_Y)
step = usable_height / max(count - 1, 1)
return INPUT_MULTI_TOP_Y + min(max(index, 0), count - 1) * step
def input_port_y_offset(node: dict[str, Any], inlet_id: str | None = None, source_id: str | None = None) -> float:
inlets = [inlet for inlet in node.get("inlets") or [] if isinstance(inlet, dict)]
if len(inlets) <= 1:
return INPUT_SINGLE_Y
return multi_port_y_offset(inlet_index(inlet_id), len(inlets))
def output_port_y_offset(_node: dict[str, Any] | None = None) -> float:
return OUTPUT_Y
def label_width_estimate(label: Any) -> float:
text = str(label or "")
return min(LABEL_WIDTH_MAX, max(LABEL_WIDTH_MIN, len(text) * LABEL_AVG_CHAR_WIDTH))
SHA-256: 73050c024d6bb1930f0cc70c929d2c6924049ff03d411800a1e6f62f7426e8d2