@gspothq/cli 0.1.1 → 0.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.
Files changed (205) hide show
  1. package/README.md +58 -11
  2. package/configurations/database/postgres/manifest.toml +51 -57
  3. package/configurations/database/postgres/rules/POSTGRES.md +14 -13
  4. package/configurations/framework/astro/manifest.toml +33 -35
  5. package/configurations/framework/astro/rules/ASTRO.md +2 -2
  6. package/configurations/framework/expo/manifest.toml +19 -19
  7. package/configurations/framework/express/manifest.toml +10 -4
  8. package/configurations/framework/express/rules/EXPRESS.md +9 -7
  9. package/configurations/framework/fastapi/manifest.toml +9 -3
  10. package/configurations/framework/fastapi/rules/FASTAPI.md +19 -18
  11. package/configurations/framework/nestjs/manifest.toml +12 -12
  12. package/configurations/framework/nestjs/rules/NESTJS.md +9 -9
  13. package/configurations/framework/nextjs/manifest.toml +39 -79
  14. package/configurations/framework/nextjs/rules/NEXTJS.md +9 -7
  15. package/configurations/framework/nextjs/tool-files/semgrep/nextjs.yml +35 -0
  16. package/configurations/framework/react/manifest.toml +33 -43
  17. package/configurations/framework/react/rules/REACT.md +14 -20
  18. package/configurations/framework/react-dom/manifest.toml +6 -6
  19. package/configurations/framework/react-native/manifest.toml +11 -11
  20. package/configurations/framework/react-native/rules/REACT-NATIVE.md +3 -5
  21. package/configurations/framework/site/manifest.toml +57 -110
  22. package/configurations/framework/site/rules/SITE.md +1 -1
  23. package/configurations/framework/svelte/manifest.toml +29 -31
  24. package/configurations/framework/svelte/rules/SVELTE.md +6 -6
  25. package/configurations/framework/vue/manifest.toml +37 -37
  26. package/configurations/framework/vue/rules/VUE.md +6 -6
  27. package/configurations/general/commits/manifest.toml +20 -84
  28. package/configurations/general/commits/rules/GIT.md +24 -13
  29. package/configurations/general/coverage/manifest.toml +1 -1
  30. package/configurations/general/dependencies/manifest.toml +47 -107
  31. package/configurations/general/dependencies/rules/DEPENDENCIES.md +13 -7
  32. package/configurations/general/docs/manifest.toml +28 -43
  33. package/configurations/general/docs/rules/DOCS.md +16 -9
  34. package/configurations/general/duplication/manifest.toml +12 -14
  35. package/configurations/general/engineering/manifest.toml +6 -2
  36. package/configurations/general/engineering/rules/agent/PLANNING.md +9 -6
  37. package/configurations/general/engineering/rules/agent/SUPPRESSIONS.md +20 -11
  38. package/configurations/general/engineering/rules/agent/TASKS.md +6 -2
  39. package/configurations/general/engineering/rules/agent/WORKING.md +34 -29
  40. package/configurations/general/engineering/rules/code/ACCESSIBILITY.md +9 -7
  41. package/configurations/general/engineering/rules/code/CLI.md +12 -9
  42. package/configurations/general/engineering/rules/code/COMMENTS.md +11 -1
  43. package/configurations/general/engineering/rules/code/CONFIGURATION.md +2 -0
  44. package/configurations/general/engineering/rules/code/ERRORS.md +5 -3
  45. package/configurations/general/engineering/rules/code/HTTP.md +9 -10
  46. package/configurations/general/engineering/rules/code/LOGGING.md +10 -9
  47. package/configurations/general/engineering/rules/code/TESTING.md +18 -11
  48. package/configurations/general/files/manifest.toml +45 -73
  49. package/configurations/general/files/rules/YAML.md +20 -10
  50. package/configurations/general/format/manifest.toml +53 -106
  51. package/configurations/general/gspot/manifest.toml +19 -39
  52. package/configurations/general/gspot/rules/GENERATED.md +14 -4
  53. package/configurations/general/licenses/manifest.toml +12 -14
  54. package/configurations/general/naming/defaults.json +14 -13
  55. package/configurations/general/naming/manifest.toml +17 -17
  56. package/configurations/general/naming/rules/NAMING.md +87 -67
  57. package/configurations/general/prose/manifest.toml +166 -25
  58. package/configurations/general/prose/rules/WRITING.md +6 -2
  59. package/configurations/general/repository/manifest.toml +12 -12
  60. package/configurations/general/secrets/manifest.toml +52 -73
  61. package/configurations/general/secrets/rules/SECRETS.md +3 -1
  62. package/configurations/general/security/manifest.toml +29 -52
  63. package/configurations/general/security/rules/SECURITY.md +8 -6
  64. package/configurations/general/spelling/manifest.toml +15 -25
  65. package/configurations/general/structure/manifest.toml +31 -31
  66. package/configurations/infrastructure/ansible/manifest.toml +15 -15
  67. package/configurations/infrastructure/docker/manifest.toml +55 -67
  68. package/configurations/infrastructure/docker/rules/DOCKER.md +15 -13
  69. package/configurations/infrastructure/github-actions/manifest.toml +21 -41
  70. package/configurations/infrastructure/github-actions/rules/GITHUB-ACTIONS.md +16 -12
  71. package/configurations/infrastructure/github-actions/tool-files/zizmor.yml +5 -0
  72. package/configurations/infrastructure/nginx/manifest.toml +20 -20
  73. package/configurations/infrastructure/nginx/rules/NGINX.md +5 -4
  74. package/configurations/infrastructure/openapi/manifest.toml +20 -20
  75. package/configurations/infrastructure/openapi/rules/OPENAPI.md +3 -1
  76. package/configurations/infrastructure/xcode/manifest.toml +55 -75
  77. package/configurations/infrastructure/xcode/rules/XCODE.md +5 -3
  78. package/configurations/language/bash/manifest.toml +89 -170
  79. package/configurations/language/bash/rules/BASH.md +79 -17
  80. package/configurations/language/bash/rules/LANGUAGE.md +30 -26
  81. package/configurations/language/bash/rules/OPERATIONS.md +10 -8
  82. package/configurations/language/bash/rules/SAFETY.md +39 -35
  83. package/configurations/language/css/manifest.toml +22 -61
  84. package/configurations/language/css/rules/CSS.md +21 -2
  85. package/configurations/language/css/rules/TAILWIND.md +7 -5
  86. package/configurations/language/html/manifest.toml +16 -35
  87. package/configurations/language/html/rules/HTML.md +23 -5
  88. package/configurations/language/javascript/eslint-runtime-names.json +66 -61
  89. package/configurations/language/javascript/eslint-runtime.mjs +118 -0
  90. package/configurations/language/javascript/manifest.toml +135 -207
  91. package/configurations/language/javascript/rules/BUN.md +2 -2
  92. package/configurations/language/javascript/rules/COMPONENTS.md +4 -4
  93. package/configurations/language/javascript/rules/DENO.md +1 -1
  94. package/configurations/language/javascript/rules/JAVASCRIPT.md +30 -17
  95. package/configurations/language/javascript/rules/NODE.md +2 -2
  96. package/configurations/language/javascript/rules/PLAYWRIGHT.md +10 -9
  97. package/configurations/language/markdown/manifest.toml +20 -51
  98. package/configurations/language/python/manifest.toml +231 -342
  99. package/configurations/language/python/rules/DESIGN.md +40 -33
  100. package/configurations/language/python/rules/FLOW.md +8 -6
  101. package/configurations/language/python/rules/PACKAGING.md +14 -7
  102. package/configurations/language/python/rules/PYTHON.md +83 -33
  103. package/configurations/language/python/rules/TYPING.md +25 -23
  104. package/configurations/language/sql/manifest.toml +19 -37
  105. package/configurations/language/sql/rules/SQL.md +90 -2
  106. package/configurations/language/swift/manifest.toml +67 -78
  107. package/configurations/language/swift/rules/SWIFT.md +138 -40
  108. package/configurations/language/swift/rules/SWIFTUI.md +11 -9
  109. package/configurations/language/swift/rules/UIKIT.md +21 -19
  110. package/configurations/language/typescript/manifest.toml +34 -34
  111. package/configurations/language/typescript/rules/TYPESCRIPT.md +62 -10
  112. package/configurations/library/drizzle/manifest.toml +25 -38
  113. package/configurations/library/drizzle/rules/DRIZZLE.md +4 -2
  114. package/configurations/library/react-hook-form/manifest.toml +4 -4
  115. package/configurations/library/react-hook-form/rules/REACT-HOOK-FORM.md +15 -13
  116. package/configurations/library/tanstack-query/manifest.toml +6 -6
  117. package/configurations/library/tanstack-query/rules/TANSTACK-QUERY.md +5 -3
  118. package/configurations/library/testing-library/manifest.toml +6 -6
  119. package/configurations/library/translations/manifest.toml +22 -22
  120. package/configurations/library/translations/rules/NEXT-INTL.md +6 -8
  121. package/configurations/library/translations/rules/TRANSLATIONS.md +22 -23
  122. package/configurations/library/trpc/manifest.toml +3 -3
  123. package/configurations/library/trpc/rules/TRPC.md +8 -6
  124. package/configurations/library/zod/manifest.toml +6 -6
  125. package/configurations/library/zod/rules/ZOD.md +4 -2
  126. package/configurations/library/zustand/manifest.toml +4 -4
  127. package/configurations/library/zustand/rules/ZUSTAND.md +16 -14
  128. package/configurations/platform/cloudflare/manifest.toml +28 -47
  129. package/configurations/platform/cloudflare/rules/CLOUDFLARE.md +11 -6
  130. package/configurations/platform/supabase/manifest.toml +48 -61
  131. package/configurations/platform/supabase/rules/SUPABASE.md +27 -28
  132. package/configurations/testing/jest/manifest.toml +21 -22
  133. package/configurations/testing/pytest/manifest.toml +28 -28
  134. package/configurations/testing/swift-tests/manifest.toml +18 -29
  135. package/configurations/testing/swift-tests/rules/SWIFT-TESTS.md +7 -5
  136. package/configurations/testing/vitest/manifest.toml +32 -32
  137. package/configurations/testing/vitest/rules/VITEST.md +3 -1
  138. package/dist/gspot.js +22297 -24707
  139. package/dist/{linkinator-program.js → linkinator-process.js} +5 -7
  140. package/dist/{purgecss-program.js → purgecss-process.js} +12 -12
  141. package/package.json +7 -9
  142. package/configurations/infrastructure/github-actions/zizmor.yml +0 -3
  143. package/configurations/language/bash/rules/NAMING.md +0 -62
  144. package/configurations/language/css/rules/NAMING.md +0 -17
  145. package/configurations/language/html/rules/NAMING.md +0 -16
  146. package/configurations/language/javascript/rules/NAMING.md +0 -31
  147. package/configurations/language/markdown/markdownlint-cli2.mjs +0 -19
  148. package/configurations/language/python/rules/NAMING.md +0 -53
  149. package/configurations/language/sql/rules/NAMING.md +0 -90
  150. package/configurations/language/swift/rules/NAMING.md +0 -88
  151. package/configurations/language/typescript/rules/NAMING.md +0 -73
  152. package/configurations/library/swift-snapshot-testing/manifest.toml +0 -32
  153. package/dist/THIRD-PARTY-NOTICES.md +0 -25
  154. package/dist/eslint-rule-levels.json +0 -10
  155. package/dist/tool-versions.json +0 -3
  156. package/gspot.schema.json +0 -45991
  157. /package/{dist/LICENSE.md → LICENSE.md} +0 -0
  158. /package/configurations/framework/express/{semgrep → tool-files/semgrep}/express.yml +0 -0
  159. /package/configurations/framework/fastapi/{semgrep → tool-files/semgrep}/fastapi.yml +0 -0
  160. /package/configurations/general/dependencies/{syncpack.json → tool-files/syncpack.json} +0 -0
  161. /package/configurations/general/prose/{vale → tool-files/vale}/styles/LICENSES.md +0 -0
  162. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/ampm.yml +0 -0
  163. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/conscious-language.yml +0 -0
  164. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/contractions.yml +0 -0
  165. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/currency.yml +0 -0
  166. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/dashes.yml +0 -0
  167. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/date-ordinals.yml +0 -0
  168. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/dates.yml +0 -0
  169. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/file-paths.yml +0 -0
  170. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/future.yml +0 -0
  171. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/hedging.yml +0 -0
  172. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/history.yml +0 -0
  173. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/idioms.yml +0 -0
  174. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/interface-verbs.yml +0 -0
  175. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/jargon.yml +0 -0
  176. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/leading-conjunctions.yml +0 -0
  177. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/link-text.yml +0 -0
  178. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/locations.yml +0 -0
  179. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/marketing.yml +0 -0
  180. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/merge-conflict-markers.yml +0 -0
  181. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/militaristic-language.yml +0 -0
  182. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/modals.yml +0 -0
  183. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/numbered-units.yml +0 -0
  184. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/obvious-fields.yml +0 -0
  185. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/ordinal-adverbs.yml +0 -0
  186. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/percentage-numbers.yml +0 -0
  187. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/placeholders.yml +0 -0
  188. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/product-centric-writing.yml +0 -0
  189. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/punctuated-headings.yml +0 -0
  190. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/self-reference.yml +0 -0
  191. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/session-identifiers.yml +0 -0
  192. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/since.yml +0 -0
  193. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/straight-quotes.yml +0 -0
  194. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/suspended-hyphens.yml +0 -0
  195. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/symbols.yml +0 -0
  196. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/time-ranges.yml +0 -0
  197. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/url-prepositions.yml +0 -0
  198. /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/version-range.yml +0 -0
  199. /package/configurations/general/secrets/{gitleaks.toml → tool-files/gitleaks.toml} +0 -0
  200. /package/configurations/infrastructure/docker/{trivyignore → tool-files/trivyignore} +0 -0
  201. /package/configurations/language/bash/{semgrep → tool-files/semgrep}/bash.yml +0 -0
  202. /package/configurations/language/javascript/{semgrep → tool-files/semgrep}/javascript.yml +0 -0
  203. /package/configurations/language/swift/{semgrep → tool-files/semgrep}/swift.yml +0 -0
  204. /package/configurations/platform/cloudflare/{semgrep → tool-files/semgrep}/cloudflare.yml +0 -0
  205. /package/configurations/platform/supabase/{semgrep → tool-files/semgrep}/supabase.yml +0 -0
@@ -1,39 +1,28 @@
1
1
  allowed_words = ["Vale", "DOM", "DTO", "RPC"]
2
2
 
3
3
  [configuration]
4
- title = "Prose"
5
4
  always_selected = true
6
- description = "Vale over every comment and every documentation file, with the gspot style, and the upstream packages."
5
+ description = "Runs Vale with the gspot style and upstream packages over comments and documentation files."
6
+ title = "Prose"
7
7
 
8
8
  [files]
9
9
  extensions = [".md", ".mdx", ".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", ".cjs", ".jsx", ".swift", ".css", ".sh", ".bash", ".zsh", ".py", ".sql", ".pgsql", ".psql"]
10
10
  tags = ["shebang:shell"]
11
11
 
12
12
  [[tool]]
13
- name = "vale"
14
- version = "3.21.0"
15
- mise = "vale"
16
13
  brew = "vale"
17
- winget = "errata-ai.Vale"
18
- scoop = "vale"
19
14
  github = { name = "errata-ai/vale", version = "v3.21.0" }
15
+ mise = "vale"
16
+ name = "vale"
17
+ replace = [".vale.ini", "_vale.ini", "vale.ini"]
18
+ scoop = "vale"
20
19
  suppression = { marker = "^<!--\\s*vale\\b", reason = "reason: (?<reason>\\S.*)", forbidden = true }
21
- [[tool.replace]]
22
- file = ".vale.ini"
23
- shared = false
24
-
25
- [[tool.replace]]
26
- file = "_vale.ini"
27
- shared = false
28
-
29
- [[tool.replace]]
30
- file = "vale.ini"
31
- shared = false
20
+ version = "3.21.0"
21
+ winget = "errata-ai.Vale"
32
22
 
33
23
  [[tool_file]]
34
24
  target = ".gspot/config/vale.ini"
35
25
  tool = "vale"
36
- rule_keys = ["*.rules", "*.BasedOnStyles"]
37
26
 
38
27
  [[tool_file]]
39
28
  target = ".gspot/config/vale/styles/gspot/acronyms.yml"
@@ -75,12 +64,164 @@ tool = "vale"
75
64
  target = ".gspot/config/vale/styles/config/vocabularies/words/accept.txt"
76
65
  tool = "vale"
77
66
 
78
- [[check]]
79
- name = "vale"
67
+ [[tool_file]]
68
+ target = ".gspot/config/vale/styles/LICENSES.md"
69
+ tool = "vale"
70
+
71
+ [[tool_file]]
72
+ target = ".gspot/config/vale/styles/gspot/numbered-units.yml"
73
+ tool = "vale"
74
+
75
+ [[tool_file]]
76
+ target = ".gspot/config/vale/styles/gspot/future.yml"
77
+ tool = "vale"
78
+
79
+ [[tool_file]]
80
+ target = ".gspot/config/vale/styles/gspot/modals.yml"
81
+ tool = "vale"
82
+
83
+ [[tool_file]]
84
+ target = ".gspot/config/vale/styles/gspot/product-centric-writing.yml"
85
+ tool = "vale"
86
+
87
+ [[tool_file]]
88
+ target = ".gspot/config/vale/styles/gspot/contractions.yml"
89
+ tool = "vale"
90
+
91
+ [[tool_file]]
92
+ target = ".gspot/config/vale/styles/gspot/dates.yml"
93
+ tool = "vale"
94
+
95
+ [[tool_file]]
96
+ target = ".gspot/config/vale/styles/gspot/hedging.yml"
97
+ tool = "vale"
98
+
99
+ [[tool_file]]
100
+ target = ".gspot/config/vale/styles/gspot/since.yml"
101
+ tool = "vale"
102
+
103
+ [[tool_file]]
104
+ target = ".gspot/config/vale/styles/gspot/leading-conjunctions.yml"
105
+ tool = "vale"
106
+
107
+ [[tool_file]]
108
+ target = ".gspot/config/vale/styles/gspot/date-ordinals.yml"
109
+ tool = "vale"
110
+
111
+ [[tool_file]]
112
+ target = ".gspot/config/vale/styles/gspot/suspended-hyphens.yml"
113
+ tool = "vale"
114
+
115
+ [[tool_file]]
116
+ target = ".gspot/config/vale/styles/gspot/link-text.yml"
117
+ tool = "vale"
118
+
119
+ [[tool_file]]
120
+ target = ".gspot/config/vale/styles/gspot/locations.yml"
121
+ tool = "vale"
122
+
123
+ [[tool_file]]
124
+ target = ".gspot/config/vale/styles/gspot/obvious-fields.yml"
125
+ tool = "vale"
126
+
127
+ [[tool_file]]
128
+ target = ".gspot/config/vale/styles/gspot/symbols.yml"
129
+ tool = "vale"
130
+
131
+ [[tool_file]]
132
+ target = ".gspot/config/vale/styles/gspot/merge-conflict-markers.yml"
133
+ tool = "vale"
134
+
135
+ [[tool_file]]
136
+ target = ".gspot/config/vale/styles/gspot/percentage-numbers.yml"
137
+ tool = "vale"
138
+
139
+ [[tool_file]]
140
+ target = ".gspot/config/vale/styles/gspot/militaristic-language.yml"
141
+ tool = "vale"
142
+
143
+ [[tool_file]]
144
+ target = ".gspot/config/vale/styles/gspot/currency.yml"
145
+ tool = "vale"
146
+
147
+ [[tool_file]]
148
+ target = ".gspot/config/vale/styles/gspot/marketing.yml"
149
+ tool = "vale"
150
+
151
+ [[tool_file]]
152
+ target = ".gspot/config/vale/styles/gspot/straight-quotes.yml"
153
+ tool = "vale"
154
+
155
+ [[tool_file]]
156
+ target = ".gspot/config/vale/styles/gspot/placeholders.yml"
157
+ tool = "vale"
158
+
159
+ [[tool_file]]
160
+ target = ".gspot/config/vale/styles/gspot/history.yml"
161
+ tool = "vale"
162
+
163
+ [[tool_file]]
164
+ target = ".gspot/config/vale/styles/gspot/dashes.yml"
165
+ tool = "vale"
166
+
167
+ [[tool_file]]
168
+ target = ".gspot/config/vale/styles/gspot/ordinal-adverbs.yml"
169
+ tool = "vale"
170
+
171
+ [[tool_file]]
172
+ target = ".gspot/config/vale/styles/gspot/interface-verbs.yml"
173
+ tool = "vale"
174
+
175
+ [[tool_file]]
176
+ target = ".gspot/config/vale/styles/gspot/punctuated-headings.yml"
177
+ tool = "vale"
178
+
179
+ [[tool_file]]
180
+ target = ".gspot/config/vale/styles/gspot/file-paths.yml"
181
+ tool = "vale"
182
+
183
+ [[tool_file]]
184
+ target = ".gspot/config/vale/styles/gspot/self-reference.yml"
185
+ tool = "vale"
186
+
187
+ [[tool_file]]
188
+ target = ".gspot/config/vale/styles/gspot/jargon.yml"
189
+ tool = "vale"
190
+
191
+ [[tool_file]]
192
+ target = ".gspot/config/vale/styles/gspot/session-identifiers.yml"
193
+ tool = "vale"
194
+
195
+ [[tool_file]]
196
+ target = ".gspot/config/vale/styles/gspot/url-prepositions.yml"
197
+ tool = "vale"
198
+
199
+ [[tool_file]]
200
+ target = ".gspot/config/vale/styles/gspot/version-range.yml"
80
201
  tool = "vale"
81
- example = "The sentence `Release on 03/04/2026.` reports an ambiguous date at the recommended level. Write `Release on March 4, 2026.` when March 4 is the intended date, then rerun. Write legitimate project names in the root allowed_words setting."
202
+
203
+ [[tool_file]]
204
+ target = ".gspot/config/vale/styles/gspot/ampm.yml"
205
+ tool = "vale"
206
+
207
+ [[tool_file]]
208
+ target = ".gspot/config/vale/styles/gspot/time-ranges.yml"
209
+ tool = "vale"
210
+
211
+ [[tool_file]]
212
+ target = ".gspot/config/vale/styles/gspot/conscious-language.yml"
213
+ tool = "vale"
214
+
215
+ [[tool_file]]
216
+ target = ".gspot/config/vale/styles/gspot/idioms.yml"
217
+ tool = "vale"
218
+
219
+ [[check]]
220
+ example = "`Release on 03/04/2026.` reports an ambiguous date. Write `Release on March 4, 2026.` instead."
221
+ help = "Rewrite the sentence the alert names, add a real name and its reason to the root allowed_words setting, or use `gspot ignore prose/vale --rule <rule> --reason \"<why>\"`."
82
222
  level = "recommended"
223
+ name = "vale"
83
224
  stage = "commit"
84
- summary = "Checks ambiguous dates, link text, and alternative text with bundled Vale styles at level `recommended`. Level `all` adds the complete style and upstream packages."
85
- why = "Prose that hedges, markets or wanders is read by everyone who reads the code, and nothing else checks it."
86
- help = "Rewrite the sentence the alert names, write a real name and its reason in the root allowed_words setting, or use gspot ignore prose/vale --rule `<rule>` --reason \"`<why>`\"."
225
+ summary = "Checks ambiguous dates, link text, and alternative text with the shipped Vale styles at level `recommended`. Level `all` adds the complete style and upstream packages."
226
+ tool = "vale"
227
+ why = "Hedging, marketing, or wandering prose reaches everyone who opens the code, and no other check catches it."
@@ -1,7 +1,11 @@
1
1
  # Writing
2
2
 
3
+ Read this rule when you write text that people read in files: documentation, comments, messages, and commit messages.
4
+
5
+ TALKING.md covers what you say to the user.
6
+
3
7
  Write in plain language under `ISO 24495-1`: short sentences and common words. State the action or result early.
4
- Use familiar words and explain a technical term when the reader needs it.
8
+ Explain a technical term when the reader needs it.
5
9
 
6
10
  ## Evidence
7
11
 
@@ -10,7 +14,7 @@ A measurement does not guarantee future results. When evidence lacks required fa
10
14
  facts to the primary source; never invent behavior to complete a page.
11
15
 
12
16
  Preserve exact API identifiers, public messages, official product names, and legal license text.
13
- Keep private reasoning, temporary acceptance notes out of shipped content.
17
+ Keep private reasoning and temporary notes out of shipped content.
14
18
  Examples use fictional people, safe values, and `example.com` addresses.
15
19
 
16
20
  ## Voice
@@ -1,24 +1,24 @@
1
1
  [configuration]
2
- title = "Repository"
3
2
  always_selected = true
4
3
  description = "Checks the files that Git tracks and their storage."
4
+ title = "Repository"
5
5
 
6
6
  [[check]]
7
- name = "large-files"
8
- example = "A tracked `notes/big.txt` containing 1,100 KiB exceeds the default 1,024 KiB ceiling and reports `size`. Remove accidental content or store a required large file through Git LFS. Generated and vendored classifications must describe the actual file ownership."
7
+ example = "A tracked `notes/big.txt` of 1,100 KiB, over the default limit of 1,024, reports `size`. Delete the file, or store it through Git LFS."
8
+ help = "Track the file with Git LFS, classify it as generated or vendored in .gitattributes, or raise repository.max_file_kilobytes with a reason."
9
9
  level = "recommended"
10
- stage = "commit"
10
+ name = "large-files"
11
11
  runs = "once"
12
- summary = "Checks that every tracked file over the size limit is stored through LFS or declared with a reason."
13
- why = "A large file in plain git history stays in every clone for good."
14
- help = "Track the file with git lfs, classify it with gspot set generated `<path>` or gspot set vendored `<path>`, or raise limits.file_kb with a reason."
12
+ stage = "commit"
13
+ summary = "Checks that each tracked file over the size limit goes through Git LFS or has a reason."
14
+ why = "A large file in plain Git history stays in every clone forever."
15
15
 
16
16
  [[check]]
17
- name = "tracked-files"
18
- example = "A tracked .env or node_modules/example/index.js reports tracked-file. Add its path to .gitignore and run git rm --cached on that file, preserving its local contents."
17
+ example = "A tracked `.env` reports `tracked-file`. Add the path to `.gitignore`, then run `git rm --cached .env`, which keeps the file on disk."
18
+ help = "Add the reported file or folder to .gitignore and remove it from the index with `git rm --cached`."
19
19
  level = "recommended"
20
- stage = "commit"
20
+ name = "local-files"
21
21
  runs = "once"
22
- summary = "Checks tracked files against the paths that selected configurations declare untracked."
22
+ stage = "commit"
23
+ summary = "Reports a tracked file at a path that a configuration keeps out of Git."
23
24
  why = "Machine-local values and installed packages belong outside shared Git history."
24
- help = "Add the reported file or folder to .gitignore and remove it from the index with git rm --cached."
@@ -1,125 +1,104 @@
1
-
2
1
  [configuration]
3
- title = "Secrets"
4
2
  always_selected = true
5
3
  description = "Checks environment files and examples, scans staged changes and pushed commits for secrets, and requires reasons for allowed values."
4
+ title = "Secrets"
6
5
 
7
6
  [files]
8
- paths = ["**"]
9
7
  kinds = ["source", "generated", "vendored", "binary"]
8
+ paths = ["**"]
10
9
 
11
10
  [[tool]]
12
- name = "gitleaks"
13
- version = "8.30.1"
14
- min_version = "8.25.0"
15
- mise = "gitleaks"
16
11
  brew = "gitleaks"
17
12
  github = { name = "gitleaks/gitleaks", version = "v8.30.1" }
18
- winget = "Gitleaks.Gitleaks"
13
+ min_version = "8.25.0"
14
+ mise = "gitleaks"
15
+ name = "gitleaks"
16
+ replace = [".gitleaks.toml", "gitleaks.toml"]
19
17
  scoop = "gitleaks"
18
+ version = "8.30.1"
20
19
  version_command = ["version"]
21
- [[tool.replace]]
22
- file = ".gitleaks.toml"
23
- shared = false
24
-
25
- [[tool.replace]]
26
- file = "gitleaks.toml"
27
- shared = false
20
+ winget = "Gitleaks.Gitleaks"
28
21
 
29
22
  [[tool]]
30
- name = "trufflehog"
31
- crash_pattern = '"level"\s*:\s*"error"'
32
- version = "3.97.5"
33
- mise = "trufflehog"
34
23
  brew = "trufflehog"
24
+ crash_pattern = '"level"\s*:\s*"error"'
35
25
  github = { name = "trufflesecurity/trufflehog", version = "v3.97.5" }
26
+ mise = "trufflehog"
27
+ name = "trufflehog"
28
+ version = "3.97.5"
36
29
 
37
30
  [[tool]]
38
- name = "dotenv-linter"
39
- version = "4.0.0"
40
- mise = "github:dotenv-linter/dotenv-linter"
41
31
  brew = "dotenv-linter"
42
32
  cargo = "dotenv-linter"
43
33
  github = { name = "dotenv-linter/dotenv-linter", version = "v4.0.0" }
34
+ mise = "github:dotenv-linter/dotenv-linter"
35
+ name = "dotenv-linter"
36
+ version = "4.0.0"
44
37
 
45
38
  [[tool_file]]
46
- source = "gitleaks.toml"
47
39
  target = ".gspot/config/gitleaks.toml"
48
40
  tool = "gitleaks"
49
41
 
50
42
  [[check]]
51
- name = "gitleaks-staged"
52
- example = "A staged credential reports a secret finding. Remove the credential from source, load it from the configured environment owner, and stage the fix. If the credential has been exposed, rotate it at its provider."
53
- level = "recommended"
54
- stage = "commit"
55
- runs = "once"
56
- when = { git = true }
57
43
  command = ["gitleaks", "git", "--staged", "--no-banner", "--redact", "--exit-code", "1", "--config", "{tool_file:gitleaks}", "--report-format", "json", "--report-path", "-", "{root}"]
44
+ example = "A staged credential reports a finding. Load it from an environment variable instead, and rotate it if it already leaked."
45
+ help = "Remove the value and load it from the environment. For a reviewed public value, use `gspot ignore` with its reported fingerprint and a reason."
46
+ level = "recommended"
47
+ name = "gitleaks-staged"
58
48
  output = { format = "json", fields = { file = "File", line = "StartLine", column = "StartColumn", rule = "Fingerprint", message = "Description" } }
49
+ runs = "once"
50
+ stage = "commit"
59
51
  summary = "Scans the staged change for keys, tokens, and passwords before the commit exists."
60
- why = "A secret that reaches a commit stays in history after the line is deleted, and every clone holds it."
61
- help = "Remove the value and load it from the environment. For a reviewed public value, use gspot ignore with its reported fingerprint and a reason."
52
+ when = { git = true }
53
+ why = "A secret that reaches a commit stays in history after you delete the line, and every clone holds it."
62
54
 
63
55
  [[check]]
64
- name = "gitleaks-pushed"
65
- example = "A credential in an earlier commit still reports after it is deleted from the working tree. Rotate the credential and remove it from the affected history, coordinating any rewrite of shared commits. Rerun the history scan."
56
+ example = "A credential in an earlier commit still reports after you delete it from the working tree. Rotate it, then remove it from history, and coordinate any rewrite of shared commits."
57
+ help = "Rewrite the commit that holds the value and rotate the secret. For a reviewed historical example, use `gspot ignore secrets/gitleaks-pushed --rule <fingerprint> --reason \"...\"`."
66
58
  level = "recommended"
67
- stage = "push"
68
- runs = "history"
69
- when = { git = true }
70
- tool = "gitleaks"
59
+ name = "gitleaks-pushed"
71
60
  output = { format = "json", file_type = "history", fields = { file = "File", line = "StartLine", column = "StartColumn", rule = "Fingerprint", message = "Description" } }
61
+ runs = "history"
62
+ stage = "push"
72
63
  summary = "Scans every commit about to be pushed for keys, tokens, and passwords."
64
+ tool = "gitleaks"
65
+ when = { git = true }
73
66
  why = "A commit made past the hook still reaches the shared branch unless the push checks it."
74
- help = "Rewrite the commit that holds the value and rotate the secret. For a reviewed historical example, use gspot ignore secrets/gitleaks-pushed --rule `<fingerprint>` --reason \"...\"."
75
-
76
- [[check]]
77
- name = "gitleaks-files"
78
- example = "In a folder with no git, a credential in a source file reports a secret finding. Remove the credential from source and load it from the configured environment owner. If the credential has been exposed, rotate it at its provider."
79
- level = "recommended"
80
- stage = "commit"
81
- runs = "once"
82
- when = { git = false }
83
- command = ["gitleaks", "dir", "--no-banner", "--redact", "--exit-code", "1", "--config", "{tool_file:gitleaks}", "--report-format", "json", "--report-path", "-", "."]
84
- output = { format = "json", fields = { file = "File", line = "StartLine", column = "StartColumn", rule = "Fingerprint", message = "Description" } }
85
- summary = "Scans every file of a folder that has no git for keys, tokens, and passwords."
86
- why = "Without git there is no staged change to scan, so the files themselves are the only place a secret can be caught."
87
- help = "Remove the value and load it from the environment. For a reviewed public value, use gspot ignore with its reported fingerprint and a reason."
88
67
 
89
68
  [[check]]
90
- name = "trufflehog"
91
- example = "A committed credential that its provider confirms as active reports a verified secret. Revoke or rotate it at the provider and remove it from the affected history."
69
+ example = "A committed credential that its provider confirms as active reports a verified secret. Rotate it at the provider, and remove it from history."
70
+ exit_codes = [183]
71
+ help = "Rotate the secret at its provider, then rewrite the commit that holds it."
92
72
  level = "recommended"
93
- stage = "push"
94
- runs = "history"
73
+ name = "trufflehog-pushed"
95
74
  needs = ["network"]
96
- when = { git = true }
97
- tool = "trufflehog"
98
- exit_codes = [183]
99
75
  output = { format = "trufflehog", file_type = "history" }
76
+ runs = "history"
77
+ stage = "push"
100
78
  summary = "Verifies candidate secrets in the pushed commits against the service that issued them."
101
- why = "A verified secret is live right now, which makes it the finding to act on first."
102
- help = "Rotate the secret at its provider, then rewrite the commit that holds it."
79
+ tool = "trufflehog"
80
+ when = { git = true }
81
+ why = "A verified secret still works, so fix that finding first."
103
82
 
104
83
  [[check]]
105
- name = "dotenv-linter"
106
- example = "A dotenv file defining the same key twice reports a duplicate entry. Keep the intended assignment and remove the duplicate, preserving secret values outside version control."
107
- level = "recommended"
108
- stage = "commit"
109
84
  command = ["dotenv-linter", "check", "--plain", "--skip-updates", "{files}"]
110
- fix = ["dotenv-linter", "fix", "--plain", "--no-backup", "{files}"]
85
+ example = "A dotenv file that defines one key twice reports a duplicate. Keep one line, and delete the other."
111
86
  files = { filenames = [".env", ".dev.vars"], paths = [".env.*", "**/.env.*", ".dev.vars.*", "**/.dev.vars.*"] }
87
+ fix = ["dotenv-linter", "fix", "--plain", "--no-backup", "{files}"]
88
+ help = "Run `gspot check --fix`, or fix the line dotenv-linter names."
89
+ level = "recommended"
90
+ name = "dotenv-linter"
112
91
  output = { format = "regex", pattern = "^(?<file>[^:]+):(?<line>\\d+) (?<rule>[A-Za-z]+): (?<message>.*)$" }
92
+ stage = "commit"
113
93
  summary = "Checks every tracked environment file: key format, duplicates, quoting, ordering, and trailing spaces."
114
- why = "A tracked environment file is a template other people copy; a malformed line there is copied into every machine."
115
- help = "Run gspot check --fix, or fix the line dotenv-linter names."
94
+ why = "Other people copy a tracked environment file, so a malformed line in it spreads to every machine."
116
95
 
117
96
  [[check]]
118
- name = "env-examples"
119
- example = "Source code reading `API_URL` while the example environment file omits that key reports a missing example entry. Add `API_URL=` to `.env.example` and document the required value without committing credentials."
97
+ example = "Code that reads `API_URL` while `.env.example` lacks that key reports a finding. Add `API_URL=` to `.env.example` with a note on the value, and no credential."
98
+ help = "Add the key to `.env.example` or a file under `secrets.env_examples`, or stop reading it."
120
99
  level = "recommended"
121
- stage = "push"
100
+ name = "env-examples"
122
101
  runs = "scope"
123
- summary = "When an example environment file exists, checks static uppercase keys read through process.env, import.meta.env, Bun.env, Deno.env.get, Python os APIs, and declared reader functions in JavaScript, TypeScript, Python, and component files."
124
- why = "A variable missing from the example file is the one a new machine lacks on its first run."
125
- help = "Add the key to the example file (.env.example or the files under secrets.env_examples), or stop reading it."
102
+ stage = "push"
103
+ summary = "Checks that an existing env example lists each static uppercase key that code reads through process.env, import.meta.env, Bun.env, Deno.env.get, the Python os module, or an environment function."
104
+ why = "A variable missing from the env example breaks the first run on a new machine."
@@ -1,5 +1,7 @@
1
1
  # Secrets
2
2
 
3
+ Read this rule when code reads, stores, or logs a secret.
4
+
3
5
  - Never hardcode API keys, tokens, passwords, or secrets anywhere in the codebase.
4
6
  - Read secrets from the environment or a secret store in one configuration module. A secret has
5
7
  no fallback or default value.
@@ -7,7 +9,7 @@
7
9
  - Builds copy public build-time variables such as `NEXT_PUBLIC_*` and `VITE_*` into the bundle. They hold
8
10
  nothing secret.
9
11
  - Examples, documentation, templates, and sample files hold placeholders, never real secrets.
10
- - Keep actual local overrides in an ignored file.
12
+ - Keep local overrides in an ignored file.
11
13
  - Never log secrets, tokens, passwords, cookies, authorization headers, or connection strings.
12
14
  - A published package lists its files explicitly; an ignored file can still leak through the
13
15
  defaults of a packaging tool.
@@ -1,77 +1,54 @@
1
- allowed_words = ["Semgrep", "CodeQL"]
1
+ allowed_words = ["Semgrep"]
2
+
2
3
  [configuration]
3
- title = "Security"
4
4
  always_selected = true
5
- description = "Static analysis for security patterns with Semgrep over every file a selected language claims, and CodeQL for configured project languages."
5
+ description = "Runs Semgrep security rules over every file a language configuration claims."
6
+ title = "Security"
6
7
 
7
8
  [files]
8
- languages = true
9
9
  extensions = [".plist"]
10
+ languages = true
10
11
 
11
12
  [[tool]]
13
+ brew = "semgrep"
14
+ builds = ["macos", "linux"]
15
+ min_version = "1.100.0"
16
+ mise = "pipx:semgrep"
12
17
  name = "semgrep"
13
- version_command = ["--disable-version-check", "--version"]
18
+ pypi = "semgrep"
19
+ replace = [".semgrepignore"]
14
20
  suppression = { marker = "\\bnosemgrep\\b", reason = "reason: (?<reason>\\S.*)", forbidden = true }
15
21
  version = "1.178.0"
16
- min_version = "1.100.0"
17
- pypi = "semgrep"
18
- mise = "pipx:semgrep"
19
- brew = "semgrep"
20
- builds = ["macos", "linux"]
21
- [[tool.replace]]
22
- file = ".semgrepignore"
23
- shared = false
24
-
25
- [[tool]]
26
- name = "codeql"
27
- version = "2.24.3"
28
- brew = "codeql"
29
- github = { name = "github/codeql-cli-binaries", version = "v2.24.3" }
30
- # The CLI ships for x64 Linux only; its bundled Java does not run on arm64.
31
- builds = ["macos", "linux-x64", "windows"]
32
- # Query versions paired with github/codeql tag codeql-cli/v2.24.3.
33
- query_packs = { actions = "0.6.21", cpp = "1.5.12", csharp = "1.6.3", go = "1.5.7", java = "1.10.8", javascript = "2.3.3", python = "1.7.8", ruby = "1.5.8", rust = "0.1.28", swift = "1.2.17" }
22
+ version_command = ["--disable-version-check", "--version"]
34
23
 
35
24
  [[tool_file]]
25
+ per_scope = true
36
26
  target = ".semgrepignore"
37
27
  tool = "semgrep"
38
- per_scope = true
39
28
 
40
29
  [[check]]
41
- name = "semgrep"
42
- example = "Code matching a selected local Semgrep rule reports that rule ID and source location. For a rule banning dynamic evaluation, replace `eval(userInput)` with explicit parsing and permitted operations, then rerun the same rule set."
43
- level = "recommended"
44
- stage = "push"
45
- exit_codes = [1, 3]
46
30
  command = ["semgrep", "scan", "--strict", "--error", "--metrics", "off", "--disable-version-check", "--no-rewrite-rule-ids", "--quiet", "--json", "{files}"]
31
+ example = "`eval(userInput)` matches a rule against dynamic evaluation and reports its ID and location. Parse the input instead, and allow only known operations."
32
+ exit_codes = [1, 3]
33
+ help = "Change the code the way the message says. Turn one rule off for a path with `gspot ignore security/semgrep --rule <id> --paths <glob> --reason \"<why>\"`."
34
+ level = "recommended"
35
+ name = "semgrep"
47
36
  output = { format = "semgrep" }
48
- summary = "Runs the Semgrep rule packs of the selected configurations, and the repository's own rules, over the changed files."
37
+ stage = "push"
38
+ summary = "Runs the Semgrep packs of each configuration, and the repository rules, over changed files."
49
39
  why = "An injection or a logged secret reads like ordinary code, and a pattern rule finds it before a reviewer has to."
50
- help = "Change the code the way the message says. Turn one rule off for a path with gspot ignore security/semgrep --rule `<id>` --paths `<glob>` --reason \"`<why>`\"."
51
40
 
52
41
  [[check]]
53
- name = "semgrep-registry"
54
- example = "Code matching a configured Semgrep registry rule reports its upstream rule ID. Correct the operation identified by that rule and rerun with network access. The configured rule set determines which patterns are findings."
55
- level = "recommended"
56
- stage = "manual"
42
+ command = ["semgrep", "scan", "--strict", "{each:--config:tools.semgrep.registry_packs}", "--error", "--metrics", "off", "--disable-version-check", "--quiet", "--json", "{files}"]
43
+ example = "Code that matches a registry rule reports its upstream ID. Fix the code at that location, then rerun with network access."
57
44
  exit_codes = [1, 3]
45
+ help = "Change the code the way the message says, or turn the rule off for a path with `gspot ignore security/semgrep-registry --rule <id> --reason \"<why>\"`."
46
+ level = "recommended"
47
+ name = "semgrep-registry"
58
48
  needs = ["network"]
59
- when = { setting = "tools.semgrep.registry_packs" }
60
- command = ["semgrep", "scan", "--strict", "{each:--config:tools.semgrep.registry_packs}", "--error", "--metrics", "off", "--disable-version-check", "--quiet", "--json", "{files}"]
61
- tool = "semgrep"
62
49
  output = { format = "semgrep" }
63
- summary = "Runs the public Semgrep registry packs named in tools.semgrep.registry_packs, which the registry serves over the network."
64
- why = "The registry packs cover the common vulnerability classes, and their license keeps them out of this package."
65
- help = "Change the code the way the message says, or turn the rule off for a path with gspot ignore security/semgrep-registry --rule `<id>` --reason \"`<why>`\"."
66
-
67
- [[check]]
68
- name = "codeql"
69
- example = "A query constructed by concatenating request input into SQL reports a SQL-injection finding when the selected language query pack detects the flow. Use a parameterized database query and rerun with the language build prerequisites satisfied."
70
- level = "recommended"
71
50
  stage = "manual"
72
- runs = "once"
73
- tool = "codeql"
74
- when = { setting = "tools.codeql.languages" }
75
- summary = "Builds a CodeQL database for every language in tools.codeql.languages and runs the security suite over it."
76
- why = "Data-flow analysis follows a value from a request to a query across files, which a pattern rule cannot."
77
- help = "Change the code the result names. Record a false positive with gspot ignore security/codeql --rule `<id>` --paths `<glob>` --reason \"`<why>`\"."
51
+ summary = "Downloads and runs the public Semgrep packs in `tools.semgrep.registry_packs`."
52
+ tool = "semgrep"
53
+ when = { setting = "tools.semgrep.registry_packs" }
54
+ why = "The registry packs cover the common vulnerability classes, and their license keeps them out of this package."
@@ -1,11 +1,13 @@
1
1
  # Security
2
2
 
3
+ Read this rule when code handles input, authentication, redirects, or downloads.
4
+
3
5
  ## Input
4
6
 
5
7
  - Validate every value that enters from outside the program before use: request bodies, query strings,
6
8
  path parameters, headers, cookies, environment, files, provider responses, queue messages,
7
- command-line arguments. A type annotation does not validate input.
8
- - Bound every input: size, length, count, depth, rate.
9
+ and command-line arguments. A type annotation does not validate input.
10
+ - Bound every input: size, length, count, depth, and rate.
9
11
  - Reject unknown fields in request bodies that create or change data.
10
12
 
11
13
  ## Never build code or paths from input
@@ -33,17 +35,17 @@
33
35
  ## Authentication and authorization
34
36
 
35
37
  - Identity comes from a verified server-side session or token. A client-supplied user ID, role,
36
- or tenant provides data, never authority.
38
+ or tenant counts as data, never authority.
37
39
  - Authorize every operation that reads or changes data, through each HTTP, RPC, job,
38
40
  and webhook entry point. Recheck access to the resource even when a parent already checked it.
39
41
  - Compare secrets, signatures, and tokens in constant time.
40
- - Generate tokens, nonces, and reset codes with the platform's cryptographic random source.
42
+ - Generate tokens, nonces, and reset codes with the system's cryptographic random source.
41
43
  - Hash passwords with a current, slow, salted algorithm through a maintained library. Use one
42
44
  failure message for unknown user and wrong password.
43
45
  - Verify webhook signatures against the raw body before decoding, and handle replay with an
44
46
  idempotency key.
45
- - Cookies that carry sessions: `HttpOnly`, `Secure`, `SameSite`, explicit `Max-Age`, non-default
46
- name. Writes never happen on `GET`. A cookie session needs CSRF protection on every
47
+ - Cookies that carry sessions: `HttpOnly`, `Secure`, `SameSite`, explicit `Max-Age`, and a
48
+ non-default name. Writes never happen on `GET`. A cookie session needs cross-site request forgery (CSRF) protection on every
47
49
  state-changing request.
48
50
 
49
51
  ## Builds