@titan-design/code-graph 0.9.1 → 0.10.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/README.md CHANGED
@@ -271,6 +271,16 @@ snapshots and buckets each violation as new, resolved, or unchanged; unchanged m
271
271
  violations are further split into worsened and improved by value. From-side ids follow the
272
272
  alias chain, as in the ratchet.
273
273
 
274
+ `computeFootprints({ nodes, edges }, options)` gives each symbol node a footprint built from
275
+ structural inputs only, so a moved declaration or a churn window never reads as a change. It
276
+ has three parts, each a `hashText` over canonical JSON: `signature` (name, exported, signature,
277
+ purpose; no span), `consumers` (sorted distinct files with a `references` edge into the symbol),
278
+ and `coupling` (sorted co-import partners at or above `minCoImports`, default 2). `hash` combines
279
+ the three. Consumers include test files unless `ignoreConsumer(fileId)` rejects them; a rejected
280
+ file is dropped from coupling too. `symbolSetHash({ unitId, symbolIds }, footprints)` hashes a
281
+ doc unit's sorted `[symbolId, footprint.hash]` pairs, so it ignores member order and changes when
282
+ a member is added, removed or changed.
283
+
274
284
  `scripts/dag-check-self.mjs` in the repo root runs this repo's DAG check on this engine
275
285
  instead of codewatch's CLI.
276
286
 
package/dist/index.d.ts CHANGED
@@ -1470,6 +1470,47 @@ interface DiffCheckResultsOptions {
1470
1470
  */
1471
1471
  declare function diffCheckResults(store: CodeGraphStore, options: DiffCheckResultsOptions): CheckDiff;
1472
1472
 
1473
+ /**
1474
+ * A symbol's documentable footprint (C-75): structural inputs only, so a moved declaration,
1475
+ * a churn window or a centrality shift never reads as a change.
1476
+ */
1477
+ interface FootprintParts {
1478
+ /** Hash of `{name, exported, signature, purpose}`; no span. */
1479
+ signature: string;
1480
+ /** Hash of the sorted distinct file ids that reference the symbol. */
1481
+ consumers: string;
1482
+ /** Hash of the sorted co-import partner symbol ids at or above `minCoImports`. */
1483
+ coupling: string;
1484
+ }
1485
+ interface SymbolFootprint {
1486
+ symbolId: string;
1487
+ parts: FootprintParts;
1488
+ /** Hash of the three part hashes. */
1489
+ hash: string;
1490
+ }
1491
+ interface FootprintGraph {
1492
+ nodes: readonly GraphNode[];
1493
+ edges: readonly GraphEdge[];
1494
+ }
1495
+ interface FootprintOptions {
1496
+ /** Drop a referencing file from consumers and co-import coupling, e.g. test files. Default keeps all. */
1497
+ ignoreConsumer?: (fileId: string) => boolean;
1498
+ /** Co-import threshold for a coupling partner. Default 2. */
1499
+ minCoImports?: number;
1500
+ }
1501
+ /** A doc target: the default unit is one file holding its symbols. */
1502
+ interface FootprintUnit {
1503
+ unitId: string;
1504
+ symbolIds: readonly string[];
1505
+ }
1506
+ /** Footprint of every symbol node in the graph, keyed by symbol id. */
1507
+ declare function computeFootprints(graph: FootprintGraph, options?: FootprintOptions): Map<string, SymbolFootprint>;
1508
+ /**
1509
+ * Order-independent hash of a unit's `[symbolId, footprint.hash]` pairs. A member with no
1510
+ * footprint hashes as null, so a symbol that disappears still changes the set.
1511
+ */
1512
+ declare function symbolSetHash(unit: FootprintUnit, footprints: ReadonlyMap<string, SymbolFootprint>): string;
1513
+
1473
1514
  interface EmbeddableSymbol {
1474
1515
  id: string;
1475
1516
  name: string;
@@ -1686,4 +1727,4 @@ declare function getConventionMap(store: CodeGraphStore, snapshotId: number, mod
1686
1727
  */
1687
1728
  declare function findConventions(store: CodeGraphStore, snapshotId: number, query: string, embedder: Embedder, model: string, opts?: FindConventionsOptions): Promise<ConventionQueryResult>;
1688
1729
 
1689
- export { ALIAS_BASE_ATTR, ALL_ROLES, type AliasChain, type AliasChainInput, type AliasChainOptions, type AliasLoader, type AliasResolution, COMMUNITY_SUMMARY_NAMESPACE, COVERAGE_METRIC_NAME, type CachedEmbedResult, type CheckDiff, type CheckResult, type CheckRule, type CheckRulesFile, type CheckSnapshotOptions, type CheckSnapshotResult, type CheckViolation, CodeGraphStore, type ConventionArea, type ConventionCorpus, type ConventionCoverage, type ConventionMap, type ConventionMatch, type ConventionOptions, type ConventionQueryResult, type ConventionSymbol, DEAD_CODE_METRIC_NAMES, DEFAULT_CHURN_WINDOWS, DEFAULT_OUTLIER_MIN_SAMPLE, DOMAIN_DDL, type DeepAst, type DeepAstInput, type DiffCheckResultsOptions, type DiffSnapshotsOptions, EXCEPTION_METRIC_NAMES, type EdgeKind, type EmbedAttempt, type EmbedCoverage, type EmbedSnapshotResult, type EmbeddableSymbol, type ExternalDiagnostic, FINDING_DDL, type FileFingerprint, type FindConventionsOptions, type FindSimilarOptions, type Finding, type FindingKeyInput, type ForbidImportRule, GROWTH_RISK_METRIC_NAMES, type GraphDiff, type GraphDiffSummary, type GraphEdge, type GraphFragment, type GraphMetric, type GraphNode, type HistoryMetricsOptions, INDEX_VERSION, type IdAlias, type IdAliasReason, type IndexOptions, type IndexResult, type IstanbulCoverage, KIT, LanguageExtractor, type LanguageExtractorOptions, type LayeredDepsRule, type LineSpan, type Lineage, type LineageSnapshot, type LineageStep, type LinkMethod, type LinkTestsOptions, type LoadedHistory, METRIC_CATALOGUE, MIGRATIONS, type MemberInfo, type MetricAbsence, type MetricAggregate, type MetricDelta, type MetricDescriptor, type MetricDirection, type MetricMaxRule, type MetricMinRule, type MetricOutlierRule, type MetricProductMaxRule, type MetricRollup, type MetricSource, type MetricUnit, type NoInternalOnlyBarrelsRule, type NodeKind, type NodeRename, type NodeRole, type PackageFlag, type PackageLayer, type PackageStats, type PageRankOptions, type PageRankResult, type PageRankRow, type PairCoupling, type PairFlag, type ParamInfo, type PartitionQualityInput, type PartitionQualityResult, type PriorSnapshotOptions, type PruneOptions, type PrunePlan, type PruneResult, PythonGraphExtractor, type ReadFile, type ReferenceEdgeLite, type RelevanceOptions, type ResolveAliasOptions, type ReuseBasis, type RuleStore, type RunChecksOptions, SCHEMA_VERSION, SNAPSHOT_SCOPED_TABLES, SOURCE_METRIC_NAMES, SYMBOL_EMBEDDING_NAMESPACE, SYMBOL_ID_SEP, SYMBOL_METRIC_NAMES, type Severity, type SimilarCandidate, type SimilarResult, type SnapshotInsert, type SnapshotRow, type SnapshotSpec, type SourceLanguage, type StoredFinding, type StoredVerdict, type SummarizeConventionsResult, type Summarizer, type SymbolConsumers, type SymbolCouplingOptions, type SymbolCouplingPair, type SymbolSpan, type TestCoverageOwnershipOptions, type TestSourceLink, type TopMetricRow, TsMorphGraphExtractor, type TsMorphGraphExtractorOptions, type UnchangedViolation, type ValidateRulesOptions, type VerdictCitation, type VerdictLabel, aggregateMetrics, aliasChain, annotateRoles, attributeCoverage, buildAliases, buildConventionAreas, buildEmbedText, buildFileModuleNodes, buildIndexerMetrics, buildLineage, canonicalEdgeKind, canonicalMetricName, canonicalRole, carryForwardVerdicts, checkSnapshot, classifyRole, collectDeclaredNames, collectDeclaredSpans, compilePatterns, computeDeadCodeMetrics, computeDeepAst, computeGrowthRiskMetrics, computeMetrics, computePageRank, computePartitionQuality, computeRecencyWindows, computeRelevance, computeRoleHints, computeSourceMetrics, computeSymbolConsumers, computeSymbolCoupling, computeTestCoverageOwnership, createAliasChain, defaultTargetCount, describeMetric, describeMetrics, detectCommunities, detectGitHead, detectGitToplevel, detectRenames, diffCheckResults, diffSnapshots, edgeWeight, embedSnapshot, embedTextsCached, externalId, externalToFinding, fileId, findConventions, findSimilarCapability, findingKey, getConventionMap, getEdgeWeight, groupTestsBySource, hashContent, hashEmbedText, hashText, indexPaths, invertBuckets, isGeneratedByHeuristic, isGeneratedFile, isInsideGitRepo, keyFindings, lineagePath, linkTestsToSources, listEdges, listEdgesTouching, listEmbeddableSymbols, listFindings, listMetrics, listMetricsForNode, listNodes, listVerdicts, loadCheckRules, loadGeneratedPatterns, loadHistoryMetrics, loadLineage, matchesAny, moduleId, normalizeFlaggedText, openCodeGraph, packageId, parentModuleId, parseSymbolId, patternToRegex, percentileOf, planPrune, priorSnapshotForRef, pruneDanglingReferences, readSourceFiles, rebasedViolationKey, resolveAlias, resolveBarrelEdges, resolveChurnWindows, resolveGitRef, resolveSnapshot, runChecks, runPrune, saveFindings, saveVerdicts, snapshotPageRank, snapshotReferenceEdges, snapshotRelevance, snapshotSymbolConsumers, snapshotSymbolCoupling, snapshotViolations, structuralSignature, summarizeConventions, symbolId, testCoverageCountMetrics, toFindings, tryEmbedSnapshot, validateRules, violationKey, walkSourceFiles, windowSuffix };
1730
+ export { ALIAS_BASE_ATTR, ALL_ROLES, type AliasChain, type AliasChainInput, type AliasChainOptions, type AliasLoader, type AliasResolution, COMMUNITY_SUMMARY_NAMESPACE, COVERAGE_METRIC_NAME, type CachedEmbedResult, type CheckDiff, type CheckResult, type CheckRule, type CheckRulesFile, type CheckSnapshotOptions, type CheckSnapshotResult, type CheckViolation, CodeGraphStore, type ConventionArea, type ConventionCorpus, type ConventionCoverage, type ConventionMap, type ConventionMatch, type ConventionOptions, type ConventionQueryResult, type ConventionSymbol, DEAD_CODE_METRIC_NAMES, DEFAULT_CHURN_WINDOWS, DEFAULT_OUTLIER_MIN_SAMPLE, DOMAIN_DDL, type DeepAst, type DeepAstInput, type DiffCheckResultsOptions, type DiffSnapshotsOptions, EXCEPTION_METRIC_NAMES, type EdgeKind, type EmbedAttempt, type EmbedCoverage, type EmbedSnapshotResult, type EmbeddableSymbol, type ExternalDiagnostic, FINDING_DDL, type FileFingerprint, type FindConventionsOptions, type FindSimilarOptions, type Finding, type FindingKeyInput, type FootprintGraph, type FootprintOptions, type FootprintParts, type FootprintUnit, type ForbidImportRule, GROWTH_RISK_METRIC_NAMES, type GraphDiff, type GraphDiffSummary, type GraphEdge, type GraphFragment, type GraphMetric, type GraphNode, type HistoryMetricsOptions, INDEX_VERSION, type IdAlias, type IdAliasReason, type IndexOptions, type IndexResult, type IstanbulCoverage, KIT, LanguageExtractor, type LanguageExtractorOptions, type LayeredDepsRule, type LineSpan, type Lineage, type LineageSnapshot, type LineageStep, type LinkMethod, type LinkTestsOptions, type LoadedHistory, METRIC_CATALOGUE, MIGRATIONS, type MemberInfo, type MetricAbsence, type MetricAggregate, type MetricDelta, type MetricDescriptor, type MetricDirection, type MetricMaxRule, type MetricMinRule, type MetricOutlierRule, type MetricProductMaxRule, type MetricRollup, type MetricSource, type MetricUnit, type NoInternalOnlyBarrelsRule, type NodeKind, type NodeRename, type NodeRole, type PackageFlag, type PackageLayer, type PackageStats, type PageRankOptions, type PageRankResult, type PageRankRow, type PairCoupling, type PairFlag, type ParamInfo, type PartitionQualityInput, type PartitionQualityResult, type PriorSnapshotOptions, type PruneOptions, type PrunePlan, type PruneResult, PythonGraphExtractor, type ReadFile, type ReferenceEdgeLite, type RelevanceOptions, type ResolveAliasOptions, type ReuseBasis, type RuleStore, type RunChecksOptions, SCHEMA_VERSION, SNAPSHOT_SCOPED_TABLES, SOURCE_METRIC_NAMES, SYMBOL_EMBEDDING_NAMESPACE, SYMBOL_ID_SEP, SYMBOL_METRIC_NAMES, type Severity, type SimilarCandidate, type SimilarResult, type SnapshotInsert, type SnapshotRow, type SnapshotSpec, type SourceLanguage, type StoredFinding, type StoredVerdict, type SummarizeConventionsResult, type Summarizer, type SymbolConsumers, type SymbolCouplingOptions, type SymbolCouplingPair, type SymbolFootprint, type SymbolSpan, type TestCoverageOwnershipOptions, type TestSourceLink, type TopMetricRow, TsMorphGraphExtractor, type TsMorphGraphExtractorOptions, type UnchangedViolation, type ValidateRulesOptions, type VerdictCitation, type VerdictLabel, aggregateMetrics, aliasChain, annotateRoles, attributeCoverage, buildAliases, buildConventionAreas, buildEmbedText, buildFileModuleNodes, buildIndexerMetrics, buildLineage, canonicalEdgeKind, canonicalMetricName, canonicalRole, carryForwardVerdicts, checkSnapshot, classifyRole, collectDeclaredNames, collectDeclaredSpans, compilePatterns, computeDeadCodeMetrics, computeDeepAst, computeFootprints, computeGrowthRiskMetrics, computeMetrics, computePageRank, computePartitionQuality, computeRecencyWindows, computeRelevance, computeRoleHints, computeSourceMetrics, computeSymbolConsumers, computeSymbolCoupling, computeTestCoverageOwnership, createAliasChain, defaultTargetCount, describeMetric, describeMetrics, detectCommunities, detectGitHead, detectGitToplevel, detectRenames, diffCheckResults, diffSnapshots, edgeWeight, embedSnapshot, embedTextsCached, externalId, externalToFinding, fileId, findConventions, findSimilarCapability, findingKey, getConventionMap, getEdgeWeight, groupTestsBySource, hashContent, hashEmbedText, hashText, indexPaths, invertBuckets, isGeneratedByHeuristic, isGeneratedFile, isInsideGitRepo, keyFindings, lineagePath, linkTestsToSources, listEdges, listEdgesTouching, listEmbeddableSymbols, listFindings, listMetrics, listMetricsForNode, listNodes, listVerdicts, loadCheckRules, loadGeneratedPatterns, loadHistoryMetrics, loadLineage, matchesAny, moduleId, normalizeFlaggedText, openCodeGraph, packageId, parentModuleId, parseSymbolId, patternToRegex, percentileOf, planPrune, priorSnapshotForRef, pruneDanglingReferences, readSourceFiles, rebasedViolationKey, resolveAlias, resolveBarrelEdges, resolveChurnWindows, resolveGitRef, resolveSnapshot, runChecks, runPrune, saveFindings, saveVerdicts, snapshotPageRank, snapshotReferenceEdges, snapshotRelevance, snapshotSymbolConsumers, snapshotSymbolCoupling, snapshotViolations, structuralSignature, summarizeConventions, symbolId, symbolSetHash, testCoverageCountMetrics, toFindings, tryEmbedSnapshot, validateRules, violationKey, walkSourceFiles, windowSuffix };
package/dist/index.js CHANGED
@@ -1050,6 +1050,13 @@ function remapDistToSrc(abs) {
1050
1050
  }
1051
1051
  return abs;
1052
1052
  }
1053
+ function repoTypeRoots(repoRoot) {
1054
+ const roots = [];
1055
+ for (let dir = path3.resolve(repoRoot); ; dir = path3.dirname(dir)) {
1056
+ roots.push(path3.join(dir, "node_modules", "@types"));
1057
+ if (path3.dirname(dir) === dir) return roots;
1058
+ }
1059
+ }
1053
1060
 
1054
1061
  // src/extractors/reexport-resolve.ts
1055
1062
  function resolveReExportOrigin(ctx, importerAbs, specifier, name) {
@@ -1247,7 +1254,8 @@ var TsMorphGraphExtractor = class {
1247
1254
  allowJs: true,
1248
1255
  target: ScriptTarget.ESNext,
1249
1256
  module: ModuleKind.ESNext,
1250
- moduleResolution: ModuleResolutionKind.NodeNext
1257
+ moduleResolution: ModuleResolutionKind.NodeNext,
1258
+ typeRoots: repoTypeRoots(this.repoRoot)
1251
1259
  }
1252
1260
  });
1253
1261
  return this.project;
@@ -6199,6 +6207,63 @@ function computeDelta(from, to) {
6199
6207
  return to.value - from.value;
6200
6208
  }
6201
6209
 
6210
+ // src/diff/footprint.ts
6211
+ var DEFAULT_MIN_CO_IMPORTS2 = 2;
6212
+ function computeFootprints(graph, options = {}) {
6213
+ const edges = referenceEdges(graph.edges, options.ignoreConsumer);
6214
+ const consumers = consumersBySymbol(edges);
6215
+ const partners = partnersBySymbol(edges, options.minCoImports ?? DEFAULT_MIN_CO_IMPORTS2);
6216
+ const out = /* @__PURE__ */ new Map();
6217
+ for (const node of graph.nodes) {
6218
+ if (node.kind !== "symbol") continue;
6219
+ const parts = {
6220
+ signature: hashJson(signatureOf2(node)),
6221
+ consumers: hashJson(consumers.get(node.id) ?? []),
6222
+ coupling: hashJson(partners.get(node.id) ?? [])
6223
+ };
6224
+ const hash = hashJson([parts.signature, parts.consumers, parts.coupling]);
6225
+ out.set(node.id, { symbolId: node.id, parts, hash });
6226
+ }
6227
+ return out;
6228
+ }
6229
+ function symbolSetHash(unit, footprints) {
6230
+ const pairs = [...new Set(unit.symbolIds)].sort().map((id) => [id, footprints.get(id)?.hash ?? null]);
6231
+ return hashJson(pairs);
6232
+ }
6233
+ function hashJson(value) {
6234
+ return hashText(JSON.stringify(value));
6235
+ }
6236
+ function signatureOf2(node) {
6237
+ const attrs = node.attrs ?? {};
6238
+ return {
6239
+ name: node.name,
6240
+ exported: attrs.exported === true,
6241
+ signature: typeof attrs.signature === "string" ? attrs.signature : null,
6242
+ purpose: typeof attrs.purpose === "string" ? attrs.purpose : null
6243
+ };
6244
+ }
6245
+ function referenceEdges(edges, ignoreConsumer) {
6246
+ return edges.filter(
6247
+ (e) => canonicalEdgeKind(e.kind) === "references" && !ignoreConsumer?.(e.srcId)
6248
+ );
6249
+ }
6250
+ function consumersBySymbol(edges) {
6251
+ return new Map(computeSymbolConsumers(edges).map((c) => [c.symbolId, c.consumers]));
6252
+ }
6253
+ function partnersBySymbol(edges, minCoImports) {
6254
+ const partners = /* @__PURE__ */ new Map();
6255
+ const add = (from, to) => {
6256
+ const set = partners.get(from) ?? /* @__PURE__ */ new Set();
6257
+ set.add(to);
6258
+ partners.set(from, set);
6259
+ };
6260
+ for (const pair of computeSymbolCoupling(edges, { minCoImports })) {
6261
+ add(pair.aId, pair.bId);
6262
+ add(pair.bId, pair.aId);
6263
+ }
6264
+ return new Map([...partners].map(([id, set]) => [id, [...set].sort()]));
6265
+ }
6266
+
6202
6267
  // src/embeddings/corpus.ts
6203
6268
  import { contentHashOf } from "@titan-design/store-sqlite";
6204
6269
  function buildEmbedText(signature, purpose) {
@@ -6697,6 +6762,7 @@ export {
6697
6762
  compilePatterns,
6698
6763
  computeDeadCodeMetrics,
6699
6764
  computeDeepAst,
6765
+ computeFootprints,
6700
6766
  computeGrowthRiskMetrics,
6701
6767
  computeMetrics,
6702
6768
  computePageRank,
@@ -6789,6 +6855,7 @@ export {
6789
6855
  structuralSignature,
6790
6856
  summarizeConventions,
6791
6857
  symbolId,
6858
+ symbolSetHash,
6792
6859
  testCoverageCountMetrics,
6793
6860
  toFindings,
6794
6861
  tryEmbedSnapshot,