packages/engine/impact
Impact analysis: given a set of seed units (or changed files), compute the blast radius — which features and layers a change touches, which files are implicated and WHY, what is shared and therefore risky, and what th...
Engine, next. Source: packages/engine/impact.mjs.
Variables#
DEFAULT_DEPTH#
constDEFAULT_DEPTH:2=2
Defined in: packages/engine/impact.mjs:37
Default transitive depth on the importer (upstream) direction — see the module docs and .
DEFAULT_LIMITS#
constDEFAULT_LIMITS:object
Defined in: packages/engine/impact.mjs:40
maxSeeds is sized for a real PR diff, not for hand-typed refs; a bigger diff than this declines loudly rather than producing a report nobody can read.
Type Declaration#
maxFiles
maxFiles:
number=200
maxSeeds
maxSeeds:
number=100
ENTRY_PROVENANCE#
constENTRY_PROVENANCE:string[]
Defined in: packages/engine/impact.mjs:42
SCHEMA_VERSION#
constSCHEMA_VERSION:1=1
Defined in: packages/engine/impact.mjs:35
SEED_METHODS#
constSEED_METHODS:string[]
Defined in: packages/engine/impact.mjs:43
SEED_PROVENANCE#
constSEED_PROVENANCE:string[]
Defined in: packages/engine/impact.mjs:41
SHARED_BY_FEATURES#
constSHARED_BY_FEATURES:2=2
Defined in: packages/engine/impact.mjs:45
How many distinct other features must import a file before it is called shared.
Functions#
analyzeImpact()#
analyzeImpact(
root,request?,opts?):any
Defined in: packages/engine/impact.mjs:166
Compute the impact of changing a set of units.
Parameters#
root
string
project root
request?
seeds: string refs ("feature:login", "features/login/domain/Login.tsx", "/login", "PAGE-003"),
or objects {ref|path, provenance, method, confidence, why, evidence}.
files: shorthand for file-path seeds (PR health passes the diff here).
depth: transitive importer hops, default 2. 0 = the seed units only; Infinity / -1 = unbounded.
depth?
number
files?
string[]
limits?
{ maxFiles?: number; }
limits.maxFiles?
number
seeds?
any[]
opts?
registry?
any
Returns#
any
impact report, or {ok:false, error}. Never throws, never writes.
buildImportGraph()#
buildImportGraph(
ctx):object
Defined in: packages/engine/impact.mjs:107
Forward (what each file imports) and reverse (who imports each file) indexes over project source, both restricted to files that actually exist in the tree. Deterministic: sorted everywhere.
Parameters#
ctx
any
Returns#
object
deps
deps:
Map<any,any>
files
files:
any
importers
importers: (
p) =>any
Parameters
p
any
Returns
any
impactApiManifest()#
impactApiManifest():
any
Defined in: packages/engine/impact.mjs:532
Machine-readable usage note for agents (served by construct research impact --usage).
Returns#
any
The usage note: schema version, provenance meanings, depth semantics and the call signatures.
impactFromChangedFiles()#
impactFromChangedFiles(
root,files,opts?):any
Defined in: packages/engine/impact.mjs:422
PR health entry point: the changed files of a diff are the seeds. Deterministic in, so
every row comes back provenance: "derived". One implementation — this delegates to analyzeImpact.
Parameters#
root
string
Project root.
files
string | string[]
The changed file(s), project-relative.
opts?
any = {}
depth and limits, plus any other analyzeImpact option.
Returns#
any
The impact report ({ok:true, ...} or {ok:false, error}), every row provenance: "derived".
Example#
impactFromChangedFiles(root, ['features/plan/services/planApi.ts'], { depth: 2 });
impactFromTicketText()#
impactFromTicketText(
root,text,opts?):any
Defined in: packages/engine/impact.mjs:518
Ticket text -> candidate seeds -> impact report, in one call. The seeds are all inferred, so every entry they reach is marked inferred too.
Parameters#
root
any
text
any
opts?
Returns#
any
proposeSeedsFromText()#
proposeSeedsFromText(
root,text,opts?):any
Defined in: packages/engine/impact.mjs:449
Propose candidate seeds from a ticket written in English — keyword/path/route/identifier matching
against what the project actually contains. LLM-free and offline, but heuristic: every candidate
comes back provenance: "inferred", method: "text-match", with the matched evidence, so
analyzeImpact marks everything downstream of it inferred too.
A model-assisted proposer is a drop-in alternative: emit the same seed objects with
method: "model". Core itself never calls an LLM.
Parameters#
root
string
Project root.
text
string
The ticket, in English.
opts?
maxSeeds?
number
Upper bound on candidates returned.
Returns#
any
{schemaVersion, ok:true, method:'text-match', count, seeds} or {ok:false, error}: candidate seeds, each provenance: 'inferred' with its evidence; {ok:false} for a missing root or empty text.
Example#
proposeSeedsFromText(root, 'Add a retry button to the plan pane', { maxSeeds: 5 });
renderImpactMarkdown()#
renderImpactMarkdown(
result):string
Defined in: packages/engine/impact.mjs:566
Render an impact report (or an error) as Markdown.
Parameters#
result
any
An impact report or error from analyzeImpact.
Returns#
string
Markdown: the seeds, features touched and files of the report, or an error heading.
scopeOf()#
scopeOf(
ctx,relPath):object
Defined in: packages/engine/impact.mjs:142
Which vertical slice a file belongs to: its feature, or (outside features/) its top-level dir.
Parameters#
ctx
any
relPath
any
Returns#
object
kind
kind:
string='feature'
name
name:
any