pyssgA tiny-kernel, plugin-driven static site generator

The kernel

The kernel is deliberately small and has zero third party dependencies - it is pure standard library. Everything it contains falls into one of a handful of modules.

ModuleResponsibility
hooks.pySyncHook, SyncBailHook, SyncWaterfallHook.
builder.pyBuilder (lifecycle orchestrator) and BuilderHooks.
build.pyBuild, the state of one run.
models.pySource and Output, neutral data bags.
plugin.pyThe Plugin protocol.
config.pyConfig and loading of pyssg.config.py.
cli.pyThe pyssg build entry point.

Dependency-free by design

The rule is simple: the kernel uses only the standard library; plugins may use whatever they need. This resolves the tension between "keep dependencies minimal" and "we need a real Markdown parser". The kernel stays clean, while a plugin like Markdown is free to depend on python-markdown, imported lazily so the cost is only paid when the plugin is actually used.

The plugin protocol

A plugin is any object with an apply method:

class Plugin(Protocol):
    def apply(self, builder: Builder) -> None: ...

Inside apply, the plugin taps the hooks it cares about. That is the entire contract between the kernel and its extensions.

The Builder

The Builder is created from a Config. On construction it applies every plugin (calling apply), then fires the initialize hook. Calling run() executes one full lifecycle and returns the resulting Build.

Because the builder is a long-lived object, it is the natural home for a future watch mode that rebuilds on file changes - without changing any plugin.