lean_ctx/core/
rule_artifacts.rs1use crate::core::config::CompressionLevel;
13use crate::core::rules_canonical::{self, Wrapper};
14
15pub const ARTIFACT_PATHS: &[&str] = &["LEAN-CTX.md", "rust/LEAN-CTX.md"];
18
19#[must_use]
25pub fn canonical_body() -> String {
26 format!(
27 "{}\n{}\n",
28 rules_canonical::PROJECT_LEAN_CTX_OWNED_MARKER,
29 rules_canonical::render(
30 false,
31 Wrapper::Longform,
32 CompressionLevel::Off,
33 &super::tool_profiles::ToolProfile::Power,
34 )
35 )
36}
37
38pub const SKILL_COPY_PATH: &str = "skills/lean-ctx/SKILL.md";
42
43pub const CLAUDE_MOD_COPIES: &[(&str, &str)] = &[
47 (
48 "integrations/claude-code-mod/hooks/register.ts",
49 crate::core::claude_host::REGISTER_TS,
50 ),
51 (
52 "integrations/claude-code-mod/hooks/hooks.json",
53 crate::core::claude_host::HOOKS_JSON,
54 ),
55 (
56 "integrations/claude-code-mod/.claude-plugin/plugin.json",
57 crate::core::claude_host::PLUGIN_JSON,
58 ),
59 (
60 "integrations/claude-code-mod/hooks/cockpit.tsx",
61 crate::core::claude_host::COCKPIT_TSX,
62 ),
63 (
64 "integrations/claude-code-mod/hooks/render.tsx",
65 crate::core::claude_host::RENDER_TSX,
66 ),
67 (
68 "integrations/claude-code-mod/types/index.d.ts",
69 crate::core::claude_host::TYPES_DTS,
70 ),
71];
72
73#[must_use]
77pub fn artifacts() -> Vec<(&'static str, String)> {
78 let body = canonical_body();
79 let mut arts: Vec<(&'static str, String)> =
80 ARTIFACT_PATHS.iter().map(|p| (*p, body.clone())).collect();
81 arts.push((
82 SKILL_COPY_PATH,
83 include_str!("../templates/SKILL.md").to_string(),
84 ));
85 arts.extend(
86 CLAUDE_MOD_COPIES
87 .iter()
88 .map(|(path, content)| (*path, (*content).to_string())),
89 );
90 arts
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn canonical_body_is_owned_versioned_and_current() {
99 let body = canonical_body();
100 assert!(body.starts_with(rules_canonical::PROJECT_LEAN_CTX_OWNED_MARKER));
101 assert!(body.contains(&format!(
102 "<!-- version: {} -->",
103 rules_canonical::RULES_VERSION
104 )));
105 assert!(body.contains("AGENT LOOP"));
107 assert!(body.contains("NAVIGATION PARADOX"));
108 assert!(body.ends_with('\n'));
109 }
110
111 #[test]
112 fn artifacts_cover_every_declared_path() {
113 let arts = artifacts();
114 for declared in ARTIFACT_PATHS.iter().chain([&SKILL_COPY_PATH]) {
115 assert!(
116 arts.iter().any(|(p, b)| p == declared && !b.is_empty()),
117 "{declared} missing from the generator output"
118 );
119 }
120 }
121}