@titan-design/code-graph 0.6.0 → 0.7.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
@@ -28,7 +28,8 @@ In: the parser (tree-sitter WASM for TypeScript, TSX and Python, since moved to
28
28
  extractor and its symbol layer, role classification, generated-file detection, id aliasing
29
29
  across git renames, the three-tier incremental reuse, and the metrics computed at index time
30
30
  (degree, utilization, loc, cyclomatic, cognitive, nesting, class count, lcom4, and per
31
- symbol `symbol_cognitive`, `symbol_cyclomatic`, `symbol_loc` and `symbol_max_nesting`). `lcom.ts` came along despite being an analysis: `source-metrics.ts` calls it
31
+ symbol `symbol_cognitive`, `symbol_cyclomatic`, `symbol_loc`, `symbol_max_nesting`, and the
32
+ comment and shape metrics below). `lcom.ts` came along despite being an analysis: `source-metrics.ts` calls it
32
33
  directly and lcom4 is a pure function of a file's bytes, so it belongs with the metrics that
33
34
  carry forward under reuse.
34
35
 
@@ -222,9 +223,17 @@ the file is unreadable.
222
223
 
223
224
  ## Checks and diffs
224
225
 
225
- The rules engine turns a snapshot into pass/fail against a `check.json`. Six rule types:
226
- `metric-max`, `metric-min`, `metric-product-max`, `forbid-import`, `layered-deps`, and
227
- `no-internal-only-barrels`. Severity defaults to `error`; only new errors fail a check.
226
+ The rules engine turns a snapshot into pass/fail against a `check.json`. Seven rule types:
227
+ `metric-max`, `metric-min`, `metric-product-max`, `metric-outlier`, `forbid-import`,
228
+ `layered-deps`, and `no-internal-only-barrels`. Severity defaults to `error`; only new errors
229
+ fail a check.
230
+
231
+ `metric-outlier` takes its threshold from the snapshot instead of the rule:
232
+ `{ "type": "metric-outlier", "id": "long-fn", "metric": "symbol_body_lines", "kind": "symbol", "percentile": 95 }`
233
+ flags every symbol strictly above the 95th percentile of `symbol_body_lines` over all symbols
234
+ that carry it, interpolated linearly between ranks. `percentile` runs from 50 to 100. The rule
235
+ stays silent until `minSample` nodes (default 20) carry the metric. Each violation's
236
+ `threshold` is the computed percentile value.
228
237
 
229
238
  ```ts
230
239
  import { checkSnapshot, loadCheckRules, openCodeGraph } from "@titan-design/code-graph";
@@ -317,6 +326,22 @@ above zero.
317
326
  not complexity bounds. Recursion and search match TypeScript call nodes only, so Python
318
327
  files get `loop_depth` alone, as in codewatch.
319
328
 
329
+ Comment, shape, and exception-handling metrics (TP-322) are also source-local, TypeScript and
330
+ Python, and are written on every function or file, zeros included:
331
+
332
+ - Per symbol: `symbol_comment_lines` (rows holding a comment inside the function, docstring
333
+ excluded), `symbol_docstring_lines` (the Python docstring, or a JSDoc block ending on the row
334
+ above the declaration), `symbol_body_lines` (rows holding code), `symbol_comment_ratio`
335
+ (comment lines over `max(body lines, 1)`), `symbol_narrating_comments` (comments whose words
336
+ share at least 2 tokens, or half their tokens, with the identifiers of the statement they sit
337
+ above or trail), and `symbol_pass_through` (1 when the body is one call that forwards every
338
+ parameter, in order, as a bare argument, skipping a `self` or `cls` receiver; a function
339
+ with no parameters is never one).
340
+ - Per file: `except_count` (Python `except` and TypeScript `catch` clauses), `except_density`
341
+ (per 100 non-blank lines), and `swallowed_except` (handlers whose body is empty, `pass`,
342
+ `...`, `continue`, a bare or `None`/`null`/`undefined` return, or one call to a logger,
343
+ `print`, `warn` or `console`).
344
+
320
345
  PageRank, relevance, and symbol coupling run at query time over one snapshot:
321
346
 
322
347
  ```ts
package/dist/index.d.ts CHANGED
@@ -205,7 +205,7 @@ declare function runPrune(store: CodeGraphStore, options?: PruneOptions & {
205
205
  * index version is never reused, so a change to node/edge shape or to a metric's
206
206
  * value for the same bytes can never be carried forward from an incompatible graph.
207
207
  */
208
- declare const INDEX_VERSION = "0.16.0";
208
+ declare const INDEX_VERSION = "0.17.0";
209
209
  interface IndexOptions {
210
210
  /** Roots to walk. Node ids are still rooted at the git toplevel, so importers across roots share an id space. */
211
211
  paths: string[];
@@ -678,6 +678,16 @@ declare const SOURCE_METRIC_NAMES: ReadonlySet<string>;
678
678
  */
679
679
  declare function computeSourceMetrics(files: readonly ParsedFile[], fileIdOf: (filePath: string) => string, symbolNamesByFile?: ReadonlyMap<string, ReadonlySet<string>>): GraphMetric[];
680
680
 
681
+ declare const SYMBOL_METRIC_NAMES: readonly string[];
682
+
683
+ /**
684
+ * Exception-handling metrics (TP-322), pure functions of one file's bytes. A
685
+ * handler is swallowed when all it does is nothing, skip, bail out empty, or
686
+ * log: the error stops here and no caller learns of it. Written on every file,
687
+ * zeros included, so percentiles over a snapshot see the clean files too.
688
+ */
689
+ declare const EXCEPTION_METRIC_NAMES: readonly string[];
690
+
681
691
  /** How a test↔source pairing was inferred. */
682
692
  type LinkMethod = "path" | "coedit";
683
693
  interface TestSourceLink {
@@ -1102,7 +1112,7 @@ declare function aggregateMetrics(store: CodeGraphStore, snapshotId: number, opt
1102
1112
  }): MetricAggregate[];
1103
1113
 
1104
1114
  /** The `unit` a metric row is stored with; every row of one metric name carries the same unit. */
1105
- type MetricUnit = "count" | "lines" | "ratio" | "days" | "percent";
1115
+ type MetricUnit = "count" | "lines" | "ratio" | "days" | "percent" | "per100loc";
1106
1116
  /** How file values combine into a directory; `none` means no rollup reproduces the group's true value. */
1107
1117
  type MetricRollup = "sum" | "max" | "mean" | "none";
1108
1118
  /** Which way is worse, for ranking and colouring; `neutral` makes no value judgement. */
@@ -1110,7 +1120,7 @@ type MetricDirection = "higher-worse" | "lower-worse" | "neutral";
1110
1120
  /** A missing row reads as zero (a sparse writer's floor) or is left out of means, percentiles, and ranks. */
1111
1121
  type MetricAbsence = "zero" | "exclude";
1112
1122
  /** The code-graph module that writes the metric, for provenance. */
1113
- type MetricSource = "degree" | "source-metrics" | "lcom" | "dead-code" | "growth-risk" | "history" | "test-linker" | "coverage";
1123
+ type MetricSource = "degree" | "source-metrics" | "lcom" | "exception-handling" | "dead-code" | "growth-risk" | "history" | "test-linker" | "coverage";
1114
1124
  interface MetricDescriptor {
1115
1125
  /** The stored name, or a template such as `churn_{w}` when {@link windowed} is set. */
1116
1126
  name: string;
@@ -1170,6 +1180,18 @@ interface MetricProductMaxRule {
1170
1180
  exclude?: string[];
1171
1181
  excludeRoles?: NodeRole[];
1172
1182
  }
1183
+ /** Flags nodes whose value sits strictly above the given percentile of the metric over every node of the kind. */
1184
+ interface MetricOutlierRule {
1185
+ type: "metric-outlier";
1186
+ id: string;
1187
+ metric: string;
1188
+ kind: NodeKind;
1189
+ /** 50 to 100; the threshold interpolates linearly between the two nearest ranked values. */
1190
+ percentile: number;
1191
+ /** Fewest nodes that must carry the metric before any is judged; defaults to 20. */
1192
+ minSample?: number;
1193
+ severity?: Severity;
1194
+ }
1173
1195
  interface ForbidImportRule {
1174
1196
  type: "forbid-import";
1175
1197
  id: string;
@@ -1192,7 +1214,7 @@ interface NoInternalOnlyBarrelsRule {
1192
1214
  /** Globs or substrings to skip, such as CLI bin entries the role classifier calls barrels. */
1193
1215
  exclude?: string[];
1194
1216
  }
1195
- type CheckRule = MetricMaxRule | MetricMinRule | MetricProductMaxRule | ForbidImportRule | LayeredDepsRule | NoInternalOnlyBarrelsRule;
1217
+ type CheckRule = MetricMaxRule | MetricMinRule | MetricProductMaxRule | MetricOutlierRule | ForbidImportRule | LayeredDepsRule | NoInternalOnlyBarrelsRule;
1196
1218
  interface CheckRulesFile {
1197
1219
  rules: CheckRule[];
1198
1220
  }
@@ -1283,6 +1305,10 @@ interface ValidateRulesOptions {
1283
1305
  }
1284
1306
  declare function validateRules(input: unknown, options?: ValidateRulesOptions): readonly CheckRule[];
1285
1307
 
1308
+ declare const DEFAULT_OUTLIER_MIN_SAMPLE = 20;
1309
+ /** Linear interpolation between closest ranks, the definition numpy and spreadsheets use by default. */
1310
+ declare function percentileOf(values: readonly number[], percentile: number): number;
1311
+
1286
1312
  /** A snapshot id, or a ref name resolved to that ref's newest snapshot. */
1287
1313
  type SnapshotSpec = number | string;
1288
1314
  interface CheckSnapshotOptions {
@@ -1588,4 +1614,4 @@ declare function getConventionMap(store: CodeGraphStore, snapshotId: number, mod
1588
1614
  */
1589
1615
  declare function findConventions(store: CodeGraphStore, snapshotId: number, query: string, embedder: Embedder, model: string, opts?: FindConventionsOptions): Promise<ConventionQueryResult>;
1590
1616
 
1591
- 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, DOMAIN_DDL, type DeepAst, type DeepAstInput, type DiffCheckResultsOptions, type DiffSnapshotsOptions, type EdgeKind, type EmbedAttempt, type EmbedCoverage, type EmbedSnapshotResult, type EmbeddableSymbol, type ExternalDiagnostic, type FileFingerprint, type FindConventionsOptions, type FindSimilarOptions, type Finding, 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 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, type Severity, type SimilarCandidate, type SimilarResult, type SnapshotInsert, type SnapshotRow, type SnapshotSpec, type SourceLanguage, 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, aggregateMetrics, aliasChain, annotateRoles, attributeCoverage, buildAliases, buildConventionAreas, buildEmbedText, buildFileModuleNodes, buildIndexerMetrics, buildLineage, canonicalEdgeKind, canonicalMetricName, canonicalRole, 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, getConventionMap, getEdgeWeight, groupTestsBySource, hashContent, hashEmbedText, indexPaths, invertBuckets, isGeneratedByHeuristic, isGeneratedFile, isInsideGitRepo, lineagePath, linkTestsToSources, listEdges, listEdgesTouching, listEmbeddableSymbols, listMetrics, listMetricsForNode, listNodes, loadCheckRules, loadGeneratedPatterns, loadHistoryMetrics, loadLineage, matchesAny, moduleId, openCodeGraph, packageId, parentModuleId, parseSymbolId, patternToRegex, planPrune, priorSnapshotForRef, pruneDanglingReferences, readSourceFiles, rebasedViolationKey, resolveAlias, resolveBarrelEdges, resolveChurnWindows, resolveGitRef, resolveSnapshot, runChecks, runPrune, snapshotPageRank, snapshotReferenceEdges, snapshotRelevance, snapshotSymbolConsumers, snapshotSymbolCoupling, snapshotViolations, structuralSignature, summarizeConventions, symbolId, testCoverageCountMetrics, toFindings, tryEmbedSnapshot, validateRules, violationKey, walkSourceFiles, windowSuffix };
1617
+ 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, type FileFingerprint, type FindConventionsOptions, type FindSimilarOptions, type Finding, 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 SummarizeConventionsResult, type Summarizer, type SymbolConsumers, type SymbolCouplingOptions, type SymbolCouplingPair, type SymbolSpan, type TestCoverageOwnershipOptions, type TestSourceLink, type TopMetricRow, TsMorphGraphExtractor, type TsMorphGraphExtractorOptions, type UnchangedViolation, type ValidateRulesOptions, aggregateMetrics, aliasChain, annotateRoles, attributeCoverage, buildAliases, buildConventionAreas, buildEmbedText, buildFileModuleNodes, buildIndexerMetrics, buildLineage, canonicalEdgeKind, canonicalMetricName, canonicalRole, 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, getConventionMap, getEdgeWeight, groupTestsBySource, hashContent, hashEmbedText, indexPaths, invertBuckets, isGeneratedByHeuristic, isGeneratedFile, isInsideGitRepo, lineagePath, linkTestsToSources, listEdges, listEdgesTouching, listEmbeddableSymbols, listMetrics, listMetricsForNode, listNodes, loadCheckRules, loadGeneratedPatterns, loadHistoryMetrics, loadLineage, matchesAny, moduleId, openCodeGraph, packageId, parentModuleId, parseSymbolId, patternToRegex, percentileOf, planPrune, priorSnapshotForRef, pruneDanglingReferences, readSourceFiles, rebasedViolationKey, resolveAlias, resolveBarrelEdges, resolveChurnWindows, resolveGitRef, resolveSnapshot, runChecks, runPrune, snapshotPageRank, snapshotReferenceEdges, snapshotRelevance, snapshotSymbolConsumers, snapshotSymbolCoupling, snapshotViolations, structuralSignature, summarizeConventions, symbolId, testCoverageCountMetrics, toFindings, tryEmbedSnapshot, validateRules, violationKey, walkSourceFiles, windowSuffix };