Metadata-Version: 2.4
Name: spatial-runtime
Version: 2.0.0
Summary: An LLM-native persistent spatial drawing runtime
Author: Spatial Runtime Contributors
License-Expression: MIT
Keywords: drawing,svg,scene-graph,llm,geometry
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Classifier: Topic :: Multimedia :: Graphics
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: coverage[toml]>=7.6; extra == "dev"
Requires-Dist: hypothesis>=6.120; extra == "dev"
Requires-Dist: jsonschema>=4.23; extra == "dev"
Requires-Dist: mypy>=1.14; extra == "dev"
Requires-Dist: playwright>=1.49; extra == "dev"
Requires-Dist: ruff>=0.9; extra == "dev"
Dynamic: license-file

# Spatial Runtime

**A zero-dependency semantic drawing runtime for Python.**

Spatial Runtime combines a persistent scene graph, geometric constraints,
atomic editing, versioned documents, reactive rendering, and a local
interactive Studio. Drawings are ordinary Python programs, while every object
remains addressable through a stable semantic ID.

Use it to build diagrams, illustrations, generated graphics, and
machine-editable scenes that retain their structure after rendering.

## Why Spatial Runtime?

- **Semantic scenes** — address objects by IDs such as `hero.head`, not by
  fragile array positions.
- **Structured geometry** — preserve hierarchy, styles, anchors, relations,
  constraints, metadata, dependencies, roles, guides, and z-order.
- **Safe editing transactions** — solve and validate before committing, with
  automatic rollback when an edit is invalid.
- **Multiple outputs** — generate deterministic SVG, PNG, PDF, canvas,
  inspection, and feedback documents.
- **Reactive workflow** — watch drawing files and their local imports, retain
  the last good render after an error, and avoid unchanged artifact writes.
- **Local Studio** — inspect, select, drag, edit, preview, undo, and export a
  scene in the browser.
- **Zero runtime dependencies** — install the package without pulling in a
  third-party runtime stack.

Spatial Runtime requires Python 3.11 or newer.

## Installation

Install the package from PyPI:

```bash
python -m pip install spatial-runtime
```

Confirm that the command-line interface is available:

```bash
spatial --help
```

## Quick start

Create `drawing.py`:

```python
from spatial import Circle, Rect, Scene

scene = Scene(600, 400, id="portrait")
scene.group("hero")

scene.add(
    Circle(
        (300, 130),
        55,
        id="head",
        role="structural",
        style={"fill": "#ffd8ad", "stroke": "#17131f", "stroke_width": 4},
    ),
    parent="hero",
)
scene.add(
    Rect(
        245,
        190,
        110,
        150,
        id="body",
        role="structural",
        style={"fill": "#ffb454", "stroke": "#17131f", "stroke_width": 4},
    ),
    parent="hero",
)

scene.relate("attached", "hero.head", "hero.body", at="neck")
scene.constrain("hero.head", horizontally_aligned_with="hero.body")
scene.solve_constraints()
```

Run the complete construct, render, inspect, and feedback cycle:

```bash
spatial cycle drawing.py --out-dir out
```

Or open the scene in Studio:

```bash
spatial studio drawing.py --open
```

## Semantic scenes

A scene is more than a list of drawing commands. Nodes keep their meaning and
relationships throughout the drawing workflow:

```python
head = scene["hero.head"]
head.anchor("neck", (300, 180))
head.set_lod(summary="circular face attached to the body")

scene.relate("attached", "hero.head", "hero.body", at="neck")
scene.constrain("hero.head", horizontally_aligned_with="hero.body")
```

Stable hierarchical IDs make scenes straightforward to inspect, patch, and
modify from Python or an automated tool.

## Atomic edits and validation

`Scene.edit()` treats a group of changes as one transaction. Spatial Runtime
solves constraints and validates the scene before committing. Solver
non-convergence or an error-level validation issue rejects the transaction,
restores the previous state, and raises `EditRejectedError`.

```python
from spatial import EditRejectedError

try:
    with scene.edit("move the head upward") as edit:
        scene["hero.head"].move(dy=-8)
except EditRejectedError as error:
    print(error.result.reason)
    print(error.result.solve_report)
    print(error.result.issues)
else:
    print(edit.result.diff)
```

Warnings, including out-of-canvas geometry, remain visible without rejecting a
valid edit. Use `allow_invalid=True` when you deliberately need to commit an
invalid state while retaining its complete diagnostics.

Undo, redo, and named snapshots are available during the active Python or
Studio session.

## Rendering and inspection

Render the same semantic scene to several targets:

```python
scene.render_svg("render.svg")
scene.render_blueprint("blueprint.svg")
scene.render_raster("render.png", scale=2)
scene.render_pdf("render.pdf")
scene.save("scene.json")

print(scene.inspect("hero", detail="full"))
print(scene.inspect("hero", detail="full", structured=True))
print(scene.occupancy("hero"))
print(scene.validate())
```

Portable outputs use explicit, versioned document envelopes:

| Document | Schema |
| --- | --- |
| Scene snapshot | `spatial.scene` |
| Declarative patch | `spatial.patch` |
| Canvas commands | `spatial.canvas` |
| Structured inspection | `spatial.inspection` |
| Reactive feedback | `spatial.feedback` |

For example, `Scene.save()` writes a lossless snapshot of the current scene:

```json
{
  "schema": "spatial.scene",
  "schema_version": 1,
  "scene": {
    "id": "portrait",
    "width": 600,
    "height": 400,
    "styles": {}
  },
  "nodes": [],
  "constraints": [],
  "relations": []
}
```

All built-in node types have exact codecs. Materialized custom `Component`
subclasses load as `FrozenComponent` snapshots that retain their class
provenance, layer metadata, hierarchy, and children. Custom `Node` subclasses
can register their own codecs.

Packaged JSON Schemas are available through `load_schema("scene")`; use
`"patch"`, `"canvas"`, `"inspection"`, or `"feedback"` for the other document
types.

## Declarative patches

> [!NOTE]
> The patch protocol is experimental and may evolve between releases.

`Scene.apply_patch()` applies a JSON-compatible set of operations atomically:

```python
result = scene.apply_patch(
    {
        "schema": "spatial.patch",
        "schema_version": 1,
        "label": "Move the head upward",
        "operations": [
            {"op": "move", "target": "hero.head", "dx": 0, "dy": -8}
        ],
    }
)
```

Patches support:

- adding, removing, and reparenting nodes;
- moving, positioning, scaling, rotating, and editing handles;
- changing styles, metadata, visibility, roles, z-order, and anchors; and
- adding or removing relations and constraints.

Operations run in order inside one transaction. An unknown operation, malformed
payload, missing target, or rejected edit rolls back the entire patch.
`dry_run=True` evaluates the patch on a clone and returns its projected diff,
diagnostics, and canvas without changing the live scene.

## Reactive rendering

Watch a drawing and rebuild when its source or local Python imports change:

```bash
spatial watch drawing.py --out-dir out --debounce 0.15
```

The reactive runner:

- waits for file changes to settle before rebuilding;
- reloads changed local modules;
- retains the last valid scene and artifacts after execution errors;
- reports failures as structured feedback and continues watching;
- writes artifacts atomically; and
- skips filesystem writes when the generated bytes are unchanged.

SVG fragments and canvas commands are cached by normalized node state.
Reloading canonical Python source starts a fresh session and clears undo/redo.

## Local Studio

> [!NOTE]
> Studio is experimental and intended for trusted local use.

```bash
spatial studio drawing.py --host 127.0.0.1 --port 8765 --open
```

Studio includes:

- a searchable semantic hierarchy with role and layer filters;
- a zoomable SVG viewport with click selection and drag-to-move;
- geometry, style, anchor, relation, constraint, metadata, and dependency
  controls;
- guide, blueprint, bounds, anchor, and role overlays;
- editable semantic handles and dry-run previews;
- undo, redo, reload, and JSON snapshot export; and
- structural diffs, changed-node highlighting, pixel-diff overlays, warnings,
  and solver status.

Studio edits only the in-memory scene and never rewrites the Python drawing.
Reloading the source discards session edits and starts a new undo/redo history.

Studio has no authentication or security boundary. Drawing files execute as
fully trusted Python, so run only code you trust and keep Studio bound to
`127.0.0.1` unless you intentionally choose otherwise.

## Source and history model

Python source is authoritative. Scene JSON captures the complete current scene
state for interchange, inspection, and export, but it does not contain
snapshots or undo/redo history.

Use Git for durable source history. Spatial Runtime intentionally does not add
a sandbox, permission system, authentication layer, or revision-control layer
around drawing files.

## Documentation

- [Architecture](docs/architecture.md)
- [Data contracts](docs/contracts.md)
- [Studio guide](docs/studio.md)
- [Feature matrix](docs/feature-matrix.md)
- [Release notes](docs/release-notes-2.0.md)

The [`examples`](examples) directory contains complete scenes demonstrating
primitives, components, constraints, patterns, fields, surfaces, skeletons,
perspective, rendering, and inspection.

## Development

Clone the repository, then install the development tools:

```bash
python -m pip install -e ".[dev]"
```

Run the main checks:

```bash
python -m compileall -q src
ruff check src tests
mypy
coverage run -m unittest discover -s tests -v
coverage report
node --test tests/js/studio.test.mjs
```

The release suite covers persistence round trips, transaction rollback, patch
atomicity, deterministic renderer documents, reactive recovery, Studio
endpoints, browser behavior, and performance at 100-, 1,000-, and 10,000-node
scene sizes.

## Project status

Spatial Runtime 2.0.0 is beta software. The core scene, persistence,
transaction, validation, rendering, inspection, and reactive APIs are stable.
The patch protocol and Studio are experimental.

Released under the [MIT License](LICENSE).
