@konvert7/klint 1.0.2 → 1.2.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/README.md CHANGED
@@ -525,11 +525,13 @@ klint scans TypeScript/JavaScript, Python, Swift, Rust, and C#. Every architectu
525
525
  | `arch.forbidden` / `singleton` — `jsx-element` | ✅ | — | — | — | — |
526
526
  | `arch.maxLines` | ✅ | ✅ | ✅ | ✅ | ✅ |
527
527
  | `arch.maxCommentDensity` / `maxCommentBlock` | ✅ `//`, `/* */`, `/** */` docs | ✅ `#` | ✅ `//`, `/* */`, `///` and `/** */` docs | ✅ `//`, `/* */`, `///` and `//!` docs | ✅ `//`, `/* */`, `///` and `/** */` docs |
528
- | Built-in rules and plugins | ✅ | ✗ | ✗ | ✗ | ✗ |
528
+ | Built-in rules and plugins | ✅ | ✗ ¹ | ✗ ¹ | ✗ ¹ | ✗ ¹ |
529
529
 
530
530
  **✅** supported · **—** the language has no equivalent construct · **✗** not supported yet
531
531
 
532
- A dash is not a gap. Swift has no dynamic import expression, no `import type`, and one module per declaration; Rust has no dynamic import and no type-only import; C# has no dynamic `using`, no type-only import, and one namespace per `using`. Those rows can never be filled. The `✗` rows are real limits: the rule set and custom rules are written against the TypeScript AST, and type-aware rules need a type checker that only the TS engine has.
532
+ ¹ except `blank-line-before-control-flow` and `blank-line-after-block`, which run on all five languages.
533
+
534
+ A dash is not a gap. Swift has no dynamic import expression, no `import type`, and one module per declaration; Rust has no dynamic import and no type-only import; C# has no dynamic `using`, no type-only import, and one namespace per `using`. Those rows can never be filled. The `✗` rows are real limits: the rule set and custom rules are written against the TypeScript AST, and type-aware rules need a type checker that only the TS engine has. The one exception is the pair of blank-line rules, which read each language's own syntax tree and so run on all five.
533
535
 
534
536
  Imports are read off the AST in every language, so a specifier written inside a comment or a string is never an import — including nested Swift block comments.
535
537
 
@@ -729,9 +731,114 @@ doc-comments alongside `/** */`.
729
731
  | `no-nested-template-literals` | Template literals nested inside template literals |
730
732
  | `no-consecutive-array-push` | Multiple consecutive `push()` calls that should be grouped |
731
733
  | `no-string-match` | `String#match()` usage better expressed with clearer APIs |
734
+ | `blank-line-before-control-flow` | Blank line above a control-flow statement that follows another statement; autofix |
735
+ | `blank-line-after-block` | Blank line below a block statement when another statement follows; autofix |
736
+ | `cognitive-complexity` | Function whose cognitive complexity (Biome / SonarSource model) is above `max`, in all five languages; opt-in, no autofix |
732
737
 
733
738
  Rules that needed TypeScript's type checker were removed in 1.0; see [Upgrading from klint 0.x](#upgrading-from-klint-0x).
734
739
 
740
+ ### Blank lines around control flow
741
+
742
+ `blank-line-before-control-flow` asks for a blank line above a control-flow statement that follows another statement in its block. `blank-line-after-block` asks for a blank line below a block statement when another statement follows it in the same block. Both work on TypeScript/JavaScript, Python, Swift, Rust and C#. They are opt-in, and `klint --fix` inserts the missing line.
743
+
744
+ ```yaml
745
+ rules:
746
+ blank-line-before-control-flow: error
747
+ blank-line-after-block: warn
748
+ ```
749
+
750
+ ```yaml
751
+ rules:
752
+ blank-line-before-control-flow:
753
+ severity: error
754
+ include: ["src/**", "!src/generated/**"]
755
+ statements: [if, for, while, switch, try, return, guard, loop, with]
756
+ allowSetup: true
757
+ blank-line-after-block:
758
+ severity: warn
759
+ include: ["src/**"]
760
+ statements: [if, for, while, switch, try, guard, loop, with]
761
+ ```
762
+
763
+ - `statements` lists the statement kinds a rule targets. The default is every kind the rule supports. `statements: []` turns the rule off. `match` is an alias of `switch`. `return` is valid only for `blank-line-before-control-flow`. An unknown keyword, or `return` on the after rule, produces one `klint/config` warning, and the remaining keywords still apply.
764
+ - `allowSetup` (before rule only, default `true`) turns the setup exception on or off, described below.
765
+
766
+ | keyword | TypeScript / JavaScript | Python | Swift | Rust | C# |
767
+ |---|---|---|---|---|---|
768
+ | `if` | `if` | `if` | `if` | `if`, `if let` | `if` |
769
+ | `for` | `for`, `for…in`, `for…of` | `for` | `for…in` | `for` | `for`, `foreach` |
770
+ | `while` | `while`, `do…while` | `while` | `while`, `repeat…while` | `while`, `while let` | `while`, `do…while` |
771
+ | `switch` (alias `match`) | `switch` | `match` | `switch` | `match` | `switch` statement |
772
+ | `try` | `try` | `try` | `do` | — | `try` |
773
+ | `return` (before rule only) | `return` | `return` | `return` | `return` | `return` |
774
+ | `guard` | — | — | `guard` | — | — |
775
+ | `loop` | — | — | — | `loop` | — |
776
+ | `with` | — | `with` | — | — | — |
777
+
778
+ **Comments.** A comment that starts its own line directly above a statement belongs to that statement. The before rule puts the blank line above the comment. The after rule puts the blank line between the block and a comment that follows the block, so the comment stays with the statement below.
779
+
780
+ **Setup exception.** With `allowSetup: true`, the before rule skips an `if`, `guard` or `switch` whose condition uses a name assigned by the statement directly above it. For example, `x = f();` followed by `if (x) …` is not reported. Only the statement directly above counts (comment lines are skipped), only plain names count (`self.x = f()` does not), and only the condition is searched, not the body.
781
+
782
+ **Autofix.** `klint --fix` inserts one empty line with the line ending of the line above it, and changes nothing else. A second run changes nothing.
783
+
784
+ **Not checked.** A file with a syntax error gets no report and no fix. A braceless body (`if (a) return 1;`) is not a block for the after rule. `do…while` and `repeat…while` are never reported by the after rule. A statement that shares its line with the previous statement is not reported, because the fix would have to split that line. Expression forms are not statements: `let x = if …` and `let r = match …` in Rust, `let x = if …` in Swift, a C# switch expression, and control flow inside a call are never reported. A Python docstring is documentation, not a statement, so the statement after it counts as first in its block. A C# preprocessor line (`#region`, `#if`, `#pragma`, …) or a Swift `#if`/`#elseif`/`#else`/`#endif` line separates statements like a blank line, so neither rule inserts a line next to one.
785
+
786
+ ### Cognitive complexity
787
+
788
+ `cognitive-complexity` reports every function whose cognitive complexity is above `max`, in TypeScript/JavaScript, Python, Swift, Rust and C#. It is opt-in and has no fix. It uses Biome 2.6.5's `noExcessiveCognitiveComplexity` scoring (the SonarSource Cognitive Complexity model, G. Ann Campbell 2017) for every language, so a TypeScript function gets the same score as in Biome.
789
+
790
+ ```yaml
791
+ rules:
792
+ cognitive-complexity: error
793
+ ```
794
+
795
+ ```yaml
796
+ rules:
797
+ cognitive-complexity:
798
+ severity: warn
799
+ include: ["src/**", "!src/generated/**"]
800
+ max: 14
801
+ ```
802
+
803
+ - `max` is an integer of at least 1, default 15. A function is reported when its score is **greater than** `max`. Any other value (0, a negative number, a fraction, a string) gives one `klint/config` warning naming the rule and the value, and the rule uses 15.
804
+ - The message has the form ``Function `big` has cognitive complexity 16 (max 15) — split it into smaller functions.``. The name is the declared name. For an anonymous function assigned to a variable or property it is that name. Otherwise it is `<anonymous>`. The line is the function's first line.
805
+ - Each function starts at 0. Top-level code is not scored.
806
+
807
+ **Scoring.** "Nesting" is how deep a construct sits: each enclosing `if`, loop, `switch`, `catch`, `guard`, `let … else` body and each enclosing function adds one.
808
+
809
+ | Increment | TypeScript / JavaScript | Python | Swift | Rust | C# |
810
+ |---|---|---|---|---|---|
811
+ | +1 plus nesting: `if`, and `else if` (which also gets the nesting) | `if`, `else if` | `if`, `elif` | `if`, `else if` | `if`, `if let`, `else if` | `if`, `else if` |
812
+ | +1 plus nesting: ternary | `?:` | `x if c else y` | `?:` | — | `?:` |
813
+ | +1 plus nesting: switch / match | `switch` | `match` | `switch` | `match` | `switch` statement, `switch` expression |
814
+ | +1 plus nesting: loops | `for`, `for…in`, `for…of`, `while`, `do…while` | `for`, `while` | `for`, `while`, `repeat…while` | `for`, `while`, `while let`, `loop` | `for`, `foreach`, `while`, `do` |
815
+ | +1 plus nesting: `catch` | `catch` | `except` | `catch` | — | `catch` |
816
+ | +1 plus nesting: `guard`, `let … else` (its `else` body is nested) | — | — | `guard` | `let … else` | — |
817
+ | +1, no nesting: `finally` (its body is not nested) | `finally` | `finally` | — | — | `finally` |
818
+ | nesting only: nested function (scored on its own, see below) | arrow, function expression, function declaration, method | `lambda`, `def` | closure | closure | lambda, local function, anonymous method |
819
+ | +1, no nesting: plain `else` (not `else if`/`elif`) | `else` | `else` of `if`, `try`, `for`, `while` | `else` | `else` | `else` |
820
+ | +1: labeled `break` / `continue`, `goto` | `break label`, `continue label` | — | `break label`, `continue label` | `break 'label`, `continue 'label` | `goto` |
821
+ | +1 per logical operator, unless its direct parent is the same operator | `&&`, `\|\|`, `??` | `and`, `or` | `&&`, `\|\|`, `??` | `&&`, `\|\|` | `&&`, `\|\|`, `??`, pattern `and`, `or` |
822
+ | +1: comprehension `if` | — | comprehension `if` | — | — | — |
823
+ | +1: guard on a case or arm | — | — | `case … where` | match-arm guard | `when` clause |
824
+
825
+ Each logical operator scores +1, unless its direct parent is a logical operator of the same kind. Parentheses break that link, so a parenthesised group scores on its own: `a && b || c` is 2, `a && (b || c) && a` is 2, `a && (b && c)` is 2, and `a ?? b ?? c` is 1. Negation (`!`, `not`) adds nothing.
826
+
827
+ It adds nothing for `try` itself, `return`, `throw`, recursion, Rust `?`, Python `with`, Swift `do` without `catch`, an `if let` or `while let` beyond the `if` or `while`, optional chaining `?.`, assignment operators `||=`, `&&=`, `??=`, and a Rust `let` without `else`.
828
+
829
+ **Differences from the Sonar paper.** This rule follows Biome, which differs from the paper in these places:
830
+
831
+ - `else if` gets the nesting increment.
832
+ - `finally` adds one and does not nest its body.
833
+ - `??` counts as a boolean operator.
834
+ - A logical operator is scored unless its direct parent is the same operator, so `a && (b && c)` is 2, not 1.
835
+ - Recursion adds nothing.
836
+ - A nested function (closure, lambda, arrow, local function) is scored and reported on its own. It starts at its enclosing nesting level plus one and does not add to the outer function.
837
+
838
+ **What counts as a function.** TypeScript/JavaScript: `function` declarations and expressions, arrow functions, methods (including getters and setters), generator functions. Python: `def` and `lambda`. Swift: `func`, `init`, `deinit`, closures, computed getters and setters. Rust: `fn` items and closures. C#: methods, constructors, destructors, local functions, lambdas, anonymous methods, property and indexer accessors, operators and conversion operators.
839
+
840
+ **Not checked.** Rust macro bodies are opaque token trees, so code inside a macro call is not scored. Code inside a Python decorator does not count toward the decorated function; a lambda there is scored on its own. A file with a syntax error gets no diagnostic. A Swift computed property without an explicit `get` is not a function. Bodyless declarations are never reported: TypeScript method signatures, Swift protocol requirements and Rust trait signatures are not functions at all, and C# interface and abstract members have nothing to score, so they score 0, which can never exceed `max`.
841
+
735
842
  ## Plugins
736
843
 
737
844
  Enable plugin rules with `plugins: [sonar]`, then override individual severities in `rules` when needed.
package/klint.schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://raw.githubusercontent.com/konvert7/klint/refs/tags/v1.0.2/klint.schema.json",
2
+ "$id": "https://raw.githubusercontent.com/konvert7/klint/refs/tags/v1.2.0/klint.schema.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "additionalProperties": false,
5
5
  "description": "klint configuration. Lives at klint.yaml (or klint.config.json) next to biome.json and knip.json.",
@@ -598,6 +598,182 @@
598
598
  },
599
599
  "description": "Map of rule name → severity or options. Example: { \"no-floating-promise\": \"error\", \"no-sync-in-async\": { \"severity\": \"warn\", \"include\": [\"src/hooks/**\"] } }.",
600
600
  "properties": {
601
+ "blank-line-after-block": {
602
+ "anyOf": [
603
+ {
604
+ "description": "Rule severity. \"error\" exits with code 2; \"warn\" reports but exits 0; \"off\" silences.",
605
+ "enum": [
606
+ "error",
607
+ "warn",
608
+ "off"
609
+ ],
610
+ "type": "string"
611
+ },
612
+ {
613
+ "additionalProperties": false,
614
+ "description": "Rule options object. Omit severity to default to \"error\". Add include to scope the rule to specific files.",
615
+ "properties": {
616
+ "include": {
617
+ "description": "Glob patterns scoping this rule to a subset of files. Prefix with ! to exclude. Example: [\"src/hooks/**\", \"!src/hooks/scripts/**\"]",
618
+ "items": {
619
+ "type": "string"
620
+ },
621
+ "type": "array"
622
+ },
623
+ "severity": {
624
+ "description": "Rule severity. \"error\" exits with code 2; \"warn\" reports but exits 0; \"off\" silences.",
625
+ "enum": [
626
+ "error",
627
+ "warn",
628
+ "off",
629
+ null
630
+ ],
631
+ "type": "string"
632
+ },
633
+ "statements": {
634
+ "description": "Block statement kinds this rule targets. Defaults to every kind: if, for, while, switch, try, guard, loop, with. match is an alias of switch. return is not a block statement. An empty list turns the rule off.",
635
+ "items": {
636
+ "description": "A block statement kind the rule targets. match is an alias of switch.",
637
+ "enum": [
638
+ "if",
639
+ "for",
640
+ "while",
641
+ "switch",
642
+ "match",
643
+ "try",
644
+ "guard",
645
+ "loop",
646
+ "with"
647
+ ],
648
+ "type": "string"
649
+ },
650
+ "type": "array"
651
+ }
652
+ },
653
+ "type": "object"
654
+ }
655
+ ],
656
+ "description": "Requires a blank line below a block statement (if, for, while, switch/match, try, guard, loop, with) when another statement follows it in the same block, like C# IDE2003. Works on TypeScript/JavaScript, Python, Swift, Rust and C#; `klint --fix` inserts the line.",
657
+ "examples": [
658
+ "blank-line-after-block: warn",
659
+ "blank-line-after-block:\n severity: warn\n include: [\"src/**\"]\n statements: [if, for, while, switch, try, guard, loop, with]"
660
+ ]
661
+ },
662
+ "blank-line-before-control-flow": {
663
+ "anyOf": [
664
+ {
665
+ "description": "Rule severity. \"error\" exits with code 2; \"warn\" reports but exits 0; \"off\" silences.",
666
+ "enum": [
667
+ "error",
668
+ "warn",
669
+ "off"
670
+ ],
671
+ "type": "string"
672
+ },
673
+ {
674
+ "additionalProperties": false,
675
+ "description": "Rule options object. Omit severity to default to \"error\". Add include to scope the rule to specific files.",
676
+ "properties": {
677
+ "allowSetup": {
678
+ "description": "Skip an if, guard or switch statement whose condition uses a name assigned by the statement directly above it. Defaults to true.",
679
+ "type": "boolean"
680
+ },
681
+ "include": {
682
+ "description": "Glob patterns scoping this rule to a subset of files. Prefix with ! to exclude. Example: [\"src/hooks/**\", \"!src/hooks/scripts/**\"]",
683
+ "items": {
684
+ "type": "string"
685
+ },
686
+ "type": "array"
687
+ },
688
+ "severity": {
689
+ "description": "Rule severity. \"error\" exits with code 2; \"warn\" reports but exits 0; \"off\" silences.",
690
+ "enum": [
691
+ "error",
692
+ "warn",
693
+ "off",
694
+ null
695
+ ],
696
+ "type": "string"
697
+ },
698
+ "statements": {
699
+ "description": "Statement kinds this rule targets. Defaults to every kind: if, for, while, switch, try, return, guard, loop, with. match is an alias of switch. An empty list turns the rule off.",
700
+ "items": {
701
+ "description": "A statement kind the rule targets. match is an alias of switch.",
702
+ "enum": [
703
+ "if",
704
+ "for",
705
+ "while",
706
+ "switch",
707
+ "match",
708
+ "try",
709
+ "return",
710
+ "guard",
711
+ "loop",
712
+ "with"
713
+ ],
714
+ "type": "string"
715
+ },
716
+ "type": "array"
717
+ }
718
+ },
719
+ "type": "object"
720
+ }
721
+ ],
722
+ "description": "Requires a blank line above a control-flow statement (if, for, while, switch/match, try, return, guard, loop, with) that follows another statement in the same block. Works on TypeScript/JavaScript, Python, Swift, Rust and C#; `klint --fix` inserts the line.",
723
+ "examples": [
724
+ "blank-line-before-control-flow: error",
725
+ "blank-line-before-control-flow:\n severity: error\n include: [\"src/**\", \"!src/generated/**\"]\n statements: [if, for, while, switch, try, return, guard, loop, with]\n allowSetup: true"
726
+ ]
727
+ },
728
+ "cognitive-complexity": {
729
+ "anyOf": [
730
+ {
731
+ "description": "Rule severity. \"error\" exits with code 2; \"warn\" reports but exits 0; \"off\" silences.",
732
+ "enum": [
733
+ "error",
734
+ "warn",
735
+ "off"
736
+ ],
737
+ "type": "string"
738
+ },
739
+ {
740
+ "additionalProperties": false,
741
+ "description": "Rule options object. Omit severity to default to \"error\". Add include to scope the rule to specific files.",
742
+ "properties": {
743
+ "include": {
744
+ "description": "Glob patterns scoping this rule to a subset of files. Prefix with ! to exclude. Example: [\"src/hooks/**\", \"!src/hooks/scripts/**\"]",
745
+ "items": {
746
+ "type": "string"
747
+ },
748
+ "type": "array"
749
+ },
750
+ "max": {
751
+ "default": 15,
752
+ "description": "Highest cognitive complexity a function may have; a function scoring above it is reported. An integer of at least 1. Defaults to 15.",
753
+ "format": "uint32",
754
+ "minimum": 1,
755
+ "type": "integer"
756
+ },
757
+ "severity": {
758
+ "description": "Rule severity. \"error\" exits with code 2; \"warn\" reports but exits 0; \"off\" silences.",
759
+ "enum": [
760
+ "error",
761
+ "warn",
762
+ "off",
763
+ null
764
+ ],
765
+ "type": "string"
766
+ }
767
+ },
768
+ "type": "object"
769
+ }
770
+ ],
771
+ "description": "Reports every function whose cognitive complexity is above `max` (default 15), scored like Biome 2.6.5's `noExcessiveCognitiveComplexity` (the SonarSource Cognitive Complexity model). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.",
772
+ "examples": [
773
+ "cognitive-complexity: error",
774
+ "cognitive-complexity:\n severity: warn\n include: [\"src/**\", \"!src/generated/**\"]\n max: 14"
775
+ ]
776
+ },
601
777
  "no-async-predicate": {
602
778
  "anyOf": [
603
779
  {
package/klint.schema.yaml CHANGED
@@ -1,4 +1,4 @@
1
- $id: https://raw.githubusercontent.com/konvert7/klint/refs/tags/v1.0.2/klint.schema.json
1
+ $id: https://raw.githubusercontent.com/konvert7/klint/refs/tags/v1.2.0/klint.schema.json
2
2
  $schema: http://json-schema.org/draft-07/schema#
3
3
  additionalProperties: false
4
4
  description: klint configuration. Lives at klint.yaml (or klint.config.json) next to biome.json and knip.json.
@@ -449,6 +449,148 @@ properties:
449
449
  type: object
450
450
  description: 'Map of rule name → severity or options. Example: { "no-floating-promise": "error", "no-sync-in-async": { "severity": "warn", "include": ["src/hooks/**"] } }.'
451
451
  properties:
452
+ blank-line-after-block:
453
+ anyOf:
454
+ - description: Rule severity. "error" exits with code 2; "warn" reports but exits 0; "off" silences.
455
+ enum:
456
+ - error
457
+ - warn
458
+ - off
459
+ type: string
460
+ - additionalProperties: false
461
+ description: Rule options object. Omit severity to default to "error". Add include to scope the rule to specific files.
462
+ properties:
463
+ include:
464
+ description: 'Glob patterns scoping this rule to a subset of files. Prefix with ! to exclude. Example: ["src/hooks/**", "!src/hooks/scripts/**"]'
465
+ items:
466
+ type: string
467
+ type: array
468
+ severity:
469
+ description: Rule severity. "error" exits with code 2; "warn" reports but exits 0; "off" silences.
470
+ enum:
471
+ - error
472
+ - warn
473
+ - off
474
+ - null
475
+ type: string
476
+ statements:
477
+ description: 'Block statement kinds this rule targets. Defaults to every kind: if, for, while, switch, try, guard, loop, with. match is an alias of switch. return is not a block statement. An empty list turns the rule off.'
478
+ items:
479
+ description: A block statement kind the rule targets. match is an alias of switch.
480
+ enum:
481
+ - if
482
+ - for
483
+ - while
484
+ - switch
485
+ - match
486
+ - try
487
+ - guard
488
+ - loop
489
+ - with
490
+ type: string
491
+ type: array
492
+ type: object
493
+ description: Requires a blank line below a block statement (if, for, while, switch/match, try, guard, loop, with) when another statement follows it in the same block, like C# IDE2003. Works on TypeScript/JavaScript, Python, Swift, Rust and C#; `klint --fix` inserts the line.
494
+ examples:
495
+ - 'blank-line-after-block: warn'
496
+ - |-
497
+ blank-line-after-block:
498
+ severity: warn
499
+ include: ["src/**"]
500
+ statements: [if, for, while, switch, try, guard, loop, with]
501
+ blank-line-before-control-flow:
502
+ anyOf:
503
+ - description: Rule severity. "error" exits with code 2; "warn" reports but exits 0; "off" silences.
504
+ enum:
505
+ - error
506
+ - warn
507
+ - off
508
+ type: string
509
+ - additionalProperties: false
510
+ description: Rule options object. Omit severity to default to "error". Add include to scope the rule to specific files.
511
+ properties:
512
+ allowSetup:
513
+ description: Skip an if, guard or switch statement whose condition uses a name assigned by the statement directly above it. Defaults to true.
514
+ type: boolean
515
+ include:
516
+ description: 'Glob patterns scoping this rule to a subset of files. Prefix with ! to exclude. Example: ["src/hooks/**", "!src/hooks/scripts/**"]'
517
+ items:
518
+ type: string
519
+ type: array
520
+ severity:
521
+ description: Rule severity. "error" exits with code 2; "warn" reports but exits 0; "off" silences.
522
+ enum:
523
+ - error
524
+ - warn
525
+ - off
526
+ - null
527
+ type: string
528
+ statements:
529
+ description: 'Statement kinds this rule targets. Defaults to every kind: if, for, while, switch, try, return, guard, loop, with. match is an alias of switch. An empty list turns the rule off.'
530
+ items:
531
+ description: A statement kind the rule targets. match is an alias of switch.
532
+ enum:
533
+ - if
534
+ - for
535
+ - while
536
+ - switch
537
+ - match
538
+ - try
539
+ - return
540
+ - guard
541
+ - loop
542
+ - with
543
+ type: string
544
+ type: array
545
+ type: object
546
+ description: Requires a blank line above a control-flow statement (if, for, while, switch/match, try, return, guard, loop, with) that follows another statement in the same block. Works on TypeScript/JavaScript, Python, Swift, Rust and C#; `klint --fix` inserts the line.
547
+ examples:
548
+ - 'blank-line-before-control-flow: error'
549
+ - |-
550
+ blank-line-before-control-flow:
551
+ severity: error
552
+ include: ["src/**", "!src/generated/**"]
553
+ statements: [if, for, while, switch, try, return, guard, loop, with]
554
+ allowSetup: true
555
+ cognitive-complexity:
556
+ anyOf:
557
+ - description: Rule severity. "error" exits with code 2; "warn" reports but exits 0; "off" silences.
558
+ enum:
559
+ - error
560
+ - warn
561
+ - off
562
+ type: string
563
+ - additionalProperties: false
564
+ description: Rule options object. Omit severity to default to "error". Add include to scope the rule to specific files.
565
+ properties:
566
+ include:
567
+ description: 'Glob patterns scoping this rule to a subset of files. Prefix with ! to exclude. Example: ["src/hooks/**", "!src/hooks/scripts/**"]'
568
+ items:
569
+ type: string
570
+ type: array
571
+ max:
572
+ default: 15
573
+ description: Highest cognitive complexity a function may have; a function scoring above it is reported. An integer of at least 1. Defaults to 15.
574
+ format: uint32
575
+ minimum: 1
576
+ type: integer
577
+ severity:
578
+ description: Rule severity. "error" exits with code 2; "warn" reports but exits 0; "off" silences.
579
+ enum:
580
+ - error
581
+ - warn
582
+ - off
583
+ - null
584
+ type: string
585
+ type: object
586
+ description: Reports every function whose cognitive complexity is above `max` (default 15), scored like Biome 2.6.5's `noExcessiveCognitiveComplexity` (the SonarSource Cognitive Complexity model). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.
587
+ examples:
588
+ - 'cognitive-complexity: error'
589
+ - |-
590
+ cognitive-complexity:
591
+ severity: warn
592
+ include: ["src/**", "!src/generated/**"]
593
+ max: 14
452
594
  no-async-predicate:
453
595
  anyOf:
454
596
  - description: Rule severity. "error" exits with code 2; "warn" reports but exits 0; "off" silences.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konvert7/klint",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "description": "Architecture-as-Code linter for TypeScript. Enforce layer boundaries, import rules, and singleton patterns in YAML.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -56,12 +56,12 @@
56
56
  ]
57
57
  },
58
58
  "optionalDependencies": {
59
- "@konvert7/klint-darwin-arm64": "1.0.2",
60
- "@konvert7/klint-darwin-x64": "1.0.2",
61
- "@konvert7/klint-linux-arm64": "1.0.2",
62
- "@konvert7/klint-linux-x64": "1.0.2",
63
- "@konvert7/klint-linux-x64-musl": "1.0.2",
64
- "@konvert7/klint-win32-x64": "1.0.2"
59
+ "@konvert7/klint-darwin-arm64": "1.2.0",
60
+ "@konvert7/klint-darwin-x64": "1.2.0",
61
+ "@konvert7/klint-linux-arm64": "1.2.0",
62
+ "@konvert7/klint-linux-x64": "1.2.0",
63
+ "@konvert7/klint-linux-x64-musl": "1.2.0",
64
+ "@konvert7/klint-win32-x64": "1.2.0"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@biomejs/biome": "2.6.5",