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 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
+ }
@@ -0,0 +1,8 @@
1
+ # CODE_GRAPH_MAP
2
+ > LLM_ONLY: DO NOT EDIT. COMPACT PROJECT MAP.
3
+
4
+ - .gitignore
5
+ - index.js|syms:[debouncedGenerate,extractSymbols,generate,getIgnores,installHook,walk,watch]
6
+ - package-lock.json
7
+ - package.json
8
+ - README.md
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
+ }