@wb200/mgrep 0.1.10
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 +288 -0
- package/dist/commands/login.js +28 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/search.js +191 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/watch.js +134 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/commands/watch_mcp.js +77 -0
- package/dist/commands/watch_mcp.js.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/install/claude-code.js +71 -0
- package/dist/install/claude-code.js.map +1 -0
- package/dist/install/codex.js +116 -0
- package/dist/install/codex.js.map +1 -0
- package/dist/install/droid.js +191 -0
- package/dist/install/droid.js.map +1 -0
- package/dist/install/opencode.js +161 -0
- package/dist/install/opencode.js.map +1 -0
- package/dist/lib/config.js +216 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/context.js +35 -0
- package/dist/lib/context.js.map +1 -0
- package/dist/lib/file.js +154 -0
- package/dist/lib/file.js.map +1 -0
- package/dist/lib/git.js +167 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/logger.js +80 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/model-studio.js +205 -0
- package/dist/lib/model-studio.js.map +1 -0
- package/dist/lib/store.js +639 -0
- package/dist/lib/store.js.map +1 -0
- package/dist/lib/sync-helpers.js +51 -0
- package/dist/lib/sync-helpers.js.map +1 -0
- package/dist/lib/utils.js +300 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/warning.js +34 -0
- package/dist/lib/warning.js.map +1 -0
- package/dist/plugins/mgrep/.claude-plugin/plugin.json +9 -0
- package/dist/plugins/mgrep/hooks/hook.json +27 -0
- package/dist/plugins/mgrep/hooks/mgrep_watch.py +55 -0
- package/dist/plugins/mgrep/hooks/mgrep_watch_kill.py +50 -0
- package/dist/plugins/mgrep/skills/mgrep/SKILL.md +59 -0
- package/package.json +74 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import YAML from "yaml";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
const LOCAL_CONFIG_FILES = [".mgreprc.yaml", ".mgreprc.yml"];
|
|
7
|
+
const GLOBAL_CONFIG_DIR = ".config/mgrep";
|
|
8
|
+
const GLOBAL_CONFIG_FILES = ["config.yaml", "config.yml"];
|
|
9
|
+
const ENV_PREFIX = "MGREP_";
|
|
10
|
+
const DEFAULT_MAX_FILE_SIZE = 4 * 1024 * 1024;
|
|
11
|
+
const DEFAULT_MAX_FILE_COUNT = 10000;
|
|
12
|
+
const DEFAULT_LANCEDB_PATH = path.join(os.homedir(), ".mgrep", "lancedb");
|
|
13
|
+
const DEFAULT_SYNC_CONCURRENCY = 20;
|
|
14
|
+
const DEFAULT_EMBED_MODEL = "Qwen/Qwen3-Embedding-4B";
|
|
15
|
+
const DEFAULT_EMBED_DIMENSIONS = 2560;
|
|
16
|
+
const DEFAULT_RERANK_MODEL = "Qwen/Qwen3-Reranker-4B";
|
|
17
|
+
const DEFAULT_LLM_MODEL = "qwen3.5-plus";
|
|
18
|
+
const ConfigSchema = z.object({
|
|
19
|
+
maxFileSize: z.number().positive().optional(),
|
|
20
|
+
maxFileCount: z.number().positive().optional(),
|
|
21
|
+
syncConcurrency: z.number().positive().optional(),
|
|
22
|
+
lancedbPath: z.string().min(1).optional(),
|
|
23
|
+
embedModel: z.string().min(1).optional(),
|
|
24
|
+
embedDimensions: z.number().positive().optional(),
|
|
25
|
+
rerankModel: z.string().min(1).optional(),
|
|
26
|
+
llmModel: z.string().min(1).optional(),
|
|
27
|
+
});
|
|
28
|
+
const DEFAULT_CONFIG = {
|
|
29
|
+
maxFileSize: DEFAULT_MAX_FILE_SIZE,
|
|
30
|
+
maxFileCount: DEFAULT_MAX_FILE_COUNT,
|
|
31
|
+
syncConcurrency: DEFAULT_SYNC_CONCURRENCY,
|
|
32
|
+
lancedbPath: DEFAULT_LANCEDB_PATH,
|
|
33
|
+
embedModel: DEFAULT_EMBED_MODEL,
|
|
34
|
+
embedDimensions: DEFAULT_EMBED_DIMENSIONS,
|
|
35
|
+
rerankModel: DEFAULT_RERANK_MODEL,
|
|
36
|
+
llmModel: DEFAULT_LLM_MODEL,
|
|
37
|
+
};
|
|
38
|
+
const configCache = new Map();
|
|
39
|
+
/**
|
|
40
|
+
* Reads and parses a YAML config file
|
|
41
|
+
*
|
|
42
|
+
* @param filePath - The path to the config file
|
|
43
|
+
* @returns The parsed config object or null if file doesn't exist or is invalid
|
|
44
|
+
*/
|
|
45
|
+
function readYamlConfig(filePath) {
|
|
46
|
+
if (!fs.existsSync(filePath)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
51
|
+
const parsed = YAML.parse(content);
|
|
52
|
+
const validated = ConfigSchema.parse(parsed);
|
|
53
|
+
return validated;
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
57
|
+
console.warn(`Warning: Failed to parse config file ${filePath}: ${message}`);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Finds and reads the first existing config file from a list of candidates
|
|
63
|
+
*
|
|
64
|
+
* @param candidates - List of file paths to check
|
|
65
|
+
* @returns The parsed config or null if none found
|
|
66
|
+
*/
|
|
67
|
+
function findConfig(candidates) {
|
|
68
|
+
for (const filePath of candidates) {
|
|
69
|
+
const config = readYamlConfig(filePath);
|
|
70
|
+
if (config !== null) {
|
|
71
|
+
return config;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
function getGlobalConfigPaths() {
|
|
77
|
+
const configDir = path.join(os.homedir(), GLOBAL_CONFIG_DIR);
|
|
78
|
+
return GLOBAL_CONFIG_FILES.map((file) => path.join(configDir, file));
|
|
79
|
+
}
|
|
80
|
+
function getLocalConfigPaths(dir) {
|
|
81
|
+
return LOCAL_CONFIG_FILES.map((file) => path.join(dir, file));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Loads configuration from environment variables
|
|
85
|
+
*
|
|
86
|
+
* @returns The config values from environment variables
|
|
87
|
+
*/
|
|
88
|
+
function loadEnvConfig() {
|
|
89
|
+
const config = {};
|
|
90
|
+
const maxFileSizeEnv = process.env[`${ENV_PREFIX}MAX_FILE_SIZE`];
|
|
91
|
+
if (maxFileSizeEnv) {
|
|
92
|
+
const parsed = Number.parseInt(maxFileSizeEnv, 10);
|
|
93
|
+
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
94
|
+
config.maxFileSize = parsed;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const maxFileCountEnv = process.env[`${ENV_PREFIX}MAX_FILE_COUNT`];
|
|
98
|
+
if (maxFileCountEnv) {
|
|
99
|
+
const parsed = Number.parseInt(maxFileCountEnv, 10);
|
|
100
|
+
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
101
|
+
config.maxFileCount = parsed;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const syncConcurrencyEnv = process.env[`${ENV_PREFIX}SYNC_CONCURRENCY`];
|
|
105
|
+
if (syncConcurrencyEnv) {
|
|
106
|
+
const parsed = Number.parseInt(syncConcurrencyEnv, 10);
|
|
107
|
+
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
108
|
+
config.syncConcurrency = parsed;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const lancedbPathEnv = process.env[`${ENV_PREFIX}LANCEDB_PATH`];
|
|
112
|
+
if (lancedbPathEnv) {
|
|
113
|
+
config.lancedbPath = lancedbPathEnv;
|
|
114
|
+
}
|
|
115
|
+
const embedModelEnv = process.env[`${ENV_PREFIX}EMBED_MODEL`];
|
|
116
|
+
if (embedModelEnv) {
|
|
117
|
+
config.embedModel = embedModelEnv;
|
|
118
|
+
}
|
|
119
|
+
const embedDimensionsEnv = process.env[`${ENV_PREFIX}EMBED_DIMENSIONS`];
|
|
120
|
+
if (embedDimensionsEnv) {
|
|
121
|
+
const parsed = Number.parseInt(embedDimensionsEnv, 10);
|
|
122
|
+
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
123
|
+
config.embedDimensions = parsed;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const rerankModelEnv = process.env[`${ENV_PREFIX}RERANK_MODEL`];
|
|
127
|
+
if (rerankModelEnv) {
|
|
128
|
+
config.rerankModel = rerankModelEnv;
|
|
129
|
+
}
|
|
130
|
+
const llmModelEnv = process.env[`${ENV_PREFIX}LLM_MODEL`];
|
|
131
|
+
if (llmModelEnv) {
|
|
132
|
+
config.llmModel = llmModelEnv;
|
|
133
|
+
}
|
|
134
|
+
return config;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Loads mgrep configuration with the following precedence (highest to lowest):
|
|
138
|
+
* 1. CLI flags (passed as cliOptions)
|
|
139
|
+
* 2. Environment variables (MGREP_MAX_FILE_SIZE, MGREP_MAX_FILE_COUNT)
|
|
140
|
+
* 3. Local config file (.mgreprc.yaml or .mgreprc.yml in project directory)
|
|
141
|
+
* 4. Global config file (~/.config/mgrep/config.yaml or config.yml)
|
|
142
|
+
* 5. Default values
|
|
143
|
+
*
|
|
144
|
+
* @param dir - The directory to load local configuration from
|
|
145
|
+
* @param cliOptions - CLI options that override all other config sources
|
|
146
|
+
* @returns The merged configuration
|
|
147
|
+
*/
|
|
148
|
+
export function loadConfig(dir, cliOptions = {}) {
|
|
149
|
+
const absoluteDir = path.resolve(dir);
|
|
150
|
+
const cacheKey = `${absoluteDir}:${JSON.stringify(cliOptions)}`;
|
|
151
|
+
if (configCache.has(cacheKey)) {
|
|
152
|
+
return configCache.get(cacheKey);
|
|
153
|
+
}
|
|
154
|
+
const globalConfig = findConfig(getGlobalConfigPaths());
|
|
155
|
+
const localConfig = findConfig(getLocalConfigPaths(absoluteDir));
|
|
156
|
+
const envConfig = loadEnvConfig();
|
|
157
|
+
const config = {
|
|
158
|
+
...DEFAULT_CONFIG,
|
|
159
|
+
...globalConfig,
|
|
160
|
+
...localConfig,
|
|
161
|
+
...envConfig,
|
|
162
|
+
...filterUndefinedCliOptions(cliOptions),
|
|
163
|
+
};
|
|
164
|
+
configCache.set(cacheKey, config);
|
|
165
|
+
return config;
|
|
166
|
+
}
|
|
167
|
+
function filterUndefinedCliOptions(options) {
|
|
168
|
+
const result = {};
|
|
169
|
+
if (options.maxFileSize !== undefined) {
|
|
170
|
+
result.maxFileSize = options.maxFileSize;
|
|
171
|
+
}
|
|
172
|
+
if (options.maxFileCount !== undefined) {
|
|
173
|
+
result.maxFileCount = options.maxFileCount;
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Clears the configuration cache.
|
|
179
|
+
* Useful for testing or when config files may have changed.
|
|
180
|
+
*/
|
|
181
|
+
export function clearConfigCache() {
|
|
182
|
+
configCache.clear();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Checks if a file exceeds the maximum allowed file size
|
|
186
|
+
*
|
|
187
|
+
* @param filePath - The path to the file to check
|
|
188
|
+
* @param maxFileSize - The maximum allowed file size in bytes
|
|
189
|
+
* @returns True if the file exceeds the limit, false otherwise
|
|
190
|
+
*/
|
|
191
|
+
export function exceedsMaxFileSize(filePath, maxFileSize) {
|
|
192
|
+
try {
|
|
193
|
+
const stat = fs.statSync(filePath);
|
|
194
|
+
return stat.size > maxFileSize;
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Formats a file size in bytes to a human-readable string
|
|
202
|
+
*
|
|
203
|
+
* @param bytes - The file size in bytes
|
|
204
|
+
* @returns Human-readable file size string
|
|
205
|
+
*/
|
|
206
|
+
export function formatFileSize(bytes) {
|
|
207
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
208
|
+
let size = bytes;
|
|
209
|
+
let unitIndex = 0;
|
|
210
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
211
|
+
size /= 1024;
|
|
212
|
+
unitIndex++;
|
|
213
|
+
}
|
|
214
|
+
return `${size.toFixed(unitIndex === 0 ? 0 : 2)} ${units[unitIndex]}`;
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,kBAAkB,GAAG,CAAC,eAAe,EAAE,cAAc,CAAU,CAAC;AACtE,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAC1C,MAAM,mBAAmB,GAAG,CAAC,aAAa,EAAE,YAAY,CAAU,CAAC;AACnE,MAAM,UAAU,GAAG,QAAQ,CAAC;AAC5B,MAAM,qBAAqB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,MAAM,sBAAsB,GAAG,KAAK,CAAC;AACrC,MAAM,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC1E,MAAM,wBAAwB,GAAG,EAAE,CAAC;AACpC,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AACtD,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AACtD,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEzC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC7C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC9C,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACjD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACxC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACjD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC;AA4DH,MAAM,cAAc,GAAgB;IAClC,WAAW,EAAE,qBAAqB;IAClC,YAAY,EAAE,sBAAsB;IACpC,eAAe,EAAE,wBAAwB;IACzC,WAAW,EAAE,oBAAoB;IACjC,UAAU,EAAE,mBAAmB;IAC/B,eAAe,EAAE,wBAAwB;IACzC,WAAW,EAAE,oBAAoB;IACjC,QAAQ,EAAE,iBAAiB;CAC5B,CAAC;AAEF,MAAM,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;AAEnD;;;;;GAKG;AACH,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7C,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CACV,wCAAwC,QAAQ,KAAK,OAAO,EAAE,CAC/D,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAAC,UAAoB;IACtC,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;IAC7D,OAAO,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAW;IACtC,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa;IACpB,MAAM,MAAM,GAAyB,EAAE,CAAC;IAExC,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,eAAe,CAAC,CAAC;IACjE,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,gBAAgB,CAAC,CAAC;IACnE,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,kBAAkB,CAAC,CAAC;IACxE,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,cAAc,CAAC,CAAC;IAChE,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,WAAW,GAAG,cAAc,CAAC;IACtC,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,aAAa,CAAC,CAAC;IAC9D,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,CAAC,UAAU,GAAG,aAAa,CAAC;IACpC,CAAC;IAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,kBAAkB,CAAC,CAAC;IACxE,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,cAAc,CAAC,CAAC;IAChE,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,WAAW,GAAG,cAAc,CAAC;IACtC,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,WAAW,CAAC,CAAC;IAC1D,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,QAAQ,GAAG,WAAW,CAAC;IAChC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CACxB,GAAW,EACX,aAA+B,EAAE;IAEjC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,GAAG,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAEhE,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,OAAO,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAgB,CAAC;IAClD,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,UAAU,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;IAElC,MAAM,MAAM,GAAgB;QAC1B,GAAG,cAAc;QACjB,GAAG,YAAY;QACf,GAAG,WAAW;QACd,GAAG,SAAS;QACZ,GAAG,yBAAyB,CAAC,UAAU,CAAC;KACzC,CAAC;IAEF,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,yBAAyB,CAChC,OAAyB;IAEzB,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAC3C,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC7C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAgB,EAChB,WAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,OAAO,IAAI,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,IAAI,CAAC;QACb,SAAS,EAAE,CAAC;IACd,CAAC;IAED,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { loadConfig } from "./config.js";
|
|
2
|
+
import { NodeFileSystem, } from "./file.js";
|
|
3
|
+
import { NodeGit } from "./git.js";
|
|
4
|
+
import { createModelStudioConfig, ModelStudioClient } from "./model-studio.js";
|
|
5
|
+
import { LanceStore, TestStore } from "./store.js";
|
|
6
|
+
import { isTest } from "./utils.js";
|
|
7
|
+
/**
|
|
8
|
+
* Creates a configured Store instance.
|
|
9
|
+
*/
|
|
10
|
+
export async function createStore() {
|
|
11
|
+
if (isTest) {
|
|
12
|
+
return new TestStore();
|
|
13
|
+
}
|
|
14
|
+
const config = loadConfig(process.cwd());
|
|
15
|
+
const client = new ModelStudioClient(createModelStudioConfig({
|
|
16
|
+
embedModel: config.embedModel,
|
|
17
|
+
embedDimensions: config.embedDimensions,
|
|
18
|
+
rerankModel: config.rerankModel,
|
|
19
|
+
llmModel: config.llmModel,
|
|
20
|
+
}));
|
|
21
|
+
return new LanceStore(config, client);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a Git instance
|
|
25
|
+
*/
|
|
26
|
+
export function createGit() {
|
|
27
|
+
return new NodeGit();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates a FileSystem instance
|
|
31
|
+
*/
|
|
32
|
+
export function createFileSystem(options = { ignorePatterns: [] }) {
|
|
33
|
+
return new NodeFileSystem(createGit(), options);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/lib/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAGL,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAY,OAAO,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAc,SAAS,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,IAAI,SAAS,EAAE,CAAC;IACzB,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAClC,uBAAuB,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC,CACH,CAAC;IAEF,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,IAAI,OAAO,EAAE,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAA6B,EAAE,cAAc,EAAE,EAAE,EAAE;IAEnD,OAAO,IAAI,cAAc,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC"}
|
package/dist/lib/file.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import ignore from "ignore";
|
|
4
|
+
/**
|
|
5
|
+
* Default glob patterns to ignore during file indexing.
|
|
6
|
+
* These are not useful for the local text-first LanceDB index.
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_IGNORE_PATTERNS = [
|
|
9
|
+
"*.lock",
|
|
10
|
+
"*.bin",
|
|
11
|
+
"*.ipynb",
|
|
12
|
+
"*.pyc",
|
|
13
|
+
"*.safetensors",
|
|
14
|
+
"*.sqlite",
|
|
15
|
+
"*.pt",
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Node.js implementation of FileSystem with gitignore support
|
|
19
|
+
*/
|
|
20
|
+
export class NodeFileSystem {
|
|
21
|
+
git;
|
|
22
|
+
customIgnoreFilter;
|
|
23
|
+
ignoreCache = new Map();
|
|
24
|
+
constructor(git, options) {
|
|
25
|
+
this.git = git;
|
|
26
|
+
this.customIgnoreFilter = ignore();
|
|
27
|
+
this.customIgnoreFilter.add(options.ignorePatterns);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Checks if a file is a hidden file (starts with .)
|
|
31
|
+
*/
|
|
32
|
+
isHiddenFile(filePath, root) {
|
|
33
|
+
const relativePath = path.relative(root, filePath);
|
|
34
|
+
const parts = relativePath.split(path.sep);
|
|
35
|
+
return parts.some((part) => part.startsWith(".") && part !== "." && part !== "..");
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets all files recursively from a directory
|
|
39
|
+
*/
|
|
40
|
+
*getAllFilesRecursive(dir, root) {
|
|
41
|
+
try {
|
|
42
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
const fullPath = path.join(dir, entry.name);
|
|
45
|
+
if (this.isHiddenFile(fullPath, root)) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (this.isIgnored(fullPath, root)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (entry.isDirectory()) {
|
|
52
|
+
yield* this.getAllFilesRecursive(fullPath, root);
|
|
53
|
+
}
|
|
54
|
+
else if (entry.isFile()) {
|
|
55
|
+
yield fullPath;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
// Log permission or other filesystem errors
|
|
61
|
+
console.error(`Warning: Failed to read directory ${dir}:`, error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
*getFiles(dirRoot) {
|
|
65
|
+
// Preload root .mgrepignore to ensure it's cached
|
|
66
|
+
this.getDirectoryIgnoreFilter(dirRoot);
|
|
67
|
+
if (this.git.isGitRepository(dirRoot)) {
|
|
68
|
+
yield* this.git.getGitFiles(dirRoot);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
yield* this.getAllFilesRecursive(dirRoot, dirRoot);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
getDirectoryIgnoreFilter(dir) {
|
|
75
|
+
if (this.ignoreCache.has(dir)) {
|
|
76
|
+
return this.ignoreCache.get(dir) ?? ignore();
|
|
77
|
+
}
|
|
78
|
+
const ig = ignore();
|
|
79
|
+
// Load .gitignore
|
|
80
|
+
const gitignorePath = path.join(dir, ".gitignore");
|
|
81
|
+
if (fs.existsSync(gitignorePath)) {
|
|
82
|
+
ig.add(fs.readFileSync(gitignorePath, "utf8"));
|
|
83
|
+
}
|
|
84
|
+
// Load .mgrepignore
|
|
85
|
+
const mgrepignorePath = path.join(dir, ".mgrepignore");
|
|
86
|
+
if (fs.existsSync(mgrepignorePath)) {
|
|
87
|
+
ig.add(fs.readFileSync(mgrepignorePath, "utf8"));
|
|
88
|
+
}
|
|
89
|
+
this.ignoreCache.set(dir, ig);
|
|
90
|
+
return ig;
|
|
91
|
+
}
|
|
92
|
+
isIgnored(filePath, root) {
|
|
93
|
+
// Always ignore hidden files
|
|
94
|
+
if (this.isHiddenFile(filePath, root)) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
// Check custom ignore patterns (global/CLI)
|
|
98
|
+
const relativeToRoot = path.relative(root, filePath);
|
|
99
|
+
const normalizedRootPath = relativeToRoot.replace(/\\/g, "/");
|
|
100
|
+
// Check if it's a directory
|
|
101
|
+
let isDirectory = false;
|
|
102
|
+
try {
|
|
103
|
+
const stat = fs.statSync(filePath);
|
|
104
|
+
isDirectory = stat.isDirectory();
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
isDirectory = false;
|
|
108
|
+
}
|
|
109
|
+
const pathToCheckRoot = isDirectory
|
|
110
|
+
? `${normalizedRootPath}/`
|
|
111
|
+
: normalizedRootPath;
|
|
112
|
+
if (this.customIgnoreFilter.ignores(pathToCheckRoot)) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
// Hierarchical check
|
|
116
|
+
let currentDir = isDirectory ? filePath : path.dirname(filePath);
|
|
117
|
+
const absoluteRoot = path.resolve(root);
|
|
118
|
+
// Walk up from file directory to root
|
|
119
|
+
while (true) {
|
|
120
|
+
const relativeToCurrent = path.relative(currentDir, filePath);
|
|
121
|
+
if (relativeToCurrent !== "") {
|
|
122
|
+
// If we are checking the directory itself against its own ignore file? No, files inside.
|
|
123
|
+
// But if we are checking a file `a/b.txt`, and we are at `a`, relative is `b.txt`.
|
|
124
|
+
// If we are at `root`, relative is `a/b.txt`.
|
|
125
|
+
const normalizedRelative = relativeToCurrent.replace(/\\/g, "/");
|
|
126
|
+
const pathToCheck = isDirectory
|
|
127
|
+
? `${normalizedRelative}/`
|
|
128
|
+
: normalizedRelative;
|
|
129
|
+
const filter = this.getDirectoryIgnoreFilter(currentDir);
|
|
130
|
+
// Use internal test() method if available to distinguish ignored vs unignored
|
|
131
|
+
const result = filter.test(pathToCheck);
|
|
132
|
+
if (result.ignored) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
if (result.unignored) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (path.resolve(currentDir) === absoluteRoot) {
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
const parent = path.dirname(currentDir);
|
|
143
|
+
if (parent === currentDir)
|
|
144
|
+
break; // Safety break for root of fs
|
|
145
|
+
currentDir = parent;
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
loadMgrepignore(dirRoot) {
|
|
150
|
+
// Now handled by getDirectoryIgnoreFilter and caching
|
|
151
|
+
this.getDirectoryIgnoreFilter(dirRoot);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/lib/file.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/git.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import ignore from "ignore";
|
|
5
|
+
/**
|
|
6
|
+
* GitIgnore filter using the ignore package with enhanced pattern support
|
|
7
|
+
*/
|
|
8
|
+
export class GitIgnoreFilter {
|
|
9
|
+
ignoreInstance;
|
|
10
|
+
constructor(gitignoreContent) {
|
|
11
|
+
this.ignoreInstance = ignore();
|
|
12
|
+
if (gitignoreContent) {
|
|
13
|
+
this.add(gitignoreContent);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Normalizes a path for gitignore pattern matching
|
|
18
|
+
*/
|
|
19
|
+
normalizePathForIgnore(filePath, root) {
|
|
20
|
+
const relativePath = path.relative(root, filePath);
|
|
21
|
+
// Normalize path separators for cross-platform compatibility
|
|
22
|
+
return relativePath.replace(/\\/g, "/");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Checks if a file path should be ignored based on gitignore patterns
|
|
26
|
+
* Handles both files and directories properly
|
|
27
|
+
*/
|
|
28
|
+
isIgnored(filePath, root) {
|
|
29
|
+
const normalizedPath = this.normalizePathForIgnore(filePath, root);
|
|
30
|
+
if (!normalizedPath)
|
|
31
|
+
return false; // Root directory itself
|
|
32
|
+
// Check if it's a directory by attempting to stat the path
|
|
33
|
+
let isDirectory = false;
|
|
34
|
+
try {
|
|
35
|
+
const stat = fs.statSync(filePath);
|
|
36
|
+
isDirectory = stat.isDirectory();
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// If we can't stat the file, assume it's not a directory
|
|
40
|
+
isDirectory = false;
|
|
41
|
+
}
|
|
42
|
+
// The ignore package expects directories to end with "/"
|
|
43
|
+
const pathToCheck = isDirectory ? `${normalizedPath}/` : normalizedPath;
|
|
44
|
+
return this.ignoreInstance.ignores(pathToCheck);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Adds gitignore patterns from a string
|
|
48
|
+
* The ignore package automatically handles comments and empty lines
|
|
49
|
+
*/
|
|
50
|
+
add(patterns) {
|
|
51
|
+
this.ignoreInstance.add(patterns);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Clears all patterns
|
|
55
|
+
*/
|
|
56
|
+
clear() {
|
|
57
|
+
this.ignoreInstance = ignore();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Node.js implementation of the Git interface using git CLI commands
|
|
62
|
+
*/
|
|
63
|
+
export class NodeGit {
|
|
64
|
+
gitRepoCache = new Map();
|
|
65
|
+
gitIgnoreCache = new Map();
|
|
66
|
+
isGitRepository(dir) {
|
|
67
|
+
const normalizedDir = path.resolve(dir);
|
|
68
|
+
const cached = this.gitRepoCache.get(normalizedDir);
|
|
69
|
+
if (cached !== undefined) {
|
|
70
|
+
return cached;
|
|
71
|
+
}
|
|
72
|
+
let isGit = false;
|
|
73
|
+
try {
|
|
74
|
+
const result = spawnSync("git", ["rev-parse", "--git-dir"], {
|
|
75
|
+
cwd: dir,
|
|
76
|
+
encoding: "utf-8",
|
|
77
|
+
});
|
|
78
|
+
isGit = result.status === 0 && !result.error;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
isGit = false;
|
|
82
|
+
}
|
|
83
|
+
this.gitRepoCache.set(normalizedDir, isGit);
|
|
84
|
+
return isGit;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Gets gitignore content from a git repository
|
|
88
|
+
*/
|
|
89
|
+
getGitIgnoreContent(repoRoot) {
|
|
90
|
+
try {
|
|
91
|
+
const gitignorePath = path.join(repoRoot, ".gitignore");
|
|
92
|
+
if (fs.existsSync(gitignorePath)) {
|
|
93
|
+
return fs.readFileSync(gitignorePath, "utf-8");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
// Log error but don't fail - .gitignore is optional
|
|
98
|
+
console.error(`Warning: Failed to read .gitignore in ${repoRoot}:`, error);
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Gets files using git ls-files when in a git repository
|
|
104
|
+
*/
|
|
105
|
+
*getGitFiles(dirRoot) {
|
|
106
|
+
try {
|
|
107
|
+
const run = (args) => {
|
|
108
|
+
const res = spawnSync("git", args, {
|
|
109
|
+
cwd: dirRoot,
|
|
110
|
+
encoding: "utf-8",
|
|
111
|
+
maxBuffer: 1024 * 1024 * 1024, // 1GB buffer for large repos
|
|
112
|
+
});
|
|
113
|
+
if (res.error || res.status !== 0) {
|
|
114
|
+
console.error(`Warning: git command failed: git ${args.join(" ")}`);
|
|
115
|
+
return "";
|
|
116
|
+
}
|
|
117
|
+
return res.stdout;
|
|
118
|
+
};
|
|
119
|
+
const tracked = run(["ls-files", "-z"]).split("\u0000").filter(Boolean);
|
|
120
|
+
const untracked = run([
|
|
121
|
+
"ls-files",
|
|
122
|
+
"--others",
|
|
123
|
+
"--exclude-standard",
|
|
124
|
+
"-z",
|
|
125
|
+
])
|
|
126
|
+
.split("\u0000")
|
|
127
|
+
.filter(Boolean);
|
|
128
|
+
const allRel = Array.from(new Set([...tracked, ...untracked]));
|
|
129
|
+
for (const rel of allRel) {
|
|
130
|
+
yield path.join(dirRoot, rel);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
console.error(`Warning: Failed to get files from git in ${dirRoot}:`, error);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Gets or creates a cached GitIgnoreFilter for a repository
|
|
139
|
+
* Includes cache invalidation based on .gitignore modification time
|
|
140
|
+
*/
|
|
141
|
+
getGitIgnoreFilter(repoRoot) {
|
|
142
|
+
const normalizedRoot = path.resolve(repoRoot);
|
|
143
|
+
const gitignorePath = path.join(repoRoot, ".gitignore");
|
|
144
|
+
// Get current mtime of .gitignore file
|
|
145
|
+
let currentMtime = 0;
|
|
146
|
+
try {
|
|
147
|
+
const stat = fs.statSync(gitignorePath);
|
|
148
|
+
currentMtime = stat.mtime.getTime();
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// If .gitignore doesn't exist, use 0 as mtime
|
|
152
|
+
}
|
|
153
|
+
const cached = this.gitIgnoreCache.get(normalizedRoot);
|
|
154
|
+
if (!cached || cached.mtime !== currentMtime) {
|
|
155
|
+
// Cache miss or stale cache
|
|
156
|
+
const filter = new GitIgnoreFilter();
|
|
157
|
+
const gitignoreContent = this.getGitIgnoreContent(repoRoot);
|
|
158
|
+
if (gitignoreContent) {
|
|
159
|
+
filter.add(gitignoreContent);
|
|
160
|
+
}
|
|
161
|
+
this.gitIgnoreCache.set(normalizedRoot, { filter, mtime: currentMtime });
|
|
162
|
+
return filter;
|
|
163
|
+
}
|
|
164
|
+
return cached.filter;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
|