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
|
+
/**
|
|
3
|
+
* v10 — Symbol Rename/Move Continuity heuristics.
|
|
4
|
+
*
|
|
5
|
+
* Goal: when exact `symbol_key` history walking terminates (because the
|
|
6
|
+
* function was renamed or moved), surface honest, confidence-labelled
|
|
7
|
+
* continuity evidence so the agent can decide whether to trust the link.
|
|
8
|
+
*
|
|
9
|
+
* Heuristics (current pass — opt-in, low-confidence by default):
|
|
10
|
+
* - shape_hash exact match: previous-symbol candidate has the same
|
|
11
|
+
* structural SimHash → strong (confidence 0.85+)
|
|
12
|
+
* - shape_hash close match: small Hamming distance (≤ 4) + similar name
|
|
13
|
+
* → medium (confidence 0.65)
|
|
14
|
+
* - signature similarity: same arity + same containing class/module
|
|
15
|
+
* → weak (confidence 0.5)
|
|
16
|
+
* - same file rename history: file was renamed in git history, the
|
|
17
|
+
* historical file had a same-shape function with a different name → boost
|
|
18
|
+
* (confidence 0.75)
|
|
19
|
+
*
|
|
20
|
+
* Stored on `symbol_history_continuity`. Never pretends rename continuity
|
|
21
|
+
* is certain.
|
|
22
|
+
*
|
|
23
|
+
* This module does NOT replace existing exact-key history. It only proposes
|
|
24
|
+
* additional links when buildSymbolHistory's exact-key walk ran out of
|
|
25
|
+
* commits. The Preflight / seer_history layers can read continuity rows
|
|
26
|
+
* alongside symbol_history.
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.buildContinuity = buildContinuity;
|
|
30
|
+
exports.getContinuityForSymbol = getContinuityForSymbol;
|
|
31
|
+
/**
|
|
32
|
+
* Run the continuity pass over every symbol whose recorded history has
|
|
33
|
+
* fewer than `historyThreshold` commits AND that has a shape_hash. For each
|
|
34
|
+
* such symbol we scan other symbols sharing a close shape_hash and propose
|
|
35
|
+
* the highest-confidence candidate (deduped per symbol_id).
|
|
36
|
+
*/
|
|
37
|
+
function buildContinuity(store, options = {}) {
|
|
38
|
+
const start = Date.now();
|
|
39
|
+
const log = options.log ?? (() => { });
|
|
40
|
+
const historyThreshold = options.historyThreshold ?? 1;
|
|
41
|
+
const maxHamming = options.maxHammingDistance ?? 4;
|
|
42
|
+
// Pool of candidates: every symbol with a shape_hash.
|
|
43
|
+
const pool = store.listSymbolsWithShapeHash({ minLoc: 1, limit: 100000 });
|
|
44
|
+
if (pool.length === 0) {
|
|
45
|
+
log('no shape-hashed symbols; nothing to do');
|
|
46
|
+
return { candidatesConsidered: 0, inserted: 0, skipped: 0, elapsedMs: Date.now() - start };
|
|
47
|
+
}
|
|
48
|
+
// Bucket by qualifiedName/name → list of candidates (so we can detect
|
|
49
|
+
// rename: same shape, different name).
|
|
50
|
+
const byHash = new Map();
|
|
51
|
+
for (const s of pool) {
|
|
52
|
+
const k = s.shapeHash.toString();
|
|
53
|
+
const list = byHash.get(k) ?? [];
|
|
54
|
+
list.push(s);
|
|
55
|
+
byHash.set(k, list);
|
|
56
|
+
}
|
|
57
|
+
let considered = 0;
|
|
58
|
+
let inserted = 0;
|
|
59
|
+
let skipped = 0;
|
|
60
|
+
const raw = store.rawDb();
|
|
61
|
+
for (const s of pool) {
|
|
62
|
+
// Find the symbol's stored history count. If it's >= historyThreshold
|
|
63
|
+
// AND we're not in includeAllSymbols mode, skip — exact history is fine.
|
|
64
|
+
if (!options.includeAllSymbols) {
|
|
65
|
+
const cnt = raw.prepare('SELECT COUNT(*) AS c FROM symbol_history WHERE symbol_id = ?').get(s.id);
|
|
66
|
+
if (cnt && cnt.c >= historyThreshold)
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
// Exact shape match candidates with a DIFFERENT (qualifiedName ?? name).
|
|
70
|
+
const exactMatches = (byHash.get(s.shapeHash.toString()) ?? [])
|
|
71
|
+
.filter(c => c.id !== s.id);
|
|
72
|
+
if (exactMatches.length > 0) {
|
|
73
|
+
const cand = pickBestCandidate(s, exactMatches);
|
|
74
|
+
if (cand) {
|
|
75
|
+
const sameClass = sharesContainingScope(s, cand);
|
|
76
|
+
const nameRelated = similarName(s.name, cand.name);
|
|
77
|
+
// How many OTHER symbols share this exact shape? A shape shared by many
|
|
78
|
+
// symbols (trivial getters, `return null;`, boilerplate) is NOT a
|
|
79
|
+
// reliable rename signal on its own. Only assert a high-confidence link
|
|
80
|
+
// when the shape is (near-)unique to this pair; otherwise require
|
|
81
|
+
// corroboration (same scope or a related name) and label the ambiguity
|
|
82
|
+
// honestly with a lower, capped confidence. Never pretend certainty.
|
|
83
|
+
const ambiguous = exactMatches.length >= 2;
|
|
84
|
+
if (ambiguous && !sameClass && !nameRelated) {
|
|
85
|
+
// Common shape, no corroborating evidence — do not invent a rename.
|
|
86
|
+
skipped++;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
considered++;
|
|
90
|
+
const reasons = ['shape_hash_exact'];
|
|
91
|
+
if (sameClass)
|
|
92
|
+
reasons.push('same_containing_scope');
|
|
93
|
+
if (nameRelated)
|
|
94
|
+
reasons.push('similar_name');
|
|
95
|
+
let confidence;
|
|
96
|
+
if (ambiguous) {
|
|
97
|
+
reasons.push(`ambiguous_shape_bucket:n=${exactMatches.length + 1}`);
|
|
98
|
+
confidence = 0.6;
|
|
99
|
+
if (sameClass)
|
|
100
|
+
confidence = Math.min(0.7, confidence + 0.05);
|
|
101
|
+
if (nameRelated)
|
|
102
|
+
confidence = Math.min(0.7, confidence + 0.05);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
confidence = 0.85;
|
|
106
|
+
if (sameClass)
|
|
107
|
+
confidence = Math.min(0.95, confidence + 0.05);
|
|
108
|
+
if (nameRelated)
|
|
109
|
+
confidence = Math.min(0.95, confidence + 0.05);
|
|
110
|
+
}
|
|
111
|
+
upsertContinuity(store, {
|
|
112
|
+
symbolId: s.id,
|
|
113
|
+
symbolKey: keyFor(s),
|
|
114
|
+
previousSymbolKey: keyFor(cand),
|
|
115
|
+
previousName: cand.name,
|
|
116
|
+
previousFile: cand.filePath,
|
|
117
|
+
confidence,
|
|
118
|
+
matchReasons: reasons,
|
|
119
|
+
});
|
|
120
|
+
inserted++;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Close hash match.
|
|
125
|
+
let best = null;
|
|
126
|
+
for (const peer of pool) {
|
|
127
|
+
if (peer.id === s.id)
|
|
128
|
+
continue;
|
|
129
|
+
if ((peer.name === s.name) && (peer.qualifiedName === s.qualifiedName))
|
|
130
|
+
continue;
|
|
131
|
+
const d = hammingDistance(s.shapeHash, peer.shapeHash);
|
|
132
|
+
if (d > maxHamming)
|
|
133
|
+
continue;
|
|
134
|
+
if (!best || d < best.distance)
|
|
135
|
+
best = { peer, distance: d };
|
|
136
|
+
}
|
|
137
|
+
if (best && best.distance <= maxHamming) {
|
|
138
|
+
const cand = best.peer;
|
|
139
|
+
// Only act when names are at least loosely related (share a prefix or
|
|
140
|
+
// a suffix), to avoid pairing every short function in the codebase.
|
|
141
|
+
if (similarName(s.name, cand.name) || sharesContainingScope(s, cand)) {
|
|
142
|
+
considered++;
|
|
143
|
+
const reasons = [`shape_hash_close:d=${best.distance}`];
|
|
144
|
+
if (similarName(s.name, cand.name))
|
|
145
|
+
reasons.push('similar_name');
|
|
146
|
+
if (sharesContainingScope(s, cand))
|
|
147
|
+
reasons.push('same_containing_scope');
|
|
148
|
+
const confidence = best.distance === 0 ? 0.8
|
|
149
|
+
: best.distance <= 2 ? 0.6
|
|
150
|
+
: 0.4;
|
|
151
|
+
upsertContinuity(store, {
|
|
152
|
+
symbolId: s.id,
|
|
153
|
+
symbolKey: keyFor(s),
|
|
154
|
+
previousSymbolKey: keyFor(cand),
|
|
155
|
+
previousName: cand.name,
|
|
156
|
+
previousFile: cand.filePath,
|
|
157
|
+
confidence,
|
|
158
|
+
matchReasons: reasons,
|
|
159
|
+
});
|
|
160
|
+
inserted++;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
skipped++;
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
candidatesConsidered: considered,
|
|
168
|
+
inserted, skipped,
|
|
169
|
+
elapsedMs: Date.now() - start,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function upsertContinuity(store, c) {
|
|
173
|
+
const raw = store.rawDb();
|
|
174
|
+
raw.prepare(`
|
|
175
|
+
INSERT INTO symbol_history_continuity
|
|
176
|
+
(symbol_id, symbol_key, previous_symbol_key, previous_name, previous_file,
|
|
177
|
+
bridging_sha, confidence, match_reasons, recorded_at)
|
|
178
|
+
VALUES (?, ?, ?, ?, ?, NULL, ?, ?, ?)
|
|
179
|
+
ON CONFLICT(symbol_id, previous_symbol_key) DO UPDATE SET
|
|
180
|
+
confidence = excluded.confidence,
|
|
181
|
+
match_reasons = excluded.match_reasons,
|
|
182
|
+
previous_name = excluded.previous_name,
|
|
183
|
+
previous_file = excluded.previous_file,
|
|
184
|
+
recorded_at = excluded.recorded_at
|
|
185
|
+
`).run(c.symbolId, c.symbolKey, c.previousSymbolKey, c.previousName, c.previousFile, c.confidence, JSON.stringify(c.matchReasons), Date.now());
|
|
186
|
+
}
|
|
187
|
+
function keyFor(s) {
|
|
188
|
+
return `${s.kind}:${s.qualifiedName ?? s.name}`;
|
|
189
|
+
}
|
|
190
|
+
function sharesContainingScope(a, b) {
|
|
191
|
+
if (a.filePath === b.filePath)
|
|
192
|
+
return true;
|
|
193
|
+
// Compare class/module prefix in the qualified name (e.g. `AuthService.foo`
|
|
194
|
+
// and `AuthService.bar` share `AuthService`).
|
|
195
|
+
const aQual = a.qualifiedName ?? '';
|
|
196
|
+
const bQual = b.qualifiedName ?? '';
|
|
197
|
+
if (!aQual.includes('.') || !bQual.includes('.'))
|
|
198
|
+
return false;
|
|
199
|
+
const aPrefix = aQual.split('.').slice(0, -1).join('.');
|
|
200
|
+
const bPrefix = bQual.split('.').slice(0, -1).join('.');
|
|
201
|
+
return aPrefix.length > 0 && aPrefix === bPrefix;
|
|
202
|
+
}
|
|
203
|
+
function similarName(a, b) {
|
|
204
|
+
if (!a || !b)
|
|
205
|
+
return false;
|
|
206
|
+
if (a === b)
|
|
207
|
+
return false; // we only flag potential RENAMES
|
|
208
|
+
const aL = a.toLowerCase();
|
|
209
|
+
const bL = b.toLowerCase();
|
|
210
|
+
// Same prefix of length >= 4 or same suffix of length >= 4.
|
|
211
|
+
const minLen = Math.min(aL.length, bL.length);
|
|
212
|
+
if (minLen < 4)
|
|
213
|
+
return false;
|
|
214
|
+
let prefix = 0;
|
|
215
|
+
while (prefix < minLen && aL[prefix] === bL[prefix])
|
|
216
|
+
prefix++;
|
|
217
|
+
if (prefix >= 4)
|
|
218
|
+
return true;
|
|
219
|
+
let suffix = 0;
|
|
220
|
+
while (suffix < minLen && aL[aL.length - 1 - suffix] === bL[bL.length - 1 - suffix])
|
|
221
|
+
suffix++;
|
|
222
|
+
if (suffix >= 4)
|
|
223
|
+
return true;
|
|
224
|
+
// Names that differ by a verb prefix swap (validate → verify) — drop the
|
|
225
|
+
// first 4 characters and compare the rest.
|
|
226
|
+
if (aL.length >= 4 && bL.length >= 4 && aL.slice(4) === bL.slice(4))
|
|
227
|
+
return true;
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
function pickBestCandidate(target, candidates) {
|
|
231
|
+
// Prefer same-file rename. Then same-class rename. Then any candidate.
|
|
232
|
+
const sameFile = candidates.filter(c => c.filePath === target.filePath);
|
|
233
|
+
if (sameFile.length > 0)
|
|
234
|
+
return sameFile[0];
|
|
235
|
+
const sameClass = candidates.filter(c => sharesContainingScope(target, c));
|
|
236
|
+
if (sameClass.length > 0)
|
|
237
|
+
return sameClass[0];
|
|
238
|
+
return candidates[0] ?? null;
|
|
239
|
+
}
|
|
240
|
+
function hammingDistance(a, b) {
|
|
241
|
+
let x = a ^ b;
|
|
242
|
+
let n = 0;
|
|
243
|
+
while (x !== 0n) {
|
|
244
|
+
x &= x - 1n;
|
|
245
|
+
n++;
|
|
246
|
+
}
|
|
247
|
+
return n;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Fetch continuity rows for a given symbol id, ordered by confidence desc.
|
|
251
|
+
*/
|
|
252
|
+
function getContinuityForSymbol(store, symbolId) {
|
|
253
|
+
if (!store.hasV10())
|
|
254
|
+
return [];
|
|
255
|
+
try {
|
|
256
|
+
const rows = store.rawDb().prepare(`
|
|
257
|
+
SELECT previous_symbol_key AS previousSymbolKey,
|
|
258
|
+
previous_name AS previousName,
|
|
259
|
+
previous_file AS previousFile,
|
|
260
|
+
confidence, match_reasons AS matchReasons
|
|
261
|
+
FROM symbol_history_continuity
|
|
262
|
+
WHERE symbol_id = ?
|
|
263
|
+
ORDER BY confidence DESC, id DESC
|
|
264
|
+
`).all(symbolId);
|
|
265
|
+
return rows.map(r => ({
|
|
266
|
+
previousSymbolKey: String(r.previousSymbolKey),
|
|
267
|
+
previousName: String(r.previousName ?? ''),
|
|
268
|
+
previousFile: String(r.previousFile ?? ''),
|
|
269
|
+
confidence: Number(r.confidence ?? 0),
|
|
270
|
+
matchReasons: parseReasons(r.matchReasons),
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function parseReasons(v) {
|
|
278
|
+
if (typeof v !== 'string')
|
|
279
|
+
return [];
|
|
280
|
+
try {
|
|
281
|
+
const parsed = JSON.parse(v);
|
|
282
|
+
return Array.isArray(parsed) ? parsed.map(String) : [];
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=continuity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuity.js","sourceRoot":"","sources":["../../src/indexer/continuity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Store } from '../db/store.js';
|
|
2
|
+
import type { SymbolRow } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Compute the blast radius of an uncommitted (or between-refs) diff. For each
|
|
5
|
+
* changed file we identify the symbols whose line ranges overlap the diff
|
|
6
|
+
* hunks, then expand by N levels of reverse callers (transitive callers,
|
|
7
|
+
* because they're the code most likely to break).
|
|
8
|
+
*/
|
|
9
|
+
export interface ChangedSymbol {
|
|
10
|
+
symbol: SymbolRow;
|
|
11
|
+
hunkCount: number;
|
|
12
|
+
}
|
|
13
|
+
export interface DetectChangesResult {
|
|
14
|
+
fromRef: string | null;
|
|
15
|
+
toRef: string | null;
|
|
16
|
+
changedFiles: Array<{
|
|
17
|
+
path: string;
|
|
18
|
+
hunks: number;
|
|
19
|
+
symbols: ChangedSymbol[];
|
|
20
|
+
}>;
|
|
21
|
+
/** Direct changed symbols (the inner symbols in `changedFiles`). */
|
|
22
|
+
directlyChanged: SymbolRow[];
|
|
23
|
+
/** Transitive callers of the directly-changed set (deduped). */
|
|
24
|
+
transitivelyAffected: SymbolRow[];
|
|
25
|
+
elapsedMs: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function detectChanges(repoRoot: string, store: Store, options?: {
|
|
28
|
+
fromRef?: string;
|
|
29
|
+
toRef?: string;
|
|
30
|
+
callerDepth?: number;
|
|
31
|
+
}): DetectChangesResult;
|
|
32
|
+
//# sourceMappingURL=detectchanges.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detectchanges.d.ts","sourceRoot":"","sources":["../../src/indexer/detectchanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;GAKG;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC,CAAC;IAC/E,oEAAoE;IACpE,eAAe,EAAE,SAAS,EAAE,CAAC;IAC7B,gEAAgE;IAChE,oBAAoB,EAAE,SAAS,EAAE,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAC9B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACvE,mBAAmB,CA0DrB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectChanges = detectChanges;
|
|
4
|
+
const git_js_1 = require("./git.js");
|
|
5
|
+
function detectChanges(repoRoot, store, options = {}) {
|
|
6
|
+
const start = Date.now();
|
|
7
|
+
const callerDepth = options.callerDepth ?? 2;
|
|
8
|
+
const fromRef = options.fromRef ?? null;
|
|
9
|
+
const toRef = options.toRef ?? null;
|
|
10
|
+
if (!(0, git_js_1.isGitRepo)(repoRoot)) {
|
|
11
|
+
return { fromRef, toRef, changedFiles: [], directlyChanged: [], transitivelyAffected: [], elapsedMs: Date.now() - start };
|
|
12
|
+
}
|
|
13
|
+
const files = (0, git_js_1.gitChangedFiles)(repoRoot, fromRef ?? undefined, toRef ?? undefined);
|
|
14
|
+
if (files.length === 0) {
|
|
15
|
+
return { fromRef, toRef, changedFiles: [], directlyChanged: [], transitivelyAffected: [], elapsedMs: Date.now() - start };
|
|
16
|
+
}
|
|
17
|
+
const dbFiles = new Map(store.listFiles().map(f => [normalize(f.path), f.id]));
|
|
18
|
+
const changedFiles = [];
|
|
19
|
+
const directIds = new Set();
|
|
20
|
+
for (const abs of files) {
|
|
21
|
+
const fileId = dbFiles.get(normalize(abs));
|
|
22
|
+
if (fileId === undefined)
|
|
23
|
+
continue;
|
|
24
|
+
const hunks = (0, git_js_1.fileDiffHunksSync)(repoRoot, abs, fromRef ?? undefined, toRef ?? undefined);
|
|
25
|
+
if (hunks.length === 0)
|
|
26
|
+
continue;
|
|
27
|
+
// Convert 1-indexed git line ranges to 0-indexed Seer line ranges.
|
|
28
|
+
const ranges = hunks.map(h => [
|
|
29
|
+
Math.max(0, h.newStart - 1),
|
|
30
|
+
Math.max(0, h.newStart - 1 + Math.max(0, h.newLines - 1)),
|
|
31
|
+
]);
|
|
32
|
+
const syms = store.symbolsTouchingLines(fileId, ranges);
|
|
33
|
+
for (const s of syms)
|
|
34
|
+
directIds.add(s.id);
|
|
35
|
+
changedFiles.push({
|
|
36
|
+
path: abs,
|
|
37
|
+
hunks: hunks.length,
|
|
38
|
+
symbols: syms.map(s => ({ symbol: s, hunkCount: hunks.length })),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const directly = [];
|
|
42
|
+
for (const id of directIds) {
|
|
43
|
+
const s = store.getSymbolById(id);
|
|
44
|
+
if (s)
|
|
45
|
+
directly.push(s);
|
|
46
|
+
}
|
|
47
|
+
const transitiveIds = new Set();
|
|
48
|
+
for (const s of directly) {
|
|
49
|
+
for (const id of store.reverseReachable(s.id, callerDepth)) {
|
|
50
|
+
if (!directIds.has(id))
|
|
51
|
+
transitiveIds.add(id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const transitively = [];
|
|
55
|
+
for (const id of transitiveIds) {
|
|
56
|
+
const s = store.getSymbolById(id);
|
|
57
|
+
if (s)
|
|
58
|
+
transitively.push(s);
|
|
59
|
+
}
|
|
60
|
+
transitively.sort((a, b) => b.pagerank - a.pagerank);
|
|
61
|
+
return {
|
|
62
|
+
fromRef,
|
|
63
|
+
toRef,
|
|
64
|
+
changedFiles,
|
|
65
|
+
directlyChanged: directly,
|
|
66
|
+
transitivelyAffected: transitively,
|
|
67
|
+
elapsedMs: Date.now() - start,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function normalize(p) {
|
|
71
|
+
const n = p.replace(/\\/g, '/');
|
|
72
|
+
return process.platform === 'win32' ? n.toLowerCase() : n;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=detectchanges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detectchanges.js","sourceRoot":"","sources":["../../src/indexer/detectchanges.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface DiscoveredFile {
|
|
2
|
+
absolutePath: string;
|
|
3
|
+
relativePath: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Discovery mode controls how aggressively we filter directories/files before
|
|
7
|
+
* parsing. Modes are layered defaults — finer-grained `includeVendor` /
|
|
8
|
+
* `includeGenerated` toggles can still override the mode's vendor/generated
|
|
9
|
+
* decisions, and `.seerignore` rules apply on top of all of them.
|
|
10
|
+
*
|
|
11
|
+
* - `full` index everything we can parse (only build/meta and .git skipped)
|
|
12
|
+
* - `standard` skip vendor + generated by default (current historical default)
|
|
13
|
+
* - `fast` standard + skip docs/examples/static/assets/migrations — aimed
|
|
14
|
+
* at iterative agent loops where most non-source dirs are dead
|
|
15
|
+
* weight
|
|
16
|
+
*
|
|
17
|
+
* Default is `standard`; `fast` is a deliberate opt-in for power users on
|
|
18
|
+
* very large repos where they want indexing as cheap as possible.
|
|
19
|
+
*/
|
|
20
|
+
export type DiscoveryMode = 'full' | 'standard' | 'fast';
|
|
21
|
+
export interface DiscoveryOptions {
|
|
22
|
+
/**
|
|
23
|
+
* If true, vendored / generated directories that the default ignore list
|
|
24
|
+
* would skip are included in discovery. Vendored/generated classification
|
|
25
|
+
* still happens at index time — this just lets the user inspect what
|
|
26
|
+
* Seer would normally hide. Off by default; the README and master guide
|
|
27
|
+
* describe this as the "I really do want vendored code" escape hatch.
|
|
28
|
+
*/
|
|
29
|
+
includeVendor?: boolean;
|
|
30
|
+
includeGenerated?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Discovery aggressiveness. Defaults to 'standard'. See `DiscoveryMode`.
|
|
33
|
+
*/
|
|
34
|
+
mode?: DiscoveryMode;
|
|
35
|
+
}
|
|
36
|
+
export declare function discoverFiles(repoRoot: string, options?: DiscoveryOptions): Promise<DiscoveredFile[]>;
|
|
37
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/indexer/discovery.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAoED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAkE/G"}
|
|
@@ -0,0 +1,136 @@
|
|
|
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.discoverFiles = discoverFiles;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const ignore_1 = __importDefault(require("ignore"));
|
|
10
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
11
|
+
// Globally-skipped paths that are never source code (build outputs, IDE
|
|
12
|
+
// state, VCS metadata). These are unconditional — `includeVendor` /
|
|
13
|
+
// `includeGenerated` do NOT re-enable them. The user can override by adding
|
|
14
|
+
// a `!pattern` line in `.seerignore`.
|
|
15
|
+
const BUILD_AND_META_IGNORE = [
|
|
16
|
+
'node_modules', '.git', '.hg', '.svn',
|
|
17
|
+
'dist', 'build', 'out', '.next', '.nuxt', '__pycache__',
|
|
18
|
+
'*.min.js', '*.min.css', '*.bundle.js',
|
|
19
|
+
'*.lock', 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml',
|
|
20
|
+
// Build outputs across other ecosystems. `target/` is universally Rust
|
|
21
|
+
// (`cargo build`), `obj/` is .NET, `cmake-build-*` is JetBrains/CLion,
|
|
22
|
+
// `_build/` is Erlang/Elixir and some doc generators. Not adding `bin/`
|
|
23
|
+
// here — TypeScript-main and others keep entry scripts there.
|
|
24
|
+
'target/**', '**/target/**',
|
|
25
|
+
'obj/**', '**/obj/**',
|
|
26
|
+
'cmake-build-*/**', '**/cmake-build-*/**',
|
|
27
|
+
'_build/**', '**/_build/**',
|
|
28
|
+
'.gradle/**', '**/.gradle/**',
|
|
29
|
+
'.cache/**',
|
|
30
|
+
'.idea/**', '.vs/**',
|
|
31
|
+
// Unreal-specific build outputs (won't exist in a clean checkout but cheap
|
|
32
|
+
// to add defensively for users who built before indexing).
|
|
33
|
+
'Intermediate/**', '**/Intermediate/**',
|
|
34
|
+
'Saved/**', '**/Saved/**',
|
|
35
|
+
'DerivedDataCache/**',
|
|
36
|
+
];
|
|
37
|
+
// Vendored dependency roots — discovery-time skip by default, but classified
|
|
38
|
+
// even when included. Match both the top level and any nested depth (Godot
|
|
39
|
+
// uses `thirdparty/`, Unreal uses `Engine/Source/ThirdParty/`, etc.).
|
|
40
|
+
const VENDOR_IGNORE = [
|
|
41
|
+
'vendor/**', '**/vendor/**',
|
|
42
|
+
'vendored/**', '**/vendored/**',
|
|
43
|
+
'Vendored/**', '**/Vendored/**',
|
|
44
|
+
'third_party/**', '**/third_party/**',
|
|
45
|
+
'thirdparty/**', '**/thirdparty/**',
|
|
46
|
+
'ThirdParty/**', '**/ThirdParty/**',
|
|
47
|
+
];
|
|
48
|
+
// Generated-code patterns that don't earn a place in default indexing. Same
|
|
49
|
+
// "skip-by-default, classify-when-included" model as vendored code.
|
|
50
|
+
const GENERATED_IGNORE = [
|
|
51
|
+
'*.pb.go', '*.pb.ts', '*.pb.h', '*.pb.cc',
|
|
52
|
+
'*.generated.h', '*.gen.cpp', '*.gen.h',
|
|
53
|
+
];
|
|
54
|
+
// Extra skips active only under `--mode fast`. These directories rarely
|
|
55
|
+
// contain source code that contributes to the call graph — examples are
|
|
56
|
+
// either demos that re-import from src, docs/static/assets are non-code, and
|
|
57
|
+
// migrations are usually flat SQL or schema-only Python. Skipping them in
|
|
58
|
+
// fast mode trims discovery and parse cost meaningfully on large monorepos.
|
|
59
|
+
// Conservative on purpose: anything that might contain real call edges
|
|
60
|
+
// (`tests/`, `src/`, `lib/`) stays indexed even in fast mode.
|
|
61
|
+
const FAST_MODE_EXTRA_IGNORE = [
|
|
62
|
+
'docs/**', '**/docs/**',
|
|
63
|
+
'examples/**', '**/examples/**',
|
|
64
|
+
'example/**', '**/example/**',
|
|
65
|
+
'assets/**', '**/assets/**',
|
|
66
|
+
'static/**', '**/static/**',
|
|
67
|
+
'public/**', '**/public/**',
|
|
68
|
+
'media/**', '**/media/**',
|
|
69
|
+
'fixtures/**', '**/fixtures/**',
|
|
70
|
+
'testdata/**', '**/testdata/**',
|
|
71
|
+
'migrations/**', '**/migrations/**',
|
|
72
|
+
];
|
|
73
|
+
async function discoverFiles(repoRoot, options = {}) {
|
|
74
|
+
const absRoot = path_1.default.resolve(repoRoot);
|
|
75
|
+
const mode = options.mode ?? 'standard';
|
|
76
|
+
// `full` mode flips both include flags ON regardless of caller intent. We
|
|
77
|
+
// still honor explicit `includeVendor=false` from a caller, but the typical
|
|
78
|
+
// use of `--mode full` is "index literally everything", so the default
|
|
79
|
+
// there is to include them.
|
|
80
|
+
const includeVendor = options.includeVendor ?? (mode === 'full');
|
|
81
|
+
const includeGenerated = options.includeGenerated ?? (mode === 'full');
|
|
82
|
+
const skip = [...BUILD_AND_META_IGNORE];
|
|
83
|
+
if (!includeVendor)
|
|
84
|
+
skip.push(...VENDOR_IGNORE);
|
|
85
|
+
if (!includeGenerated)
|
|
86
|
+
skip.push(...GENERATED_IGNORE);
|
|
87
|
+
if (mode === 'fast')
|
|
88
|
+
skip.push(...FAST_MODE_EXTRA_IGNORE);
|
|
89
|
+
// Build ignore rules from .gitignore + optional .seerignore. The two are
|
|
90
|
+
// separate intentionally — .gitignore controls what's committed (often
|
|
91
|
+
// includes build outputs that we ALSO want hidden) while .seerignore is
|
|
92
|
+
// for repo-specific tweaks that don't belong in version control rules
|
|
93
|
+
// (e.g. "don't index our `examples/` folder").
|
|
94
|
+
const ig = (0, ignore_1.default)();
|
|
95
|
+
const gitignorePath = path_1.default.join(absRoot, '.gitignore');
|
|
96
|
+
if (fs_1.default.existsSync(gitignorePath)) {
|
|
97
|
+
ig.add(fs_1.default.readFileSync(gitignorePath, 'utf8'));
|
|
98
|
+
}
|
|
99
|
+
const seerignorePath = path_1.default.join(absRoot, '.seerignore');
|
|
100
|
+
if (fs_1.default.existsSync(seerignorePath)) {
|
|
101
|
+
ig.add(fs_1.default.readFileSync(seerignorePath, 'utf8'));
|
|
102
|
+
}
|
|
103
|
+
// Glob for source files in supported languages
|
|
104
|
+
const entries = await (0, fast_glob_1.default)([
|
|
105
|
+
'**/*.py', '**/*.pyw',
|
|
106
|
+
'**/*.ts', '**/*.tsx',
|
|
107
|
+
'**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs',
|
|
108
|
+
'**/*.go',
|
|
109
|
+
'**/*.java',
|
|
110
|
+
'**/*.rs',
|
|
111
|
+
'**/*.c',
|
|
112
|
+
'**/*.cpp', '**/*.cc', '**/*.cxx', '**/*.c++',
|
|
113
|
+
'**/*.hpp', '**/*.hh', '**/*.h++', '**/*.h',
|
|
114
|
+
'**/*.cs',
|
|
115
|
+
], {
|
|
116
|
+
cwd: absRoot,
|
|
117
|
+
ignore: skip,
|
|
118
|
+
onlyFiles: true,
|
|
119
|
+
followSymbolicLinks: false,
|
|
120
|
+
dot: false,
|
|
121
|
+
});
|
|
122
|
+
// Stable order across runs is a correctness requirement: file IDs are
|
|
123
|
+
// AUTOINCREMENT, and tests/scale invariants depend on the same input
|
|
124
|
+
// producing the same IDs. `fast-glob` on Windows returns files in MFT/
|
|
125
|
+
// FS-cache order, which is not stable run-to-run. Sort here so every
|
|
126
|
+
// downstream stage — the byte semaphore window, parser-worker dispatch,
|
|
127
|
+
// SQLite inserts — sees the same sequence on every invocation.
|
|
128
|
+
return entries
|
|
129
|
+
.filter(rel => !ig.ignores(rel))
|
|
130
|
+
.sort()
|
|
131
|
+
.map(rel => ({
|
|
132
|
+
absolutePath: path_1.default.join(absRoot, rel),
|
|
133
|
+
relativePath: rel,
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/indexer/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Store } from '../db/store.js';
|
|
2
|
+
/**
|
|
3
|
+
* Walk the repo for known package manifests and emit one row per declared
|
|
4
|
+
* dependency. Idempotent: clears `external_dependencies` and re-inserts every
|
|
5
|
+
* call, so deletions in package.json are reflected on the next index.
|
|
6
|
+
*
|
|
7
|
+
* Supported ecosystems:
|
|
8
|
+
* npm package.json / package-lock.json / pnpm-lock.yaml (deps only)
|
|
9
|
+
* cargo Cargo.toml (Cargo.lock not parsed — duplicates would be noisy)
|
|
10
|
+
* pypi requirements.txt, pyproject.toml (PEP 621 [project.dependencies])
|
|
11
|
+
* go go.mod
|
|
12
|
+
*
|
|
13
|
+
* Manifest discovery uses fast-glob with the same ignores as the rest of the
|
|
14
|
+
* indexer (no node_modules, no vendor) so monorepos can be picked up from
|
|
15
|
+
* `packages/foo/package.json`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractExternalDependencies(repoRoot: string, store: Store): Promise<number>;
|
|
18
|
+
//# sourceMappingURL=externaldeps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"externaldeps.d.ts","sourceRoot":"","sources":["../../src/indexer/externaldeps.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CjG"}
|