Main exports
Narrate actions
narrate(actions: &[EditAction], file_path: Option<&str>) -> Vec<SemanticChange> attaches descriptions and optional file identity. narrate_action(&EditAction) -> String describes one action. humanize_kind(&str) -> String formats canonical/parser concept names.
OutputFormat is Terminal, Json, Markdown, Llm, or Ndjson. format_changes(changes, format) -> Result<String, serde_json::Error> renders a change list. readable_changes(changes, limit) groups descendant edits into named constructs for presentation; summarize(changes, compact) returns a summary string.
SemanticChange owns an action, description, optional file path, and optional cross-file paths. Its grouped flag is internal presentation state and is skipped in JSON. Grouping does not redefine the underlying matching result.
For repository/directory envelopes, ordered file streaming, and cross-file correlation, use differens-engine::report. Single-file JSON is a change array; changeset JSON is an envelope. See machine outputs.
Vocabulary
Concepts are assigned by the parser adapters, then converted to display names. For example,humanize_kind("CallExpression") returns "call expression".
Descriptions include a useful named scope, such as a containing class or
function. Go method descriptions include the receiver type. Related edits may
be grouped under a declaration, but narration does not change the core matching
result. Some name-token duplicates are suppressed; not every grammar produces
one displayed line for every rename.
Parse, narrate, and render
This example is self-contained withdifferens-tiers and differens-narrate
dependencies. It prints terminal output followed by the compact LLM report:
format_changes(..., OutputFormat::Ndjson) serializes individual changes as
lines. The CLI’s file-record NDJSON contract comes from the engine reporting
layer, which also handles cross-file trailers. Use
differens-engine::report when you need that full changeset format.