Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>RotorNew to Visual Studio Code? Get it now.
Rotor

Rotor

kgroshev

|
8 installs
| (0) | Free
A VS Code UX layer for analytical Jupyter notebooks with SQL cells.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Rotor

Rotor is a Visual Studio Code extension for analytical Jupyter notebooks that use SQL cells. It adds a notebook-focused workflow for naming paragraphs, assigning SQL connections, navigating notebook structure, formatting SQL, linting SQL, and viewing query results without leaving the notebook.

Features

  • A context-aware Rotor: Paragraphs panel for notebook paragraphs and the full report structure of Motor report.md files.
  • Paragraph titles stored in notebook metadata and shown as CodeLens entries.
  • Drag paragraphs in Rotor: Paragraphs to reorder notebook cells. Drop onto a paragraph to insert before it, or onto empty space to move to the end. Code, metadata, and outputs are preserved; use the notebook's Undo to revert. A running paragraph must finish before it can be moved.
  • SQL connection labels per paragraph, with configurable aliases and dialect mapping.
  • One-click execution for the active cell or a selected paragraph.
  • A manual Pipeline graph with Waterfall/Flat layouts, an optional native tree, dependency-aware runs and code-change tracking for Stator notebook tasks.
  • A Rotor: Output webview for mirrored notebook output.
  • A DataFrames tab with bounded pandas/Polars head previews from the active kernel.
  • SQL formatting through SQLFluff, scoped to detected SQL cell bodies.
  • SQL diagnostics through SQLFluff with configurable severity and ignored rules.
  • OpenMetadata-aware SQL completion for configured metadata servers.
  • Setup command that inserts a notebook bootstrap cell for required kernel packages.
  • Native VS Code Outline navigation for Motor report.md files, including nested layouts, data sources, parameter types, SQL view/query kinds, component types, and each component's query datasource.
  • Go to Definition for Motor report references through F12, Peek Definition, or Cmd+Click on macOS / Ctrl+Click on Windows and Linux.
  • Find All References for Motor declarations and references through Shift+F12 or the editor context menu.

For a Motor report, use either the standard VS Code Outline view or the dedicated Rotor: Paragraphs panel. The Rotor panel switches automatically: Jupyter notebooks show paragraphs, while recognized Motor reports show data sources, parameters, SQL, templates, and nested layout. Clicking an entry jumps to its declaration. The custom Expand All title action opens every Motor branch; VS Code provides the adjacent Collapse All action. Expanded Motor branches are remembered separately for each report when switching editor tabs and are restored from workspace state after a VS Code reload. While the Rotor Paragraphs panel is visible, moving the editor cursor selects and reveals the deepest enclosing Motor item without moving focus out of the editor. The standard Outline and Go to Symbol in Editor (Ctrl+Shift+O) support both Markdown and Evidence Markdown (emd). Keep the standard Outline sorting set to Position to preserve source order.

Motor definition navigation works in both Markdown and Evidence Markdown (emd). Rotor links component query, template, and params attributes; parameter options.source; dimension default choices; SQL parameter helpers such as in_filter, between_filter, and dimension; and relations after SQL FROM or JOIN. Relation lookup understands report data sources, named SQL blocks, and scoped CTEs, including chained and nested CTEs. Local CTE names take priority while they are in scope. Find All References searches the current report and can be invoked from either a declaration or one of its references.

Requirements

Rotor activates for VS Code Jupyter notebooks. Install and configure the VS Code Jupyter extension separately.

SQL formatting and linting require sqlfluff to be available on your PATH, or configured through rotor.sqlLint.sqlfluffPath.

OpenMetadata completion requires a reachable OpenMetadata server and an API key configured through the Rotor command palette command.

Notebook output

By default, Rotor mirrors cell output into Rotor: Output and automatically collapses the output in the notebook. To keep standard Jupyter output behavior, open VS Code Settings, search for Rotor: Output Mode, and select mirror. Alternatively, add this to your user or workspace settings.json:

"rotor.outputMode": "mirror"

In mirror mode, Rotor leaves notebook output visibility unchanged while continuing to display a copy in Query Result. The other modes are mirror-and-collapse (the default) and mirror-and-clear (clear notebook output after mirroring).

Pipeline

Open Rotor: Open Pipeline, or select the separate Rotor: Pipeline panel. It shows only Stator tasks declared by %%sql task=..., %%task task=... and %%trino_loop task=.... Dependencies are explicit: root=true declares a root and after=orders,rates declares parents. %%sql part_of=orders adds another cell to the same logical task. Its cells always execute together, in order. Other notebook cells are not task nodes.

Install a Stator build providing parse_notebook_content, pipeline_to_dict and the stator-notebook-graph-v1 contract in the selected notebook kernel. The dagster package is not required. Missing/older Stator produces an update message and a Refresh action (Check again in the native tree); ordinary paragraphs and other Rotor features remain available. Run the notebook's stator.setup() cell before executing tasks.

Graph and tree presentations

The default graph shows each task once, including tasks with multiple parents. Arrows represent explicit dependencies, not SQL inference or elapsed time.

  • Waterfall places dependency levels from left to right. Unbranched chains share a row; forks and joins get their own lanes.
  • Flat places one task per row with compact dependency indentation.
  • Click a task to select it; double-click it or use Reveal cell to open its notebook cell. Task details / cells shows its connection, code hash, freshness and every cell of a multipart task.
  • Click empty graph space to deselect; dragging the background keeps the selection. Queued tasks have a separate purple status color and legend entry, distinct from running tasks.
  • Upstream / Downstream in the highlighting selector emphasize the selected task's lineage without changing the execution plan.
  • Use Fit, zoom controls, Ctrl/Cmd+wheel, scroll or drag the background to navigate. Layout, zoom, viewport and selection survive webview recreation for the current notebook.

Select Tree in the graph toolbar, or run Rotor: Show Pipeline Tree, to return to the original native tree. Use its Show Pipeline Graph title action or the command of that name to switch back. The graph/tree choice is remembered per workspace, and Rotor: Open Pipeline opens the selected presentation.

The native tree expands from roots toward downstream tasks. A shared task has one expandable occurrence and leaf references under its other parents. All occurrences share state and each task executes only once in a plan. Clicking an entry reveals its notebook cell; Cells lists the pieces of a multipart task.

Both presentations share the same controller, freshness records, confirmation preview and sequential Jupyter execution. Switching presentations does not refresh the kernel or stop an active queue.

Run actions are manual and preview the complete ordered plan before executing:

  • Run Task forces the selected task.
  • Run Task with Upstream forces its ancestors and the task.
  • Run Task with Downstream forces the task and its descendants.
  • Run Changed Tasks and Downstream selects changed, stale and never-run tasks, together with their descendants.
  • Run All Pipeline Tasks forces the entire graph.

Missing or stale required parents from other branches are added to the plan and listed in the preview. Execution follows dependency order, even when notebook cell order differs. A failed or interrupted cell stops the queue; descendants are blocked. Native Jupyter execution owns cell outputs, errors and history. Stop Pipeline Queue lets the active cell finish and prevents further cells; use Jupyter's Stop action to interrupt the active query. Editing notebook source, moving/removing cells or changing Pipeline connection settings stops the plan before continuing with a different snapshot. Run without concurrently queuing other SQL cells while Pipeline is binding a cell's connection.

Connections

Pipeline sends every cell's source to Stator, including ordinary %sql gp switches. A switch does not appear as a task but determines the connection for subsequent %%sql tasks. connection=... overrides that connection and part_of=... inherits its owner's connection even if another %sql switch appears between parts. Rotor pins the resolved alias for the native cell run; it does not depend on whichever alias happened to be active in the live kernel, and does not rewrite cell source or notebook metadata.

For cells before the first %sql switch, use connection=... or configure rotor.pipeline.defaultAlias. Custom aliases require rotor.pipeline.profiles to match stator.setup(profiles=...), for example:

"rotor.pipeline.profiles": { "lake": "trino", "gp": "greenplum" },
"rotor.pipeline.defaultAlias": "lake"

An empty profile mapping uses Stator defaults. Setup Python code is not evaluated to discover settings. rotor.connections labels/metadata are display settings and do not select runtime connections.

Freshness and performance

Graph positions are cached by task names and dependencies. Status/code-hash updates reuse coordinates; status-only updates also reuse the existing SVG nodes. Switching Waterfall/Flat, zooming, selecting and highlighting tasks are local UI operations and do not inspect the kernel. The hidden graph performs no layout or state serialization, and its browser context is not retained.

changed compares Stator's code hash against the last successful Pipeline run. stale means an upstream is no longer current, or was rerun after the consumer's last success. never means there is no confirmed result in this session. Multipart tasks are confirmed only after every part succeeds. Records are kept in memory separately for up to eight notebooks. Kernel replacement/restart or a changed Stator partition window clears confirmed results. External execution of a task while Pipeline is visible conservatively invalidates its tracked result and downstream. Changes to database contents, arbitrary Python variables and external files are not inferred; use a force-run action for new data.

There is no automatic execution, typing subscription or polling. Graphs are checked on opening Pipeline, Refresh, before an explicit run, and after saving while the view is visible. Kernel metadata changes also trigger a compatibility check, or stop the remaining queue during a run. Save bursts are coalesced for 150 ms; unchanged source and output-only saves issue no new kernel request. Unsaved changes can be checked with Refresh. Hidden/collapsed views detach notebook/configuration/kernel listeners and start no background inspections. An already dispatched request may finish; its hidden response is discarded. Hiding the view stops any remaining explicit run queue after the active cell finishes and its one-shot binding is cleaned up. Retry and timeout magic parameters remain metadata in this notebook runner; there are no automatic retries or per-task timeout enforcement.

DataFrames

Open Rotor: Open DataFrames, or select DataFrames in Query Result. The list on the left shows existing pandas and Polars DataFrames in the active notebook's Python kernel. Select an entry to inspect its head. Jupyter may ask you to grant Rotor access to the kernel the first time. Rotor uses the public Jupyter extension API; it does not start a kernel, add cells or alter execution history. No Stator changes or additional kernel packages are needed.

The status dot has an accessible label and a tooltip:

  • Green: the snapshot is current for the last observed execution.
  • Yellow: the snapshot is stale; refresh is pending until the view is visible and the kernel is idle.
  • Blue: an inspection is in progress.
  • Red: inspection failed; the previous snapshot remains available. Use Refresh to retry, for example after granting kernel access.
  • Gray: no preview is loaded, the kernel is unavailable, or a LazyFrame is selected.

There is no polling. The list/selected preview refresh after notebook execution or a manual Refresh. Typing in a cell does not invalidate the snapshot. Execution events are coalesced until 750 ms have passed without a new refresh event. Hidden, collapsed and disposed panels, and the Query Result tab, issue no new inspection requests. An existing request may finish; its result is discarded if the notebook, selection or visibility changed. Rotor never interrupts user code to stop an inspection. Changes made by external clients or background threads may require a manual Refresh.

The default head is 20 rows, with 5/20/50/100 available. Inspection is capped at 50 columns, 500 characters per scalar cell, 200 frames/5,000 namespace entries and a 256 KiB response. Large/nested/object/binary cells use bounded summaries; the interface reports when preview/discovery limits apply. Only eight head snapshots are retained in memory, and incompatible state is cleared on notebook switch or kernel restart. Data and caches are not written into the notebook. Sorting, filters, copy and CSV export operate on the preview only. Polars LazyFrames are listed but never collected or queried for their schema.

Development checks

npm test compiles and runs the Node tests and Python inspector checks (Python 3 is required). Tests of real pandas, Polars and IPython kernels run when those packages are installed in the selected interpreter; set ROTOR_TEST_PYTHON to its executable. Browser tests use the development-only playwright-core package and run when ROTOR_BROWSER_EXECUTABLE points to a Chromium/headless-shell executable. For example, with the Python packages and browser already installed:

ROTOR_TEST_PYTHON=/path/to/python \
ROTOR_BROWSER_EXECUTABLE=/path/to/chrome-headless-shell npm test

Commands

Command Command ID Description
Rename Paragraph rotor.renameParagraph Rename the active or selected notebook paragraph.
Set Paragraph Connection rotor.setParagraphConnection Assign a configured SQL connection alias to a paragraph.
Run Cell in Place rotor.runCellInPlace Execute the active notebook cell and keep output in notebook context.
Run Paragraph rotor.runParagraph Execute a selected paragraph from the Rotor panel.
Reveal Paragraph rotor.revealParagraph Jump from the Rotor panel to the paragraph in the notebook.
Reveal Paragraph Output rotor.revealParagraphOutput Jump to a paragraph and focus the Query Result view.
Go to Paragraph rotor.goToParagraph Open a quick pick for notebook paragraphs and navigate to the selected item.
Open Query Result rotor.openQueryResult Open and refresh the Rotor Query Result view.
Open DataFrames rotor.openDataframes Open bounded head previews of DataFrames in the active kernel.
Open Pipeline rotor.openPipeline Open the remembered graph or native tree presentation.
Show Pipeline Graph rotor.showPipelineGraph Show the custom graph with Waterfall and Flat layouts.
Show Pipeline Tree rotor.showPipelineTree Show the original native Pipeline tree.
Clear Query Result rotor.clearQueryResult Clear the mirrored query result output.
Expand All rotor.expandMotorOutline Expand every branch in the active Motor report outline.
Format SQL Cell rotor.formatSqlCell Format the active or selected SQL paragraph with SQLFluff.
Format All SQL Cells rotor.formatAllSqlCells Format all detected SQL paragraphs in the active notebook.
Setup Kernel Packages rotor.setupKernelPackages Insert or run the Rotor kernel setup cell in the active Jupyter notebook.
Configure OpenMetadata rotor.configureOpenMetadata Store the OpenMetadata API key used by metadata-aware completion.
Refresh OpenMetadata Cache rotor.refreshOpenMetadataCache Clear cached OpenMetadata responses.
Show Output rotor.showOutput Show the Rotor output channel.
Toggle SQL Lint Diagnostics rotor.toggleSqlLintDiagnostics Enable or disable SQL lint diagnostics and error highlighting.
Debug SQL Lint Active Cell rotor.debugSqlLintActiveCell Print SQL lint debug details for the active cell to the Rotor output channel.

Settings

Setting Default Description
rotor.cellLanguages { "%": "sql" } Language IDs to apply to notebook code cells by first magic-line prefix.
rotor.connections ClickHouse, Greenplum, Trino aliases SQL connection aliases used for display and metadata.
rotor.dialectByConnection ClickHouse, Greenplum, Trino dialects SQLFluff dialect names keyed by Rotor connection alias.
rotor.sqlLint.enabled true Enable SQLFluff and Rotor SQL diagnostics for Rotor SQL notebook cells.
rotor.sqlLint.sqlfluffPath sqlfluff Path to the SQLFluff executable.
rotor.sqlLint.ignoreLocalConfig true Run SQLFluff diagnostics without local project config files.
rotor.sqlLint.debug false Write SQLFluff diagnostic pipeline details to the Rotor output channel.
rotor.sqlLint.errorCodes PRS, LXR, TMP SQLFluff codes or prefixes shown as errors.
rotor.sqlLint.criticalCodesByDialect common parser and semantic rules Dialect-specific codes or prefixes shown as execution-risk errors.
rotor.sqlLint.ignoredCodes LT13 SQLFluff codes or prefixes Rotor should never show.
rotor.sqlLint.otherSeverity off Severity for non-ignored, non-critical SQLFluff violations.
rotor.sqlFormat.ignoreLocalConfig true Run SQLFluff format without local project config files.
rotor.openMetadata.baseUrl https://metadata.ecom.tech OpenMetadata server URL used for SQL metadata features.
rotor.motorOutline.defaultExpansion collapsed Initial Motor Outline state for reports without saved state: collapsed or expanded. Saved per-report state takes precedence.
rotor.outputMode mirror-and-collapse Notebook output behavior: mirror keeps standard Jupyter behavior; mirror-and-collapse automatically collapses output; mirror-and-clear clears output after mirroring. All modes also display output in Query Result.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft