omni_dev/cli/
commands.rs

1//! Command template management
2
3use anyhow::{Context, Result};
4use clap::{Parser, Subcommand};
5use std::fs;
6use std::path::Path;
7
8// Embed the template files as strings
9const COMMIT_TWIDDLE_TEMPLATE: &str = include_str!("../templates/commit-twiddle.md");
10const PR_CREATE_TEMPLATE: &str = include_str!("../templates/pr-create.md");
11const PR_UPDATE_TEMPLATE: &str = include_str!("../templates/pr-update.md");
12
13/// Command template management
14#[derive(Parser)]
15pub struct CommandsCommand {
16    /// Commands subcommand to execute
17    #[command(subcommand)]
18    pub command: CommandsSubcommands,
19}
20
21/// Commands subcommands
22#[derive(Subcommand)]
23pub enum CommandsSubcommands {
24    /// Generate command templates
25    Generate(GenerateCommand),
26}
27
28/// Generate command options
29#[derive(Parser)]
30pub struct GenerateCommand {
31    /// Generate subcommand to execute
32    #[command(subcommand)]
33    pub command: GenerateSubcommands,
34}
35
36/// Generate subcommands
37#[derive(Subcommand)]
38pub enum GenerateSubcommands {
39    /// Generate commit-twiddle command template
40    #[command(name = "commit-twiddle")]
41    CommitTwiddle,
42    /// Generate pr-create command template
43    #[command(name = "pr-create")]
44    PrCreate,
45    /// Generate pr-update command template
46    #[command(name = "pr-update")]
47    PrUpdate,
48    /// Generate all command templates
49    All,
50}
51
52impl CommandsCommand {
53    /// Execute commands command
54    pub fn execute(self) -> Result<()> {
55        match self.command {
56            CommandsSubcommands::Generate(generate_cmd) => generate_cmd.execute(),
57        }
58    }
59}
60
61impl GenerateCommand {
62    /// Execute generate command
63    pub fn execute(self) -> Result<()> {
64        match self.command {
65            GenerateSubcommands::CommitTwiddle => {
66                generate_commit_twiddle()?;
67                println!("✅ Generated .claude/commands/commit-twiddle.md");
68            }
69            GenerateSubcommands::PrCreate => {
70                generate_pr_create()?;
71                println!("✅ Generated .claude/commands/pr-create.md");
72            }
73            GenerateSubcommands::PrUpdate => {
74                generate_pr_update()?;
75                println!("✅ Generated .claude/commands/pr-update.md");
76            }
77            GenerateSubcommands::All => {
78                generate_commit_twiddle()?;
79                generate_pr_create()?;
80                generate_pr_update()?;
81                println!("✅ Generated all command templates:");
82                println!("   - .claude/commands/commit-twiddle.md");
83                println!("   - .claude/commands/pr-create.md");
84                println!("   - .claude/commands/pr-update.md");
85            }
86        }
87        Ok(())
88    }
89}
90
91/// Generate commit-twiddle command template
92fn generate_commit_twiddle() -> Result<()> {
93    ensure_claude_commands_dir()?;
94    fs::write(
95        ".claude/commands/commit-twiddle.md",
96        COMMIT_TWIDDLE_TEMPLATE,
97    )
98    .context("Failed to write .claude/commands/commit-twiddle.md")?;
99    Ok(())
100}
101
102/// Generate pr-create command template
103fn generate_pr_create() -> Result<()> {
104    ensure_claude_commands_dir()?;
105    fs::write(".claude/commands/pr-create.md", PR_CREATE_TEMPLATE)
106        .context("Failed to write .claude/commands/pr-create.md")?;
107    Ok(())
108}
109
110/// Generate pr-update command template
111fn generate_pr_update() -> Result<()> {
112    ensure_claude_commands_dir()?;
113    fs::write(".claude/commands/pr-update.md", PR_UPDATE_TEMPLATE)
114        .context("Failed to write .claude/commands/pr-update.md")?;
115    Ok(())
116}
117
118/// Ensure the .claude/commands directory exists
119fn ensure_claude_commands_dir() -> Result<()> {
120    let commands_dir = Path::new(".claude/commands");
121    if !commands_dir.exists() {
122        fs::create_dir_all(commands_dir).context("Failed to create .claude/commands directory")?;
123    }
124    Ok(())
125}