a thin orchestrator over a C ABI

The Python boundary

Python authors views and orchestrates. The engine is C++. The line is sharp: every model operation crosses one C ABI, and nothing that has to be fast, correct, or shared with the native app lives in Python.

Where Python stops

Python authors views and orchestrates. The engine is C++. The line between them is sharp and deliberate: anything that has to be fast, correct, or shared with the native app lives in C++; Python is the thin layer that drives it.

your app (Python)      view(state) → a kinogaki.view tree; the CLI; the server loop
   │
the C ABI  kinogaki_*  one stable seam; every model operation crosses it
   │
the C++ libraries      Core (model), Platform (runtime + transport), UI (render)

The binding

pip install kinogaki is a ctypes binding over the C ABI from the seams. A Document in Python is a handle to a C++ Document; doc.append(path, type), doc.eval(slot, time), and doc.diff(other) each call straight through kinogaki_*. No model logic is reimplemented in Python: the binding marshals arguments and hands back native values. Because the C ABI is version-agnostic C, the binding works on any CPython 3.x without recompiling per version.

The three packages

The library-to-package mapping is one to one:

PackageWrapsGives you
kinogakiCorethe model: Documents, Elements, Values, codecs, queries
kinogaki.platformPlatformthe runtime and the SDUI transport (SduiChannel, the WebSocket framing) that drive serve
kinogaki.uiUIthe native render of a view-Document, the toolkit in a window (run)

kinogaki and kinogaki.platform are portable and ship on every OS. kinogaki.ui is macOS only; off macOS it degrades to a clear ImportError and kinogaki run prints a message, while serve works regardless. How each is built and tagged is in building and shipping.

What stays in C++

The document model, the evaluator, the codecs, the diff and overlay, the WebSocket framing and the SDUI protocol, the widgets and their reconciler: all C++. A Python program never parses Prism bytes, never computes a diff, never reconciles a widget tree. It says what the view is; the C++ underneath decides what to send and how to draw it. That is why the same view renders in a browser and in a native window with no Python on either render path, and why a slow language on the authoring side costs nothing on the rendering side.