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-Nonevalue wins. If a hook returnsNone, 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
¶
Registry maintaining registered hooks organized by hook point.
get_matching
¶
Return matching hooks sorted by priority descending and specificity descending.
For ties in priority and specificity, later registered hooks take precedence.
hook
¶
Decorator to register a hook implementation.
HookDispatcher
¶
Dispatches calls across registered hooks according to execution mode.
execute_pipeline
¶
Execute the 3-stage hook pipeline: parse_unit -> transform_unit -> write_output.