Earlier today, I finished up some of the changes I was working on. So, what can I do next...
Keeping in mind that I am incredibly tired, let's see which files need to be broken up how.
The api module needs to be broken into several layers of abstraction, which must themselves be divided into smaller units of responsibility. At the lowest level of abstraction in the module, there are five functions that directly interact with the stream-based interface to Rgistry construction. Two of these functions are somewhat related, but I don't think they're fundamentally more tightly coupled than any other pair.
The next layer of abstraction is made up of three classes and their corresponding helper functions. Each class represents a specific Action, and the helper function constructs an appropriately detailed change stream around an instance of its corresponding class. This layer consumes a pair of data classes that represent the production and consumption of Targets.
The next layer on top of that specializes the usage of the above classes into helper classes/functions for setting up isolated execution environments. Currently, this is just virtual environments via the stdlib venv, but my long-term goals basically require a version of this using the pip-installable virtualenv module. Also, I could support other programming languages, probably. (Possibly have a version that uses conda instead of pip. If I come up with a really compelling reason.)
Above that layer, I have the somewhat-implicit concept of clusters of specific Python packages that provide an executable and may require project code to be installed to work properly.
Very sketchily above that layer, the idea of different wrappers around pytest, to provide different functionality. It makes sense, I think, to apply a similar structure to other test runners, and ideally the wrappers don't have to care about what code they happen to be wrapping.
Anyway, that covers the api module and the config prototype. Beyond that, we have...
The base controller, which has some not-terribly-related helper code in it that should be using plugins or extensions instead of what it's currently doing.
While the registry module is pretty big, I think I've pulled out everything that really makes sense. I may want to create a Protocol for the Registry class, because I think that would let me break some import cycles more elegantly, but that's still not a priority.
The runner module is probably the best place to put that Protocol if/when I do make it. It's got three main classes that are pretty thoroughly coupled together, but it would probably help make it more obvious what was going on if there were a simple helper method that filled in some of the expected values. There's also a helper method that could easily go either in its own module, or the base controller, but I'm not sure it matters.
The application defines a single extension module that should probably be split up into two or three. Some of it deals with conditional formatting, and some of it deals with colored text, and some of it deals with conditionally applying colors to text.
There are various other modules in the application, but the rest of them look pretty well broken down for now.
I'm going to call this post here. I don't know how much of a chance I'm going to get to work on any of this over the weekend, but I can't handle anything else right now.