Single-commit clean baseline after security scrub of niche-tells, project codenames, internal jargon, and contributor-email leaks. Contents: - 100 Rust crates (_primitives/_rust/) - 37 agent manifests (_manifests/) + generated specs (_generated/) - 67 user-invocable skills (skills/) - 33 hooks (hooks/) - Composition blocks (_blocks/) - Documentation (docs/, README.md) - TS adapter packages (_ts_packages/) - Assembler (_assembler/) - Roles (_roles/) - Templates (_templates/) - Forgejo CI (.forgejo/) Author: Denis Parfionovich <info@greendragon.info> License: see LICENSE.
76 lines
2.3 KiB
Rust
76 lines
2.3 KiB
Rust
//! Markdown renderer for the refactor plan.
|
|
|
|
use crate::plan::{Plan, PlanItem};
|
|
|
|
pub fn render(plan: &Plan, branch: Option<&str>) -> String {
|
|
let mut out = String::new();
|
|
out.push_str("# Deep-sleep refactor plan\n\n");
|
|
if let Some(b) = branch {
|
|
out.push_str(&format!("Proposed fork branch: `{}`\n\n", b));
|
|
}
|
|
out.push_str(&summary(plan));
|
|
out.push_str(&auto_section(plan));
|
|
out.push_str(&manual_section(plan));
|
|
out.push_str(&footer());
|
|
out
|
|
}
|
|
|
|
fn summary(plan: &Plan) -> String {
|
|
let total = plan.items.len();
|
|
let auto = plan.auto_items().len();
|
|
let manual = plan.manual_items().len();
|
|
format!(
|
|
"## Summary\n\n\
|
|
- Total conflicts: **{total}**\n\
|
|
- Auto-apply candidates: **{auto}**\n\
|
|
- Requires human decision (zero-conflict guarantee excludes these from patch): **{manual}**\n\n",
|
|
)
|
|
}
|
|
|
|
fn auto_section(plan: &Plan) -> String {
|
|
let items = plan.auto_items();
|
|
if items.is_empty() {
|
|
return "## Auto-apply\n\n_No safe auto-apply changes this cycle._\n\n".to_string();
|
|
}
|
|
let mut s = String::from("## Auto-apply (engine-proposed; review before merge)\n\n");
|
|
for (i, item) in items.iter().enumerate() {
|
|
s.push_str(&item_block(i + 1, item));
|
|
}
|
|
s
|
|
}
|
|
|
|
fn manual_section(plan: &Plan) -> String {
|
|
let items = plan.manual_items();
|
|
if items.is_empty() {
|
|
return "## Requires human decision\n\n_None this cycle._\n\n".to_string();
|
|
}
|
|
let mut s = String::from("## Requires human decision (NOT in patch)\n\n");
|
|
for (i, item) in items.iter().enumerate() {
|
|
s.push_str(&item_block(i + 1, item));
|
|
}
|
|
s
|
|
}
|
|
|
|
fn item_block(n: usize, item: &PlanItem) -> String {
|
|
format!(
|
|
"### {n}. [{cat}/{sev}] {files}\n\n\
|
|
- **Why:** {why}\n\
|
|
- **Example:** {ex}\n\
|
|
- **Tradeoff:** {tr}\n\n",
|
|
n = n,
|
|
cat = item.category,
|
|
sev = item.severity,
|
|
files = item.files.join(" + "),
|
|
why = item.why,
|
|
ex = item.example,
|
|
tr = item.tradeoff,
|
|
)
|
|
}
|
|
|
|
fn footer() -> String {
|
|
"---\n\n\
|
|
Generated by `kei-refactor-engine` (v0.13.0). Zero-conflict guarantee: \
|
|
no item above marked `requires human decision` appears in the companion \
|
|
patch file.\n"
|
|
.to_string()
|
|
}
|