Best for
- Use when delivering an analysis notebook with all cells run and figures embedded.
fmschulz/omics-skills/skills/notebooks/SKILL.md
Author, execute, validate, and convert reproducible marimo or Jupyter notebooks. Use when delivering an analysis notebook with all cells run and figures embedded.
Decision brief
A single skill for authoring, validating, and delivering reproducible analysis notebooks. Marimo is the default format; Jupyter is supported for existing .ipynb files and when a downstream tool requires JSON. Conversion between the two formats is part of this skill.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/fmschulz/omics-skills --skill "skills/notebooks"Inspect the Agent Skill "notebooks" from https://github.com/fmschulz/omics-skills/blob/2703ad88739298766b597d097f77970b6066b536/skills/notebooks/SKILL.md at commit 2703ad88739298766b597d097f77970b6066b536. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
1. Pick the format. - New notebook: write a marimo .py notebook. Use the canonical cell layout (one concept per cell, final expression renders, no if guards around outputs, no try/except for control flow). - Existing .ipynb to extend or polish: keep it as Jupyter unless the user…
Review the “Quick Reference” section in the pinned source before continuing.
Notebook scope and goals (what question, what data, what output).
A reproducible notebook (.py for marimo, .ipynb for Jupyter) with narrative markdown cells, code cells, and embedded figures.
[ ] Notebook format chosen explicitly (marimo by default; Jupyter only when justified or when the input is .ipynb).
Permission review
The documentation asks the agent to run terminal commands or scripts.
uv run --script "$NOTEBOOKS_SKILL/scripts/execute_notebook.py" \The documentation asks the agent to run terminal commands or scripts.
| Execute Jupyter headlessly | `uv run --script "$NOTEBOOKS_SKILL/scripts/execute_notebook.py" <notebook.ipynb> --kernel <project>` |Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 91/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 7 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
A single skill for authoring, validating, and delivering reproducible analysis notebooks. Marimo is the default format; Jupyter is supported for existing .ipynb files and when a downstream tool requires JSON. Conversion between the two formats is part of this skill.
A notebook is not "done" until it has been executed end-to-end on a fresh kernel and every figure is embedded in the delivered file.
Pick the format.
.py notebook. Use the canonical cell layout (one concept per cell, final expression renders, no if guards around outputs, no try/except for control flow)..ipynb to extend or polish: keep it as Jupyter unless the user asks to convert.Outline before coding. Write the notebook plan (purpose, data sources, analysis steps, expected outputs/plots) as the first markdown cell, then implement against that plan.
Keep marimo cells clean. These are hard rules for every .py notebook:
mo.md(r"""...""") or mo.md(f"""...""") only when interpolation is required. Put the prose directly inside the string; never paste quoted string fragments such as " ... " lines inside the markdown body.@app.cell def _(): return placeholders. Remove them before final verification.Set up the kernel and dependencies.
.py file:
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "marimo",
# "polars",
# "duckdb",
# "matplotlib",
# # ... add every import used in the notebook
# ]
# ///
Run with uvx marimo run --sandbox <notebook.py> or edit interactively with uvx marimo edit --sandbox <notebook.py>. The sandbox reads the header and resolves the notebook environment.python3 kernel leaks the system interpreter:
pixi run python -m ipykernel install --user --name <project> --display-name "<project> (pixi)"
Then in <notebook>.ipynb confirm:
"kernelspec": {"name": "<project>", "display_name": "<project> (pixi)"}
Add every import used in the notebook to pixi.toml so the kernel can resolve it from a clean install.Load data with project-relative paths. Prefer DuckDB for TSV/Parquet (duckdb.read_csv, duckdb.read_parquet). Avoid absolute paths and ~. Avoid hidden state from the runtime working directory.
Run checks and all cells to generate plots. Execute the notebook headlessly on a fresh kernel before delivery:
uvx marimo check --strict <notebook.py> before export. Then run uvx marimo export ipynb <notebook.py> -o <notebook.executed.ipynb> --include-outputs --sandbox -f. For a deterministic HTML artifact, use uvx marimo export html <notebook.py> -o <notebook.html> --sandbox -f. Run the strict check again after the final edit/export cycle.NOTEBOOKS_SKILL="${NOTEBOOKS_SKILL:-$HOME/.agents/skills/notebooks}"
uv run --script "$NOTEBOOKS_SKILL/scripts/execute_notebook.py" \
<notebook.ipynb> --kernel <project>
The helper writes <notebook>.executed.ipynb. pixi run jupyter nbconvert --to notebook --execute --inplace <notebook.ipynb> is also valid when Jupyter is declared in the project environment.Evaluate the plots, then refine. This step is required, not optional. After the run-all execution:
Deliver pre-executed notebooks. The artifact handed back to the user must:
.ipynb (or in the marimo HTML export).pixi install + jupyter nbconvert --to notebook --execute (Jupyter) must reproduce the same notebook end-to-end.Convert between marimo and Jupyter when the user asks for it:
scripts/convert_notebook.py for a pinned conversion path. The fixtures under fixtures/ exercise both directions. Replace <PROJECT_NAME> and <PIXI_PROJECT_KERNEL> in copied Jupyter templates with the actual Pixi kernel before execution..ipynb → marimo .py: uvx marimo convert <notebook.ipynb> -o <notebook.py>, then uvx marimo check --strict <notebook.py>, then clean up Jupyter artifacts (display() calls, %magics, indented final expressions, ipywidget usage). See references/widgets.md and references/latex.md for ipywidget→marimo and MathJax→KaTeX mappings..py → .ipynb: uvx marimo export ipynb <notebook.py> -o <notebook.ipynb> --include-outputs --sandbox -f.| Task | Action |
|---|---|
| Resolve bundled helpers | NOTEBOOKS_SKILL="${NOTEBOOKS_SKILL:-$HOME/.agents/skills/notebooks}" |
| Author marimo notebook | Edit .py, run uvx marimo edit --sandbox <notebook.py> |
| Author Jupyter notebook | Register pixi kernel, set notebook kernelspec, edit .ipynb |
| Lint marimo notebook | uvx marimo check --strict <notebook.py> |
| Execute marimo headlessly | uvx marimo export ipynb <notebook.py> -o <executed.ipynb> --include-outputs --sandbox -f |
| Execute Jupyter headlessly | uv run --script "$NOTEBOOKS_SKILL/scripts/execute_notebook.py" <notebook.ipynb> --kernel <project> |
Convert .ipynb → marimo | uvx marimo convert <notebook.ipynb> -o <notebook.py> |
Convert marimo → .ipynb | uvx marimo export ipynb <notebook.py> -o <notebook.ipynb> --include-outputs --sandbox -f |
| Marimo references | references/notebook_structure.md, references/UI.md, references/SQL.md, references/STATE.md, references/EXPORTS.md, references/PYTEST.md, references/TOP-LEVEL-IMPORTS.md, references/DEPLOYMENT.md |
| Conversion references | references/widgets.md, references/latex.md |
| Pixi + Jupyter | references/pixi_jupyter.md |
| Plot style | references/plot_style.md |
| Data loading (DuckDB/TSV/Parquet) | references/data_loading_duckdb.md |
| Definition-of-done checklist | references/verification.md |
| Templates | templates/marimo_notebook_template.py, templates/jupyter_kiss_template.py |
| Headless executor | scripts/execute_notebook.py |
| Jupyter structure linter | uv run --script "$NOTEBOOKS_SKILL/scripts/lint_notebook_structure.py" <notebook.ipynb> |
| Pinned converter | uv run --script "$NOTEBOOKS_SKILL/scripts/convert_notebook.py" --help |
uv available on PATH, or marimo installed in the environment.pixi available and a pixi.toml (or equivalent env spec) for the project..py for marimo, .ipynb for Jupyter) with narrative markdown cells, code cells, and embedded figures.<notebook>.executed.ipynb or an .html export) where every cell has been run on a fresh kernel..ipynb).kernelspec set to a named pixi kernel.pixi.toml).--include-outputs --sandbox, or Jupyter execution exits zero.uvx marimo check --strict <notebook.py> passes before and after export.mo.md(...), trailing empty cells, or return-only placeholder cells remain.<PIXI_PROJECT_KERNEL> placeholder.# /// script
# requires-python = ">=3.12"
# dependencies = ["marimo", "polars", "duckdb", "matplotlib"]
# ///
import marimo
app = marimo.App(width="medium")
@app.cell
def _():
import marimo as mo
import polars as pl
import duckdb
import matplotlib.pyplot as plt
return mo, pl, duckdb, plt
@app.cell(hide_code=True)
def _(mo):
mo.md(r"""
# Analysis notebook
This notebook loads project data, validates it, and renders the requested figures.
""")
return
@app.cell
def _(duckdb):
df = duckdb.read_parquet("data/measurements.parquet").pl()
df.head()
return (df,)
@app.cell
def _(df, plt):
fig, ax = plt.subplots(figsize=(5, 3.2))
ax.scatter(df["x"], df["y"], s=10)
ax.set_xlabel("x (units)"); ax.set_ylabel("y (units)")
fig
return
Then:
uvx marimo check --strict notebook.py
uvx marimo export ipynb notebook.py -o notebook.executed.ipynb \
--include-outputs --sandbox -f
uvx marimo check --strict notebook.py
# One-time kernel registration in the project root:
pixi run python -m ipykernel install --user --name myproject --display-name "myproject (pixi)"
# After authoring, run end-to-end on a fresh kernel:
NOTEBOOKS_SKILL="${NOTEBOOKS_SKILL:-$HOME/.agents/skills/notebooks}"
uv run --script "$NOTEBOOKS_SKILL/scripts/execute_notebook.py" notebooks/analysis.ipynb \
--kernel myproject \
--out notebooks/analysis.executed.ipynb
.ipynb to marimouvx marimo convert notebooks/legacy.ipynb -o notebooks/legacy.py
uvx marimo check --strict notebooks/legacy.py
uvx marimo export ipynb notebooks/legacy.py -o notebooks/legacy.executed.ipynb \
--include-outputs --sandbox -f
Issue: Jupyter notebook executes locally but fails on a teammate's machine.
Solution: The kernel was unpinned (python3) or used a packaged interpreter outside the project's pixi env. Re-register a named kernel and pin it in the notebook kernelspec.
Issue: Marimo cell does not render a figure.
Solution: The figure must be the final expression of the cell. Indented expressions inside if blocks or expressions buried before other statements will not render.
Issue: Figures look correct interactively but the executed file shows empty plots.
Solution: Code is mutating shared state across cells (e.g. plt.gcf() reuse). Build a fresh fig, ax = plt.subplots(...) per cell and return / display fig as the final expression.
Issue: Converted notebook fails marimo check.
Solution: Remove leftover display(...) calls, drop %magic lines that have no marimo equivalent, and rewrite ipywidget usage using mo.ui.* per references/widgets.md.
Issue: Every matplotlib figure appears twice in the executed Jupyter notebook.
Solution: The inline backend's flush_figures post-execute hook auto-displays every open figure (display_data), and the cell's fig return value produces a second copy (execute_result). Unregister the hook in the preamble cell:
plt.ioff()
try:
from matplotlib_inline.backend_inline import flush_figures
get_ipython().events.unregister("post_execute", flush_figures)
except Exception:
pass
With this fix, only the cell's final fig expression renders. For figures inside if/else blocks (where fig is not a top-level expression and therefore not captured as execute_result), use display(fig) explicitly instead of bare fig. Do not use mpl.use("agg") as a workaround — it disables _repr_png_() entirely and produces zero images.
Frequently asked questions
A single skill for authoring, validating, and delivering reproducible analysis notebooks. Marimo is the default format; Jupyter is supported for existing .ipynb files and when a downstream tool requires JSON. Conversion between the two formats is part of this skill.
The source record exposes this install command: npx skills add https://github.com/fmschulz/omics-skills --skill "skills/notebooks". Inspect the command and pinned source before running it.
Static rules flagged exec-script in the source; the page lists the matching lines and excerpts.
Alternatives
coreyhaines31/marketingskills
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
coreyhaines31/marketingskills
When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o
alirezarezvani/claude-skills
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
wanshuiyin/Auto-claude-code-research-in-sleep
Use it for operations and research tasks; the detail page covers purpose, installation, and practical steps.