The Module Architecture¶
Protostar is built around modular plugins. When you run a command, Protostar turns your CLI flags into an ordered list of tool modules.
These modules act as autonomous, stateless plugins that interact strictly with the EnvironmentManifest. They do not inspect sibling modules, do not read the host filesystem, and do not execute system commands directly.
The Layering Model¶
If multiple modules touch the same configuration space, the Orchestrator relies on sequence order to determine precedence.
graph TD
%% Styling
classDef layer fill:#1e293b,stroke:#3b82f6,stroke-width:2px,color:#fff,font-weight:bold;
classDef base fill:#0f172a,stroke:#00e5ff,stroke-width:3px,color:#fff;
subgraph Stack [ ]
direction TB
L1[1. System Layer]:::base
L2[2. Language Layer]:::layer
L3[3. Tooling Layer]:::layer
%% Relationships showing precedence flow
L1 --> L2 --> L3
end
%% Annotations
Note1["**Foundation**<br/>Universal Hygiene"] -- Initialized first --> L1
style Stack fill:transparent,stroke:#475569,stroke-dasharray: 5 5
The stack is resolved in the following strict order:
1. System Layer¶
Configures universal environment artifacts and workspace hygiene. The SystemWorkspaceModule ignores standard host artifacts (.DS_Store), IDE directories (.idea/, .vscode/), and credentials (.env).
2. Language Layer¶
The core runtime environment (PythonCore). Establishes the primary package manager (uv), initializes project metadata (pyproject.toml), and binds IDE settings.
3. Tooling Layer¶
Ancillary development tools. Tools like ruff, mypy, pytest, and prek evaluate the manifest to inject configuration blocks into the project files.
The Module Contract¶
pre_flight()¶
Pre-flight checks. If a module requires external binaries (e.g., git, uv), it verifies their presence in $PATH. If the check fails, an exception is raised before any files or directories are created.
build(manifest: EnvironmentManifest)¶
The aggregation phase. Modules receive the mutable manifest object and register dependencies, directory structures, ignored files, and AST payloads.
# Example: A simplified tool implementation
class MyPyModule(BootstrapModule):
def build(self, manifest: EnvironmentManifest) -> None:
# Register the dependency
manifest.dependencies.add_dev("mypy")
# Inject the AST payload for pyproject.toml
manifest.filesystem.add_file_append("pyproject.toml", """
[tool.mypy]
strict = true
warn_return_any = true
""")
API Reference¶
Core Interface: BootstrapModule
protostar.modules.base.BootstrapModule ¶
Bases: ABC
Appends module-specific requirements to the environment manifest.
Source code in src/protostar/modules/base.py
cli_flags
class-attribute
¶
The CLI flags to trigger this module (e.g., ('-p', '--python')).
config_key
class-attribute
¶
The global configuration key used to evaluate if this module is active.
required_metadata
class-attribute
¶
The metadata keys that MUST be resolved for this module to function.
optional_metadata
class-attribute
¶
The metadata keys that are nice to have but not strictly required.
collision_markers
property
¶
Returns a list of critical filesystem paths to evaluate for collisions during pre-flight.
Returns:
| Type | Description |
|---|---|
list[Path]
|
A list of Path objects representing critical configuration files or directories |
list[Path]
|
managed by this module. Defaults to an empty list. |
pre_flight ¶
Verifies system prerequisites before manifest building begins.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If a critical dependency (e.g., 'uv', 'cargo') is missing. |
build
abstractmethod
¶
Appends module-specific requirements to the environment manifest.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifest
|
EnvironmentManifest
|
The centralized state object. |
required |
Next Steps & Developer Guides¶
- Built-in Modules: Browse the source code for official implementations.
- Extending Protostar: Step-by-step guide to implementing your own custom
BootstrapModule. - The Environment Manifest: Full breakdown of the manifest namespaces and mutation methods used during
build(). - Testing Architecture & Philosophy: Learn how to test modules in-memory with strict subprocess mocking.