codelore-lib 0.27.3

CodeLore — Behavioral Code Analyzer library
Documentation
[package]
name = "codelore-lib"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
description = "CodeLore — Behavioral Code Analyzer library"
readme.workspace = true
keywords.workspace = true
categories.workspace = true

[lints]
workspace = true

[build-dependencies]
# Build-script HTTP fetch for the optional `spa` dashboard emitter's
# vendored JS deps. ureq is sync, ~30KB, no async runtime — exactly
# the right size for a build script. sha2/hex pin the downloaded
# bytes against tampering (audit-trail-clean supply chain).
# ureq 3.x — sole consumer is `build.rs`'s SHA-pinned CDN fetcher for
# the SPA's vendored JS deps (ECharts, d3-hierarchy, Alpine.js, persist
# plugin). Default features (`rustls`, `gzip`, `json`) cover what we
# need — TLS via rustls' aws-lc-rs backend, and decompression for
# CDN responses. Bumped from `2` to `3`: the v2 branch
# is maintenance-only with no new features going forward; v3 unifies
# the TLS story on rustls (was a separate feature-flag concern in v2),
# moves per-request config under `.config().build()`, and replaces the
# `into_reader()` chain with `body_mut().read_to_vec()`.
ureq = "3"
sha2 = "0.11"
hex = "0.4"

[dependencies]
time = { version = "0.3", features = ["serde", "macros"] }
serde = { version = "1", features = ["derive"] }
# `float_roundtrip`: exact f64 parsing so a JSON sidecar (change-set report,
# enrichment narrative) deserializes to the bit-identical value it was written
# from — without it serde_json's best-effort float parse drifts in the last
# ULPs and a warm cache read would differ from the cold computation.
serde_json = { version = "1", features = ["float_roundtrip"] }
thiserror = "2"
arrow = "59.1"
gix = { version = "0.86", features = ["max-performance", "blob-diff"] }
tempfile = { version = "3", optional = true }
duckdb = { version = "=1.10505.0", features = ["bundled", "appender-arrow"] }
crossbeam-channel = "0.5"
codelore-rca = { path = "../codelore-rca", version = "0.27.3" }
# RFC 3986 §4.1 percent-encoding for SARIF artifactLocation.uri values.
# Paths with spaces / `#` / non-ASCII chars must be percent-encoded;
# unencoded URIs are rejected by GitHub Code Scanning's SARIF upload.
percent-encoding = "2"
# Leiden community detection on the behavioural coupling graph.
# Default features disabled because the upstream default pulls in
# `cli` (clap binary we don't need), `gryf` (alternative graph crate;
# we feed edges directly as Vec<(u32, u32, f64)>), and `rayon`. We
# opt back into `rayon` only — the parallel Leiden iterations are
# meaningfully faster on linux-kernel-scale coupling graphs
# (~70k nodes). The `petgraph` feature is intentionally left off so
# leiden-rs's optional petgraph 0.8 dep doesn't conflict with
# codelore-rca's pinned 0.6 (CLAUDE.md documents why the 0.6 → 0.8
# bump is held).
leiden-rs = { version = "0.8", default-features = false, features = ["rayon"] }
# Headless Chrome driver, opt-in via the `browser-tests` feature.
# Used only by `tests/spa_browser_test.rs` to drive the rendered SPA
# in a real browser — closes the runtime-defect blind spot that the
# existing string-grep `spa_integration_test` can't cover. `optional`
# so the default build (no `browser-tests` flag) doesn't fetch the
# crate or its native-CDP transitive deps. Default features cover
# what the smoke test needs (CDP + JSON RPC + the bundled Chrome
# fetcher fallback path).
headless_chrome = { version = "1", optional = true }
sha2 = "0.11"
hex = "0.4"
# Direct tree-sitter + grammar deps for clone-detection AST walking (Plan 7).
# All pinned to the exact versions codelore-rca uses, for parser-ABI compat.
tree-sitter = "=0.25.3"
tree-sitter-rust = "=0.23.2"
tree-sitter-python = "=0.23.6"
tree-sitter-java = "=0.23.5"
tree-sitter-javascript = "=0.23.1"
tree-sitter-typescript = "=0.23.1"
walkdir = "2"
globset = "0.4"
# `ignore` powers the `.gitignore` + `.codeloreignore` + `.git/info/exclude`
# auto-respect at HEAD-time scan. Same crate used by ripgrep / bat. Avoids
# us hand-rolling gitignore semantics (negation patterns, parent-dir
# inheritance, conditional-include rules, etc.).
ignore = "0.4"
dirs = "6"
# `anstyle` is what cargo + clap use for ANSI styling. Already in our tree
# transitively via clap; declaring it as a direct dep lets the banner module
# import it without bumping the binary footprint (anstyle is ~5KB, all-const).
anstyle = "1"
tracing = "0.1"
rayon = "1"
# `messages` analysis validates user-supplied --expression-to-match
# regex eagerly (DuckDB does the actual matching server-side via
# regexp_matches).
regex = "1"
# Architectural grouping (--group-file) uses fancy-regex because
# code-maat's own test fixture (regex-layers-definition.txt) uses
# lookaround patterns like `^src\/((?!.*Test.*).).*$` — the standard
# Rust `regex` crate doesn't support lookaround. fancy-regex wraps
# `regex` with a backtracking engine for non-regular features.
fancy-regex = "0.19"
# TOML parser for `.codelore-arch-rules.toml` and the thresholds
# config. `toml` 1.x split `parse` (low-level parser) from `serde`
# (`from_str` / `Deserialize` glue). We need both: `parse` for the
# core deserializer and `serde` for the typed `from_str` API
# `quality_gates::Thresholds::parse` and `arch_rules::LayerRules::parse`
# call. (In 0.8.x `parse` implied `serde`; that bundling went away in
# the 1.0 release.) `preserve_order` makes `toml::Table` iterate layers
# in the order they appear in the file (backed by `indexmap`), so
# arch-rules first-match layer classification follows declaration order
# instead of the sorted layer names.
toml = { version = "1", default-features = false, features = ["parse", "serde", "display", "preserve_order"] }
# Synchronous HTTP client for the advisory enrichment layer's two-dialect chat
# client (Anthropic-native + OpenAI-compatible). Blocking by design — the crate
# carries no async runtime and issues one advisory completion per invocation.
# The `json` feature enables `send_json`/`read_json` for request/response
# bodies; the default features keep rustls TLS + gzip for real HTTPS endpoints.
# Also a `[build-dependencies]` entry, where build.rs uses it (default features,
# no `json`) for the SPA's SHA-pinned vendored-JS fetch.
ureq = { version = "3", features = ["json"] }

[features]
default = []
test-support = ["dep:tempfile"]

# `spa` — opt-in CodeScene-equivalent dashboard emitter (--format spa).
# Activating this feature makes `build.rs` fetch and SHA-pin the
# vendored JS deps (Apache ECharts + d3-hierarchy) from jsDelivr at
# build time and embed them into the binary. Without this feature
# CodeLore builds cleanly offline and the `spa` format is unavailable
# from the CLI. Released binaries (Homebrew, ghcr, GitHub Releases)
# ship with `--features spa` enabled.
spa = []

# `browser-tests` — opt-in headless-browser smoke test for the SPA
# emitter. Closes the runtime-defect blind spot the earlier
# string-grep `spa_integration_test` can't cover (production browser-
# console errors that ship through every PR because no JS executes
# at CI time). Defaults OFF so contributors who don't have Chrome
# installed locally still get a clean `cargo test`; CI's ubuntu
# matrix opts in via `--features browser-tests`. Requires `spa` to
# be enabled too — there's nothing to drive in a browser otherwise.
browser-tests = ["spa", "dep:headless_chrome"]

[dev-dependencies]
criterion = "0.8"

[[bench]]
name = "end_to_end"
harness = false
required-features = ["test-support"]

[[test]]
name = "facts_test"
required-features = ["test-support"]

[[test]]
name = "gix_repo_test"
required-features = ["test-support"]

[[test]]
name = "ingest_test"
required-features = ["test-support"]

[[test]]
name = "revisions_test"
required-features = ["test-support"]

[[test]]
name = "complexity_test"

[[test]]
name = "hotspots_test"
required-features = ["test-support"]

[[test]]
name = "code_health_test"
required-features = ["test-support"]

[[test]]
name = "change_set_test"
required-features = ["test-support"]

[[test]]
name = "calibration_test"
required-features = ["test-support"]

[[test]]
name = "defect_calibration_test"
required-features = ["test-support"]

[[test]]
name = "mailmap_test"
required-features = ["test-support"]

[[test]]
name = "kamei_test"
required-features = ["test-support"]

[[test]]
name = "churn_test"
required-features = ["test-support"]

[[test]]
name = "code_age_test"
required-features = ["test-support"]

[[test]]
name = "communication_test"
required-features = ["test-support"]

[[test]]
name = "ownership_test"
required-features = ["test-support"]

[[test]]
name = "coupling_test"
required-features = ["test-support"]

[[test]]
name = "summary_test"
required-features = ["test-support"]

[[test]]
name = "authors_test"
required-features = ["test-support"]

[[test]]
name = "clones_exclude_test"
required-features = ["test-support"]

[[test]]
name = "clones_factsdb_test"
required-features = ["test-support"]

[[test]]
name = "clone_coupling_test"
required-features = ["test-support"]

[[test]]
name = "imports_factsdb_test"
required-features = ["test-support"]

[[test]]
name = "provenance_test"
required-features = ["test-support"]

[[test]]
name = "output_json_test"

[[test]]
name = "output_sarif_test"

[[test]]
name = "output_parquet_test"
required-features = ["test-support"]

[[test]]
name = "output_sqlite_test"
required-features = ["test-support"]

[[test]]
name = "git_cli_repo_test"
required-features = ["test-support"]

[[test]]
name = "differential_repo_test"
required-features = ["test-support"]

[[test]]
name = "code_maat_parity_test"
required-features = ["test-support"]

[[test]]
name = "cache_test"
required-features = ["test-support"]

[[test]]
name = "ownership_hhi_window_spike_test"
required-features = ["test-support"]

[[test]]
name = "bus_factor_test"
required-features = ["test-support"]

[[test]]
name = "lead_time_test"
required-features = ["test-support"]

[[test]]
name = "stale_code_test"
required-features = ["test-support"]

[[test]]
name = "pair_programming_test"
required-features = ["test-support"]

[[test]]
name = "god_classes_test"
required-features = ["test-support"]

[[test]]
name = "arch_violations_test"
required-features = ["test-support"]

[[test]]
name = "spa_browser_test"
required-features = ["browser-tests", "test-support"]

[[test]]
name = "centrality_test"
required-features = ["test-support"]

[[test]]
name = "communities_test"
required-features = ["test-support"]

[[test]]
name = "mi_test"
required-features = ["test-support"]

[[test]]
name = "effort_exposure_test"
required-features = ["test-support"]

[[test]]
name = "new_code_test"
required-features = ["test-support"]

[[test]]
name = "commit_parents_test"
required-features = ["test-support"]

[[test]]
name = "test_support_fixture_test"
required-features = ["test-support"]

[[test]]
name = "knowledge_shares_test"
required-features = ["test-support"]

[[test]]
name = "code_familiarity_test"
required-features = ["test-support"]

[[test]]
name = "function_xray_test"
required-features = ["test-support"]

[[test]]
name = "function_coupling_test"
required-features = ["test-support"]

[[test]]
name = "sarif_parse_test"

[[test]]
name = "external_store_test"
required-features = ["test-support"]

[[test]]
name = "finding_hotspot_overlap_test"
required-features = ["test-support"]

[[test]]
name = "code_maat_csv_compat_test"
required-features = ["test-support"]

[[test]]
name = "enrichment_fact_sheet_test"
required-features = ["test-support"]

[[test]]
name = "entity_ownership_test"
required-features = ["test-support"]

[[test]]
name = "entity_effort_test"
required-features = ["test-support"]