@markuplint/ml-core 4.13.2 → 4.18.0

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.
Files changed (80) hide show
  1. package/ARCHITECTURE.ja.md +467 -0
  2. package/ARCHITECTURE.md +467 -0
  3. package/CHANGELOG.md +14 -2
  4. package/README.md +5 -0
  5. package/SKILL.md +61 -0
  6. package/docs/linting-pipeline.ja.md +303 -0
  7. package/docs/linting-pipeline.md +303 -0
  8. package/docs/maintenance.ja.md +210 -0
  9. package/docs/maintenance.md +210 -0
  10. package/docs/ml-dom/attr.ja.md +95 -0
  11. package/docs/ml-dom/attr.md +95 -0
  12. package/docs/ml-dom/block.ja.md +272 -0
  13. package/docs/ml-dom/block.md +272 -0
  14. package/docs/ml-dom/document.ja.md +141 -0
  15. package/docs/ml-dom/document.md +141 -0
  16. package/docs/ml-dom/element.ja.md +176 -0
  17. package/docs/ml-dom/element.md +176 -0
  18. package/docs/ml-dom/helpers.ja.md +203 -0
  19. package/docs/ml-dom/helpers.md +203 -0
  20. package/docs/ml-dom/node.ja.md +200 -0
  21. package/docs/ml-dom/node.md +200 -0
  22. package/docs/ml-dom/others.ja.md +119 -0
  23. package/docs/ml-dom/others.md +119 -0
  24. package/docs/ml-dom/overview.ja.md +102 -0
  25. package/docs/ml-dom/overview.md +102 -0
  26. package/docs/ml-dom/pretender.ja.md +269 -0
  27. package/docs/ml-dom/pretender.md +269 -0
  28. package/docs/ml-dom/rule-mapping.ja.md +371 -0
  29. package/docs/ml-dom/rule-mapping.md +371 -0
  30. package/docs/ml-dom.ja.md +18 -0
  31. package/docs/ml-dom.md +18 -0
  32. package/docs/rule-system.ja.md +270 -0
  33. package/docs/rule-system.md +270 -0
  34. package/lib/convert-ruleset.d.ts +7 -0
  35. package/lib/convert-ruleset.js +7 -0
  36. package/lib/debug.d.ts +4 -0
  37. package/lib/debug.js +4 -0
  38. package/lib/ml-core.d.ts +36 -0
  39. package/lib/ml-core.js +29 -0
  40. package/lib/ml-dom/helper/get-indent.d.ts +4 -1
  41. package/lib/ml-dom/helper/get-indent.js +4 -1
  42. package/lib/ml-dom/node/attr.d.ts +65 -4
  43. package/lib/ml-dom/node/attr.js +53 -4
  44. package/lib/ml-dom/node/block.d.ts +21 -0
  45. package/lib/ml-dom/node/block.js +14 -0
  46. package/lib/ml-dom/node/child-node.d.ts +9 -0
  47. package/lib/ml-dom/node/child-node.js +9 -0
  48. package/lib/ml-dom/node/comment.d.ts +7 -0
  49. package/lib/ml-dom/node/comment.js +7 -0
  50. package/lib/ml-dom/node/document-fragment.d.ts +8 -0
  51. package/lib/ml-dom/node/document-fragment.js +8 -0
  52. package/lib/ml-dom/node/document-type.d.ts +22 -0
  53. package/lib/ml-dom/node/document-type.js +13 -0
  54. package/lib/ml-dom/node/document.d.ts +98 -4
  55. package/lib/ml-dom/node/document.js +87 -2
  56. package/lib/ml-dom/node/element.d.ts +164 -11
  57. package/lib/ml-dom/node/element.js +135 -6
  58. package/lib/ml-dom/node/node.d.ts +23 -0
  59. package/lib/ml-dom/node/node.js +29 -0
  60. package/lib/ml-dom/node/text.d.ts +12 -0
  61. package/lib/ml-dom/node/text.js +12 -0
  62. package/lib/ml-dom/node/types.d.ts +68 -0
  63. package/lib/ml-dom/token/token.d.ts +42 -0
  64. package/lib/ml-dom/token/token.js +36 -0
  65. package/lib/ml-rule/create-rule.d.ts +9 -0
  66. package/lib/ml-rule/create-rule.js +9 -0
  67. package/lib/ml-rule/ml-rule.d.ts +33 -0
  68. package/lib/ml-rule/ml-rule.js +30 -0
  69. package/lib/ml-rule/types.d.ts +41 -0
  70. package/lib/plugin/plugin.d.ts +8 -0
  71. package/lib/plugin/plugin.js +8 -0
  72. package/lib/plugin/types.d.ts +21 -0
  73. package/lib/ruleset/index.d.ts +10 -0
  74. package/lib/ruleset/index.js +7 -0
  75. package/lib/test/index.d.ts +42 -1
  76. package/lib/test/index.js +35 -1
  77. package/lib/types.d.ts +8 -0
  78. package/lib/violation-collector.d.ts +33 -0
  79. package/lib/violation-collector.js +33 -0
  80. package/package.json +14 -14
@@ -0,0 +1,303 @@
1
+ # リンティングパイプライン
2
+
3
+ `@markuplint/ml-core` の MLCore リンティングエンジンの詳細リファレンスです。
4
+
5
+ ## 概要
6
+
7
+ `MLCore` はパース、DOM 構築、ルール実行、違反収集を接続するオーケストレーションエンジンです。パイプラインのフロー:
8
+
9
+ ```
10
+ ソースコード → パーサー → MLASTDocument → MLDocument → ルール検証 → 違反
11
+ ```
12
+
13
+ ## MLCore クラス
14
+
15
+ ソース: `src/ml-core.ts`
16
+
17
+ ### コンストラクタ
18
+
19
+ ```typescript
20
+ constructor(params: MLCoreParams)
21
+ ```
22
+
23
+ `MLCoreParams` は `MLFabric` を以下で拡張します:
24
+
25
+ | パラメータ | 型 | 説明 |
26
+ | ------------ | --------- | ---------------------- |
27
+ | `sourceCode` | `string` | リントするソースコード |
28
+ | `filename` | `string` | ソースファイル名 |
29
+ | `debug` | `boolean` | デバッグログの有効化 |
30
+
31
+ ### MLFabric
32
+
33
+ `MLFabric` 型はリンティング設定全体を定義します:
34
+
35
+ | フィールド | 型 | 説明 |
36
+ | --------------- | --------------------------------- | ----------------------------------------------------- |
37
+ | `parser` | `MLParser` | パーサーインスタンス(例:`@markuplint/html-parser`) |
38
+ | `ruleset` | `Ruleset` | 解決済みルール設定 |
39
+ | `rules` | `readonly MLRule[]` | ルールインスタンスの配列 |
40
+ | `locale` | `LocaleSet` | 違反メッセージのロケール |
41
+ | `schemas` | `MLSchema` | HTML/ARIA 仕様タプル |
42
+ | `parserOptions` | `ParserOptions` | パーサー設定オプション |
43
+ | `severity` | `{ parseError?: SeverityOption }` | 重大度オーバーライド |
44
+ | `pretenders` | `readonly Pretender[]` | コンポーネントから HTML へのマッピング |
45
+ | `configErrors` | `readonly ConfigError[]` | 報告する設定エラー |
46
+
47
+ ### プロパティ
48
+
49
+ | プロパティ | 型 | 説明 |
50
+ | ---------- | --------------------------- | ------------------------------------------ |
51
+ | `document` | `MLDocument \| ParserError` | パースされたドキュメントまたはパースエラー |
52
+
53
+ ### 構築フロー
54
+
55
+ 1. `_parse()` — `parser.parse(sourceCode, parserOptions)` を呼び出して `MLASTDocument` を生成
56
+ 2. `_createDocument()` — AST を `MLDocument` でラップ(ruleset、schemas、オプション付き)
57
+
58
+ パースが失敗した場合、`document` は `MLDocument` の代わりに `ParserError` を保持します。
59
+
60
+ ## パースフェーズ
61
+
62
+ ### `_parse()`
63
+
64
+ `parser.parse(sourceCode, parserOptions)` を呼び出し、`MLASTDocument` を返します。
65
+
66
+ パーサーがスローした場合:
67
+
68
+ - エラーが `ParserError` としてキャッチされる
69
+ - `document` に `ParserError` オブジェクトが設定される
70
+ - `verify()` が後でこれを `Violation` に変換
71
+
72
+ ## ドキュメント作成フェーズ
73
+
74
+ ### `_createDocument()`
75
+
76
+ パースされた AST から `MLDocument` を作成します:
77
+
78
+ ```typescript
79
+ new Document(ast, ruleset, schemas, {
80
+ filename,
81
+ endTag,
82
+ booleanish,
83
+ tagNameCaseSensitive,
84
+ pretenders,
85
+ });
86
+ ```
87
+
88
+ 構築時に `MLDocument` は:
89
+
90
+ 1. AST を走査してフラットな `nodeList` を構築
91
+ 2. `RuleMapper` を初期化してルール設定を配布
92
+ 3. pretender 定義が存在する場合、pretender コンテキストをセットアップ
93
+
94
+ ## 検証フェーズ
95
+
96
+ ### `verify(fix?): Promise<Violation[]>`
97
+
98
+ メインのリンティングメソッド。違反の配列を返します。
99
+
100
+ **フロー:**
101
+
102
+ ```mermaid
103
+ flowchart TD
104
+ A["verify(fix?)"] --> B{パースエラー?}
105
+ B -->|はい| C["_createParseError()\n→ Violation"]
106
+ B -->|いいえ| D["未定義ルールチェック"]
107
+ D --> E["configErrors を報告"]
108
+ E --> F["各ルールに対して:"]
109
+ F --> G["getRuleInfo(ruleset, rule.name)"]
110
+ G --> H{無効かつ\nオーバーライドなし?}
111
+ H -->|はい| I["スキップ"]
112
+ H -->|いいえ| J["rule.verify(document, locale, fix)"]
113
+ J --> K{ParserError?}
114
+ K -->|はい| L["キャッチ → Violation"]
115
+ K -->|いいえ| M["違反を収集"]
116
+ M --> N["カウントをログ"]
117
+ N --> O["Violation[] を返す"]
118
+ C --> O
119
+ ```
120
+
121
+ ### ステップごとの説明
122
+
123
+ 1. **パースエラーチェック**: `document` が `ParserError` の場合、単一の違反を作成して返す
124
+ 2. **未定義ルールの検出**: `setRuleNames`(設定内のルール)と `definedRuleName`(実際にロードされたルール)を比較。未定義ルールに対して `config-error` 警告を報告
125
+ 3. **設定エラー**: `configErrors` 配列を違反に変換
126
+ 4. **ルールループ**: 各ルールに対して:
127
+ - `rule.getRuleInfo(ruleset, rule.name)` で有効性をチェック
128
+ - `disabled && nodeRules.length === 0 && childNodeRules.length === 0` → スキップ
129
+ - `rule.verify(document, locale, fix)` — ルールを実行
130
+ - 検証中にスローされた `ParserError` をキャッチ
131
+ 5. **結果ログ**: デバッグ経由で error/warning/info カウントをログ出力
132
+
133
+ ### パースエラーの重大度
134
+
135
+ `severity.parseError` が設定されている場合:
136
+
137
+ | 設定 | 動作 |
138
+ | ---------------------- | ------------------------------ |
139
+ | `false` または `'off'` | パースエラーを抑制(違反なし) |
140
+ | `true` または `null` | `'error'` 重大度として報告 |
141
+ | Severity 値 | その重大度で報告 |
142
+
143
+ ## 更新と再パース
144
+
145
+ ### `setCode(sourceCode)`
146
+
147
+ 新しいソースコードで再パース:
148
+
149
+ 1. 保存されたソースコードを更新
150
+ 2. `_parse()` を呼び出して新しい AST を生成
151
+ 3. `_createDocument()` を呼び出して MLDOM を再構築
152
+
153
+ ### `update(partial<MLFabric>)`
154
+
155
+ リンティング設定の部分更新:
156
+
157
+ - `parserOptions` が変更された場合 → 完全な再パース(`_parse()` + `_createDocument()`)
158
+ - それ以外 → `_createDocument()` のみ(既存の AST を再利用)
159
+
160
+ この最適化により、ルールや設定のみの変更時に不要な再パースを回避します。
161
+
162
+ ## ViolationCollector
163
+
164
+ ソース: `src/violation-collector.ts`
165
+
166
+ オプションの最大数制限付きで複数ファイルの違反を集約します。
167
+
168
+ ### コンストラクタ
169
+
170
+ ```typescript
171
+ constructor(maxCount?: number)
172
+ ```
173
+
174
+ ### メソッド
175
+
176
+ | メソッド | 戻り値 | 説明 |
177
+ | --------------------------------------- | -------------------------- | --------------------------------------- |
178
+ | `pushWithFile(filePath, ...violations)` | `void` | ファイルの違反を追加(maxCount を尊重) |
179
+ | `isLocked()` | `boolean` | maxCount に到達した場合 `true` |
180
+ | `toArray()` | `FileViolation[]` | すべての違反をフラット配列として返す |
181
+ | `groupByFile()` | `Map<string, Violation[]>` | ファイルパスでグループ化された違反 |
182
+
183
+ ### プロパティ
184
+
185
+ | プロパティ | 型 | 説明 |
186
+ | ---------- | -------- | ---------- |
187
+ | `length` | `number` | 違反の総数 |
188
+
189
+ ### maxCount の動作
190
+
191
+ `maxCount` が設定されている場合:
192
+
193
+ - `pushWithFile()` は `length >= maxCount` に到達すると違反の受け入れを停止
194
+ - `isLocked()` は制限到達後に `true` を返す
195
+ - 既に追加された違反は保持される
196
+
197
+ ## Pretender システム
198
+
199
+ ソース: `src/ml-dom/node/document.ts`、要素の pretending メソッド
200
+
201
+ ### Pretender 型
202
+
203
+ ```typescript
204
+ type Pretender = {
205
+ selector: string; // コンポーネントにマッチする CSS セレクタ
206
+ as: string; // 偽装する HTML 要素
207
+ aria?: PretenderARIA; // オプションの ARIA オーバーライド
208
+ };
209
+ ```
210
+
211
+ ### 動作の仕組み
212
+
213
+ 1. `MLDocument` の構築時に `_pretending()` が pretender 定義を処理
214
+ 2. pretender セレクタにマッチする各 `MLElement` が `element.pretending(pretenders)` を呼び出す
215
+ 3. マッチした要素が `PretenderContext` を取得:
216
+ - コンポーネント要素に `type: 'pretender'`
217
+ - 対象 HTML 要素参照に `type: 'origin'`
218
+ 4. ルールが `element.pretenderContext` にアクセスしてセマンティックマッピングを確認
219
+ 5. アクセシブル名の計算(`getAccname()`)がロール/名前の解決に pretender コンテキストを使用
220
+
221
+ ### PretenderContext
222
+
223
+ ```typescript
224
+ type PretenderContext =
225
+ | { type: 'pretender'; as: MLElement; aria?: PretenderARIA }
226
+ | { type: 'origin'; pretender: MLElement };
227
+ ```
228
+
229
+ ## プラグインシステム
230
+
231
+ ソース: `src/plugin/types.ts`, `src/plugin/plugin.ts`
232
+
233
+ ### Plugin 型
234
+
235
+ ```typescript
236
+ type Plugin = {
237
+ readonly name: string;
238
+ readonly rules?: Record<string, RuleSeed<any, any>>;
239
+ readonly configs?: Record<string, Config>;
240
+ };
241
+ ```
242
+
243
+ ### PluginCreator
244
+
245
+ 設定を受け付けるプラグイン用:
246
+
247
+ ```typescript
248
+ type PluginCreator<S> = {
249
+ readonly name: string;
250
+ create(setting: S): Omit<Plugin, 'name'>;
251
+ };
252
+ ```
253
+
254
+ ### createPlugin
255
+
256
+ ```typescript
257
+ function createPlugin<S>(creator: PluginCreator<S>): PluginCreator<S>;
258
+ ```
259
+
260
+ 型安全なプラグインクリエーター定義のためのファクトリ関数。クリエーターをそのまま返し、型ヘルパーとして機能します。
261
+
262
+ ### プラグインの利用
263
+
264
+ プラグインが提供するもの:
265
+
266
+ - **カスタムルール** — 名前で登録される追加のルールシード
267
+ - **共有設定** — 再利用可能な設定プリセット
268
+
269
+ ## MLSchema
270
+
271
+ ソース: `src/types.ts`
272
+
273
+ ```typescript
274
+ type MLSchema = [MLMLSpec, ...ExtendedSpec[]];
275
+ ```
276
+
277
+ タプル構造:
278
+
279
+ - 最初の要素: ベースの HTML/ARIA 仕様(`MLMLSpec`)
280
+ - 残り: 拡張仕様(例:フレームワーク固有の要素定義)
281
+
282
+ ### schemaToSpec()
283
+
284
+ スキーマタプルを単一の仕様オブジェクトに解決します。MLDOM が要素/属性の検証に使用します。
285
+
286
+ ## デバッグ
287
+
288
+ ソース: `src/debug.ts`
289
+
290
+ ### enableDebug()
291
+
292
+ ml-core パッケージと CLI のデバッグログを有効化します。
293
+
294
+ ### デバッグ名前空間
295
+
296
+ | 名前空間 | 説明 |
297
+ | ------------------------- | ---------------------- |
298
+ | `ml-core` | コアエンジンの操作 |
299
+ | `ml-core:ml-dom` | MLDOM ツリーの操作 |
300
+ | `ml-core:ml-dom:document` | ドキュメント構築の詳細 |
301
+ | `ml-core:rule-mapper` | ルールマッピングの操作 |
302
+
303
+ デバッグ出力は `debug` npm パッケージで制御されます。環境変数 `DEBUG=ml-core*` で有効化できます。
@@ -0,0 +1,303 @@
1
+ # Linting Pipeline
2
+
3
+ Detailed reference for the MLCore linting engine in `@markuplint/ml-core`.
4
+
5
+ ## Overview
6
+
7
+ `MLCore` is the orchestration engine that connects parsing, DOM construction, rule execution, and violation collection. The pipeline flows:
8
+
9
+ ```
10
+ Source Code → Parser → MLASTDocument → MLDocument → Rule Verification → Violations
11
+ ```
12
+
13
+ ## MLCore Class
14
+
15
+ Source: `src/ml-core.ts`
16
+
17
+ ### Constructor
18
+
19
+ ```typescript
20
+ constructor(params: MLCoreParams)
21
+ ```
22
+
23
+ Where `MLCoreParams` extends `MLFabric` with:
24
+
25
+ | Parameter | Type | Description |
26
+ | ------------ | --------- | ----------------------- |
27
+ | `sourceCode` | `string` | The source code to lint |
28
+ | `filename` | `string` | Source filename |
29
+ | `debug` | `boolean` | Enable debug logging |
30
+
31
+ ### MLFabric
32
+
33
+ The `MLFabric` type defines the full linting configuration:
34
+
35
+ | Field | Type | Description |
36
+ | --------------- | --------------------------------- | ------------------------------------------------- |
37
+ | `parser` | `MLParser` | Parser instance (e.g., `@markuplint/html-parser`) |
38
+ | `ruleset` | `Ruleset` | Resolved rule configuration |
39
+ | `rules` | `readonly MLRule[]` | Array of rule instances |
40
+ | `locale` | `LocaleSet` | Locale for violation messages |
41
+ | `schemas` | `MLSchema` | HTML/ARIA specification tuple |
42
+ | `parserOptions` | `ParserOptions` | Parser configuration options |
43
+ | `severity` | `{ parseError?: SeverityOption }` | Severity overrides |
44
+ | `pretenders` | `readonly Pretender[]` | Component-to-HTML mappings |
45
+ | `configErrors` | `readonly ConfigError[]` | Configuration errors to report |
46
+
47
+ ### Properties
48
+
49
+ | Property | Type | Description |
50
+ | ---------- | --------------------------- | ------------------------------ |
51
+ | `document` | `MLDocument \| ParserError` | Parsed document or parse error |
52
+
53
+ ### Construction Flow
54
+
55
+ 1. `_parse()` — Invokes `parser.parse(sourceCode, parserOptions)` to produce `MLASTDocument`
56
+ 2. `_createDocument()` — Wraps AST in `MLDocument` with ruleset, schemas, and options
57
+
58
+ If parsing fails, `document` holds a `ParserError` instead of `MLDocument`.
59
+
60
+ ## Parse Phase
61
+
62
+ ### `_parse()`
63
+
64
+ Calls `parser.parse(sourceCode, parserOptions)` which returns an `MLASTDocument`.
65
+
66
+ If the parser throws:
67
+
68
+ - The error is caught as a `ParserError`
69
+ - `document` is set to the `ParserError` object
70
+ - `verify()` will later convert this to a `Violation`
71
+
72
+ ## Document Creation Phase
73
+
74
+ ### `_createDocument()`
75
+
76
+ Creates `MLDocument` from the parsed AST:
77
+
78
+ ```typescript
79
+ new Document(ast, ruleset, schemas, {
80
+ filename,
81
+ endTag,
82
+ booleanish,
83
+ tagNameCaseSensitive,
84
+ pretenders,
85
+ });
86
+ ```
87
+
88
+ During construction, `MLDocument`:
89
+
90
+ 1. Builds the flat `nodeList` by traversing the AST
91
+ 2. Initializes `RuleMapper` to distribute rule configuration
92
+ 3. Sets up pretender contexts when pretender definitions exist
93
+
94
+ ## Verification Phase
95
+
96
+ ### `verify(fix?): Promise<Violation[]>`
97
+
98
+ The main linting method. Returns an array of violations.
99
+
100
+ **Flow:**
101
+
102
+ ```mermaid
103
+ flowchart TD
104
+ A["verify(fix?)"] --> B{Parse error?}
105
+ B -->|Yes| C["_createParseError()\n→ Violation"]
106
+ B -->|No| D["Check undefined rules"]
107
+ D --> E["Report configErrors"]
108
+ E --> F["For each rule:"]
109
+ F --> G["getRuleInfo(ruleset, rule.name)"]
110
+ G --> H{Disabled and\nno overrides?}
111
+ H -->|Yes| I["Skip"]
112
+ H -->|No| J["rule.verify(document, locale, fix)"]
113
+ J --> K{ParserError?}
114
+ K -->|Yes| L["Catch → Violation"]
115
+ K -->|No| M["Collect violations"]
116
+ M --> N["Log counts"]
117
+ N --> O["Return Violation[]"]
118
+ C --> O
119
+ ```
120
+
121
+ ### Step-by-step
122
+
123
+ 1. **Parse error check**: If `document` is a `ParserError`, creates a single violation and returns
124
+ 2. **Undefined rule detection**: Compares `setRuleNames` (rules in config) vs `definedRuleName` (rules actually loaded). Reports `config-error` warnings for undefined rules
125
+ 3. **Config errors**: Converts `configErrors` array to violations
126
+ 4. **Rule loop**: For each rule:
127
+ - `rule.getRuleInfo(ruleset, rule.name)` checks enablement
128
+ - If `disabled && nodeRules.length === 0 && childNodeRules.length === 0` → skip
129
+ - `rule.verify(document, locale, fix)` — executes the rule
130
+ - Catches `ParserError` if thrown during verification
131
+ 5. **Result logging**: Logs error/warning/info counts via debug
132
+
133
+ ### Parse Error Violation
134
+
135
+ When `severity.parseError` is configured:
136
+
137
+ | Setting | Behavior |
138
+ | ------------------ | ------------------------------------- |
139
+ | `false` or `'off'` | Parse error suppressed (no violation) |
140
+ | `true` or `null` | Reported as `'error'` severity |
141
+ | Severity value | Reported with that severity |
142
+
143
+ ## Update and Re-parse
144
+
145
+ ### `setCode(sourceCode)`
146
+
147
+ Re-parses with new source code:
148
+
149
+ 1. Updates stored source code
150
+ 2. Calls `_parse()` to produce new AST
151
+ 3. Calls `_createDocument()` to rebuild MLDOM
152
+
153
+ ### `update(partial<MLFabric>)`
154
+
155
+ Partially updates the linting configuration:
156
+
157
+ - If `parserOptions` changed → full re-parse (`_parse()` + `_createDocument()`)
158
+ - Otherwise → only `_createDocument()` (reuses existing AST)
159
+
160
+ This optimization avoids unnecessary re-parsing when only rules or config change.
161
+
162
+ ## ViolationCollector
163
+
164
+ Source: `src/violation-collector.ts`
165
+
166
+ Aggregates violations across multiple files with an optional maximum count.
167
+
168
+ ### Constructor
169
+
170
+ ```typescript
171
+ constructor(maxCount?: number)
172
+ ```
173
+
174
+ ### Methods
175
+
176
+ | Method | Returns | Description |
177
+ | --------------------------------------- | -------------------------- | --------------------------------------------- |
178
+ | `pushWithFile(filePath, ...violations)` | `void` | Add violations for a file (respects maxCount) |
179
+ | `isLocked()` | `boolean` | `true` if maxCount reached |
180
+ | `toArray()` | `FileViolation[]` | All violations as flat array |
181
+ | `groupByFile()` | `Map<string, Violation[]>` | Violations grouped by file path |
182
+
183
+ ### Properties
184
+
185
+ | Property | Type | Description |
186
+ | -------- | -------- | --------------------- |
187
+ | `length` | `number` | Total violation count |
188
+
189
+ ### maxCount Behavior
190
+
191
+ When `maxCount` is set:
192
+
193
+ - `pushWithFile()` stops accepting violations once `length >= maxCount`
194
+ - `isLocked()` returns `true` after reaching the limit
195
+ - Already-added violations are preserved
196
+
197
+ ## Pretender System
198
+
199
+ Source: `src/ml-dom/node/document.ts`, element pretending methods
200
+
201
+ ### Pretender Type
202
+
203
+ ```typescript
204
+ type Pretender = {
205
+ selector: string; // CSS selector matching the component
206
+ as: string; // HTML element to pretend as
207
+ aria?: PretenderARIA; // Optional ARIA overrides
208
+ };
209
+ ```
210
+
211
+ ### How It Works
212
+
213
+ 1. During `MLDocument` construction, `_pretending()` processes pretender definitions
214
+ 2. Each `MLElement` matching a pretender selector calls `element.pretending(pretenders)`
215
+ 3. Matched elements get a `PretenderContext`:
216
+ - `type: 'pretender'` on the component element
217
+ - `type: 'origin'` on the target HTML element reference
218
+ 4. Rules access `element.pretenderContext` to check semantic mappings
219
+ 5. Accessible name computation (`getAccname()`) uses pretender context for role/name resolution
220
+
221
+ ### PretenderContext
222
+
223
+ ```typescript
224
+ type PretenderContext =
225
+ | { type: 'pretender'; as: MLElement; aria?: PretenderARIA }
226
+ | { type: 'origin'; pretender: MLElement };
227
+ ```
228
+
229
+ ## Plugin System
230
+
231
+ Source: `src/plugin/types.ts`, `src/plugin/plugin.ts`
232
+
233
+ ### Plugin Type
234
+
235
+ ```typescript
236
+ type Plugin = {
237
+ readonly name: string;
238
+ readonly rules?: Record<string, RuleSeed<any, any>>;
239
+ readonly configs?: Record<string, Config>;
240
+ };
241
+ ```
242
+
243
+ ### PluginCreator
244
+
245
+ For plugins that accept settings:
246
+
247
+ ```typescript
248
+ type PluginCreator<S> = {
249
+ readonly name: string;
250
+ create(setting: S): Omit<Plugin, 'name'>;
251
+ };
252
+ ```
253
+
254
+ ### createPlugin
255
+
256
+ ```typescript
257
+ function createPlugin<S>(creator: PluginCreator<S>): PluginCreator<S>;
258
+ ```
259
+
260
+ Factory function for type-safe plugin creator definitions. Returns the creator as-is, serving as a type helper.
261
+
262
+ ### Plugin Usage
263
+
264
+ Plugins provide:
265
+
266
+ - **Custom rules** — Additional rule seeds registered by name
267
+ - **Shared configurations** — Reusable config presets
268
+
269
+ ## MLSchema
270
+
271
+ Source: `src/types.ts`
272
+
273
+ ```typescript
274
+ type MLSchema = [MLMLSpec, ...ExtendedSpec[]];
275
+ ```
276
+
277
+ A tuple where:
278
+
279
+ - First element: The base HTML/ARIA specification (`MLMLSpec`)
280
+ - Rest: Extended specifications (e.g., framework-specific element definitions)
281
+
282
+ ### schemaToSpec()
283
+
284
+ Resolves the schema tuple into a single spec object used by MLDOM for element/attribute validation.
285
+
286
+ ## Debug
287
+
288
+ Source: `src/debug.ts`
289
+
290
+ ### enableDebug()
291
+
292
+ Enables debug logging for the ml-core package and CLI.
293
+
294
+ ### Debug Namespaces
295
+
296
+ | Namespace | Description |
297
+ | ------------------------- | ----------------------------- |
298
+ | `ml-core` | Core engine operations |
299
+ | `ml-core:ml-dom` | MLDOM tree operations |
300
+ | `ml-core:ml-dom:document` | Document construction details |
301
+ | `ml-core:rule-mapper` | Rule mapping operations |
302
+
303
+ Debug output is controlled via the `debug` npm package. Enable with `DEBUG=ml-core*` environment variable.