@chiway/contextweaver 1.4.0 → 1.5.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 +138 -28
- package/dist/{SearchService-OS7CYHNJ.js → SearchService-WVD6THR3.js} +116 -74
- package/dist/{chunk-ZOMGPIU6.js → chunk-3BNHQV5W.js} +1 -5
- package/dist/chunk-BFCIZ52F.js +102 -0
- package/dist/{chunk-X7PAYQMT.js → chunk-GDVB6PJ4.js} +21 -3
- package/dist/{lock-FL54LIQL.js → chunk-HHYPQA3X.js} +1 -1
- package/dist/chunk-ISVCQFB4.js +223 -0
- package/dist/chunk-IZ6IUHNN.js +77 -0
- package/dist/chunk-LB42CZEB.js +18 -0
- package/dist/{chunk-RGJSXUFS.js → chunk-PPLFJGO3.js} +60 -0
- package/dist/chunk-R6CNZXZ7.js +143 -0
- package/dist/chunk-TPM6YP43.js +38 -0
- package/dist/{chunk-EMSMLPMK.js → chunk-V3K4YVAR.js} +10 -117
- package/dist/chunk-VWBKZ6QL.js +115 -0
- package/dist/chunk-XFIM2T6S.js +57 -0
- package/dist/{chunk-AB24E3Z7.js → chunk-XMZZZKG7.js} +23 -79
- package/dist/chunk-XTWNT7KP.js +156 -0
- package/dist/chunk-Y6H7C3NA.js +85 -0
- package/dist/{codebaseRetrieval-3Z4CRA7X.js → codebaseRetrieval-DIS5RH2C.js} +5 -2
- package/dist/{db-PMVM7557.js → db-GBCLP4GG.js} +15 -1
- package/dist/findReferences-N7ML7TUP.js +16 -0
- package/dist/getSymbolDefinition-6KMY4H33.js +17 -0
- package/dist/index.js +244 -41
- package/dist/listFiles-4VT2TPJD.js +14 -0
- package/dist/loadConfig-XTVT2OWW.js +9 -0
- package/dist/lock-HNKQ6X5B.js +8 -0
- package/dist/scanner-QDFZJLP7.js +13 -0
- package/dist/server-UAI3U7AB.js +347 -0
- package/dist/stats-AGKUCJQI.js +12 -0
- package/dist/{vectorStore-HPQZOVWF.js → vectorStore-4ODCERRO.js} +1 -1
- package/package.json +9 -23
- package/dist/scanner-2XGJWYHR.js +0 -11
- package/dist/server-XK6EINRV.js +0 -146
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureIndexed,
|
|
3
|
+
formatTextResponse
|
|
4
|
+
} from "./chunk-VWBKZ6QL.js";
|
|
5
|
+
import {
|
|
6
|
+
generateProjectId,
|
|
7
|
+
initDb
|
|
8
|
+
} from "./chunk-PPLFJGO3.js";
|
|
9
|
+
import {
|
|
10
|
+
logger
|
|
11
|
+
} from "./chunk-JVKVSTQ3.js";
|
|
12
|
+
|
|
13
|
+
// src/mcp/tools/listFiles.ts
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
var listFilesSchema = z.object({
|
|
16
|
+
repo_path: z.string().describe(
|
|
17
|
+
"The absolute file system path to the repository root. (e.g., '/Users/dev/my-project')"
|
|
18
|
+
),
|
|
19
|
+
glob: z.string().optional().describe("Optional glob pattern to filter returned file paths."),
|
|
20
|
+
language: z.string().optional().describe("Optional language filter matched against files.language."),
|
|
21
|
+
max_results: z.number().int().positive().max(1e3).optional().describe("Maximum number of files to return. Defaults to 200.")
|
|
22
|
+
});
|
|
23
|
+
function escapeRegexCharacter(char) {
|
|
24
|
+
return char.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
|
|
25
|
+
}
|
|
26
|
+
function globToRegExp(glob) {
|
|
27
|
+
const normalized = glob.replace(/\\/g, "/");
|
|
28
|
+
let pattern = "^";
|
|
29
|
+
for (let i = 0; i < normalized.length; ) {
|
|
30
|
+
if (normalized.slice(i, i + 3) === "**/") {
|
|
31
|
+
pattern += "(?:.*/)?";
|
|
32
|
+
i += 3;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (normalized.slice(i, i + 2) === "**") {
|
|
36
|
+
pattern += ".*";
|
|
37
|
+
i += 2;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const char = normalized[i];
|
|
41
|
+
if (char === "*") {
|
|
42
|
+
pattern += "[^/]*";
|
|
43
|
+
} else if (char === "?") {
|
|
44
|
+
pattern += "[^/]";
|
|
45
|
+
} else {
|
|
46
|
+
pattern += escapeRegexCharacter(char);
|
|
47
|
+
}
|
|
48
|
+
i += 1;
|
|
49
|
+
}
|
|
50
|
+
return new RegExp(`${pattern}$`);
|
|
51
|
+
}
|
|
52
|
+
function formatSize(size) {
|
|
53
|
+
if (size < 1024) {
|
|
54
|
+
return `${size}B`;
|
|
55
|
+
}
|
|
56
|
+
const kb = size / 1024;
|
|
57
|
+
if (kb < 1024) {
|
|
58
|
+
return `${kb.toFixed(1)}KB`;
|
|
59
|
+
}
|
|
60
|
+
return `${(kb / 1024).toFixed(1)}MB`;
|
|
61
|
+
}
|
|
62
|
+
async function handleListFiles(args, onProgress) {
|
|
63
|
+
const { repo_path, glob, language, max_results = 200 } = args;
|
|
64
|
+
const projectId = generateProjectId(repo_path);
|
|
65
|
+
logger.info({ repo_path, glob, language, max_results }, "MCP list-files \u8C03\u7528\u5F00\u59CB");
|
|
66
|
+
await ensureIndexed(repo_path, projectId, { onProgress, vectorIndex: false });
|
|
67
|
+
const db = initDb(projectId);
|
|
68
|
+
try {
|
|
69
|
+
const rows = language ? db.prepare("SELECT path, language, size FROM files WHERE language = ? ORDER BY path").all(language) : db.prepare("SELECT path, language, size FROM files ORDER BY path").all();
|
|
70
|
+
const matcher = glob ? globToRegExp(glob) : null;
|
|
71
|
+
const filtered = matcher ? rows.filter((row) => matcher.test(row.path)) : rows;
|
|
72
|
+
const limited = filtered.slice(0, max_results);
|
|
73
|
+
const body = limited.length > 0 ? limited.map((row) => `- ${row.path} (${row.language}, ${formatSize(row.size)})`).join("\n") : "No files matched the requested filters.";
|
|
74
|
+
return formatTextResponse(`Found ${limited.length} files
|
|
75
|
+
|
|
76
|
+
${body}`);
|
|
77
|
+
} finally {
|
|
78
|
+
db.close();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export {
|
|
83
|
+
listFilesSchema,
|
|
84
|
+
handleListFiles
|
|
85
|
+
};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
codebaseRetrievalSchema,
|
|
3
3
|
handleCodebaseRetrieval
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-V3K4YVAR.js";
|
|
5
|
+
import "./chunk-VWBKZ6QL.js";
|
|
6
|
+
import "./chunk-TPM6YP43.js";
|
|
7
|
+
import "./chunk-BFCIZ52F.js";
|
|
8
|
+
import "./chunk-PPLFJGO3.js";
|
|
6
9
|
import "./chunk-JVKVSTQ3.js";
|
|
7
10
|
import "./chunk-SKBAE26T.js";
|
|
8
11
|
export {
|
|
@@ -7,23 +7,30 @@ import {
|
|
|
7
7
|
clearAllVectorIndexHash,
|
|
8
8
|
clearVectorIndexHash,
|
|
9
9
|
closeDb,
|
|
10
|
+
collectHealthSnapshot,
|
|
10
11
|
countPendingMarks,
|
|
11
12
|
deletePendingMarks,
|
|
12
13
|
generateProjectId,
|
|
13
14
|
getAllFileMeta,
|
|
14
15
|
getAllPaths,
|
|
16
|
+
getAllStats,
|
|
15
17
|
getFilesNeedingVectorIndex,
|
|
18
|
+
getIndexVersion,
|
|
16
19
|
getLanceDbMigrationState,
|
|
20
|
+
getStatJson,
|
|
17
21
|
getStoredEmbeddingDimensions,
|
|
22
|
+
incrementIndexVersion,
|
|
23
|
+
incrementStat,
|
|
18
24
|
initDb,
|
|
19
25
|
insertPendingMarks,
|
|
20
26
|
migrateSchema,
|
|
21
27
|
releaseLanceDbMigrationLock,
|
|
22
28
|
replayPendingMarks,
|
|
23
29
|
setLanceDbMigrationState,
|
|
30
|
+
setStatJson,
|
|
24
31
|
setStoredEmbeddingDimensions,
|
|
25
32
|
tryAcquireLanceDbMigrationLock
|
|
26
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-PPLFJGO3.js";
|
|
27
34
|
import "./chunk-JVKVSTQ3.js";
|
|
28
35
|
import "./chunk-SKBAE26T.js";
|
|
29
36
|
export {
|
|
@@ -35,20 +42,27 @@ export {
|
|
|
35
42
|
clearAllVectorIndexHash,
|
|
36
43
|
clearVectorIndexHash,
|
|
37
44
|
closeDb,
|
|
45
|
+
collectHealthSnapshot,
|
|
38
46
|
countPendingMarks,
|
|
39
47
|
deletePendingMarks,
|
|
40
48
|
generateProjectId,
|
|
41
49
|
getAllFileMeta,
|
|
42
50
|
getAllPaths,
|
|
51
|
+
getAllStats,
|
|
43
52
|
getFilesNeedingVectorIndex,
|
|
53
|
+
getIndexVersion,
|
|
44
54
|
getLanceDbMigrationState,
|
|
55
|
+
getStatJson,
|
|
45
56
|
getStoredEmbeddingDimensions,
|
|
57
|
+
incrementIndexVersion,
|
|
58
|
+
incrementStat,
|
|
46
59
|
initDb,
|
|
47
60
|
insertPendingMarks,
|
|
48
61
|
migrateSchema,
|
|
49
62
|
releaseLanceDbMigrationLock,
|
|
50
63
|
replayPendingMarks,
|
|
51
64
|
setLanceDbMigrationState,
|
|
65
|
+
setStatJson,
|
|
52
66
|
setStoredEmbeddingDimensions,
|
|
53
67
|
tryAcquireLanceDbMigrationLock
|
|
54
68
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findReferencesSchema,
|
|
3
|
+
handleFindReferences
|
|
4
|
+
} from "./chunk-R6CNZXZ7.js";
|
|
5
|
+
import "./chunk-XFIM2T6S.js";
|
|
6
|
+
import "./chunk-3BNHQV5W.js";
|
|
7
|
+
import "./chunk-VWBKZ6QL.js";
|
|
8
|
+
import "./chunk-TPM6YP43.js";
|
|
9
|
+
import "./chunk-BFCIZ52F.js";
|
|
10
|
+
import "./chunk-PPLFJGO3.js";
|
|
11
|
+
import "./chunk-JVKVSTQ3.js";
|
|
12
|
+
import "./chunk-SKBAE26T.js";
|
|
13
|
+
export {
|
|
14
|
+
findReferencesSchema,
|
|
15
|
+
handleFindReferences
|
|
16
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getSymbolDefinitionSchema,
|
|
3
|
+
handleGetSymbolDefinition
|
|
4
|
+
} from "./chunk-ISVCQFB4.js";
|
|
5
|
+
import "./chunk-LB42CZEB.js";
|
|
6
|
+
import "./chunk-XFIM2T6S.js";
|
|
7
|
+
import "./chunk-3BNHQV5W.js";
|
|
8
|
+
import "./chunk-VWBKZ6QL.js";
|
|
9
|
+
import "./chunk-TPM6YP43.js";
|
|
10
|
+
import "./chunk-BFCIZ52F.js";
|
|
11
|
+
import "./chunk-PPLFJGO3.js";
|
|
12
|
+
import "./chunk-JVKVSTQ3.js";
|
|
13
|
+
import "./chunk-SKBAE26T.js";
|
|
14
|
+
export {
|
|
15
|
+
getSymbolDefinitionSchema,
|
|
16
|
+
handleGetSymbolDefinition
|
|
17
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,37 +1,228 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
withLock
|
|
4
|
+
} from "./chunk-HHYPQA3X.js";
|
|
5
|
+
import {
|
|
6
|
+
initFilter,
|
|
7
|
+
isFiltered,
|
|
3
8
|
scan
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-GDVB6PJ4.js";
|
|
10
|
+
import "./chunk-XMZZZKG7.js";
|
|
11
|
+
import "./chunk-LB42CZEB.js";
|
|
12
|
+
import "./chunk-XFIM2T6S.js";
|
|
13
|
+
import "./chunk-3BNHQV5W.js";
|
|
14
|
+
import {
|
|
15
|
+
getDefaultEnvFileContent
|
|
16
|
+
} from "./chunk-TPM6YP43.js";
|
|
17
|
+
import "./chunk-BFCIZ52F.js";
|
|
7
18
|
import {
|
|
8
19
|
generateProjectId
|
|
9
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-PPLFJGO3.js";
|
|
10
21
|
import {
|
|
11
22
|
logger
|
|
12
23
|
} from "./chunk-JVKVSTQ3.js";
|
|
13
24
|
import "./chunk-SKBAE26T.js";
|
|
14
25
|
|
|
15
26
|
// src/index.ts
|
|
16
|
-
import { promises as
|
|
27
|
+
import { promises as fs2 } from "fs";
|
|
17
28
|
import os from "os";
|
|
18
|
-
import
|
|
29
|
+
import path3 from "path";
|
|
19
30
|
import { fileURLToPath } from "url";
|
|
20
31
|
import cac from "cac";
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
|
|
33
|
+
// src/cli/mirrorCommands.ts
|
|
34
|
+
import path from "path";
|
|
35
|
+
function parseOptionalPositiveInt(value) {
|
|
36
|
+
if (!value) {
|
|
37
|
+
return void 0;
|
|
38
|
+
}
|
|
39
|
+
const parsed = Number.parseInt(value, 10);
|
|
40
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
41
|
+
}
|
|
42
|
+
async function writeResponse(response) {
|
|
43
|
+
const text = response.content.map((item) => item.text).join("\n");
|
|
44
|
+
process.stdout.write(`${text}
|
|
45
|
+
`);
|
|
46
|
+
}
|
|
47
|
+
function registerMirrorCommands(cli2) {
|
|
48
|
+
cli2.command("list-files [path]", "\u5217\u51FA\u5DF2\u7D22\u5F15\u6587\u4EF6\u7ED3\u6784\uFF08\u955C\u50CF MCP list-files\uFF09").option("--glob <pattern>", "\u8DEF\u5F84 glob \u8FC7\u6EE4").option("--language <language>", "\u8BED\u8A00\u8FC7\u6EE4").option("--max-results <n>", "\u6700\u591A\u8FD4\u56DE\u6570\u91CF").action(
|
|
49
|
+
async (targetPath, options) => {
|
|
50
|
+
const repoPath = targetPath ? path.resolve(targetPath) : process.cwd();
|
|
51
|
+
const { handleListFiles } = await import("./listFiles-4VT2TPJD.js");
|
|
52
|
+
const response = await handleListFiles({
|
|
53
|
+
repo_path: repoPath,
|
|
54
|
+
glob: options.glob,
|
|
55
|
+
language: options.language,
|
|
56
|
+
max_results: parseOptionalPositiveInt(options.maxResults)
|
|
57
|
+
});
|
|
58
|
+
await writeResponse(response);
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
cli2.command("definition <symbol>", "\u67E5\u770B\u7B26\u53F7\u5B9A\u4E49\uFF08\u955C\u50CF MCP get-symbol-definition\uFF09").option("-p, --path <path>", "\u9879\u76EE\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").option("--hint-path <path>", "\u7528\u4E8E\u540C\u540D\u5B9A\u4E49\u6D88\u6B67\u7684\u504F\u597D\u8DEF\u5F84").option("--max-results <n>", "\u6700\u591A\u8FD4\u56DE\u6570\u91CF").action(
|
|
62
|
+
async (symbol, options) => {
|
|
63
|
+
const repoPath = options.path ? path.resolve(options.path) : process.cwd();
|
|
64
|
+
const { handleGetSymbolDefinition } = await import("./getSymbolDefinition-6KMY4H33.js");
|
|
65
|
+
const response = await handleGetSymbolDefinition({
|
|
66
|
+
repo_path: repoPath,
|
|
67
|
+
symbol,
|
|
68
|
+
hint_path: options.hintPath,
|
|
69
|
+
max_results: parseOptionalPositiveInt(options.maxResults)
|
|
70
|
+
});
|
|
71
|
+
await writeResponse(response);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
cli2.command("references <symbol>", "\u67E5\u770B\u7B26\u53F7\u5F15\u7528\uFF08\u955C\u50CF MCP find-references\uFF09").option("-p, --path <path>", "\u9879\u76EE\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").option("--exclude-definition", "\u6392\u9664\u5B9A\u4E49\u672C\u8EAB").option("--max-results <n>", "\u6700\u591A\u8FD4\u56DE\u6570\u91CF").action(
|
|
75
|
+
async (symbol, options) => {
|
|
76
|
+
const repoPath = options.path ? path.resolve(options.path) : process.cwd();
|
|
77
|
+
const { handleFindReferences } = await import("./findReferences-N7ML7TUP.js");
|
|
78
|
+
const response = await handleFindReferences({
|
|
79
|
+
repo_path: repoPath,
|
|
80
|
+
symbol,
|
|
81
|
+
exclude_definition: options.excludeDefinition,
|
|
82
|
+
max_results: parseOptionalPositiveInt(options.maxResults)
|
|
83
|
+
});
|
|
84
|
+
await writeResponse(response);
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/scanner/watcher.ts
|
|
90
|
+
import fs from "fs";
|
|
91
|
+
import path2 from "path";
|
|
92
|
+
function defaultWatchFactory(rootPath, options, callback) {
|
|
93
|
+
const watcher = fs.watch(rootPath, options, (eventType, fileName) => {
|
|
94
|
+
callback(eventType, fileName);
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
close() {
|
|
98
|
+
watcher.close();
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function normalizeRelativePath(fileName) {
|
|
103
|
+
if (!fileName) return null;
|
|
104
|
+
return fileName.replace(/\\/g, "/");
|
|
105
|
+
}
|
|
106
|
+
function createWatchCoordinator(rootPath, options) {
|
|
107
|
+
const { debounceMs, scanFn, shouldIgnore, watchFactory = defaultWatchFactory } = options;
|
|
108
|
+
let timer = null;
|
|
109
|
+
let watcher = null;
|
|
110
|
+
let started = false;
|
|
111
|
+
let closed = false;
|
|
112
|
+
let isScanning = false;
|
|
113
|
+
let rerunRequested = false;
|
|
114
|
+
const runScan = async () => {
|
|
115
|
+
if (closed) return;
|
|
116
|
+
if (isScanning) {
|
|
117
|
+
rerunRequested = true;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
isScanning = true;
|
|
121
|
+
try {
|
|
122
|
+
await scanFn();
|
|
123
|
+
} finally {
|
|
124
|
+
isScanning = false;
|
|
125
|
+
if (!closed && rerunRequested) {
|
|
126
|
+
rerunRequested = false;
|
|
127
|
+
void runScan();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const scheduleScan = () => {
|
|
132
|
+
if (closed) return;
|
|
133
|
+
if (timer) {
|
|
134
|
+
clearTimeout(timer);
|
|
135
|
+
}
|
|
136
|
+
timer = setTimeout(() => {
|
|
137
|
+
timer = null;
|
|
138
|
+
void runScan();
|
|
139
|
+
}, debounceMs);
|
|
140
|
+
};
|
|
141
|
+
const onWatchEvent = (_eventType, fileName) => {
|
|
142
|
+
const relativePath = normalizeRelativePath(fileName);
|
|
143
|
+
if (relativePath && shouldIgnore(relativePath)) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
scheduleScan();
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
async start() {
|
|
150
|
+
if (started) return;
|
|
151
|
+
started = true;
|
|
152
|
+
watcher = watchFactory(rootPath, { recursive: true }, onWatchEvent);
|
|
153
|
+
await runScan();
|
|
154
|
+
},
|
|
155
|
+
close() {
|
|
156
|
+
closed = true;
|
|
157
|
+
if (timer) {
|
|
158
|
+
clearTimeout(timer);
|
|
159
|
+
timer = null;
|
|
160
|
+
}
|
|
161
|
+
watcher?.close();
|
|
162
|
+
watcher = null;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
async function startWatchMode(rootPath, options = {}) {
|
|
167
|
+
const absoluteRoot = path2.resolve(rootPath);
|
|
168
|
+
const projectId = generateProjectId(absoluteRoot);
|
|
169
|
+
const debounceMs = options.debounceMs ?? 500;
|
|
170
|
+
await initFilter(absoluteRoot);
|
|
171
|
+
const runLockedScan = async () => {
|
|
172
|
+
logger.info({ rootPath: absoluteRoot }, "watch: \u89E6\u53D1\u589E\u91CF\u626B\u63CF");
|
|
173
|
+
await withLock(
|
|
174
|
+
projectId,
|
|
175
|
+
"index",
|
|
176
|
+
async () => {
|
|
177
|
+
const stats = await scan(absoluteRoot, { vectorIndex: true });
|
|
178
|
+
logger.info(
|
|
179
|
+
{
|
|
180
|
+
added: stats.added,
|
|
181
|
+
modified: stats.modified,
|
|
182
|
+
deleted: stats.deleted,
|
|
183
|
+
unchanged: stats.unchanged,
|
|
184
|
+
skipped: stats.skipped,
|
|
185
|
+
errors: stats.errors
|
|
186
|
+
},
|
|
187
|
+
"watch: \u626B\u63CF\u5B8C\u6210"
|
|
188
|
+
);
|
|
189
|
+
},
|
|
190
|
+
10 * 60 * 1e3
|
|
191
|
+
);
|
|
192
|
+
};
|
|
193
|
+
const coordinator = createWatchCoordinator(absoluteRoot, {
|
|
194
|
+
debounceMs,
|
|
195
|
+
scanFn: runLockedScan,
|
|
196
|
+
shouldIgnore: (relativePath) => isFiltered(relativePath)
|
|
197
|
+
});
|
|
198
|
+
await coordinator.start();
|
|
199
|
+
logger.info({ rootPath: absoluteRoot, debounceMs }, "watch: \u6587\u4EF6\u76D1\u542C\u5DF2\u542F\u52A8\uFF0C\u6309 Ctrl+C \u505C\u6B62");
|
|
200
|
+
const shutdown = () => {
|
|
201
|
+
coordinator.close();
|
|
202
|
+
logger.info("watch: \u6587\u4EF6\u76D1\u542C\u5DF2\u505C\u6B62");
|
|
203
|
+
process.exit(0);
|
|
204
|
+
};
|
|
205
|
+
process.once("SIGINT", shutdown);
|
|
206
|
+
process.once("SIGTERM", shutdown);
|
|
207
|
+
await new Promise(() => {
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/index.ts
|
|
212
|
+
var __dirname = path3.dirname(fileURLToPath(import.meta.url));
|
|
213
|
+
var pkgPath = path3.resolve(__dirname, "../package.json");
|
|
214
|
+
var pkg = JSON.parse(await fs2.readFile(pkgPath, "utf-8"));
|
|
24
215
|
var cli = cac("contextweaver");
|
|
25
216
|
if (process.argv.includes("-v") || process.argv.includes("--version")) {
|
|
26
217
|
console.log(pkg.version);
|
|
27
218
|
process.exit(0);
|
|
28
219
|
}
|
|
29
220
|
cli.command("init", "\u521D\u59CB\u5316 ContextWeaver \u914D\u7F6E").action(async () => {
|
|
30
|
-
const configDir =
|
|
31
|
-
const envFile =
|
|
221
|
+
const configDir = path3.join(os.homedir(), ".contextweaver");
|
|
222
|
+
const envFile = path3.join(configDir, ".env");
|
|
32
223
|
logger.info("\u5F00\u59CB\u521D\u59CB\u5316 ContextWeaver...");
|
|
33
224
|
try {
|
|
34
|
-
await
|
|
225
|
+
await fs2.mkdir(configDir, { recursive: true });
|
|
35
226
|
logger.info(`\u521B\u5EFA\u914D\u7F6E\u76EE\u5F55: ${configDir}`);
|
|
36
227
|
} catch (err) {
|
|
37
228
|
const error = err;
|
|
@@ -42,32 +233,15 @@ cli.command("init", "\u521D\u59CB\u5316 ContextWeaver \u914D\u7F6E").action(asyn
|
|
|
42
233
|
logger.info(`\u914D\u7F6E\u76EE\u5F55\u5DF2\u5B58\u5728: ${configDir}`);
|
|
43
234
|
}
|
|
44
235
|
try {
|
|
45
|
-
await
|
|
236
|
+
await fs2.access(envFile);
|
|
46
237
|
logger.warn(`.env \u6587\u4EF6\u5DF2\u5B58\u5728: ${envFile}`);
|
|
47
238
|
logger.info("\u521D\u59CB\u5316\u5B8C\u6210\uFF01");
|
|
48
239
|
return;
|
|
49
240
|
} catch {
|
|
50
241
|
}
|
|
51
|
-
const defaultEnvContent =
|
|
52
|
-
|
|
53
|
-
# Embedding API \u914D\u7F6E\uFF08\u5FC5\u9700\uFF09
|
|
54
|
-
EMBEDDINGS_API_KEY=your-api-key-here
|
|
55
|
-
EMBEDDINGS_BASE_URL=https://api.siliconflow.cn/v1/embeddings
|
|
56
|
-
EMBEDDINGS_MODEL=BAAI/bge-m3
|
|
57
|
-
EMBEDDINGS_MAX_CONCURRENCY=10
|
|
58
|
-
EMBEDDINGS_DIMENSIONS=1024
|
|
59
|
-
|
|
60
|
-
# Reranker \u914D\u7F6E\uFF08\u5FC5\u9700\uFF09
|
|
61
|
-
RERANK_API_KEY=your-api-key-here
|
|
62
|
-
RERANK_BASE_URL=https://api.siliconflow.cn/v1/rerank
|
|
63
|
-
RERANK_MODEL=BAAI/bge-reranker-v2-m3
|
|
64
|
-
RERANK_TOP_N=20
|
|
65
|
-
|
|
66
|
-
# \u7D22\u5F15\u5FFD\u7565\u6A21\u5F0F\uFF08\u53EF\u9009\uFF0C\u9017\u53F7\u5206\u9694\uFF0C\u9ED8\u8BA4\u5DF2\u5305\u542B\u5E38\u89C1\u5FFD\u7565\u9879\uFF09
|
|
67
|
-
# IGNORE_PATTERNS=.venv,node_modules
|
|
68
|
-
`;
|
|
242
|
+
const defaultEnvContent = getDefaultEnvFileContent();
|
|
69
243
|
try {
|
|
70
|
-
await
|
|
244
|
+
await fs2.writeFile(envFile, defaultEnvContent);
|
|
71
245
|
logger.info(`\u521B\u5EFA .env \u6587\u4EF6: ${envFile}`);
|
|
72
246
|
} catch (err) {
|
|
73
247
|
const error = err;
|
|
@@ -80,7 +254,7 @@ RERANK_TOP_N=20
|
|
|
80
254
|
logger.info("\u521D\u59CB\u5316\u5B8C\u6210\uFF01");
|
|
81
255
|
});
|
|
82
256
|
cli.command("index [path]", "\u626B\u63CF\u4EE3\u7801\u5E93\u5E76\u5EFA\u7ACB\u7D22\u5F15").option("-f, --force", "\u5F3A\u5236\u91CD\u65B0\u7D22\u5F15").action(async (targetPath, options) => {
|
|
83
|
-
const rootPath = targetPath ?
|
|
257
|
+
const rootPath = targetPath ? path3.resolve(targetPath) : process.cwd();
|
|
84
258
|
const projectId = generateProjectId(rootPath);
|
|
85
259
|
logger.info(`\u5F00\u59CB\u626B\u63CF: ${rootPath}`);
|
|
86
260
|
logger.info(`\u9879\u76EE ID: ${projectId}`);
|
|
@@ -89,9 +263,9 @@ cli.command("index [path]", "\u626B\u63CF\u4EE3\u7801\u5E93\u5E76\u5EFA\u7ACB\u7
|
|
|
89
263
|
}
|
|
90
264
|
const startTime = Date.now();
|
|
91
265
|
try {
|
|
92
|
-
const { withLock } = await import("./lock-
|
|
266
|
+
const { withLock: withLock2 } = await import("./lock-HNKQ6X5B.js");
|
|
93
267
|
let lastLoggedPercent = 0;
|
|
94
|
-
const stats = await
|
|
268
|
+
const stats = await withLock2(
|
|
95
269
|
projectId,
|
|
96
270
|
"index",
|
|
97
271
|
async () => scan(rootPath, {
|
|
@@ -120,8 +294,23 @@ cli.command("index [path]", "\u626B\u63CF\u4EE3\u7801\u5E93\u5E76\u5EFA\u7ACB\u7
|
|
|
120
294
|
process.exit(1);
|
|
121
295
|
}
|
|
122
296
|
});
|
|
297
|
+
cli.command("watch [path]", "\u76D1\u542C\u6587\u4EF6\u53D8\u5316\u5E76\u81EA\u52A8\u6267\u884C\u589E\u91CF\u7D22\u5F15").option("--debounce <ms>", "\u9632\u6296\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF0C\u9ED8\u8BA4 500\uFF09").action(async (targetPath, options) => {
|
|
298
|
+
const rootPath = targetPath ? path3.resolve(targetPath) : process.cwd();
|
|
299
|
+
const debounceMs = options.debounce ? Number.parseInt(options.debounce, 10) : 500;
|
|
300
|
+
if (!Number.isFinite(debounceMs) || debounceMs < 0) {
|
|
301
|
+
logger.error("\u65E0\u6548\u7684 --debounce \u53C2\u6570\uFF0C\u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 0 \u7684\u6574\u6570");
|
|
302
|
+
process.exit(1);
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
await startWatchMode(rootPath, { debounceMs });
|
|
306
|
+
} catch (err) {
|
|
307
|
+
const error = err;
|
|
308
|
+
logger.error({ err, stack: error.stack }, `watch \u6A21\u5F0F\u542F\u52A8\u5931\u8D25: ${error.message}`);
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
123
312
|
cli.command("mcp", "\u542F\u52A8 MCP \u670D\u52A1\u5668").action(async () => {
|
|
124
|
-
const { startMcpServer } = await import("./server-
|
|
313
|
+
const { startMcpServer } = await import("./server-UAI3U7AB.js");
|
|
125
314
|
try {
|
|
126
315
|
await startMcpServer();
|
|
127
316
|
} catch (err) {
|
|
@@ -135,14 +324,14 @@ cli.command("mcp", "\u542F\u52A8 MCP \u670D\u52A1\u5668").action(async () => {
|
|
|
135
324
|
});
|
|
136
325
|
cli.command("search", "\u672C\u5730\u68C0\u7D22\uFF08\u53C2\u6570\u5BF9\u9F50 MCP\uFF09").option("--repo-path <path>", "\u4EE3\u7801\u5E93\u6839\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").option("--information-request <text>", "\u81EA\u7136\u8BED\u8A00\u95EE\u9898\u63CF\u8FF0\uFF08\u5FC5\u586B\uFF09").option("--technical-terms <terms>", "\u7CBE\u786E\u672F\u8BED\uFF08\u9017\u53F7\u5206\u9694\uFF09").action(
|
|
137
326
|
async (options) => {
|
|
138
|
-
const repoPath = options.repoPath ?
|
|
327
|
+
const repoPath = options.repoPath ? path3.resolve(options.repoPath) : process.cwd();
|
|
139
328
|
const informationRequest = options.informationRequest;
|
|
140
329
|
if (!informationRequest) {
|
|
141
330
|
logger.error("\u7F3A\u5C11 --information-request");
|
|
142
331
|
process.exit(1);
|
|
143
332
|
}
|
|
144
333
|
const technicalTerms = (options.technicalTerms || "").split(",").map((t) => t.trim()).filter(Boolean);
|
|
145
|
-
const { handleCodebaseRetrieval } = await import("./codebaseRetrieval-
|
|
334
|
+
const { handleCodebaseRetrieval } = await import("./codebaseRetrieval-DIS5RH2C.js");
|
|
146
335
|
const response = await handleCodebaseRetrieval({
|
|
147
336
|
repo_path: repoPath,
|
|
148
337
|
information_request: informationRequest,
|
|
@@ -154,9 +343,9 @@ cli.command("search", "\u672C\u5730\u68C0\u7D22\uFF08\u53C2\u6570\u5BF9\u9F50 MC
|
|
|
154
343
|
}
|
|
155
344
|
);
|
|
156
345
|
cli.command("migrate", "LanceDB \u8FC1\u79FB\u7BA1\u7406\uFF08CRIT-B/CRIT-C\uFF09").option("--reset", "\u6E05\u7A7A LanceDB chunks \u8868\u5E76\u91CD\u7F6E\u8FC1\u79FB\u72B6\u6001\uFF08\u7528\u4E8E\u89E3\u9664 aborted\uFF09").option("-p, --path <path>", "\u9879\u76EE\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").action(async (options) => {
|
|
157
|
-
const rootPath = options.path ?
|
|
346
|
+
const rootPath = options.path ? path3.resolve(options.path) : process.cwd();
|
|
158
347
|
const projectId = generateProjectId(rootPath);
|
|
159
|
-
const { initDb, getLanceDbMigrationState, setLanceDbMigrationState, clearAllVectorIndexHash } = await import("./db-
|
|
348
|
+
const { initDb, getLanceDbMigrationState, setLanceDbMigrationState, clearAllVectorIndexHash } = await import("./db-GBCLP4GG.js");
|
|
160
349
|
const db = initDb(projectId);
|
|
161
350
|
const state = getLanceDbMigrationState(db);
|
|
162
351
|
logger.info({ projectId, state }, "\u5F53\u524D LanceDB \u8FC1\u79FB\u72B6\u6001");
|
|
@@ -170,7 +359,7 @@ cli.command("migrate", "LanceDB \u8FC1\u79FB\u7BA1\u7406\uFF08CRIT-B/CRIT-C\uFF0
|
|
|
170
359
|
db.close();
|
|
171
360
|
return;
|
|
172
361
|
}
|
|
173
|
-
const { getVectorStore } = await import("./vectorStore-
|
|
362
|
+
const { getVectorStore } = await import("./vectorStore-4ODCERRO.js");
|
|
174
363
|
const { getEmbeddingConfig } = await import("./config-LCOJHTCF.js");
|
|
175
364
|
const store = await getVectorStore(projectId, getEmbeddingConfig().dimensions);
|
|
176
365
|
await store.clear();
|
|
@@ -181,5 +370,19 @@ cli.command("migrate", "LanceDB \u8FC1\u79FB\u7BA1\u7406\uFF08CRIT-B/CRIT-C\uFF0
|
|
|
181
370
|
logger.info("\u8FC1\u79FB\u72B6\u6001\u5DF2\u91CD\u7F6E\u4E3A done\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C `contextweaver index` \u91CD\u5EFA\u7D22\u5F15\u3002");
|
|
182
371
|
db.close();
|
|
183
372
|
});
|
|
373
|
+
cli.command("stats", "\u67E5\u770B\u7D22\u5F15/\u641C\u7D22/\u5065\u5EB7\u7EDF\u8BA1").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").option("-p, --path <path>", "\u9879\u76EE\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").action(async (options) => {
|
|
374
|
+
const rootPath = options.path ? path3.resolve(options.path) : process.cwd();
|
|
375
|
+
const projectId = generateProjectId(rootPath);
|
|
376
|
+
const { collectStats, renderStatsText } = await import("./stats-AGKUCJQI.js");
|
|
377
|
+
const report = await collectStats(projectId);
|
|
378
|
+
if (options.json) {
|
|
379
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}
|
|
380
|
+
`);
|
|
381
|
+
} else {
|
|
382
|
+
process.stdout.write(`${renderStatsText(report)}
|
|
383
|
+
`);
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
registerMirrorCommands(cli);
|
|
184
387
|
cli.help();
|
|
185
388
|
cli.parse();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
handleListFiles,
|
|
3
|
+
listFilesSchema
|
|
4
|
+
} from "./chunk-Y6H7C3NA.js";
|
|
5
|
+
import "./chunk-VWBKZ6QL.js";
|
|
6
|
+
import "./chunk-TPM6YP43.js";
|
|
7
|
+
import "./chunk-BFCIZ52F.js";
|
|
8
|
+
import "./chunk-PPLFJGO3.js";
|
|
9
|
+
import "./chunk-JVKVSTQ3.js";
|
|
10
|
+
import "./chunk-SKBAE26T.js";
|
|
11
|
+
export {
|
|
12
|
+
handleListFiles,
|
|
13
|
+
listFilesSchema
|
|
14
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
scan
|
|
3
|
+
} from "./chunk-GDVB6PJ4.js";
|
|
4
|
+
import "./chunk-XMZZZKG7.js";
|
|
5
|
+
import "./chunk-LB42CZEB.js";
|
|
6
|
+
import "./chunk-XFIM2T6S.js";
|
|
7
|
+
import "./chunk-3BNHQV5W.js";
|
|
8
|
+
import "./chunk-PPLFJGO3.js";
|
|
9
|
+
import "./chunk-JVKVSTQ3.js";
|
|
10
|
+
import "./chunk-SKBAE26T.js";
|
|
11
|
+
export {
|
|
12
|
+
scan
|
|
13
|
+
};
|