chant/operations/
reset.rs1use anyhow::Result;
6use std::path::Path;
7
8use crate::spec::{Spec, SpecStatus};
9
10#[derive(Debug, Clone, Default)]
12pub struct ResetOptions {
13 pub re_execute: bool,
15 pub prompt: Option<String>,
17 pub branch: Option<String>,
19}
20
21pub fn reset_spec(spec: &mut Spec, spec_path: &Path, _options: ResetOptions) -> Result<()> {
26 if spec.frontmatter.status != SpecStatus::Failed
28 && spec.frontmatter.status != SpecStatus::InProgress
29 {
30 anyhow::bail!(
31 "Spec '{}' is not in failed or in_progress state (current: {:?}). \
32 Only failed or in_progress specs can be reset.",
33 spec.id,
34 spec.frontmatter.status
35 );
36 }
37
38 let spec_id = &spec.id;
39
40 if let Err(e) = crate::lock::remove_lock(spec_id) {
46 eprintln!(
47 "Warning: Failed to remove lock file for spec {}: {}",
48 spec_id, e
49 );
50 }
51
52 if let Err(e) = crate::pid::remove_pid_file(spec_id) {
54 eprintln!(
55 "Warning: Failed to remove PID file for spec {}: {}",
56 spec_id, e
57 );
58 }
59
60 if let Err(e) = crate::pid::remove_process_files(spec_id) {
62 eprintln!(
63 "Warning: Failed to remove process files for spec {}: {}",
64 spec_id, e
65 );
66 }
67
68 if let Ok(config) = crate::config::Config::load() {
70 let project_name = Some(config.project.name.as_str());
71 if let Some(worktree_path) = crate::worktree::get_active_worktree(spec_id, project_name) {
72 if let Err(e) = crate::worktree::remove_worktree(&worktree_path) {
73 eprintln!(
74 "Warning: Failed to remove worktree for spec {}: {}",
75 spec_id, e
76 );
77 }
78 }
79 }
80
81 if let Ok(config) = crate::config::Config::load() {
83 let branch_prefix = &config.defaults.branch_prefix;
84 let branch = format!("{}{}", branch_prefix, spec_id);
85 if let Err(e) = std::process::Command::new("git")
86 .args(["branch", "-D", &branch])
87 .output()
88 {
89 eprintln!("Warning: Failed to delete git branch {}: {}", branch, e);
90 }
91 }
92
93 spec.set_status(SpecStatus::Pending)
95 .map_err(|e| anyhow::anyhow!("Failed to transition spec to Pending: {}", e))?;
96
97 spec.save(spec_path)?;
99
100 Ok(())
101}