agent-docs 1.3.0 → 1.4.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.
package/docs/PMD.md CHANGED
@@ -4,13 +4,17 @@
4
4
 
5
5
  PMD guide or Salesforce Code Analyzer integration.
6
6
 
7
- **Refs:** [PMD Engine](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/engine-pmd.html) | [Schema](https://pmd.sourceforge.io/ruleset_2_0_0.xsd) | [Apex Docs](https://pmd.github.io/pmd/pmd_languages_apex.html)
7
+ **Refs:**
8
+ [PMD Engine](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/engine-pmd.html)
9
+ | [Schema](https://pmd.sourceforge.io/ruleset_2_0_0.xsd) |
10
+ [Apex Docs](https://pmd.github.io/pmd/pmd_languages_apex.html)
8
11
 
9
12
  **Related:** [Code Analyzer Config](CODEANALYZER.md) | [XPath 3.1](XPATH31.md)
10
13
 
11
14
  ## Installation
12
15
 
13
- Download from [GitHub releases](https://github.com/pmd/pmd/releases), add `bin/` to PATH. Code Analyzer bundles PMD—direct install only for standalone CLI.
16
+ Download from [GitHub releases](https://github.com/pmd/pmd/releases), add `bin/`
17
+ to PATH. Code Analyzer bundles PMD—direct install only for standalone CLI.
14
18
 
15
19
  ## Rulesets
16
20
 
@@ -18,9 +22,9 @@ XML defining rules. Reference in `code-analyzer.yml`:
18
22
 
19
23
  ```yaml
20
24
  engines:
21
- pmd:
22
- rulesets:
23
- - rulesets/design/InnerClassesCannotBeStatic.xml
25
+ pmd:
26
+ rulesets:
27
+ - rulesets/design/InnerClassesCannotBeStatic.xml
24
28
  ```
25
29
 
26
30
  ### Structure
@@ -38,7 +42,8 @@ engines:
38
42
  </ruleset>
39
43
  ```
40
44
 
41
- **Elements:** `description` (required), `exclude-pattern`*, `include-pattern`*, `rule`+
45
+ **Elements:** `description` (required), `exclude-pattern`_, `include-pattern`_,
46
+ `rule`+
42
47
 
43
48
  ### Referencing Rules
44
49
 
@@ -66,9 +71,11 @@ engines:
66
71
 
67
72
  ### Properties
68
73
 
69
- **Attrs:** `name` (required), `value`, `description`, `type`, `delimiter`, `min`, `max`
74
+ **Attrs:** `name` (required), `value`, `description`, `type`, `delimiter`,
75
+ `min`, `max`
70
76
 
71
- **Important:** Code Analyzer only supports `severity`/`tags` in `code-analyzer.yml`. Property overrides require ruleset XML.
77
+ **Important:** Code Analyzer only supports `severity`/`tags` in
78
+ `code-analyzer.yml`. Property overrides require ruleset XML.
72
79
 
73
80
  ```xml
74
81
  <!-- Child element (recommended) -->
@@ -95,10 +102,10 @@ engines:
95
102
 
96
103
  ```yaml
97
104
  rules:
98
- pmd:
99
- NPathComplexity:
100
- severity: 'High'
101
- tags: ['Recommended']
105
+ pmd:
106
+ NPathComplexity:
107
+ severity: 'High'
108
+ tags: ['Recommended']
102
109
  ```
103
110
 
104
111
  **Ref format:** `{ruleset-path}/{rule-name}`
@@ -111,9 +118,12 @@ if ('${prop}' = '${prop}') then 'default' else '${prop}'
111
118
 
112
119
  ### Rule Element
113
120
 
114
- **Child order:** `description` → `priority` → `properties` → `exclude` → `example`
121
+ **Child order:** `description` → `priority` → `properties` → `exclude` →
122
+ `example`
115
123
 
116
- **Attrs:** `name`, `language`, `minimumLanguageVersion`, `maximumLanguageVersion`, `ref`, `message`, `class`, `since`, `externalInfoUrl`, `deprecated`, `dfa`, `typeResolution`
124
+ **Attrs:** `name`, `language`, `minimumLanguageVersion`,
125
+ `maximumLanguageVersion`, `ref`, `message`, `class`, `since`, `externalInfoUrl`,
126
+ `deprecated`, `dfa`, `typeResolution`
117
127
 
118
128
  ```xml
119
129
  <rule name="MyRule" language="apex" message="Custom message">
@@ -170,9 +180,12 @@ Must be on same line. Custom marker: `--suppress-marker "CUSTOM"`
170
180
  ```
171
181
 
172
182
  XPath examples:
183
+
173
184
  - `.[pmd-apex:typeIs('String')]` — String type
174
- - `./ancestor-or-self::MethodDeclaration[@Name = ('equals', 'hashCode')]` — specific methods
175
- - `./ancestor-or-self::ClassDeclaration[matches(@SimpleName, '^.*Bean$')]` — regex match
185
+ - `./ancestor-or-self::MethodDeclaration[@Name = ('equals', 'hashCode')]` —
186
+ specific methods
187
+ - `./ancestor-or-self::ClassDeclaration[matches(@SimpleName, '^.*Bean$')]` —
188
+ regex match
176
189
 
177
190
  ## CLI
178
191
 
@@ -180,20 +193,21 @@ XPath examples:
180
193
  pmd check -d <source> -R <ruleset> -f <format>
181
194
  ```
182
195
 
183
- | Option | Description |
184
- |--------|-------------|
185
- | `-d`, `--dir` | Source directory |
186
- | `-R`, `--rulesets` | Ruleset file |
187
- | `-f`, `--format` | Report format |
188
- | `--minimum-priority` | 1-5 or High/Medium/Low |
189
- | `-l`, `--language` | apex, java, etc. |
190
- | `--use-version` | Language version |
191
- | `--fail-on-violation` | Exit error on violations |
192
- | `--cache` / `--no-cache` | Cache control |
196
+ | Option | Description |
197
+ | ------------------------ | ------------------------ |
198
+ | `-d`, `--dir` | Source directory |
199
+ | `-R`, `--rulesets` | Ruleset file |
200
+ | `-f`, `--format` | Report format |
201
+ | `--minimum-priority` | 1-5 or High/Medium/Low |
202
+ | `-l`, `--language` | apex, java, etc. |
203
+ | `--use-version` | Language version |
204
+ | `--fail-on-violation` | Exit error on violations |
205
+ | `--cache` / `--no-cache` | Cache control |
193
206
 
194
207
  **PMD 6→7:** `-no-cache`→`--no-cache`, `-failOnViolation`→`--fail-on-violation`
195
208
 
196
- **Formats:** `text`, `xml`, `html`, `csv`, `json`, `sarif`, `codeclimate`, `junit`
209
+ **Formats:** `text`, `xml`, `html`, `csv`, `json`, `sarif`, `codeclimate`,
210
+ `junit`
197
211
 
198
212
  ### CPD (Copy-Paste Detector)
199
213
 
@@ -208,135 +222,145 @@ pmd cpd --minimum-tokens 100 --language apex --files src/
208
222
  ```yaml
209
223
  - uses: pmd/pmd-github-action@v2
210
224
  with:
211
- rulesets: 'rulesets/all.xml'
212
- version: 'latest'
213
- sourcePath: '.'
214
- analyzeModifiedFilesOnly: 'true'
225
+ rulesets: 'rulesets/all.xml'
226
+ version: 'latest'
227
+ sourcePath: '.'
228
+ analyzeModifiedFilesOnly: 'true'
215
229
  ```
216
230
 
217
- **Output:** `violations` count. **Limits:** XPath rules only, max 300 files with `analyzeModifiedFilesOnly`
231
+ **Output:** `violations` count. **Limits:** XPath rules only, max 300 files with
232
+ `analyzeModifiedFilesOnly`
218
233
 
219
234
  ## Apex AST Reference (PMD 7+)
220
235
 
221
- Summit AST parser. **Removed from PMD 6:** `Method/@Synthetic`, `Method/@Namespace`, `ReferenceExpression/@Context`, `BridgeMethodCreator`, `<clinit>`/`<init>` methods.
236
+ Summit AST parser. **Removed from PMD 6:** `Method/@Synthetic`,
237
+ `Method/@Namespace`, `ReferenceExpression/@Context`, `BridgeMethodCreator`,
238
+ `<clinit>`/`<init>` methods.
222
239
 
223
240
  ### Key Rules
224
241
 
225
242
  1. **Annotations:** Path `*/ModifierNode/Annotation[@Name]` (not `*/Annotation`)
226
243
  2. **Comments:** Only block comments (`/* */`) in AST; use regex for `//`
227
- 3. **Field groups:** Multiple decls share parent `FieldDeclarationStatements/@Type`
244
+ 3. **Field groups:** Multiple decls share parent
245
+ `FieldDeclarationStatements/@Type`
228
246
  4. **Init blocks:** `Method[Identifier='_init']`
229
247
  5. **Local vars:** `[ancestor::Method]` to filter
230
- 6. **Safe nav `?.`:** `@isSafe=true` on `MethodCallExpression`/`ReferenceExpression`
248
+ 6. **Safe nav `?.`:** `@isSafe=true` on
249
+ `MethodCallExpression`/`ReferenceExpression`
231
250
  7. **Switch:** `WhenValue` (values), `WhenType` (SObject), `WhenElse` (default)
232
251
  8. **Location:** Lines 1-based, columns 0-based, end exclusive
233
252
 
234
253
  ### Attributes
235
254
 
236
- | Category | Attributes |
237
- |----------|------------|
238
- | Names | `@Image`, `@Name`, `@SimpleName`, `@MethodName`, `@FullMethodName`, `@VariableName` |
239
- | Location | `@BeginLine`, `@EndLine` (1-based), `@BeginColumn`, `@EndColumn` (0-based, excl) |
240
- | Operators | `@Op` (`+`,`-`,`==`,`!=`,`++`,`--`,`+=`,`&&`,`\|\|`,`??`, etc.) |
241
- | Types | `@Type`, `@ReturnType`, `@LiteralType` |
255
+ | Category | Attributes |
256
+ | --------- | ------------------------------------------------------------------------------------------------------------ |
257
+ | Names | `@Image`, `@Name`, `@SimpleName`, `@MethodName`, `@FullMethodName`, `@VariableName` |
258
+ | Location | `@BeginLine`, `@EndLine` (1-based), `@BeginColumn`, `@EndColumn` (0-based, excl) |
259
+ | Operators | `@Op` (`+`,`-`,`==`,`!=`,`++`,`--`,`+=`,`&&`,`\|\|`,`??`, etc.) |
260
+ | Types | `@Type`, `@ReturnType`, `@LiteralType` |
242
261
  | Modifiers | `@Static`, `@Final`, `@Abstract`, `@Public`, `@Private`, `@Protected`, `@Override`, `@Global`, `@WebService` |
243
- | Flags | `@Constructor`, `@Interface`, `@Nested`, `@Null`, `@String`, `@Boolean`, `@isSafe` |
244
- | Counts | `@InputParametersSize` |
262
+ | Flags | `@Constructor`, `@Interface`, `@Nested`, `@Null`, `@String`, `@Boolean`, `@isSafe` |
263
+ | Counts | `@InputParametersSize` |
245
264
 
246
265
  ### Node Reference
247
266
 
248
267
  #### Root
249
268
 
250
- - **ApexFile/CompilationUnit** — Root. Child: `UserClass`/`UserInterface`/`UserEnum`
269
+ - **ApexFile/CompilationUnit** — Root. Child:
270
+ `UserClass`/`UserInterface`/`UserEnum`
251
271
 
252
272
  #### Declarations
253
273
 
254
- | Node | Key Attrs | Notes |
255
- |------|-----------|-------|
256
- | `Annotation` | `@Name` | Children: `Identifier`, `AnnotationParameter`* |
257
- | `AnnotationParameter` | `@Name`, `@Value` | |
258
- | `EnumValue` | `@Name` | |
259
- | `FieldDeclaration` | `@Name` | Init expr optional |
260
- | `FieldDeclarationStatements` | `@Type` | Children: `ModifierNode`, `TypeRef`, `FieldDeclaration`+ |
261
- | `Method` | `@MethodName`, `@FullMethodName`, `@Constructor`, `@InputParametersSize`, `@ReturnType` | |
262
- | `Parameter` | `@Name`, `@Type` | |
263
- | `Property` | `@Name`, `@Type` | Getter/setter methods |
264
- | `TriggerDeclaration` | `@Name` | Cases: `TRIGGER_{BEFORE\|AFTER}_{INSERT\|UPDATE\|DELETE\|UNDELETE}` |
265
- | `UserClass` | `@Name`, `@Abstract`, `@Nested` | |
266
- | `UserEnum` | `@Name` | Children: `EnumValue`+ |
267
- | `UserInterface` | `@Name`, `@Interface=true` | |
268
- | `VariableDeclaration` | `@Name` | Init expr optional |
269
- | `VariableDeclarationStatements` | `@Type` | Children: `ModifierNode`, `TypeRef`, `VariableDeclaration`+ |
274
+ | Node | Key Attrs | Notes |
275
+ | ------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
276
+ | `Annotation` | `@Name` | Children: `Identifier`, `AnnotationParameter`\* |
277
+ | `AnnotationParameter` | `@Name`, `@Value` | |
278
+ | `EnumValue` | `@Name` | |
279
+ | `FieldDeclaration` | `@Name` | Init expr optional |
280
+ | `FieldDeclarationStatements` | `@Type` | Children: `ModifierNode`, `TypeRef`, `FieldDeclaration`+ |
281
+ | `Method` | `@MethodName`, `@FullMethodName`, `@Constructor`, `@InputParametersSize`, `@ReturnType` | |
282
+ | `Parameter` | `@Name`, `@Type` | |
283
+ | `Property` | `@Name`, `@Type` | Getter/setter methods |
284
+ | `TriggerDeclaration` | `@Name` | Cases: `TRIGGER_{BEFORE\|AFTER}_{INSERT\|UPDATE\|DELETE\|UNDELETE}` |
285
+ | `UserClass` | `@Name`, `@Abstract`, `@Nested` | |
286
+ | `UserEnum` | `@Name` | Children: `EnumValue`+ |
287
+ | `UserInterface` | `@Name`, `@Interface=true` | |
288
+ | `VariableDeclaration` | `@Name` | Init expr optional |
289
+ | `VariableDeclarationStatements` | `@Type` | Children: `ModifierNode`, `TypeRef`, `VariableDeclaration`+ |
270
290
 
271
291
  #### Expressions
272
292
 
273
- | Node | Key Attrs | Notes |
274
- |------|-----------|-------|
275
- | `ArrayLoadExpression` | | array, index |
276
- | `AssignmentExpression` | `@Op` (`=`,`+=`,`-=`...) | target, source |
277
- | `BinaryExpression` | `@Op` | `+`,`-`,`*`,`/`,`==`,`!=`,`<`,`<=`,`>`,`>=`,`&&`,`\|\|`,`and`,`or`,`??`,`===`,`!==`,`instanceof`,`&`,`\|`,`^`,`<<`,`>>`,`>>>` |
278
- | `BooleanExpression` | `@Op` | |
279
- | `CastExpression` | | expr, `TypeRef` |
280
- | `InstanceOfExpression` | | expr, `TypeRef` |
281
- | `LiteralExpression` | `@Image`, `@LiteralType`, `@Null`, `@String`, `@Boolean` | Leaf |
282
- | `MapEntryNode` | | key, value |
283
- | `MethodCallExpression` | `@MethodName`, `@FullMethodName`, `@InputParametersSize`, `@isSafe` | `@FullMethodName`: e.g. `'String.join'` |
284
- | `NewObjectExpression` | | `Initializer` |
285
- | `PostfixExpression` | `@Op` (`++`,`--`) | |
286
- | `PrefixExpression` | `@Op` (`++`,`--`) | |
287
- | `ReferenceExpression` | `@Image`, `@isSafe` | |
288
- | `SoqlExpression` | | `SoqlOrSoslBinding`* |
289
- | `SoslExpression` | | `SoqlOrSoslBinding`* |
290
- | `SuperExpression` | | Leaf |
291
- | `TernaryExpression` | | condition, then, else |
292
- | `ThisVariableExpression` | | Leaf |
293
- | `UnaryExpression` | `@Op` (`+`,`-`,`!`,`not`,`~`,`++`,`--`) | |
294
- | `VariableExpression` | `@Image` | |
293
+ | Node | Key Attrs | Notes |
294
+ | ------------------------ | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
295
+ | `ArrayLoadExpression` | | array, index |
296
+ | `AssignmentExpression` | `@Op` (`=`,`+=`,`-=`...) | target, source |
297
+ | `BinaryExpression` | `@Op` | `+`,`-`,`*`,`/`,`==`,`!=`,`<`,`<=`,`>`,`>=`,`&&`,`\|\|`,`and`,`or`,`??`,`===`,`!==`,`instanceof`,`&`,`\|`,`^`,`<<`,`>>`,`>>>` |
298
+ | `BooleanExpression` | `@Op` | |
299
+ | `CastExpression` | | expr, `TypeRef` |
300
+ | `InstanceOfExpression` | | expr, `TypeRef` |
301
+ | `LiteralExpression` | `@Image`, `@LiteralType`, `@Null`, `@String`, `@Boolean` | Leaf |
302
+ | `MapEntryNode` | | key, value |
303
+ | `MethodCallExpression` | `@MethodName`, `@FullMethodName`, `@InputParametersSize`, `@isSafe` | `@FullMethodName`: e.g. `'String.join'` |
304
+ | `NewObjectExpression` | | `Initializer` |
305
+ | `PostfixExpression` | `@Op` (`++`,`--`) | |
306
+ | `PrefixExpression` | `@Op` (`++`,`--`) | |
307
+ | `ReferenceExpression` | `@Image`, `@isSafe` | |
308
+ | `SoqlExpression` | | `SoqlOrSoslBinding`\* |
309
+ | `SoslExpression` | | `SoqlOrSoslBinding`\* |
310
+ | `SuperExpression` | | Leaf |
311
+ | `TernaryExpression` | | condition, then, else |
312
+ | `ThisVariableExpression` | | Leaf |
313
+ | `UnaryExpression` | `@Op` (`+`,`-`,`!`,`not`,`~`,`++`,`--`) | |
314
+ | `VariableExpression` | `@Image` | |
295
315
 
296
316
  #### Initializers
297
317
 
298
- | Node | Use |
299
- |------|-----|
300
- | `ConstructorInitializer` | `new Type(args)` |
301
- | `ValuesInitializer` | `new List<T>{...}`, `new Set<T>{...}` |
302
- | `MapInitializer` | `new Map<K,V>{'k'=>'v'}` |
303
- | `SizedArrayInitializer` | `new T[size]` |
318
+ | Node | Use |
319
+ | ------------------------ | ------------------------------------- |
320
+ | `ConstructorInitializer` | `new Type(args)` |
321
+ | `ValuesInitializer` | `new List<T>{...}`, `new Set<T>{...}` |
322
+ | `MapInitializer` | `new Map<K,V>{'k'=>'v'}` |
323
+ | `SizedArrayInitializer` | `new T[size]` |
304
324
 
305
325
  #### Modifiers
306
326
 
307
327
  - **ModifierNode** — Container
308
- - **KeywordModifier** — `ABSTRACT`, `FINAL`, `GLOBAL`, `STATIC`, `PUBLIC`, `PRIVATE`, `PROTECTED`, `OVERRIDE`, `TESTMETHOD`, `TRANSIENT`, `VIRTUAL`, `WEBSERVICE`, `WITHSHARING`, `WITHOUTSHARING`, `INHERITEDSHARING`
328
+ - **KeywordModifier** — `ABSTRACT`, `FINAL`, `GLOBAL`, `STATIC`, `PUBLIC`,
329
+ `PRIVATE`, `PROTECTED`, `OVERRIDE`, `TESTMETHOD`, `TRANSIENT`, `VIRTUAL`,
330
+ `WEBSERVICE`, `WITHSHARING`, `WITHOUTSHARING`, `INHERITEDSHARING`
309
331
 
310
332
  #### Statements
311
333
 
312
- | Node | Notes |
313
- |------|-------|
314
- | `BlockStatement`/`CompoundStatement` | Scoping: `SCOPE_BOUNDARY`/`SCOPE_TRANSPARENT` |
315
- | `BreakStatement`, `ContinueStatement`, `EmptyStatement` | Leaf |
316
- | `CatchBlockStatement` | `VariableDeclarationStatements`, body |
317
- | `DoLoopStatement` | condition, body |
318
- | `ExpressionStatement` | expr |
319
- | `ForEachStatement` | `VariableDeclarationStatements`, collection, body |
320
- | `ForLoopStatement` | init, condition, updates, body |
321
- | `IfBlockStatement` | condition, then, else? |
322
- | `IfElseBlockStatement` | `IfBlockStatement`+ |
323
- | `ReturnStatement` | expr? |
324
- | `RunAsStatement` | user exprs, body |
325
- | `SwitchStatement` | condition, `WhenValue`*/`WhenType`*/`WhenElse`? |
326
- | `ThrowStatement` | expr |
327
- | `TryStatement` | body, `CatchBlockStatement`*, finally? |
328
- | `WhileLoopStatement` | condition, body |
329
-
330
- **DML** (`@AccessLevel`: `USER_MODE`/`SYSTEM_MODE`): `DmlInsertStatement`, `DmlUpdateStatement`, `DmlDeleteStatement`, `DmlUndeleteStatement`, `DmlUpsertStatement`, `DmlMergeStatement`
334
+ | Node | Notes |
335
+ | ------------------------------------------------------- | ------------------------------------------------- |
336
+ | `BlockStatement`/`CompoundStatement` | Scoping: `SCOPE_BOUNDARY`/`SCOPE_TRANSPARENT` |
337
+ | `BreakStatement`, `ContinueStatement`, `EmptyStatement` | Leaf |
338
+ | `CatchBlockStatement` | `VariableDeclarationStatements`, body |
339
+ | `DoLoopStatement` | condition, body |
340
+ | `ExpressionStatement` | expr |
341
+ | `ForEachStatement` | `VariableDeclarationStatements`, collection, body |
342
+ | `ForLoopStatement` | init, condition, updates, body |
343
+ | `IfBlockStatement` | condition, then, else? |
344
+ | `IfElseBlockStatement` | `IfBlockStatement`+ |
345
+ | `ReturnStatement` | expr? |
346
+ | `RunAsStatement` | user exprs, body |
347
+ | `SwitchStatement` | condition, `WhenValue`_/`WhenType`_/`WhenElse`? |
348
+ | `ThrowStatement` | expr |
349
+ | `TryStatement` | body, `CatchBlockStatement`\*, finally? |
350
+ | `WhileLoopStatement` | condition, body |
351
+
352
+ **DML** (`@AccessLevel`: `USER_MODE`/`SYSTEM_MODE`): `DmlInsertStatement`,
353
+ `DmlUpdateStatement`, `DmlDeleteStatement`, `DmlUndeleteStatement`,
354
+ `DmlUpsertStatement`, `DmlMergeStatement`
331
355
 
332
356
  #### Other
333
357
 
334
- | Node | Notes |
335
- |------|-------|
336
- | `FormalComment` | Block comments only (`/* */`, `/** */`). `//` NOT in AST |
337
- | `Identifier` | `@Image`; may be synthetic (`'_init'`) |
338
- | `TypeRef` | `components`, `arrayNesting`; void=empty |
339
- | `StandardCondition` | Condition wrapper for if/while/for |
358
+ | Node | Notes |
359
+ | ------------------- | -------------------------------------------------------- |
360
+ | `FormalComment` | Block comments only (`/* */`, `/** */`). `//` NOT in AST |
361
+ | `Identifier` | `@Image`; may be synthetic (`'_init'`) |
362
+ | `TypeRef` | `components`, `arrayNesting`; void=empty |
363
+ | `StandardCondition` | Condition wrapper for if/while/for |
340
364
 
341
365
  ### XPath Patterns
342
366
 
@@ -402,11 +426,13 @@ int cyclo = MetricsUtil.computeMetric(ApexMetrics.CYCLO, node);
402
426
 
403
427
  ## Rule Categories
404
428
 
405
- Best Practices | Code Style | Design | Documentation | Error Prone | Multithreading | Performance | Security
429
+ Best Practices | Code Style | Design | Documentation | Error Prone |
430
+ Multithreading | Performance | Security
406
431
 
407
432
  ## Code Analyzer Config
408
433
 
409
434
  `code-analyzer.yml`:
435
+
410
436
  - `engines.pmd.rulesets` — Ruleset paths
411
437
  - `rules.pmd.{Rule}.severity` — High/Medium/Low
412
438
  - `rules.pmd.{Rule}.tags` — Tag array
package/docs/XPATH31.md CHANGED
@@ -75,6 +75,7 @@ map { 'k': v } # Constructor
75
75
  $m('k') $m?k $m?('k') ?k # Lookup
76
76
  map:keys map:contains map:get map:put map:remove map:size map:merge map:entry
77
77
  ```
78
+
78
79
  ````
79
80
 
80
81
  ## Arrays
@@ -206,3 +207,4 @@ $seq ! (./child/@attr) # apply to each, flatten
206
207
  - Document order preserved
207
208
  - Namespaces: prefixes or `Q{uri}local`
208
209
  - Errors: `try/catch` in 3.1
210
+ ````
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-docs",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "description": "A tool for generating reusable, low-token AI agent instruction documents",
6
6
  "keywords": [
@@ -18,6 +18,7 @@
18
18
  "url": "https://github.com/starch-uk/agent-docs.git"
19
19
  },
20
20
  "devDependencies": {
21
+ "husky": "^9.1.7",
21
22
  "prettier": "^3.7.4"
22
23
  },
23
24
  "engines": {