code_ranker_plugin_api/lib.rs
1//! # code-ranker-plugin-api
2//!
3//! The contract everything in Code Ranker builds on: a **generic property-graph
4//! model** plus the [`LanguagePlugin`](plugin::LanguagePlugin) trait. This crate is the foundation — it
5//! depends on **nothing** else from Code Ranker and re-exports nothing. Every
6//! other crate (graph operations, complexity, language plugins, viewer, cli)
7//! depends on *this*.
8//!
9//! ## Model
10//!
11//! Analysis produces a [`Graph`](graph::Graph) of **[`Node`](node::Node)**s connected by **[`Edge`](edge::Edge)**s.
12//! A node is *anything we analyze*: today a source file (`kind == "file"`),
13//! tomorrow a folder, module, function, variable or line — with **no model
14//! change**. `kind` is a free-form [`String`] (the plugin's own vocabulary);
15//! the core never interprets it, it only stores and projects.
16//!
17//! Both nodes and edges carry free-form **[`Attributes`](attrs::Attributes)** (string key →
18//! scalar [`AttrValue`](attrs::AttrValue)). There is no fixed, file/language-specific field set:
19//! the plugin chooses keys (`path`, `loc`, `visibility`, `version`, or
20//! language-specific ones), the orchestrator adds computed keys (metrics,
21//! cycle), and the core reads only the keys it understands. Each level describes
22//! its keys with an [`AttributeSpec`](level::AttributeSpec) dictionary (type + label/hint), so the UI
23//! knows what each key means and what it can do with it.
24//!
25//! ## Responsibilities
26//!
27//! A [`LanguagePlugin`](plugin::LanguagePlugin) is a **pure parser**: it turns a workspace into nodes +
28//! edges at a requested level (by name; see [`Level`](level::Level)). It does **not**
29//! compute metrics — complexity / cycles / Henry-Kafura / stats are filled in
30//! centrally, for all languages, by the orchestrator. The plugin also describes
31//! its edge kinds ([`EdgeKindSpec`](level::EdgeKindSpec)) and attribute keys
32//! ([`AttributeSpec`](level::AttributeSpec)), so the core scores, draws and labels unknown
33//! kinds/keys without hardcoding their names.
34
35pub mod attrs;
36pub mod detection;
37pub mod edge;
38pub mod graph;
39pub mod level;
40pub mod list_override;
41pub mod log;
42pub mod metrics;
43pub mod node;
44pub mod plugin;
45pub mod preset;
46pub mod report;
47pub mod toml_merge;
48
49pub use attrs::{AttrValue, Attributes, ValueType};
50pub use detection::detect_with_marker;
51pub use edge::Edge;
52pub use graph::Graph;
53pub use level::{
54 AttributeGroup, AttributeSpec, CycleKindSpec, Direction, EdgeKindSpec, Level, NodeKindSpec,
55 SpecRow, Thresholds, attr_dict, group,
56};
57pub use metrics::{FunctionUnit, MetricInputs};
58pub use node::{Node, NodeId};
59pub use plugin::{LanguagePlugin, PluginInput, PluginRegistration, registry};
60pub use preset::{Preset, PromptTemplate};
61pub use report::{ListPatch, ReportOverride};
62
63use std::collections::BTreeMap;
64
65/// The generic node-kind palette every file-based plugin seeds its level with:
66/// `file` (a project source unit, blue) and `external` (a third-party library,
67/// amber, flagged external). A plugin may recolor or add kinds.
68pub fn default_node_kinds() -> BTreeMap<String, NodeKindSpec> {
69 BTreeMap::from([
70 (
71 node::FILE.to_string(),
72 NodeKindSpec {
73 label: Some("File".into()),
74 plural: Some("Files".into()),
75 fill: Some("#dbe9f4".into()),
76 stroke: Some("#4d6f9c".into()),
77 external: None,
78 },
79 ),
80 (
81 node::EXTERNAL.to_string(),
82 NodeKindSpec {
83 label: Some("Library".into()),
84 plural: Some("Libraries".into()),
85 fill: Some("#f6e2c0".into()),
86 stroke: Some("#b3801f".into()),
87 external: Some(true),
88 },
89 ),
90 ])
91}
92
93/// The generic cycle-kind keys (`mutual` / `chain`) a file-based plugin's level
94/// declares. The diagnostic vocabulary (label / `description` = why /
95/// `remediation` = fix) is **data, not code**: it is filled centrally by the
96/// orchestrator from `code-ranker-graph`'s `cycle_specs` (the `builtin.toml`
97/// `[cycles.*]` catalog), so no cycle prose lives here.
98pub fn default_cycle_kinds() -> BTreeMap<String, CycleKindSpec> {
99 ["mutual", "chain"]
100 .into_iter()
101 .map(|k| {
102 (
103 k.to_string(),
104 CycleKindSpec {
105 label: None,
106 description: None,
107 remediation: None,
108 },
109 )
110 })
111 .collect()
112}