@gobing-ai/ts-rule-engine 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -19,8 +19,8 @@ erDiagram
19
19
  CAPABILITY_REGISTRY ||--o{ EVALUATOR : registers
20
20
  CAPABILITY_REGISTRY ||--o{ RESOLVER : registers
21
21
  CAPABILITY_REGISTRY ||--o{ FORMATTER : registers
22
+ CAPABILITY_REGISTRY ||--o{ FIXER_PROVIDER : registers
22
23
  RULE_ENGINE ||--o{ CONSTRAINT_RULE : evaluates
23
- RULE_ENGINE ||--o{ FIXER_PROVIDER : owns
24
24
  PRESET ||--o{ CONSTRAINT_RULE : composes
25
25
  PRESET ||--o{ EXTENSION_REF : declares
26
26
  EXTENSION_REF }o--|| RULE_ENGINE_HOST : loads_into
@@ -32,7 +32,7 @@ erDiagram
32
32
  | Entity | One-line Description |
33
33
  |--------|----------------------|
34
34
  | `RuleEngine` | Orchestrates evaluation of enabled rules against a workspace directory. Supports opt-in early exit via `stopOnFirst` parameter. Accepts an optional `EventBus<RuleEngineEvents>` for structured in-process observability. |
35
- | `RuleEngineHost` | Capability host backed by `CapabilityRegistry` from `@gobing-ai/ts-runtime/plugin` — holds evaluators, resolvers, and formatters, each with origin tracking for safe override detection. |
35
+ | `RuleEngineHost` | Capability host backed by `CapabilityRegistry` from `@gobing-ai/ts-runtime/plugin` — holds evaluators, resolvers, formatters, and fixer providers, each with origin tracking for safe override detection. |
36
36
  | `CapabilityRegistry<T>` | Generic named registry (shared with `ts-rule-engine`, `ts-dual-workflow-engine`) that tags each entry with its `origin` (`'builtin'`, `'extension'`, `'caller'`). |
37
37
  | `ConstraintRule` | Declarative policy unit: id, severity, include/exclude globs, evaluator type + config, and optional fix config. |
38
38
  | `Preset` | YAML/JSON composition: extends rule categories and other presets, declares `disable`/`overrides`, and exposes extension modules. |
@@ -65,8 +65,8 @@ flowchart TD
65
65
  Core concepts:
66
66
 
67
67
  - `ConstraintRule`: one policy check. It has an `id`, `severity`, evaluator type/config, optional include/exclude globs, and optional fix config.
68
- - `RuleEngine`: runs enabled rules against a `workdir`. The constructor auto-registers built-in evaluators, formatters, and resolvers.
69
- - `RuleEngineHost`: capability container backed by three `CapabilityRegistry` instances from `@gobing-ai/ts-runtime/plugin`. Each entry tracks its origin (`'builtin'` / `'extension'` / `'caller'`) so the engine can detect and report conflicting registrations.
68
+ - `RuleEngine`: runs enabled rules against a `workdir`. The constructor auto-registers built-in evaluators, formatters, resolvers, and fixer providers.
69
+ - `RuleEngineHost`: capability container backed by four `CapabilityRegistry` instances from `@gobing-ai/ts-runtime/plugin`. Each entry tracks its origin (`'builtin'` / `'extension'` / `'caller'`) so the engine can detect and report conflicting registrations.
70
70
  - `RuleEvaluator`: implementation of one rule type, such as `regex`, `path`, or `coverage-gate`.
71
71
  - `Fix`: byte-range replacement candidate. Fixes are collected separately from findings and only written when you call `applyFixes()`.
72
72
  - Preset: YAML/JSON file that composes rule categories and can expose extension modules.
@@ -112,7 +112,9 @@ sequenceDiagram
112
112
  Evaluator-->>Engine: { findings: Finding[], fixes: Fix[] }
113
113
 
114
114
  opt rule.fix mode ≠ none and findings exist
115
- Engine->>Fixer: fixers.get(evaluatorType)
115
+ Engine->>Host: host.fixers.getEntry(evaluatorType)?.capability
116
+ Host-->>Engine: RuleFixerProvider (or undefined)
117
+ Engine->>Fixer: provider.createFixes(input)
116
118
  Fixer->>Fixer: resolve effective mode (min(rule, caller))
117
119
  Fixer->>FS: read / write (dry-run or real)
118
120
  Fixer-->>Engine: Fix[]
@@ -136,31 +138,7 @@ The key design decisions visible in this flow:
136
138
  - **Evaluators are stateless plugins**: each evaluator receives `(rule, context)` and returns findings. The engine owns the loop, error boundary, and fixer dispatch.
137
139
  - **Fixes are opt-in and authority-gated**: the effective fix mode is `min(rule.fix.mode, caller.maxFixMode)`. Fixes are never written during evaluation — only when the caller explicitly calls `applyFixes()`.
138
140
  - **Extension loading is trust-gated**: the `allowExtensions` flag must be explicitly `true`. Without it, `loadExtensionsIntoHost()` throws, preventing untrusted code from registering capabilities.
139
- - **Origins prevent silent override**: each `CapabilityRegistry` entry records its origin. A preset extension cannot silently replace a built-in evaluator — conflicts are surfaced.
140
-
141
- ## Quick Start
142
-
143
- ```ts
144
- import { RuleEngine, TextFormatter, type ConstraintRule } from '@gobing-ai/ts-rule-engine';
145
-
146
- const rules: ConstraintRule[] = [
147
- {
148
- id: 'no-console-log',
149
- description: 'Do not commit console.log calls',
150
- enabled: true,
151
- severity: 'error',
152
- include: ['src/**/*.ts'],
153
- evaluator: {
154
- type: 'regex',
155
- config: {
156
- mode: 'forbid',
157
- pattern: 'console\\.log\\(',
158
- },
159
- },
160
- },
161
- ];
162
- ```
163
-
141
+ - **Origins prevent silent override**: each `CapabilityRegistry` entry records its origin. A preset extension cannot silently replace a built-in capability (evaluator, resolver, formatter, or fixer) — conflicts are surfaced.
164
142
 
165
143
  ## Quick Start
166
144
 
@@ -672,6 +650,8 @@ extensions:
672
650
  - ./extensions/custom-resolver.ts
673
651
  evaluators:
674
652
  - ./extensions/custom-evaluator.ts
653
+ fixers:
654
+ - ./extensions/custom-fixer.ts
675
655
  formatters:
676
656
  - ./extensions/compact-formatter.ts
677
657
  ```
@@ -702,6 +682,22 @@ const evaluator: RuleEvaluator & { name: string } = {
702
682
  export default evaluator;
703
683
  ```
704
684
 
685
+ Fixer extension (keyed by the evaluator type it handles):
686
+
687
+ ```ts
688
+ import type { RuleFixerProvider } from '@gobing-ai/ts-rule-engine';
689
+
690
+ const fixer: RuleFixerProvider & { name: string } = {
691
+ name: 'custom-fixer',
692
+ async createFixes(input) {
693
+ // Return Fix[] (byte-range replacements) based on findings and fix config.
694
+ return [];
695
+ },
696
+ };
697
+
698
+ export default fixer;
699
+ ```
700
+
705
701
  Load extensions (uses the shared `loadExtensionModules` from `@gobing-ai/ts-runtime/plugin`):
706
702
 
707
703
  ```ts
@@ -720,8 +716,8 @@ Supported extension kinds:
720
716
  | ---- | ------------ | -------------- | ------ |
721
717
  | `resolvers` | `host.resolvers` (`CapabilityRegistry<TestPathResolver>`) | object with `name` and `resolveTestPath()` | `'extension'` |
722
718
  | `evaluators` | `host.evaluators` (`CapabilityRegistry<RuleEvaluator>`) | object with `name` and `evaluate()` | `'extension'` |
719
+ | `fixers` | `host.fixers` (`CapabilityRegistry<RuleFixerProvider>`) | object with `name` and `createFixes()`, keyed by evaluator type | `'extension'` |
723
720
  | `formatters` | `host.formatters` (`CapabilityRegistry<ResultFormatter>`) | object with `name` and `format()` | `'extension'` |
724
-
725
721
  ## Traversal Control (`stopOnFirst`)
726
722
 
727
723
  By default, the engine evaluates every enabled rule exhaustively. Pass `stopOnFirst: 'error' | 'warning' | 'info'` to break early when the severity threshold is met:
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/config/extensions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAOlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,2DAA2D;AAC3D,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEjF,yEAAyE;AACzE,MAAM,WAAW,YAAY;IACzB,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AAED,oDAAoD;AACpD,MAAM,WAAW,qBAAqB;IAClC;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,oFAAoF;IACpF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACxE;AASD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC7B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,GAC7E,YAAY,EAAE,CAShB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CACxC,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,SAAS,YAAY,EAAE,EAC7B,OAAO,GAAE,qBAA0B,GACpC,OAAO,CAAC,IAAI,CAAC,CAuDf"}
1
+ {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/config/extensions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAOlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,2DAA2D;AAC3D,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEjF,yEAAyE;AACzE,MAAM,WAAW,YAAY;IACzB,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AAED,oDAAoD;AACpD,MAAM,WAAW,qBAAqB;IAClC;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,oFAAoF;IACpF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACxE;AAUD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC7B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,GAC7E,YAAY,EAAE,CAShB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CACxC,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,SAAS,YAAY,EAAE,EAC7B,OAAO,GAAE,qBAA0B,GACpC,OAAO,CAAC,IAAI,CAAC,CAuDf"}
@@ -1,10 +1,11 @@
1
1
  import { fileURLToPath } from 'node:url';
2
2
  import { basenamePath, dirnamePath, resolvePath, SEP } from '@gobing-ai/ts-runtime';
3
3
  import { loadExtensionModules } from '@gobing-ai/ts-runtime/plugin';
4
- /** Host registries that can receive extension capabilities (fixers live on the engine, not the host). */
4
+ /** Host registries that can receive extension capabilities (all four kinds). */
5
5
  const HOST_REGISTRY_BY_KIND = {
6
6
  resolvers: 'resolvers',
7
7
  evaluators: 'evaluators',
8
+ fixers: 'fixers',
8
9
  formatters: 'formatters',
9
10
  };
10
11
  /**
package/dist/engine.d.ts CHANGED
@@ -19,8 +19,6 @@ export interface RuleEngineOptions {
19
19
  export declare class RuleEngine {
20
20
  /** Capability host used by this engine. */
21
21
  readonly host: RuleEngineHost;
22
- /** Fixer providers keyed by evaluator type. */
23
- private readonly fixers;
24
22
  private readonly events;
25
23
  private readonly logger;
26
24
  constructor(options?: RuleEngineOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAKH,KAAK,oBAAoB,EAE5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAqB,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGhH,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAC9B,+DAA+D;IAC/D,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,mCAAmC;IACnC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,kEAAkE;IAClE,MAAM,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IACpC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,4EAA4E;AAC5E,qBAAa,UAAU;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAE9B,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,iBAAsB;IAQ3C,wCAAwC;IACxC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI;IAI/D;;;;;;;OAOG;IACG,QAAQ,CACV,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAC3C,OAAO,CAAC,gBAAgB,CAAC;IAI5B;;;;;;;;;;;;;;OAcG;IACG,iBAAiB,CACnB,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,UAAU,GAAE,OAAgB,EAC5B,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAC3C,OAAO,CAAC,gBAAgB,CAAC;IAoH5B;;;;;;;OAOG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAG1G"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAIH,KAAK,oBAAoB,EAE5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAqB,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGhH,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAC9B,+DAA+D;IAC/D,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,mCAAmC;IACnC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,kEAAkE;IAClE,MAAM,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IACpC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,4EAA4E;AAC5E,qBAAa,UAAU;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAE9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,iBAAsB;IAQ3C,wCAAwC;IACxC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI;IAI/D;;;;;;;OAOG;IACG,QAAQ,CACV,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAC3C,OAAO,CAAC,gBAAgB,CAAC;IAI5B;;;;;;;;;;;;;;OAcG;IACG,iBAAiB,CACnB,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,UAAU,GAAE,OAAgB,EAC5B,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAC3C,OAAO,CAAC,gBAAgB,CAAC;IAoH5B;;;;;;;OAOG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAG1G"}
package/dist/engine.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { addSpanEvent, getLogger, traceAsync } from '@gobing-ai/ts-infra';
2
- import { applyFixes as applyFixesImpl, builtInFixers, FIX_MODE_RANK, } from './fixers/fixers.js';
2
+ import { applyFixes as applyFixesImpl, FIX_MODE_RANK, registerBuiltinFixers, } from './fixers/fixers.js';
3
3
  import { registerBuiltins } from './host/builtins.js';
4
4
  import { RuleEngineHost } from './host/rule-engine-host.js';
5
5
  import { createFinding, SEVERITY_RANK } from './types.js';
@@ -7,14 +7,12 @@ import { createFinding, SEVERITY_RANK } from './types.js';
7
7
  export class RuleEngine {
8
8
  /** Capability host used by this engine. */
9
9
  host;
10
- /** Fixer providers keyed by evaluator type. */
11
- fixers;
12
10
  events;
13
11
  logger;
14
12
  constructor(options = {}) {
15
13
  this.host = options.host ?? new RuleEngineHost();
16
14
  registerBuiltins(this.host, options.processExecutor);
17
- this.fixers = builtInFixers(this.host, options.processExecutor);
15
+ registerBuiltinFixers(this.host, options.processExecutor);
18
16
  this.events = options.events;
19
17
  this.logger = options.logger ?? getLogger('rule-engine');
20
18
  }
@@ -103,7 +101,7 @@ export class RuleEngine {
103
101
  const ruleMode = rule.fix?.mode ?? 'none';
104
102
  const effectiveMode = effectiveFixMode(ruleMode, maxFixMode);
105
103
  if (effectiveMode !== 'none' && ruleFindings.length > 0) {
106
- const provider = this.fixers.get(rule.evaluator.type);
104
+ const provider = this.host.fixers.getEntry(rule.evaluator.type)?.capability;
107
105
  if (provider) {
108
106
  const effectiveFix = {
109
107
  mode: effectiveMode,
@@ -1,40 +1,15 @@
1
1
  /**
2
- * Core fixer pipeline: provider contracts, built-in fixer implementations,
2
+ * Core fixer pipeline: built-in fixer implementations,
3
3
  * and the byte-range fix application function.
4
4
  *
5
5
  * @module rule-engine/fixers
6
6
  */
7
7
  import { NodeFileSystem, type ProcessExecutor } from '@gobing-ai/ts-runtime';
8
- import type { CapabilityRegistry } from '@gobing-ai/ts-runtime/plugin';
9
- import type { TestPathResolver } from '../resolvers/test-path-resolver';
10
- import type { ConstraintFinding, ConstraintRule, Fix, FixMode, RuleContext } from '../types';
8
+ import type { RuleEngineHost } from '../host/rule-engine-host';
9
+ import type { Fix, FixMode, RuleFixerInput, RuleFixerProvider } from '../types';
10
+ export type { EffectiveFix, RuleFixerInput, RuleFixerProvider } from '../types';
11
11
  /** Numeric ordering for fix authority; higher means more write authority. */
12
12
  export declare const FIX_MODE_RANK: Record<FixMode, number>;
13
- /** Result of resolving effective fix authority for a rule. */
14
- export interface EffectiveFix {
15
- /** Effective mode after all downgrades. */
16
- readonly mode: FixMode;
17
- /** Optional replacement text configured by the rule author. */
18
- readonly replacement?: string;
19
- /** Optional provider-specific parameters. */
20
- readonly params?: Record<string, unknown>;
21
- }
22
- /** Input passed to a rule fixer provider. */
23
- export interface RuleFixerInput {
24
- /** Rule that produced the findings. */
25
- readonly rule: ConstraintRule;
26
- /** Rule execution context. */
27
- readonly context: RuleContext;
28
- /** Findings emitted for this rule. */
29
- readonly findings: ConstraintFinding[];
30
- /** Effective fix metadata after authority enforcement. */
31
- readonly fix: EffectiveFix;
32
- }
33
- /** Provider that turns findings into byte-range fixes. */
34
- export interface RuleFixerProvider {
35
- /** Produce fixes for mechanically fixable findings. */
36
- createFixes(input: RuleFixerInput): Fix[] | Promise<Fix[]>;
37
- }
38
13
  /** Result of applying or previewing a batch of fixes. */
39
14
  export interface FixApplicationResult {
40
15
  /** Files changed in memory or on disk. */
@@ -46,13 +21,8 @@ export interface FixApplicationResult {
46
21
  /** Unified diff when dry-run mode is requested. */
47
22
  readonly diff: string;
48
23
  }
49
- /** Dependencies required for the built-in fixer registry. */
50
- export interface BuiltInFixersDeps {
51
- /** Resolver registry, required for TestStubFixer. */
52
- resolvers: CapabilityRegistry<TestPathResolver>;
53
- }
54
- /** Registry of built-in rule fixer providers keyed by evaluator type. */
55
- export declare function builtInFixers(host?: BuiltInFixersDeps, exec?: ProcessExecutor): Map<string, RuleFixerProvider>;
24
+ /** Register built-in fixer providers into the host's fixer registry. */
25
+ export declare function registerBuiltinFixers(host: RuleEngineHost, exec?: ProcessExecutor): void;
56
26
  /** Resolve a workdir-relative or absolute path to an absolute path. */
57
27
  export declare function resolveWorkdirPath(workdir: string, filePath: string): string;
58
28
  /** Apply byte-range fixes to files, optionally returning a dry-run diff only. */
@@ -1 +1 @@
1
- {"version":3,"file":"fixers.d.ts","sourceRoot":"","sources":["../../src/fixers/fixers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fixers.d.ts","sourceRoot":"","sources":["../../src/fixers/fixers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGH,cAAc,EACd,KAAK,eAAe,EAGvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAkB,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAIhG,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAEhF,6EAA6E;AAC7E,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAIjD,CAAC;AAEF,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACjC,0CAA0C;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAChC,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC;IACzB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,IAAI,CAcxF;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,iFAAiF;AACjF,wBAAsB,UAAU,CAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,GAAG,EAAE,EACrB,MAAM,UAAQ,EACd,EAAE,GAAE,cAAqC,GAC1C,OAAO,CAAC,oBAAoB,CAAC,CA0D/B;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOzF;AA8BD;;;;;;GAMG;AACH,qBAAa,kBAAmB,YAAW,iBAAiB;IACxD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAwB;IAE3C,kDAAkD;IAC5C,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;CAkCtF;AAED;;;;;;GAMG;AACH,qBAAa,iBAAkB,YAAW,iBAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAwB;IAE3C,0DAA0D;IACpD,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;CAoBtF"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Core fixer pipeline: provider contracts, built-in fixer implementations,
2
+ * Core fixer pipeline: built-in fixer implementations,
3
3
  * and the byte-range fix application function.
4
4
  *
5
5
  * @module rule-engine/fixers
@@ -12,20 +12,17 @@ export const FIX_MODE_RANK = {
12
12
  suggest: 1,
13
13
  auto: 2,
14
14
  };
15
- /** Registry of built-in rule fixer providers keyed by evaluator type. */
16
- export function builtInFixers(host, exec) {
15
+ /** Register built-in fixer providers into the host's fixer registry. */
16
+ export function registerBuiltinFixers(host, exec) {
17
17
  const regexFixer = new RegexFixerProvider();
18
18
  const pathFixer = new PathFixerProvider();
19
- const entries = [
20
- ['regex', regexFixer],
21
- ['rg', regexFixer],
22
- ['path', pathFixer],
23
- ['file-exist', pathFixer],
24
- ];
25
- if (host && exec) {
26
- entries.push(['test-location', new TestStubFixer({ resolvers: host.resolvers, processExecutor: exec })]);
19
+ host.fixers.register('regex', regexFixer, 'builtin');
20
+ host.fixers.register('rg', regexFixer, 'builtin');
21
+ host.fixers.register('path', pathFixer, 'builtin');
22
+ host.fixers.register('file-exist', pathFixer, 'builtin');
23
+ if (exec) {
24
+ host.fixers.register('test-location', new TestStubFixer({ resolvers: host.resolvers, processExecutor: exec }), 'builtin');
27
25
  }
28
- return new Map(entries);
29
26
  }
30
27
  /** Resolve a workdir-relative or absolute path to an absolute path. */
31
28
  export function resolveWorkdirPath(workdir, filePath) {
@@ -1,6 +1,6 @@
1
1
  import { CapabilityRegistry } from '@gobing-ai/ts-runtime/plugin';
2
2
  import type { TestPathResolver } from '../resolvers/test-path-resolver';
3
- import type { ResultFormatter, RuleEvaluator } from '../types';
3
+ import type { ResultFormatter, RuleEvaluator, RuleFixerProvider } from '../types';
4
4
  /** Host container for rule-engine capabilities. */
5
5
  export declare class RuleEngineHost {
6
6
  /** Evaluator registry keyed by evaluator type. */
@@ -9,6 +9,8 @@ export declare class RuleEngineHost {
9
9
  readonly formatters: CapabilityRegistry<ResultFormatter>;
10
10
  /** Test-path resolver registry keyed by language name. */
11
11
  readonly resolvers: CapabilityRegistry<TestPathResolver>;
12
+ /** Fixer provider registry keyed by evaluator type. */
13
+ readonly fixers: CapabilityRegistry<RuleFixerProvider>;
12
14
  constructor();
13
15
  }
14
16
  //# sourceMappingURL=rule-engine-host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rule-engine-host.d.ts","sourceRoot":"","sources":["../../src/host/rule-engine-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE/D,mDAAmD;AACnD,qBAAa,cAAc;IACvB,kDAAkD;IAClD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACvD,kDAAkD;IAClD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACzD,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;;CAO5D"}
1
+ {"version":3,"file":"rule-engine-host.d.ts","sourceRoot":"","sources":["../../src/host/rule-engine-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElF,mDAAmD;AACnD,qBAAa,cAAc;IACvB,kDAAkD;IAClD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACvD,kDAAkD;IAClD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACzD,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IACzD,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;;CAQ1D"}
@@ -7,9 +7,12 @@ export class RuleEngineHost {
7
7
  formatters;
8
8
  /** Test-path resolver registry keyed by language name. */
9
9
  resolvers;
10
+ /** Fixer provider registry keyed by evaluator type. */
11
+ fixers;
10
12
  constructor() {
11
13
  this.evaluators = new CapabilityRegistry('evaluator');
12
14
  this.formatters = new CapabilityRegistry('formatter');
13
15
  this.resolvers = new CapabilityRegistry('resolver');
16
+ this.fixers = new CapabilityRegistry('fixer');
14
17
  }
15
18
  }
package/dist/types.d.ts CHANGED
@@ -152,6 +152,31 @@ export interface ResultFormatter {
152
152
  /** Format an engine result for CLI or machine output. */
153
153
  format(result: RuleEngineResult): string;
154
154
  }
155
+ /** Result of resolving effective fix authority for a rule. */
156
+ export interface EffectiveFix {
157
+ /** Effective mode after all downgrades. */
158
+ readonly mode: FixMode;
159
+ /** Optional replacement text configured by the rule author. */
160
+ readonly replacement?: string;
161
+ /** Optional provider-specific parameters. */
162
+ readonly params?: Record<string, unknown>;
163
+ }
164
+ /** Input passed to a rule fixer provider. */
165
+ export interface RuleFixerInput {
166
+ /** Rule that produced the findings. */
167
+ readonly rule: ConstraintRule;
168
+ /** Rule execution context. */
169
+ readonly context: RuleContext;
170
+ /** Findings emitted for this rule. */
171
+ readonly findings: ConstraintFinding[];
172
+ /** Effective fix metadata after authority enforcement. */
173
+ readonly fix: EffectiveFix;
174
+ }
175
+ /** Provider that turns findings into byte-range fixes. */
176
+ export interface RuleFixerProvider {
177
+ /** Produce fixes for mechanically fixable findings. */
178
+ createFixes(input: RuleFixerInput): Fix[] | Promise<Fix[]>;
179
+ }
155
180
  /** Engine-level evaluation result. */
156
181
  export interface RuleEngineResult {
157
182
  /** Findings emitted by enabled rules. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/ts-rule-engine",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "@gobing-ai/ts-rule-engine — Constraint rule schemas, loading, evaluation, and result formatting.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -49,9 +49,9 @@
49
49
  "release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-rule-engine-v<version> && git push --tags' && exit 1"
50
50
  },
51
51
  "dependencies": {
52
- "@gobing-ai/ts-ai-runner": "^0.3.3",
53
- "@gobing-ai/ts-infra": "^0.3.3",
54
- "@gobing-ai/ts-runtime": "^0.3.3",
52
+ "@gobing-ai/ts-ai-runner": "^0.3.5",
53
+ "@gobing-ai/ts-infra": "^0.3.5",
54
+ "@gobing-ai/ts-runtime": "^0.3.5",
55
55
  "yaml": "^2.7.0",
56
56
  "zod": "^4.1.0"
57
57
  },
@@ -34,10 +34,11 @@ export interface LoadExtensionsOptions {
34
34
  moduleLoader?: (absPath: string) => Promise<Record<string, unknown>>;
35
35
  }
36
36
 
37
- /** Host registries that can receive extension capabilities (fixers live on the engine, not the host). */
38
- const HOST_REGISTRY_BY_KIND: Partial<Record<ExtensionKind, 'resolvers' | 'evaluators' | 'formatters'>> = {
37
+ /** Host registries that can receive extension capabilities (all four kinds). */
38
+ const HOST_REGISTRY_BY_KIND: Record<ExtensionKind, 'resolvers' | 'evaluators' | 'fixers' | 'formatters'> = {
39
39
  resolvers: 'resolvers',
40
40
  evaluators: 'evaluators',
41
+ fixers: 'fixers',
41
42
  formatters: 'formatters',
42
43
  };
43
44
 
package/src/engine.ts CHANGED
@@ -4,11 +4,10 @@ import type { ProcessExecutor } from '@gobing-ai/ts-runtime';
4
4
  import type { RuleEngineEvents } from './events';
5
5
  import {
6
6
  applyFixes as applyFixesImpl,
7
- builtInFixers,
8
7
  type EffectiveFix,
9
8
  FIX_MODE_RANK,
10
9
  type FixApplicationResult,
11
- type RuleFixerProvider,
10
+ registerBuiltinFixers,
12
11
  } from './fixers/fixers';
13
12
  import { registerBuiltins } from './host/builtins';
14
13
  import { RuleEngineHost } from './host/rule-engine-host';
@@ -32,15 +31,13 @@ export class RuleEngine {
32
31
  /** Capability host used by this engine. */
33
32
  readonly host: RuleEngineHost;
34
33
 
35
- /** Fixer providers keyed by evaluator type. */
36
- private readonly fixers: Map<string, RuleFixerProvider>;
37
34
  private readonly events: EventBus<RuleEngineEvents> | undefined;
38
35
  private readonly logger: Logger;
39
36
 
40
37
  constructor(options: RuleEngineOptions = {}) {
41
38
  this.host = options.host ?? new RuleEngineHost();
42
39
  registerBuiltins(this.host, options.processExecutor);
43
- this.fixers = builtInFixers(this.host, options.processExecutor);
40
+ registerBuiltinFixers(this.host, options.processExecutor);
44
41
  this.events = options.events;
45
42
  this.logger = options.logger ?? getLogger('rule-engine');
46
43
  }
@@ -150,7 +147,7 @@ export class RuleEngine {
150
147
  const effectiveMode = effectiveFixMode(ruleMode, maxFixMode);
151
148
 
152
149
  if (effectiveMode !== 'none' && ruleFindings.length > 0) {
153
- const provider = this.fixers.get(rule.evaluator.type);
150
+ const provider = this.host.fixers.getEntry(rule.evaluator.type)?.capability;
154
151
  if (provider) {
155
152
  const effectiveFix: EffectiveFix = {
156
153
  mode: effectiveMode,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Core fixer pipeline: provider contracts, built-in fixer implementations,
2
+ * Core fixer pipeline: built-in fixer implementations,
3
3
  * and the byte-range fix application function.
4
4
  *
5
5
  * @module rule-engine/fixers
@@ -13,11 +13,13 @@ import {
13
13
  relativePath,
14
14
  resolvePath,
15
15
  } from '@gobing-ai/ts-runtime';
16
- import type { CapabilityRegistry } from '@gobing-ai/ts-runtime/plugin';
17
- import type { TestPathResolver } from '../resolvers/test-path-resolver';
18
- import type { ConstraintFinding, ConstraintRule, Fix, FixMode, RuleContext } from '../types';
16
+ import type { RuleEngineHost } from '../host/rule-engine-host';
17
+ import type { ConstraintRule, Fix, FixMode, RuleFixerInput, RuleFixerProvider } from '../types';
19
18
  import { TestStubFixer } from './test-stub-fixer';
20
19
 
20
+ // Re-export types that moved to ../types — consumers import them from the barrel.
21
+ export type { EffectiveFix, RuleFixerInput, RuleFixerProvider } from '../types';
22
+
21
23
  /** Numeric ordering for fix authority; higher means more write authority. */
22
24
  export const FIX_MODE_RANK: Record<FixMode, number> = {
23
25
  none: 0,
@@ -25,34 +27,6 @@ export const FIX_MODE_RANK: Record<FixMode, number> = {
25
27
  auto: 2,
26
28
  };
27
29
 
28
- /** Result of resolving effective fix authority for a rule. */
29
- export interface EffectiveFix {
30
- /** Effective mode after all downgrades. */
31
- readonly mode: FixMode;
32
- /** Optional replacement text configured by the rule author. */
33
- readonly replacement?: string;
34
- /** Optional provider-specific parameters. */
35
- readonly params?: Record<string, unknown>;
36
- }
37
-
38
- /** Input passed to a rule fixer provider. */
39
- export interface RuleFixerInput {
40
- /** Rule that produced the findings. */
41
- readonly rule: ConstraintRule;
42
- /** Rule execution context. */
43
- readonly context: RuleContext;
44
- /** Findings emitted for this rule. */
45
- readonly findings: ConstraintFinding[];
46
- /** Effective fix metadata after authority enforcement. */
47
- readonly fix: EffectiveFix;
48
- }
49
-
50
- /** Provider that turns findings into byte-range fixes. */
51
- export interface RuleFixerProvider {
52
- /** Produce fixes for mechanically fixable findings. */
53
- createFixes(input: RuleFixerInput): Fix[] | Promise<Fix[]>;
54
- }
55
-
56
30
  /** Result of applying or previewing a batch of fixes. */
57
31
  export interface FixApplicationResult {
58
32
  /** Files changed in memory or on disk. */
@@ -65,26 +39,21 @@ export interface FixApplicationResult {
65
39
  readonly diff: string;
66
40
  }
67
41
 
68
- /** Dependencies required for the built-in fixer registry. */
69
- export interface BuiltInFixersDeps {
70
- /** Resolver registry, required for TestStubFixer. */
71
- resolvers: CapabilityRegistry<TestPathResolver>;
72
- }
73
-
74
- /** Registry of built-in rule fixer providers keyed by evaluator type. */
75
- export function builtInFixers(host?: BuiltInFixersDeps, exec?: ProcessExecutor): Map<string, RuleFixerProvider> {
42
+ /** Register built-in fixer providers into the host's fixer registry. */
43
+ export function registerBuiltinFixers(host: RuleEngineHost, exec?: ProcessExecutor): void {
76
44
  const regexFixer = new RegexFixerProvider();
77
45
  const pathFixer = new PathFixerProvider();
78
- const entries: Array<[string, RuleFixerProvider]> = [
79
- ['regex', regexFixer],
80
- ['rg', regexFixer],
81
- ['path', pathFixer],
82
- ['file-exist', pathFixer],
83
- ];
84
- if (host && exec) {
85
- entries.push(['test-location', new TestStubFixer({ resolvers: host.resolvers, processExecutor: exec })]);
46
+ host.fixers.register('regex', regexFixer, 'builtin');
47
+ host.fixers.register('rg', regexFixer, 'builtin');
48
+ host.fixers.register('path', pathFixer, 'builtin');
49
+ host.fixers.register('file-exist', pathFixer, 'builtin');
50
+ if (exec) {
51
+ host.fixers.register(
52
+ 'test-location',
53
+ new TestStubFixer({ resolvers: host.resolvers, processExecutor: exec }),
54
+ 'builtin',
55
+ );
86
56
  }
87
- return new Map(entries);
88
57
  }
89
58
 
90
59
  /** Resolve a workdir-relative or absolute path to an absolute path. */
@@ -1,6 +1,6 @@
1
1
  import { CapabilityRegistry } from '@gobing-ai/ts-runtime/plugin';
2
2
  import type { TestPathResolver } from '../resolvers/test-path-resolver';
3
- import type { ResultFormatter, RuleEvaluator } from '../types';
3
+ import type { ResultFormatter, RuleEvaluator, RuleFixerProvider } from '../types';
4
4
 
5
5
  /** Host container for rule-engine capabilities. */
6
6
  export class RuleEngineHost {
@@ -10,10 +10,13 @@ export class RuleEngineHost {
10
10
  readonly formatters: CapabilityRegistry<ResultFormatter>;
11
11
  /** Test-path resolver registry keyed by language name. */
12
12
  readonly resolvers: CapabilityRegistry<TestPathResolver>;
13
+ /** Fixer provider registry keyed by evaluator type. */
14
+ readonly fixers: CapabilityRegistry<RuleFixerProvider>;
13
15
 
14
16
  constructor() {
15
17
  this.evaluators = new CapabilityRegistry<RuleEvaluator>('evaluator');
16
18
  this.formatters = new CapabilityRegistry<ResultFormatter>('formatter');
17
19
  this.resolvers = new CapabilityRegistry<TestPathResolver>('resolver');
20
+ this.fixers = new CapabilityRegistry<RuleFixerProvider>('fixer');
18
21
  }
19
22
  }
package/src/types.ts CHANGED
@@ -170,6 +170,34 @@ export interface ResultFormatter {
170
170
  format(result: RuleEngineResult): string;
171
171
  }
172
172
 
173
+ /** Result of resolving effective fix authority for a rule. */
174
+ export interface EffectiveFix {
175
+ /** Effective mode after all downgrades. */
176
+ readonly mode: FixMode;
177
+ /** Optional replacement text configured by the rule author. */
178
+ readonly replacement?: string;
179
+ /** Optional provider-specific parameters. */
180
+ readonly params?: Record<string, unknown>;
181
+ }
182
+
183
+ /** Input passed to a rule fixer provider. */
184
+ export interface RuleFixerInput {
185
+ /** Rule that produced the findings. */
186
+ readonly rule: ConstraintRule;
187
+ /** Rule execution context. */
188
+ readonly context: RuleContext;
189
+ /** Findings emitted for this rule. */
190
+ readonly findings: ConstraintFinding[];
191
+ /** Effective fix metadata after authority enforcement. */
192
+ readonly fix: EffectiveFix;
193
+ }
194
+
195
+ /** Provider that turns findings into byte-range fixes. */
196
+ export interface RuleFixerProvider {
197
+ /** Produce fixes for mechanically fixable findings. */
198
+ createFixes(input: RuleFixerInput): Fix[] | Promise<Fix[]>;
199
+ }
200
+
173
201
  /** Engine-level evaluation result. */
174
202
  export interface RuleEngineResult {
175
203
  /** Findings emitted by enabled rules. */