maven-indexer-mcp 1.0.7 → 1.0.8
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/build/db/index.js +16 -3
- package/build/indexer.js +78 -37
- package/build/simple_watcher.js +121 -0
- package/package.json +1 -1
package/build/db/index.js
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import Database from 'better-sqlite3';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import fs from 'fs';
|
|
3
5
|
export class DB {
|
|
4
6
|
static instance;
|
|
5
7
|
db;
|
|
6
8
|
constructor() {
|
|
7
9
|
// Check environment variable for DB path (useful for testing)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
if (process.env.DB_FILE) {
|
|
11
|
+
this.db = new Database(process.env.DB_FILE);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
// Use home directory for the database file
|
|
15
|
+
const homeDir = os.homedir();
|
|
16
|
+
const configDir = path.join(homeDir, '.maven-indexer-mcp');
|
|
17
|
+
// Ensure the directory exists
|
|
18
|
+
if (!fs.existsSync(configDir)) {
|
|
19
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
const dbPath = path.join(configDir, 'maven-index.sqlite');
|
|
22
|
+
this.db = new Database(dbPath);
|
|
23
|
+
}
|
|
11
24
|
this.initSchema();
|
|
12
25
|
}
|
|
13
26
|
static getInstance() {
|
package/build/indexer.js
CHANGED
|
@@ -15,6 +15,7 @@ export class Indexer {
|
|
|
15
15
|
isIndexing = false;
|
|
16
16
|
watcher = null;
|
|
17
17
|
debounceTimer = null;
|
|
18
|
+
pollingTimer = null;
|
|
18
19
|
constructor() {
|
|
19
20
|
}
|
|
20
21
|
static getInstance() {
|
|
@@ -24,55 +25,95 @@ export class Indexer {
|
|
|
24
25
|
return Indexer.instance;
|
|
25
26
|
}
|
|
26
27
|
/**
|
|
27
|
-
* Starts watching the local repository for changes
|
|
28
|
-
*
|
|
28
|
+
* Starts watching the local repository for changes - ULTRA SIMPLE VERSION
|
|
29
|
+
* Just watch the root directories without recursion
|
|
29
30
|
*/
|
|
30
31
|
async startWatch() {
|
|
31
32
|
const config = await Config.getInstance();
|
|
32
|
-
const
|
|
33
|
+
const watchPaths = [];
|
|
34
|
+
// Simple: Just add the main repository paths
|
|
33
35
|
if (config.localRepository && fsSync.existsSync(config.localRepository)) {
|
|
34
|
-
|
|
36
|
+
watchPaths.push(config.localRepository);
|
|
35
37
|
}
|
|
36
38
|
if (config.gradleRepository && fsSync.existsSync(config.gradleRepository)) {
|
|
37
|
-
|
|
39
|
+
watchPaths.push(config.gradleRepository);
|
|
38
40
|
}
|
|
39
|
-
if (
|
|
41
|
+
if (watchPaths.length === 0) {
|
|
40
42
|
console.error("No repository paths found, skipping watch mode.");
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
43
|
-
if (this.watcher) {
|
|
45
|
+
if (this.watcher || this.pollingTimer) {
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
|
-
console.error(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
48
|
+
console.error(`🔍 Starting ultra-simple file watcher on: ${watchPaths.join(', ')}`);
|
|
49
|
+
try {
|
|
50
|
+
// ULTRA SIMPLE: Watch only root directories, no recursion
|
|
51
|
+
this.watcher = chokidar.watch(watchPaths, {
|
|
52
|
+
// Watch only the root directory itself, not subdirectories
|
|
53
|
+
depth: 0,
|
|
54
|
+
// Don't trigger for files that already exist
|
|
55
|
+
ignoreInitial: true,
|
|
56
|
+
// Wait for files to finish writing before triggering
|
|
57
|
+
awaitWriteFinish: {
|
|
58
|
+
stabilityThreshold: 2000,
|
|
59
|
+
pollInterval: 100
|
|
60
|
+
},
|
|
61
|
+
// Don't crash on permission errors
|
|
62
|
+
ignorePermissionErrors: true
|
|
63
|
+
});
|
|
64
|
+
// SIMPLE: Watch for any changes in the root directories
|
|
65
|
+
// This will catch when new directories are created (which means new artifacts)
|
|
66
|
+
this.watcher
|
|
67
|
+
.on('addDir', (dirPath) => {
|
|
68
|
+
console.error(`� New directory detected: ${path.basename(dirPath)}`);
|
|
69
|
+
this.triggerReindex();
|
|
70
|
+
})
|
|
71
|
+
.on('unlinkDir', (dirPath) => {
|
|
72
|
+
console.error(`🗑️ Directory removed: ${path.basename(dirPath)}`);
|
|
73
|
+
this.triggerReindex();
|
|
74
|
+
})
|
|
75
|
+
.on('error', (error) => {
|
|
76
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
77
|
+
console.error(`❌ Watcher error: ${errorMessage}`);
|
|
78
|
+
this.fallbackToPolling();
|
|
79
|
+
});
|
|
80
|
+
console.error('✅ Ultra-simple file watcher started successfully');
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
84
|
+
console.error(`❌ Failed to start watcher: ${errorMessage}`);
|
|
85
|
+
this.fallbackToPolling();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Falls back to polling mode if watcher fails.
|
|
90
|
+
* Polls the repository every 1 min
|
|
91
|
+
*/
|
|
92
|
+
fallbackToPolling() {
|
|
93
|
+
if (this.pollingTimer) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
console.error('⚠️ Falling back to polling mode (every 10s)...');
|
|
97
|
+
if (this.watcher) {
|
|
98
|
+
this.watcher.close().catch(err => console.error(`Error closing watcher: ${err}`));
|
|
99
|
+
this.watcher = null;
|
|
100
|
+
}
|
|
101
|
+
this.pollingTimer = setInterval(() => {
|
|
102
|
+
this.index().catch(console.error);
|
|
103
|
+
}, 60000);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Trigger reindexing with debouncing (wait a bit for multiple changes)
|
|
107
|
+
*/
|
|
108
|
+
triggerReindex() {
|
|
109
|
+
if (this.debounceTimer) {
|
|
110
|
+
clearTimeout(this.debounceTimer);
|
|
111
|
+
}
|
|
112
|
+
// Wait 3 seconds after the last change before reindexing
|
|
113
|
+
this.debounceTimer = setTimeout(() => {
|
|
114
|
+
console.error('🔄 Changes detected - triggering reindex...');
|
|
115
|
+
this.index().catch(console.error);
|
|
116
|
+
}, 3000);
|
|
76
117
|
}
|
|
77
118
|
/**
|
|
78
119
|
* Forces a full re-index of the repository.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIMPLIFIED FILE WATCHER for Maven Indexer
|
|
3
|
+
*
|
|
4
|
+
* This is a cleaned-up version that's easier to understand.
|
|
5
|
+
* It watches for new JAR and POM files in your Maven/Gradle repositories.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
export class SimpleWatcher {
|
|
10
|
+
watcher = null;
|
|
11
|
+
onChangeCallback;
|
|
12
|
+
constructor(onChangeCallback) {
|
|
13
|
+
this.onChangeCallback = onChangeCallback;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Start watching - SIMPLE VERSION
|
|
17
|
+
* Just watch the main folders and filter for JAR/POM files
|
|
18
|
+
*/
|
|
19
|
+
async startWatching(mavenRepoPath, gradleRepoPath) {
|
|
20
|
+
if (this.watcher) {
|
|
21
|
+
console.log('Watcher already running');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const watchPaths = [];
|
|
25
|
+
// Add Maven repo if it exists
|
|
26
|
+
if (mavenRepoPath && fs.existsSync(mavenRepoPath)) {
|
|
27
|
+
watchPaths.push(mavenRepoPath);
|
|
28
|
+
}
|
|
29
|
+
// Add Gradle repo if it exists
|
|
30
|
+
if (gradleRepoPath && fs.existsSync(gradleRepoPath)) {
|
|
31
|
+
watchPaths.push(gradleRepoPath);
|
|
32
|
+
}
|
|
33
|
+
if (watchPaths.length === 0) {
|
|
34
|
+
console.log('No repository paths to watch');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
console.log(`🔍 Watching for new JAR/POM files in: ${watchPaths.join(', ')}`);
|
|
38
|
+
// SIMPLE: Use chokidar with basic ignore patterns
|
|
39
|
+
const chokidar = await import('chokidar');
|
|
40
|
+
this.watcher = chokidar.watch(watchPaths, {
|
|
41
|
+
// Ignore common junk files (simple patterns)
|
|
42
|
+
ignored: [
|
|
43
|
+
'**/.*', // Hidden files
|
|
44
|
+
'**/*.tmp', // Temp files
|
|
45
|
+
'**/*.sha1', // Checksum files
|
|
46
|
+
'**/*.sha256', // Checksum files
|
|
47
|
+
'**/*.md5', // Checksum files
|
|
48
|
+
],
|
|
49
|
+
// Don't watch too deep (Maven repos are usually 3-4 levels)
|
|
50
|
+
depth: 6,
|
|
51
|
+
// Don't trigger for files that already exist
|
|
52
|
+
ignoreInitial: true,
|
|
53
|
+
// Wait for files to finish writing before triggering
|
|
54
|
+
awaitWriteFinish: {
|
|
55
|
+
stabilityThreshold: 2000, // Wait 2 seconds after file stops changing
|
|
56
|
+
pollInterval: 100
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
// SIMPLE: Just watch for new files being added
|
|
60
|
+
this.watcher
|
|
61
|
+
.on('add', (filePath) => {
|
|
62
|
+
// Only care about JAR and POM files
|
|
63
|
+
if (filePath.endsWith('.jar') || filePath.endsWith('.pom')) {
|
|
64
|
+
console.log(`📦 New file detected: ${path.basename(filePath)}`);
|
|
65
|
+
this.triggerReindex();
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
.on('unlink', (filePath) => {
|
|
69
|
+
// Also watch for files being deleted
|
|
70
|
+
if (filePath.endsWith('.jar') || filePath.endsWith('.pom')) {
|
|
71
|
+
console.log(`🗑️ File removed: ${path.basename(filePath)}`);
|
|
72
|
+
this.triggerReindex();
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
.on('error', (error) => {
|
|
76
|
+
console.log(`❌ Watcher error: ${error.message}`);
|
|
77
|
+
});
|
|
78
|
+
console.log('✅ File watcher started successfully');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Stop watching
|
|
82
|
+
*/
|
|
83
|
+
stopWatching() {
|
|
84
|
+
if (this.watcher) {
|
|
85
|
+
this.watcher.close();
|
|
86
|
+
this.watcher = null;
|
|
87
|
+
console.log('🛑 File watcher stopped');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Trigger reindexing with debouncing (wait a bit for multiple changes)
|
|
92
|
+
*/
|
|
93
|
+
debounceTimer = null;
|
|
94
|
+
triggerReindex() {
|
|
95
|
+
// Clear any existing timer
|
|
96
|
+
if (this.debounceTimer) {
|
|
97
|
+
clearTimeout(this.debounceTimer);
|
|
98
|
+
}
|
|
99
|
+
// Wait 3 seconds after the last change before reindexing
|
|
100
|
+
this.debounceTimer = setTimeout(() => {
|
|
101
|
+
console.log('🔄 Changes detected - triggering reindex...');
|
|
102
|
+
this.onChangeCallback();
|
|
103
|
+
}, 3000);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* USAGE EXAMPLE:
|
|
108
|
+
*
|
|
109
|
+
* const watcher = new SimpleWatcher(() => {
|
|
110
|
+
* console.log('Time to reindex the repository!');
|
|
111
|
+
* // Put your reindexing code here
|
|
112
|
+
* });
|
|
113
|
+
*
|
|
114
|
+
* await watcher.startWatching(
|
|
115
|
+
* '/Users/tangcent/.m2/repository',
|
|
116
|
+
* '/Users/tangcent/.gradle/caches/modules-2/files-2.1'
|
|
117
|
+
* );
|
|
118
|
+
*
|
|
119
|
+
* // Later... when you want to stop
|
|
120
|
+
* watcher.stopWatching();
|
|
121
|
+
**/
|