@zvec/zvec-grep 0.1.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/LICENSE +201 -0
- package/README.md +222 -0
- package/README_CN.md +222 -0
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.js +611 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/commands.d.ts +2 -0
- package/dist/cli/commands.js +270 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/errors.d.ts +6 -0
- package/dist/cli/errors.js +97 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/format/context.d.ts +5 -0
- package/dist/cli/format/context.js +490 -0
- package/dist/cli/format/context.js.map +1 -0
- package/dist/cli/format/debug.d.ts +4 -0
- package/dist/cli/format/debug.js +42 -0
- package/dist/cli/format/debug.js.map +1 -0
- package/dist/cli/format/highlight.d.ts +3 -0
- package/dist/cli/format/highlight.js +106 -0
- package/dist/cli/format/highlight.js.map +1 -0
- package/dist/cli/format/progress.d.ts +9 -0
- package/dist/cli/format/progress.js +92 -0
- package/dist/cli/format/progress.js.map +1 -0
- package/dist/cli/format/range.d.ts +3 -0
- package/dist/cli/format/range.js +24 -0
- package/dist/cli/format/range.js.map +1 -0
- package/dist/cli/format/status.d.ts +7 -0
- package/dist/cli/format/status.js +200 -0
- package/dist/cli/format/status.js.map +1 -0
- package/dist/cli/help.d.ts +1 -0
- package/dist/cli/help.js +88 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +32 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/types.d.ts +56 -0
- package/dist/cli/types.js +10 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/version.d.ts +1 -0
- package/dist/cli/version.js +11 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/engine/collection/index.d.ts +50 -0
- package/dist/engine/collection/index.js +388 -0
- package/dist/engine/collection/index.js.map +1 -0
- package/dist/engine/errors/details.d.ts +6 -0
- package/dist/engine/errors/details.js +27 -0
- package/dist/engine/errors/details.js.map +1 -0
- package/dist/engine/errors/index.d.ts +14 -0
- package/dist/engine/errors/index.js +16 -0
- package/dist/engine/errors/index.js.map +1 -0
- package/dist/engine/models/catalog.d.ts +47 -0
- package/dist/engine/models/catalog.js +68 -0
- package/dist/engine/models/catalog.js.map +1 -0
- package/dist/engine/models/embeddings.d.ts +25 -0
- package/dist/engine/models/embeddings.js +100 -0
- package/dist/engine/models/embeddings.js.map +1 -0
- package/dist/engine/models/factory.d.ts +5 -0
- package/dist/engine/models/factory.js +66 -0
- package/dist/engine/models/factory.js.map +1 -0
- package/dist/engine/models/index.d.ts +6 -0
- package/dist/engine/models/index.js +5 -0
- package/dist/engine/models/index.js.map +1 -0
- package/dist/engine/models/providers/index.d.ts +2 -0
- package/dist/engine/models/providers/index.js +3 -0
- package/dist/engine/models/providers/index.js.map +1 -0
- package/dist/engine/models/providers/llama-cpp/embedding.d.ts +94 -0
- package/dist/engine/models/providers/llama-cpp/embedding.js +459 -0
- package/dist/engine/models/providers/llama-cpp/embedding.js.map +1 -0
- package/dist/engine/models/providers/llama-cpp/index.d.ts +1 -0
- package/dist/engine/models/providers/llama-cpp/index.js +2 -0
- package/dist/engine/models/providers/llama-cpp/index.js.map +1 -0
- package/dist/engine/models/providers/qwen/embedding.d.ts +38 -0
- package/dist/engine/models/providers/qwen/embedding.js +322 -0
- package/dist/engine/models/providers/qwen/embedding.js.map +1 -0
- package/dist/engine/models/providers/qwen/index.d.ts +1 -0
- package/dist/engine/models/providers/qwen/index.js +2 -0
- package/dist/engine/models/providers/qwen/index.js.map +1 -0
- package/dist/engine/models/ranking.d.ts +15 -0
- package/dist/engine/models/ranking.js +2 -0
- package/dist/engine/models/ranking.js.map +1 -0
- package/dist/engine/models/types.d.ts +30 -0
- package/dist/engine/models/types.js +2 -0
- package/dist/engine/models/types.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/adapter.d.ts +19 -0
- package/dist/engine/pipeline/indexing/extractor/code/adapter.js +24 -0
- package/dist/engine/pipeline/indexing/extractor/code/adapter.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/extractor.d.ts +14 -0
- package/dist/engine/pipeline/indexing/extractor/code/extractor.js +594 -0
- package/dist/engine/pipeline/indexing/extractor/code/extractor.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/c-family.d.ts +2 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/c-family.js +116 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/c-family.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/js-ts.d.ts +12 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/js-ts.js +112 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/js-ts.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/metadata.d.ts +8 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/metadata.js +83 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/metadata.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/name-field.d.ts +3 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/name-field.js +22 -0
- package/dist/engine/pipeline/indexing/extractor/code/families/name-field.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/c.d.ts +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/c.js +15 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/c.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/cpp.d.ts +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/cpp.js +18 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/cpp.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/go.d.ts +2 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/go.js +72 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/go.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/java.d.ts +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/java.js +17 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/java.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/javascript.d.ts +2 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/javascript.js +25 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/javascript.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/python.d.ts +2 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/python.js +53 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/python.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/rust.d.ts +2 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/rust.js +29 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/rust.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/typescript.d.ts +2 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/typescript.js +37 -0
- package/dist/engine/pipeline/indexing/extractor/code/languages/typescript.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/index.d.ts +44 -0
- package/dist/engine/pipeline/indexing/extractor/index.js +281 -0
- package/dist/engine/pipeline/indexing/extractor/index.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/markdown/extractor.d.ts +13 -0
- package/dist/engine/pipeline/indexing/extractor/markdown/extractor.js +339 -0
- package/dist/engine/pipeline/indexing/extractor/markdown/extractor.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/grammar.d.ts +4 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/grammar.js +49 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/grammar.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/nodes.d.ts +3 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/nodes.js +26 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/nodes.js.map +1 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/parser.d.ts +2 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/parser.js +31 -0
- package/dist/engine/pipeline/indexing/extractor/tree-sitter/parser.js.map +1 -0
- package/dist/engine/pipeline/indexing/ids.d.ts +1 -0
- package/dist/engine/pipeline/indexing/ids.js +5 -0
- package/dist/engine/pipeline/indexing/ids.js.map +1 -0
- package/dist/engine/pipeline/indexing/index.d.ts +12 -0
- package/dist/engine/pipeline/indexing/index.js +538 -0
- package/dist/engine/pipeline/indexing/index.js.map +1 -0
- package/dist/engine/pipeline/indexing/root-paths.d.ts +7 -0
- package/dist/engine/pipeline/indexing/root-paths.js +151 -0
- package/dist/engine/pipeline/indexing/root-paths.js.map +1 -0
- package/dist/engine/pipeline/indexing/scanner/index.d.ts +5 -0
- package/dist/engine/pipeline/indexing/scanner/index.js +504 -0
- package/dist/engine/pipeline/indexing/scanner/index.js.map +1 -0
- package/dist/engine/pipeline/search/index.d.ts +12 -0
- package/dist/engine/pipeline/search/index.js +761 -0
- package/dist/engine/pipeline/search/index.js.map +1 -0
- package/dist/engine/service/index.d.ts +2 -0
- package/dist/engine/service/index.js +2 -0
- package/dist/engine/service/index.js.map +1 -0
- package/dist/engine/service/lexical.d.ts +29 -0
- package/dist/engine/service/lexical.js +482 -0
- package/dist/engine/service/lexical.js.map +1 -0
- package/dist/engine/service/root.d.ts +15 -0
- package/dist/engine/service/root.js +44 -0
- package/dist/engine/service/root.js.map +1 -0
- package/dist/engine/service/types.d.ts +157 -0
- package/dist/engine/service/types.js +2 -0
- package/dist/engine/service/types.js.map +1 -0
- package/dist/engine/service/zvec-grep.d.ts +2 -0
- package/dist/engine/service/zvec-grep.js +935 -0
- package/dist/engine/service/zvec-grep.js.map +1 -0
- package/dist/engine/storage/index.d.ts +42 -0
- package/dist/engine/storage/index.js +2 -0
- package/dist/engine/storage/index.js.map +1 -0
- package/dist/engine/storage/zvec.d.ts +51 -0
- package/dist/engine/storage/zvec.js +706 -0
- package/dist/engine/storage/zvec.js.map +1 -0
- package/dist/engine/types.d.ts +266 -0
- package/dist/engine/types.js +14 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/engine/utils/glob.d.ts +6 -0
- package/dist/engine/utils/glob.js +110 -0
- package/dist/engine/utils/glob.js.map +1 -0
- package/dist/engine/utils/hash.d.ts +2 -0
- package/dist/engine/utils/hash.js +8 -0
- package/dist/engine/utils/hash.js.map +1 -0
- package/dist/engine/utils/json.d.ts +4 -0
- package/dist/engine/utils/json.js +45 -0
- package/dist/engine/utils/json.js.map +1 -0
- package/dist/engine/utils/lock.d.ts +19 -0
- package/dist/engine/utils/lock.js +254 -0
- package/dist/engine/utils/lock.js.map +1 -0
- package/dist/engine/utils/path.d.ts +4 -0
- package/dist/engine/utils/path.js +18 -0
- package/dist/engine/utils/path.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
- package/skills/zvec-grep/SKILL.md +141 -0
- package/skills/zvec-grep/agents/openai.yaml +4 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { realpathSync, statSync } from "node:fs";
|
|
2
|
+
import { dirname, relative } from "node:path";
|
|
3
|
+
import { EngineError } from "../../errors/index.js";
|
|
4
|
+
import { pathPatternMatches } from "../../utils/glob.js";
|
|
5
|
+
import { isPathInside, normalizePath, toDisplayPath } from "../../utils/path.js";
|
|
6
|
+
export function validateRootPaths(paths) {
|
|
7
|
+
const roots = paths.map(normalizeRootPath);
|
|
8
|
+
const domains = roots.map(rootPathToScanDomain);
|
|
9
|
+
for (let leftIndex = 0; leftIndex < domains.length; leftIndex++) {
|
|
10
|
+
for (let rightIndex = leftIndex + 1; rightIndex < domains.length; rightIndex++) {
|
|
11
|
+
const left = domains[leftIndex];
|
|
12
|
+
const right = domains[rightIndex];
|
|
13
|
+
if (scanDomainsOverlap(left, right)) {
|
|
14
|
+
throw new EngineError("Collection root paths overlap", {
|
|
15
|
+
code: "ZVEC_GREP.ENGINE.SCANNER.OVERLAPPING_ROOT_PATHS",
|
|
16
|
+
context: `left=${left.root.absolutePath} right=${right.root.absolutePath}`,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return roots;
|
|
22
|
+
}
|
|
23
|
+
export function normalizeRootPath(path) {
|
|
24
|
+
if (typeof path === "string") {
|
|
25
|
+
return {
|
|
26
|
+
absolutePath: normalizePath(path),
|
|
27
|
+
recursive: true,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
...path,
|
|
32
|
+
absolutePath: normalizePath(path.absolutePath),
|
|
33
|
+
recursive: path.recursive,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function fileBelongsToRootPath(absolutePath, rootPath) {
|
|
37
|
+
const normalizedPath = normalizePath(absolutePath);
|
|
38
|
+
if (!isPathInside(rootPath.absolutePath, normalizedPath)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const relativePath = toDisplayPath(relative(rootPath.absolutePath, normalizedPath));
|
|
42
|
+
return matchesRootPatterns(relativePath, rootPath);
|
|
43
|
+
}
|
|
44
|
+
export function matchesRootPatterns(relativePath, rootPath) {
|
|
45
|
+
if (matchesAny(relativePath, rootPath.exclude)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if (!rootPath.include || rootPath.include.length === 0) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return matchesAny(relativePath, rootPath.include);
|
|
52
|
+
}
|
|
53
|
+
export function matchesRootIncludePatterns(relativePath, rootPath) {
|
|
54
|
+
return matchesAny(relativePath, rootPath.include);
|
|
55
|
+
}
|
|
56
|
+
export function matchesRootExcludePatterns(relativePath, rootPath) {
|
|
57
|
+
return matchesAny(relativePath, rootPath.exclude);
|
|
58
|
+
}
|
|
59
|
+
function rootPathToScanDomain(root) {
|
|
60
|
+
let info;
|
|
61
|
+
try {
|
|
62
|
+
info = statSync(root.absolutePath, { throwIfNoEntry: false });
|
|
63
|
+
}
|
|
64
|
+
catch (cause) {
|
|
65
|
+
throw new EngineError("Collection root path could not be inspected", {
|
|
66
|
+
code: "ZVEC_GREP.ENGINE.SCANNER.ROOT_PATH_STAT_FAILED",
|
|
67
|
+
context: `rootPath=${root.absolutePath}`,
|
|
68
|
+
cause,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (!info) {
|
|
72
|
+
throw new EngineError("Collection root path does not exist", {
|
|
73
|
+
code: "ZVEC_GREP.ENGINE.SCANNER.ROOT_PATH_MISSING",
|
|
74
|
+
context: `rootPath=${root.absolutePath}`,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const kind = info.isFile()
|
|
78
|
+
? "file"
|
|
79
|
+
: info.isDirectory()
|
|
80
|
+
? "directory"
|
|
81
|
+
: null;
|
|
82
|
+
if (!kind) {
|
|
83
|
+
throw new EngineError("Collection root path must be a file or directory", {
|
|
84
|
+
code: "ZVEC_GREP.ENGINE.SCANNER.UNSUPPORTED_ROOT_PATH",
|
|
85
|
+
context: `rootPath=${root.absolutePath}`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
let realPath;
|
|
89
|
+
try {
|
|
90
|
+
realPath = normalizePath(realpathSync(root.absolutePath));
|
|
91
|
+
}
|
|
92
|
+
catch (cause) {
|
|
93
|
+
throw new EngineError("Collection root path could not be resolved", {
|
|
94
|
+
code: "ZVEC_GREP.ENGINE.SCANNER.ROOT_PATH_REALPATH_FAILED",
|
|
95
|
+
context: `rootPath=${root.absolutePath}`,
|
|
96
|
+
cause,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
root,
|
|
101
|
+
realPath,
|
|
102
|
+
kind,
|
|
103
|
+
stat: info,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function scanDomainsOverlap(left, right) {
|
|
107
|
+
if (sameFileIdentity(left, right)) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (left.kind === "file" && right.kind === "file") {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
if (left.kind === "directory" && right.kind === "directory") {
|
|
114
|
+
return directoryDomainsOverlap(left, right);
|
|
115
|
+
}
|
|
116
|
+
const directory = left.kind === "directory" ? left : right;
|
|
117
|
+
const file = left.kind === "file" ? left : right;
|
|
118
|
+
return directoryCoversFile(directory, file.realPath);
|
|
119
|
+
}
|
|
120
|
+
function sameFileIdentity(left, right) {
|
|
121
|
+
return left.realPath === right.realPath
|
|
122
|
+
|| (left.stat.dev === right.stat.dev
|
|
123
|
+
&& left.stat.ino !== 0
|
|
124
|
+
&& left.stat.ino === right.stat.ino);
|
|
125
|
+
}
|
|
126
|
+
function directoryDomainsOverlap(left, right) {
|
|
127
|
+
if (left.realPath === right.realPath) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
return directoryCoversDirectory(left, right.realPath)
|
|
131
|
+
|| directoryCoversDirectory(right, left.realPath);
|
|
132
|
+
}
|
|
133
|
+
function directoryCoversDirectory(directory, childDirectoryPath) {
|
|
134
|
+
return directory.root.recursive && isPathInside(directory.realPath, childDirectoryPath);
|
|
135
|
+
}
|
|
136
|
+
function directoryCoversFile(directory, filePath) {
|
|
137
|
+
if (!isPathInside(directory.realPath, filePath)) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return directory.root.recursive || dirname(filePath) === directory.realPath;
|
|
141
|
+
}
|
|
142
|
+
function matchesAny(relativePath, patterns) {
|
|
143
|
+
if (!patterns || patterns.length === 0) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return patterns.some((pattern) => patternMatches(pattern, relativePath));
|
|
147
|
+
}
|
|
148
|
+
function patternMatches(pattern, relativePath) {
|
|
149
|
+
return pathPatternMatches(pattern, relativePath);
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=root-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root-paths.js","sourceRoot":"","sources":["../../../../src/engine/pipeline/indexing/root-paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import { open, readFile, readdir, stat } from "node:fs/promises";
|
|
2
|
+
import { basename, extname, join, relative } from "node:path";
|
|
3
|
+
import { sha256Text } from "../../../utils/hash.js";
|
|
4
|
+
import { normalizePathPattern, pathPatternMatches, pathPatternMightMatchDescendant, } from "../../../utils/glob.js";
|
|
5
|
+
import { normalizePath, toDisplayPath } from "../../../utils/path.js";
|
|
6
|
+
import { matchesRootExcludePatterns, matchesRootIncludePatterns, matchesRootPatterns, normalizeRootPath, validateRootPaths, } from "../root-paths.js";
|
|
7
|
+
const DEFAULT_MAX_FILE_SIZE_BYTES = 1 * 1024 * 1024;
|
|
8
|
+
const BINARY_SNIFF_BYTES = 8192;
|
|
9
|
+
const BINARY_CONTROL_CHAR_RATIO = 0.30;
|
|
10
|
+
const DEFAULT_IGNORED_DIRECTORY_NAMES = [
|
|
11
|
+
"node_modules",
|
|
12
|
+
"vendor",
|
|
13
|
+
"dist",
|
|
14
|
+
"build",
|
|
15
|
+
"out",
|
|
16
|
+
"target",
|
|
17
|
+
"coverage",
|
|
18
|
+
"__pycache__",
|
|
19
|
+
"venv",
|
|
20
|
+
".venv",
|
|
21
|
+
"env",
|
|
22
|
+
".tox",
|
|
23
|
+
".eggs",
|
|
24
|
+
"Pods",
|
|
25
|
+
".next",
|
|
26
|
+
".nuxt",
|
|
27
|
+
".svelte-kit",
|
|
28
|
+
".turbo",
|
|
29
|
+
".vite",
|
|
30
|
+
".parcel-cache",
|
|
31
|
+
".cache",
|
|
32
|
+
".gradle",
|
|
33
|
+
".pytest_cache",
|
|
34
|
+
".mypy_cache",
|
|
35
|
+
".ruff_cache",
|
|
36
|
+
"tmp",
|
|
37
|
+
"temp",
|
|
38
|
+
"logs",
|
|
39
|
+
];
|
|
40
|
+
const HARD_SKIP_HIDDEN_NAMES = new Set([
|
|
41
|
+
".git",
|
|
42
|
+
".zvec-grep",
|
|
43
|
+
]);
|
|
44
|
+
const DEFAULT_IGNORE_RULES = DEFAULT_IGNORED_DIRECTORY_NAMES.map((pattern) => ({
|
|
45
|
+
basePath: "",
|
|
46
|
+
pattern,
|
|
47
|
+
negated: false,
|
|
48
|
+
directoryOnly: true,
|
|
49
|
+
anchored: false,
|
|
50
|
+
hasSlash: false,
|
|
51
|
+
}));
|
|
52
|
+
const BINARY_EXTENSIONS = new Set([
|
|
53
|
+
".zip",
|
|
54
|
+
".tar",
|
|
55
|
+
".gz",
|
|
56
|
+
".bz2",
|
|
57
|
+
".xz",
|
|
58
|
+
".7z",
|
|
59
|
+
".rar",
|
|
60
|
+
".exe",
|
|
61
|
+
".dll",
|
|
62
|
+
".dylib",
|
|
63
|
+
".so",
|
|
64
|
+
".a",
|
|
65
|
+
".o",
|
|
66
|
+
".obj",
|
|
67
|
+
".wasm",
|
|
68
|
+
".class",
|
|
69
|
+
".jar",
|
|
70
|
+
".pdf",
|
|
71
|
+
".doc",
|
|
72
|
+
".docx",
|
|
73
|
+
".ppt",
|
|
74
|
+
".pptx",
|
|
75
|
+
".xls",
|
|
76
|
+
".xlsx",
|
|
77
|
+
".mp3",
|
|
78
|
+
".mp4",
|
|
79
|
+
".mov",
|
|
80
|
+
".avi",
|
|
81
|
+
".mkv",
|
|
82
|
+
".db",
|
|
83
|
+
".sqlite",
|
|
84
|
+
]);
|
|
85
|
+
const CODE_FORMATS = {
|
|
86
|
+
".c": "c",
|
|
87
|
+
".cc": "cpp",
|
|
88
|
+
".cpp": "cpp",
|
|
89
|
+
".cxx": "cpp",
|
|
90
|
+
".h": "cpp",
|
|
91
|
+
".hpp": "cpp",
|
|
92
|
+
".go": "go",
|
|
93
|
+
".java": "java",
|
|
94
|
+
".js": "javascript",
|
|
95
|
+
".jsx": "jsx",
|
|
96
|
+
".mjs": "javascript",
|
|
97
|
+
".cjs": "javascript",
|
|
98
|
+
".ts": "typescript",
|
|
99
|
+
".tsx": "tsx",
|
|
100
|
+
".py": "python",
|
|
101
|
+
".rs": "rust",
|
|
102
|
+
".rb": "ruby",
|
|
103
|
+
".php": "php",
|
|
104
|
+
".swift": "swift",
|
|
105
|
+
".kt": "kotlin",
|
|
106
|
+
".kts": "kotlin",
|
|
107
|
+
".cs": "csharp",
|
|
108
|
+
".scala": "scala",
|
|
109
|
+
".sh": "bash",
|
|
110
|
+
".bash": "bash",
|
|
111
|
+
".zsh": "bash",
|
|
112
|
+
".sql": "sql",
|
|
113
|
+
".css": "css",
|
|
114
|
+
".scss": "scss",
|
|
115
|
+
".less": "less",
|
|
116
|
+
".vue": "vue",
|
|
117
|
+
".svelte": "svelte",
|
|
118
|
+
};
|
|
119
|
+
const DATA_FORMATS = {
|
|
120
|
+
".csv": "csv",
|
|
121
|
+
".json": "json",
|
|
122
|
+
".jsonc": "json",
|
|
123
|
+
".toml": "toml",
|
|
124
|
+
".yaml": "yaml",
|
|
125
|
+
".yml": "yaml",
|
|
126
|
+
};
|
|
127
|
+
const TEXT_FORMATS = {
|
|
128
|
+
".md": "markdown",
|
|
129
|
+
".mdx": "markdown",
|
|
130
|
+
".rst": "rst",
|
|
131
|
+
".txt": "text",
|
|
132
|
+
".html": "html",
|
|
133
|
+
".htm": "html",
|
|
134
|
+
".xml": "xml",
|
|
135
|
+
};
|
|
136
|
+
const IMAGE_FORMATS = {
|
|
137
|
+
".gif": "gif",
|
|
138
|
+
".jpeg": "jpeg",
|
|
139
|
+
".jpg": "jpeg",
|
|
140
|
+
".png": "png",
|
|
141
|
+
".webp": "webp",
|
|
142
|
+
};
|
|
143
|
+
export async function scanRootPaths(collectionId, rootPaths) {
|
|
144
|
+
const validatedRootPaths = validateRootPaths(rootPaths);
|
|
145
|
+
const files = [];
|
|
146
|
+
for (const rootPath of validatedRootPaths) {
|
|
147
|
+
await scanRootPath(collectionId, rootPath, files);
|
|
148
|
+
}
|
|
149
|
+
return { files };
|
|
150
|
+
}
|
|
151
|
+
async function scanRootPath(collectionId, rootPath, files) {
|
|
152
|
+
const root = normalizeRootPath(rootPath);
|
|
153
|
+
const info = await stat(root.absolutePath).catch(() => null);
|
|
154
|
+
if (!info) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (info.isFile()) {
|
|
158
|
+
const file = await readFileInfo(collectionId, root, root.absolutePath);
|
|
159
|
+
if (file) {
|
|
160
|
+
files.push(file);
|
|
161
|
+
}
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (!info.isDirectory()) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (HARD_SKIP_HIDDEN_NAMES.has(basename(root.absolutePath))) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
await walk(collectionId, root, root.absolutePath, files, DEFAULT_IGNORE_RULES);
|
|
171
|
+
}
|
|
172
|
+
async function walk(collectionId, rootPath, currentPath, files, parentIgnoreRules) {
|
|
173
|
+
let entries;
|
|
174
|
+
const ignoreRules = [
|
|
175
|
+
...parentIgnoreRules,
|
|
176
|
+
...await readGitIgnoreRules(rootPath, currentPath),
|
|
177
|
+
];
|
|
178
|
+
try {
|
|
179
|
+
entries = await readdir(currentPath, { withFileTypes: true });
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
for (const entry of entries) {
|
|
185
|
+
const absolutePath = join(currentPath, entry.name);
|
|
186
|
+
const relativePath = toDisplayPath(relative(rootPath.absolutePath, absolutePath));
|
|
187
|
+
if (entry.isDirectory()) {
|
|
188
|
+
if (!rootPath.recursive) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
const ignoreMatch = matchIgnoreRules(relativePath, true, ignoreRules);
|
|
192
|
+
if (HARD_SKIP_HIDDEN_NAMES.has(entry.name)
|
|
193
|
+
|| matchesRootExcludePatterns(relativePath, rootPath)
|
|
194
|
+
|| (ignoreMatch.ignored && !ignoredPathExplicitlyIncluded(relativePath, rootPath, ignoreMatch))
|
|
195
|
+
|| shouldSkipHiddenDirectory(entry.name, relativePath, rootPath, ignoreMatch.matchedNegation)) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
await walk(collectionId, rootPath, absolutePath, files, ignoreRules);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (!entry.isFile()) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const ignoreMatch = matchIgnoreRules(relativePath, false, ignoreRules);
|
|
205
|
+
if (ignoreMatch.ignored && !ignoredPathExplicitlyIncluded(relativePath, rootPath, ignoreMatch)) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (shouldSkipHiddenFile(entry.name, relativePath, rootPath, ignoreMatch.matchedNegation)) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (!matchesRootPatterns(relativePath, rootPath)) {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
const file = await readFileInfo(collectionId, rootPath, absolutePath);
|
|
215
|
+
if (file) {
|
|
216
|
+
files.push(file);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function isHiddenName(name) {
|
|
221
|
+
return name.startsWith(".") && name !== "." && name !== "..";
|
|
222
|
+
}
|
|
223
|
+
async function readGitIgnoreRules(rootPath, currentPath) {
|
|
224
|
+
const content = await readFile(join(currentPath, ".gitignore"), "utf8").catch(() => null);
|
|
225
|
+
if (content === null) {
|
|
226
|
+
return [];
|
|
227
|
+
}
|
|
228
|
+
const basePath = toDisplayPath(relative(rootPath.absolutePath, currentPath));
|
|
229
|
+
return parseGitIgnoreRules(content, basePath);
|
|
230
|
+
}
|
|
231
|
+
function parseGitIgnoreRules(content, basePath) {
|
|
232
|
+
const rules = [];
|
|
233
|
+
for (const rawLine of content.split(/\r?\n/)) {
|
|
234
|
+
const rule = parseGitIgnoreRule(rawLine, basePath);
|
|
235
|
+
if (rule) {
|
|
236
|
+
rules.push(rule);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return rules;
|
|
240
|
+
}
|
|
241
|
+
function parseGitIgnoreRule(line, basePath) {
|
|
242
|
+
let pattern = line.trim();
|
|
243
|
+
if (pattern.length === 0 || pattern.startsWith("#")) {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
let negated = false;
|
|
247
|
+
if (pattern.startsWith("\\#") || pattern.startsWith("\\!")) {
|
|
248
|
+
pattern = pattern.slice(1);
|
|
249
|
+
}
|
|
250
|
+
else if (pattern.startsWith("!")) {
|
|
251
|
+
negated = true;
|
|
252
|
+
pattern = pattern.slice(1).trim();
|
|
253
|
+
}
|
|
254
|
+
if (pattern.length === 0) {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
const directoryOnly = pattern.endsWith("/");
|
|
258
|
+
pattern = directoryOnly ? pattern.replace(/\/+$/, "") : pattern;
|
|
259
|
+
const anchored = pattern.startsWith("/");
|
|
260
|
+
pattern = anchored ? pattern.replace(/^\/+/, "") : pattern;
|
|
261
|
+
pattern = normalizePathPattern(pattern);
|
|
262
|
+
if (pattern.length === 0) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
basePath,
|
|
267
|
+
pattern,
|
|
268
|
+
negated,
|
|
269
|
+
directoryOnly,
|
|
270
|
+
anchored,
|
|
271
|
+
hasSlash: pattern.includes("/"),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function matchIgnoreRules(relativePath, isDirectory, rules) {
|
|
275
|
+
let ignored = false;
|
|
276
|
+
let matchedNegation = false;
|
|
277
|
+
let matchedRule;
|
|
278
|
+
for (const rule of rules) {
|
|
279
|
+
if (!ignoreRuleMatches(rule, relativePath, isDirectory)) {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
ignored = !rule.negated;
|
|
283
|
+
matchedNegation = rule.negated;
|
|
284
|
+
matchedRule = rule;
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
ignored,
|
|
288
|
+
matchedNegation,
|
|
289
|
+
matchedRule,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
function ignoredPathExplicitlyIncluded(relativePath, rootPath, ignoreMatch) {
|
|
293
|
+
if (!ignoreMatch.ignored || !ignoreMatch.matchedRule || !rootPath.include) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
return rootPath.include.some((pattern) => includePatternNamesIgnoredPath(pattern, relativePath, ignoreMatch.matchedRule.pattern));
|
|
297
|
+
}
|
|
298
|
+
function includePatternNamesIgnoredPath(includePattern, relativePath, ignoredPattern) {
|
|
299
|
+
const normalizedInclude = normalizePathPattern(includePattern);
|
|
300
|
+
const normalizedRelativePath = normalizePathPattern(relativePath);
|
|
301
|
+
const ignoredSegments = ignoredPattern.split("/");
|
|
302
|
+
if (!pathPatternMightMatchDescendant(normalizedInclude, normalizedRelativePath)
|
|
303
|
+
&& !pathPatternMatches(normalizedInclude, normalizedRelativePath)) {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
return normalizedInclude.split("/").some((segment) => ignoredSegments.some((ignoredSegment) => includeSegmentNamesIgnoredPath(segment, ignoredSegment)));
|
|
307
|
+
}
|
|
308
|
+
function includeSegmentNamesIgnoredPath(segment, ignoredSegment) {
|
|
309
|
+
if (segment === "*" || segment === "**" || segment === "?") {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
return segmentMatches(segment, ignoredSegment);
|
|
313
|
+
}
|
|
314
|
+
function ignoreRuleMatches(rule, relativePath, isDirectory) {
|
|
315
|
+
const path = relativeToIgnoreRuleBase(relativePath, rule.basePath);
|
|
316
|
+
if (path === null || path.length === 0) {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
if (rule.directoryOnly) {
|
|
320
|
+
if (rule.anchored || rule.hasSlash) {
|
|
321
|
+
return pathPatternMatches(rule.pattern, path);
|
|
322
|
+
}
|
|
323
|
+
return pathContainsMatchingSegment(path, rule.pattern);
|
|
324
|
+
}
|
|
325
|
+
if (rule.anchored || rule.hasSlash) {
|
|
326
|
+
return pathPatternMatches(rule.pattern, path);
|
|
327
|
+
}
|
|
328
|
+
if (isDirectory && pathContainsMatchingSegment(path, rule.pattern)) {
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
return segmentMatches(rule.pattern, basename(path));
|
|
332
|
+
}
|
|
333
|
+
function relativeToIgnoreRuleBase(relativePath, basePath) {
|
|
334
|
+
if (basePath.length === 0) {
|
|
335
|
+
return relativePath;
|
|
336
|
+
}
|
|
337
|
+
if (relativePath === basePath) {
|
|
338
|
+
return "";
|
|
339
|
+
}
|
|
340
|
+
const prefix = `${basePath}/`;
|
|
341
|
+
return relativePath.startsWith(prefix)
|
|
342
|
+
? relativePath.slice(prefix.length)
|
|
343
|
+
: null;
|
|
344
|
+
}
|
|
345
|
+
function pathContainsMatchingSegment(path, pattern) {
|
|
346
|
+
return path.split("/").some((segment) => segmentMatches(pattern, segment));
|
|
347
|
+
}
|
|
348
|
+
function segmentMatches(pattern, segment) {
|
|
349
|
+
return pathPatternMatches(pattern, segment);
|
|
350
|
+
}
|
|
351
|
+
function shouldSkipHiddenDirectory(name, relativePath, rootPath, unignoredByGitIgnore) {
|
|
352
|
+
if (!isHiddenName(name)) {
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
if (unignoredByGitIgnore) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
return !matchesRootIncludePatterns(relativePath, rootPath)
|
|
359
|
+
&& !hasIncludeDescendant(relativePath, rootPath.include);
|
|
360
|
+
}
|
|
361
|
+
function shouldSkipHiddenFile(name, relativePath, rootPath, unignoredByGitIgnore) {
|
|
362
|
+
if (unignoredByGitIgnore) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
return isHiddenName(name) && !matchesRootIncludePatterns(relativePath, rootPath);
|
|
366
|
+
}
|
|
367
|
+
function hasIncludeDescendant(relativePath, includePatterns) {
|
|
368
|
+
if (!includePatterns || includePatterns.length === 0) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
return includePatterns.some((pattern) => includePatternDeclaresHiddenDirectory(pattern, relativePath)
|
|
372
|
+
&& pathPatternMightMatchDescendant(pattern, relativePath));
|
|
373
|
+
}
|
|
374
|
+
function includePatternDeclaresHiddenDirectory(pattern, relativePath) {
|
|
375
|
+
const name = basename(relativePath);
|
|
376
|
+
if (!isHiddenName(name)) {
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
return normalizePathPattern(pattern)
|
|
380
|
+
.split("/")
|
|
381
|
+
.some((segment) => hiddenPatternSegmentMatches(segment, name));
|
|
382
|
+
}
|
|
383
|
+
function hiddenPatternSegmentMatches(patternSegment, name) {
|
|
384
|
+
if (!patternSegment.startsWith(".")) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
if (!patternSegment.includes("*") && !patternSegment.includes("?")) {
|
|
388
|
+
return patternSegment === name;
|
|
389
|
+
}
|
|
390
|
+
return segmentGlobToRegExp(patternSegment).test(name);
|
|
391
|
+
}
|
|
392
|
+
function segmentGlobToRegExp(pattern) {
|
|
393
|
+
let expression = "^";
|
|
394
|
+
for (const char of pattern) {
|
|
395
|
+
if (char === "*") {
|
|
396
|
+
expression += "[^/]*";
|
|
397
|
+
}
|
|
398
|
+
else if (char === "?") {
|
|
399
|
+
expression += "[^/]";
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
expression += escapeRegExp(char);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return new RegExp(`${expression}$`);
|
|
406
|
+
}
|
|
407
|
+
function escapeRegExp(value) {
|
|
408
|
+
return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
|
|
409
|
+
}
|
|
410
|
+
async function readFileInfo(collectionId, rootPath, absolutePath) {
|
|
411
|
+
const info = await stat(absolutePath).catch(() => null);
|
|
412
|
+
if (!info || !info.isFile()) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
if (info.size === 0 || info.size > DEFAULT_MAX_FILE_SIZE_BYTES) {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
const detected = detectFileType(absolutePath);
|
|
419
|
+
if (!detected) {
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
if (detected.kind !== "image" && await isLikelyBinaryFile(absolutePath)) {
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
return {
|
|
426
|
+
id: makeFileId(collectionId, absolutePath),
|
|
427
|
+
collectionId,
|
|
428
|
+
absolutePath,
|
|
429
|
+
relativePath: toDisplayPath(relative(rootPath.absolutePath, absolutePath)),
|
|
430
|
+
rootPath: rootPath.absolutePath,
|
|
431
|
+
sizeBytes: info.size,
|
|
432
|
+
lastModifiedTime: info.mtimeMs,
|
|
433
|
+
kind: detected.kind,
|
|
434
|
+
format: detected.format,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
async function isLikelyBinaryFile(path) {
|
|
438
|
+
let handle;
|
|
439
|
+
try {
|
|
440
|
+
handle = await open(path, "r");
|
|
441
|
+
const buffer = Buffer.alloc(BINARY_SNIFF_BYTES);
|
|
442
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
443
|
+
if (bytesRead === 0) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
let suspicious = 0;
|
|
447
|
+
for (let index = 0; index < bytesRead; index++) {
|
|
448
|
+
const value = buffer[index];
|
|
449
|
+
if (value === 0) {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
if (isSuspiciousControlByte(value)) {
|
|
453
|
+
suspicious++;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return suspicious / bytesRead > BINARY_CONTROL_CHAR_RATIO;
|
|
457
|
+
}
|
|
458
|
+
catch {
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
finally {
|
|
462
|
+
await handle?.close().catch(() => undefined);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function isSuspiciousControlByte(value) {
|
|
466
|
+
return value < 32
|
|
467
|
+
&& value !== 7
|
|
468
|
+
&& value !== 8
|
|
469
|
+
&& value !== 9
|
|
470
|
+
&& value !== 10
|
|
471
|
+
&& value !== 12
|
|
472
|
+
&& value !== 13
|
|
473
|
+
&& value !== 27;
|
|
474
|
+
}
|
|
475
|
+
function detectFileType(path) {
|
|
476
|
+
const name = basename(path);
|
|
477
|
+
if (name === "Dockerfile") {
|
|
478
|
+
return { kind: "code", format: "dockerfile" };
|
|
479
|
+
}
|
|
480
|
+
if (name === "Makefile") {
|
|
481
|
+
return { kind: "code", format: "makefile" };
|
|
482
|
+
}
|
|
483
|
+
const extension = extname(name).toLowerCase();
|
|
484
|
+
if (extension in CODE_FORMATS) {
|
|
485
|
+
return { kind: "code", format: CODE_FORMATS[extension] };
|
|
486
|
+
}
|
|
487
|
+
if (extension in DATA_FORMATS) {
|
|
488
|
+
return { kind: "data", format: DATA_FORMATS[extension] };
|
|
489
|
+
}
|
|
490
|
+
if (extension in TEXT_FORMATS) {
|
|
491
|
+
return { kind: "text", format: TEXT_FORMATS[extension] };
|
|
492
|
+
}
|
|
493
|
+
if (extension in IMAGE_FORMATS) {
|
|
494
|
+
return { kind: "image", format: IMAGE_FORMATS[extension] };
|
|
495
|
+
}
|
|
496
|
+
if (BINARY_EXTENSIONS.has(extension)) {
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
return { kind: "text", format: extension ? extension.slice(1) : "text" };
|
|
500
|
+
}
|
|
501
|
+
function makeFileId(collectionId, absolutePath) {
|
|
502
|
+
return sha256Text(`${collectionId}\0${normalizePath(absolutePath)}`);
|
|
503
|
+
}
|
|
504
|
+
//# sourceMappingURL=index.js.map
|