@pragmatiks/lint 0.6.0 → 0.8.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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## js-v0.8.0 (2026-11-07)
4
+
5
+ ### Features
6
+
7
+ - **rules**: flag pure-prefixed functions that perform I/O (PRA-453, PRA-750)
8
+
9
+ ## js-v0.7.0 (2026-10-07)
10
+
11
+ ### Bug Fixes
12
+
13
+ - **rules**: recognize Path.open and with-open as file I/O in pra-io-prefix-mismatch
14
+
15
+ ### Features
16
+
17
+ - **rules**: drop the Python comment rules the strict comment check replaces
18
+
3
19
  ## js-v0.6.0 (2026-09-27)
4
20
 
5
21
  ### Features
package/README.md CHANGED
@@ -142,7 +142,7 @@ Fix these by rewriting the code:
142
142
 
143
143
  ## Development
144
144
 
145
- | Command | Purpose |
146
- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
147
- | `task js:check` / `task js:test` / `task js:build` | Lint and type check / tests (Node `>=22.15` for `module.registerHooks`; `mise.toml` pins Node 26) / build |
148
- | `task js:pack` | Install, build and `npm pack` the committed HEAD with CI's toolchain (Node 26, pnpm 12.6.0, latest npm) in a throwaway worktree, printing all three versions; the tarball lands in `js/` |
145
+ | Command | Purpose |
146
+ | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
147
+ | `mise run js:check` / `mise run js:test` / `mise run js:build` | Lint and type check / tests (Node `>=22.15` for `module.registerHooks`; `mise.toml` pins Node 26) / build |
148
+ | `mise run js:pack` | Install, build and `npm pack` the committed HEAD as CI publishes it, with the mise-locked node, pnpm and npm, in a throwaway worktree, printing all three versions; the tarball lands in `js/` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pragmatiks/lint",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Pragmatiks engineering principles eslint config and bundled semgrep rules.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,6 +26,23 @@ rules:
26
26
  ...
27
27
  open(...)
28
28
  ...
29
+ - pattern-not: |
30
+ def $NAME(...):
31
+ ...
32
+ with open(...) as $HANDLE:
33
+ ...
34
+ ...
35
+ - pattern-not: |
36
+ def $NAME(...):
37
+ ...
38
+ $PATH.open(...)
39
+ ...
40
+ - pattern-not: |
41
+ def $NAME(...):
42
+ ...
43
+ with $PATH.open(...) as $HANDLE:
44
+ ...
45
+ ...
29
46
  - pattern-not: |
30
47
  def $NAME(...):
31
48
  ...
@@ -86,6 +103,16 @@ rules:
86
103
  ...
87
104
  $PATH.rmdir(...)
88
105
  ...
106
+ - pattern-not: |
107
+ def $NAME(...):
108
+ ...
109
+ $PATH.resolve(...)
110
+ ...
111
+ - pattern-not: |
112
+ def $NAME(...):
113
+ ...
114
+ importlib.import_module(...)
115
+ ...
89
116
  - pattern-not: |
90
117
  def $NAME(...):
91
118
  ...
@@ -96,10 +123,10 @@ rules:
96
123
  ...
97
124
  subprocess.$METHOD(...)
98
125
  ...
99
- - pattern-not-regex: '(?s)\bos\.(mkdir|makedirs|rmdir|removedirs|remove|unlink|rename|replace|kill|chdir|chmod|chown|symlink|link|stat|lstat|listdir|scandir|access|system|popen|path\.(exists|isfile|isdir|islink|getsize))\('
126
+ - pattern-not-regex: '(?s)\bos\.(mkdir|makedirs|rmdir|removedirs|remove|unlink|rename|replace|kill|chdir|chmod|chown|symlink|link|stat|lstat|listdir|scandir|access|system|popen|path\.(exists|isfile|isdir|islink|getsize|realpath))\('
100
127
  - pattern-not-regex: '(?s)(database|session|connection|cursor|client)\.(execute|fetch|get|post|put|delete|query|read|write|save)\('
101
128
  message: "principle #7 I/O-prefixed function appears pure. Rename it with compute, build, derive, format, or parse."
102
129
  severity: WARNING
103
130
  languages: [python]
104
131
  metadata:
105
- note: "Heuristic rule; false positives are expected for hidden I/O wrappers."
132
+ note: "Heuristic rule; false positives are expected for hidden I/O wrappers. The I/O vocabulary mirrors pra-pure-prefix-mismatch in opposite polarity; keep both rules in step."
@@ -0,0 +1,6 @@
1
+ rules:
2
+ - id: pra-no-block-comments-js
3
+ pattern-regex: '/\*(?!\*)[\s\S]*?\*/'
4
+ message: "principle #10 Block comments make code harder to trust. Delete the comment; rationale worth keeping goes in the owning docstring."
5
+ severity: ERROR
6
+ languages: [typescript, javascript]
@@ -0,0 +1,6 @@
1
+ rules:
2
+ - id: pra-no-todo-comments-js
3
+ pattern-regex: '(?i)(//|/\*)\s*(TODO(?!\(PRA-[0-9]+\))|FIXME|XXX)\b'
4
+ message: "principle #10 Planning comments decay. Track the work as an issue and delete the comment."
5
+ severity: ERROR
6
+ languages: [typescript, javascript]
@@ -0,0 +1,78 @@
1
+ rules:
2
+ - id: pra-pure-prefix-mismatch
3
+ patterns:
4
+ - pattern-either:
5
+ - pattern: |
6
+ def $NAME(...):
7
+ ...
8
+ - pattern: |
9
+ async def $NAME(...):
10
+ ...
11
+ - metavariable-regex:
12
+ metavariable: $NAME
13
+ regex: '^(compute|build|derive|format|parse|extract)_.*'
14
+ - pattern-either:
15
+ - pattern-inside: |
16
+ def $NAME(...):
17
+ ...
18
+ $IO
19
+ ...
20
+ - pattern-inside: |
21
+ async def $NAME(...):
22
+ ...
23
+ $IO
24
+ ...
25
+ - metavariable-pattern:
26
+ metavariable: $IO
27
+ pattern-either:
28
+ - pattern: open(...)
29
+ - pattern: $PATH.open(...)
30
+ - patterns:
31
+ - pattern-either:
32
+ - pattern: httpx.$METHOD(...)
33
+ - pattern: requests.$METHOD(...)
34
+ - metavariable-regex:
35
+ metavariable: $METHOD
36
+ regex: '^(get|post|put|patch|delete|head|options|request|stream)$'
37
+ - pattern: $PATH.read_text(...)
38
+ - pattern: $PATH.read_bytes(...)
39
+ - pattern: $PATH.write_text(...)
40
+ - pattern: $PATH.write_bytes(...)
41
+ - pattern: $PATH.unlink(...)
42
+ - pattern: $PATH.mkdir(...)
43
+ - pattern: $PATH.exists(...)
44
+ - pattern: $PATH.iterdir(...)
45
+ - pattern: $PATH.glob(...)
46
+ - pattern: $PATH.rmdir(...)
47
+ - pattern: $PATH.resolve(...)
48
+ - pattern: shutil.$METHOD(...)
49
+ - pattern: subprocess.$METHOD(...)
50
+ - pattern: importlib.import_module(...)
51
+ - patterns:
52
+ - pattern: os.$METHOD(...)
53
+ - metavariable-regex:
54
+ metavariable: $METHOD
55
+ regex: '^(mkdir|makedirs|rmdir|removedirs|remove|unlink|rename|replace|kill|chdir|chmod|chown|symlink|link|stat|lstat|listdir|scandir|access|system|popen)$'
56
+ - patterns:
57
+ - pattern: os.path.$METHOD(...)
58
+ - metavariable-regex:
59
+ metavariable: $METHOD
60
+ regex: '^(exists|isfile|isdir|islink|getsize|realpath)$'
61
+ - patterns:
62
+ - pattern: $CLIENT.$METHOD(...)
63
+ - metavariable-regex:
64
+ metavariable: $CLIENT
65
+ regex: '(database|session|connection|cursor|client)$'
66
+ - metavariable-regex:
67
+ metavariable: $METHOD
68
+ regex: '^(execute|fetch|get|post|put|delete|query|read|write|save)$'
69
+ - patterns:
70
+ - pattern: $CALLEE(...)
71
+ - metavariable-regex:
72
+ metavariable: $CALLEE
73
+ regex: '^(fetch|retrieve|load|save|read|write|query)_\w+$'
74
+ message: "principle #7 pure-prefixed function appears to perform I/O. Rename it with get, fetch, retrieve, load, save, read, write, or query, or move the I/O to the caller."
75
+ severity: WARNING
76
+ languages: [python]
77
+ metadata:
78
+ note: "Heuristic rule; detects I/O written in the body, or a call to a bare function named with an I/O prefix other than get. I/O hidden behind other helpers is not seen. The I/O vocabulary mirrors pra-io-prefix-mismatch in opposite polarity; keep both rules in step."
@@ -1,11 +0,0 @@
1
- rules:
2
- - id: pra-no-block-comments-python
3
- pattern-regex: '(?m)^[ \t]*#(?![ \t]*WHY:).*\n[ \t]*#(?![ \t]*WHY:).*$'
4
- message: "principle #10 Block comments make code harder to trust. Delete the comment or replace it with one WHY line."
5
- severity: ERROR
6
- languages: [python]
7
- - id: pra-no-block-comments-js
8
- pattern-regex: '/\*(?!\*)[\s\S]*?\*/'
9
- message: "principle #10 Block comments make code harder to trust. Delete the comment or replace it with one WHY line."
10
- severity: ERROR
11
- languages: [typescript, javascript]
@@ -1,11 +0,0 @@
1
- rules:
2
- - id: pra-no-todo-comments-python
3
- pattern-regex: '(?i)#\s*(TODO(?!\(PRA-[0-9]+\))|FIXME|XXX)\b'
4
- message: "principle #10 Planning comments decay. Link a Linear issue or remove the comment."
5
- severity: ERROR
6
- languages: [python]
7
- - id: pra-no-todo-comments-js
8
- pattern-regex: '(?i)(//|/\*)\s*(TODO(?!\(PRA-[0-9]+\))|FIXME|XXX)\b'
9
- message: "principle #10 Planning comments decay. Link a Linear issue or remove the comment."
10
- severity: ERROR
11
- languages: [typescript, javascript]