@aarock1234/slopscan 0.1.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 (195) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +143 -0
  3. package/SKILL.md +149 -0
  4. package/dist/analyzer.d.ts +5 -0
  5. package/dist/analyzer.js +13 -0
  6. package/dist/analyzer.js.map +1 -0
  7. package/dist/analyzers/ast.d.ts +12 -0
  8. package/dist/analyzers/ast.js +73 -0
  9. package/dist/analyzers/ast.js.map +1 -0
  10. package/dist/analyzers/judge-chunks.d.ts +13 -0
  11. package/dist/analyzers/judge-chunks.js +87 -0
  12. package/dist/analyzers/judge-chunks.js.map +1 -0
  13. package/dist/analyzers/judge-validate.d.ts +19 -0
  14. package/dist/analyzers/judge-validate.js +81 -0
  15. package/dist/analyzers/judge-validate.js.map +1 -0
  16. package/dist/analyzers/judge.d.ts +44 -0
  17. package/dist/analyzers/judge.js +177 -0
  18. package/dist/analyzers/judge.js.map +1 -0
  19. package/dist/change.d.ts +19 -0
  20. package/dist/change.js +87 -0
  21. package/dist/change.js.map +1 -0
  22. package/dist/cli.d.ts +2 -0
  23. package/dist/cli.js +125 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/config.d.ts +91 -0
  26. package/dist/config.js +61 -0
  27. package/dist/config.js.map +1 -0
  28. package/dist/confirm.d.ts +11 -0
  29. package/dist/confirm.js +100 -0
  30. package/dist/confirm.js.map +1 -0
  31. package/dist/finding.d.ts +13 -0
  32. package/dist/finding.js +18 -0
  33. package/dist/finding.js.map +1 -0
  34. package/dist/lang.d.ts +16 -0
  35. package/dist/lang.js +37 -0
  36. package/dist/lang.js.map +1 -0
  37. package/dist/model.d.ts +2 -0
  38. package/dist/model.js +34 -0
  39. package/dist/model.js.map +1 -0
  40. package/dist/report.d.ts +124 -0
  41. package/dist/report.js +112 -0
  42. package/dist/report.js.map +1 -0
  43. package/dist/rule.d.ts +66 -0
  44. package/dist/rule.js +259 -0
  45. package/dist/rule.js.map +1 -0
  46. package/dist/scan.d.ts +14 -0
  47. package/dist/scan.js +33 -0
  48. package/dist/scan.js.map +1 -0
  49. package/dist/score.d.ts +147 -0
  50. package/dist/score.js +142 -0
  51. package/dist/score.js.map +1 -0
  52. package/dist/shared/concurrency.d.ts +5 -0
  53. package/dist/shared/concurrency.js +17 -0
  54. package/dist/shared/concurrency.js.map +1 -0
  55. package/dist/shared/env.d.ts +27 -0
  56. package/dist/shared/env.js +29 -0
  57. package/dist/shared/env.js.map +1 -0
  58. package/dist/shared/errors.d.ts +18 -0
  59. package/dist/shared/errors.js +26 -0
  60. package/dist/shared/errors.js.map +1 -0
  61. package/dist/shared/log.d.ts +2 -0
  62. package/dist/shared/log.js +18 -0
  63. package/dist/shared/log.js.map +1 -0
  64. package/dist/shared/paths.d.ts +3 -0
  65. package/dist/shared/paths.js +6 -0
  66. package/dist/shared/paths.js.map +1 -0
  67. package/dist/shared/prompts.d.ts +3 -0
  68. package/dist/shared/prompts.js +34 -0
  69. package/dist/shared/prompts.js.map +1 -0
  70. package/package.json +79 -0
  71. package/prompts/judge.md +37 -0
  72. package/rules/any/futureproof/abstraction/pass-through-wrapper.md +70 -0
  73. package/rules/any/futureproof/abstraction/single-caller-helper.md +38 -0
  74. package/rules/any/futureproof/abstraction/single-impl-interface.md +83 -0
  75. package/rules/any/futureproof/exports/dead-export.md +62 -0
  76. package/rules/any/futureproof/layering/framework-type-in-domain.md +83 -0
  77. package/rules/any/futureproof/layering/logic-in-handler.md +94 -0
  78. package/rules/any/futureproof/params/boolean-positional-param.md +128 -0
  79. package/rules/any/futureproof/params/positional-config-args.md +135 -0
  80. package/rules/any/futureproof/structure/wide-function.md +138 -0
  81. package/rules/any/futureproof/testing/test-asserts-implementation.md +70 -0
  82. package/rules/any/hacky/comments/comment-restates-code.md +50 -0
  83. package/rules/any/hacky/comments/shipped-todo-comment.md +55 -0
  84. package/rules/any/hacky/concurrency/sleep-based-sync.md +95 -0
  85. package/rules/any/hacky/config/hardcoded-url.md +88 -0
  86. package/rules/any/hacky/constants/magic-number.md +94 -0
  87. package/rules/any/hacky/debugging/debug-print.md +73 -0
  88. package/rules/any/hacky/duplication/copy-paste-block.md +117 -0
  89. package/rules/any/hacky/types/stringly-typed-enum.md +86 -0
  90. package/rules/any/idiom/comments/no-section-banners.md +47 -0
  91. package/rules/go/futureproof/constants/string-enums-when-serialized.md +47 -0
  92. package/rules/go/futureproof/constants/typed-constants-for-enums.md +45 -0
  93. package/rules/go/futureproof/interfaces/compile-time-impl-assertion.md +43 -0
  94. package/rules/go/futureproof/interfaces/define-interfaces-at-consumer.md +47 -0
  95. package/rules/go/futureproof/interfaces/keep-interfaces-small.md +53 -0
  96. package/rules/go/futureproof/naming/no-utils-helpers-common-package.md +34 -0
  97. package/rules/go/futureproof/structs/zero-value-usable.md +50 -0
  98. package/rules/go/futureproof/types/generics-over-any.md +55 -0
  99. package/rules/go/hacky/concurrency/no-goroutine-without-wait.md +44 -0
  100. package/rules/go/hacky/context/never-pass-nil-context.md +64 -0
  101. package/rules/go/hacky/context/no-context-in-struct.md +44 -0
  102. package/rules/go/hacky/errors/check-close-error-on-writable.md +53 -0
  103. package/rules/go/hacky/errors/custom-error-type-errors-as.md +54 -0
  104. package/rules/go/hacky/errors/ignored-error-blank.md +84 -0
  105. package/rules/go/hacky/errors/panic-only-unrecoverable.md +77 -0
  106. package/rules/go/hacky/errors/sentinel-errors-with-errors-is.md +63 -0
  107. package/rules/go/hacky/errors/wrap-errors-with-w.md +71 -0
  108. package/rules/go/hacky/state/package-level-mutable-var.md +95 -0
  109. package/rules/go/hacky/structure/os-exit-only-in-main.md +61 -0
  110. package/rules/go/hacky/type-safety/no-map-string-any.md +49 -0
  111. package/rules/go/hacky/types/json-into-struct-not-map.md +48 -0
  112. package/rules/go/hacky/types/no-any.md +71 -0
  113. package/rules/go/hacky/types/no-map-any-any.md +35 -0
  114. package/rules/go/idiom/comments/doc-comment-on-exported.md +81 -0
  115. package/rules/go/idiom/comments/doc-comment-starts-with-name.md +36 -0
  116. package/rules/go/idiom/concurrency/mutex-over-channels-for-state.md +47 -0
  117. package/rules/go/idiom/constructors/constructor-named-new.md +37 -0
  118. package/rules/go/idiom/context/context-is-first-param.md +47 -0
  119. package/rules/go/idiom/context/io-takes-context.md +50 -0
  120. package/rules/go/idiom/errors/capitalized-error-message.md +52 -0
  121. package/rules/go/idiom/errors/check-error-immediately.md +45 -0
  122. package/rules/go/idiom/errors/defer-close-explicit-discard.md +65 -0
  123. package/rules/go/idiom/errors/error-is-last-return-value.md +53 -0
  124. package/rules/go/idiom/errors/no-log-and-return.md +45 -0
  125. package/rules/go/idiom/formatting/blank-line-before-return.md +48 -0
  126. package/rules/go/idiom/formatting/multiline-struct-literals.md +56 -0
  127. package/rules/go/idiom/imports/import-order-groups.md +42 -0
  128. package/rules/go/idiom/imports/side-effect-imports-own-group.md +51 -0
  129. package/rules/go/idiom/interfaces/accept-interfaces-return-concrete.md +39 -0
  130. package/rules/go/idiom/iterators/prefer-iter-seq.md +47 -0
  131. package/rules/go/idiom/logging/lowercase-log-messages.md +80 -0
  132. package/rules/go/idiom/logging/use-slog.md +46 -0
  133. package/rules/go/idiom/naming/acronyms-consistent-case.md +97 -0
  134. package/rules/go/idiom/naming/interface-er-suffix.md +33 -0
  135. package/rules/go/idiom/naming/no-package-name-stutter.md +37 -0
  136. package/rules/go/idiom/naming/package-name-single-lowercase-word.md +40 -0
  137. package/rules/go/idiom/receivers/consistent-receiver-kind-per-type.md +40 -0
  138. package/rules/go/idiom/receivers/no-this-receiver.md +37 -0
  139. package/rules/go/idiom/receivers/pointer-vs-value-receiver-choice.md +49 -0
  140. package/rules/go/idiom/receivers/short-receiver-names.md +43 -0
  141. package/rules/go/idiom/structs/new-expr-for-pointer-fields.md +40 -0
  142. package/rules/go/idiom/structure/main-delegates-to-run.md +54 -0
  143. package/rules/ts/futureproof/classes/composition-over-abstract-base.md +73 -0
  144. package/rules/ts/futureproof/functions/explicit-return-type-on-exports.md +50 -0
  145. package/rules/ts/futureproof/structure/colocate-zod-schemas.md +46 -0
  146. package/rules/ts/futureproof/types/exhaustive-switch-never-check.md +52 -0
  147. package/rules/ts/futureproof/types/readonly-for-immutable-data.md +46 -0
  148. package/rules/ts/futureproof/zod/enum-values-from-const-object.md +37 -0
  149. package/rules/ts/futureproof/zod/no-z-native-enum.md +36 -0
  150. package/rules/ts/futureproof/zod/schema-first-infer-type.md +46 -0
  151. package/rules/ts/hacky/async/no-floating-promises.md +52 -0
  152. package/rules/ts/hacky/config/env-read-outside-config.md +56 -0
  153. package/rules/ts/hacky/errors/catch-param-typed-unknown.md +67 -0
  154. package/rules/ts/hacky/errors/custom-error-class-instanceof.md +66 -0
  155. package/rules/ts/hacky/errors/empty-catch.md +52 -0
  156. package/rules/ts/hacky/errors/log-and-swallow.md +65 -0
  157. package/rules/ts/hacky/errors/throw-typed-error-with-context.md +64 -0
  158. package/rules/ts/hacky/operators/nullish-coalescing-over-or.md +50 -0
  159. package/rules/ts/hacky/state/exported-let.md +60 -0
  160. package/rules/ts/hacky/type-safety/no-double-assertion.md +34 -0
  161. package/rules/ts/hacky/type-safety/no-explicit-any.md +48 -0
  162. package/rules/ts/hacky/type-safety/no-non-null-assertion.md +43 -0
  163. package/rules/ts/hacky/type-safety/no-unchecked-type-assertion.md +54 -0
  164. package/rules/ts/hacky/type-safety/validate-parsed-json.md +48 -0
  165. package/rules/ts/idiom/async/no-promise-chains.md +45 -0
  166. package/rules/ts/idiom/async/parallelize-independent-awaits.md +46 -0
  167. package/rules/ts/idiom/comments/doc-comment-above-declaration.md +43 -0
  168. package/rules/ts/idiom/constants/as-const-for-literal-config.md +65 -0
  169. package/rules/ts/idiom/constants/no-enum.md +37 -0
  170. package/rules/ts/idiom/control-flow/always-brace-if.md +56 -0
  171. package/rules/ts/idiom/control-flow/guard-clauses-early-return.md +52 -0
  172. package/rules/ts/idiom/control-flow/no-nested-ternary.md +54 -0
  173. package/rules/ts/idiom/errors/error-message-lowercase.md +56 -0
  174. package/rules/ts/idiom/errors/log-at-boundary-not-every-layer.md +66 -0
  175. package/rules/ts/idiom/exports/inline-export-at-declaration.md +49 -0
  176. package/rules/ts/idiom/exports/no-default-export.md +37 -0
  177. package/rules/ts/idiom/formatting/multiline-object-literals.md +46 -0
  178. package/rules/ts/idiom/functions/arrow-for-callbacks.md +44 -0
  179. package/rules/ts/idiom/functions/function-declaration-for-top-level.md +56 -0
  180. package/rules/ts/idiom/imports/export-type-for-types.md +34 -0
  181. package/rules/ts/idiom/imports/import-order.md +66 -0
  182. package/rules/ts/idiom/imports/import-type-for-types.md +50 -0
  183. package/rules/ts/idiom/imports/side-effect-imports-last.md +42 -0
  184. package/rules/ts/idiom/logging/structured-logging-lowercase.md +45 -0
  185. package/rules/ts/idiom/naming/boolean-name-question-prefix.md +42 -0
  186. package/rules/ts/idiom/naming/descriptive-identifier-quality.md +48 -0
  187. package/rules/ts/idiom/naming/screaming-snake-module-constants.md +58 -0
  188. package/rules/ts/idiom/strings/template-literals-over-concat.md +51 -0
  189. package/rules/ts/idiom/types/interface-extends-over-intersection.md +44 -0
  190. package/rules/ts/idiom/types/null-vs-undefined-convention.md +43 -0
  191. package/rules/ts/idiom/types/prefer-type-over-interface.md +64 -0
  192. package/rules/ts/idiom/types/satisfies-over-annotation.md +43 -0
  193. package/rules/ts/idiom/types/type-predicates-for-narrowing.md +53 -0
  194. package/rules/ts/idiom/variables/const-by-default.md +41 -0
  195. package/rules/ts/idiom/variables/no-var.md +36 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
package/dist/rule.d.ts ADDED
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+ import { RuleLang } from './lang.js';
3
+ import type { Lang } from './lang.js';
4
+ export declare const Axis: {
5
+ readonly IDIOM: "idiom";
6
+ readonly HACKY: "hacky";
7
+ readonly FUTUREPROOF: "futureproof";
8
+ };
9
+ export type Axis = (typeof Axis)[keyof typeof Axis];
10
+ export declare const axisValues: [Axis, ...Axis[]];
11
+ export declare const Severity: {
12
+ readonly INFO: "info";
13
+ readonly MINOR: "minor";
14
+ readonly MAJOR: "major";
15
+ readonly CRITICAL: "critical";
16
+ };
17
+ export type Severity = (typeof Severity)[keyof typeof Severity];
18
+ export declare const severityValues: [Severity, ...Severity[]];
19
+ export declare const Detect: {
20
+ readonly AST: "ast";
21
+ readonly JUDGE: "judge";
22
+ };
23
+ export type Detect = (typeof Detect)[keyof typeof Detect];
24
+ export declare const Confirm: {
25
+ readonly CALL_COUNT: "callCount";
26
+ readonly IMPL_COUNT: "implCount";
27
+ readonly REF_COUNT: "refCount";
28
+ };
29
+ export type Confirm = (typeof Confirm)[keyof typeof Confirm];
30
+ declare const astMatcherSchema: z.ZodObject<{
31
+ rule: z.ZodRecord<z.ZodString, z.ZodUnknown>;
32
+ constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
33
+ utils: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
34
+ }, z.core.$strict>;
35
+ export type AstMatcher = z.infer<typeof astMatcherSchema>;
36
+ export type Example = {
37
+ lang: Lang;
38
+ source: string;
39
+ expectLines: readonly number[];
40
+ };
41
+ type RuleBase = {
42
+ id: string;
43
+ lang: RuleLang;
44
+ axis: Axis;
45
+ category: string;
46
+ severity: Severity;
47
+ ignore: readonly string[];
48
+ why: string;
49
+ message: string;
50
+ good: readonly Example[];
51
+ bad: readonly Example[];
52
+ path: string;
53
+ };
54
+ export type AstRule = RuleBase & {
55
+ detect: typeof Detect.AST;
56
+ ast: Partial<Record<Lang, AstMatcher>>;
57
+ };
58
+ export type JudgeRule = RuleBase & {
59
+ detect: typeof Detect.JUDGE;
60
+ confirm?: Confirm;
61
+ falsePositives: readonly string[];
62
+ };
63
+ export type Rule = AstRule | JudgeRule;
64
+ export declare function loadRules(rulesDir: string): Promise<Rule[]>;
65
+ export declare function parseRule(rulesDir: string, path: string, content: string): Rule;
66
+ export {};
package/dist/rule.js ADDED
@@ -0,0 +1,259 @@
1
+ import { readdir, readFile } from 'node:fs/promises';
2
+ import { join, relative, sep } from 'node:path';
3
+ import matter from 'gray-matter';
4
+ import { z } from 'zod';
5
+ import { RuleLang, fenceLang, ruleAppliesTo, ruleLangValues } from './lang.js';
6
+ import { RuleError } from './shared/errors.js';
7
+ export const Axis = {
8
+ IDIOM: 'idiom',
9
+ HACKY: 'hacky',
10
+ FUTUREPROOF: 'futureproof',
11
+ };
12
+ export const axisValues = Object.values(Axis);
13
+ export const Severity = {
14
+ INFO: 'info',
15
+ MINOR: 'minor',
16
+ MAJOR: 'major',
17
+ CRITICAL: 'critical',
18
+ };
19
+ export const severityValues = Object.values(Severity);
20
+ export const Detect = {
21
+ AST: 'ast',
22
+ JUDGE: 'judge',
23
+ };
24
+ // deterministic checks that a judge finding must pass before it counts; implemented in confirm.ts
25
+ export const Confirm = {
26
+ CALL_COUNT: 'callCount',
27
+ IMPL_COUNT: 'implCount',
28
+ REF_COUNT: 'refCount',
29
+ };
30
+ const confirmValues = Object.values(Confirm);
31
+ // an ast-grep rule body exactly as its YAML reference defines it. ast-grep validates the shape when matching,
32
+ // so this schema only guards the envelope.
33
+ const astMatcherSchema = z
34
+ .object({
35
+ rule: z.record(z.string(), z.unknown()),
36
+ constraints: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),
37
+ utils: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),
38
+ })
39
+ .strict();
40
+ const astByLangSchema = z
41
+ .object({
42
+ ts: astMatcherSchema.optional(),
43
+ go: astMatcherSchema.optional(),
44
+ })
45
+ .strict();
46
+ const commonFrontmatter = {
47
+ severity: z.enum(severityValues),
48
+ ignore: z.array(z.string()).default([]),
49
+ };
50
+ const frontmatterSchema = z.discriminatedUnion('detect', [
51
+ z
52
+ .object({
53
+ detect: z.literal(Detect.AST),
54
+ ast: z.union([astMatcherSchema, astByLangSchema]),
55
+ ...commonFrontmatter,
56
+ })
57
+ .strict(),
58
+ z
59
+ .object({
60
+ detect: z.literal(Detect.JUDGE),
61
+ confirm: z.enum(confirmValues).optional(),
62
+ falsePositives: z.array(z.string()).default([]),
63
+ ...commonFrontmatter,
64
+ })
65
+ .strict(),
66
+ ]);
67
+ const RULE_EXTENSION = '.md';
68
+ const MARKER_PATTERN = /^\s*\/\/\s*(GOOD|BAD):/;
69
+ const FENCE_OPEN_PATTERN = /^```(\w*)\s*$/;
70
+ const FENCE_CLOSE = '```';
71
+ const SECTION_PREFIX = '## ';
72
+ const Section = {
73
+ WHY: 'why',
74
+ BAD: 'bad',
75
+ GOOD: 'good',
76
+ MESSAGE: 'message',
77
+ };
78
+ export async function loadRules(rulesDir) {
79
+ const entries = await readdir(rulesDir, { recursive: true, withFileTypes: true });
80
+ const paths = entries
81
+ .filter(entry => entry.isFile() && entry.name.endsWith(RULE_EXTENSION))
82
+ .map(entry => join(entry.parentPath, entry.name))
83
+ .sort();
84
+ return Promise.all(paths.map(async (path) => parseRule(rulesDir, path, await readFile(path, 'utf-8'))));
85
+ }
86
+ // parses one rule file. identity comes from the path: rules/<lang>/<axis>/<category>/<slug>.md
87
+ export function parseRule(rulesDir, path, content) {
88
+ const identity = parseIdentity(rulesDir, path);
89
+ const { data, content: body } = matter(content);
90
+ const frontmatter = frontmatterSchema.safeParse(data);
91
+ if (!frontmatter.success) {
92
+ const issues = frontmatter.error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`);
93
+ throw new RuleError(path, `invalid frontmatter: ${issues.join('; ')}`);
94
+ }
95
+ const sections = splitSections(body);
96
+ const why = requireSection(path, sections, Section.WHY);
97
+ const good = parseExamples(path, identity.lang, sections.get(Section.GOOD), Section.GOOD);
98
+ const bad = parseExamples(path, identity.lang, sections.get(Section.BAD), Section.BAD);
99
+ const message = sections.get(Section.MESSAGE)?.trim() ?? firstSentence(why);
100
+ const base = {
101
+ ...identity,
102
+ severity: frontmatter.data.severity,
103
+ ignore: frontmatter.data.ignore,
104
+ why,
105
+ message,
106
+ good,
107
+ bad,
108
+ path,
109
+ };
110
+ if (frontmatter.data.detect === Detect.AST) {
111
+ return {
112
+ ...base,
113
+ detect: Detect.AST,
114
+ ast: normalizeAst(path, identity.lang, frontmatter.data.ast),
115
+ };
116
+ }
117
+ return {
118
+ ...base,
119
+ detect: Detect.JUDGE,
120
+ ...(frontmatter.data.confirm && { confirm: frontmatter.data.confirm }),
121
+ falsePositives: frontmatter.data.falsePositives,
122
+ };
123
+ }
124
+ function parseIdentity(rulesDir, path) {
125
+ const segments = relative(rulesDir, path).split(sep);
126
+ const [lang, axis, category, file] = segments;
127
+ if (segments.length !== 4 || !lang || !axis || !category || !file) {
128
+ throw new RuleError(path, 'expected path rules/<lang>/<axis>/<category>/<slug>.md');
129
+ }
130
+ if (!isRuleLang(lang)) {
131
+ throw new RuleError(path, `unknown language directory "${lang}"`);
132
+ }
133
+ if (!isAxis(axis)) {
134
+ throw new RuleError(path, `unknown axis directory "${axis}"`);
135
+ }
136
+ const slug = file.slice(0, -RULE_EXTENSION.length);
137
+ return {
138
+ id: `${lang}.${axis}.${slug}`,
139
+ lang,
140
+ axis,
141
+ category,
142
+ };
143
+ }
144
+ function isRuleLang(value) {
145
+ return ruleLangValues.includes(value);
146
+ }
147
+ function isAxis(value) {
148
+ return axisValues.includes(value);
149
+ }
150
+ // a lang-specific rule writes `ast: { rule: ... }`; a lang-agnostic rule writes `ast: { ts: {...}, go: {...} }`
151
+ function normalizeAst(path, lang, ast) {
152
+ const isSingle = 'rule' in ast;
153
+ if (lang === RuleLang.ANY) {
154
+ if (isSingle) {
155
+ throw new RuleError(path, 'lang-agnostic rules must give ast.ts and/or ast.go');
156
+ }
157
+ if (!ast.ts && !ast.go) {
158
+ throw new RuleError(path, 'ast must define at least one of ts, go');
159
+ }
160
+ return ast;
161
+ }
162
+ if (!isSingle) {
163
+ throw new RuleError(path, `${lang} rules must give ast.rule directly`);
164
+ }
165
+ return { [lang]: ast };
166
+ }
167
+ // splits the markdown body into `## Heading` sections keyed by lowercase heading, ignoring headings inside fences
168
+ function splitSections(body) {
169
+ const sections = new Map();
170
+ let current;
171
+ let lines = [];
172
+ let inFence = false;
173
+ for (const line of body.split('\n')) {
174
+ if (line.startsWith(FENCE_CLOSE)) {
175
+ inFence = !inFence;
176
+ }
177
+ if (!inFence && line.startsWith(SECTION_PREFIX)) {
178
+ if (current !== undefined) {
179
+ sections.set(current, lines.join('\n'));
180
+ }
181
+ current = line.slice(SECTION_PREFIX.length).trim().toLowerCase();
182
+ lines = [];
183
+ continue;
184
+ }
185
+ lines.push(line);
186
+ }
187
+ if (current !== undefined) {
188
+ sections.set(current, lines.join('\n'));
189
+ }
190
+ return sections;
191
+ }
192
+ function requireSection(path, sections, name) {
193
+ const text = sections.get(name)?.trim();
194
+ if (!text) {
195
+ throw new RuleError(path, `missing "## ${capitalize(name)}" section`);
196
+ }
197
+ return text;
198
+ }
199
+ function parseExamples(path, ruleLang, section, name) {
200
+ const examples = [...fencedBlocks(section ?? '')].map(block => toExample(path, ruleLang, block));
201
+ if (examples.length === 0) {
202
+ throw new RuleError(path, `"## ${capitalize(name)}" needs at least one fenced code block`);
203
+ }
204
+ return examples;
205
+ }
206
+ function* fencedBlocks(section) {
207
+ let open;
208
+ let lines = [];
209
+ for (const line of section.split('\n')) {
210
+ const fence = FENCE_OPEN_PATTERN.exec(line);
211
+ if (open === undefined) {
212
+ if (fence?.[1] !== undefined) {
213
+ open = { info: fence[1], lines: [] };
214
+ lines = [];
215
+ }
216
+ continue;
217
+ }
218
+ if (line.startsWith(FENCE_CLOSE)) {
219
+ yield { ...open, lines };
220
+ open = undefined;
221
+ continue;
222
+ }
223
+ lines.push(line);
224
+ }
225
+ }
226
+ function toExample(path, ruleLang, block) {
227
+ const lang = fenceLang(block.info);
228
+ if (lang === undefined) {
229
+ throw new RuleError(path, `code fence needs a ts or go language tag, got "${block.info}"`);
230
+ }
231
+ if (!ruleAppliesTo(ruleLang, lang)) {
232
+ throw new RuleError(path, `${lang} example in a ${ruleLang} rule`);
233
+ }
234
+ const kept = [];
235
+ const expectLines = [];
236
+ for (const line of block.lines) {
237
+ const marker = MARKER_PATTERN.exec(line);
238
+ if (marker === null) {
239
+ kept.push(line);
240
+ continue;
241
+ }
242
+ if (marker[1] === 'BAD') {
243
+ expectLines.push(kept.length + 1);
244
+ }
245
+ }
246
+ return {
247
+ lang,
248
+ source: kept.join('\n'),
249
+ expectLines,
250
+ };
251
+ }
252
+ // a sentence ends at punctuation followed by whitespace, so `!` inside backticks does not cut it short
253
+ function firstSentence(text) {
254
+ return text.split(/(?<=[.!?])\s+/, 1)[0]?.trim() ?? text;
255
+ }
256
+ function capitalize(text) {
257
+ return text.charAt(0).toUpperCase() + text.slice(1);
258
+ }
259
+ //# sourceMappingURL=rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.js","sourceRoot":"","sources":["../src/rule.ts"],"names":[],"mappings":"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"}
package/dist/scan.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import type { Judge } from './analyzers/judge.js';
2
+ import type { Range } from './change.js';
3
+ import type { Config } from './config.js';
4
+ import type { Report } from './report.js';
5
+ import type { Rule } from './rule.js';
6
+ export type ScanOptions = {
7
+ repo: string;
8
+ range: Range;
9
+ config: Config;
10
+ rules: readonly Rule[];
11
+ judge?: Judge;
12
+ baseline?: string;
13
+ };
14
+ export declare function scan(options: ScanOptions): Promise<Report>;
package/dist/scan.js ADDED
@@ -0,0 +1,33 @@
1
+ import { collectFindings } from './analyzer.js';
2
+ import { astAnalyzer } from './analyzers/ast.js';
3
+ import { readChanges } from './change.js';
4
+ import { confirm } from './confirm.js';
5
+ import { score } from './score.js';
6
+ // the whole engine: read what changed, run every analyzer over it, confirm what needs confirming, score the rest.
7
+ export async function scan(options) {
8
+ const { scored, rejected } = await scoreRange(options, options.range);
9
+ const baseline = options.baseline === undefined
10
+ ? undefined
11
+ : pickScore((await scoreRange(options, { base: options.baseline, head: options.range.base })).scored);
12
+ return {
13
+ ...scored,
14
+ ...(baseline && { baseline }),
15
+ ...(options.judge && { judge: options.judge.summary() }),
16
+ ...(rejected.length > 0 && { rejected }),
17
+ };
18
+ }
19
+ async function scoreRange(options, range) {
20
+ const enabled = options.rules.filter(rule => options.config.rules[rule.id] !== false);
21
+ const analyzers = [astAnalyzer, ...(options.judge ? [options.judge.analyze] : [])];
22
+ const changes = await readChanges(options.repo, range, options.config.ignore);
23
+ const findings = await collectFindings(changes, enabled, analyzers);
24
+ const { kept, rejected } = await confirm(findings, enabled, { repo: options.repo, ignore: options.config.ignore });
25
+ return {
26
+ scored: score(kept, changes, enabled, options.config.scoring),
27
+ rejected,
28
+ };
29
+ }
30
+ function pickScore({ overall, grade, axes }) {
31
+ return { overall, grade, axes };
32
+ }
33
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAIvC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAcnC,kHAAkH;AAClH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAoB;IAC9C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAEtE,MAAM,QAAQ,GACb,OAAO,CAAC,QAAQ,KAAK,SAAS;QAC7B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAExG,OAAO;QACN,GAAG,MAAM;QACT,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC7B,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;KACxC,CAAC;AACH,CAAC;AAOD,KAAK,UAAU,UAAU,CAAC,OAAoB,EAAE,KAAY;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC;IACtF,MAAM,SAAS,GAAe,CAAC,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE/F,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACpE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAEnH,OAAO;QACN,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;QAC7D,QAAQ;KACR,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAU;IAClD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,147 @@
1
+ import { z } from 'zod';
2
+ import type { Change } from './change.js';
3
+ import type { Finding } from './finding.js';
4
+ import type { Rule } from './rule.js';
5
+ export declare const scoringSchema: z.ZodObject<{
6
+ points: z.ZodPrefault<z.ZodObject<{
7
+ info: z.ZodDefault<z.ZodNumber>;
8
+ minor: z.ZodDefault<z.ZodNumber>;
9
+ major: z.ZodDefault<z.ZodNumber>;
10
+ critical: z.ZodDefault<z.ZodNumber>;
11
+ }, z.core.$strict>>;
12
+ damping: z.ZodDefault<z.ZodNumber>;
13
+ densityScale: z.ZodDefault<z.ZodNumber>;
14
+ axisWeights: z.ZodPrefault<z.ZodObject<{
15
+ idiom: z.ZodDefault<z.ZodNumber>;
16
+ hacky: z.ZodDefault<z.ZodNumber>;
17
+ futureproof: z.ZodDefault<z.ZodNumber>;
18
+ }, z.core.$strict>>;
19
+ minScoredLines: z.ZodDefault<z.ZodNumber>;
20
+ }, z.core.$strict>;
21
+ export type Scoring = z.infer<typeof scoringSchema>;
22
+ export declare const Grade: {
23
+ readonly A: "A";
24
+ readonly B: "B";
25
+ readonly C: "C";
26
+ readonly D: "D";
27
+ readonly F: "F";
28
+ };
29
+ export type Grade = (typeof Grade)[keyof typeof Grade];
30
+ export declare const scoredFindingSchema: z.ZodObject<{
31
+ ruleId: z.ZodString;
32
+ path: z.ZodString;
33
+ line: z.ZodNumber;
34
+ endLine: z.ZodNumber;
35
+ quote: z.ZodString;
36
+ message: z.ZodString;
37
+ confidence: z.ZodNumber;
38
+ symbol: z.ZodOptional<z.ZodString>;
39
+ axis: z.ZodEnum<{
40
+ idiom: "idiom";
41
+ hacky: "hacky";
42
+ futureproof: "futureproof";
43
+ }>;
44
+ severity: z.ZodEnum<{
45
+ info: "info";
46
+ minor: "minor";
47
+ major: "major";
48
+ critical: "critical";
49
+ }>;
50
+ points: z.ZodNumber;
51
+ }, z.core.$strip>;
52
+ export type ScoredFinding = z.infer<typeof scoredFindingSchema>;
53
+ export declare const axisScoreSchema: z.ZodObject<{
54
+ score: z.ZodNumber;
55
+ points: z.ZodNumber;
56
+ density: z.ZodNumber;
57
+ findings: z.ZodNumber;
58
+ }, z.core.$strip>;
59
+ export type AxisScore = z.infer<typeof axisScoreSchema>;
60
+ export declare const scoreSchema: z.ZodObject<{
61
+ overall: z.ZodNumber;
62
+ grade: z.ZodEnum<{
63
+ A: "A";
64
+ B: "B";
65
+ C: "C";
66
+ D: "D";
67
+ F: "F";
68
+ }>;
69
+ axes: z.ZodObject<{
70
+ idiom: z.ZodObject<{
71
+ score: z.ZodNumber;
72
+ points: z.ZodNumber;
73
+ density: z.ZodNumber;
74
+ findings: z.ZodNumber;
75
+ }, z.core.$strip>;
76
+ hacky: z.ZodObject<{
77
+ score: z.ZodNumber;
78
+ points: z.ZodNumber;
79
+ density: z.ZodNumber;
80
+ findings: z.ZodNumber;
81
+ }, z.core.$strip>;
82
+ futureproof: z.ZodObject<{
83
+ score: z.ZodNumber;
84
+ points: z.ZodNumber;
85
+ density: z.ZodNumber;
86
+ findings: z.ZodNumber;
87
+ }, z.core.$strip>;
88
+ }, z.core.$strip>;
89
+ }, z.core.$strip>;
90
+ export type Score = z.infer<typeof scoreSchema>;
91
+ export declare const scoredSchema: z.ZodObject<{
92
+ overall: z.ZodNumber;
93
+ grade: z.ZodEnum<{
94
+ A: "A";
95
+ B: "B";
96
+ C: "C";
97
+ D: "D";
98
+ F: "F";
99
+ }>;
100
+ axes: z.ZodObject<{
101
+ idiom: z.ZodObject<{
102
+ score: z.ZodNumber;
103
+ points: z.ZodNumber;
104
+ density: z.ZodNumber;
105
+ findings: z.ZodNumber;
106
+ }, z.core.$strip>;
107
+ hacky: z.ZodObject<{
108
+ score: z.ZodNumber;
109
+ points: z.ZodNumber;
110
+ density: z.ZodNumber;
111
+ findings: z.ZodNumber;
112
+ }, z.core.$strip>;
113
+ futureproof: z.ZodObject<{
114
+ score: z.ZodNumber;
115
+ points: z.ZodNumber;
116
+ density: z.ZodNumber;
117
+ findings: z.ZodNumber;
118
+ }, z.core.$strip>;
119
+ }, z.core.$strip>;
120
+ files: z.ZodNumber;
121
+ scoredLines: z.ZodNumber;
122
+ findings: z.ZodArray<z.ZodObject<{
123
+ ruleId: z.ZodString;
124
+ path: z.ZodString;
125
+ line: z.ZodNumber;
126
+ endLine: z.ZodNumber;
127
+ quote: z.ZodString;
128
+ message: z.ZodString;
129
+ confidence: z.ZodNumber;
130
+ symbol: z.ZodOptional<z.ZodString>;
131
+ axis: z.ZodEnum<{
132
+ idiom: "idiom";
133
+ hacky: "hacky";
134
+ futureproof: "futureproof";
135
+ }>;
136
+ severity: z.ZodEnum<{
137
+ info: "info";
138
+ minor: "minor";
139
+ major: "major";
140
+ critical: "critical";
141
+ }>;
142
+ points: z.ZodNumber;
143
+ }, z.core.$strip>>;
144
+ }, z.core.$strip>;
145
+ export type Scored = z.infer<typeof scoredSchema>;
146
+ export declare function score(findings: readonly Finding[], changes: readonly Change[], rules: readonly Rule[], scoring: Scoring): Scored;
147
+ export declare function gradeFor(overall: number): Grade;