Skip to content

Latest commit

 

History

History
252 lines (224 loc) · 17.6 KB

AGENTS.md

File metadata and controls

252 lines (224 loc) · 17.6 KB

AGENTS.md

Guidance for coding agents working in this uv, pnpm, and Vite+ workspace. marimo-export runs selected marimo notebook states and writes one verified export for applications, agents, Python, and custom clients.

Commands

Use the Python version from .python-version and the Node, pnpm, and Vite+ versions declared by package.json and pnpm-workspace.yaml. CI verifies the Python package on every supported version on Ubuntu and Windows.

Task Command Expected result
Install make bootstrap Locked Python and TypeScript workspaces sync
Format make format Authored source is formatted
Lint make lint Python and TypeScript boundaries pass
Type-check make typecheck Python and TypeScript types pass
Test make test Python, browser, loader, skill, and app tests pass
Build make build Python, npm, docs, and example packages build
Build docs make docs-build VitePress site and LLM text bundles build
Serve docs make docs-serve Portless prints the workspace-specific documentation URL
Package make package Python and npm release artifacts pass isolated smoke tests
Complete local gate make check Format, lint, types, tests, builds, and package smoke pass

Run focused package commands while developing, then finish with make check.

Architecture in nine rules

  1. marimo owns notebook parsing, reactive execution, dependency pruning, cell hashing, computation-cache persistence, UI updates, and native serialization.
  2. marimo-export owns StateSpace and ExportSpec normalization, observations, state planning, preparation, reusable prepared outputs, export integrity, and typed Python and browser consumption.
  3. The export repository stores preparation metadata in private SQLite tables and portable artifacts in immutable directories. Marimo's native cache remains the computation cache.
  4. Producer functions call services under _services. Those services use the private PreparationRepository. The observation ledger uses the private ObservationRepository. Reader, public repository, inspection, and diagnostic operations use their focused owners.
  5. Private marimo._* imports stay under _marimo/compat. The package pins its supported Marimo release in packages/python/pyproject.toml and validates the marimo source digests recorded in _marimo/compat/release.json before installing a reversible adapter lease.
  6. OwnedNotebook owns a temporary notebook copy, loopback server, session, process groups, and cleanup. prepare uses one owned context when work is missing. capture borrows one active edit session.
  7. packages/portable-json owns the cross-language JSON boundary. packages/browser owns export parsing, integrity, immutable readers, prepared-publication control, and loader contracts. Each packages/loader-* owns one representation runtime.
  8. Applications compose the public Python SDK and browser prepared subpath. The proposed marimo-studio prepared runtime remains outside current architecture until its cross-repository acceptance conditions pass.
  9. docs/ owns user workflows and reference. development_docs/ owns code ownership, lifecycle, compatibility seams, and contributor validation.

Read Architecture before changing an ownership or lifecycle boundary.

Dependency rule

Dependencies point from each public operation toward its focused owner. The producer path continues through narrow capabilities to private adapters:

CLI and applications -> public Python SDK
  producer operations -> services -> records and capabilities
  reader operations   -> reader and verification
  repository API      -> ExportRepository -> SQLite and artifact adapters
  diagnostics         -> Marimo composition root

Observation ledger -> ObservationRepository -> SQLite adapter
Observation runs   -> KernelRun records -> Marimo composition root -> compat run hook
Producer services  -> PreparationRepository -> repository adapters

Marimo bridge            -> exporter preparation -> ExporterRuntime port
Marimo composition roots -> private Marimo compatibility adapters
Compatibility adapters   -> marimo-export policy modules

Browser application -> prepared controller -> browser core -> loader facade
                                                        -> one loader runtime
  • _services owns planning, preparation, capture, artifact assembly, and durable writes.
  • delivery.py owns application-level staging and prepared-export materialization. _directory*.py owns destination races, native exchange, and rollback.
  • _repository/preparation.py is the private preparation capability available to services. _repository/observations.py is the private raw observation capability available to the ledger and preparation. _repository/sqlite owns SQL and schema details.
  • _marimo/composition.py, _marimo/anywidget.py, _marimo/blob.py, _marimo/entrypoints.py, and _marimo/managed_server.py construct private Marimo adapters.
  • _marimo/compat/observations.py reports each finished cell-runner pass as a KernelRun. _observations/runs.py decides which runs become observations, and _observations/source.py binds them to one stable source revision.
  • exporters/_prepare.py resolves and freezes exporters through the ExporterRuntime port. PrivateKernelRuntime in _marimo/compat/kernel.py implements it with the kernel reads in _marimo/compat/exporters.py. exporters/_identity.py hashes exporter sources and detects drift.
  • Compatibility adapters delegate these decisions to marimo-export policy modules. _marimo/file_urls.py parses marimo file URLs, _marimo/ui_functions.py decides which UI functions an output may list, exporters/_anywidget_assets.py validates AnyWidget modules and styles, _environment.py computes the import-scoped environment identity that producer identity and the native cell cache share, and _execution/plan.py decides which output cells run live.
  • _remote owns HTTP, authentication, scratchpad transport, server-sent events, and managed process ownership.
  • Browser core imports no specialized chart, table, array, or widget runtime.
  • Loader packages either implement browser contracts or expose a browser-independent decoder bound by one public facade. A loader package referenced by browser remains browser-independent. Loader packages remain independent of one another.
  • Add dependencies to the smallest workspace member that imports them.

Ruff and repository boundary tests enforce service, repository, and private Marimo containment. Vite+ enforces browser and loader direction.

Product language

marimo-export creates a notebook export. Use export after defining the noun once.

Action Verb
Resolve reusable and missing work plan
Prepare from a notebook file prepare
Prepare from a running session capture
Prepare and write from a notebook file build
Write a prepared export write
Read in Python or TypeScript open
Select a state by name or inputs resolve
Decode an output for browser use load
Attach an interactive value to the DOM mount
Put static files on a host deploy or serve
Release a package to a registry publish

A state space is a finite declaration of explicit state rows, a Cartesian input matrix, or both. A state is one complete assignment for the inferred ExportSpec inputs. Authors may write sparse rows because one captured baseline supplies omitted values. An observation is one successful complete input vector retained as authoring evidence. A prepared state is a reusable portable result for one producer, output plan, and state fingerprint. A prepared export is a leased immutable generation for one exact ExportSpec. An output is one published name with a representation in every state, or an unavailable entry where an optional output has no value. An asset is a content-addressed file referenced by an output descriptor. A consumer is a Python reader, browser reader, agent, or another implementation of the export format.

Change routing

Change Primary owner Required companions
StateSpace, ExportSpec, or state normalization spec.py, _execution/plan.py, planning.py YAML, JSON, programmatic, matrix, and live-state tests
Observation lifecycle observations.py, _observations/runs.py, _repository/observations.py Success, queue, and close tests
Observation source matching _observations/source.py, compat/observations.py Source-match, revision, and KernelRun tests
Planning or preparation _services, prepared.py, progress.py, _index_budget.py Exact reuse, incremental state, cancellation, and live tests
Repository or retention repository.py, _repository SQLite, filesystem, concurrency, fencing, and recovery tests
Export format or local reader descriptors.py, index.py, wire.py, reader.py, _limits.py Browser schema and canonical fixtures
Marimo integration or cache _marimo/capabilities.py, composition, one compat adapter Probe, adapter, build, and capture tests
Live outputs and cache bypass _execution/plan.py, exporters/_definitions.py Warm-build cache hit and miss tests
Environment identity _environment.py Import closure, script metadata, and reuse tests
Exporter resolution or identity exporters/_prepare.py, exporters/_identity.py, compat/exporters.py Identity pin, source drift, and custom exporter build tests
marimo file URLs or exported UI functions _marimo/file_urls.py, _marimo/ui_functions.py URL grammar, read-only table, and transfer tests
Managed process lifecycle producer.py, _remote/managed.py, managed entry points Startup, shutdown, source, and descendant tests
Prepared browser control packages/browser/src/prepared Manifest, refresh, transition, cancellation, packed tests
Browser reader or loader contract packages/browser TypeScript and cross-language tests
Portable JSON contract packages/portable-json, _json.py Cross-language fixtures and packed consumers
One output representation packages/loader-*, exporters/_runtime, exporters/_anywidget_assets.py Peer dependency, malformed input, abort, and disposal tests
Value selection or media negotiation values.py Grammar, resolution, renderer, and standard-library tests
CLI or public Python API _cli, package root, public records Human output, JSON, JSONL, exit, and wheel smoke
Application directory delivery delivery.py, _directory* Materialization, races, rollback, and Windows tests
External consumer integration Public SDK and browser prepared subpath Consumer revision and cross-repository acceptance tests
Example or browser transition examples/vite-vanilla Typecheck, build, desktop, and narrow browser proof
Public documentation docs/, VitePress config Examples, links, search, LLM bundles, and rendered proof

Core invariants

  • Every output runs through one transient marimo leaf for every state, unless an optional output is already known to be unavailable in that state.
  • State vectors are complete and fingerprinted before execution.
  • The ExportSpec names an explicit default state. Authoring observations remain repository history until an application places them in an explicit spec.
  • Public observation and exact-prepared repository operations accept an ExportPlan. Raw producer keys remain inside private repository capabilities.
  • A prepared state is reusable by producer identity, output-plan identity, and complete state fingerprint. A prepared export adds the exact spec identity.
  • Exact reuse returns a leased PreparedExport before starting a notebook.
  • Ordinary overrides and UI updates stay local to one child state run.
  • AnyWidget patches record the complete serializer-owned model state.
  • The authored notebook source remains byte-for-byte unchanged.
  • The client and attached kernel use the same marimo-export version and source identity.
  • One failed state, output, transfer, or verification fails the complete producer operation. An optional output records an unavailable output for a missing value, missing representation, or stopped closure instead. Cleanup preserves the primary error. Post-commit parent sync and retired-destination cleanup failures return typed warnings.
  • Preparation reservations carry monotonically increasing fencing tokens. Publication compares the current pointer and reservation owner before commit.
  • Active artifact, staging, and preparation leases renew until their owner closes. Retention preserves every live artifact.
  • Repository storage failures preserve the current prepared export. Confirmed integrity failures retire the affected artifact for cleanup.
  • index.json is canonical UTF-8 JSON and the single export entry point.
  • Readers verify the declared asset closure before decoding output data.
  • Application delivery re-verifies each materialized export before committing the complete outer directory.
  • Opening and verification execute no notebook-authored browser module. Mounting an interactive value grants it page authority.

Validation

  • Test through public APIs, command results, files, protocol records, package imports, or browser state. Avoid assertions on private helper trivia.
  • Run live build and capture evidence after changing marimo integration, process ownership, state execution, cache behavior, or transfer.
  • Use browser inspection for layout, responsive behavior, rapid state changes, charts, AnyWidgets, cancellation, and mount disposal.
  • Rebuild generated package and documentation output from its owning source. Do not commit raw build directories.

Reference