habit-hooks 0.2.0 → 1.0.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 (267) hide show
  1. package/README.md +17 -226
  2. package/bin/habit-hooks.js +32 -0
  3. package/package.json +11 -44
  4. package/LICENSE.md +0 -21
  5. package/dist/baseline/auto-prune.d.ts +0 -4
  6. package/dist/baseline/auto-prune.js +0 -38
  7. package/dist/baseline/auto-prune.js.map +0 -1
  8. package/dist/baseline/commands.d.ts +0 -12
  9. package/dist/baseline/commands.js +0 -125
  10. package/dist/baseline/commands.js.map +0 -1
  11. package/dist/baseline/file-hash.d.ts +0 -2
  12. package/dist/baseline/file-hash.js +0 -25
  13. package/dist/baseline/file-hash.js.map +0 -1
  14. package/dist/baseline/filter.d.ts +0 -9
  15. package/dist/baseline/filter.js +0 -18
  16. package/dist/baseline/filter.js.map +0 -1
  17. package/dist/baseline/reap.d.ts +0 -6
  18. package/dist/baseline/reap.js +0 -22
  19. package/dist/baseline/reap.js.map +0 -1
  20. package/dist/baseline/snooze-index.d.ts +0 -5
  21. package/dist/baseline/snooze-index.js +0 -65
  22. package/dist/baseline/snooze-index.js.map +0 -1
  23. package/dist/baseline/store.d.ts +0 -18
  24. package/dist/baseline/store.js +0 -106
  25. package/dist/baseline/store.js.map +0 -1
  26. package/dist/checks/comment-check.d.ts +0 -3
  27. package/dist/checks/comment-check.js +0 -85
  28. package/dist/checks/comment-check.js.map +0 -1
  29. package/dist/checks/eslint-wrap.d.ts +0 -2
  30. package/dist/checks/eslint-wrap.js +0 -107
  31. package/dist/checks/eslint-wrap.js.map +0 -1
  32. package/dist/checks/jscpd-wrap.d.ts +0 -9
  33. package/dist/checks/jscpd-wrap.js +0 -159
  34. package/dist/checks/jscpd-wrap.js.map +0 -1
  35. package/dist/checks/knip-resolve.d.ts +0 -4
  36. package/dist/checks/knip-resolve.js +0 -49
  37. package/dist/checks/knip-resolve.js.map +0 -1
  38. package/dist/checks/knip-schema.d.ts +0 -32
  39. package/dist/checks/knip-schema.js +0 -24
  40. package/dist/checks/knip-schema.js.map +0 -1
  41. package/dist/checks/knip-wrap.d.ts +0 -4
  42. package/dist/checks/knip-wrap.js +0 -135
  43. package/dist/checks/knip-wrap.js.map +0 -1
  44. package/dist/cli/baseline-commands.d.ts +0 -2
  45. package/dist/cli/baseline-commands.js +0 -61
  46. package/dist/cli/baseline-commands.js.map +0 -1
  47. package/dist/cli/emit.d.ts +0 -7
  48. package/dist/cli/emit.js +0 -8
  49. package/dist/cli/emit.js.map +0 -1
  50. package/dist/cli/init/apply-recommendations.d.ts +0 -3
  51. package/dist/cli/init/apply-recommendations.js +0 -76
  52. package/dist/cli/init/apply-recommendations.js.map +0 -1
  53. package/dist/cli/init/command-runner.d.ts +0 -6
  54. package/dist/cli/init/command-runner.js +0 -22
  55. package/dist/cli/init/command-runner.js.map +0 -1
  56. package/dist/cli/init/completion-report.d.ts +0 -11
  57. package/dist/cli/init/completion-report.js +0 -98
  58. package/dist/cli/init/completion-report.js.map +0 -1
  59. package/dist/cli/init/ctx.d.ts +0 -12
  60. package/dist/cli/init/ctx.js +0 -16
  61. package/dist/cli/init/ctx.js.map +0 -1
  62. package/dist/cli/init/detect.d.ts +0 -10
  63. package/dist/cli/init/detect.js +0 -69
  64. package/dist/cli/init/detect.js.map +0 -1
  65. package/dist/cli/init/git-hook.d.ts +0 -7
  66. package/dist/cli/init/git-hook.js +0 -52
  67. package/dist/cli/init/git-hook.js.map +0 -1
  68. package/dist/cli/init/install-commands.d.ts +0 -8
  69. package/dist/cli/init/install-commands.js +0 -82
  70. package/dist/cli/init/install-commands.js.map +0 -1
  71. package/dist/cli/init/package-scripts.d.ts +0 -6
  72. package/dist/cli/init/package-scripts.js +0 -55
  73. package/dist/cli/init/package-scripts.js.map +0 -1
  74. package/dist/cli/init/prompts.d.ts +0 -9
  75. package/dist/cli/init/prompts.js +0 -33
  76. package/dist/cli/init/prompts.js.map +0 -1
  77. package/dist/cli/init/recommendations.d.ts +0 -14
  78. package/dist/cli/init/recommendations.js +0 -66
  79. package/dist/cli/init/recommendations.js.map +0 -1
  80. package/dist/cli/init/report-language.d.ts +0 -1
  81. package/dist/cli/init/report-language.js +0 -12
  82. package/dist/cli/init/report-language.js.map +0 -1
  83. package/dist/cli/init/reporters.d.ts +0 -12
  84. package/dist/cli/init/reporters.js +0 -44
  85. package/dist/cli/init/reporters.js.map +0 -1
  86. package/dist/cli/init/run.d.ts +0 -17
  87. package/dist/cli/init/run.js +0 -123
  88. package/dist/cli/init/run.js.map +0 -1
  89. package/dist/cli/init/scaffold-baseline.d.ts +0 -4
  90. package/dist/cli/init/scaffold-baseline.js +0 -11
  91. package/dist/cli/init/scaffold-baseline.js.map +0 -1
  92. package/dist/cli/init/scaffold-config.d.ts +0 -20
  93. package/dist/cli/init/scaffold-config.js +0 -59
  94. package/dist/cli/init/scaffold-config.js.map +0 -1
  95. package/dist/cli/init/scaffold-eslint-config.d.ts +0 -2
  96. package/dist/cli/init/scaffold-eslint-config.js +0 -12
  97. package/dist/cli/init/scaffold-eslint-config.js.map +0 -1
  98. package/dist/cli/init/scaffold-jscpd-config.d.ts +0 -3
  99. package/dist/cli/init/scaffold-jscpd-config.js +0 -12
  100. package/dist/cli/init/scaffold-jscpd-config.js.map +0 -1
  101. package/dist/cli/init/scaffold-knip-config.d.ts +0 -2
  102. package/dist/cli/init/scaffold-knip-config.js +0 -12
  103. package/dist/cli/init/scaffold-knip-config.js.map +0 -1
  104. package/dist/cli/init/scaffold-ruff-config.d.ts +0 -2
  105. package/dist/cli/init/scaffold-ruff-config.js +0 -12
  106. package/dist/cli/init/scaffold-ruff-config.js.map +0 -1
  107. package/dist/cli/init/skill.d.ts +0 -8
  108. package/dist/cli/init/skill.js +0 -39
  109. package/dist/cli/init/skill.js.map +0 -1
  110. package/dist/cli/init/snippet.d.ts +0 -2
  111. package/dist/cli/init/snippet.js +0 -31
  112. package/dist/cli/init/snippet.js.map +0 -1
  113. package/dist/cli/init/templates/eslint-config.d.ts +0 -2
  114. package/dist/cli/init/templates/eslint-config.js +0 -45
  115. package/dist/cli/init/templates/eslint-config.js.map +0 -1
  116. package/dist/cli/init/templates/jscpd-config.d.ts +0 -3
  117. package/dist/cli/init/templates/jscpd-config.js +0 -17
  118. package/dist/cli/init/templates/jscpd-config.js.map +0 -1
  119. package/dist/cli/init/templates/knip-config.d.ts +0 -2
  120. package/dist/cli/init/templates/knip-config.js +0 -8
  121. package/dist/cli/init/templates/knip-config.js.map +0 -1
  122. package/dist/cli/init/templates/ruff-config.d.ts +0 -2
  123. package/dist/cli/init/templates/ruff-config.js +0 -16
  124. package/dist/cli/init/templates/ruff-config.js.map +0 -1
  125. package/dist/cli/init/tool-steps.d.ts +0 -2
  126. package/dist/cli/init/tool-steps.js +0 -78
  127. package/dist/cli/init/tool-steps.js.map +0 -1
  128. package/dist/cli/init-command.d.ts +0 -2
  129. package/dist/cli/init-command.js +0 -59
  130. package/dist/cli/init-command.js.map +0 -1
  131. package/dist/cli.d.ts +0 -2
  132. package/dist/cli.js +0 -101
  133. package/dist/cli.js.map +0 -1
  134. package/dist/config/catalogue-unused.d.ts +0 -2
  135. package/dist/config/catalogue-unused.js +0 -39
  136. package/dist/config/catalogue-unused.js.map +0 -1
  137. package/dist/config/catalogue.d.ts +0 -2
  138. package/dist/config/catalogue.js +0 -163
  139. package/dist/config/catalogue.js.map +0 -1
  140. package/dist/config/defaults.d.ts +0 -4
  141. package/dist/config/defaults.js +0 -12
  142. package/dist/config/defaults.js.map +0 -1
  143. package/dist/config/jiti-loader.d.ts +0 -1
  144. package/dist/config/jiti-loader.js +0 -13
  145. package/dist/config/jiti-loader.js.map +0 -1
  146. package/dist/config/load.d.ts +0 -9
  147. package/dist/config/load.js +0 -54
  148. package/dist/config/load.js.map +0 -1
  149. package/dist/config/merge.d.ts +0 -3
  150. package/dist/config/merge.js +0 -91
  151. package/dist/config/merge.js.map +0 -1
  152. package/dist/config/schema.d.ts +0 -41
  153. package/dist/config/schema.js +0 -4
  154. package/dist/config/schema.js.map +0 -1
  155. package/dist/config/tool-smells.d.ts +0 -14
  156. package/dist/config/tool-smells.js +0 -69
  157. package/dist/config/tool-smells.js.map +0 -1
  158. package/dist/config/validate.d.ts +0 -2
  159. package/dist/config/validate.js +0 -159
  160. package/dist/config/validate.js.map +0 -1
  161. package/dist/detect/package-json.d.ts +0 -1
  162. package/dist/detect/package-json.js +0 -15
  163. package/dist/detect/package-json.js.map +0 -1
  164. package/dist/detect/path.d.ts +0 -1
  165. package/dist/detect/path.js +0 -14
  166. package/dist/detect/path.js.map +0 -1
  167. package/dist/detect/tool.d.ts +0 -10
  168. package/dist/detect/tool.js +0 -75
  169. package/dist/detect/tool.js.map +0 -1
  170. package/dist/discover.d.ts +0 -2
  171. package/dist/discover.js +0 -14
  172. package/dist/discover.js.map +0 -1
  173. package/dist/git/exec.d.ts +0 -8
  174. package/dist/git/exec.js +0 -48
  175. package/dist/git/exec.js.map +0 -1
  176. package/dist/git/resolve-scope.d.ts +0 -15
  177. package/dist/git/resolve-scope.js +0 -89
  178. package/dist/git/resolve-scope.js.map +0 -1
  179. package/dist/git/scope.d.ts +0 -7
  180. package/dist/git/scope.js +0 -58
  181. package/dist/git/scope.js.map +0 -1
  182. package/dist/guide/command.d.ts +0 -6
  183. package/dist/guide/command.js +0 -20
  184. package/dist/guide/command.js.map +0 -1
  185. package/dist/guide/guide.d.ts +0 -11
  186. package/dist/guide/guide.js +0 -82
  187. package/dist/guide/guide.js.map +0 -1
  188. package/dist/guide/render.d.ts +0 -3
  189. package/dist/guide/render.js +0 -14
  190. package/dist/guide/render.js.map +0 -1
  191. package/dist/index.d.ts +0 -1
  192. package/dist/index.js +0 -2
  193. package/dist/index.js.map +0 -1
  194. package/dist/mapper/mapper.d.ts +0 -34
  195. package/dist/mapper/mapper.js +0 -80
  196. package/dist/mapper/mapper.js.map +0 -1
  197. package/dist/prompts/loader.d.ts +0 -6
  198. package/dist/prompts/loader.js +0 -27
  199. package/dist/prompts/loader.js.map +0 -1
  200. package/dist/prompts/packaged-dir.d.ts +0 -1
  201. package/dist/prompts/packaged-dir.js +0 -10
  202. package/dist/prompts/packaged-dir.js.map +0 -1
  203. package/dist/prompts/registry.d.ts +0 -3
  204. package/dist/prompts/registry.js +0 -43
  205. package/dist/prompts/registry.js.map +0 -1
  206. package/dist/rule-files.d.ts +0 -2
  207. package/dist/rule-files.js +0 -22
  208. package/dist/rule-files.js.map +0 -1
  209. package/dist/rules/registry.d.ts +0 -3
  210. package/dist/rules/registry.js +0 -37
  211. package/dist/rules/registry.js.map +0 -1
  212. package/dist/runner.d.ts +0 -15
  213. package/dist/runner.js +0 -141
  214. package/dist/runner.js.map +0 -1
  215. package/dist/sensors/adapter.d.ts +0 -17
  216. package/dist/sensors/adapter.js +0 -81
  217. package/dist/sensors/adapter.js.map +0 -1
  218. package/dist/sensors/deptry-sensor.d.ts +0 -3
  219. package/dist/sensors/deptry-sensor.js +0 -43
  220. package/dist/sensors/deptry-sensor.js.map +0 -1
  221. package/dist/sensors/line-count-sensor.d.ts +0 -3
  222. package/dist/sensors/line-count-sensor.js +0 -50
  223. package/dist/sensors/line-count-sensor.js.map +0 -1
  224. package/dist/sensors/needs-extraction.d.ts +0 -3
  225. package/dist/sensors/needs-extraction.js +0 -57
  226. package/dist/sensors/needs-extraction.js.map +0 -1
  227. package/dist/sensors/preset.d.ts +0 -17
  228. package/dist/sensors/preset.js +0 -57
  229. package/dist/sensors/preset.js.map +0 -1
  230. package/dist/sensors/python-preset.d.ts +0 -7
  231. package/dist/sensors/python-preset.js +0 -34
  232. package/dist/sensors/python-preset.js.map +0 -1
  233. package/dist/sensors/runner.d.ts +0 -12
  234. package/dist/sensors/runner.js +0 -94
  235. package/dist/sensors/runner.js.map +0 -1
  236. package/dist/sensors/types.d.ts +0 -15
  237. package/dist/sensors/types.js +0 -5
  238. package/dist/sensors/types.js.map +0 -1
  239. package/dist/types.d.ts +0 -44
  240. package/dist/types.js +0 -2
  241. package/dist/types.js.map +0 -1
  242. package/dist/wrap/notices.d.ts +0 -19
  243. package/dist/wrap/notices.js +0 -38
  244. package/dist/wrap/notices.js.map +0 -1
  245. package/dist/wrap/resolve.d.ts +0 -5
  246. package/dist/wrap/resolve.js +0 -9
  247. package/dist/wrap/resolve.js.map +0 -1
  248. package/dist/wrap/run.d.ts +0 -17
  249. package/dist/wrap/run.js +0 -31
  250. package/dist/wrap/run.js.map +0 -1
  251. package/dist/wrap/shell.d.ts +0 -15
  252. package/dist/wrap/shell.js +0 -50
  253. package/dist/wrap/shell.js.map +0 -1
  254. package/src/prompts/deep-nesting.md +0 -13
  255. package/src/prompts/duplicated-code.md +0 -9
  256. package/src/prompts/high-complexity.md +0 -9
  257. package/src/prompts/needs-extraction.md +0 -9
  258. package/src/prompts/non-essential-comment.md +0 -7
  259. package/src/prompts/non-null-assertion.md +0 -10
  260. package/src/prompts/oversized-file.md +0 -9
  261. package/src/prompts/oversized-function.issues.njk +0 -5
  262. package/src/prompts/oversized-function.md +0 -9
  263. package/src/prompts/parse-error.md +0 -5
  264. package/src/prompts/too-many-parameters.md +0 -9
  265. package/src/prompts/uncoached.md +0 -4
  266. package/src/skills/habit-hooks-prompting/SKILL.md +0 -37
  267. package/src/skills/habit-hooks-review/SKILL.md +0 -108
package/dist/runner.js DELETED
@@ -1,141 +0,0 @@
1
- import { dirname, isAbsolute, resolve } from 'node:path';
2
- import { filterFilesForRule } from './rule-files.js';
3
- import { discoverFiles } from './discover.js';
4
- import { loadConfig, loadConfigFromPath, RULES_DEPRECATION } from './config/load.js';
5
- import { buildRules } from './rules/registry.js';
6
- import { lookupPrompt } from './prompts/registry.js';
7
- import { resolvePackagedDir } from './prompts/packaged-dir.js';
8
- import { resolveScope } from './git/resolve-scope.js';
9
- import { loadBaseline } from './baseline/store.js';
10
- import { partitionBySnooze } from './baseline/filter.js';
11
- import { createSnoozeIndex } from './baseline/snooze-index.js';
12
- import { SensorRunner, satisfiableSensors } from './sensors/runner.js';
13
- import { applyReplaceMode } from './sensors/needs-extraction.js';
14
- import { buildPresetSensors, issueToViolation, violationToIssue } from './sensors/preset.js';
15
- import { buildPythonPresetSensors } from './sensors/python-preset.js';
16
- import { mapIssues } from './mapper/mapper.js';
17
- import { guide } from './guide/guide.js';
18
- import { COMMENT_SMELL } from './config/tool-smells.js';
19
- function applyScopeToRule(rule, files, scope) {
20
- if (!rule.changedFilesOnly)
21
- return files;
22
- const changed = scope.changedFiles;
23
- if (changed === null)
24
- return files;
25
- return files.filter((file) => changed.has(file));
26
- }
27
- function applyBaselineToRule(files, ctx) {
28
- if (ctx.baseline === null)
29
- return files;
30
- return partitionBySnooze(files, ctx.baseline, ctx.snoozeIndex).active;
31
- }
32
- function resolveFilesForRule(rule, ctx) {
33
- const filtered = filterFilesForRule(rule, ctx.files, ctx.cwd);
34
- const scoped = applyScopeToRule(rule, filtered, ctx.scope);
35
- return applyBaselineToRule(scoped, ctx);
36
- }
37
- async function resolveConfig(cwd, options) {
38
- if (options.configPath !== undefined) {
39
- const loaded = await loadConfigFromPath(options.configPath);
40
- return { config: loaded.config, configDir: dirname(options.configPath) };
41
- }
42
- const loaded = await loadConfig(cwd);
43
- const configDir = loaded.sourcePath ? dirname(loaded.sourcePath) : cwd;
44
- return { config: loaded.config, configDir };
45
- }
46
- function resolveBaseline(cwd, options) {
47
- if (options.applyBaseline === false)
48
- return null;
49
- return loadBaseline(cwd);
50
- }
51
- function resolvePromptsDir(config, configDir) {
52
- if (config.prompts === undefined)
53
- return undefined;
54
- return isAbsolute(config.prompts) ? config.prompts : resolve(configDir, config.prompts);
55
- }
56
- function buildRunContext(inputs) {
57
- const { cwd, config, configDir, files, scope, baseline } = inputs;
58
- const promptsDir = resolvePromptsDir(config, configDir);
59
- const configWarnings = config.rules !== undefined ? [RULES_DEPRECATION] : [];
60
- const snoozeIndex = createSnoozeIndex(cwd);
61
- const needsExtractionReplace = config.needsExtraction?.replace === true;
62
- return { cwd, files, scope, baseline, snoozeIndex, language: config.language ?? 'typescript', promptsDir, configWarnings, needsExtractionReplace };
63
- }
64
- async function buildContext(cwd, options) {
65
- const { config, configDir } = await resolveConfig(cwd, options);
66
- const rules = buildRules(config, configDir);
67
- const language = config.language ?? 'typescript';
68
- const files = await discoverFiles(cwd, language, config.scope?.exclude);
69
- const scope = resolveScope(options.scopeFlags ?? {}, config.scope, cwd);
70
- const baseline = resolveBaseline(cwd, options);
71
- return { ctx: buildRunContext({ cwd, config, configDir, files, scope, baseline }), rules };
72
- }
73
- // A sensor runs only when at least one smell it produces has an active rule
74
- // resolving to a non-empty file set. This reproduces the legacy "a tool runs
75
- // iff its source has an active in-scope rule" gate, so disabling or
76
- // empty-scoping a sensor's smells suppresses the whole tool (including its
77
- // uncoached sibling smells) rather than letting its findings leak through.
78
- function sensorActive(sensor, rulesById, ctx) {
79
- return sensor.produces.some((smell) => {
80
- const rule = rulesById.get(smell);
81
- return rule !== undefined && resolveFilesForRule(rule, ctx).length > 0;
82
- });
83
- }
84
- function presetSensors(ctx, rulesById, sink) {
85
- if (ctx.language === 'python')
86
- return buildPythonPresetSensors({ sink, cwd: ctx.cwd });
87
- return buildPresetSensors({ sink, commentRule: rulesById.get(COMMENT_SMELL) });
88
- }
89
- // Active sensors detect over the full discovered file set and their issues are
90
- // merged; rule-scoped file filtering is applied afterwards so the sensor stage
91
- // stays a pure smell detector (docs/sensors.md).
92
- async function detect(ctx, rules) {
93
- const sink = { notices: [], failures: [] };
94
- const rulesById = new Map(rules.map((r) => [r.id, r]));
95
- const all = presetSensors(ctx, rulesById, sink);
96
- const active = satisfiableSensors(all.filter((sensor) => sensorActive(sensor, rulesById, ctx)));
97
- const issues = await new SensorRunner(active).run({ files: ctx.files, cwd: ctx.cwd });
98
- const combined = applyReplaceMode(issues, ctx.needsExtractionReplace);
99
- return { violations: combined.map(issueToViolation), sink };
100
- }
101
- // Keep a violation when its smell has no rule (uncoached), or its file is not a
102
- // discovered source file (a project-level artifact like pyproject.toml reported
103
- // by a whole-project sensor), or its file is in the rule's resolved set.
104
- function filterViolations(violations, rules, ctx) {
105
- const allowed = new Map(rules.map((rule) => [rule.id, new Set(resolveFilesForRule(rule, ctx))]));
106
- const sourceFiles = new Set(ctx.files);
107
- return violations.filter((v) => {
108
- const set = allowed.get(v.ruleId);
109
- if (set === undefined || !sourceFiles.has(v.file))
110
- return true;
111
- return set.has(v.file);
112
- });
113
- }
114
- // Routing for the mapper: the merged smell config wins; otherwise the catalogue
115
- // (prompt registry) supplies severity/title for supplemental smells, so their
116
- // enforced severity survives. Unknown smells -> uncoached.
117
- function buildRouting(rules) {
118
- const byId = new Map(rules.map((r) => [r.id, r]));
119
- return (smell) => {
120
- const rule = byId.get(smell);
121
- if (rule !== undefined) {
122
- return { severity: rule.severity, fix: rule.fix, title: rule.title, description: rule.description };
123
- }
124
- const prompt = lookupPrompt(smell);
125
- if (prompt === null)
126
- return undefined;
127
- return { severity: prompt.severity, title: prompt.title, description: prompt.description };
128
- };
129
- }
130
- export async function run(cwd, options = {}) {
131
- const { ctx, rules } = await buildContext(cwd, options);
132
- const detected = await detect(ctx, rules);
133
- const violations = filterViolations(detected.violations, rules, ctx);
134
- const dirs = { overrideDir: ctx.promptsDir, packagedDir: resolvePackagedDir() };
135
- const mapped = mapIssues(violations.map(violationToIssue), buildRouting(rules), dirs);
136
- const rendered = await guide({ result: mapped, dirs, cwd });
137
- const exitCode = detected.sink.failures.length > 0 ? 1 : rendered.exitCode;
138
- const stderr = [...ctx.configWarnings, ...detected.sink.notices];
139
- return { stdout: rendered.stdout, exitCode, violations, stderr, scopeMode: ctx.scope.mode };
140
- }
141
- //# sourceMappingURL=runner.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- import { type SensorSink } from '../wrap/notices.js';
2
- import type { Issue, Sensor } from './types.js';
3
- export interface AdapterSpec {
4
- id: string;
5
- command: string;
6
- group?: string;
7
- items: string;
8
- fields: Record<string, string>;
9
- map?: Record<string, string>;
10
- }
11
- type Json = unknown;
12
- export declare function extractIssues(root: Json, spec: AdapterSpec): Issue[];
13
- export interface DeclarativeSensorSpec extends AdapterSpec {
14
- produces: string[];
15
- }
16
- export declare function declarativeSensor(spec: DeclarativeSensorSpec, sink: SensorSink): Sensor;
17
- export {};
@@ -1,81 +0,0 @@
1
- import { runTool } from '../wrap/shell.js';
2
- import { isSpawnFailure, recordSpawnFailure, spawnFailureWarning } from '../wrap/notices.js';
3
- function getByPath(value, path) {
4
- if (path === '')
5
- return value;
6
- return path.split('.').reduce((acc, key) => {
7
- if (acc !== null && typeof acc === 'object')
8
- return acc[key];
9
- return undefined;
10
- }, value);
11
- }
12
- // A path ending in "[]" denotes an array; "[]" alone is the value itself.
13
- function resolveArray(value, path) {
14
- const base = path.endsWith('[]') ? path.slice(0, -2) : path;
15
- const resolved = getByPath(value, base);
16
- return Array.isArray(resolved) ? resolved : [];
17
- }
18
- function readField(issue, group, path) {
19
- if (path.startsWith('group.'))
20
- return getByPath(group, path.slice('group.'.length));
21
- return getByPath(issue, path);
22
- }
23
- function buildDetails(spec, issue, group) {
24
- const details = {};
25
- let rawSmell = '';
26
- for (const [field, path] of Object.entries(spec.fields)) {
27
- const value = readField(issue, group, path);
28
- if (field === 'smell')
29
- rawSmell = String(value);
30
- else if (value !== undefined)
31
- details[field] = value;
32
- }
33
- return { rawSmell, details };
34
- }
35
- function extractOne(spec, issue, group) {
36
- const { rawSmell, details } = buildDetails(spec, issue, group);
37
- details.source = `${spec.id}:${rawSmell}`;
38
- return { smell: spec.map?.[rawSmell] ?? rawSmell, details };
39
- }
40
- export function extractIssues(root, spec) {
41
- if (spec.group !== undefined) {
42
- return resolveArray(root, spec.group).flatMap((group) => resolveArray(group, spec.items).map((issue) => extractOne(spec, issue, group)));
43
- }
44
- return resolveArray(root, spec.items).map((issue) => extractOne(spec, issue, null));
45
- }
46
- // Split the command on whitespace and expand the `${files}` token into the
47
- // scoped file list (the preset commands are unquoted, so a simple split suffices).
48
- function buildArgv(command, files) {
49
- const tokens = command.split(/\s+/).filter((token) => token.length > 0);
50
- const expanded = tokens.flatMap((token) => (token === '${files}' ? files : [token]));
51
- return { bin: expanded[0] ?? '', args: expanded.slice(1) };
52
- }
53
- function parseJson(stdout) {
54
- const trimmed = stdout.trim();
55
- if (trimmed.length === 0)
56
- return null;
57
- try {
58
- return JSON.parse(trimmed);
59
- }
60
- catch {
61
- return null;
62
- }
63
- }
64
- async function runDeclarative(spec, ctx, sink) {
65
- if (ctx.files.length === 0)
66
- return [];
67
- const { bin, args } = buildArgv(spec.command, ctx.files);
68
- const result = await runTool({ bin, args, cwd: ctx.cwd });
69
- if (isSpawnFailure(result)) {
70
- recordSpawnFailure(sink, spawnFailureWarning(spec.id, ctx.cwd, result.warnings));
71
- return [];
72
- }
73
- return extractIssues(parseJson(result.stdout), spec);
74
- }
75
- // Wrap a JSON-emitting tool as a leaf sensor via the declarative spec. A spawn
76
- // or timeout failure fails the run (docs/sensors.md): the message is shown and
77
- // recorded as a failure, with zero issues for that tool.
78
- export function declarativeSensor(spec, sink) {
79
- return { id: spec.id, produces: spec.produces, run: (ctx) => runDeclarative(spec, ctx, sink) };
80
- }
81
- //# sourceMappingURL=adapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/sensors/adapter.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { type SensorSink } from '../wrap/notices.js';
2
- import type { Sensor } from './types.js';
3
- export declare function deptrySensor(sink: SensorSink): Sensor;
@@ -1,43 +0,0 @@
1
- import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
2
- import { tmpdir } from 'node:os';
3
- import { join } from 'node:path';
4
- import { runTool } from '../wrap/shell.js';
5
- import { isSpawnFailure, recordSpawnFailure, spawnFailureWarning } from '../wrap/notices.js';
6
- import { DEPTRY_PRODUCES, DEPTRY_SPEC } from '../config/tool-smells.js';
7
- import { extractIssues } from './adapter.js';
8
- // deptry analyses the whole project and reports unused dependencies. Its
9
- // `--json-output` must target a real file (writing to /dev/stdout yields nothing
10
- // when stdout is a pipe), so deptry uses the temp-report pattern rather than the
11
- // stdout declarative adapter — but reuses the adapter's extractIssues to map.
12
- function parseReport(path) {
13
- if (!existsSync(path))
14
- return [];
15
- try {
16
- return extractIssues(JSON.parse(readFileSync(path, 'utf8')), DEPTRY_SPEC);
17
- }
18
- catch {
19
- return [];
20
- }
21
- }
22
- async function runReport(cwd, out, sink) {
23
- const result = await runTool({ bin: 'deptry', args: ['.', '--json-output', out], cwd });
24
- if (isSpawnFailure(result)) {
25
- recordSpawnFailure(sink, spawnFailureWarning('deptry', cwd, result.warnings));
26
- return false;
27
- }
28
- return true;
29
- }
30
- async function runDeptry(cwd, sink) {
31
- const dir = mkdtempSync(join(tmpdir(), 'hh-deptry-'));
32
- try {
33
- const out = join(dir, 'deptry.json');
34
- return (await runReport(cwd, out, sink)) ? parseReport(out) : [];
35
- }
36
- finally {
37
- rmSync(dir, { recursive: true, force: true });
38
- }
39
- }
40
- export function deptrySensor(sink) {
41
- return { id: 'deptry', produces: DEPTRY_PRODUCES, run: (ctx) => runDeptry(ctx.cwd, sink) };
42
- }
43
- //# sourceMappingURL=deptry-sensor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deptry-sensor.js","sourceRoot":"","sources":["../../src/sensors/deptry-sensor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAmB,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,yEAAyE;AACzE,iFAAiF;AACjF,iFAAiF;AACjF,8EAA8E;AAE9E,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,GAAW,EAAE,IAAgB;IACjE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACxF,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,IAAgB;IACpD,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACrC,OAAO,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAgB;IAC3C,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;AAC7F,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { Sensor } from './types.js';
2
- export declare const DEFAULT_MAX_FILE_LINES = 200;
3
- export declare function lineCountSensor(maxLines: number): Sensor;
@@ -1,50 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- // Default file-length ceiling, matching the TS `max-lines` (200).
3
- export const DEFAULT_MAX_FILE_LINES = 200;
4
- function lineCount(content) {
5
- if (content.length === 0)
6
- return 0;
7
- const body = content.endsWith('\n') ? content.slice(0, -1) : content;
8
- return body.split('\n').length;
9
- }
10
- function readLineCount(file) {
11
- try {
12
- return lineCount(readFileSync(file, 'utf8'));
13
- }
14
- catch {
15
- return null;
16
- }
17
- }
18
- function oversizedIssue(file, count, maxLines) {
19
- return {
20
- smell: 'oversized-file',
21
- details: {
22
- file,
23
- line: maxLines + 1,
24
- column: 1,
25
- message: `File has ${String(count)} lines; the maximum is ${String(maxLines)}.`,
26
- source: 'line-count:max-module-lines',
27
- },
28
- };
29
- }
30
- function oversizedIssues(files, maxLines) {
31
- const issues = [];
32
- for (const file of files) {
33
- const count = readLineCount(file);
34
- if (count !== null && count > maxLines)
35
- issues.push(oversizedIssue(file, count, maxLines));
36
- }
37
- return issues;
38
- }
39
- // A language-agnostic leaf sensor that emits `oversized-file` for any discovered
40
- // file whose physical line count exceeds the threshold. `oversized-file` is a
41
- // pure line count and needs no AST, so this covers languages (Python) that have
42
- // no tool rule for it.
43
- export function lineCountSensor(maxLines) {
44
- return {
45
- id: 'line-count',
46
- produces: ['oversized-file'],
47
- run: (ctx) => Promise.resolve(oversizedIssues(ctx.files, maxLines)),
48
- };
49
- }
50
- //# sourceMappingURL=line-count-sensor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"line-count-sensor.js","sourceRoot":"","sources":["../../src/sensors/line-count-sensor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,kEAAkE;AAClE,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,SAAS,SAAS,CAAC,OAAe;IAChC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACrE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa,EAAE,QAAgB;IACnE,OAAO;QACL,KAAK,EAAE,gBAAgB;QACvB,OAAO,EAAE;YACP,IAAI;YACJ,IAAI,EAAE,QAAQ,GAAG,CAAC;YAClB,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,YAAY,MAAM,CAAC,KAAK,CAAC,0BAA0B,MAAM,CAAC,QAAQ,CAAC,GAAG;YAC/E,MAAM,EAAE,6BAA6B;SACtC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAe,EAAE,QAAgB;IACxD,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,QAAQ;YAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,iFAAiF;AACjF,8EAA8E;AAC9E,gFAAgF;AAChF,uBAAuB;AACvB,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,OAAO;QACL,EAAE,EAAE,YAAY;QAChB,QAAQ,EAAE,CAAC,gBAAgB,CAAC;QAC5B,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;KACpE,CAAC;AACJ,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { Issue, Sensor } from './types.js';
2
- export declare function needsExtractionSensor(): Sensor;
3
- export declare function applyReplaceMode(issues: Issue[], replace: boolean): Issue[];
@@ -1,57 +0,0 @@
1
- import { JSCPD_SMELL } from '../config/tool-smells.js';
2
- const SMELL = 'needs-extraction';
3
- const INPUT_SMELLS = ['oversized-file', JSCPD_SMELL];
4
- function fileOf(issue) {
5
- const file = issue.details.file;
6
- return typeof file === 'string' ? file : null;
7
- }
8
- function filesWith(issues, smell) {
9
- const files = new Set();
10
- for (const issue of issues) {
11
- if (issue.smell !== smell)
12
- continue;
13
- const file = fileOf(issue);
14
- if (file !== null)
15
- files.add(file);
16
- }
17
- return files;
18
- }
19
- function needsExtractionIssue(file) {
20
- return {
21
- smell: SMELL,
22
- details: {
23
- file,
24
- line: 1,
25
- column: 1,
26
- message: 'File is both oversized and duplicated; extract the duplicated block into a shared module.',
27
- source: 'composite:oversized-file+duplicated-code',
28
- },
29
- };
30
- }
31
- function combine(deps) {
32
- const duplicated = filesWith(deps, JSCPD_SMELL);
33
- return [...filesWith(deps, 'oversized-file')].filter((file) => duplicated.has(file)).map(needsExtractionIssue);
34
- }
35
- // The composite sensor: a real multi sensor that reads oversized-file +
36
- // duplicated-code from ctx.deps and emits needs-extraction for any file that has
37
- // both (docs/architecture.md "Combinations"). All combination logic stays here
38
- // in the sensor layer; the mapper never sees it.
39
- export function needsExtractionSensor() {
40
- return {
41
- id: SMELL,
42
- produces: [SMELL],
43
- dependsOn: [...INPUT_SMELLS],
44
- run: (ctx) => Promise.resolve(combine(ctx.deps)),
45
- };
46
- }
47
- // `replace` mode: once needs-extraction fires for a file, drop that file's two
48
- // input smells so only the consolidated finding shows. Default (augment) keeps
49
- // all three. Operates on the merged bag before the mapper runs.
50
- export function applyReplaceMode(issues, replace) {
51
- if (!replace)
52
- return issues;
53
- const extracted = filesWith(issues, SMELL);
54
- const suppressed = new Set(INPUT_SMELLS);
55
- return issues.filter((issue) => !(suppressed.has(issue.smell) && extracted.has(fileOf(issue) ?? '')));
56
- }
57
- //# sourceMappingURL=needs-extraction.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"needs-extraction.js","sourceRoot":"","sources":["../../src/sensors/needs-extraction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,MAAM,KAAK,GAAG,kBAAkB,CAAC;AACjC,MAAM,YAAY,GAAG,CAAC,gBAAgB,EAAE,WAAW,CAAU,CAAC;AAE9D,SAAS,MAAM,CAAC,KAAY;IAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;IAChC,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,SAAS,SAAS,CAAC,MAAe,EAAE,KAAa;IAC/C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK;YAAE,SAAS;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,IAAI,KAAK,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACxC,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE;YACP,IAAI;YACJ,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,2FAA2F;YACpG,MAAM,EAAE,0CAA0C;SACnD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,IAAa;IAC5B,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AACjH,CAAC;AAED,wEAAwE;AACxE,iFAAiF;AACjF,+EAA+E;AAC/E,iDAAiD;AACjD,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,EAAE,EAAE,KAAK;QACT,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,SAAS,EAAE,CAAC,GAAG,YAAY,CAAC;QAC5B,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KACjD,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,+EAA+E;AAC/E,gEAAgE;AAChE,MAAM,UAAU,gBAAgB,CAAC,MAAe,EAAE,OAAgB;IAChE,IAAI,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAC5B,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,YAAY,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACxG,CAAC"}
@@ -1,17 +0,0 @@
1
- import type { SensorSink } from '../wrap/notices.js';
2
- import type { Check, Rule, Violation } from '../types.js';
3
- import type { Issue, Sensor } from './types.js';
4
- export declare function violationToIssue(v: Violation): Issue;
5
- export declare function issueToViolation(issue: Issue): Violation;
6
- export interface LeafSpec {
7
- check: Check;
8
- produces: string[];
9
- sink: SensorSink;
10
- rules?: Rule[];
11
- }
12
- export declare function checkLeafSensor(spec: LeafSpec): Sensor;
13
- export interface PresetInput {
14
- sink: SensorSink;
15
- commentRule?: Rule;
16
- }
17
- export declare function buildPresetSensors(input: PresetInput): Sensor[];
@@ -1,57 +0,0 @@
1
- import { eslintWrap } from '../checks/eslint-wrap.js';
2
- import { commentCheck } from '../checks/comment-check.js';
3
- import { jscpdWrap } from '../checks/jscpd-wrap.js';
4
- import { knipWrap } from '../checks/knip-wrap.js';
5
- import { COMMENT_SMELL, ESLINT_PRODUCES, JSCPD_SMELL, KNIP_PRODUCES } from '../config/tool-smells.js';
6
- import { needsExtractionSensor } from './needs-extraction.js';
7
- export function violationToIssue(v) {
8
- const details = { file: v.file, line: v.line, message: v.message };
9
- if (v.column !== undefined)
10
- details.column = v.column;
11
- if (v.source !== undefined)
12
- details.source = v.source;
13
- return { smell: v.ruleId, details };
14
- }
15
- export function issueToViolation(issue) {
16
- const d = issue.details;
17
- const column = typeof d.column === 'number' ? d.column : undefined;
18
- const source = typeof d.source === 'string' ? d.source : undefined;
19
- const line = typeof d.line === 'number' ? d.line : 1;
20
- return { ruleId: issue.smell, file: String(d.file), line, column, message: String(d.message), source };
21
- }
22
- function normalizeOutcome(result) {
23
- return Array.isArray(result) ? { violations: result } : result;
24
- }
25
- export function checkLeafSensor(spec) {
26
- return {
27
- id: spec.check.id,
28
- produces: spec.produces,
29
- async run(ctx) {
30
- const outcome = normalizeOutcome(await spec.check.run(ctx.files, spec.rules ?? [], ctx.cwd));
31
- if (outcome.stderr)
32
- spec.sink.notices.push(...outcome.stderr);
33
- if (outcome.failures)
34
- spec.sink.failures.push(...outcome.failures);
35
- return outcome.violations.map(violationToIssue);
36
- },
37
- };
38
- }
39
- // commentRule carries the resolved comment thresholds the ts-morph scan needs.
40
- function commentSensor(input) {
41
- const rules = input.commentRule ? [input.commentRule] : [];
42
- return checkLeafSensor({ check: commentCheck, produces: [COMMENT_SMELL], sink: input.sink, rules });
43
- }
44
- // The TypeScript/JavaScript preset: leaf sensors over eslint, ts-morph comments,
45
- // jscpd, and knip, plus the needs-extraction composite over oversized-file +
46
- // duplicated-code.
47
- export function buildPresetSensors(input) {
48
- const { sink } = input;
49
- return [
50
- checkLeafSensor({ check: eslintWrap, produces: ESLINT_PRODUCES, sink }),
51
- commentSensor(input),
52
- checkLeafSensor({ check: jscpdWrap, produces: [JSCPD_SMELL], sink }),
53
- checkLeafSensor({ check: knipWrap, produces: KNIP_PRODUCES, sink }),
54
- needsExtractionSensor(),
55
- ];
56
- }
57
- //# sourceMappingURL=preset.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"preset.js","sourceRoot":"","sources":["../../src/sensors/preset.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- import type { SensorSink } from '../wrap/notices.js';
2
- import type { Sensor } from './types.js';
3
- export interface PythonPresetInput {
4
- sink: SensorSink;
5
- cwd: string;
6
- }
7
- export declare function buildPythonPresetSensors(input: PythonPresetInput): Sensor[];
@@ -1,34 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { jscpdWrap } from '../checks/jscpd-wrap.js';
4
- import { TOOL_CONFIG_FILENAMES } from '../detect/tool.js';
5
- import { JSCPD_SMELL, RUFF_SPEC } from '../config/tool-smells.js';
6
- import { declarativeSensor } from './adapter.js';
7
- import { checkLeafSensor } from './preset.js';
8
- import { deptrySensor } from './deptry-sensor.js';
9
- import { DEFAULT_MAX_FILE_LINES, lineCountSensor } from './line-count-sensor.js';
10
- import { needsExtractionSensor } from './needs-extraction.js';
11
- // `oversized-file` has no ruff rule (ruff 0.15 has no C0302 port and rejects an
12
- // unknown `max-module-lines` key under `[tool.ruff]`), so the threshold is read
13
- // from the consumer's config text by the same no-TOML-parser approach the init
14
- // drift-check uses; defaults to 200, matching the TS `max-lines`.
15
- function readMaxModuleLines(cwd) {
16
- const sources = [...TOOL_CONFIG_FILENAMES.ruff, 'pyproject.toml'];
17
- const text = sources.map((name) => readTextOrEmpty(join(cwd, name))).join('\n');
18
- const match = text.match(/max-module-lines\s*=\s*(\d+)/);
19
- return match ? Number(match[1]) : DEFAULT_MAX_FILE_LINES;
20
- }
21
- function readTextOrEmpty(path) {
22
- return existsSync(path) ? readFileSync(path, 'utf8') : '';
23
- }
24
- export function buildPythonPresetSensors(input) {
25
- const { sink, cwd } = input;
26
- return [
27
- declarativeSensor(RUFF_SPEC, sink),
28
- checkLeafSensor({ check: jscpdWrap, produces: [JSCPD_SMELL], sink }),
29
- deptrySensor(sink),
30
- lineCountSensor(readMaxModuleLines(cwd)),
31
- needsExtractionSensor(),
32
- ];
33
- }
34
- //# sourceMappingURL=python-preset.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"python-preset.js","sourceRoot":"","sources":["../../src/sensors/python-preset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAW9D,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,kEAAkE;AAClE,SAAS,kBAAkB,CAAC,GAAW;IACrC,MAAM,OAAO,GAAG,CAAC,GAAG,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACzD,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC;AAC3D,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAwB;IAC/D,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IAC5B,OAAO;QACL,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC;QAClC,eAAe,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC;QACpE,YAAY,CAAC,IAAI,CAAC;QAClB,eAAe,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACxC,qBAAqB,EAAE;KACxB,CAAC;AACJ,CAAC"}
@@ -1,12 +0,0 @@
1
- import type { Issue, Sensor } from './types.js';
2
- export interface SensorRunInput {
3
- files: string[];
4
- cwd: string;
5
- }
6
- export declare function satisfiableSensors(sensors: Sensor[]): Sensor[];
7
- export declare class SensorRunner {
8
- private readonly ordered;
9
- constructor(sensors: Sensor[]);
10
- get sensors(): Sensor[];
11
- run(input: SensorRunInput): Promise<Issue[]>;
12
- }