@monoes/monomindcli 1.6.3 → 1.6.5
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.
- package/.claude/commands/monomind-createtask.md +3 -3
- package/.claude/commands/monomind-do.md +2 -2
- package/.claude/commands/monomind-idea.md +2 -2
- package/.claude/helpers/graphify-freshen.cjs +15 -6
- package/README.md +307 -553
- package/bundled-graph/dist/src/analyze.d.ts +32 -0
- package/bundled-graph/dist/src/analyze.d.ts.map +1 -0
- package/bundled-graph/dist/src/analyze.js +297 -0
- package/bundled-graph/dist/src/analyze.js.map +1 -0
- package/bundled-graph/dist/src/build.d.ts +8 -0
- package/bundled-graph/dist/src/build.d.ts.map +1 -0
- package/bundled-graph/dist/src/build.js +73 -0
- package/bundled-graph/dist/src/build.js.map +1 -0
- package/bundled-graph/dist/src/cache.d.ts +12 -0
- package/bundled-graph/dist/src/cache.d.ts.map +1 -0
- package/bundled-graph/dist/src/cache.js +43 -0
- package/bundled-graph/dist/src/cache.js.map +1 -0
- package/bundled-graph/dist/src/cluster.d.ts +5 -0
- package/bundled-graph/dist/src/cluster.d.ts.map +1 -0
- package/bundled-graph/dist/src/cluster.js +120 -0
- package/bundled-graph/dist/src/cluster.js.map +1 -0
- package/bundled-graph/dist/src/detect.d.ts +21 -0
- package/bundled-graph/dist/src/detect.d.ts.map +1 -0
- package/bundled-graph/dist/src/detect.js +195 -0
- package/bundled-graph/dist/src/detect.js.map +1 -0
- package/bundled-graph/dist/src/export.d.ts +21 -0
- package/bundled-graph/dist/src/export.d.ts.map +1 -0
- package/bundled-graph/dist/src/export.js +68 -0
- package/bundled-graph/dist/src/export.js.map +1 -0
- package/bundled-graph/dist/src/extract/index.d.ts +20 -0
- package/bundled-graph/dist/src/extract/index.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/index.js +158 -0
- package/bundled-graph/dist/src/extract/index.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/c.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/c.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/c.js +88 -0
- package/bundled-graph/dist/src/extract/languages/c.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/cpp.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/cpp.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/cpp.js +121 -0
- package/bundled-graph/dist/src/extract/languages/cpp.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/csharp.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/csharp.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/csharp.js +121 -0
- package/bundled-graph/dist/src/extract/languages/csharp.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/go.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/go.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/go.js +181 -0
- package/bundled-graph/dist/src/extract/languages/go.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/java.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/java.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/java.js +117 -0
- package/bundled-graph/dist/src/extract/languages/java.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/kotlin.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/kotlin.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/kotlin.js +112 -0
- package/bundled-graph/dist/src/extract/languages/kotlin.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/php.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/php.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/php.js +130 -0
- package/bundled-graph/dist/src/extract/languages/php.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/python.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/python.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/python.js +230 -0
- package/bundled-graph/dist/src/extract/languages/python.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/ruby.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/ruby.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/ruby.js +120 -0
- package/bundled-graph/dist/src/extract/languages/ruby.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/rust.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/rust.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/rust.js +195 -0
- package/bundled-graph/dist/src/extract/languages/rust.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/scala.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/scala.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/scala.js +110 -0
- package/bundled-graph/dist/src/extract/languages/scala.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/swift.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/swift.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/swift.js +122 -0
- package/bundled-graph/dist/src/extract/languages/swift.js.map +1 -0
- package/bundled-graph/dist/src/extract/languages/typescript.d.ts +3 -0
- package/bundled-graph/dist/src/extract/languages/typescript.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/languages/typescript.js +295 -0
- package/bundled-graph/dist/src/extract/languages/typescript.js.map +1 -0
- package/bundled-graph/dist/src/extract/semantic.d.ts +38 -0
- package/bundled-graph/dist/src/extract/semantic.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/semantic.js +242 -0
- package/bundled-graph/dist/src/extract/semantic.js.map +1 -0
- package/bundled-graph/dist/src/extract/tree-sitter-runner.d.ts +48 -0
- package/bundled-graph/dist/src/extract/tree-sitter-runner.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/tree-sitter-runner.js +137 -0
- package/bundled-graph/dist/src/extract/tree-sitter-runner.js.map +1 -0
- package/bundled-graph/dist/src/extract/types.d.ts +7 -0
- package/bundled-graph/dist/src/extract/types.d.ts.map +1 -0
- package/bundled-graph/dist/src/extract/types.js +2 -0
- package/bundled-graph/dist/src/extract/types.js.map +1 -0
- package/bundled-graph/dist/src/index.d.ts +28 -0
- package/bundled-graph/dist/src/index.d.ts.map +1 -0
- package/bundled-graph/dist/src/index.js +26 -0
- package/bundled-graph/dist/src/index.js.map +1 -0
- package/bundled-graph/dist/src/pipeline.d.ts +27 -0
- package/bundled-graph/dist/src/pipeline.d.ts.map +1 -0
- package/bundled-graph/dist/src/pipeline.js +269 -0
- package/bundled-graph/dist/src/pipeline.js.map +1 -0
- package/bundled-graph/dist/src/report.d.ts +26 -0
- package/bundled-graph/dist/src/report.d.ts.map +1 -0
- package/bundled-graph/dist/src/report.js +214 -0
- package/bundled-graph/dist/src/report.js.map +1 -0
- package/bundled-graph/dist/src/types.d.ts +124 -0
- package/bundled-graph/dist/src/types.d.ts.map +1 -0
- package/bundled-graph/dist/src/types.js +2 -0
- package/bundled-graph/dist/src/types.js.map +1 -0
- package/bundled-graph/dist/src/visualize.d.ts +4 -0
- package/bundled-graph/dist/src/visualize.d.ts.map +1 -0
- package/bundled-graph/dist/src/visualize.js +574 -0
- package/bundled-graph/dist/src/visualize.js.map +1 -0
- package/bundled-graph/dist/tsconfig.tsbuildinfo +1 -0
- package/bundled-graph/package.json +57 -0
- package/dist/src/commands/memory.d.ts.map +1 -1
- package/dist/src/commands/memory.js +0 -1
- package/dist/src/commands/memory.js.map +1 -1
- package/dist/src/init/executor.d.ts.map +1 -1
- package/dist/src/init/executor.js +6 -1
- package/dist/src/init/executor.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -2
- /package/.claude/commands/{monobrain-help.md → monomind-help.md} +0 -0
- /package/.claude/commands/{monobrain-memory.md → monomind-memory.md} +0 -0
- /package/.claude/commands/{monobrain-swarm.md → monomind-swarm.md} +0 -0
|
@@ -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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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c.d.ts","sourceRoot":"","sources":["../../../../src/extract/languages/c.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA0FrD,eAAO,MAAM,UAAU,EAAE,iBAQxB,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { basename } from 'path';
|
|
2
|
+
import { tryLoadParser, walk } from '../tree-sitter-runner.js';
|
|
3
|
+
function loc(node) {
|
|
4
|
+
return `L${node.startPosition.row + 1}`;
|
|
5
|
+
}
|
|
6
|
+
function extractWithTreeSitter(filePath, content) {
|
|
7
|
+
const nodes = [];
|
|
8
|
+
const edges = [];
|
|
9
|
+
const errors = [];
|
|
10
|
+
const parser = tryLoadParser('c');
|
|
11
|
+
if (!parser)
|
|
12
|
+
return { nodes, edges, filesProcessed: 1, fromCache: 0, errors };
|
|
13
|
+
let tree;
|
|
14
|
+
try {
|
|
15
|
+
tree = parser.parse(content);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
errors.push(`tree-sitter parse error in ${filePath}: ${String(err)}`);
|
|
19
|
+
return { nodes, edges, filesProcessed: 1, fromCache: 0, errors };
|
|
20
|
+
}
|
|
21
|
+
walk(tree.rootNode, (n) => {
|
|
22
|
+
if (n.type === 'function_definition') {
|
|
23
|
+
const declarator = n.childForFieldName('declarator');
|
|
24
|
+
const nameNode = declarator?.childForFieldName('declarator') ?? declarator;
|
|
25
|
+
const name = nameNode?.type === 'identifier' ? nameNode.text : (nameNode?.childForFieldName('name')?.text ?? '');
|
|
26
|
+
if (name)
|
|
27
|
+
nodes.push({ id: name, label: name, fileType: 'code', sourceFile: filePath, sourceLocation: loc(n) });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (n.type === 'struct_specifier' || n.type === 'union_specifier' || n.type === 'enum_specifier') {
|
|
31
|
+
const nameNode = n.childForFieldName('name');
|
|
32
|
+
if (nameNode?.text) {
|
|
33
|
+
nodes.push({ id: nameNode.text, label: nameNode.text, fileType: 'code', sourceFile: filePath, sourceLocation: loc(n), nodeKind: n.type.replace('_specifier', '') });
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (n.type === 'preproc_include') {
|
|
38
|
+
const pathNode = n.childForFieldName('path');
|
|
39
|
+
if (pathNode) {
|
|
40
|
+
const importPath = pathNode.text.replace(/^["<]|[">]$/g, '');
|
|
41
|
+
edges.push({ source: basename(filePath), target: importPath, relation: 'imports', confidence: 'EXTRACTED', sourceFile: filePath, sourceLocation: loc(n) });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
return { nodes, edges, filesProcessed: 1, fromCache: 0, errors };
|
|
46
|
+
}
|
|
47
|
+
function extractWithRegex(filePath, content) {
|
|
48
|
+
const nodes = [];
|
|
49
|
+
const edges = [];
|
|
50
|
+
const lines = content.split('\n');
|
|
51
|
+
lines.forEach((line, idx) => {
|
|
52
|
+
const location = `L${idx + 1}`;
|
|
53
|
+
const trimmed = line.trim();
|
|
54
|
+
// #include
|
|
55
|
+
const includeMatch = trimmed.match(/^#include\s+["<]([^">]+)[">]/);
|
|
56
|
+
if (includeMatch) {
|
|
57
|
+
edges.push({ source: basename(filePath), target: includeMatch[1], relation: 'imports', confidence: 'EXTRACTED', sourceFile: filePath, sourceLocation: location });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// struct / union / enum
|
|
61
|
+
const structMatch = trimmed.match(/^(?:typedef\s+)?(?:struct|union|enum)\s+(\w+)/);
|
|
62
|
+
if (structMatch) {
|
|
63
|
+
nodes.push({ id: structMatch[1], label: structMatch[1], fileType: 'code', sourceFile: filePath, sourceLocation: location });
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// function definition: return_type func_name(
|
|
67
|
+
// Heuristic: line not starting with # or //, contains word followed by ( at reasonable position
|
|
68
|
+
if (!trimmed.startsWith('#') && !trimmed.startsWith('//') && !trimmed.startsWith('*')) {
|
|
69
|
+
const funcMatch = trimmed.match(/^(?:[\w*\s]+\s)?(\w+)\s*\((?!\s*\))/);
|
|
70
|
+
if (funcMatch && funcMatch[1] && !['if', 'while', 'for', 'switch', 'return', 'sizeof', 'typeof'].includes(funcMatch[1])) {
|
|
71
|
+
// Only emit if previous non-empty line doesn't end with = or , (avoid call expressions)
|
|
72
|
+
nodes.push({ id: funcMatch[1], label: funcMatch[1], fileType: 'code', sourceFile: filePath, sourceLocation: location });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return { nodes, edges, filesProcessed: 1, fromCache: 0, errors: [] };
|
|
77
|
+
}
|
|
78
|
+
export const cExtractor = {
|
|
79
|
+
language: 'c',
|
|
80
|
+
extensions: ['.c', '.h'],
|
|
81
|
+
extract(filePath, content) {
|
|
82
|
+
const ts = extractWithTreeSitter(filePath, content);
|
|
83
|
+
if (ts.nodes.length > 0 || ts.edges.length > 0 || ts.errors.length > 0)
|
|
84
|
+
return ts;
|
|
85
|
+
return extractWithRegex(filePath, content);
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=c.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c.js","sourceRoot":"","sources":["../../../../src/extract/languages/c.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cpp.d.ts","sourceRoot":"","sources":["../../../../src/extract/languages/cpp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA6HrD,eAAO,MAAM,YAAY,EAAE,iBAQ1B,CAAC"}
|