What's Changed
This release launches marimo pair — an agent skill that drops AI agents directly inside a running marimo notebook session — along with a cleaner, more responsive data table experience and a slate of reliability fixes.
⭐ Highlights
marimo pair: collaborate with agents inside your notebook
marimo pair is a new agent skill that gives AI agents full control over a running marimo notebook session — accessing live variables, executing cells, installing packages, and building reproducible programs alongside you. This release adds the marimo pair prompt CLI command, a "Pair with an agent" modal in the notebook menu, and a secure --with-token auth flow that keeps credentials out of shell history.
npx skills add marimo-team/marimo-pairSmarter table headers and responsive column layout
Column headers are now split into a dedicated sort button (cycles asc → desc → clear on click, hidden until hover) and a separate ⋯ menu button for column options. Tables with ≤ 4 columns automatically use natural width with a filler column; larger tables fill the container. Vertical column separators complete the refresh.
✨ Enhancements
- Surface graph errors on code_mode NotebookCell (#9057)
- Add cross-origin authentication token handling for WebSocket URLs (#9077)
- Enrich code_mode
NotebookCellwith runtime status and error (#9056) - LSP root and document URI discovery (#9019)
- Made table responsive to no. of columns and improved table header (#9006)
- Add concise repr to NotebookCell for better REPL discoverability (#9036)
- Add repr, find(), and grep() to _CellsView and improve KeyError messages (#9034)
- Add auth token endpoint and --with-token flow for pair programming (#9003)
- Fix skill detection for marketplace and plugin installs (#9021)
- Propagate kernel-initiated UI value updates to the frontend (#9014)
- Decouple skew protection from agent-facing endpoints (#8993)
- Add
marimo pair promptCLI command and "Pair with an agent" modal (#9000) - Remove feat flag for storage inspector (#8987)
- Migrate @radix-ui/* packages to unified radix-ui (#8981)
- Support anywidget's descriptor API (
MimeBundleDescriptor) (#8972) - Inline audio and video in HTML export (#8931)
- Adjust styles for table (#8963)
- Make data table flush to cell output when it's the only output (#8954)
- Improve chart builder tab management UX (#8957)
- Persistent top toolbar in data table with search, chart-builder, and other actions (#8932)
🐛 Bug fixes
- LSP servers not stopping gracefully on shutdown (#9084)
- Skip scratchpad changes in document transaction sync (#9078)
- Table hangs when sorting/page-size change triggers cell re-render with style_cell/hover_template (#9072)
- Allow custom pickler failure to fall back to default (#9070)
- Sanitize traceback HTML to prevent XSS (#9063)
- Altair chart fails to render after enabling PNG renderer (#9049)
- Use MarimoPlusIcon for "New notebook" action (#9060)
- Make _CellsView iterate over NotebookCell objects instead of cell IDs (#9039)
- Show which cell defines a variable in multiply-defined error (#9037)
- Surface cell errors from
_code_modethrough scratchpad (#9030) - Gracefully handle delete of unknown cell and read document on reconnect (#9033)
- Pass model_id as data attribute to prevent loss on value update (#9032)
- Ignore attribute error during websocket closure in certain edge cases (#9020)
- Revert "feat: Output Altair SVG charts as base64-encoded images" (#9017)
- Resolve duplicate column keys when index name conflicts with column name (#8999)
- Do not double encode msgspec values (#9005)
- Fix inf rerender tables col sizing (#8997)
- Fix double bottom borders for unflushed tables (#8994)
- Adjust spacing and border for chart tabs (#8988)
- Ignore /lsp/health in wasm (#8974)
- Resolve AI SDK URL and headers lazily to handle runtime redirects (#8973)
- Fix altair not setting to full-width when width: container (#8969)
- Style_cell and hover_template lost when sorting in descending order (#8915)
- Account for 0 width arrays (#8950)
📚 Documentation
- Add page actions dropdown for AI tools integration (#9031)
- Add reactive waterfall selection support (#9045)
- Fix duplicate word in OAuth2 example reference (#9050)
- Migrate to oxfmt and oxlint (#8982)
📝 Other changes
- Add defensive null checks for output channel access (#7883) (#9065) (b89c2f7)
- Re-encode WebSocket proxy query params so spaces use %20 (#9041) (#9064) (0579862)
- [Snyk] Security upgrade path-to-regexp from 8.3.0 to 8.4.0 (#8983)
- SVG data URL rendering in layout elements (#9043)
- Add option to display error tracebacks inline and in modal (#8376) (34f87a5)
- Verbose and attestations (#9027)
- Add reactive line selection support (#8657) (31d1d05)
- Recover polling file watcher from transient file absence (#8860) (18617c2)
- Add reactive bar selection support (#8787) (0efa6cf)
- Add cursor agent and auth flow (#8645) (d735232)
- Enable single-click selection for reactive Plotly charts (#8782) (750fb85)
- Add starrocks catalog support (#8856) (14e0e13)
- Resolve GitHub Copilot "Retry Connection" failing with "Agent service not initialized" (#8925) (#8976) (7c3cc60)
- Revert "Update pygments version constraint in pyproject.toml" (#8979)
- Cleanup link check (#8975)
- Update dependency @typescript/native-preview to v7.0.0-dev.20260324.1 (#8958)
- Update pygments version constraint in pyproject.toml (#8921)
Contributors
Thanks to all our community and contributors who made this release possible: @alwaysahustler, @app/marimo-github-maintenance-bot, @app/renovate, @axsseldz, @daizutabi, @dmadisetti, @kirangadhave, @Light2Dark, @ManasVardhan, @manzt, @mscolnick, @tschm
And especially to our new contributors:
- @alwaysahustler made their first contribution in #9050
- @ManasVardhan made their first contribution in #8915
- @tschm made their first contribution in #8921
Full Changelog: 0.22.0...0.22.5




