seer-mcp 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/.vscode/settings.json +3 -0
- package/LICENSE +176 -0
- package/README.md +272 -0
- package/README_dev.md +199 -0
- package/dist/bundle/ci.d.ts +47 -0
- package/dist/bundle/ci.d.ts.map +1 -0
- package/dist/bundle/ci.js +113 -0
- package/dist/bundle/ci.js.map +1 -0
- package/dist/bundle/contract.d.ts +111 -0
- package/dist/bundle/contract.d.ts.map +1 -0
- package/dist/bundle/contract.js +352 -0
- package/dist/bundle/contract.js.map +1 -0
- package/dist/bundle/export.d.ts +36 -0
- package/dist/bundle/export.d.ts.map +1 -0
- package/dist/bundle/export.js +152 -0
- package/dist/bundle/export.js.map +1 -0
- package/dist/bundle/external.d.ts +66 -0
- package/dist/bundle/external.d.ts.map +1 -0
- package/dist/bundle/external.js +238 -0
- package/dist/bundle/external.js.map +1 -0
- package/dist/bundle/format.d.ts +94 -0
- package/dist/bundle/format.d.ts.map +1 -0
- package/dist/bundle/format.js +42 -0
- package/dist/bundle/format.js.map +1 -0
- package/dist/bundle/import.d.ts +49 -0
- package/dist/bundle/import.d.ts.map +1 -0
- package/dist/bundle/import.js +116 -0
- package/dist/bundle/import.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1402 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +48 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +284 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/db/schema.d.ts +3 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +616 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/store.d.ts +1011 -0
- package/dist/db/store.d.ts.map +1 -0
- package/dist/db/store.js +3888 -0
- package/dist/db/store.js.map +1 -0
- package/dist/graph/pagerank.d.ts +9 -0
- package/dist/graph/pagerank.d.ts.map +1 -0
- package/dist/graph/pagerank.js +47 -0
- package/dist/graph/pagerank.js.map +1 -0
- package/dist/indexer/architecture.d.ts +72 -0
- package/dist/indexer/architecture.d.ts.map +1 -0
- package/dist/indexer/architecture.js +112 -0
- package/dist/indexer/architecture.js.map +1 -0
- package/dist/indexer/behavior.d.ts +75 -0
- package/dist/indexer/behavior.d.ts.map +1 -0
- package/dist/indexer/behavior.js +395 -0
- package/dist/indexer/behavior.js.map +1 -0
- package/dist/indexer/boundaries.d.ts +60 -0
- package/dist/indexer/boundaries.d.ts.map +1 -0
- package/dist/indexer/boundaries.js +366 -0
- package/dist/indexer/boundaries.js.map +1 -0
- package/dist/indexer/churn.d.ts +15 -0
- package/dist/indexer/churn.d.ts.map +1 -0
- package/dist/indexer/churn.js +49 -0
- package/dist/indexer/churn.js.map +1 -0
- package/dist/indexer/classify.d.ts +9 -0
- package/dist/indexer/classify.d.ts.map +1 -0
- package/dist/indexer/classify.js +90 -0
- package/dist/indexer/classify.js.map +1 -0
- package/dist/indexer/context.d.ts +176 -0
- package/dist/indexer/context.d.ts.map +1 -0
- package/dist/indexer/context.js +193 -0
- package/dist/indexer/context.js.map +1 -0
- package/dist/indexer/continuity.d.ts +67 -0
- package/dist/indexer/continuity.d.ts.map +1 -0
- package/dist/indexer/continuity.js +288 -0
- package/dist/indexer/continuity.js.map +1 -0
- package/dist/indexer/detectchanges.d.ts +32 -0
- package/dist/indexer/detectchanges.d.ts.map +1 -0
- package/dist/indexer/detectchanges.js +74 -0
- package/dist/indexer/detectchanges.js.map +1 -0
- package/dist/indexer/discovery.d.ts +37 -0
- package/dist/indexer/discovery.d.ts.map +1 -0
- package/dist/indexer/discovery.js +136 -0
- package/dist/indexer/discovery.js.map +1 -0
- package/dist/indexer/externaldeps.d.ts +18 -0
- package/dist/indexer/externaldeps.d.ts.map +1 -0
- package/dist/indexer/externaldeps.js +288 -0
- package/dist/indexer/externaldeps.js.map +1 -0
- package/dist/indexer/freshness.d.ts +48 -0
- package/dist/indexer/freshness.d.ts.map +1 -0
- package/dist/indexer/freshness.js +128 -0
- package/dist/indexer/freshness.js.map +1 -0
- package/dist/indexer/git.d.ts +144 -0
- package/dist/indexer/git.d.ts.map +1 -0
- package/dist/indexer/git.js +444 -0
- package/dist/indexer/git.js.map +1 -0
- package/dist/indexer/index.d.ts +145 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +930 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/modules.d.ts +62 -0
- package/dist/indexer/modules.d.ts.map +1 -0
- package/dist/indexer/modules.js +293 -0
- package/dist/indexer/modules.js.map +1 -0
- package/dist/indexer/preflight.d.ts +154 -0
- package/dist/indexer/preflight.d.ts.map +1 -0
- package/dist/indexer/preflight.js +399 -0
- package/dist/indexer/preflight.js.map +1 -0
- package/dist/indexer/protoScanner.d.ts +34 -0
- package/dist/indexer/protoScanner.d.ts.map +1 -0
- package/dist/indexer/protoScanner.js +133 -0
- package/dist/indexer/protoScanner.js.map +1 -0
- package/dist/indexer/risk.d.ts +115 -0
- package/dist/indexer/risk.d.ts.map +1 -0
- package/dist/indexer/risk.js +194 -0
- package/dist/indexer/risk.js.map +1 -0
- package/dist/indexer/serviceHostScanner.d.ts +25 -0
- package/dist/indexer/serviceHostScanner.d.ts.map +1 -0
- package/dist/indexer/serviceHostScanner.js +95 -0
- package/dist/indexer/serviceHostScanner.js.map +1 -0
- package/dist/indexer/serviceLinks.d.ts +105 -0
- package/dist/indexer/serviceLinks.d.ts.map +1 -0
- package/dist/indexer/serviceLinks.js +509 -0
- package/dist/indexer/serviceLinks.js.map +1 -0
- package/dist/indexer/shapehash.d.ts +98 -0
- package/dist/indexer/shapehash.d.ts.map +1 -0
- package/dist/indexer/shapehash.js +354 -0
- package/dist/indexer/shapehash.js.map +1 -0
- package/dist/indexer/skeleton.d.ts +15 -0
- package/dist/indexer/skeleton.d.ts.map +1 -0
- package/dist/indexer/skeleton.js +136 -0
- package/dist/indexer/skeleton.js.map +1 -0
- package/dist/indexer/symbolhistory.d.ts +41 -0
- package/dist/indexer/symbolhistory.d.ts.map +1 -0
- package/dist/indexer/symbolhistory.js +124 -0
- package/dist/indexer/symbolhistory.js.map +1 -0
- package/dist/indexer/watcher.d.ts +68 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +179 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/mcp/server.d.ts +80 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +1610 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/parser/index.d.ts +8 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +33 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/languages/cpp.d.ts +3 -0
- package/dist/parser/languages/cpp.d.ts.map +1 -0
- package/dist/parser/languages/cpp.js +350 -0
- package/dist/parser/languages/cpp.js.map +1 -0
- package/dist/parser/languages/csharp.d.ts +3 -0
- package/dist/parser/languages/csharp.d.ts.map +1 -0
- package/dist/parser/languages/csharp.js +239 -0
- package/dist/parser/languages/csharp.js.map +1 -0
- package/dist/parser/languages/go.d.ts +3 -0
- package/dist/parser/languages/go.d.ts.map +1 -0
- package/dist/parser/languages/go.js +259 -0
- package/dist/parser/languages/go.js.map +1 -0
- package/dist/parser/languages/java.d.ts +3 -0
- package/dist/parser/languages/java.d.ts.map +1 -0
- package/dist/parser/languages/java.js +391 -0
- package/dist/parser/languages/java.js.map +1 -0
- package/dist/parser/languages/python.d.ts +3 -0
- package/dist/parser/languages/python.d.ts.map +1 -0
- package/dist/parser/languages/python.js +396 -0
- package/dist/parser/languages/python.js.map +1 -0
- package/dist/parser/languages/rust.d.ts +3 -0
- package/dist/parser/languages/rust.d.ts.map +1 -0
- package/dist/parser/languages/rust.js +159 -0
- package/dist/parser/languages/rust.js.map +1 -0
- package/dist/parser/languages/typescript.d.ts +3 -0
- package/dist/parser/languages/typescript.d.ts.map +1 -0
- package/dist/parser/languages/typescript.js +1442 -0
- package/dist/parser/languages/typescript.js.map +1 -0
- package/dist/parser/parserContext.d.ts +77 -0
- package/dist/parser/parserContext.d.ts.map +1 -0
- package/dist/parser/parserContext.js +354 -0
- package/dist/parser/parserContext.js.map +1 -0
- package/dist/parser/walker.d.ts +81 -0
- package/dist/parser/walker.d.ts.map +1 -0
- package/dist/parser/walker.js +217 -0
- package/dist/parser/walker.js.map +1 -0
- package/dist/parser/worker.d.ts +66 -0
- package/dist/parser/worker.d.ts.map +1 -0
- package/dist/parser/worker.js +129 -0
- package/dist/parser/worker.js.map +1 -0
- package/dist/parser/workerpool.d.ts +107 -0
- package/dist/parser/workerpool.d.ts.map +1 -0
- package/dist/parser/workerpool.js +383 -0
- package/dist/parser/workerpool.js.map +1 -0
- package/dist/scip/format.d.ts +87 -0
- package/dist/scip/format.d.ts.map +1 -0
- package/dist/scip/format.js +31 -0
- package/dist/scip/format.js.map +1 -0
- package/dist/scip/import.d.ts +37 -0
- package/dist/scip/import.d.ts.map +1 -0
- package/dist/scip/import.js +180 -0
- package/dist/scip/import.js.map +1 -0
- package/dist/types.d.ts +392 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/docs/architecture.md +105 -0
- package/docs/benchmarks/methodology.md +134 -0
- package/docs/benchmarks/raw-results.md +71 -0
- package/docs/benchmarks.md +74 -0
- package/docs/cli.md +148 -0
- package/docs/examples/behavior-tests.md +70 -0
- package/docs/examples/change-history.md +85 -0
- package/docs/examples/pre-edit-context.md +81 -0
- package/docs/examples/service-links.md +88 -0
- package/docs/examples.md +80 -0
- package/docs/faq.md +70 -0
- package/docs/internals.md +104 -0
- package/docs/languages.md +70 -0
- package/docs/limits.md +52 -0
- package/docs/mcp.md +199 -0
- package/docs/quickstart.md +119 -0
- package/docs/testing.md +123 -0
- package/docs/tools.md +115 -0
- package/package.json +52 -0
- package/research-codebase.md +578 -0
- package/seer-cli-docs.md +326 -0
- package/seer-master-guide.md +246 -0
- package/src/bundle/ci.ts +141 -0
- package/src/bundle/contract.ts +387 -0
- package/src/bundle/export.ts +175 -0
- package/src/bundle/external.ts +285 -0
- package/src/bundle/format.ts +92 -0
- package/src/bundle/import.ts +157 -0
- package/src/cli/index.ts +1249 -0
- package/src/cli/init.ts +389 -0
- package/src/db/schema.ts +614 -0
- package/src/db/store.ts +4306 -0
- package/src/graph/pagerank.ts +53 -0
- package/src/indexer/architecture.ts +148 -0
- package/src/indexer/behavior.ts +466 -0
- package/src/indexer/boundaries.ts +374 -0
- package/src/indexer/churn.ts +58 -0
- package/src/indexer/classify.ts +96 -0
- package/src/indexer/context.ts +340 -0
- package/src/indexer/continuity.ts +322 -0
- package/src/indexer/detectchanges.ts +94 -0
- package/src/indexer/discovery.ts +176 -0
- package/src/indexer/externaldeps.ts +243 -0
- package/src/indexer/freshness.ts +166 -0
- package/src/indexer/git.ts +453 -0
- package/src/indexer/index.ts +1092 -0
- package/src/indexer/modules.ts +358 -0
- package/src/indexer/preflight.ts +548 -0
- package/src/indexer/protoScanner.ts +147 -0
- package/src/indexer/risk.ts +304 -0
- package/src/indexer/serviceHostScanner.ts +92 -0
- package/src/indexer/serviceLinks.ts +543 -0
- package/src/indexer/shapehash.ts +370 -0
- package/src/indexer/skeleton.ts +169 -0
- package/src/indexer/symbolhistory.ts +172 -0
- package/src/indexer/watcher.ts +206 -0
- package/src/mcp/server.ts +1659 -0
- package/src/parser/index.ts +37 -0
- package/src/parser/languages/cpp.ts +361 -0
- package/src/parser/languages/csharp.ts +235 -0
- package/src/parser/languages/go.ts +259 -0
- package/src/parser/languages/java.ts +382 -0
- package/src/parser/languages/python.ts +370 -0
- package/src/parser/languages/rust.ts +164 -0
- package/src/parser/languages/typescript.ts +1435 -0
- package/src/parser/parserContext.ts +392 -0
- package/src/parser/walker.ts +306 -0
- package/src/parser/worker.ts +181 -0
- package/src/parser/workerpool.ts +448 -0
- package/src/scip/format.ts +83 -0
- package/src/scip/import.ts +216 -0
- package/src/types.ts +457 -0
- package/tests/benchmark-service-links.ts +244 -0
- package/tests/bug-regressions.ts +626 -0
- package/tests/filters.ts +264 -0
- package/tests/fixtures/Counter.tsx +38 -0
- package/tests/fixtures/caller.ts +7 -0
- package/tests/fixtures/collisions.ts +23 -0
- package/tests/fixtures/local_helper.ts +5 -0
- package/tests/fixtures/overloads.java +17 -0
- package/tests/fixtures/remote_helper.ts +4 -0
- package/tests/fixtures/sample.c +15 -0
- package/tests/fixtures/sample.cpp +47 -0
- package/tests/fixtures/sample.cs +62 -0
- package/tests/fixtures/sample.go +68 -0
- package/tests/fixtures/sample.h +30 -0
- package/tests/fixtures/sample.java +85 -0
- package/tests/fixtures/sample.py +46 -0
- package/tests/fixtures/sample.rs +78 -0
- package/tests/fixtures/sample.ts +76 -0
- package/tests/fixtures-service/HttpClients.cs +30 -0
- package/tests/fixtures-service/HttpClients.java +24 -0
- package/tests/fixtures-service/billing.ts +15 -0
- package/tests/fixtures-service/docker-compose.yml +15 -0
- package/tests/fixtures-service/gateway.ts +10 -0
- package/tests/fixtures-service/get_user.ts +11 -0
- package/tests/fixtures-service/graphql_client.ts +63 -0
- package/tests/fixtures-service/graphql_server.ts +30 -0
- package/tests/fixtures-service/grpc_client.go +30 -0
- package/tests/fixtures-service/http_clients.go +23 -0
- package/tests/fixtures-service/http_clients.py +38 -0
- package/tests/fixtures-service/http_clients.ts +49 -0
- package/tests/fixtures-service/k8s/payment-service.yaml +22 -0
- package/tests/fixtures-service/k8s_calls.ts +20 -0
- package/tests/fixtures-service/messaging.ts +87 -0
- package/tests/fixtures-service/trpc_client.ts +39 -0
- package/tests/fixtures-service/trpc_server.ts +39 -0
- package/tests/fixtures-service/user_service.proto +33 -0
- package/tests/fixtures-trackcd/Cargo.toml +11 -0
- package/tests/fixtures-trackcd/SpringController.java +36 -0
- package/tests/fixtures-trackcd/auth_service.ts +19 -0
- package/tests/fixtures-trackcd/complex_module.py +50 -0
- package/tests/fixtures-trackcd/express_app.js +30 -0
- package/tests/fixtures-trackcd/fastapi_app.py +49 -0
- package/tests/fixtures-trackcd/fastify_object_routes.js +32 -0
- package/tests/fixtures-trackcd/go.mod +8 -0
- package/tests/fixtures-trackcd/package.json +15 -0
- package/tests/fixtures-trackcd/requirements.txt +4 -0
- package/tests/fixtures-trackcd/tests/auth_service.test.ts +13 -0
- package/tests/fixtures-tracke/auth/AuthService.ts +23 -0
- package/tests/fixtures-tracke/auth/crypto.ts +7 -0
- package/tests/fixtures-tracke/billing/Billing.ts +20 -0
- package/tests/fixtures-tracke/billing/Invoice.ts +10 -0
- package/tests/fixtures-tracke/billing/server.ts +17 -0
- package/tests/fixtures-tracke/package.json +7 -0
- package/tests/fixtures-tracke/tests/auth.test.ts +23 -0
- package/tests/fixtures-tracke/tests/billing.test.ts +14 -0
- package/tests/fixtures-trackf/package.json +5 -0
- package/tests/fixtures-trackf/src/auth.ts +26 -0
- package/tests/fixtures-trackf/src/handlers.ts +35 -0
- package/tests/fixtures-tracki/billing/routes.ts +12 -0
- package/tests/fixtures-tracki/gateway/client.ts +13 -0
- package/tests/git-features.ts +267 -0
- package/tests/init.ts +141 -0
- package/tests/mcp-jit.ts +130 -0
- package/tests/mcp-smoke.ts +191 -0
- package/tests/mcp-trackcd.ts +169 -0
- package/tests/mcp-tracke.ts +229 -0
- package/tests/mcp-trackf.ts +330 -0
- package/tests/mcp-trackg.ts +219 -0
- package/tests/mcp-tracki.ts +174 -0
- package/tests/mcp-watcher.ts +126 -0
- package/tests/optspec.ts +194 -0
- package/tests/parallel-index.ts +333 -0
- package/tests/parallel-read.ts +125 -0
- package/tests/parallel-recovery.ts +241 -0
- package/tests/perf-callers.ts +145 -0
- package/tests/query-parity.ts +184 -0
- package/tests/query-perf.ts +55 -0
- package/tests/scale-parallel-parity.ts +225 -0
- package/tests/scale-test.ts +523 -0
- package/tests/smoke.ts +396 -0
- package/tests/trackcd.ts +325 -0
- package/tests/tracke-collisions.ts +255 -0
- package/tests/tracke.ts +314 -0
- package/tests/trackf-bugs.ts +406 -0
- package/tests/trackf.ts +390 -0
- package/tests/trackg.ts +1372 -0
- package/tests/tracki-boundaries.ts +202 -0
- package/tests/tracki-continuity.ts +253 -0
- package/tests/tracki-contract-diff.ts +249 -0
- package/tests/tracki-external-bundles.ts +341 -0
- package/tests/tracki-preflight.ts +251 -0
- package/tests/verify-roles.ts +51 -0
- package/tests/worker-parity.ts +286 -0
- package/tests/worker-pool.ts +262 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.extractExternalDependencies = extractExternalDependencies;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
10
|
+
/**
|
|
11
|
+
* Walk the repo for known package manifests and emit one row per declared
|
|
12
|
+
* dependency. Idempotent: clears `external_dependencies` and re-inserts every
|
|
13
|
+
* call, so deletions in package.json are reflected on the next index.
|
|
14
|
+
*
|
|
15
|
+
* Supported ecosystems:
|
|
16
|
+
* npm package.json / package-lock.json / pnpm-lock.yaml (deps only)
|
|
17
|
+
* cargo Cargo.toml (Cargo.lock not parsed — duplicates would be noisy)
|
|
18
|
+
* pypi requirements.txt, pyproject.toml (PEP 621 [project.dependencies])
|
|
19
|
+
* go go.mod
|
|
20
|
+
*
|
|
21
|
+
* Manifest discovery uses fast-glob with the same ignores as the rest of the
|
|
22
|
+
* indexer (no node_modules, no vendor) so monorepos can be picked up from
|
|
23
|
+
* `packages/foo/package.json`.
|
|
24
|
+
*/
|
|
25
|
+
async function extractExternalDependencies(repoRoot, store) {
|
|
26
|
+
const abs = path_1.default.resolve(repoRoot);
|
|
27
|
+
const manifestPatterns = [
|
|
28
|
+
'package.json',
|
|
29
|
+
'**/package.json',
|
|
30
|
+
'Cargo.toml',
|
|
31
|
+
'**/Cargo.toml',
|
|
32
|
+
'pyproject.toml',
|
|
33
|
+
'**/pyproject.toml',
|
|
34
|
+
'requirements*.txt',
|
|
35
|
+
'**/requirements*.txt',
|
|
36
|
+
'go.mod',
|
|
37
|
+
'**/go.mod',
|
|
38
|
+
];
|
|
39
|
+
const ignored = [
|
|
40
|
+
'node_modules/**', '**/node_modules/**',
|
|
41
|
+
'vendor/**', '**/vendor/**', 'vendored/**', '**/vendored/**',
|
|
42
|
+
'third_party/**', '**/third_party/**', 'thirdparty/**', '**/thirdparty/**',
|
|
43
|
+
'target/**', '**/target/**',
|
|
44
|
+
'dist/**', '**/dist/**',
|
|
45
|
+
'.git/**',
|
|
46
|
+
];
|
|
47
|
+
const matches = await (0, fast_glob_1.default)(manifestPatterns, {
|
|
48
|
+
cwd: abs, ignore: ignored, onlyFiles: true, followSymbolicLinks: false, dot: false,
|
|
49
|
+
unique: true,
|
|
50
|
+
});
|
|
51
|
+
store.clearExternalDeps();
|
|
52
|
+
let inserted = 0;
|
|
53
|
+
for (const rel of matches) {
|
|
54
|
+
const filePath = path_1.default.join(abs, rel);
|
|
55
|
+
let content;
|
|
56
|
+
try {
|
|
57
|
+
content = fs_1.default.readFileSync(filePath, 'utf8');
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (rel.endsWith('package.json') || rel === 'package.json') {
|
|
63
|
+
inserted += parsePackageJson(content, rel, store);
|
|
64
|
+
}
|
|
65
|
+
else if (rel.endsWith('Cargo.toml') || rel === 'Cargo.toml') {
|
|
66
|
+
inserted += parseCargoToml(content, rel, store);
|
|
67
|
+
}
|
|
68
|
+
else if (rel.endsWith('pyproject.toml') || rel === 'pyproject.toml') {
|
|
69
|
+
inserted += parsePyproject(content, rel, store);
|
|
70
|
+
}
|
|
71
|
+
else if (rel.endsWith('.txt')) {
|
|
72
|
+
inserted += parseRequirementsTxt(content, rel, store);
|
|
73
|
+
}
|
|
74
|
+
else if (rel.endsWith('go.mod') || rel === 'go.mod') {
|
|
75
|
+
inserted += parseGoMod(content, rel, store);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return inserted;
|
|
79
|
+
}
|
|
80
|
+
function parsePackageJson(content, manifestPath, store) {
|
|
81
|
+
let json;
|
|
82
|
+
try {
|
|
83
|
+
json = JSON.parse(content);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
if (!json || typeof json !== 'object')
|
|
89
|
+
return 0;
|
|
90
|
+
let count = 0;
|
|
91
|
+
const groups = [
|
|
92
|
+
[json.dependencies, 0],
|
|
93
|
+
[json.devDependencies, 1],
|
|
94
|
+
[json.peerDependencies, 0],
|
|
95
|
+
[json.optionalDependencies, 0],
|
|
96
|
+
];
|
|
97
|
+
for (const [group, isDev] of groups) {
|
|
98
|
+
if (!group || typeof group !== 'object')
|
|
99
|
+
continue;
|
|
100
|
+
for (const [name, version] of Object.entries(group)) {
|
|
101
|
+
if (!name)
|
|
102
|
+
continue;
|
|
103
|
+
store.insertExternalDep('npm', name, typeof version === 'string' ? version : null, manifestPath, isDev);
|
|
104
|
+
count++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return count;
|
|
108
|
+
}
|
|
109
|
+
function parseCargoToml(content, manifestPath, store) {
|
|
110
|
+
// Lightweight TOML parser for [dependencies] / [dev-dependencies] sections.
|
|
111
|
+
// We intentionally don't pull in a full TOML lib — Cargo manifests are
|
|
112
|
+
// well-formed enough that a section-aware line walk suffices.
|
|
113
|
+
let count = 0;
|
|
114
|
+
let section = '';
|
|
115
|
+
for (const rawLine of content.split('\n')) {
|
|
116
|
+
const line = rawLine.replace(/#.*$/, '').trim();
|
|
117
|
+
if (!line)
|
|
118
|
+
continue;
|
|
119
|
+
const sectionMatch = line.match(/^\[(.+?)\]$/);
|
|
120
|
+
if (sectionMatch) {
|
|
121
|
+
section = sectionMatch[1].trim();
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const inDeps = section === 'dependencies' || section === 'dev-dependencies' || section === 'build-dependencies';
|
|
125
|
+
if (!inDeps)
|
|
126
|
+
continue;
|
|
127
|
+
const eq = line.indexOf('=');
|
|
128
|
+
if (eq < 0)
|
|
129
|
+
continue;
|
|
130
|
+
const name = line.slice(0, eq).trim();
|
|
131
|
+
const rest = line.slice(eq + 1).trim();
|
|
132
|
+
if (!name || /[\[{]/.test(name))
|
|
133
|
+
continue;
|
|
134
|
+
let version = null;
|
|
135
|
+
const strMatch = rest.match(/^"([^"]+)"/);
|
|
136
|
+
if (strMatch)
|
|
137
|
+
version = strMatch[1];
|
|
138
|
+
else {
|
|
139
|
+
const inlineVer = rest.match(/version\s*=\s*"([^"]+)"/);
|
|
140
|
+
if (inlineVer)
|
|
141
|
+
version = inlineVer[1];
|
|
142
|
+
}
|
|
143
|
+
const isDev = section === 'dev-dependencies' ? 1 : 0;
|
|
144
|
+
store.insertExternalDep('cargo', name, version, manifestPath, isDev);
|
|
145
|
+
count++;
|
|
146
|
+
}
|
|
147
|
+
return count;
|
|
148
|
+
}
|
|
149
|
+
function parsePyproject(content, manifestPath, store) {
|
|
150
|
+
// [project] dependencies / optional-dependencies — Poetry uses
|
|
151
|
+
// [tool.poetry.dependencies] in addition. We handle both.
|
|
152
|
+
let count = 0;
|
|
153
|
+
let section = '';
|
|
154
|
+
let inList = false;
|
|
155
|
+
let buf = [];
|
|
156
|
+
const flushList = (isDev) => {
|
|
157
|
+
for (const item of buf) {
|
|
158
|
+
const m = item.match(/^"([^"]+)"|^'([^']+)'/);
|
|
159
|
+
if (!m)
|
|
160
|
+
continue;
|
|
161
|
+
const spec = (m[1] ?? m[2] ?? '').trim();
|
|
162
|
+
if (!spec)
|
|
163
|
+
continue;
|
|
164
|
+
// Strip extras / version: "package[extras]>=1.2.3"
|
|
165
|
+
const nameMatch = spec.match(/^([A-Za-z0-9_.\-]+)/);
|
|
166
|
+
if (!nameMatch)
|
|
167
|
+
continue;
|
|
168
|
+
const name = nameMatch[1];
|
|
169
|
+
const versionMatch = spec.slice(nameMatch[0].length).match(/[<>=~!^].+/);
|
|
170
|
+
const version = versionMatch ? versionMatch[0].trim() : null;
|
|
171
|
+
store.insertExternalDep('pypi', name, version, manifestPath, isDev);
|
|
172
|
+
count++;
|
|
173
|
+
}
|
|
174
|
+
buf = [];
|
|
175
|
+
};
|
|
176
|
+
const lines = content.split('\n');
|
|
177
|
+
for (let i = 0; i < lines.length; i++) {
|
|
178
|
+
const raw = lines[i];
|
|
179
|
+
const line = raw.replace(/#.*$/, '').trim();
|
|
180
|
+
const sectionMatch = line.match(/^\[(.+?)\]$/);
|
|
181
|
+
if (sectionMatch) {
|
|
182
|
+
if (inList) {
|
|
183
|
+
flushList(section.includes('dev') ? 1 : 0);
|
|
184
|
+
inList = false;
|
|
185
|
+
}
|
|
186
|
+
section = sectionMatch[1].trim();
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (section === 'project' || section === 'tool.poetry.dependencies' || section === 'tool.poetry.dev-dependencies') {
|
|
190
|
+
// [project] dependencies = ["pkg>=1.0", ...]
|
|
191
|
+
if (section === 'project' && /^dependencies\s*=\s*\[/.test(line)) {
|
|
192
|
+
inList = true;
|
|
193
|
+
const after = line.replace(/^dependencies\s*=\s*\[/, '');
|
|
194
|
+
if (after.includes(']')) {
|
|
195
|
+
for (const item of after.replace(/\].*$/, '').split(','))
|
|
196
|
+
buf.push(item.trim());
|
|
197
|
+
flushList(0);
|
|
198
|
+
inList = false;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
buf.push(after);
|
|
202
|
+
}
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (inList) {
|
|
206
|
+
if (line.includes(']')) {
|
|
207
|
+
for (const item of line.replace(/\].*$/, '').split(','))
|
|
208
|
+
if (item.trim())
|
|
209
|
+
buf.push(item.trim());
|
|
210
|
+
flushList(0);
|
|
211
|
+
inList = false;
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
for (const item of line.split(','))
|
|
215
|
+
if (item.trim())
|
|
216
|
+
buf.push(item.trim());
|
|
217
|
+
}
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (section.startsWith('tool.poetry') && /^[A-Za-z0-9_.\-]+\s*=/.test(line)) {
|
|
221
|
+
const eq = line.indexOf('=');
|
|
222
|
+
const name = line.slice(0, eq).trim();
|
|
223
|
+
const rest = line.slice(eq + 1).trim();
|
|
224
|
+
const verMatch = rest.match(/^"([^"]+)"/);
|
|
225
|
+
const version = verMatch ? verMatch[1] : null;
|
|
226
|
+
const isDev = section.includes('dev') ? 1 : 0;
|
|
227
|
+
store.insertExternalDep('pypi', name, version, manifestPath, isDev);
|
|
228
|
+
count++;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (inList)
|
|
233
|
+
flushList(section.includes('dev') ? 1 : 0);
|
|
234
|
+
return count;
|
|
235
|
+
}
|
|
236
|
+
function parseRequirementsTxt(content, manifestPath, store) {
|
|
237
|
+
let count = 0;
|
|
238
|
+
const isDev = /dev|test/i.test(manifestPath) ? 1 : 0;
|
|
239
|
+
for (const raw of content.split('\n')) {
|
|
240
|
+
const line = raw.replace(/#.*$/, '').trim();
|
|
241
|
+
if (!line || line.startsWith('-'))
|
|
242
|
+
continue;
|
|
243
|
+
const m = line.match(/^([A-Za-z0-9_.\-]+)/);
|
|
244
|
+
if (!m)
|
|
245
|
+
continue;
|
|
246
|
+
const name = m[1];
|
|
247
|
+
const rest = line.slice(m[0].length);
|
|
248
|
+
const ver = rest.match(/[<>=~!^].+/);
|
|
249
|
+
store.insertExternalDep('pypi', name, ver ? ver[0].trim() : null, manifestPath, isDev);
|
|
250
|
+
count++;
|
|
251
|
+
}
|
|
252
|
+
return count;
|
|
253
|
+
}
|
|
254
|
+
function parseGoMod(content, manifestPath, store) {
|
|
255
|
+
let count = 0;
|
|
256
|
+
let inRequire = false;
|
|
257
|
+
for (const raw of content.split('\n')) {
|
|
258
|
+
const line = raw.replace(/\/\/.*$/, '').trim();
|
|
259
|
+
if (!line)
|
|
260
|
+
continue;
|
|
261
|
+
if (line.startsWith('require (')) {
|
|
262
|
+
inRequire = true;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
if (line === ')') {
|
|
266
|
+
inRequire = false;
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (line.startsWith('require ')) {
|
|
270
|
+
// single-line: `require mod v1.2.3`
|
|
271
|
+
const parts = line.slice('require '.length).trim().split(/\s+/);
|
|
272
|
+
if (parts.length >= 2) {
|
|
273
|
+
store.insertExternalDep('go', parts[0], parts[1], manifestPath, 0);
|
|
274
|
+
count++;
|
|
275
|
+
}
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (inRequire) {
|
|
279
|
+
const parts = line.split(/\s+/);
|
|
280
|
+
if (parts.length >= 2 && !/^\/\//.test(parts[0])) {
|
|
281
|
+
store.insertExternalDep('go', parts[0], parts[1], manifestPath, 0);
|
|
282
|
+
count++;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return count;
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=externaldeps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"externaldeps.js","sourceRoot":"","sources":["../../src/indexer/externaldeps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Indexer } from './index.js';
|
|
2
|
+
import { Store } from '../db/store.js';
|
|
3
|
+
/**
|
|
4
|
+
* Quick freshness check + targeted re-index for MCP/CLI queries.
|
|
5
|
+
*
|
|
6
|
+
* Design contract: the watcher (when running) keeps the index warm by marking
|
|
7
|
+
* files dirty in the background. JIT sync runs before every query as the
|
|
8
|
+
* correctness layer — it does the actual reindex of dirty files so a query
|
|
9
|
+
* returning right now reflects the current workspace state.
|
|
10
|
+
*
|
|
11
|
+
* Implementation: discover the workspace, compare on-disk content hashes
|
|
12
|
+
* against what the DB says, and only reindex files whose hash changed.
|
|
13
|
+
* Unchanged files are skipped entirely; we don't touch the parser for them.
|
|
14
|
+
*
|
|
15
|
+
* The intentional bias here is correctness over latency: we re-discover the
|
|
16
|
+
* full workspace each time so newly-added or newly-renamed files are not
|
|
17
|
+
* missed. For very large repos this is still cheap (a glob + dir walk
|
|
18
|
+
* over 10-100k files is sub-second) compared to a single tree-sitter parse,
|
|
19
|
+
* and you only do it once per JIT call.
|
|
20
|
+
*/
|
|
21
|
+
export interface FreshnessReport {
|
|
22
|
+
/** Files where the on-disk hash differed from the DB. Reindexed. */
|
|
23
|
+
dirtyReindexed: number;
|
|
24
|
+
/** Files that vanished from disk since the last index. Pruned. */
|
|
25
|
+
removed: number;
|
|
26
|
+
/** Files newly seen this run (not in the DB yet). Indexed. */
|
|
27
|
+
added: number;
|
|
28
|
+
/** Total wall time in ms. */
|
|
29
|
+
elapsedMs: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Inspect a workspace for changes since the last index, then reindex only
|
|
33
|
+
* the files that need it. Designed to run before every MCP query.
|
|
34
|
+
*
|
|
35
|
+
* @param store a writable Store (NOT readonly — we may need to mutate)
|
|
36
|
+
* @param indexer an Indexer over the same store
|
|
37
|
+
* @param repoRoot the workspace path used at index time
|
|
38
|
+
* @param options.maxDirty cap reindex work per call. When the dirty set is
|
|
39
|
+
* larger than this, we still run a full `indexer.indexDirectory()` because
|
|
40
|
+
* a partial JIT pass would leave the index inconsistent (resolveEdges
|
|
41
|
+
* needs the full graph). Defaults to 200 — small enough to keep the
|
|
42
|
+
* "type a few characters and ask" workflow snappy.
|
|
43
|
+
*/
|
|
44
|
+
export declare function jitSync(store: Store, indexer: Indexer, repoRoot: string, options?: {
|
|
45
|
+
maxDirty?: number;
|
|
46
|
+
verbose?: boolean;
|
|
47
|
+
}): Promise<FreshnessReport>;
|
|
48
|
+
//# sourceMappingURL=freshness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"freshness.d.ts","sourceRoot":"","sources":["../../src/indexer/freshness.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;CACnB;AAWD;;;;;;;;;;;;GAYG;AACH,wBAAsB,OAAO,CAC3B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GACrD,OAAO,CAAC,eAAe,CAAC,CA2F1B"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.jitSync = jitSync;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const discovery_js_1 = require("./discovery.js");
|
|
11
|
+
/**
|
|
12
|
+
* Cheap content hash matching what the indexer uses internally. Kept here as
|
|
13
|
+
* a duplicate (not exported from indexer/index.ts) because the indexer's
|
|
14
|
+
* version is in the hot loop and we don't want to widen its export surface.
|
|
15
|
+
*/
|
|
16
|
+
function sha256Short(content) {
|
|
17
|
+
return crypto_1.default.createHash('sha256').update(content, 'utf8').digest('hex').slice(0, 16);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Inspect a workspace for changes since the last index, then reindex only
|
|
21
|
+
* the files that need it. Designed to run before every MCP query.
|
|
22
|
+
*
|
|
23
|
+
* @param store a writable Store (NOT readonly — we may need to mutate)
|
|
24
|
+
* @param indexer an Indexer over the same store
|
|
25
|
+
* @param repoRoot the workspace path used at index time
|
|
26
|
+
* @param options.maxDirty cap reindex work per call. When the dirty set is
|
|
27
|
+
* larger than this, we still run a full `indexer.indexDirectory()` because
|
|
28
|
+
* a partial JIT pass would leave the index inconsistent (resolveEdges
|
|
29
|
+
* needs the full graph). Defaults to 200 — small enough to keep the
|
|
30
|
+
* "type a few characters and ask" workflow snappy.
|
|
31
|
+
*/
|
|
32
|
+
async function jitSync(store, indexer, repoRoot, options = {}) {
|
|
33
|
+
const start = Date.now();
|
|
34
|
+
const maxDirty = options.maxDirty ?? 200;
|
|
35
|
+
const absRoot = path_1.default.resolve(repoRoot);
|
|
36
|
+
// 1. Snapshot what the DB knows.
|
|
37
|
+
const dbFiles = store.listFiles();
|
|
38
|
+
const dbByPath = new Map(dbFiles.map(f => [normalizeForCompare(f.path), f]));
|
|
39
|
+
// 2. Walk the workspace and find candidate files. discoverFiles() applies
|
|
40
|
+
// the same ignore rules the indexer uses, so freshness can't be
|
|
41
|
+
// misled by build artifacts or `vendor/` entries.
|
|
42
|
+
const discovered = await (0, discovery_js_1.discoverFiles)(absRoot);
|
|
43
|
+
const discoveredByPath = new Map();
|
|
44
|
+
for (const d of discovered) {
|
|
45
|
+
discoveredByPath.set(normalizeForCompare(d.absolutePath), d.relativePath);
|
|
46
|
+
}
|
|
47
|
+
// 3. Identify added / removed / candidate-dirty files.
|
|
48
|
+
const added = [];
|
|
49
|
+
const removed = [];
|
|
50
|
+
const candidateDirty = [];
|
|
51
|
+
for (const f of dbFiles) {
|
|
52
|
+
const key = normalizeForCompare(f.path);
|
|
53
|
+
if (!discoveredByPath.has(key)) {
|
|
54
|
+
removed.push(f.id);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
candidateDirty.push(f);
|
|
58
|
+
}
|
|
59
|
+
for (const [key, _rel] of discoveredByPath) {
|
|
60
|
+
if (!dbByPath.has(key))
|
|
61
|
+
added.push(key);
|
|
62
|
+
}
|
|
63
|
+
// 4. Hash each candidate. Same trade-off as the indexer: read everything
|
|
64
|
+
// we'd parse anyway, but if the hash matches we never spend time on
|
|
65
|
+
// the parser. We stop early as soon as we cross `maxDirty` so a giant
|
|
66
|
+
// change like a git checkout falls back to a full reindex.
|
|
67
|
+
const dirty = [];
|
|
68
|
+
for (const f of candidateDirty) {
|
|
69
|
+
if (dirty.length + added.length >= maxDirty)
|
|
70
|
+
break;
|
|
71
|
+
let content;
|
|
72
|
+
try {
|
|
73
|
+
content = await fs_1.default.promises.readFile(f.path, 'utf8');
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// File became unreadable mid-check (rename, permission flip). Treat
|
|
77
|
+
// as removed so the next pass cleans it up.
|
|
78
|
+
removed.push(f.id);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const hash = sha256Short(content);
|
|
82
|
+
if (hash !== f.hash)
|
|
83
|
+
dirty.push(f.path);
|
|
84
|
+
}
|
|
85
|
+
const fullReindexNeeded = dirty.length + added.length >= maxDirty || removed.length > 0;
|
|
86
|
+
if (dirty.length === 0 && added.length === 0 && removed.length === 0) {
|
|
87
|
+
return { dirtyReindexed: 0, removed: 0, added: 0, elapsedMs: Date.now() - start };
|
|
88
|
+
}
|
|
89
|
+
if (fullReindexNeeded) {
|
|
90
|
+
// Cheaper to invoke the full pipeline than to surgically remove files
|
|
91
|
+
// and reconcile edge graphs. The indexer's cache means unchanged files
|
|
92
|
+
// are still skipped at parse time, so this is O(dirty + added + |touched|)
|
|
93
|
+
// not O(|workspace|).
|
|
94
|
+
// JIT pins parallel:false. The dirty set is small (≤ maxDirty=200) and
|
|
95
|
+
// worker spawn cost dominates the wins at this scale; serial is the
|
|
96
|
+
// right default for the snappy "edit + ask" loop. MCP servers that want
|
|
97
|
+
// parallel JIT can override later via an option.
|
|
98
|
+
const result = await indexer.indexDirectory(absRoot, { quiet: !options.verbose, parallel: false });
|
|
99
|
+
return {
|
|
100
|
+
dirtyReindexed: dirty.length,
|
|
101
|
+
removed: removed.length,
|
|
102
|
+
added: added.length,
|
|
103
|
+
elapsedMs: Date.now() - start + (result.elapsedMs ?? 0),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// Targeted JIT path: dirty/added files only, no full re-discovery. Reuse
|
|
107
|
+
// the indexer's machinery by calling indexDirectory — its cache skips
|
|
108
|
+
// unchanged files. This is dominated by the discovery walk we already did,
|
|
109
|
+
// so the marginal cost is small.
|
|
110
|
+
await indexer.indexDirectory(absRoot, { quiet: !options.verbose, parallel: false });
|
|
111
|
+
return {
|
|
112
|
+
dirtyReindexed: dirty.length,
|
|
113
|
+
removed: removed.length,
|
|
114
|
+
added: added.length,
|
|
115
|
+
elapsedMs: Date.now() - start,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Normalize a path for comparison across the OS-specific quirks we hit on
|
|
120
|
+
* Windows. We index with backslashes; discovery resolves through `path.join`
|
|
121
|
+
* which also produces backslashes. Read-only callers might pass a slash-form
|
|
122
|
+
* path through the MCP layer; lowercase folds Windows case-insensitivity.
|
|
123
|
+
*/
|
|
124
|
+
function normalizeForCompare(p) {
|
|
125
|
+
const norm = p.replace(/\\/g, '/');
|
|
126
|
+
return process.platform === 'win32' ? norm.toLowerCase() : norm;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=freshness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"freshness.js","sourceRoot":"","sources":["../../src/indexer/freshness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin async wrapper around `git` so the rest of the indexer doesn't deal
|
|
3
|
+
* with child_process directly. All commands run with `cwd = repoRoot`.
|
|
4
|
+
*
|
|
5
|
+
* Errors are surfaced as `null` returns (not throws) so a non-git workspace
|
|
6
|
+
* silently no-ops. Callers should check the return value.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isGitRepo(repoRoot: string): boolean;
|
|
9
|
+
export declare function gitHeadSha(repoRoot: string): string | null;
|
|
10
|
+
export declare function gitRemoteUrl(repoRoot: string, remote?: string): string | null;
|
|
11
|
+
export interface FileChurnStats {
|
|
12
|
+
commitCount: number;
|
|
13
|
+
lastCommitSha: string | null;
|
|
14
|
+
lastCommitAt: number | null;
|
|
15
|
+
topAuthor: string | null;
|
|
16
|
+
secondAuthor: string | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Collect file-level churn stats by streaming `git log` once and bucketing
|
|
20
|
+
* per file. Uses `--follow` per-file would be ~slow on big repos, so we use
|
|
21
|
+
* a single `git log --name-only` pass and aggregate in JS. The trade-off is
|
|
22
|
+
* that renames lose their pre-rename history; callers documenting that fact
|
|
23
|
+
* matches the master guide's "honest about rename limits" stance.
|
|
24
|
+
*/
|
|
25
|
+
export declare function collectFileChurn(repoRoot: string, filesAbs: Iterable<string>): Promise<Map<string, FileChurnStats>>;
|
|
26
|
+
export interface CommitMeta {
|
|
27
|
+
sha: string;
|
|
28
|
+
authorName: string | null;
|
|
29
|
+
authorEmail: string | null;
|
|
30
|
+
committedAt: number;
|
|
31
|
+
message: string;
|
|
32
|
+
/**
|
|
33
|
+
* The path the file had AT THIS COMMIT (forward-slash, repo-relative).
|
|
34
|
+
* Resolved from `git log --follow --name-status` so commits prior to a
|
|
35
|
+
* rename can still be looked up by the historical path. Null if the path
|
|
36
|
+
* couldn't be determined from log output (in which case callers should
|
|
37
|
+
* fall back to the current path).
|
|
38
|
+
*/
|
|
39
|
+
pathAtCommit: string | null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `git log` commits that touched a single file, newest first. Each commit
|
|
43
|
+
* includes its author info and full message. Used by the symbol-history pass.
|
|
44
|
+
*
|
|
45
|
+
* `--name-status` is added on top of `--follow` so we get a per-commit path —
|
|
46
|
+
* critical for the rename case: the historical commits touched the OLD path,
|
|
47
|
+
* but our usual `git show <sha> -- <currentPath>` would look at the wrong
|
|
48
|
+
* path and return empty hunks. With pathAtCommit threaded through to
|
|
49
|
+
* fileDiffInfo(), pre-rename history is preserved.
|
|
50
|
+
*
|
|
51
|
+
* Parser shape: we ask git for a per-commit header line prefixed `__C__`
|
|
52
|
+
* (sha, author, email, ISO date — all NUL-free fields tab-separated), then
|
|
53
|
+
* the commit body (terminated by a unique end marker `__BODY_END__`), then
|
|
54
|
+
* the name-status lines that git appends after each commit. The name-status
|
|
55
|
+
* block has one path entry per commit relative to this file's --follow chain:
|
|
56
|
+
* either `M\tpath`, `A\tpath`, `D\tpath`, or `R<score>\toldPath\tnewPath`.
|
|
57
|
+
*
|
|
58
|
+
* Using a custom body terminator (instead of git's default blank-line
|
|
59
|
+
* separator) lets us handle commit messages that themselves contain blank
|
|
60
|
+
* lines or `__C__` literals without re-introducing the old `__C__ff8` bug.
|
|
61
|
+
*/
|
|
62
|
+
export declare function commitsForFile(repoRoot: string, filePath: string, options?: {
|
|
63
|
+
limit?: number;
|
|
64
|
+
since?: number;
|
|
65
|
+
}): Promise<CommitMeta[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Walk the line stream from `git log --follow --name-status` (with the
|
|
68
|
+
* `__C__` header / `__BODY_END__` body terminator format above) and emit
|
|
69
|
+
* one CommitMeta per `__C__` header. Exposed only for tests; the live
|
|
70
|
+
* pipeline goes through commitsForFile().
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseFollowLog(buf: string): CommitMeta[];
|
|
73
|
+
export interface DiffHunk {
|
|
74
|
+
oldStart: number;
|
|
75
|
+
oldLines: number;
|
|
76
|
+
newStart: number;
|
|
77
|
+
newLines: number;
|
|
78
|
+
}
|
|
79
|
+
export interface FileDiffInfo {
|
|
80
|
+
hunks: DiffHunk[];
|
|
81
|
+
/**
|
|
82
|
+
* True when the commit created the file (or — symmetrically — deleted it).
|
|
83
|
+
* In that case the diff has `--- /dev/null` (added) or `+++ /dev/null`
|
|
84
|
+
* (deleted) and EVERY symbol currently in the file should be attributed,
|
|
85
|
+
* because the file's current shape didn't exist before.
|
|
86
|
+
*/
|
|
87
|
+
isFileAddition: boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Diff hunks for a file changed by a single commit. `git show -U0 <sha>`
|
|
91
|
+
* handles the root commit transparently (no parent → diff against the empty
|
|
92
|
+
* tree), so the caller doesn't need to pass parentSha. `parentSha` is kept
|
|
93
|
+
* for compatibility but ignored.
|
|
94
|
+
*/
|
|
95
|
+
export declare function fileDiffHunks(repoRoot: string, _parentSha: string | null, sha: string, filePath: string): Promise<DiffHunk[]>;
|
|
96
|
+
/** Like fileDiffHunks but returns extra metadata used for "this commit
|
|
97
|
+
* created the file → match every symbol" heuristic.
|
|
98
|
+
*
|
|
99
|
+
* `filePath` may be either an absolute path or a repo-relative one. When the
|
|
100
|
+
* file was renamed across history, callers should pass the PATH-AT-COMMIT
|
|
101
|
+
* (resolved from `git log --follow --name-status`) so `git show` looks at
|
|
102
|
+
* the right side of the rename — passing the current path would return
|
|
103
|
+
* empty hunks for pre-rename commits and silently lose history.
|
|
104
|
+
*/
|
|
105
|
+
export declare function fileDiffInfo(repoRoot: string, sha: string, filePath: string): Promise<FileDiffInfo>;
|
|
106
|
+
/**
|
|
107
|
+
* Diff numstat for one commit: returns added/removed line counts per file
|
|
108
|
+
* (or aggregated when filePath is given).
|
|
109
|
+
*/
|
|
110
|
+
export declare function commitNumstat(repoRoot: string, sha: string, filePath?: string): Promise<{
|
|
111
|
+
added: number;
|
|
112
|
+
removed: number;
|
|
113
|
+
}>;
|
|
114
|
+
/**
|
|
115
|
+
* git diff name-only between two refs. Defaults to HEAD vs the working
|
|
116
|
+
* tree (uncommitted changes) — used by `detect_changes`. Returns absolute
|
|
117
|
+
* paths (after path.resolve(repoRoot, rel)).
|
|
118
|
+
*/
|
|
119
|
+
export declare function gitChangedFiles(repoRoot: string, fromRef?: string, toRef?: string): string[];
|
|
120
|
+
/**
|
|
121
|
+
* git diff -U0 hunks for one file between two refs (or working tree if refs
|
|
122
|
+
* omitted). Returns parsed hunk headers (line ranges in the new file) so
|
|
123
|
+
* `detect_changes` can compute which symbols overlap.
|
|
124
|
+
*/
|
|
125
|
+
export declare function fileDiffHunksSync(repoRoot: string, filePath: string, fromRef?: string, toRef?: string): DiffHunk[];
|
|
126
|
+
/**
|
|
127
|
+
* Extract GitHub-style PR numbers from a commit message. We accept the
|
|
128
|
+
* common conventions:
|
|
129
|
+
* "Merge pull request #1234 from ..."
|
|
130
|
+
* "Fix something (#1234)"
|
|
131
|
+
* "#1234"
|
|
132
|
+
* "PR #1234"
|
|
133
|
+
*
|
|
134
|
+
* Returns the first matched PR number, or null.
|
|
135
|
+
*/
|
|
136
|
+
export declare function extractPrNumber(message: string): number | null;
|
|
137
|
+
/**
|
|
138
|
+
* If `remoteUrl` is a GitHub URL (HTTPS or SSH), return the matching
|
|
139
|
+
* `https://github.com/<owner>/<repo>/pull/<n>` URL for a PR number.
|
|
140
|
+
* Returns null for non-GitHub remotes so we don't fabricate links to
|
|
141
|
+
* GitLab/Bitbucket/etc.
|
|
142
|
+
*/
|
|
143
|
+
export declare function githubPrUrl(remoteUrl: string | null, prNumber: number): string | null;
|
|
144
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/indexer/git.ts"],"names":[],"mappings":"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"}
|