verso-v1.1.3
·
32 commits
to main
since this release
Release replacing the in-process Python integration with a supervised host process that runs the CPython installation already on your machine, adding plain Markdown (.md) as a first-class notebook format, drawing ipywidgets-based visualizations inside Python cells, introducing an output model that distinguishes standard error and progress from ordinary output, and bounding object-graph rendering so framework internals can no longer exhaust the output budget.
Upgrade Notes
- Python cells now need CPython 3.8 or newer installed on the machine. Verso no longer carries a Python runtime. Where no interpreter is found, a Python cell reports what was searched instead of failing silently
PythonKernelOptions.PythonDllis ignored. The property remains, so nothing fails to compile, and a session that sets it says once that it has no effect now that Python runs as a separate process. There is no other public API change: the types removed fromVerso.Pythonwere all internal
New: Python Runs on Your Own Interpreter
- Python cells execute in a separate host process that Verso supervises over a loopback connection, replacing the previous in-process integration. The embedded Python runtime is gone; cells run a CPython installation on your machine, 3.8 or newer
- Each spawn is authenticated with its own token handshake and framed with NDJSON. The accept loop keeps listening until a valid handshake arrives, applies a per-connection greeting timeout, and reports refusals and authentication failures instead of hanging
- A crashed or wedged interpreter no longer takes the notebook with it: the connection recovers, and a peer reset is treated as end of stream rather than a transport error
- Interrupting a running cell escalates per platform, SIGINT on Unix and CTRL_BREAK on Windows, respecting console ownership. Windows children are assigned to a job object, so terminating the host takes the whole process tree with it
- On POSIX the host watches the process that launched it and exits on its own if that process goes away, so an orphaned interpreter cannot linger
New: Interpreter Discovery and Selection
- Interpreters resolve in a defined precedence order: explicit configuration,
VERSO_PYTHON, the interpreter selected for the session,VIRTUAL_ENV,CONDA_PREFIX, workspace virtual environments,PATH, then well-known install locations - Candidates are probed with an introspection script and cached by modification time. A probe distinguishes runnable, abandoned, and not-runnable outcomes, and only a probe that finished successfully is cached
- Validation enforces CPython and the minimum version, and detects PEP 668 externally managed installations so package operations can explain themselves rather than failing obscurely
- Where the chosen interpreter is not writable, a derived virtual environment is created or reused, using
uvwhen it is available and stdlibvenvotherwise #!pythoninspects, lists, and selects interpreters for the session, reporting the path, version, how it was discovered, and whether the environment is externally managed--python <path>pins the interpreter forverso repl,verso run, andverso serve- Discovery is hardened on Windows: the
pylauncher is resolved by full path, WindowsApps stubs are skipped, launcher and output-drain steps are bounded by timeouts, an overrunning probe is killed instead of left to hang, and installs under%LOCALAPPDATA%\Pythonare found
New: Python IntelliSense
- Completions, hover, and diagnostics are computed in the host process against the live session, on a dedicated thread with timeouts, replacing the in-process completion provider
- The analysis package is provisioned in the background into a per-version tools directory, installed to a staging directory and published atomically so a reader never observes a partial tree
New: Python Package Handling
- A cell's imports are scanned before it runs; a package the environment lacks is offered for installation, installed, and the cell retried, with a
ModuleNotFoundErrorbackstop for imports that scanning cannot see --auto-installonverso run, and a matching environment variable, enables this without prompting- Consent prompts distinguish package installs from extension installs and name the environment being modified
- Notebook-declared requirements refuse installer options and external sources
- Installer output is summarized by default and can be switched to full detail per kernel, for pip/uv and npm alike. A failed install always prints in full
New: Cross-Process Variable Sharing
- Values cross to and from Python as data, with wire tagging for shapes JSON cannot carry natively: dates and times, exact decimals, big integers, GUIDs, byte arrays, NaN and infinity, and a
DataTableas rows - A value with no meaning outside the process that made it (a delegate, a task in flight, an open resource, an F# union case) is still bound to its name, and printing or using it explains which variable it was and why it could not cross
- Canonical fingerprinting makes identical numbers hash the same under Python's JSON writer and
System.Text.Json, which stops unchanged values from being re-injected on every execution - Per-variable size budgets, oversize notices, and status tracking. A name beginning with a double underscore is never injected, since Python reserves that prefix for the interpreter's own
New: Python Widget Rendering
- Libraries that render only as ipywidgets models, among them k3d, ipyleaflet, pythreejs, bqplot, and ipyvolume, now draw in Python cells. Widget state is packaged into a self-contained document (
text/x-verso-widget) and given its own auto-resized frame - Framed widgets follow the host theme: theme tokens are resolved to concrete colors and injected into the widget document, then re-injected when the theme changes
- A widget that exports a file, such as a chart snapshot, hands the bytes to the host, which offers a save dialog and writes them. Both a direct
click()and a synthetic click dispatched throughdispatchEventare intercepted - Widget outputs are never serialized into layout copies, because they are full documents whose scripts would not run when inlined. Layouts render them as live elements instead
- The HTML exporter unwraps them, and the terminal shows a placeholder
New: Markdown Notebooks
- Plain Markdown (
.md) is a first-class notebook format. Opening one turns prose into markdown cells and recognized fenced code blocks into executable cells. Everything else stays part of the prose: untagged fences, unrecognized tags, indented code, and fences nested inside quotes, lists, or other containers - Saving writes plain Markdown back to the same file, with no forced conversion to
.verso. Fence style, tag spelling, and CRLF line endings are preserved per cell - Cell outputs are not persisted, and neither is anything else the format has nowhere to put: parameters, layout, theme, extension requirements, and saved layout state
- An Export Verso toolbar action produces a native
.versofile carrying the cells and their current outputs, leaving the original file untouched .mdis accepted byverso serve,verso run,verso convert,verso repl, andverso export, and--to mdconverts a native notebook into a readable document- In VS Code the Markdown editor stays the default for
.mdand Verso is offered alongside it. The newverso.showOpenInVersoMenusetting hides the Explorer context-menu entry without removing the Reopen Editor With route - Serializers can declare
PreservesFormatByDefault, wired through the server, the host handlers, CLI serializer resolution, and REPL save logic - A new guide covers the format, and the README, CLI reference, cell types, language kernels, and Jupyter migration pages were updated for it
New: Output Channels, Progress, and Failure Signals
- An output carries the channel it came from, so text a cell wrote to standard error is labeled and rendered distinctly instead of blending into ordinary output
- A progress MIME type (
text/x-verso-progress) renders as a progress bar, with helpers for producing one --fail-on-stderronverso runtreats anything on standard error as a failure, with the decision centralized so exit codes and summaries agree- Background faults are tracked per notebook with attribution heuristics and a bounded queue, replacing the previous global monitor
- SQL provider notices accumulate through a provider message listener wired into the SQL kernel
Improved: Object Tree Rendering
System.*andMicrosoft.*types render throughToString()at depth 2 and deeper instead of expanding their property graphs, cutting off the Type to Assembly to DefinedTypes fan-out that could spend the entire 512 KB output budget on reflection internals, contributed by @JoeJoeflyn (#88)- Namespace matching is exact, so a user namespace such as
Systematicis unaffected. Collections are checked first, so nested lists and arrays still expand. Framework types still expand at depth 0 and 1, and user types at every depth - Opacity is applied before cycle detection, so a shared instance such as
typeof(int)renders its value rather than[circular reference] - Collections reached through framework internals are summarized instead of expanded, which bounds reflection output
- F# anonymous records format as field tables again
Improved: Cell Preview Interaction
- Dragging to select text inside a rendered cell preview no longer flips the cell into its editor when the mouse is released. Clicks on interactive controls inside a preview still reach the control, including through shadow DOM
Improved: Packaging and API Documentation
Verso.HttpandVerso.Pythonare packed and published alongside the other packages in both the CI and release workflows- XML documentation is generated for
VersoandVerso.Abstractions, so API docs appear in the editor for consumers of those packages - README revisions: the HTTP package notes TRACE and CONNECT support, that it loads automatically in notebooks, and its dependencies; the Python package documents interpreter resolution order including conda and venv locations and states that no Python runtime or native dependencies are bundled; the main README clarifies that kernels and cell types ship with the VS Code extension, the Blazor hosts, and the CLI while also being published separately
- CI and release workflows pin an interpreter with
actions/setup-pythonand exportVERSO_PYTHONinto the test steps, and preinstall the analysis package so completion tests do not reach a package index. A test prerequisite helper treats a missing runtime dependency as inconclusive on a developer machine but failing on CI
Fixed
- Widget outputs no longer flash or remount when an execution count arrives after the outputs themselves. Output error boundaries are keyed by cell identity and recovered only when a new execution is genuinely observed
- A lone carriage return in a Markdown file no longer corrupts cell slices or indexes past the end of the document
- The editor overlay in the Slide Studio layout no longer mis-stacks when a cell is selected