@monoes/monomindcli 1.6.4 → 1.6.6

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 (116) hide show
  1. package/.claude/helpers/graphify-freshen.cjs +10 -1
  2. package/bundled-graph/dist/src/analyze.d.ts +32 -0
  3. package/bundled-graph/dist/src/analyze.d.ts.map +1 -0
  4. package/bundled-graph/dist/src/analyze.js +297 -0
  5. package/bundled-graph/dist/src/analyze.js.map +1 -0
  6. package/bundled-graph/dist/src/build.d.ts +8 -0
  7. package/bundled-graph/dist/src/build.d.ts.map +1 -0
  8. package/bundled-graph/dist/src/build.js +73 -0
  9. package/bundled-graph/dist/src/build.js.map +1 -0
  10. package/bundled-graph/dist/src/cache.d.ts +12 -0
  11. package/bundled-graph/dist/src/cache.d.ts.map +1 -0
  12. package/bundled-graph/dist/src/cache.js +43 -0
  13. package/bundled-graph/dist/src/cache.js.map +1 -0
  14. package/bundled-graph/dist/src/cluster.d.ts +5 -0
  15. package/bundled-graph/dist/src/cluster.d.ts.map +1 -0
  16. package/bundled-graph/dist/src/cluster.js +120 -0
  17. package/bundled-graph/dist/src/cluster.js.map +1 -0
  18. package/bundled-graph/dist/src/detect.d.ts +21 -0
  19. package/bundled-graph/dist/src/detect.d.ts.map +1 -0
  20. package/bundled-graph/dist/src/detect.js +195 -0
  21. package/bundled-graph/dist/src/detect.js.map +1 -0
  22. package/bundled-graph/dist/src/export.d.ts +21 -0
  23. package/bundled-graph/dist/src/export.d.ts.map +1 -0
  24. package/bundled-graph/dist/src/export.js +68 -0
  25. package/bundled-graph/dist/src/export.js.map +1 -0
  26. package/bundled-graph/dist/src/extract/index.d.ts +20 -0
  27. package/bundled-graph/dist/src/extract/index.d.ts.map +1 -0
  28. package/bundled-graph/dist/src/extract/index.js +158 -0
  29. package/bundled-graph/dist/src/extract/index.js.map +1 -0
  30. package/bundled-graph/dist/src/extract/languages/c.d.ts +3 -0
  31. package/bundled-graph/dist/src/extract/languages/c.d.ts.map +1 -0
  32. package/bundled-graph/dist/src/extract/languages/c.js +88 -0
  33. package/bundled-graph/dist/src/extract/languages/c.js.map +1 -0
  34. package/bundled-graph/dist/src/extract/languages/cpp.d.ts +3 -0
  35. package/bundled-graph/dist/src/extract/languages/cpp.d.ts.map +1 -0
  36. package/bundled-graph/dist/src/extract/languages/cpp.js +121 -0
  37. package/bundled-graph/dist/src/extract/languages/cpp.js.map +1 -0
  38. package/bundled-graph/dist/src/extract/languages/csharp.d.ts +3 -0
  39. package/bundled-graph/dist/src/extract/languages/csharp.d.ts.map +1 -0
  40. package/bundled-graph/dist/src/extract/languages/csharp.js +121 -0
  41. package/bundled-graph/dist/src/extract/languages/csharp.js.map +1 -0
  42. package/bundled-graph/dist/src/extract/languages/go.d.ts +3 -0
  43. package/bundled-graph/dist/src/extract/languages/go.d.ts.map +1 -0
  44. package/bundled-graph/dist/src/extract/languages/go.js +181 -0
  45. package/bundled-graph/dist/src/extract/languages/go.js.map +1 -0
  46. package/bundled-graph/dist/src/extract/languages/java.d.ts +3 -0
  47. package/bundled-graph/dist/src/extract/languages/java.d.ts.map +1 -0
  48. package/bundled-graph/dist/src/extract/languages/java.js +117 -0
  49. package/bundled-graph/dist/src/extract/languages/java.js.map +1 -0
  50. package/bundled-graph/dist/src/extract/languages/kotlin.d.ts +3 -0
  51. package/bundled-graph/dist/src/extract/languages/kotlin.d.ts.map +1 -0
  52. package/bundled-graph/dist/src/extract/languages/kotlin.js +112 -0
  53. package/bundled-graph/dist/src/extract/languages/kotlin.js.map +1 -0
  54. package/bundled-graph/dist/src/extract/languages/php.d.ts +3 -0
  55. package/bundled-graph/dist/src/extract/languages/php.d.ts.map +1 -0
  56. package/bundled-graph/dist/src/extract/languages/php.js +130 -0
  57. package/bundled-graph/dist/src/extract/languages/php.js.map +1 -0
  58. package/bundled-graph/dist/src/extract/languages/python.d.ts +3 -0
  59. package/bundled-graph/dist/src/extract/languages/python.d.ts.map +1 -0
  60. package/bundled-graph/dist/src/extract/languages/python.js +230 -0
  61. package/bundled-graph/dist/src/extract/languages/python.js.map +1 -0
  62. package/bundled-graph/dist/src/extract/languages/ruby.d.ts +3 -0
  63. package/bundled-graph/dist/src/extract/languages/ruby.d.ts.map +1 -0
  64. package/bundled-graph/dist/src/extract/languages/ruby.js +120 -0
  65. package/bundled-graph/dist/src/extract/languages/ruby.js.map +1 -0
  66. package/bundled-graph/dist/src/extract/languages/rust.d.ts +3 -0
  67. package/bundled-graph/dist/src/extract/languages/rust.d.ts.map +1 -0
  68. package/bundled-graph/dist/src/extract/languages/rust.js +195 -0
  69. package/bundled-graph/dist/src/extract/languages/rust.js.map +1 -0
  70. package/bundled-graph/dist/src/extract/languages/scala.d.ts +3 -0
  71. package/bundled-graph/dist/src/extract/languages/scala.d.ts.map +1 -0
  72. package/bundled-graph/dist/src/extract/languages/scala.js +110 -0
  73. package/bundled-graph/dist/src/extract/languages/scala.js.map +1 -0
  74. package/bundled-graph/dist/src/extract/languages/swift.d.ts +3 -0
  75. package/bundled-graph/dist/src/extract/languages/swift.d.ts.map +1 -0
  76. package/bundled-graph/dist/src/extract/languages/swift.js +122 -0
  77. package/bundled-graph/dist/src/extract/languages/swift.js.map +1 -0
  78. package/bundled-graph/dist/src/extract/languages/typescript.d.ts +3 -0
  79. package/bundled-graph/dist/src/extract/languages/typescript.d.ts.map +1 -0
  80. package/bundled-graph/dist/src/extract/languages/typescript.js +295 -0
  81. package/bundled-graph/dist/src/extract/languages/typescript.js.map +1 -0
  82. package/bundled-graph/dist/src/extract/semantic.d.ts +38 -0
  83. package/bundled-graph/dist/src/extract/semantic.d.ts.map +1 -0
  84. package/bundled-graph/dist/src/extract/semantic.js +242 -0
  85. package/bundled-graph/dist/src/extract/semantic.js.map +1 -0
  86. package/bundled-graph/dist/src/extract/tree-sitter-runner.d.ts +48 -0
  87. package/bundled-graph/dist/src/extract/tree-sitter-runner.d.ts.map +1 -0
  88. package/bundled-graph/dist/src/extract/tree-sitter-runner.js +137 -0
  89. package/bundled-graph/dist/src/extract/tree-sitter-runner.js.map +1 -0
  90. package/bundled-graph/dist/src/extract/types.d.ts +7 -0
  91. package/bundled-graph/dist/src/extract/types.d.ts.map +1 -0
  92. package/bundled-graph/dist/src/extract/types.js +2 -0
  93. package/bundled-graph/dist/src/extract/types.js.map +1 -0
  94. package/bundled-graph/dist/src/index.d.ts +28 -0
  95. package/bundled-graph/dist/src/index.d.ts.map +1 -0
  96. package/bundled-graph/dist/src/index.js +26 -0
  97. package/bundled-graph/dist/src/index.js.map +1 -0
  98. package/bundled-graph/dist/src/pipeline.d.ts +27 -0
  99. package/bundled-graph/dist/src/pipeline.d.ts.map +1 -0
  100. package/bundled-graph/dist/src/pipeline.js +269 -0
  101. package/bundled-graph/dist/src/pipeline.js.map +1 -0
  102. package/bundled-graph/dist/src/report.d.ts +26 -0
  103. package/bundled-graph/dist/src/report.d.ts.map +1 -0
  104. package/bundled-graph/dist/src/report.js +214 -0
  105. package/bundled-graph/dist/src/report.js.map +1 -0
  106. package/bundled-graph/dist/src/types.d.ts +124 -0
  107. package/bundled-graph/dist/src/types.d.ts.map +1 -0
  108. package/bundled-graph/dist/src/types.js +2 -0
  109. package/bundled-graph/dist/src/types.js.map +1 -0
  110. package/bundled-graph/dist/src/visualize.d.ts +4 -0
  111. package/bundled-graph/dist/src/visualize.d.ts.map +1 -0
  112. package/bundled-graph/dist/src/visualize.js +574 -0
  113. package/bundled-graph/dist/src/visualize.js.map +1 -0
  114. package/bundled-graph/dist/tsconfig.tsbuildinfo +1 -0
  115. package/bundled-graph/package.json +57 -0
  116. package/package.json +9 -2
@@ -0,0 +1,120 @@
1
+ import Graph from 'graphology';
2
+ export async function detectCommunities(graph) {
3
+ let louvainFn = null;
4
+ try {
5
+ const mod = await import('graphology-communities-louvain');
6
+ louvainFn = mod.default;
7
+ }
8
+ catch { /* louvain not available */ }
9
+ if (louvainFn) {
10
+ try {
11
+ const assignment = louvainFn(graph);
12
+ for (const [nodeId, communityId] of Object.entries(assignment)) {
13
+ graph.setNodeAttribute(nodeId, 'community', communityId);
14
+ }
15
+ const communities = {};
16
+ for (const [nodeId, communityId] of Object.entries(assignment)) {
17
+ if (!communities[communityId])
18
+ communities[communityId] = [];
19
+ communities[communityId].push(nodeId);
20
+ }
21
+ return splitOversizedCommunities(graph, communities, 0.25, louvainFn);
22
+ }
23
+ catch { /* fall through */ }
24
+ }
25
+ return splitOversizedCommunities(graph, fallbackCluster(graph), 0.25, louvainFn);
26
+ }
27
+ function fallbackCluster(graph) {
28
+ const dirMap = new Map();
29
+ let nextId = 0;
30
+ const communities = {};
31
+ graph.forEachNode((id, attrs) => {
32
+ const file = attrs.sourceFile || '';
33
+ const parts = file.split('/');
34
+ const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : 'root';
35
+ if (!dirMap.has(dir))
36
+ dirMap.set(dir, nextId++);
37
+ const cid = dirMap.get(dir);
38
+ graph.setNodeAttribute(id, 'community', cid);
39
+ if (!communities[cid])
40
+ communities[cid] = [];
41
+ communities[cid].push(id);
42
+ });
43
+ return communities;
44
+ }
45
+ export function cohesionScore(graph, communityNodes) {
46
+ const memberSet = new Set(communityNodes);
47
+ let totalEdges = 0;
48
+ let internalEdges = 0;
49
+ graph.forEachEdge((_edge, _attrs, source, target) => {
50
+ const srcIn = memberSet.has(source);
51
+ const tgtIn = memberSet.has(target);
52
+ if (srcIn || tgtIn) {
53
+ totalEdges++;
54
+ if (srcIn && tgtIn)
55
+ internalEdges++;
56
+ }
57
+ });
58
+ return totalEdges === 0 ? 1.0 : internalEdges / totalEdges;
59
+ }
60
+ export function splitOversizedCommunities(graph, communities, threshold = 0.25, louvainFn = null) {
61
+ const maxSize = threshold * graph.order;
62
+ const allIds = Object.keys(communities).map(Number);
63
+ let nextId = allIds.length > 0 ? Math.max(...allIds) + 1 : 0;
64
+ for (const [cidStr, members] of Object.entries(communities)) {
65
+ if (members.length <= maxSize)
66
+ continue;
67
+ const cid = Number(cidStr);
68
+ // Attempt topology-based second pass via Louvain on the community subgraph
69
+ if (louvainFn && members.length >= 10) {
70
+ try {
71
+ const memberSet = new Set(members);
72
+ const subG = new Graph({ type: 'undirected', multi: false });
73
+ for (const nodeId of members)
74
+ subG.addNode(nodeId);
75
+ graph.forEachEdge((_e, _a, source, target) => {
76
+ if (memberSet.has(source) && memberSet.has(target) && source !== target && !subG.hasEdge(source, target))
77
+ subG.addEdge(source, target);
78
+ });
79
+ const subAssignment = louvainFn(subG);
80
+ const subCommunityCount = new Set(Object.values(subAssignment)).size;
81
+ if (subCommunityCount > 1 && subCommunityCount <= Math.ceil(members.length / 2)) {
82
+ const subIdMap = new Map();
83
+ const newSubIds = {};
84
+ for (const [nodeId, localId] of Object.entries(subAssignment)) {
85
+ if (!subIdMap.has(localId))
86
+ subIdMap.set(localId, nextId++);
87
+ const globalId = subIdMap.get(localId);
88
+ graph.setNodeAttribute(nodeId, 'community', globalId);
89
+ if (!newSubIds[globalId])
90
+ newSubIds[globalId] = [];
91
+ newSubIds[globalId].push(nodeId);
92
+ }
93
+ delete communities[cid];
94
+ Object.assign(communities, newSubIds);
95
+ continue;
96
+ }
97
+ }
98
+ catch { /* fall through to directory heuristic */ }
99
+ }
100
+ // Directory heuristic fallback
101
+ const subMap = new Map();
102
+ const newSubIds = {};
103
+ for (const nodeId of members) {
104
+ const file = graph.getNodeAttribute(nodeId, 'sourceFile') || '';
105
+ const parts = file.split('/');
106
+ const parentDir = parts.length > 1 ? parts[parts.length - 2] : 'root';
107
+ if (!subMap.has(parentDir))
108
+ subMap.set(parentDir, nextId++);
109
+ const subId = subMap.get(parentDir);
110
+ graph.setNodeAttribute(nodeId, 'community', subId);
111
+ if (!newSubIds[subId])
112
+ newSubIds[subId] = [];
113
+ newSubIds[subId].push(nodeId);
114
+ }
115
+ delete communities[cid];
116
+ Object.assign(communities, newSubIds);
117
+ }
118
+ return communities;
119
+ }
120
+ //# sourceMappingURL=cluster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster.js","sourceRoot":"","sources":["../../src/cluster.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { BuildOptions, ClassifiedFile } from './types.js';
2
+ /**
3
+ * Walks up the directory tree from rootPath to the filesystem root,
4
+ * collecting patterns from any `.graphifyignore` files found along the way.
5
+ * Lines beginning with `#` are comments; blank lines are skipped.
6
+ * Returns the combined list of pattern strings (closest dir first).
7
+ */
8
+ export declare function loadIgnorePatterns(rootPath: string): string[];
9
+ /**
10
+ * Recursively collects and classifies all files under rootPath, applying
11
+ * exclusion rules for directories, file size limits, security-sensitive filenames,
12
+ * .graphifyignore patterns, and optional language filtering from BuildOptions.
13
+ */
14
+ export declare function collectFiles(rootPath: string, options?: BuildOptions): ClassifiedFile[];
15
+ /**
16
+ * Analyses a collected file corpus and returns a list of human-readable warning
17
+ * strings describing potential issues. Returns an empty array when the corpus
18
+ * looks healthy.
19
+ */
20
+ export declare function corpusHealth(files: ClassifiedFile[]): string[];
21
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/detect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAY,MAAM,YAAY,CAAC;AA6EzE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAuB7D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,YAAiB,GACzB,cAAc,EAAE,CAuDlB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAsC9D"}
@@ -0,0 +1,195 @@
1
+ import { readdirSync, readFileSync, statSync } from 'fs';
2
+ import { join, extname, relative, dirname } from 'path';
3
+ const DEFAULT_MAX_FILE_SIZE = 500 * 1024; // 500KB
4
+ const EXCLUDED_DIRS = new Set([
5
+ 'node_modules', '.git', 'dist', 'build', '.monomind',
6
+ '__pycache__', '.pytest_cache', 'target', '.cache',
7
+ ]);
8
+ // Maps file extension to [fileType, language]
9
+ const EXTENSION_MAP = {
10
+ '.ts': ['code', 'typescript'], '.tsx': ['code', 'typescript'],
11
+ '.mts': ['code', 'typescript'], '.cts': ['code', 'typescript'],
12
+ '.js': ['code', 'javascript'], '.jsx': ['code', 'javascript'],
13
+ '.mjs': ['code', 'javascript'], '.cjs': ['code', 'javascript'],
14
+ '.py': ['code', 'python'], '.go': ['code', 'go'],
15
+ '.rs': ['code', 'rust'], '.java': ['code', 'java'],
16
+ '.c': ['code', 'c'], '.cpp': ['code', 'cpp'],
17
+ '.h': ['code', 'c'], '.cs': ['code', 'csharp'],
18
+ '.rb': ['code', 'ruby'], '.php': ['code', 'php'],
19
+ '.swift': ['code', 'swift'], '.kt': ['code', 'kotlin'],
20
+ '.scala': ['code', 'scala'], '.md': ['document', 'markdown'],
21
+ '.txt': ['document', 'text'], '.rst': ['document', 'rst'],
22
+ };
23
+ // Patterns matching filenames/paths that may contain credentials or secrets.
24
+ // Matched against both the basename and the relative path.
25
+ const SECURITY_SENSITIVE_PATTERNS = [
26
+ // .env files
27
+ /^\.env(\.|$)/i,
28
+ /[/\\]\.env(\.|$)/i,
29
+ // PEM / key files
30
+ /\.(pem|key|p12|pfx)$/i,
31
+ // SSH private keys
32
+ /\b(id_rsa|id_dsa|id_ecdsa|id_ed25519)(\.[^/\\]*)?$/i,
33
+ // Credential / secret JSON / YAML
34
+ /\bcredentials\.json$/i,
35
+ /\bsecrets?\.(json|ya?ml)$/i,
36
+ // AWS
37
+ /\baws-credentials$/i,
38
+ /[/\\]\.aws[/\\]credentials$/i,
39
+ // GCP / Firebase
40
+ /\bservice-?account\.json$/i,
41
+ /\bclient_secret\.json$/i,
42
+ /\bgoogle-credentials\.json$/i,
43
+ /\bfirebase[^/\\]*\.json$/i,
44
+ // Auth-related
45
+ /\bprivate\.key$/i,
46
+ /\bprivate_key\.json$/i,
47
+ /\.htpasswd$/i,
48
+ /\bshadow$/i,
49
+ /\bvault-token$/i,
50
+ /\.token$/i,
51
+ /\bauth\.json$/i,
52
+ // Package auth files
53
+ /\.npmrc$/i,
54
+ /\.pypirc$/i,
55
+ /\bnetrc$/i,
56
+ /\.pgpass$/i,
57
+ ];
58
+ /** Returns true if the given basename or relative path matches any security-sensitive pattern. */
59
+ function isSecuritySensitive(basename, relPath) {
60
+ return SECURITY_SENSITIVE_PATTERNS.some((re) => re.test(basename) || re.test(relPath));
61
+ }
62
+ /**
63
+ * Converts a .graphifyignore pattern line into a RegExp.
64
+ * Escapes regex special chars then converts `*` to `.*`.
65
+ */
66
+ function patternToRegex(pattern) {
67
+ const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*');
68
+ return new RegExp(escaped);
69
+ }
70
+ /**
71
+ * Walks up the directory tree from rootPath to the filesystem root,
72
+ * collecting patterns from any `.graphifyignore` files found along the way.
73
+ * Lines beginning with `#` are comments; blank lines are skipped.
74
+ * Returns the combined list of pattern strings (closest dir first).
75
+ */
76
+ export function loadIgnorePatterns(rootPath) {
77
+ const patterns = [];
78
+ let current = rootPath;
79
+ while (true) {
80
+ const candidate = join(current, '.graphifyignore');
81
+ try {
82
+ const contents = readFileSync(candidate, 'utf8');
83
+ for (const line of contents.split(/\r?\n/)) {
84
+ const trimmed = line.trim();
85
+ if (trimmed && !trimmed.startsWith('#')) {
86
+ patterns.push(trimmed);
87
+ }
88
+ }
89
+ }
90
+ catch {
91
+ // File does not exist or is unreadable at this level — continue walking up
92
+ }
93
+ const parent = dirname(current);
94
+ if (parent === current)
95
+ break; // reached filesystem root
96
+ current = parent;
97
+ }
98
+ return patterns;
99
+ }
100
+ /**
101
+ * Recursively collects and classifies all files under rootPath, applying
102
+ * exclusion rules for directories, file size limits, security-sensitive filenames,
103
+ * .graphifyignore patterns, and optional language filtering from BuildOptions.
104
+ */
105
+ export function collectFiles(rootPath, options = {}) {
106
+ const maxFileSizeBytes = options.maxFileSizeBytes ?? DEFAULT_MAX_FILE_SIZE;
107
+ const codeOnly = options.codeOnly ?? false;
108
+ const languageFilter = options.languages ? new Set(options.languages) : null;
109
+ const excludePatterns = options.excludePatterns ?? [];
110
+ // Load .graphifyignore patterns and compile to regexes
111
+ const ignorePatternStrings = loadIgnorePatterns(rootPath);
112
+ const ignoreRegexes = ignorePatternStrings.map(patternToRegex);
113
+ const results = [];
114
+ function walkDir(dirPath) {
115
+ let entries;
116
+ try {
117
+ entries = readdirSync(dirPath);
118
+ }
119
+ catch {
120
+ return;
121
+ }
122
+ for (const entry of entries) {
123
+ const fullPath = join(dirPath, entry);
124
+ const relPath = relative(rootPath, fullPath);
125
+ // Check against caller-supplied exclude patterns
126
+ if (excludePatterns.some((pat) => relPath.includes(pat)))
127
+ continue;
128
+ // Check against .graphifyignore patterns
129
+ if (ignoreRegexes.some((re) => re.test(relPath)))
130
+ continue;
131
+ let stat;
132
+ try {
133
+ stat = statSync(fullPath);
134
+ }
135
+ catch {
136
+ continue;
137
+ }
138
+ if (stat.isDirectory()) {
139
+ if (EXCLUDED_DIRS.has(entry))
140
+ continue;
141
+ walkDir(fullPath);
142
+ continue;
143
+ }
144
+ if (!stat.isFile())
145
+ continue;
146
+ if (stat.size > maxFileSizeBytes)
147
+ continue;
148
+ // Skip security-sensitive files
149
+ if (isSecuritySensitive(entry, relPath))
150
+ continue;
151
+ const ext = extname(entry).toLowerCase();
152
+ const mapping = EXTENSION_MAP[ext];
153
+ if (!mapping)
154
+ continue;
155
+ const [fileType, language] = mapping;
156
+ if (codeOnly && fileType !== 'code')
157
+ continue;
158
+ if (languageFilter && !languageFilter.has(language))
159
+ continue;
160
+ results.push({ path: fullPath, fileType, language, sizeBytes: stat.size });
161
+ }
162
+ }
163
+ walkDir(rootPath);
164
+ return results;
165
+ }
166
+ /**
167
+ * Analyses a collected file corpus and returns a list of human-readable warning
168
+ * strings describing potential issues. Returns an empty array when the corpus
169
+ * looks healthy.
170
+ */
171
+ export function corpusHealth(files) {
172
+ const warnings = [];
173
+ const codeFiles = files.filter((f) => f.fileType === 'code');
174
+ const docFiles = files.filter((f) => f.fileType === 'document');
175
+ const totalSize = files.reduce((sum, f) => sum + f.sizeBytes, 0);
176
+ if (codeFiles.length < 5) {
177
+ warnings.push(`Corpus is very small (${codeFiles.length} code files). Graph may be sparse.`);
178
+ }
179
+ if (totalSize < 50_000) {
180
+ const kb = Math.round(totalSize / 1024);
181
+ warnings.push(`Corpus total size is very small (~${kb}KB). Consider including more source files.`);
182
+ }
183
+ if (totalSize > 50_000_000) {
184
+ const mb = Math.round(totalSize / (1024 * 1024));
185
+ warnings.push(`Corpus is very large (~${mb}MB). Build may be slow. Consider using codeOnly or excludePatterns.`);
186
+ }
187
+ if (docFiles.length === 0) {
188
+ warnings.push('No documentation files found. Graph will have no document nodes.');
189
+ }
190
+ if (files.length > 0 && docFiles.length / files.length > 0.8) {
191
+ warnings.push('Corpus is mostly documentation. Consider codeOnly: true for a code-focused graph.');
192
+ }
193
+ return warnings;
194
+ }
195
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import Graph from 'graphology';
2
+ /**
3
+ * Serialize a graphology graph to disk as a JSON file.
4
+ * Creates the output directory if it does not exist.
5
+ * Returns the absolute path to the written file.
6
+ */
7
+ export declare function saveGraph(graph: Graph, outputDir: string, projectPath: string): string;
8
+ /**
9
+ * Deserialize a graph from a previously saved JSON file.
10
+ * Silently skips edges whose endpoints are missing from the node list.
11
+ */
12
+ export declare function loadGraph(graphPath: string): Graph;
13
+ /**
14
+ * Return true when a graph.json already exists in the given output directory.
15
+ */
16
+ export declare function graphExists(outputDir: string): boolean;
17
+ /**
18
+ * Return the canonical path to graph.json inside an output directory.
19
+ */
20
+ export declare function getGraphPath(outputDir: string): string;
21
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/export.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,YAAY,CAAC;AAG/B;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAsBtF;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAyBlD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD"}
@@ -0,0 +1,68 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
2
+ import { join } from 'path';
3
+ import Graph from 'graphology';
4
+ /**
5
+ * Serialize a graphology graph to disk as a JSON file.
6
+ * Creates the output directory if it does not exist.
7
+ * Returns the absolute path to the written file.
8
+ */
9
+ export function saveGraph(graph, outputDir, projectPath) {
10
+ mkdirSync(outputDir, { recursive: true });
11
+ const graphPath = join(outputDir, 'graph.json');
12
+ const nodes = [];
13
+ graph.forEachNode((id, attrs) => nodes.push({ id, ...attrs }));
14
+ const links = [];
15
+ graph.forEachEdge((_, attrs, source, target) => links.push({ source, target, ...attrs }));
16
+ const serialized = {
17
+ version: '1.0.0',
18
+ builtAt: new Date().toISOString(),
19
+ projectPath,
20
+ nodes,
21
+ links,
22
+ directed: graph.type === 'directed',
23
+ multigraph: graph.multi,
24
+ };
25
+ writeFileSync(graphPath, JSON.stringify(serialized, null, 2), 'utf-8');
26
+ return graphPath;
27
+ }
28
+ /**
29
+ * Deserialize a graph from a previously saved JSON file.
30
+ * Silently skips edges whose endpoints are missing from the node list.
31
+ */
32
+ export function loadGraph(graphPath) {
33
+ const raw = readFileSync(graphPath, 'utf-8');
34
+ const data = JSON.parse(raw);
35
+ const graph = new Graph({
36
+ type: data.directed ? 'directed' : 'undirected',
37
+ multi: false,
38
+ });
39
+ for (const node of data.nodes) {
40
+ const { id, ...attrs } = node;
41
+ graph.addNode(id, attrs);
42
+ }
43
+ for (const link of data.links) {
44
+ const { source, target, ...attrs } = link;
45
+ if (!graph.hasNode(source) || !graph.hasNode(target))
46
+ continue;
47
+ try {
48
+ graph.addEdge(source, target, attrs);
49
+ }
50
+ catch {
51
+ // Duplicate edge — ignore
52
+ }
53
+ }
54
+ return graph;
55
+ }
56
+ /**
57
+ * Return true when a graph.json already exists in the given output directory.
58
+ */
59
+ export function graphExists(outputDir) {
60
+ return existsSync(join(outputDir, 'graph.json'));
61
+ }
62
+ /**
63
+ * Return the canonical path to graph.json inside an output directory.
64
+ */
65
+ export function getGraphPath(outputDir) {
66
+ return join(outputDir, 'graph.json');
67
+ }
68
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { ClassifiedFile, ExtractionResult, BuildOptions } from '../types.js';
2
+ /**
3
+ * Extract graph nodes and edges from all classified files.
4
+ *
5
+ * Reads each file, checks the on-disk cache keyed by SHA-256 content hash,
6
+ * dispatches to the appropriate language extractor, and merges all results
7
+ * into a single ExtractionResult (nodes deduplicated by id, edges by source+target+relation).
8
+ *
9
+ * @param files - Classified files to process (from the classify layer)
10
+ * @param outputDir - Directory used for cache storage (.monomind/graph by default)
11
+ * @param options - Build options (languages filter, maxFileSizeBytes, etc.)
12
+ */
13
+ export declare function extractAll(files: ClassifiedFile[], outputDir: string, options?: BuildOptions): Promise<ExtractionResult>;
14
+ export type { LanguageExtractor } from './types.js';
15
+ export { typescriptExtractor } from './languages/typescript.js';
16
+ export { pythonExtractor } from './languages/python.js';
17
+ export { goExtractor } from './languages/go.js';
18
+ export { rustExtractor } from './languages/rust.js';
19
+ export { isTreeSitterAvailable, tryLoadParser, walk, parseFile, parseFileFromDisk } from './tree-sitter-runner.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extract/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,YAAY,EAAwB,MAAM,aAAa,CAAC;AA+ExG;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,cAAc,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAqF3B;AAGD,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,158 @@
1
+ import { readFileSync, mkdirSync } from 'fs';
2
+ import { extname } from 'path';
3
+ import { FileCache } from '../cache.js';
4
+ import { typescriptExtractor } from './languages/typescript.js';
5
+ import { pythonExtractor } from './languages/python.js';
6
+ import { goExtractor } from './languages/go.js';
7
+ import { rustExtractor } from './languages/rust.js';
8
+ // ---- registry ----
9
+ const EXTRACTORS = [
10
+ typescriptExtractor,
11
+ pythonExtractor,
12
+ goExtractor,
13
+ rustExtractor,
14
+ ];
15
+ /** Build a lookup from file extension → extractor */
16
+ const EXT_MAP = new Map(EXTRACTORS.flatMap((e) => e.extensions.map((ext) => [ext, e])));
17
+ /** Build a lookup from language name → extractor */
18
+ const LANG_MAP = new Map(EXTRACTORS.map((e) => [e.language, e]));
19
+ function resolveExtractor(file) {
20
+ if (file.language) {
21
+ const byLang = LANG_MAP.get(file.language.toLowerCase());
22
+ if (byLang)
23
+ return byLang;
24
+ }
25
+ const ext = extname(file.path).toLowerCase();
26
+ return EXT_MAP.get(ext) ?? null;
27
+ }
28
+ // ---- result merging ----
29
+ function mergeResults(results) {
30
+ const nodeMap = new Map();
31
+ const edgeSet = new Set();
32
+ const edges = [];
33
+ const errors = [];
34
+ let filesProcessed = 0;
35
+ let fromCache = 0;
36
+ for (const r of results) {
37
+ filesProcessed += r.filesProcessed;
38
+ fromCache += r.fromCache;
39
+ errors.push(...r.errors);
40
+ for (const node of r.nodes) {
41
+ // Deduplicate by id — keep the first occurrence
42
+ if (!nodeMap.has(node.id)) {
43
+ nodeMap.set(node.id, node);
44
+ }
45
+ }
46
+ for (const edge of r.edges) {
47
+ // Deduplicate edges by source+target+relation key
48
+ const key = `${edge.source}||${edge.target}||${edge.relation}`;
49
+ if (!edgeSet.has(key)) {
50
+ edgeSet.add(key);
51
+ edges.push(edge);
52
+ }
53
+ }
54
+ }
55
+ return {
56
+ nodes: Array.from(nodeMap.values()),
57
+ edges,
58
+ filesProcessed,
59
+ fromCache,
60
+ errors,
61
+ };
62
+ }
63
+ // ---- public API ----
64
+ /**
65
+ * Extract graph nodes and edges from all classified files.
66
+ *
67
+ * Reads each file, checks the on-disk cache keyed by SHA-256 content hash,
68
+ * dispatches to the appropriate language extractor, and merges all results
69
+ * into a single ExtractionResult (nodes deduplicated by id, edges by source+target+relation).
70
+ *
71
+ * @param files - Classified files to process (from the classify layer)
72
+ * @param outputDir - Directory used for cache storage (.monomind/graph by default)
73
+ * @param options - Build options (languages filter, maxFileSizeBytes, etc.)
74
+ */
75
+ export async function extractAll(files, outputDir, options) {
76
+ const maxSize = options?.maxFileSizeBytes ?? 500 * 1024; // 500 KB
77
+ const langFilter = options?.languages?.map((l) => l.toLowerCase());
78
+ mkdirSync(outputDir, { recursive: true });
79
+ const cache = new FileCache(outputDir);
80
+ const results = [];
81
+ for (const file of files) {
82
+ // Skip files that are too large
83
+ if (file.sizeBytes > maxSize) {
84
+ results.push({
85
+ nodes: [],
86
+ edges: [],
87
+ filesProcessed: 1,
88
+ fromCache: 0,
89
+ errors: [`Skipped ${file.path}: file size ${file.sizeBytes} exceeds limit ${maxSize}`],
90
+ });
91
+ continue;
92
+ }
93
+ // Apply language filter
94
+ if (langFilter && langFilter.length > 0) {
95
+ const extractor = resolveExtractor(file);
96
+ const fileLang = (file.language ?? '').toLowerCase();
97
+ const extractorLang = extractor?.language ?? '';
98
+ if (!langFilter.includes(fileLang) && !langFilter.includes(extractorLang)) {
99
+ continue;
100
+ }
101
+ }
102
+ const extractor = resolveExtractor(file);
103
+ if (!extractor) {
104
+ // No extractor for this file type — skip silently
105
+ continue;
106
+ }
107
+ // Read content
108
+ let content;
109
+ try {
110
+ content = readFileSync(file.path, 'utf8');
111
+ }
112
+ catch (err) {
113
+ results.push({
114
+ nodes: [],
115
+ edges: [],
116
+ filesProcessed: 1,
117
+ fromCache: 0,
118
+ errors: [`Failed to read ${file.path}: ${err instanceof Error ? err.message : String(err)}`],
119
+ });
120
+ continue;
121
+ }
122
+ // Check cache using FileCache (keyed on filePath + content hash)
123
+ const cacheKey = cache.key(file.path, content);
124
+ const cached = cache.get(cacheKey);
125
+ if (cached) {
126
+ results.push({
127
+ ...cached,
128
+ filesProcessed: 1,
129
+ fromCache: 1,
130
+ });
131
+ continue;
132
+ }
133
+ // Extract
134
+ let result;
135
+ try {
136
+ result = extractor.extract(file.path, content);
137
+ }
138
+ catch (err) {
139
+ result = {
140
+ nodes: [],
141
+ edges: [],
142
+ filesProcessed: 1,
143
+ fromCache: 0,
144
+ errors: [`Extractor error for ${file.path}: ${err instanceof Error ? err.message : String(err)}`],
145
+ };
146
+ }
147
+ // Store in cache
148
+ cache.set(cacheKey, result);
149
+ results.push(result);
150
+ }
151
+ return mergeResults(results);
152
+ }
153
+ export { typescriptExtractor } from './languages/typescript.js';
154
+ export { pythonExtractor } from './languages/python.js';
155
+ export { goExtractor } from './languages/go.js';
156
+ export { rustExtractor } from './languages/rust.js';
157
+ export { isTreeSitterAvailable, tryLoadParser, walk, parseFile, parseFileFromDisk } from './tree-sitter-runner.js';
158
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extract/index.ts"],"names":[],"mappings":"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"}