Documentation Index
Fetch the complete documentation index at: https://mintlify.com/cad0p/pi-steering-hooks/llms.txt
Use this file to discover all available pages before exploring further.
definePredicate<T> is a pure pass-through at runtime — it returns the handler unchanged. Use it so plugin authors can declare typed argument shapes without casting at the plugin registration site. The generic parameter T narrows the handler’s first argument to the author’s intended shape; the PredicateHandler<T> return type preserves that narrowing when the result is stored in a local variable. The Plugin.predicates registry slot then accepts the result cast-free via AnyPredicateHandler (which uses TypeScript’s bivariance fallback to admit typed handlers directly).
Signature
Type parameter
The typed argument shape the predicate accepts. This is whatever the rule
author writes under the
when.<key> slot in their config. The handler is
responsible for validating the actual value at runtime — TypeScript can catch
obvious mismatches, but a user writing when: { myPredicate: "not-the-expected-shape" }
bypasses compile-time narrowing. Guard the args shape at the top of the
handler body (e.g. if (typeof args !== "boolean") return false).Complete example
when.requiresFlag:
PredicateVerdict
| Return value | Meaning |
|---|---|
true | Predicate fires — rule condition is satisfied |
false | Predicate does not fire — rule condition is not satisfied |
"unknown" | Handler could not resolve its value |
boolean remain source-compatible — boolean is a subtype of PredicateVerdict, so existing handlers assign without changes.
"unknown" verdict and the onUnknown policy
When a handler returns "unknown" — typically because some piece of walker-tracked state (cwd, branch, etc.) was not statically resolvable — the engine applies the onUnknown policy configured on that predicate leaf to project the trinary verdict back to a definite boolean:
"block"(default): treat as fail-closed — the predicate fires."allow": treat as fail-open — the predicate skips.
not: block, the onUnknown policy lives at the block level rather than the leaf level, and applies to all leaves in the block.
Throw behavior
Throws inside a handler — synchronous or from a rejected promise — are caught by the engine, treated as"unknown", and the onUnknown policy applies. This prevents a buggy handler from silently failing open by skipping its rule. Prefer explicit "unknown" returns; the catch exists as a safety net, not a control-flow mechanism.
Registering module augmentations
For TypeScript to offer autocomplete and shape-checking onwhen.requiresFlag in rule definitions, declare the predicate in the global PiSteeringPredicates interface. This is separate from the handler registration in Plugin.predicates and is required for the registry-driven mapped types to surface the field:
when.requiresFlag is shape-checked at every rule definition site that uses defineConfig or satisfies Rule.