A terminal tool for managing experimental Python projects
Project description
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.
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 (once published)
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.
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
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
Project details
Release history Release notifications | RSS feed
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 novo-0.1.1.tar.gz.
File metadata
- Download URL: novo-0.1.1.tar.gz
- Upload date:
- Size: 24.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d9f793b57445c70871d5356d28c5b14f70d0b48a6cfadb00c69a905c2edcba3
|
|
| MD5 |
c46f40392c66775de9a3f80ac3de2871
|
|
| BLAKE2b-256 |
0f8ed4d92b0933942935a1621d105756ad2420376b85c26378ea1f8fd578ea1d
|
Provenance
The following attestation bundles were made for novo-0.1.1.tar.gz:
Publisher:
pypi_workflow.yml on fmeiraf/novo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
novo-0.1.1.tar.gz -
Subject digest:
7d9f793b57445c70871d5356d28c5b14f70d0b48a6cfadb00c69a905c2edcba3 - Sigstore transparency entry: 1414223171
- Sigstore integration time:
-
Permalink:
fmeiraf/novo@f823500a5ae51f617bf3d2f5409f55142131add1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/fmeiraf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi_workflow.yml@f823500a5ae51f617bf3d2f5409f55142131add1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file novo-0.1.1-py3-none-any.whl.
File metadata
- Download URL: novo-0.1.1-py3-none-any.whl
- Upload date:
- Size: 39.5 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 |
a13300d03c44686876cc1a53b1722ed6e0577eaeffe3b5a083e91831d2b90b5e
|
|
| MD5 |
d6dd727bb66db3db19ebae6254ce90bc
|
|
| BLAKE2b-256 |
dbdfb87c476ee91dabd1dab7e6c40dce69f2b43c86869180b9334e4fe5c51a30
|
Provenance
The following attestation bundles were made for novo-0.1.1-py3-none-any.whl:
Publisher:
pypi_workflow.yml on fmeiraf/novo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
novo-0.1.1-py3-none-any.whl -
Subject digest:
a13300d03c44686876cc1a53b1722ed6e0577eaeffe3b5a083e91831d2b90b5e - Sigstore transparency entry: 1414223269
- Sigstore integration time:
-
Permalink:
fmeiraf/novo@f823500a5ae51f617bf3d2f5409f55142131add1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/fmeiraf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi_workflow.yml@f823500a5ae51f617bf3d2f5409f55142131add1 -
Trigger Event:
push
-
Statement type: