1use regex::Regex;
8use std::path::{Path, PathBuf};
9
10pub fn planning_dir(ito_path: &Path) -> PathBuf {
14 ito_path.join("planning")
15}
16
17pub fn milestones_dir(ito_path: &Path) -> PathBuf {
19 planning_dir(ito_path).join("milestones")
20}
21
22pub fn project_md_template(project_name: Option<&str>, description: Option<&str>) -> String {
24 let project_name = project_name.unwrap_or("[Project Name]");
25 let description =
26 description.unwrap_or("[1-2 sentence description of what we're building and why]");
27 format!(
28 "# Project: {project_name}\n\n## Vision\n{description}\n\n## Core Value Proposition\n[What makes this valuable to users]\n\n## Constraints\n- Technical: [stack, compatibility requirements]\n- Resources: [team size, expertise gaps]\n\n## Stakeholders\n- [Role]: [Concerns and success criteria]\n\n## Out of Scope\n- [Explicitly excluded features/concerns]\n\n## AI Assistant Notes\n[Special instructions for AI tools working on this project]\n- Preferred patterns: [...]\n- Avoid: [...]\n- Always check: [...]\n"
29 )
30}
31
32pub fn roadmap_md_template() -> String {
34 "# Roadmap\n\n## Current Milestone: v1-core\n- Status: Not Started\n- Phase: 0 of 0\n\n## Milestones\n\n### v1-core\nTarget: [Define the goal for this milestone]\n\n| Phase | Name | Status | Changes |\n|-------|------|--------|---------|\n| 1 | [Phase Name] | Pending | - |\n\n## Completed Milestones\n[None yet]\n"
35 .to_string()
36}
37
38pub fn state_md_template(current_date: &str, ito_dir: &str) -> String {
40 format!(
41 "# Project State\n\nLast Updated: {current_date}\n\n## Current Focus\n[What we're working on right now]\n\n## Recent Decisions\n- {current_date}: Project initialized\n\n## Open Questions\n- [ ] [Question needing resolution]\n\n## Blockers\n[None currently]\n\n## Session Notes\n### {current_date} - Initial Setup\n- Completed: Project planning structure initialized\n- Next: Define project vision and first milestone\n\n---\n## For AI Assistants\nWhen resuming work on this project:\n1. Read this STATE.md first\n2. Check ROADMAP.md for current phase\n3. Review any in-progress changes in `{ito_dir}/changes/`\n4. Continue from \"Current Focus\" above\n"
42 )
43}
44
45pub fn read_current_progress(roadmap_contents: &str) -> Option<(String, String, String)> {
50 let re = Regex::new(r"## Current Milestone: (.+)\n- Status: (.+)\n- Phase: (.+)").unwrap();
51 let caps = re.captures(roadmap_contents)?;
52 Some((
53 caps[1].to_string(),
54 caps[2].to_string(),
55 caps[3].to_string(),
56 ))
57}
58
59pub fn read_phase_rows(roadmap_contents: &str) -> Vec<(String, String, String, String)> {
63 let mut rows: Vec<(String, String, String, String)> = Vec::new();
64
65 let mut in_table = false;
66 let mut saw_sep = false;
67 for line in roadmap_contents.lines() {
68 let t = line.trim();
69 if t == "| Phase | Name | Status | Changes |" {
70 in_table = true;
71 saw_sep = false;
72 continue;
73 }
74 if !in_table {
75 continue;
76 }
77 if !saw_sep {
78 if t.starts_with("|-------") {
79 saw_sep = true;
80 }
81 continue;
82 }
83 if t.is_empty() || !t.starts_with('|') {
84 break;
85 }
86
87 let cols: Vec<String> = t
88 .split('|')
89 .map(|c| c.trim().to_string())
90 .filter(|c| !c.is_empty())
91 .collect();
92 if cols.len() >= 4 {
93 rows.push((
94 cols[0].clone(),
95 cols[1].clone(),
96 cols[2].clone(),
97 cols[3].clone(),
98 ));
99 }
100 }
101 rows
102}