@colbymchenry/codegraph-darwin-x64 0.9.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/dist/bin/codegraph.d.ts +1 -0
- package/lib/dist/bin/codegraph.d.ts.map +1 -1
- package/lib/dist/bin/codegraph.js +247 -39
- package/lib/dist/bin/codegraph.js.map +1 -1
- package/lib/dist/context/index.d.ts +9 -0
- package/lib/dist/context/index.d.ts.map +1 -1
- package/lib/dist/context/index.js +102 -6
- package/lib/dist/context/index.js.map +1 -1
- package/lib/dist/context/markers.d.ts +19 -0
- package/lib/dist/context/markers.d.ts.map +1 -0
- package/lib/dist/context/markers.js +22 -0
- package/lib/dist/context/markers.js.map +1 -0
- package/lib/dist/db/index.d.ts.map +1 -1
- package/lib/dist/db/index.js +2 -1
- package/lib/dist/db/index.js.map +1 -1
- package/lib/dist/db/migrations.d.ts +1 -1
- package/lib/dist/db/migrations.d.ts.map +1 -1
- package/lib/dist/db/migrations.js +10 -1
- package/lib/dist/db/migrations.js.map +1 -1
- package/lib/dist/db/queries.d.ts +43 -0
- package/lib/dist/db/queries.d.ts.map +1 -1
- package/lib/dist/db/queries.js +103 -7
- package/lib/dist/db/queries.js.map +1 -1
- package/lib/dist/db/schema.sql +1 -0
- package/lib/dist/db/sqlite-adapter.d.ts +7 -0
- package/lib/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/lib/dist/db/sqlite-adapter.js +3 -0
- package/lib/dist/db/sqlite-adapter.js.map +1 -1
- package/lib/dist/directory.d.ts +34 -2
- package/lib/dist/directory.d.ts.map +1 -1
- package/lib/dist/directory.js +129 -35
- package/lib/dist/directory.js.map +1 -1
- package/lib/dist/extraction/astro-extractor.d.ts +79 -0
- package/lib/dist/extraction/astro-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/astro-extractor.js +320 -0
- package/lib/dist/extraction/astro-extractor.js.map +1 -0
- package/lib/dist/extraction/extraction-version.d.ts +25 -0
- package/lib/dist/extraction/extraction-version.d.ts.map +1 -0
- package/lib/dist/extraction/extraction-version.js +28 -0
- package/lib/dist/extraction/extraction-version.js.map +1 -0
- package/lib/dist/extraction/function-ref.d.ts +118 -0
- package/lib/dist/extraction/function-ref.d.ts.map +1 -0
- package/lib/dist/extraction/function-ref.js +727 -0
- package/lib/dist/extraction/function-ref.js.map +1 -0
- package/lib/dist/extraction/generated-detection.d.ts.map +1 -1
- package/lib/dist/extraction/generated-detection.js +3 -0
- package/lib/dist/extraction/generated-detection.js.map +1 -1
- package/lib/dist/extraction/grammars.d.ts +7 -1
- package/lib/dist/extraction/grammars.d.ts.map +1 -1
- package/lib/dist/extraction/grammars.js +52 -4
- package/lib/dist/extraction/grammars.js.map +1 -1
- package/lib/dist/extraction/index.d.ts +34 -0
- package/lib/dist/extraction/index.d.ts.map +1 -1
- package/lib/dist/extraction/index.js +346 -62
- package/lib/dist/extraction/index.js.map +1 -1
- package/lib/dist/extraction/languages/c-cpp.d.ts +8 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/lib/dist/extraction/languages/c-cpp.js +87 -28
- package/lib/dist/extraction/languages/c-cpp.js.map +1 -1
- package/lib/dist/extraction/languages/csharp.d.ts +22 -0
- package/lib/dist/extraction/languages/csharp.d.ts.map +1 -1
- package/lib/dist/extraction/languages/csharp.js +84 -2
- package/lib/dist/extraction/languages/csharp.js.map +1 -1
- package/lib/dist/extraction/languages/dart.d.ts.map +1 -1
- package/lib/dist/extraction/languages/dart.js +161 -1
- package/lib/dist/extraction/languages/dart.js.map +1 -1
- package/lib/dist/extraction/languages/go.d.ts.map +1 -1
- package/lib/dist/extraction/languages/go.js +43 -2
- package/lib/dist/extraction/languages/go.js.map +1 -1
- package/lib/dist/extraction/languages/index.d.ts.map +1 -1
- package/lib/dist/extraction/languages/index.js +2 -0
- package/lib/dist/extraction/languages/index.js.map +1 -1
- package/lib/dist/extraction/languages/java.d.ts.map +1 -1
- package/lib/dist/extraction/languages/java.js +42 -1
- package/lib/dist/extraction/languages/java.js.map +1 -1
- package/lib/dist/extraction/languages/javascript.d.ts.map +1 -1
- package/lib/dist/extraction/languages/javascript.js +16 -0
- package/lib/dist/extraction/languages/javascript.js.map +1 -1
- package/lib/dist/extraction/languages/kotlin.d.ts.map +1 -1
- package/lib/dist/extraction/languages/kotlin.js +69 -0
- package/lib/dist/extraction/languages/kotlin.js.map +1 -1
- package/lib/dist/extraction/languages/objc.d.ts.map +1 -1
- package/lib/dist/extraction/languages/objc.js +42 -0
- package/lib/dist/extraction/languages/objc.js.map +1 -1
- package/lib/dist/extraction/languages/pascal.d.ts.map +1 -1
- package/lib/dist/extraction/languages/pascal.js +11 -0
- package/lib/dist/extraction/languages/pascal.js.map +1 -1
- package/lib/dist/extraction/languages/php.d.ts.map +1 -1
- package/lib/dist/extraction/languages/php.js +90 -1
- package/lib/dist/extraction/languages/php.js.map +1 -1
- package/lib/dist/extraction/languages/r.d.ts +3 -0
- package/lib/dist/extraction/languages/r.d.ts.map +1 -0
- package/lib/dist/extraction/languages/r.js +314 -0
- package/lib/dist/extraction/languages/r.js.map +1 -0
- package/lib/dist/extraction/languages/ruby.d.ts.map +1 -1
- package/lib/dist/extraction/languages/ruby.js +35 -0
- package/lib/dist/extraction/languages/ruby.js.map +1 -1
- package/lib/dist/extraction/languages/rust.d.ts.map +1 -1
- package/lib/dist/extraction/languages/rust.js +35 -2
- package/lib/dist/extraction/languages/rust.js.map +1 -1
- package/lib/dist/extraction/languages/scala.d.ts.map +1 -1
- package/lib/dist/extraction/languages/scala.js +61 -1
- package/lib/dist/extraction/languages/scala.js.map +1 -1
- package/lib/dist/extraction/languages/swift.d.ts.map +1 -1
- package/lib/dist/extraction/languages/swift.js +61 -0
- package/lib/dist/extraction/languages/swift.js.map +1 -1
- package/lib/dist/extraction/languages/typescript.d.ts +13 -0
- package/lib/dist/extraction/languages/typescript.d.ts.map +1 -1
- package/lib/dist/extraction/languages/typescript.js +38 -0
- package/lib/dist/extraction/languages/typescript.js.map +1 -1
- package/lib/dist/extraction/liquid-extractor.d.ts +7 -0
- package/lib/dist/extraction/liquid-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/liquid-extractor.js +53 -9
- package/lib/dist/extraction/liquid-extractor.js.map +1 -1
- package/lib/dist/extraction/razor-extractor.d.ts +42 -0
- package/lib/dist/extraction/razor-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/razor-extractor.js +285 -0
- package/lib/dist/extraction/razor-extractor.js.map +1 -0
- package/lib/dist/extraction/svelte-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/svelte-extractor.js +6 -3
- package/lib/dist/extraction/svelte-extractor.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter-helpers.js +59 -10
- package/lib/dist/extraction/tree-sitter-helpers.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-types.d.ts +33 -0
- package/lib/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.d.ts +237 -0
- package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.js +1820 -68
- package/lib/dist/extraction/tree-sitter.js.map +1 -1
- package/lib/dist/extraction/vue-extractor.d.ts +15 -0
- package/lib/dist/extraction/vue-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/vue-extractor.js +94 -3
- package/lib/dist/extraction/vue-extractor.js.map +1 -1
- package/lib/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
- package/lib/dist/graph/queries.d.ts.map +1 -1
- package/lib/dist/graph/queries.js +13 -40
- package/lib/dist/graph/queries.js.map +1 -1
- package/lib/dist/graph/traversal.d.ts.map +1 -1
- package/lib/dist/graph/traversal.js +16 -4
- package/lib/dist/graph/traversal.js.map +1 -1
- package/lib/dist/index.d.ts +41 -3
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +99 -9
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +52 -2
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/installer/instructions-template.d.ts +34 -11
- package/lib/dist/installer/instructions-template.d.ts.map +1 -1
- package/lib/dist/installer/instructions-template.js +44 -12
- package/lib/dist/installer/instructions-template.js.map +1 -1
- package/lib/dist/installer/targets/claude.d.ts.map +1 -1
- package/lib/dist/installer/targets/claude.js +6 -10
- package/lib/dist/installer/targets/claude.js.map +1 -1
- package/lib/dist/installer/targets/codex.js +4 -6
- package/lib/dist/installer/targets/codex.js.map +1 -1
- package/lib/dist/installer/targets/gemini.js +4 -6
- package/lib/dist/installer/targets/gemini.js.map +1 -1
- package/lib/dist/installer/targets/opencode.d.ts +9 -1
- package/lib/dist/installer/targets/opencode.d.ts.map +1 -1
- package/lib/dist/installer/targets/opencode.js +91 -40
- package/lib/dist/installer/targets/opencode.js.map +1 -1
- package/lib/dist/installer/targets/shared.d.ts +14 -0
- package/lib/dist/installer/targets/shared.d.ts.map +1 -1
- package/lib/dist/installer/targets/shared.js +19 -2
- package/lib/dist/installer/targets/shared.js.map +1 -1
- package/lib/dist/mcp/daemon.d.ts +60 -1
- package/lib/dist/mcp/daemon.d.ts.map +1 -1
- package/lib/dist/mcp/daemon.js +221 -8
- package/lib/dist/mcp/daemon.js.map +1 -1
- package/lib/dist/mcp/dynamic-boundaries.d.ts +41 -0
- package/lib/dist/mcp/dynamic-boundaries.d.ts.map +1 -0
- package/lib/dist/mcp/dynamic-boundaries.js +359 -0
- package/lib/dist/mcp/dynamic-boundaries.js.map +1 -0
- package/lib/dist/mcp/index.d.ts.map +1 -1
- package/lib/dist/mcp/index.js +18 -9
- package/lib/dist/mcp/index.js.map +1 -1
- package/lib/dist/mcp/ppid-watchdog.d.ts +44 -0
- package/lib/dist/mcp/ppid-watchdog.d.ts.map +1 -0
- package/lib/dist/mcp/ppid-watchdog.js +27 -0
- package/lib/dist/mcp/ppid-watchdog.js.map +1 -0
- package/lib/dist/mcp/proxy.d.ts +6 -0
- package/lib/dist/mcp/proxy.d.ts.map +1 -1
- package/lib/dist/mcp/proxy.js +153 -24
- package/lib/dist/mcp/proxy.js.map +1 -1
- package/lib/dist/mcp/server-instructions.d.ts +12 -1
- package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
- package/lib/dist/mcp/server-instructions.js +58 -32
- package/lib/dist/mcp/server-instructions.js.map +1 -1
- package/lib/dist/mcp/session.d.ts +2 -0
- package/lib/dist/mcp/session.d.ts.map +1 -1
- package/lib/dist/mcp/session.js +49 -2
- package/lib/dist/mcp/session.js.map +1 -1
- package/lib/dist/mcp/stdin-teardown.d.ts +27 -0
- package/lib/dist/mcp/stdin-teardown.d.ts.map +1 -0
- package/lib/dist/mcp/stdin-teardown.js +49 -0
- package/lib/dist/mcp/stdin-teardown.js.map +1 -0
- package/lib/dist/mcp/tools.d.ts +110 -49
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +1222 -972
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/mcp/transport.d.ts.map +1 -1
- package/lib/dist/mcp/transport.js +18 -2
- package/lib/dist/mcp/transport.js.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.d.ts +3 -3
- package/lib/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.js +549 -21
- package/lib/dist/resolution/callback-synthesizer.js.map +1 -1
- package/lib/dist/resolution/frameworks/astro.d.ts +9 -0
- package/lib/dist/resolution/frameworks/astro.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/astro.js +169 -0
- package/lib/dist/resolution/frameworks/astro.js.map +1 -0
- package/lib/dist/resolution/frameworks/expo-modules.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/expo-modules.js +6 -1
- package/lib/dist/resolution/frameworks/expo-modules.js.map +1 -1
- package/lib/dist/resolution/frameworks/index.d.ts +1 -0
- package/lib/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/index.js +5 -1
- package/lib/dist/resolution/frameworks/index.js.map +1 -1
- package/lib/dist/resolution/frameworks/java.js +6 -1
- package/lib/dist/resolution/frameworks/java.js.map +1 -1
- package/lib/dist/resolution/frameworks/python.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/python.js +7 -3
- package/lib/dist/resolution/frameworks/python.js.map +1 -1
- package/lib/dist/resolution/frameworks/react-native.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/react-native.js +53 -3
- package/lib/dist/resolution/frameworks/react-native.js.map +1 -1
- package/lib/dist/resolution/frameworks/react.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/react.js +15 -3
- package/lib/dist/resolution/frameworks/react.js.map +1 -1
- package/lib/dist/resolution/frameworks/svelte.js +5 -1
- package/lib/dist/resolution/frameworks/svelte.js.map +1 -1
- package/lib/dist/resolution/frameworks/vue.js +24 -27
- package/lib/dist/resolution/frameworks/vue.js.map +1 -1
- package/lib/dist/resolution/import-resolver.d.ts +10 -0
- package/lib/dist/resolution/import-resolver.d.ts.map +1 -1
- package/lib/dist/resolution/import-resolver.js +564 -2
- package/lib/dist/resolution/import-resolver.js.map +1 -1
- package/lib/dist/resolution/index.d.ts +80 -0
- package/lib/dist/resolution/index.d.ts.map +1 -1
- package/lib/dist/resolution/index.js +457 -7
- package/lib/dist/resolution/index.js.map +1 -1
- package/lib/dist/resolution/name-matcher.d.ts +61 -0
- package/lib/dist/resolution/name-matcher.d.ts.map +1 -1
- package/lib/dist/resolution/name-matcher.js +590 -14
- package/lib/dist/resolution/name-matcher.js.map +1 -1
- package/lib/dist/resolution/types.d.ts +27 -3
- package/lib/dist/resolution/types.d.ts.map +1 -1
- package/lib/dist/resolution/workspace-packages.d.ts +48 -0
- package/lib/dist/resolution/workspace-packages.d.ts.map +1 -0
- package/lib/dist/resolution/workspace-packages.js +208 -0
- package/lib/dist/resolution/workspace-packages.js.map +1 -0
- package/lib/dist/search/query-utils.d.ts +35 -1
- package/lib/dist/search/query-utils.d.ts.map +1 -1
- package/lib/dist/search/query-utils.js +109 -10
- package/lib/dist/search/query-utils.js.map +1 -1
- package/lib/dist/sync/watcher.d.ts +124 -32
- package/lib/dist/sync/watcher.d.ts.map +1 -1
- package/lib/dist/sync/watcher.js +326 -111
- package/lib/dist/sync/watcher.js.map +1 -1
- package/lib/dist/telemetry/index.d.ts +146 -0
- package/lib/dist/telemetry/index.d.ts.map +1 -0
- package/lib/dist/telemetry/index.js +544 -0
- package/lib/dist/telemetry/index.js.map +1 -0
- package/lib/dist/types.d.ts +25 -2
- package/lib/dist/types.d.ts.map +1 -1
- package/lib/dist/types.js +3 -0
- package/lib/dist/types.js.map +1 -1
- package/lib/dist/upgrade/index.d.ts +132 -0
- package/lib/dist/upgrade/index.d.ts.map +1 -0
- package/lib/dist/upgrade/index.js +462 -0
- package/lib/dist/upgrade/index.js.map +1 -0
- package/lib/dist/utils.d.ts +30 -24
- package/lib/dist/utils.d.ts.map +1 -1
- package/lib/dist/utils.js +64 -48
- package/lib/dist/utils.js.map +1 -1
- package/lib/node_modules/.package-lock.json +1 -29
- package/lib/package.json +1 -2
- package/package.json +1 -1
- package/lib/node_modules/chokidar/LICENSE +0 -21
- package/lib/node_modules/chokidar/README.md +0 -305
- package/lib/node_modules/chokidar/esm/handler.d.ts +0 -90
- package/lib/node_modules/chokidar/esm/handler.js +0 -629
- package/lib/node_modules/chokidar/esm/index.d.ts +0 -215
- package/lib/node_modules/chokidar/esm/index.js +0 -798
- package/lib/node_modules/chokidar/esm/package.json +0 -1
- package/lib/node_modules/chokidar/handler.d.ts +0 -90
- package/lib/node_modules/chokidar/handler.js +0 -635
- package/lib/node_modules/chokidar/index.d.ts +0 -215
- package/lib/node_modules/chokidar/index.js +0 -804
- package/lib/node_modules/chokidar/package.json +0 -69
- package/lib/node_modules/readdirp/LICENSE +0 -21
- package/lib/node_modules/readdirp/README.md +0 -120
- package/lib/node_modules/readdirp/esm/index.d.ts +0 -108
- package/lib/node_modules/readdirp/esm/index.js +0 -257
- package/lib/node_modules/readdirp/esm/package.json +0 -1
- package/lib/node_modules/readdirp/index.d.ts +0 -108
- package/lib/node_modules/readdirp/index.js +0 -263
- package/lib/node_modules/readdirp/package.json +0 -70
|
@@ -41,9 +41,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
41
41
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
42
|
};
|
|
43
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
-
exports.loadAllGrammars = exports.loadGrammarsForLanguages = exports.initGrammars = exports.getSupportedLanguages = exports.isGrammarLoaded = exports.isLanguageSupported = exports.isSourceFile = exports.detectLanguage = exports.extractFromSource = exports.ExtractionOrchestrator = void 0;
|
|
44
|
+
exports.loadAllGrammars = exports.loadGrammarsForLanguages = exports.initGrammars = exports.getSupportedLanguages = exports.isGrammarLoaded = exports.isLanguageSupported = exports.isSourceFile = exports.detectLanguage = exports.extractFromSource = exports.ExtractionOrchestrator = exports.ScopeIgnore = void 0;
|
|
45
45
|
exports.hashContent = hashContent;
|
|
46
46
|
exports.buildDefaultIgnore = buildDefaultIgnore;
|
|
47
|
+
exports.buildScopeIgnore = buildScopeIgnore;
|
|
48
|
+
exports.discoverEmbeddedRepoRoots = discoverEmbeddedRepoRoots;
|
|
47
49
|
exports.scanDirectory = scanDirectory;
|
|
48
50
|
exports.scanDirectoryAsync = scanDirectoryAsync;
|
|
49
51
|
const fs = __importStar(require("fs"));
|
|
@@ -53,6 +55,7 @@ const crypto = __importStar(require("crypto"));
|
|
|
53
55
|
const child_process_1 = require("child_process");
|
|
54
56
|
const tree_sitter_1 = require("./tree-sitter");
|
|
55
57
|
const grammars_1 = require("./grammars");
|
|
58
|
+
const directory_1 = require("../directory");
|
|
56
59
|
const errors_1 = require("../errors");
|
|
57
60
|
const utils_1 = require("../utils");
|
|
58
61
|
const ignore_1 = __importDefault(require("ignore"));
|
|
@@ -147,6 +150,74 @@ const DEFAULT_IGNORE_PATTERNS = [
|
|
|
147
150
|
'cmake-build-*/', // CLion / CMake build trees
|
|
148
151
|
'bazel-*/', // Bazel output symlink trees
|
|
149
152
|
];
|
|
153
|
+
/** True if `buf` decodes as strict UTF-8 (no invalid byte sequences). */
|
|
154
|
+
function isValidUtf8(buf) {
|
|
155
|
+
try {
|
|
156
|
+
new TextDecoder('utf-8', { fatal: true }).decode(buf);
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Read a `.gitignore` and return patterns safe to hand to the `ignore` matcher —
|
|
165
|
+
* never throwing, even when the file isn't real gitignore text. Two failure
|
|
166
|
+
* modes, both seen in the wild (issue #682):
|
|
167
|
+
*
|
|
168
|
+
* - The file isn't valid UTF-8 — e.g. transparently encrypted in place by
|
|
169
|
+
* corporate DLP / endpoint-security software, leaving a UTF-16 header plus
|
|
170
|
+
* ciphertext. None of it is meaningful patterns, so the whole file is skipped.
|
|
171
|
+
* - The file is text but a single line can't be compiled to a regex by the
|
|
172
|
+
* `ignore` library — `\\[` and friends throw "Unterminated character class".
|
|
173
|
+
* Crucially the throw is LAZY (at match time, not `.add()`), so it would
|
|
174
|
+
* otherwise escape mid-scan. That one pattern is dropped; the rest are kept.
|
|
175
|
+
*
|
|
176
|
+
* Either way a warning that NAMES the file is logged (the reporter couldn't tell
|
|
177
|
+
* which `.gitignore` was at fault) and indexing continues instead of aborting.
|
|
178
|
+
* Returns '' when there's nothing usable.
|
|
179
|
+
*/
|
|
180
|
+
function readGitignorePatterns(giPath) {
|
|
181
|
+
let buf;
|
|
182
|
+
try {
|
|
183
|
+
buf = fs.readFileSync(giPath);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return ''; // unreadable (permissions / race) — treat as absent
|
|
187
|
+
}
|
|
188
|
+
// A NUL byte never appears in real gitignore text, and a fatal UTF-8 decode
|
|
189
|
+
// catches the rest. Such a file isn't ignore patterns at all.
|
|
190
|
+
if (buf.includes(0) || !isValidUtf8(buf)) {
|
|
191
|
+
(0, errors_1.logWarn)('Ignoring a .gitignore that is not valid UTF-8 text — it may have been encrypted ' +
|
|
192
|
+
'in place by endpoint-security software. Indexing continues without it.', { file: giPath });
|
|
193
|
+
return '';
|
|
194
|
+
}
|
|
195
|
+
const content = buf.toString('utf-8');
|
|
196
|
+
// Fast path: one `.ignores()` call forces the library to compile EVERY rule,
|
|
197
|
+
// so if it doesn't throw, the whole file is safe to use verbatim.
|
|
198
|
+
try {
|
|
199
|
+
(0, ignore_1.default)().add(content).ignores('.codegraph-probe');
|
|
200
|
+
return content;
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// Fall through: a line is uncompilable — keep the good ones, drop the bad.
|
|
204
|
+
}
|
|
205
|
+
const kept = [];
|
|
206
|
+
let dropped = 0;
|
|
207
|
+
for (const line of content.split(/\r?\n/)) {
|
|
208
|
+
try {
|
|
209
|
+
(0, ignore_1.default)().add(line).ignores('.codegraph-probe');
|
|
210
|
+
kept.push(line);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
dropped++;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (dropped > 0) {
|
|
217
|
+
(0, errors_1.logWarn)(`Skipped ${dropped} unparseable pattern(s) in a .gitignore; the rest are applied.`, { file: giPath });
|
|
218
|
+
}
|
|
219
|
+
return kept.join('\n');
|
|
220
|
+
}
|
|
150
221
|
/**
|
|
151
222
|
* An `ignore` matcher seeded with the built-in defaults, merged with the project's
|
|
152
223
|
* root .gitignore so a negation there (e.g. `!vendor/`) overrides a default. Shared
|
|
@@ -156,15 +227,184 @@ const DEFAULT_IGNORE_PATTERNS = [
|
|
|
156
227
|
*/
|
|
157
228
|
function buildDefaultIgnore(rootDir) {
|
|
158
229
|
const ig = (0, ignore_1.default)().add(DEFAULT_IGNORE_PATTERNS);
|
|
230
|
+
const rootGitignore = path.join(rootDir, '.gitignore');
|
|
231
|
+
if (fs.existsSync(rootGitignore))
|
|
232
|
+
ig.add(readGitignorePatterns(rootGitignore));
|
|
233
|
+
return ig;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Defaults-only ignore matcher (no root `.gitignore` merged). Used wherever the
|
|
237
|
+
* parent repo's own ignore rules must NOT apply — inside embedded child repos,
|
|
238
|
+
* whose gitignore semantics their own `git ls-files` already enforced (#514).
|
|
239
|
+
*/
|
|
240
|
+
function defaultsOnlyIgnore() {
|
|
241
|
+
return (0, ignore_1.default)().add(DEFAULT_IGNORE_PATTERNS);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* List the gitignored DIRECTORIES of a repo (collapsed, trailing-slash form),
|
|
245
|
+
* relative to `repoDir`. These are invisible to every other `git ls-files` /
|
|
246
|
+
* `git status` mode — and in a multi-repo workspace they are exactly where the
|
|
247
|
+
* nested project repos live (a super-repo `.gitignore`s its child repos to keep
|
|
248
|
+
* `git status` quiet; that does not make them third-party code). (#514)
|
|
249
|
+
*/
|
|
250
|
+
function listIgnoredDirs(repoDir) {
|
|
159
251
|
try {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
ig.add(fs.readFileSync(rootGitignore, 'utf-8'));
|
|
252
|
+
const out = (0, child_process_1.execFileSync)('git', ['ls-files', '-z', '-o', '-i', '--exclude-standard', '--directory'], { cwd: repoDir, encoding: 'utf-8', timeout: 30000, maxBuffer: 50 * 1024 * 1024, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true });
|
|
253
|
+
return out.split('\0').filter((e) => e.endsWith('/'));
|
|
163
254
|
}
|
|
164
255
|
catch {
|
|
165
|
-
|
|
256
|
+
return [];
|
|
166
257
|
}
|
|
167
|
-
|
|
258
|
+
}
|
|
259
|
+
/** Max directory depth searched below an ignored dir for nested `.git` roots. */
|
|
260
|
+
const EMBEDDED_REPO_SEARCH_DEPTH = 4;
|
|
261
|
+
/** Max directories examined per search — a huge ignored data dir must never stall a scan/sync. */
|
|
262
|
+
const EMBEDDED_REPO_SEARCH_ENTRIES = 2000;
|
|
263
|
+
/**
|
|
264
|
+
* Find git repositories nested under `absDir` (inclusive), shallow bounded BFS.
|
|
265
|
+
* Stops descending at each repo root found — contents belong to that repo's own
|
|
266
|
+
* enumeration. Skips default-ignored dirs (`node_modules` can contain `.git`
|
|
267
|
+
* from npm git-dependencies — that never makes it project code) and CodeGraph
|
|
268
|
+
* data dirs. Depth- and entry-capped so a huge ignored tree can't stall the scan.
|
|
269
|
+
*/
|
|
270
|
+
function findNestedGitRepos(absDir, relPrefix) {
|
|
271
|
+
const found = [];
|
|
272
|
+
const defaults = defaultsOnlyIgnore();
|
|
273
|
+
const queue = [
|
|
274
|
+
{ abs: absDir, rel: relPrefix, depth: 0 },
|
|
275
|
+
];
|
|
276
|
+
let examined = 0;
|
|
277
|
+
while (queue.length > 0) {
|
|
278
|
+
const { abs, rel, depth } = queue.shift();
|
|
279
|
+
if (++examined > EMBEDDED_REPO_SEARCH_ENTRIES) {
|
|
280
|
+
(0, errors_1.logDebug)('Embedded-repo search entry cap hit — deeper repos (if any) not discovered', { under: relPrefix });
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
if (fs.existsSync(path.join(abs, '.git'))) {
|
|
284
|
+
found.push(rel);
|
|
285
|
+
continue; // its own git handles everything below
|
|
286
|
+
}
|
|
287
|
+
if (depth >= EMBEDDED_REPO_SEARCH_DEPTH)
|
|
288
|
+
continue;
|
|
289
|
+
let entries;
|
|
290
|
+
try {
|
|
291
|
+
entries = fs.readdirSync(abs, { withFileTypes: true });
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
for (const entry of entries) {
|
|
297
|
+
if (!entry.isDirectory())
|
|
298
|
+
continue;
|
|
299
|
+
if (entry.name === '.git' || (0, directory_1.isCodeGraphDataDir)(entry.name))
|
|
300
|
+
continue;
|
|
301
|
+
const childRel = rel + entry.name + '/';
|
|
302
|
+
if (defaults.ignores(childRel))
|
|
303
|
+
continue;
|
|
304
|
+
queue.push({ abs: path.join(abs, entry.name), rel: childRel, depth: depth + 1 });
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return found;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Workspace-scope ignore matcher. Ordinary paths get the root's matcher
|
|
311
|
+
* (built-in defaults + root `.gitignore`); paths inside an EMBEDDED repo get
|
|
312
|
+
* that repo's own matcher (defaults + its root `.gitignore`) — the parent's
|
|
313
|
+
* `.gitignore` hides a child repo from git, not from the index (#514). A
|
|
314
|
+
* directory path (trailing slash) that is an ANCESTOR of an embedded root is
|
|
315
|
+
* never ignored, so directory-pruning callers (the Linux per-directory
|
|
316
|
+
* watcher) still descend to reach the embedded repos.
|
|
317
|
+
*
|
|
318
|
+
* Single source of truth for indexer and watcher scope — they must not diverge.
|
|
319
|
+
*/
|
|
320
|
+
class ScopeIgnore {
|
|
321
|
+
rootMatcher;
|
|
322
|
+
embedded;
|
|
323
|
+
defaults = defaultsOnlyIgnore();
|
|
324
|
+
constructor(rootMatcher, embedded) {
|
|
325
|
+
this.rootMatcher = rootMatcher;
|
|
326
|
+
// Longest root first so paths in nested embedded repos hit the innermost matcher.
|
|
327
|
+
this.embedded = [...embedded].sort((a, b) => b.root.length - a.root.length);
|
|
328
|
+
}
|
|
329
|
+
ignores(rel) {
|
|
330
|
+
for (const { root, matcher } of this.embedded) {
|
|
331
|
+
if (rel.startsWith(root)) {
|
|
332
|
+
const inner = rel.slice(root.length);
|
|
333
|
+
if (inner === '')
|
|
334
|
+
return false;
|
|
335
|
+
// Built-in defaults apply to the FULL path uniformly (#407) — an
|
|
336
|
+
// embedded repo inside node_modules (an npm git-dependency) must stay
|
|
337
|
+
// excluded even though its own rules wouldn't ignore its files.
|
|
338
|
+
return this.defaults.ignores(rel) || matcher.ignores(inner);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// Never prune a directory that leads to an embedded repo.
|
|
342
|
+
if (rel.endsWith('/') && this.embedded.some(({ root }) => root.startsWith(rel))) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
return this.rootMatcher.ignores(rel);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
exports.ScopeIgnore = ScopeIgnore;
|
|
349
|
+
/**
|
|
350
|
+
* Build the workspace-scope matcher. When the caller already knows the
|
|
351
|
+
* embedded roots (the scanner discovers them during collection), pass them to
|
|
352
|
+
* skip rediscovery; otherwise they're discovered here (the watcher path).
|
|
353
|
+
*/
|
|
354
|
+
function buildScopeIgnore(rootDir, embeddedRoots) {
|
|
355
|
+
const roots = embeddedRoots ? [...embeddedRoots] : discoverEmbeddedRepoRoots(rootDir);
|
|
356
|
+
return new ScopeIgnore(buildDefaultIgnore(rootDir), roots.map((root) => ({ root, matcher: buildDefaultIgnore(path.join(rootDir, root)) })));
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Standalone discovery of every embedded repo root under `rootDir` (relative,
|
|
360
|
+
* trailing-slashed) — both the untracked kind (#193) and the gitignored kind
|
|
361
|
+
* (#514), recursively (an embedded repo can embed further repos). Returns []
|
|
362
|
+
* for non-git roots: the filesystem walk handles nested repos there already.
|
|
363
|
+
*/
|
|
364
|
+
function discoverEmbeddedRepoRoots(rootDir) {
|
|
365
|
+
try {
|
|
366
|
+
(0, child_process_1.execFileSync)('git', ['rev-parse', '--git-dir'], { cwd: rootDir, encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true });
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
return [];
|
|
370
|
+
}
|
|
371
|
+
const out = [];
|
|
372
|
+
const defaults = defaultsOnlyIgnore();
|
|
373
|
+
const visit = (repoAbs, prefix) => {
|
|
374
|
+
const candidates = [];
|
|
375
|
+
try {
|
|
376
|
+
const o = (0, child_process_1.execFileSync)('git', ['ls-files', '-z', '-o', '--exclude-standard', '--directory'], { cwd: repoAbs, encoding: 'utf-8', timeout: 30000, maxBuffer: 50 * 1024 * 1024, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true });
|
|
377
|
+
for (const e of o.split('\0')) {
|
|
378
|
+
if (e.endsWith('/') && !defaults.ignores(e)) {
|
|
379
|
+
candidates.push(...findNestedGitRepos(path.join(repoAbs, e), e));
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
catch { /* untracked listing failed — ignored-side discovery still runs */ }
|
|
384
|
+
candidates.push(...findIgnoredEmbeddedRepos(repoAbs));
|
|
385
|
+
for (const rel of candidates) {
|
|
386
|
+
const full = (0, utils_1.normalizePath)(prefix + rel);
|
|
387
|
+
out.push(full);
|
|
388
|
+
visit(path.join(repoAbs, rel), full);
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
visit(rootDir, '');
|
|
392
|
+
return out;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Discover embedded repos hidden by `repoDir`'s OWN ignore rules: for each
|
|
396
|
+
* gitignored directory (skipping built-in default excludes), search for nested
|
|
397
|
+
* `.git` roots. Returns repo paths relative to `repoDir`, trailing-slashed.
|
|
398
|
+
*/
|
|
399
|
+
function findIgnoredEmbeddedRepos(repoDir) {
|
|
400
|
+
const defaults = defaultsOnlyIgnore();
|
|
401
|
+
const repos = [];
|
|
402
|
+
for (const dir of listIgnoredDirs(repoDir)) {
|
|
403
|
+
if (defaults.ignores(dir))
|
|
404
|
+
continue;
|
|
405
|
+
repos.push(...findNestedGitRepos(path.join(repoDir, dir), dir));
|
|
406
|
+
}
|
|
407
|
+
return repos;
|
|
168
408
|
}
|
|
169
409
|
/**
|
|
170
410
|
* Collect git-visible files (tracked + untracked, .gitignore-respected) from the
|
|
@@ -177,41 +417,55 @@ function buildDefaultIgnore(rootDir) {
|
|
|
177
417
|
* skips them entirely, and untracked output reports them only as an opaque
|
|
178
418
|
* "subdir/" entry (trailing slash) rather than expanding their files. Each
|
|
179
419
|
* embedded repo is its own git boundary, so we re-run `git ls-files` inside it.
|
|
180
|
-
* (See issue #193.)
|
|
420
|
+
* (See issue #193.) GITIGNORED embedded repos are invisible even to that —
|
|
421
|
+
* they're discovered separately via `findIgnoredEmbeddedRepos` (#514); every
|
|
422
|
+
* embedded repo root (however found) is recorded in `embeddedRoots` so callers
|
|
423
|
+
* can exempt its files from the parent's own gitignore rules.
|
|
181
424
|
*/
|
|
182
|
-
function collectGitFiles(repoDir, prefix, files) {
|
|
425
|
+
function collectGitFiles(repoDir, prefix, files, embeddedRoots) {
|
|
183
426
|
const gitOpts = { cwd: repoDir, encoding: 'utf-8', timeout: 30000, maxBuffer: 50 * 1024 * 1024, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true };
|
|
184
427
|
// Tracked files. --recurse-submodules pulls in files from active submodules,
|
|
185
428
|
// which the index would otherwise represent only as a commit pointer.
|
|
186
429
|
// Without this, monorepos using submodules index 0 files. (See issue #147.)
|
|
187
430
|
// Note: --recurse-submodules only supports -c/--cached and --stage modes — it
|
|
188
431
|
// can't be combined with -o, so untracked files are gathered separately below.
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
432
|
+
// -z gives NUL-separated, unquoted output so non-ASCII (e.g. CJK) paths
|
|
433
|
+
// survive verbatim. Without it git octal-escapes and double-quotes such paths
|
|
434
|
+
// (the core.quotepath default), and the quoted form never matches a real file
|
|
435
|
+
// on disk → those files are silently dropped from the index. (#541)
|
|
436
|
+
const tracked = (0, child_process_1.execFileSync)('git', ['ls-files', '-z', '-c', '--recurse-submodules'], gitOpts);
|
|
437
|
+
for (const rel of tracked.split('\0')) {
|
|
438
|
+
if (rel)
|
|
439
|
+
files.add((0, utils_1.normalizePath)(prefix + rel));
|
|
195
440
|
}
|
|
196
441
|
// Untracked files (submodules manage their own untracked state). Embedded git
|
|
197
442
|
// repos surface here as a single "subdir/" entry that git refuses to descend
|
|
198
443
|
// into — recurse into those as their own repos so their source gets indexed.
|
|
199
|
-
const untracked = (0, child_process_1.execFileSync)('git', ['ls-files', '-o', '--exclude-standard'], gitOpts);
|
|
200
|
-
for (const
|
|
201
|
-
|
|
202
|
-
if (!trimmed)
|
|
444
|
+
const untracked = (0, child_process_1.execFileSync)('git', ['ls-files', '-z', '-o', '--exclude-standard'], gitOpts);
|
|
445
|
+
for (const rel of untracked.split('\0')) {
|
|
446
|
+
if (!rel)
|
|
203
447
|
continue;
|
|
204
|
-
if (
|
|
448
|
+
if (rel.endsWith('/')) {
|
|
205
449
|
// git only emits a trailing-slash directory entry for an embedded repo.
|
|
206
450
|
// Guard with a .git check anyway, and skip anything else exactly as git
|
|
207
|
-
// itself skips it (we never descend into a non-repo opaque dir).
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
451
|
+
// itself skips it (we never descend into a non-repo opaque dir). Never
|
|
452
|
+
// descend into default-ignored locations — an embedded repo inside
|
|
453
|
+
// node_modules is an npm git-dependency, not project code.
|
|
454
|
+
const childDir = path.join(repoDir, rel);
|
|
455
|
+
if (fs.existsSync(path.join(childDir, '.git')) && !defaultsOnlyIgnore().ignores(rel)) {
|
|
456
|
+
embeddedRoots?.add((0, utils_1.normalizePath)(prefix + rel));
|
|
457
|
+
collectGitFiles(childDir, prefix + rel, files, embeddedRoots);
|
|
211
458
|
}
|
|
212
459
|
continue;
|
|
213
460
|
}
|
|
214
|
-
files.add((0, utils_1.normalizePath)(prefix +
|
|
461
|
+
files.add((0, utils_1.normalizePath)(prefix + rel));
|
|
462
|
+
}
|
|
463
|
+
// Embedded repos hidden by THIS repo's ignore rules (`/packages/` in a
|
|
464
|
+
// super-repo .gitignore) never appear in any listing above — discover and
|
|
465
|
+
// recurse into them too. (#514)
|
|
466
|
+
for (const rel of findIgnoredEmbeddedRepos(repoDir)) {
|
|
467
|
+
embeddedRoots?.add((0, utils_1.normalizePath)(prefix + rel));
|
|
468
|
+
collectGitFiles(path.join(repoDir, rel), prefix + rel, files, embeddedRoots);
|
|
215
469
|
}
|
|
216
470
|
}
|
|
217
471
|
/**
|
|
@@ -238,11 +492,15 @@ function getGitVisibleFiles(rootDir) {
|
|
|
238
492
|
}
|
|
239
493
|
}
|
|
240
494
|
const files = new Set();
|
|
241
|
-
|
|
495
|
+
const embeddedRoots = new Set();
|
|
496
|
+
collectGitFiles(rootDir, '', files, embeddedRoots);
|
|
242
497
|
// Apply built-in default ignores uniformly — to tracked files too, since
|
|
243
498
|
// committing a dependency/build dir doesn't make it project code. A
|
|
244
499
|
// `.gitignore` negation (e.g. `!vendor/`) is the explicit opt-in. (issue #407)
|
|
245
|
-
|
|
500
|
+
// Files inside an EMBEDDED repo are matched against that repo's own rules,
|
|
501
|
+
// not the parent's: the parent's .gitignore hides the child repo from git,
|
|
502
|
+
// not from the index. (#514)
|
|
503
|
+
const ig = buildScopeIgnore(rootDir, embeddedRoots);
|
|
246
504
|
return new Set([...files].filter((f) => !ig.ignores(f)));
|
|
247
505
|
}
|
|
248
506
|
catch {
|
|
@@ -252,38 +510,65 @@ function getGitVisibleFiles(rootDir) {
|
|
|
252
510
|
/**
|
|
253
511
|
* Use `git status` to detect changed files instead of scanning every file.
|
|
254
512
|
* Returns null on failure so callers fall back to full scan.
|
|
513
|
+
*
|
|
514
|
+
* Recurses into embedded repos — both the untracked kind (#193: the parent's
|
|
515
|
+
* status collapses them to an opaque `?? subdir/` entry) and the gitignored
|
|
516
|
+
* kind (#514: they never appear in the parent's status at all) — running
|
|
517
|
+
* `git status` inside each, so changes in a multi-repo workspace sync without
|
|
518
|
+
* a full rescan. Deleting an ENTIRE embedded repo dir is the one case this
|
|
519
|
+
* cannot see (the child status that would report the deletions is gone with
|
|
520
|
+
* it); a full `codegraph index` reconciles that.
|
|
255
521
|
*/
|
|
256
522
|
function getGitChangedFiles(rootDir) {
|
|
257
523
|
try {
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const deleted = [];
|
|
262
|
-
for (const line of output.split('\n')) {
|
|
263
|
-
if (line.length < 4)
|
|
264
|
-
continue; // Minimum: "XY file"
|
|
265
|
-
const statusCode = line.substring(0, 2);
|
|
266
|
-
const filePath = (0, utils_1.normalizePath)(line.substring(3));
|
|
267
|
-
// Skip non-source files (git status already omits .gitignored paths).
|
|
268
|
-
if (!(0, grammars_1.isSourceFile)(filePath))
|
|
269
|
-
continue;
|
|
270
|
-
if (statusCode === '??') {
|
|
271
|
-
added.push(filePath);
|
|
272
|
-
}
|
|
273
|
-
else if (statusCode.includes('D')) {
|
|
274
|
-
deleted.push(filePath);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
// M, MM, AM, A (staged), etc. — treat as modified
|
|
278
|
-
modified.push(filePath);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return { modified, added, deleted };
|
|
524
|
+
const changes = { modified: [], added: [], deleted: [] };
|
|
525
|
+
collectGitStatus(rootDir, '', changes);
|
|
526
|
+
return changes;
|
|
282
527
|
}
|
|
283
528
|
catch {
|
|
284
529
|
return null;
|
|
285
530
|
}
|
|
286
531
|
}
|
|
532
|
+
function collectGitStatus(repoDir, prefix, out) {
|
|
533
|
+
const output = (0, child_process_1.execFileSync)('git', ['status', '--porcelain', '--no-renames'], { cwd: repoDir, encoding: 'utf-8', timeout: 10000, maxBuffer: 50 * 1024 * 1024, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true });
|
|
534
|
+
const untrackedDirs = [];
|
|
535
|
+
for (const line of output.split('\n')) {
|
|
536
|
+
if (line.length < 4)
|
|
537
|
+
continue; // Minimum: "XY file"
|
|
538
|
+
const statusCode = line.substring(0, 2);
|
|
539
|
+
const rel = (0, utils_1.normalizePath)(line.substring(3));
|
|
540
|
+
// Untracked directory entries (trailing slash) may hide an embedded repo —
|
|
541
|
+
// collect for the recursion below instead of treating as a file.
|
|
542
|
+
if (statusCode === '??' && rel.endsWith('/')) {
|
|
543
|
+
untrackedDirs.push(rel);
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
const filePath = (0, utils_1.normalizePath)(prefix + rel);
|
|
547
|
+
// Skip non-source files (git status already omits .gitignored paths).
|
|
548
|
+
if (!(0, grammars_1.isSourceFile)(filePath))
|
|
549
|
+
continue;
|
|
550
|
+
if (statusCode === '??') {
|
|
551
|
+
out.added.push(filePath);
|
|
552
|
+
}
|
|
553
|
+
else if (statusCode.includes('D')) {
|
|
554
|
+
out.deleted.push(filePath);
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
// M, MM, AM, A (staged), etc. — treat as modified
|
|
558
|
+
out.modified.push(filePath);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
// Recurse embedded repos found under untracked dirs (at the dir itself or
|
|
562
|
+
// nested deeper) and under this repo's gitignored dirs.
|
|
563
|
+
for (const rel of untrackedDirs) {
|
|
564
|
+
for (const repoRel of findNestedGitRepos(path.join(repoDir, rel), rel)) {
|
|
565
|
+
collectGitStatus(path.join(repoDir, repoRel), prefix + repoRel, out);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
for (const rel of findIgnoredEmbeddedRepos(repoDir)) {
|
|
569
|
+
collectGitStatus(path.join(repoDir, rel), prefix + rel, out);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
287
572
|
/**
|
|
288
573
|
* Recursively scan a directory for source files.
|
|
289
574
|
*
|
|
@@ -341,16 +626,14 @@ function scanDirectoryWalk(rootDir, onProgress) {
|
|
|
341
626
|
let count = 0;
|
|
342
627
|
const visitedDirs = new Set();
|
|
343
628
|
const loadIgnore = (dir) => {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
return null;
|
|
629
|
+
const giPath = path.join(dir, '.gitignore');
|
|
630
|
+
if (!fs.existsSync(giPath))
|
|
631
|
+
return null;
|
|
632
|
+
// readGitignorePatterns is defensive: a non-UTF-8 (DLP-encrypted) or
|
|
633
|
+
// uncompilable .gitignore is skipped/filtered with a warning, never thrown
|
|
634
|
+
// (issue #682) — so the per-file `.ignores()` calls below can't crash.
|
|
635
|
+
const patterns = readGitignorePatterns(giPath);
|
|
636
|
+
return patterns ? { dir, ig: (0, ignore_1.default)().add(patterns) } : null;
|
|
354
637
|
};
|
|
355
638
|
const isIgnored = (fullPath, isDir, matchers) => {
|
|
356
639
|
for (const { dir, ig } of matchers) {
|
|
@@ -392,8 +675,9 @@ function scanDirectoryWalk(rootDir, onProgress) {
|
|
|
392
675
|
return;
|
|
393
676
|
}
|
|
394
677
|
for (const entry of entries) {
|
|
395
|
-
// Never descend into git internals or
|
|
396
|
-
|
|
678
|
+
// Never descend into git internals or any CodeGraph data directory
|
|
679
|
+
// (the active one or a sibling another environment created — #636).
|
|
680
|
+
if (entry.name === '.git' || (0, directory_1.isCodeGraphDataDir)(entry.name))
|
|
397
681
|
continue;
|
|
398
682
|
const fullPath = path.join(dir, entry.name);
|
|
399
683
|
const relativePath = (0, utils_1.normalizePath)(path.relative(rootDir, fullPath));
|