code-graph-llm 1.5.0 → 1.6.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.
package/index.js CHANGED
@@ -154,6 +154,7 @@ export function extractEdges(content) {
154
154
  async function generate(cwd = process.cwd()) {
155
155
  const files = [];
156
156
  const allEdges = [];
157
+ const incomingEdges = {}; // Map of projectPath -> count of incoming edges
157
158
 
158
159
  function walk(dir, ig) {
159
160
  let localIg = ig;
@@ -186,16 +187,26 @@ async function generate(cwd = process.cwd()) {
186
187
  if (SUPPORTED_EXTENSIONS.includes(ext)) {
187
188
  const content = fs.readFileSync(fullPath, 'utf8');
188
189
 
189
- // Extract file-level description
190
+ // Extract file-level description and tags
190
191
  const lines = content.split('\n');
191
192
  let fileDesc = '';
192
- for (let i = 0; i < Math.min(10, lines.length); i++) {
193
+ const tags = [];
194
+ for (let i = 0; i < lines.length; i++) {
193
195
  const line = lines[i].trim();
194
- if (line.startsWith('#!') || line === '') continue;
195
- if (line.startsWith('//') || line.startsWith('#') || line.startsWith('/*')) {
196
- fileDesc += line.replace(/[\/*#]/g, '').trim() + ' ';
197
- } else {
198
- break;
196
+ // Surface actionable tags
197
+ const tagMatch = line.match(/\b(TODO|FIXME|BUG|DEPRECATED):?\s*(.*)/i);
198
+ if (tagMatch) {
199
+ tags.push(`${tagMatch[1]}: ${tagMatch[2].substring(0, 50).trim()}`);
200
+ }
201
+
202
+ if (i < 10) {
203
+ if (line.startsWith('#!') || line === '') continue;
204
+ if (line.startsWith('//') || line.startsWith('#') || line.startsWith('/*')) {
205
+ fileDesc += line.replace(/[\/*#]/g, '').trim() + ' ';
206
+ } else if (fileDesc) {
207
+ // Stop if we hit non-comment code
208
+ break;
209
+ }
199
210
  }
200
211
  }
201
212
 
@@ -204,11 +215,38 @@ async function generate(cwd = process.cwd()) {
204
215
 
205
216
  if (!fileDesc.trim() && symbols.length > 0) fileDesc = `Contains ${symbols.length} symbols.`;
206
217
 
207
- files.push({ path: normalizedPath, desc: fileDesc.trim(), symbols });
218
+ // Identify core entry points
219
+ const isCore = /^(index|main|app|server|cli)\.(js|ts|py|go|rs|java|cpp)$/i.test(entry.name);
220
+
221
+ const fileObj = {
222
+ path: normalizedPath,
223
+ desc: fileDesc.trim(),
224
+ symbols,
225
+ tags: Array.from(new Set(tags)),
226
+ isCore,
227
+ outCount: dependencies.length
228
+ };
229
+ files.push(fileObj);
208
230
 
209
- // Collect Edges
231
+ // Collect Edges and track incoming
210
232
  dependencies.forEach(dep => {
211
- allEdges.push(`[${normalizedPath}] -> [imports] -> [${dep}]`);
233
+ let target = dep;
234
+ if (dep.startsWith('.')) {
235
+ // Resolve relative path to project-relative
236
+ const resolved = path.normalize(path.join(path.dirname(normalizedPath), dep));
237
+ target = resolved.replace(/\\/g, '/');
238
+ // Basic extension guesser
239
+ if (!path.extname(target)) {
240
+ for (const ex of SUPPORTED_EXTENSIONS) {
241
+ if (fs.existsSync(path.join(cwd, target + ex))) {
242
+ target += ex;
243
+ break;
244
+ }
245
+ }
246
+ }
247
+ }
248
+ allEdges.push(`[${normalizedPath}] -> [imports] -> [${target}]`);
249
+ incomingEdges[target] = (incomingEdges[target] || 0) + 1;
212
250
  });
213
251
  inheritance.forEach(inh => {
214
252
  allEdges.push(`[${inh.child}] -> [inherits] -> [${inh.parent}]`);
@@ -220,17 +258,30 @@ async function generate(cwd = process.cwd()) {
220
258
 
221
259
  walk(cwd, getIgnores(cwd));
222
260
 
261
+ // Sort: Core files first, then by incoming edges (importance)
262
+ files.sort((a, b) => {
263
+ if (a.isCore && !b.isCore) return -1;
264
+ if (!a.isCore && b.isCore) return 1;
265
+ const inA = incomingEdges[a.path] || 0;
266
+ const inB = incomingEdges[b.path] || 0;
267
+ return inB - inA;
268
+ });
269
+
223
270
  const nodesOutput = files.map(f => {
271
+ const inCount = incomingEdges[f.path] || 0;
272
+ const coreMark = f.isCore ? '[CORE] ' : '';
273
+ const stats = `(↑${f.outCount} ↓${inCount})`;
274
+ const tagStr = f.tags.length > 0 ? ` [${f.tags.join(', ')}]` : '';
224
275
  const descStr = f.desc ? ` | desc: ${f.desc.substring(0, 100)}` : '';
225
276
  const symStr = f.symbols.length > 0 ? `\n - syms: [${f.symbols.join(', ')}]` : '';
226
- return `- ${f.path}${descStr}${symStr}`;
277
+ return `- ${coreMark}${f.path} ${stats}${tagStr}${descStr}${symStr}`;
227
278
  }).join('\n');
228
279
 
229
280
  const edgesOutput = allEdges.length > 0
230
281
  ? `\n\n## GRAPH EDGES\n${Array.from(new Set(allEdges)).sort().join('\n')}`
231
282
  : '';
232
283
 
233
- const header = `# CODE_GRAPH_MAP\n> LLM_ONLY: DO NOT EDIT. COMPACT PROJECT MAP.\n\n`;
284
+ const header = `# CODE_GRAPH_MAP\n> LLM_ONLY: DO NOT EDIT. COMPACT PROJECT MAP.\n> Legend: [CORE] Entry Point, (↑N) Outgoing Deps, (↓M) Incoming Dependents\n> Notation: syms: [Name [Signature/Context]], desc: File Summary, [TAG: Context] Actionable items\n\n`;
234
285
  fs.writeFileSync(path.join(cwd, DEFAULT_MAP_FILE), header + nodesOutput + edgesOutput);
235
286
  console.log(`[Code-Graph] Updated ${DEFAULT_MAP_FILE}`);
236
287
  }
package/llm-code-graph.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # CODE_GRAPH_MAP
2
2
  > LLM_ONLY: DO NOT EDIT. COMPACT PROJECT MAP.
3
+ > Legend: [CORE] Entry Point, (↑N) Outgoing Deps, (↓M) Incoming Dependents
4
+ > Notation: syms: [Name [Signature/Context]], desc: File Summary, [TAG: Context] Actionable items
3
5
 
4
- - index.js | desc: Contains 5 symbols.
6
+ - [CORE] index.js (↑5 ↓1) [TODO: |FIXME|BUG|DEPRECATED):?\s*(.*)/i);] | desc: Contains 5 symbols.
5
7
  - syms: [SUPPORTED_EXTENSIONS [= [], extractSymbolsAndInheritance [(content)], generate [(cwd = process.cwd()], getIgnores [(cwd, additionalLines = [])], walk [(dir, ig)]]
6
- - test/index.test.js
8
+ - test/index.test.js (↑10 ↓0)
7
9
 
8
10
  ## GRAPH EDGES
9
11
  [index.js] -> [imports] -> [chokidar]
@@ -11,13 +13,13 @@
11
13
  [index.js] -> [imports] -> [ignore]
12
14
  [index.js] -> [imports] -> [path]
13
15
  [index.js] -> [imports] -> [url]
14
- [test/index.test.js] -> [imports] -> [../index.js]
15
- [test/index.test.js] -> [imports] -> [./local-file]
16
16
  [test/index.test.js] -> [imports] -> [assert]
17
17
  [test/index.test.js] -> [imports] -> [fs]
18
18
  [test/index.test.js] -> [imports] -> [header.h]
19
+ [test/index.test.js] -> [imports] -> [index.js]
19
20
  [test/index.test.js] -> [imports] -> [node]
20
21
  [test/index.test.js] -> [imports] -> [other-module]
21
22
  [test/index.test.js] -> [imports] -> [path]
23
+ [test/index.test.js] -> [imports] -> [test/local-file]
22
24
  [test/index.test.js] -> [imports] -> [test]
23
25
  [test/index.test.js] -> [imports] -> [url]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-graph-llm",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Compact, language-agnostic codebase mapper for LLM token efficiency.",
5
5
  "main": "index.js",
6
6
  "bin": {