Skip to main content

A terminal tool for managing experimental Python projects

Project description

novo

novo

Spin up Python experiments in seconds, from anywhere in your terminal.

Install once with uv, then use novo from any directory to scaffold isolated, git-tracked Python experiments from reusable seed templates — drive it from the command line or a built-in TUI.

Python 3.11+ Built with uv License: MIT


Install

novo is distributed as a uv tool — installed once into an isolated environment and exposed on your PATH.

Prerequisite: uv and git.

# from PyPI
uv tool install novo

# or from this repo
uv tool install git+https://github.com/fmeiraf/novo

If novo isn't found after install, run uv tool update-shell once to add ~/.local/bin to your PATH.

novo --version

That's it — the novo source tree is no longer needed. Use novo from any directory.


First steps

1. Set up a workspace

The workspace is a single git-tracked directory where all your experiments live.

cd ~/code/experiments    # or wherever you want them
novo init

This registers the current directory as your workspace and initializes it as a git repo. Skip it entirely and novo will use an XDG-compliant default (~/.local/share/novo/workspace/).

2. Create your first experiment

novo new image-classifier --tag ml --desc "ResNet experiments"

novo creates a date-prefixed directory inside your workspace, sets up a uv project, applies the default seed, and commits the result.

3. Set up a seed (optional)

Seeds are reusable project templates — your favorite stack, scripts, and config files copied into every new experiment.

novo seed list                      # see what's available
novo seed init data-science         # scaffold a new empty seed

This creates ~/.local/share/novo/seeds/data-science/ with a seed.toml manifest and a template/ directory. Edit the manifest to declare dependencies and post-create hooks:

[seed]
name = "data-science"
description = "Numpy + pandas + jupyter starter"

[seed.dependencies]
packages = ["numpy", "pandas", "jupyter"]

[seed.post_create]
commands = ["mkdir notebooks"]

Drop starter files into template/ — they'll be copied into every new experiment that uses the seed:

novo new churn-analysis --seed data-science

Configuration

novo works out of the box, but a handful of settings let you tailor the defaults. They live in a single TOML file at ~/.config/novo/config.toml (XDG-compliant; the exact path depends on your OS).

Key Type Default What it does
workspace.path str "" (XDG default) Where experiments are created. Empty falls back to ~/.local/share/novo/workspace/. Set by novo init.
defaults.seed str "default" Seed used when novo new is called without --seed.
defaults.python str "" (system) Python version passed to uv init for new experiments (e.g. "3.12"). Override per-experiment with --python.
defaults.auto_commit bool true Auto-commit the workspace on novo new / novo delete.
naming.date_prefix bool true Prefix experiment directories with today's date (2026-05-06-foo). Skip per-experiment with --no-date.

Inspecting and changing settings

novo config show                          # table of all keys
novo config get defaults.python           # read one key
novo config set defaults.python 3.12      # write one key
novo config set naming.date_prefix false  # accepts true/false, yes/no, 1/0, on/off

You can also edit ~/.config/novo/config.toml directly:

[workspace]
path = "/Users/me/code/experiments"

[defaults]
seed = "data-science"
python = "3.12"
auto_commit = true

[naming]
date_prefix = true

Pinning a Python version

A seed itself can't declare a Python version today — it's resolved per-experiment in this order:

  1. --python flag on novo new
  2. defaults.python in config.toml
  3. Whatever uv picks as the system default

So to make every new experiment use 3.12 by default:

novo config set defaults.python 3.12
novo new quick-test          # uses 3.12
novo new legacy --python 3.10  # one-off override

The TUI

Run novo with no arguments to launch the interactive terminal UI — a Textual app for browsing, searching, and managing experiments without memorizing flags.

 ┌─ Experiments ─────────────┐ ┌─ Details ──────────────────┐
 │  > 2026-04-21-transformer  │ │  Name: transformer-exp     │
 │    2026-04-20-image-cls    │ │  Seed: ml-stack            │
 │    2026-04-19-data-clean   │ │  Tags: nlp, pytorch        │
 └────────────────────────────┘ └────────────────────────────┘
  n new  d delete  s seeds  / search  Enter open  ? help  q quit
Key Action
n Create new experiment
d Delete selected
s Browse seeds
/ Search
Enter Open experiment in a new terminal window
j / k Navigate (vim-style)
? Help
q Quit

See docs/tui.md for the full screen and widget breakdown.


Everyday commands

novo                       # launch the interactive TUI
novo new <name>            # create an experiment
novo list                  # list experiments
novo info [name]           # workspace summary, or details for one experiment
novo search <query>        # fuzzy search across name, description, tags
novo open <name>           # cd into an experiment (needs shell integration)
novo delete <name>
novo seed list | init <name>
novo config show | get <key> | set <key> <value>

For novo open to actually cd, add this to your ~/.zshrc / ~/.bashrc:

eval "$(novo --shell-init)"

Updating & uninstalling

uv tool upgrade novo
uv tool uninstall novo

Documentation

Deeper docs live in docs/:

Document Description
architecture.md Layers, data flow, project structure
cli.md All CLI commands and flags
tui.md Textual app, screens, keybindings
core.md Experiment, seed, config, and git logic
models.md Pydantic schemas
development.md Local dev setup
testing.md Test layout and conventions

Development

Work on novo itself with an editable install so changes are picked up immediately:

git clone https://github.com/fmeiraf/novo
cd novo
uv tool install --editable .
uv run pytest

License

MIT

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

novo-0.1.4.tar.gz (25.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

novo-0.1.4-py3-none-any.whl (40.9 kB view details)

Uploaded Python 3

File details

Details for the file novo-0.1.4.tar.gz.

File metadata

  • Download URL: novo-0.1.4.tar.gz
  • Upload date:
  • Size: 25.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for novo-0.1.4.tar.gz
Algorithm Hash digest
SHA256 a1e172965166334603759a93efe528a995f7d0d30e7ab7dcb89790091d7f4aaf
MD5 06993a7b330ff6c6eb3fe689fa12f823
BLAKE2b-256 8e78b34eadf0400ff6599a57f056578b66b9b61daa87baa5824071befa8252d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for novo-0.1.4.tar.gz:

Publisher: pypi_workflow.yml on fmeiraf/novo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file novo-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: novo-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 40.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for novo-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 6ae397ccbe26e63589cf82220048b00cb67e041e2bc1a5e1abdae6a7efaca675
MD5 d326b5ec5defa3ef2ada20e95e5a7dcc
BLAKE2b-256 50248cc987014d6f7f362dd896e415f61cf8e699349d0cecbeb0c3bbca06b408

See more details on using hashes here.

Provenance

The following attestation bundles were made for novo-0.1.4-py3-none-any.whl:

Publisher: pypi_workflow.yml on fmeiraf/novo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page