code-graph-llm 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.
- package/README.md +117 -0
- package/index.js +131 -0
- package/llm-code-graph.md +8 -0
- package/package.json +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# CODE-GRAPH
|
|
2
|
+
|
|
3
|
+
A language-agnostic, ultra-compact codebase mapper designed specifically for LLM agents to optimize context and token usage.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### 1. Install via NPM (Recommended)
|
|
8
|
+
You can install **Code-Graph** globally or as a project-specific dependency without cloning the repository.
|
|
9
|
+
|
|
10
|
+
**Global Installation:**
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g code-graph-llm
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Local Project Dependency:**
|
|
16
|
+
```bash
|
|
17
|
+
npm install --save-dev code-graph-llm
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. Direct Usage
|
|
21
|
+
Once installed, you can run it from any project directory:
|
|
22
|
+
```bash
|
|
23
|
+
# Generate the map
|
|
24
|
+
code-graph generate
|
|
25
|
+
|
|
26
|
+
# Start the live watcher
|
|
27
|
+
code-graph watch
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage in Different Workflows
|
|
31
|
+
|
|
32
|
+
### 1. Node.js (package.json)
|
|
33
|
+
If installed as a dependency, add it to your scripts:
|
|
34
|
+
```json
|
|
35
|
+
"scripts": {
|
|
36
|
+
"postinstall": "code-graph generate",
|
|
37
|
+
"pretest": "code-graph generate"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Git Integration
|
|
42
|
+
Automatically update and stage `llm-code-graph.md` on every commit:
|
|
43
|
+
```bash
|
|
44
|
+
code-graph install-hook
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## LLM Usage & Token Efficiency
|
|
50
|
+
|
|
51
|
+
To achieve the best performance and minimize token consumption, follow these guidelines:
|
|
52
|
+
|
|
53
|
+
### 1. The "Read First" Rule
|
|
54
|
+
Always instruct the LLM agent to read `llm-code-graph.md` as its first step. It provides an immediate, high-level map without scanning every directory.
|
|
55
|
+
|
|
56
|
+
**Example System Prompt:**
|
|
57
|
+
> "Before performing any tasks, read `llm-code-graph.md` to understand the project structure. Use this map to target specific files rather than scanning the entire codebase."
|
|
58
|
+
|
|
59
|
+
### 2. Targeted File Reads
|
|
60
|
+
The `|syms:[...]` metadata allows the LLM to identify exactly which file contains a specific function or class. It can jump directly to the relevant file.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Language Examples & Build Phase Integration
|
|
65
|
+
|
|
66
|
+
### 1. Rust (build.rs)
|
|
67
|
+
```rust
|
|
68
|
+
use std::process::Command;
|
|
69
|
+
fn main() {
|
|
70
|
+
Command::new("code-graph").arg("generate").status().unwrap();
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 2. Java/Kotlin (Maven/Gradle)
|
|
75
|
+
|
|
76
|
+
#### Maven (pom.xml)
|
|
77
|
+
```xml
|
|
78
|
+
<plugin>
|
|
79
|
+
<groupId>org.codehaus.mojo</groupId>
|
|
80
|
+
<artifactId>exec-maven-plugin</artifactId>
|
|
81
|
+
<executions>
|
|
82
|
+
<execution>
|
|
83
|
+
<phase>compile</phase>
|
|
84
|
+
<goals><goal>exec</goal></goals>
|
|
85
|
+
<configuration>
|
|
86
|
+
<executable>code-graph</executable>
|
|
87
|
+
<arguments><argument>generate</argument></arguments>
|
|
88
|
+
</configuration>
|
|
89
|
+
</execution>
|
|
90
|
+
</executions>
|
|
91
|
+
</plugin>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### Gradle (Groovy DSL)
|
|
95
|
+
```groovy
|
|
96
|
+
task generateCodeGraph(type: Exec) {
|
|
97
|
+
commandLine 'code-graph', 'generate'
|
|
98
|
+
}
|
|
99
|
+
compileJava.dependsOn generateCodeGraph
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3. Python Integration
|
|
103
|
+
Add this to your `Makefile`:
|
|
104
|
+
```makefile
|
|
105
|
+
map:
|
|
106
|
+
code-graph generate
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## How it works
|
|
112
|
+
The tool scans your project directory (respecting `.gitignore`), extracts classes, functions, and exports using optimized regular expressions, and compiles them into a dense, machine-readable `llm-code-graph.md` file.
|
|
113
|
+
|
|
114
|
+
## Publishing as a Package (For Developers)
|
|
115
|
+
To publish this to the NPM registry:
|
|
116
|
+
1. Log in: `npm login`
|
|
117
|
+
2. Publish: `npm publish --access public` (Ensure the name in `package.json` is unique, e.g., `code-graph-llm`).
|
package/index.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import chokidar from 'chokidar';
|
|
7
|
+
import ignore from 'ignore';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
|
|
12
|
+
const IGNORE_FILE = '.gitignore';
|
|
13
|
+
const DEFAULT_MAP_FILE = 'llm-code-graph.md';
|
|
14
|
+
|
|
15
|
+
const SYMBOL_REGEXES = [
|
|
16
|
+
/\b(?:class|interface|type|struct|enum)\s+([a-zA-Z_]\w*)/g,
|
|
17
|
+
/\b(?:function|def|fn|func|void|fun)\s+([a-zA-Z_]\w*)/g,
|
|
18
|
+
/\bconst\s+([a-zA-Z_]\w*)\s*=\s*(?:async\s*)?\([^)]*\)\s*=>/g, // Arrow functions
|
|
19
|
+
/\bexport\s+(?:const|let|var|function|class|type|interface|enum)\s+([a-zA-Z_]\w*)/g
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
function getIgnores(cwd) {
|
|
23
|
+
const ig = ignore().add(['.git', 'node_modules', DEFAULT_MAP_FILE]);
|
|
24
|
+
const ignorePath = path.join(cwd, IGNORE_FILE);
|
|
25
|
+
if (fs.existsSync(ignorePath)) {
|
|
26
|
+
ig.add(fs.readFileSync(ignorePath, 'utf8'));
|
|
27
|
+
}
|
|
28
|
+
return ig;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function extractSymbols(content) {
|
|
32
|
+
const symbols = new Set();
|
|
33
|
+
for (const regex of SYMBOL_REGEXES) {
|
|
34
|
+
let match;
|
|
35
|
+
while ((match = regex.exec(content)) !== null) {
|
|
36
|
+
if (match[1]) symbols.add(match[1]);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return Array.from(symbols).sort();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function generate(cwd = process.cwd()) {
|
|
43
|
+
const ig = getIgnores(cwd);
|
|
44
|
+
const files = [];
|
|
45
|
+
|
|
46
|
+
function walk(dir) {
|
|
47
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
48
|
+
for (const entry of entries) {
|
|
49
|
+
const fullPath = path.join(dir, entry.name);
|
|
50
|
+
const relativePath = path.relative(cwd, fullPath);
|
|
51
|
+
|
|
52
|
+
if (ig.ignores(relativePath)) continue;
|
|
53
|
+
|
|
54
|
+
if (entry.isDirectory()) {
|
|
55
|
+
walk(fullPath);
|
|
56
|
+
} else if (entry.isFile()) {
|
|
57
|
+
const ext = path.extname(entry.name);
|
|
58
|
+
if (['.js', '.ts', '.py', '.go', '.rs', '.java', '.cpp', '.c', '.h', '.rb', '.php', '.swift', '.kt'].includes(ext)) {
|
|
59
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
60
|
+
const symbols = extractSymbols(content);
|
|
61
|
+
files.push({ path: relativePath, symbols });
|
|
62
|
+
} else {
|
|
63
|
+
files.push({ path: relativePath, symbols: [] });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
walk(cwd);
|
|
70
|
+
|
|
71
|
+
const output = files.map(f => {
|
|
72
|
+
const symStr = f.symbols.length > 0 ? `|syms:[${f.symbols.join(',')}]` : '';
|
|
73
|
+
return `- ${f.path}${symStr}`;
|
|
74
|
+
}).join('\n');
|
|
75
|
+
|
|
76
|
+
const header = `# CODE_GRAPH_MAP\n> LLM_ONLY: DO NOT EDIT. COMPACT PROJECT MAP.\n\n`;
|
|
77
|
+
fs.writeFileSync(path.join(cwd, DEFAULT_MAP_FILE), header + output);
|
|
78
|
+
console.log(`[Code-Graph] Updated ${DEFAULT_MAP_FILE}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function watch(cwd = process.cwd()) {
|
|
82
|
+
console.log(`[Code-Graph] Watching for changes in ${cwd}...`);
|
|
83
|
+
const ig = getIgnores(cwd);
|
|
84
|
+
|
|
85
|
+
const watcher = chokidar.watch(cwd, {
|
|
86
|
+
ignored: (p) => {
|
|
87
|
+
const rel = path.relative(cwd, p);
|
|
88
|
+
return rel && ig.ignores(rel);
|
|
89
|
+
},
|
|
90
|
+
persistent: true,
|
|
91
|
+
ignoreInitial: true
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
let timeout;
|
|
95
|
+
const debouncedGenerate = () => {
|
|
96
|
+
clearTimeout(timeout);
|
|
97
|
+
timeout = setTimeout(() => generate(cwd), 500);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
watcher.on('all', (event, path) => {
|
|
101
|
+
console.log(`[Code-Graph] Change detected: ${event} on ${path}`);
|
|
102
|
+
debouncedGenerate();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function installHook(cwd = process.cwd()) {
|
|
107
|
+
const hooksDir = path.join(cwd, '.git', 'hooks');
|
|
108
|
+
if (!fs.existsSync(hooksDir)) {
|
|
109
|
+
console.error('[Code-Graph] No .git directory found. Cannot install hook.');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const hookPath = path.join(hooksDir, 'pre-commit');
|
|
114
|
+
const hookContent = `#!/bin/sh\n# Code-Graph pre-commit hook\nnode "${__filename}" generate\ngit add "${DEFAULT_MAP_FILE}"\n`;
|
|
115
|
+
|
|
116
|
+
fs.writeFileSync(hookPath, hookContent, { mode: 0o755 });
|
|
117
|
+
console.log('[Code-Graph] Installed pre-commit hook.');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const args = process.argv.slice(2);
|
|
121
|
+
const command = args[0] || 'generate';
|
|
122
|
+
|
|
123
|
+
if (command === 'generate') {
|
|
124
|
+
generate();
|
|
125
|
+
} else if (command === 'watch') {
|
|
126
|
+
watch();
|
|
127
|
+
} else if (command === 'install-hook') {
|
|
128
|
+
installHook();
|
|
129
|
+
} else {
|
|
130
|
+
console.log('Usage: code-graph [generate|watch|install-hook]');
|
|
131
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "code-graph-llm",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Compact, language-agnostic codebase mapper for LLM token efficiency.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"code-graph": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"llm",
|
|
11
|
+
"context",
|
|
12
|
+
"token-efficiency",
|
|
13
|
+
"codebase-map",
|
|
14
|
+
"ai-agent",
|
|
15
|
+
"documentation"
|
|
16
|
+
],
|
|
17
|
+
"author": "Code-Graph Contributors",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/youruser/code-graph.git"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"chokidar": "^3.6.0",
|
|
25
|
+
"ignore": "^5.3.1"
|
|
26
|
+
},
|
|
27
|
+
"type": "module"
|
|
28
|
+
}
|