Reproducible plotting and analysis pipeline for research projects
Project description
FigOps
FigOps helps research teams turn raw analysis outputs into reproducible, publication-ready figures. It is meant to be boring in the best way: one config, one command, traceable inputs, repeatable outputs.
The short version:
figops --help
figops-mcp --smoke
If those two commands work, the package is installed and the MCP surface is alive.
Current status
- Installable package: yes. The wheel is built and smoke-tested like an external user would run it.
- Current distribution name:
figops. - Current commands:
figopsandfigops-mcp(legacy aliasesgraphhub/graphhub-mcpremain for compatibility). - GitHub Release assets: yes, for users who already have repository access.
- Public PyPI: not uploaded yet. The package policy is now Apache-2.0, and the next gate is TestPyPI/PyPI account publishing.
This means the built package is ready for public package-distribution checks, while the full repository can remain private until repo-only docs/tests/internal style packs are separated. Check LICENSE and NOTICE before redistributing.
Install from the current GitHub release
For internal users with repository access:
gh release download v0.17.4 --repo Moonweave-Research/figops --pattern "*.whl" --dir dist-release
python -m pip install dist-release/figops-0.17.4-py3-none-any.whl
figops-mcp --smoke
For local development from a clone:
python hub_uv.py run python orchestrator.py --list-projects
python hub_uv.py run python -m pytest tests/test_runtime_paths.py -q
hub_uv.py keeps the Python runtime outside the repo so the working tree does
not get polluted with local virtualenv state.
What it does
FigOps coordinates the work around a research figure:
- read a project's
project_config.yaml, - validate declared data contracts,
- run analysis scripts when needed,
- render figures and diagrams,
- apply journal/presentation styling,
- write provenance so the run can be audited later.
It is designed around a simple rule: data is the API. A figure should be traceable back to declared inputs, scripts, config, environment, and output files.
Daily commands
# Choose a configured project interactively
figops
# List configured projects
figops --list-projects
# Run the full pipeline for one project
figops --project "ProjectName" --step all
# Re-render figures only
figops --project "ProjectName" --step plot
# Re-render diagrams only
figops --project "ProjectName" --step diagrams
# Force a clean rerun
figops --project "ProjectName" --step all --force
From a source checkout, the equivalent command is python orchestrator.py ... or
python hub_uv.py run python orchestrator.py ....
Starting a new project
figops --init --project "new_project_folder"
That creates a scaffold with a project_config.yaml, script folders, and output
folders. The config is the contract between your data, analysis, and figures.
A minimal project shape looks like this:
project:
name: "Example Study"
visual_style:
target_format: nature
font_scale: 1.0
profile: baseline
pipeline:
analysis:
- script: "hub_scripts/analyze.R"
lang: R
cache: true
figures:
- id: Fig1
script: "hub_scripts/plot.py"
output: "results/figures/Fig1.png"
cache: true
MCP smoke check
The package exposes a Model Context Protocol server entry point:
figops-mcp --smoke
A healthy smoke response looks like:
{"status": "ok", "health_status": "ok", "tool_surface": "figops_mcp"}
Use this before wiring the package into an agent or external MCP client.
Quality gates
The repository currently verifies release candidates with these checks:
uv build
python scripts/package_metadata_smoke.py
python scripts/public_package_surface.py
python scripts/consumer_install_smoke.py
uv run --with twine python -m twine check dist/*
python hub_uv.py run python -m pytest -q
python hub_uv.py run ruff check .
After the GitHub Release is created and the wheel/sdist are uploaded, maintainers also run:
python scripts/github_release_asset_smoke.py
python scripts/check_public_release.py may still block for repo-only private docs/tests.
For PyPI, the manual Trusted Publishing workflow runs the guarded uploader before publishing, so distribution policy, LICENSE/NOTICE, and the built wheel/sdist package surface are checked first.
When something goes wrong
-
project_config.yaml not foundRunfigops --init --project "<project>"or move into a configured project. -
Project directory not foundRunfigops --list-projectsand copy the exact configured name. -
Strict lockfile errors
--strict-lockis for reproducibility checks. For a quick local render, rerun without strict mode; for release or audit work, add/fix the lockfiles. -
Google Drive files feel stuck Let Drive finish syncing, then rerun. The hub also has a prefetch layer for declared inputs, but it cannot repair a broken Drive login/session.
Repo map
orchestrator.py— CLI entry point.hub_core/— config parsing, validation, cache, provenance, process execution, MCP logic.plotting/— reusable plotting helpers.themes/— journal and presentation style presets.scripts/— release, packaging, and distribution checks.tests/— regression and contract tests.docs/packaging/pypi-readiness.md— current packaging and public-release boundary.
What is next
The next public-distribution step is TestPyPI, then PyPI, through the manual Trusted Publishing workflow:
- keep
figopsas the public PyPI name unless a final product review changes it, - rebuild wheel/sdist from a clean tree,
- confirm package artifacts exclude private docs/tests/research markers,
- make
scripts/guarded_pypi_upload.py --repository testpypipass in dry-run mode, - run
publish.ymlfor TestPyPI, install-check from TestPyPI, then runpublish.ymlfor PyPI.
The working checklist is in
docs/packaging/public-release-clearance.md, with exact publishing setup in
docs/packaging/trusted-publishing.md.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file figops-0.17.4.tar.gz.
File metadata
- Download URL: figops-0.17.4.tar.gz
- Upload date:
- Size: 256.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b692eb525202fb35bce09348235140ed0d1dd6ef764594a0694fbd21e3a4279
|
|
| MD5 |
63244040bd05c12250ca1962c62ab4f6
|
|
| BLAKE2b-256 |
c8707e68a350046e3a9f3370203d2c49cea21772735c19aa4b46df58e6f564ec
|
Provenance
The following attestation bundles were made for figops-0.17.4.tar.gz:
Publisher:
publish.yml on Moonweave-Research/figops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
figops-0.17.4.tar.gz -
Subject digest:
7b692eb525202fb35bce09348235140ed0d1dd6ef764594a0694fbd21e3a4279 - Sigstore transparency entry: 1945625423
- Sigstore integration time:
-
Permalink:
Moonweave-Research/figops@07921010b4a8991cca6be8f8218c1454ff329e95 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Moonweave-Research
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@07921010b4a8991cca6be8f8218c1454ff329e95 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file figops-0.17.4-py3-none-any.whl.
File metadata
- Download URL: figops-0.17.4-py3-none-any.whl
- Upload date:
- Size: 290.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
498fb20ce275ec14d681c112230928a9c0137f2cf0f6f3be6dc746279dd921b6
|
|
| MD5 |
5ab5b6923006c1ca6026ae84f7fd370d
|
|
| BLAKE2b-256 |
34a454dec99b29dba7395e99c20d9138abdf2d3917e6752e81b3029ce6f07b53
|
Provenance
The following attestation bundles were made for figops-0.17.4-py3-none-any.whl:
Publisher:
publish.yml on Moonweave-Research/figops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
figops-0.17.4-py3-none-any.whl -
Subject digest:
498fb20ce275ec14d681c112230928a9c0137f2cf0f6f3be6dc746279dd921b6 - Sigstore transparency entry: 1945625454
- Sigstore integration time:
-
Permalink:
Moonweave-Research/figops@07921010b4a8991cca6be8f8218c1454ff329e95 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Moonweave-Research
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@07921010b4a8991cca6be8f8218c1454ff329e95 -
Trigger Event:
workflow_dispatch
-
Statement type: