honeytree 1.1.2 → 1.1.4

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.
@@ -0,0 +1,92 @@
1
+ const DOC_EXTENSIONS = new Set([".md", ".mdx", ".rst", ".txt", ".adoc", ".wiki"]);
2
+ const TEST_PATTERNS = ["test", "spec", "__test__", ".test.", ".spec.", "_test."];
3
+
4
+ function isTestFile(filePath) {
5
+ const lower = filePath.toLowerCase();
6
+ return TEST_PATTERNS.some((pattern) => lower.includes(pattern));
7
+ }
8
+
9
+ function isDocFile(filePath) {
10
+ const ext = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
11
+ return DOC_EXTENSIONS.has(ext);
12
+ }
13
+
14
+ export function classifyDiffStat(stat) {
15
+ const { insertions = 0, deletions = 0, files = 0, renames = 0, testFiles = 0, docFiles = 0 } = stat;
16
+ const totalChanges = insertions + deletions;
17
+
18
+ if (totalChanges === 0) return null;
19
+
20
+ // Refactoring: deletions > 40% of changes and renames present
21
+ if (deletions / totalChanges > 0.4 && renames > 0) {
22
+ return "refactoring";
23
+ }
24
+
25
+ // Testing: > 60% of files are test files
26
+ if (files > 0 && testFiles / files > 0.6) {
27
+ return "testing";
28
+ }
29
+
30
+ // Docs: > 60% of files are doc files
31
+ if (files > 0 && docFiles / files > 0.6) {
32
+ return "docs";
33
+ }
34
+
35
+ // Bugfix: small targeted edits, test file touched
36
+ if (files < 5 && testFiles >= 1) {
37
+ return "bugfix";
38
+ }
39
+
40
+ return null;
41
+ }
42
+
43
+ export function updateSessionWindow(window) {
44
+ const counts = {};
45
+ for (const type of window) {
46
+ if (type) {
47
+ counts[type] = (counts[type] || 0) + 1;
48
+ }
49
+ }
50
+
51
+ let best = null;
52
+ let bestCount = 0;
53
+ for (const [type, count] of Object.entries(counts)) {
54
+ if (count > bestCount) {
55
+ bestCount = count;
56
+ best = type;
57
+ }
58
+ }
59
+
60
+ if (bestCount >= 3) {
61
+ return { type: best, strength: bestCount };
62
+ }
63
+
64
+ return null;
65
+ }
66
+
67
+ export function parseDiffStatLine(line) {
68
+ const filesMatch = line.match(/(\d+)\s+files?\s+changed/);
69
+ const insMatch = line.match(/(\d+)\s+insertions?/);
70
+ const delMatch = line.match(/(\d+)\s+deletions?/);
71
+
72
+ return {
73
+ files: filesMatch ? parseInt(filesMatch[1], 10) : 0,
74
+ insertions: insMatch ? parseInt(insMatch[1], 10) : 0,
75
+ deletions: delMatch ? parseInt(delMatch[1], 10) : 0,
76
+ };
77
+ }
78
+
79
+ export function classifyFileList(changedFiles) {
80
+ let testFiles = 0;
81
+ let docFiles = 0;
82
+ let renames = 0;
83
+
84
+ for (const file of changedFiles) {
85
+ if (file.includes(" => ")) renames += 1;
86
+ const cleanPath = file.replace(/.*=> /, "").trim();
87
+ if (isTestFile(cleanPath)) testFiles += 1;
88
+ if (isDocFile(cleanPath)) docFiles += 1;
89
+ }
90
+
91
+ return { testFiles, docFiles, renames };
92
+ }