Expand description
Host capability exposing the harn-rules declarative rule engine to
Harn as rules.search / rules.report / rules.apply.
This crate lives outside harn-hostlib on purpose: harn-rules already
depends on harn-hostlib (for the tree-sitter grammars), so the rules
builtins would form a dependency cycle if they lived there. An embedder
(harn-cli, harn-serve) calls install alongside harn_hostlib::install_default.
§Builtins
rules.search(read-only) — run a rule and return its matches.rules.report(read-only) — run a rule in report-only mode and return aharn_rules::DataTable(counts + per-match rows).rules.diagnostics(read-only) — run a declarative rule and return itsharn_rules::Diagnostics (message + severity + span + fix).rules.visit(read-only, async) — the imperative escape hatch: run a rule’s matcher, then invoke a.harnvisitoron_match($node, $ctx)once per match. The visitor returns its report(s) —nil/falseto skip, a{message, fix, safety}dict, or a list of them — which the engine turns into diagnostics of the same shaperules.diagnosticsemits. The visitor has full programmatic control (compute a message/fix from the captured metavars), which the declarative form cannot.rules.apply(write-gated) — apply a codemod rule’sfix; writes only whendry_run: falseand the rule is safe to auto-apply (orallow_unsafe: true). Shares the deterministic-tools gate with the other mutating builtins.
A rule is passed as its TOML source (rule), so an agent can author and
run a rule — declarative or imperative — entirely from .harn without
recompiling the binary.
§Why rules.visit is async, and why it returns rather than mutates
A synchronous hostlib builtin cannot call a .harn closure: the VM’s
Vm::call_closure_pub is async-only. So the visitor is registered as an
async builtin (directly on the VM via Vm::register_async_builtin,
bypassing the sync HostlibRegistry), which can obtain a child VM from
its AsyncBuiltinCtx and call back per match.
The visitor returns its reports instead of calling a mutating
ctx.report(...): Harn closures capture by value, so a Harn-side
accumulator could not collect across calls, and VmValue has no callable
variant that carries captured Rust state to embed a stateful report
method in ctx. Returning is both the sound option and the simpler one.
Structs§
- Lint
Capability - The
linthost capability (#2851): runs the Harn linter for an agent/IDE/cloud caller, returning the same diagnostics the CLI emits. - Rules
Capability - The
ruleshost capability.
Functions§
- install
- Install the
rules+lintcapabilities into a VM. Call this alongsideharn_hostlib::install_default.