project-graph-mcp 1.5.0 → 2.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.
Files changed (121) hide show
  1. package/README.md +128 -8
  2. package/package.json +12 -8
  3. package/src/.project-graph-cache.json +1 -1
  4. package/src/analysis/analysis-cache.js +7 -0
  5. package/src/analysis/complexity.js +14 -0
  6. package/src/analysis/custom-rules.js +36 -0
  7. package/src/analysis/db-analysis.js +9 -0
  8. package/src/analysis/dead-code.js +19 -0
  9. package/src/analysis/full-analysis.js +18 -0
  10. package/src/analysis/jsdoc-checker.js +24 -0
  11. package/src/analysis/jsdoc-generator.js +10 -0
  12. package/src/analysis/large-files.js +11 -0
  13. package/src/analysis/outdated-patterns.js +12 -0
  14. package/src/analysis/similar-functions.js +16 -0
  15. package/src/analysis/test-annotations.js +21 -0
  16. package/src/analysis/type-checker.js +8 -0
  17. package/src/analysis/undocumented.js +14 -0
  18. package/src/cli/cli-handlers.js +4 -0
  19. package/src/cli/cli.js +5 -0
  20. package/src/compact/ai-context.js +7 -0
  21. package/src/compact/compact.js +18 -0
  22. package/src/compact/compress.js +13 -0
  23. package/src/compact/ctx-to-jsdoc.js +29 -0
  24. package/src/compact/doc-dialect.js +30 -0
  25. package/src/compact/expand.js +37 -0
  26. package/src/compact/framework-references.js +5 -0
  27. package/src/compact/instructions.js +3 -0
  28. package/src/compact/mode-config.js +8 -0
  29. package/src/compact/validate-pipeline.js +9 -0
  30. package/src/core/event-bus.js +9 -0
  31. package/src/core/filters.js +14 -0
  32. package/src/core/graph-builder.js +12 -0
  33. package/src/core/parser.js +31 -0
  34. package/src/core/workspace.js +8 -0
  35. package/src/lang/lang-go.js +17 -0
  36. package/src/lang/lang-python.js +12 -0
  37. package/src/lang/lang-sql.js +23 -0
  38. package/src/lang/lang-typescript.js +9 -0
  39. package/src/lang/lang-utils.js +4 -0
  40. package/src/mcp/mcp-server.js +17 -0
  41. package/src/mcp/tool-defs.js +3 -0
  42. package/src/mcp/tools.js +25 -0
  43. package/src/network/backend-lifecycle.js +19 -0
  44. package/src/network/backend.js +5 -0
  45. package/src/network/local-gateway.js +23 -0
  46. package/src/network/mdns.js +13 -0
  47. package/src/network/server.js +10 -0
  48. package/src/network/web-server.js +34 -0
  49. package/web/.project-graph-cache.json +1 -0
  50. package/web/app.js +16 -0
  51. package/web/components/code-block.js +3 -0
  52. package/web/components/quick-open.js +5 -0
  53. package/web/dashboard-state.js +3 -0
  54. package/web/dashboard.html +27 -0
  55. package/web/dashboard.js +8 -0
  56. package/web/highlight.js +13 -0
  57. package/web/index.html +35 -0
  58. package/web/panels/ActionBoard/ActionBoard.css.js +1 -0
  59. package/web/panels/ActionBoard/ActionBoard.js +4 -0
  60. package/web/panels/ActionBoard/ActionBoard.tpl.js +1 -0
  61. package/web/panels/EventItem/EventItem.css.js +1 -0
  62. package/web/panels/EventItem/EventItem.js +4 -0
  63. package/web/panels/EventItem/EventItem.tpl.js +1 -0
  64. package/web/panels/ProjectItem/ProjectItem.css.js +1 -0
  65. package/web/panels/ProjectItem/ProjectItem.js +5 -0
  66. package/web/panels/ProjectItem/ProjectItem.tpl.js +1 -0
  67. package/web/panels/ProjectList/ProjectList.css.js +1 -0
  68. package/web/panels/ProjectList/ProjectList.js +4 -0
  69. package/web/panels/ProjectList/ProjectList.tpl.js +1 -0
  70. package/web/panels/SettingsPanel/.project-graph-cache.json +1 -0
  71. package/web/panels/SettingsPanel/SettingsPanel.css.js +1 -0
  72. package/web/panels/SettingsPanel/SettingsPanel.js +7 -0
  73. package/web/panels/SettingsPanel/SettingsPanel.tpl.js +1 -0
  74. package/web/panels/code-viewer.js +5 -0
  75. package/web/panels/ctx-panel.js +4 -0
  76. package/web/panels/dep-graph.js +6 -0
  77. package/web/panels/file-tree.js +188 -0
  78. package/web/panels/health-panel.js +3 -0
  79. package/web/panels/live-monitor.js +3 -0
  80. package/web/state.js +17 -0
  81. package/web/style.css +157 -0
  82. package/references/symbiote-3x.md +0 -834
  83. package/src/ai-context.js +0 -113
  84. package/src/analysis-cache.js +0 -155
  85. package/src/cli-handlers.js +0 -271
  86. package/src/cli.js +0 -95
  87. package/src/compact.js +0 -207
  88. package/src/complexity.js +0 -237
  89. package/src/compress.js +0 -319
  90. package/src/ctx-to-jsdoc.js +0 -514
  91. package/src/custom-rules.js +0 -584
  92. package/src/db-analysis.js +0 -194
  93. package/src/dead-code.js +0 -468
  94. package/src/doc-dialect.js +0 -716
  95. package/src/filters.js +0 -227
  96. package/src/framework-references.js +0 -177
  97. package/src/full-analysis.js +0 -470
  98. package/src/graph-builder.js +0 -299
  99. package/src/instructions.js +0 -73
  100. package/src/jsdoc-checker.js +0 -351
  101. package/src/jsdoc-generator.js +0 -203
  102. package/src/lang-go.js +0 -285
  103. package/src/lang-python.js +0 -197
  104. package/src/lang-sql.js +0 -309
  105. package/src/lang-typescript.js +0 -190
  106. package/src/lang-utils.js +0 -124
  107. package/src/large-files.js +0 -163
  108. package/src/mcp-server.js +0 -675
  109. package/src/mode-config.js +0 -127
  110. package/src/outdated-patterns.js +0 -296
  111. package/src/parser.js +0 -662
  112. package/src/server.js +0 -28
  113. package/src/similar-functions.js +0 -279
  114. package/src/test-annotations.js +0 -323
  115. package/src/tool-defs.js +0 -793
  116. package/src/tools.js +0 -470
  117. package/src/type-checker.js +0 -188
  118. package/src/undocumented.js +0 -259
  119. package/src/workspace.js +0 -70
  120. /package/{AGENT_ROLE.md → docs/examples/AGENT_ROLE.md} +0 -0
  121. /package/{AGENT_ROLE_MINIMAL.md → docs/examples/AGENT_ROLE_MINIMAL.md} +0 -0
package/src/filters.js DELETED
@@ -1,227 +0,0 @@
1
- /**
2
- * Filter Configuration for Project Graph
3
- * Manages excludes, includes, and gitignore parsing
4
- */
5
-
6
- import { readFileSync, existsSync } from 'fs';
7
- import { join, relative } from 'path';
8
-
9
- /**
10
- * Default directories to exclude
11
- */
12
- const DEFAULT_EXCLUDES = [
13
- 'node_modules',
14
- 'dist',
15
- 'build',
16
- 'coverage',
17
- '.next',
18
- '.nuxt',
19
- '.output',
20
- '__pycache__',
21
- '.cache',
22
- '.turbo',
23
- 'out',
24
- ];
25
-
26
- /**
27
- * Default file patterns to exclude
28
- */
29
- const DEFAULT_EXCLUDE_PATTERNS = [
30
- '*.test.js',
31
- '*.spec.js',
32
- '*.min.js',
33
- '*.bundle.js',
34
- '*.d.ts',
35
- '.project-graph-cache.json',
36
- ];
37
-
38
- // Current filter configuration (mutable via MCP)
39
- let config = {
40
- excludeDirs: [...DEFAULT_EXCLUDES],
41
- excludePatterns: [...DEFAULT_EXCLUDE_PATTERNS],
42
- includeHidden: false,
43
- useGitignore: true,
44
- gitignorePatterns: [],
45
- };
46
-
47
- /**
48
- * Get current filter configuration
49
- * @returns {Object}
50
- */
51
- export function getFilters() {
52
- return { ...config };
53
- }
54
-
55
- /**
56
- * Update filter configuration
57
- * @param {Object} updates
58
- * @returns {Object}
59
- */
60
- export function setFilters(updates) {
61
- if (updates.excludeDirs !== undefined) {
62
- config.excludeDirs = updates.excludeDirs;
63
- }
64
- if (updates.excludePatterns !== undefined) {
65
- config.excludePatterns = updates.excludePatterns;
66
- }
67
- if (updates.includeHidden !== undefined) {
68
- config.includeHidden = updates.includeHidden;
69
- }
70
- if (updates.useGitignore !== undefined) {
71
- config.useGitignore = updates.useGitignore;
72
- }
73
- return getFilters();
74
- }
75
-
76
- /**
77
- * Add directories to exclude list
78
- * @param {string[]} dirs
79
- * @returns {Object}
80
- */
81
- export function addExcludes(dirs) {
82
- config.excludeDirs = [...new Set([...config.excludeDirs, ...dirs])];
83
- return getFilters();
84
- }
85
-
86
- /**
87
- * Remove directories from exclude list
88
- * @param {string[]} dirs
89
- * @returns {Object}
90
- */
91
- export function removeExcludes(dirs) {
92
- config.excludeDirs = config.excludeDirs.filter(d => !dirs.includes(d));
93
- return getFilters();
94
- }
95
-
96
- /**
97
- * Reset filters to defaults
98
- * @returns {Object}
99
- */
100
- export function resetFilters() {
101
- config = {
102
- excludeDirs: [...DEFAULT_EXCLUDES],
103
- excludePatterns: [...DEFAULT_EXCLUDE_PATTERNS],
104
- includeHidden: false,
105
- useGitignore: true,
106
- gitignorePatterns: [],
107
- };
108
- return getFilters();
109
- }
110
-
111
- /**
112
- * Parse .gitignore file
113
- * @param {string} rootDir
114
- * @returns {string[]}
115
- */
116
- export function parseGitignore(rootDir) {
117
- const gitignorePath = join(rootDir, '.gitignore');
118
-
119
- if (!existsSync(gitignorePath)) {
120
- return [];
121
- }
122
-
123
- try {
124
- const content = readFileSync(gitignorePath, 'utf-8');
125
- const patterns = content
126
- .split('\n')
127
- .map(line => line.trim())
128
- .filter(line => line && !line.startsWith('#'))
129
- .map(line => line.replace(/\/$/, '')); // Remove trailing slashes
130
-
131
- config.gitignorePatterns = patterns;
132
- return patterns;
133
- } catch (e) {
134
- return [];
135
- }
136
- }
137
-
138
- /**
139
- * Check if a directory should be excluded
140
- * @param {string} dirName - Directory name (not path)
141
- * @param {string} relativePath - Relative path from root
142
- * @returns {boolean}
143
- */
144
- export function shouldExcludeDir(dirName, relativePath = '') {
145
- // Check hidden directories
146
- if (!config.includeHidden && dirName.startsWith('.')) {
147
- return true;
148
- }
149
-
150
- // Check default excludes
151
- if (config.excludeDirs.includes(dirName)) {
152
- return true;
153
- }
154
-
155
- // Check gitignore patterns
156
- if (config.useGitignore) {
157
- for (const pattern of config.gitignorePatterns) {
158
- if (matchGitignorePattern(pattern, dirName, relativePath)) {
159
- return true;
160
- }
161
- }
162
- }
163
-
164
- return false;
165
- }
166
-
167
- /**
168
- * Check if a file should be excluded
169
- * @param {string} fileName
170
- * @param {string} relativePath
171
- * @returns {boolean}
172
- */
173
- export function shouldExcludeFile(fileName, relativePath = '') {
174
- // Check exclude patterns
175
- for (const pattern of config.excludePatterns) {
176
- if (matchWildcard(pattern, fileName)) {
177
- return true;
178
- }
179
- }
180
-
181
- // Check gitignore patterns
182
- if (config.useGitignore) {
183
- for (const pattern of config.gitignorePatterns) {
184
- if (matchGitignorePattern(pattern, fileName, relativePath)) {
185
- return true;
186
- }
187
- }
188
- }
189
-
190
- return false;
191
- }
192
-
193
- /**
194
- * Match simple wildcard pattern (*.js, *.test.js)
195
- * @param {string} pattern
196
- * @param {string} str
197
- * @returns {boolean}
198
- */
199
- function matchWildcard(pattern, str) {
200
- const regex = pattern
201
- .replace(/\./g, '\\.')
202
- .replace(/\*/g, '.*');
203
- return new RegExp(`^${regex}$`).test(str);
204
- }
205
-
206
- /**
207
- * Match gitignore pattern
208
- * @param {string} pattern
209
- * @param {string} name
210
- * @param {string} relativePath
211
- * @returns {boolean}
212
- */
213
- function matchGitignorePattern(pattern, name, relativePath) {
214
- // Simple matching: exact name or wildcard
215
- if (pattern === name) return true;
216
-
217
- // Pattern with wildcard
218
- if (pattern.includes('*')) {
219
- return matchWildcard(pattern, name);
220
- }
221
-
222
- // Pattern in path
223
- const fullPath = relativePath ? `${relativePath}/${name}` : name;
224
- if (fullPath.includes(pattern)) return true;
225
-
226
- return false;
227
- }
@@ -1,177 +0,0 @@
1
- /**
2
- * Framework Reference System
3
- * Loads framework-specific AI references from GitHub (with caching) or local files
4
- */
5
-
6
- import { readFileSync, readdirSync, existsSync, writeFileSync } from 'fs';
7
- import { join, basename, dirname } from 'path';
8
- import { fileURLToPath } from 'url';
9
- import { detectProjectRuleSets } from './custom-rules.js';
10
-
11
- const __dirname = dirname(fileURLToPath(import.meta.url));
12
- const REFERENCES_DIR = join(__dirname, '..', 'references');
13
-
14
- /**
15
- * Remote sources for framework references
16
- * Maps reference name to raw GitHub URL
17
- */
18
- const REMOTE_SOURCES = {
19
- 'symbiote-3x': 'https://raw.githubusercontent.com/symbiotejs/symbiote.js/main/AI_REFERENCE.md',
20
- };
21
-
22
- /** @type {Map<string, {content: string, fetchedAt: number}>} */
23
- const cache = new Map();
24
-
25
- /** Cache TTL: 1 hour */
26
- const CACHE_TTL = 60 * 60 * 1000;
27
-
28
- /**
29
- * Fetch reference from GitHub with caching
30
- * Falls back to local file if fetch fails
31
- * @param {string} name - Reference name
32
- * @returns {Promise<{content: string, source: string}>}
33
- */
34
- async function fetchReference(name) {
35
- const url = REMOTE_SOURCES[name];
36
- const localPath = join(REFERENCES_DIR, `${name}.md`);
37
-
38
- // Check in-memory cache
39
- const cached = cache.get(name);
40
- if (cached && Date.now() - cached.fetchedAt < CACHE_TTL) {
41
- return { content: cached.content, source: 'cache' };
42
- }
43
-
44
- // Try fetching from GitHub
45
- if (url) {
46
- try {
47
- const response = await fetch(url, { signal: AbortSignal.timeout(5000) });
48
- if (response.ok) {
49
- const content = await response.text();
50
- cache.set(name, { content, fetchedAt: Date.now() });
51
-
52
- // Update local file as backup
53
- try {
54
- writeFileSync(localPath, content, 'utf-8');
55
- } catch (e) {
56
- // Write failure is non-critical
57
- }
58
-
59
- return { content, source: `github (${url})` };
60
- }
61
- } catch (e) {
62
- // Fetch failed — fall back to local
63
- }
64
- }
65
-
66
- // Fall back to local file
67
- if (existsSync(localPath)) {
68
- const content = readFileSync(localPath, 'utf-8');
69
- cache.set(name, { content, fetchedAt: Date.now() });
70
- return { content, source: 'local' };
71
- }
72
-
73
- return { content: '', source: 'not_found' };
74
- }
75
-
76
- /**
77
- * Map ruleset names to reference names
78
- */
79
- const RULESET_TO_REFERENCE = {
80
- 'symbiote-3x': 'symbiote-3x',
81
- 'symbiote-2x': 'symbiote-3x',
82
- };
83
-
84
- /**
85
- * List available framework references (local + remote)
86
- * @returns {string[]}
87
- */
88
- function listAvailable() {
89
- const names = new Set(Object.keys(REMOTE_SOURCES));
90
-
91
- if (existsSync(REFERENCES_DIR)) {
92
- for (const f of readdirSync(REFERENCES_DIR)) {
93
- if (f.endsWith('.md')) {
94
- names.add(basename(f, '.md'));
95
- }
96
- }
97
- }
98
-
99
- return [...names];
100
- }
101
-
102
- /**
103
- * Get framework reference content
104
- * @param {Object} options
105
- * @param {string} [options.framework] - Explicit framework name
106
- * @param {string} [options.path] - Project path for auto-detection
107
- * @returns {Promise<Object>}
108
- */
109
- export async function getFrameworkReference(options = {}) {
110
- const available = listAvailable();
111
-
112
- // Explicit framework requested
113
- if (options.framework) {
114
- if (!available.includes(options.framework)) {
115
- return {
116
- error: `Framework reference '${options.framework}' not found`,
117
- available,
118
- };
119
- }
120
-
121
- const { content, source } = await fetchReference(options.framework);
122
- if (!content) {
123
- return { error: `Failed to load reference '${options.framework}'`, available };
124
- }
125
-
126
- return {
127
- framework: options.framework,
128
- source,
129
- lines: content.split('\n').length,
130
- content,
131
- };
132
- }
133
-
134
- // Auto-detect from project path
135
- if (options.path) {
136
- const { detected, reasons } = detectProjectRuleSets(options.path);
137
-
138
- const matchedRefs = [];
139
- for (const ruleset of detected) {
140
- const refName = RULESET_TO_REFERENCE[ruleset];
141
- if (refName && available.includes(refName) && !matchedRefs.includes(refName)) {
142
- matchedRefs.push(refName);
143
- }
144
- }
145
-
146
- if (matchedRefs.length === 0) {
147
- return {
148
- error: 'No framework references found for this project',
149
- detected,
150
- reasons,
151
- available,
152
- };
153
- }
154
-
155
- const results = await Promise.all(matchedRefs.map(fetchReference));
156
- const contents = results.map(r => r.content).filter(Boolean);
157
- const sources = results.map(r => r.source);
158
-
159
- return {
160
- frameworks: matchedRefs,
161
- sources,
162
- detected: { rulesets: detected, reasons },
163
- lines: contents.reduce((sum, c) => sum + c.split('\n').length, 0),
164
- content: contents.join('\n\n---\n\n'),
165
- };
166
- }
167
-
168
- // No framework specified — list available
169
- return {
170
- error: 'Specify framework name or path for auto-detection',
171
- available: available.map(name => ({
172
- name,
173
- remote: !!REMOTE_SOURCES[name],
174
- url: REMOTE_SOURCES[name] ?? null,
175
- })),
176
- };
177
- }