Skip to content

Hooks Pipeline

Headerkit provides a unified, priority-ordered hook pipeline (headerkit.hooks) for intercepting and customizing parsing, IR transformation, and output generation.

Priority Tiers

Hooks execute according to integer priority tiers defined in Priority. Higher numeric values execute first:

Tier Value Intended Usage
Priority.FALLBACK 10 Default fallback handlers (e.g. Tree-sitter fallback when system libclang is unavailable)
Priority.STANDARD 50 Built-in backends and writers
Priority.PROJECT 100 Local repository customizations and pyproject.toml extensions
Priority.OVERRIDE 1000 Explicit hard overrides that take absolute precedence

Execution Modes

The HookDispatcher supports two execution modes:

  • First-Result Dispatch (first_result): Queries matching candidate hooks sorted from highest priority to lowest. The first hook to return a non-None value wins. If a hook returns None, the dispatcher cascades to the next candidate.
  • Waterfall Pipeline (waterfall): Passes an initial value sequentially through all matching hooks in priority order, threading the transformed output through each stage.

Pattern Matching with Globs

Hooks can filter invocation contexts by specifying attribute matchers:

from headerkit.hooks import hook, Priority, PipelineContext
from headerkit.ir import SourceUnit

@hook("parse_unit", backend="tree-sitter", priority=Priority.STANDARD)
def custom_parser(code: str, filename: str, context: PipelineContext) -> SourceUnit | None:
    ...

@hook("write_output", writer="ctypes", priority=Priority.STANDARD)
def write_ctypes(unit: SourceUnit, context: PipelineContext) -> str:
    ...

@hook("write_output", writer="*", target="*windows*", priority=Priority.PROJECT)
def windows_override(unit: SourceUnit, context: PipelineContext) -> str:
    ...

Backend and Writer Unification

All parser backends and output writers register into the unified hook pipeline: - Backends register at parse_unit and get_backend. - Writers register at write_output and get_writer. - Calling get_backend() and get_writer() queries the highest-priority matching hook. - Custom plugins can override built-in backends or writers by registering hooks at Priority.PROJECT (100) or Priority.OVERRIDE (1000).

3-Stage Pipeline: Ingestion to Output

The pipeline executes in three stages: 1. parse_unit (first_result): Parses raw source into a SourceUnit Intermediate Representation. 2. transform_unit (waterfall): Passes the SourceUnit through sequential AST transformations (such as runtime lifecycle injections, macro expansion, or dialect conversions). 3. write_output (first_result): Generates code for the requested writer target.

execute_pipeline automates this three-stage flow:

from headerkit.hooks import execute_pipeline, PipelineContext
from headerkit.ir import InputSpec

spec = InputSpec.from_path("api.h", content="int compute(int x);")
ctx = PipelineContext(backend="tree-sitter", writer="json", runtime="nim")
unit, output = execute_pipeline(spec, context=ctx)

API Reference

Priority

Bases: IntEnum

Execution priority tiers for registered hooks.

Higher numeric values execute first.

PipelineContext dataclass

PipelineContext(backend=None, writer=None, target=None, layout=None, language=None, classification=None, runtime=None, options=None)

Contextual metadata passed to hooks during dispatch.

HookRegistry

HookRegistry()

Registry maintaining registered hooks organized by hook point.

register

register(point, func, priority=STANDARD, **matchers)

Register a hook implementation.

get_matching

get_matching(point, context)

Return matching hooks sorted by priority descending and specificity descending.

For ties in priority and specificity, later registered hooks take precedence.

snapshot classmethod

snapshot()

Return a copy of all globally registered hooks.

restore classmethod

restore(snapshot)

Restore global hooks from a snapshot.

clear classmethod

clear()

Clear all globally registered hooks.

hook

hook(point, priority=STANDARD, registry=None, **matchers)

Decorator to register a hook implementation.

HookDispatcher

HookDispatcher(registry=None)

Dispatches calls across registered hooks according to execution mode.

first_result

first_result(point, *args, context, **kwargs)

Execute matching hooks in priority order until one returns a non-None value.

waterfall

waterfall(point, initial_value, *args, context, **kwargs)

Pass a value sequentially through matching hooks in priority order.

HookCaller

HookCaller(point, registry=None)

Convenience caller bound to a specific hook point.

execute_pipeline

execute_pipeline(input_item, code=None, context=None, dispatcher=None, **kwargs)

Execute the 3-stage hook pipeline: parse_unit -> transform_unit -> write_output.