Skip to content

Commit 9d98077

Browse files
authored
Merge pull request #9 from MikeGarde/interactive
Add interactive file classification workflow with staged prompts
2 parents 9b72059 + bdd16bc commit 9d98077

File tree

9 files changed

+664
-288
lines changed

9 files changed

+664
-288
lines changed

Cargo.lock

Lines changed: 179 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ categories = ["command-line-utilities", "development-tools", "text-processing"]
1515
[dependencies]
1616
anyhow = "1.0"
1717
clap = { version = "4.5", features = ["derive", "env"] }
18+
crossterm = "0.29"
1819
dirs = "6.0.0"
1920
reqwest = { version = "0.12", features = ["json", "blocking"] }
2021
serde = { version = "1", features = ["derive"] }

src/cli_args.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use clap::{ArgGroup, Parser, Subcommand};
2+
3+
/// CLI options
4+
#[derive(Parser, Debug)]
5+
#[command(
6+
name = "commitbot",
7+
version,
8+
about = "LLM-assisted Git commit message generator"
9+
)]
10+
#[command(group(
11+
ArgGroup::new("model_group")
12+
.args(["model", "no_model"])
13+
.multiple(false)
14+
))]
15+
pub struct Cli {
16+
/// Interactive mode: classify each file and do per-file summaries
17+
#[arg(long, global = true)]
18+
pub ask: bool,
19+
20+
/// If set, write the generated message into .git/COMMIT_EDITMSG (no commit is created)
21+
#[arg(short = 'w', long, global = true)]
22+
pub apply: bool,
23+
24+
/// Stage all changes before generating the commit message
25+
#[arg(short, long, global = true)]
26+
pub stage: bool,
27+
28+
/// Debug mode: log prompts, responses, token usage
29+
#[arg(long, global = true)]
30+
pub debug: bool,
31+
32+
/// Model name to use (e.g. gpt-4o-mini). If 'none', acts like --no-model.
33+
#[arg(short, long, global = true)]
34+
pub model: Option<String>,
35+
36+
/// Disable model calls; return dummy responses instead
37+
#[arg(long, global = true)]
38+
pub no_model: bool,
39+
40+
/// API key (otherwise uses OPENAI_API_KEY env var)
41+
#[arg(short = 'k', long, env = "OPENAI_API_KEY", global = true)]
42+
pub api_key: Option<String>,
43+
44+
/// Optional: a brief human description of the ticket (for commit/PR summaries)
45+
#[arg(long, global = true)]
46+
pub ticket_summary: Option<String>,
47+
48+
/// Subcommand (e.g. 'pr')
49+
#[command(subcommand)]
50+
pub command: Option<Command>,
51+
}
52+
53+
/// Subcommands, e.g. `commitbot pr develop`
54+
#[derive(Subcommand, Debug)]
55+
pub enum Command {
56+
/// Generate a Pull Request description by summarizing commit or PR messages
57+
Pr {
58+
/// Base branch to compare against (e.g. main or develop)
59+
base: String,
60+
61+
/// Optional feature/source branch; defaults to current branch if omitted
62+
from: Option<String>,
63+
64+
/// Force using PR-oriented grouping (PR numbers) instead of commits
65+
#[arg(long = "pr")]
66+
pr_mode: bool,
67+
68+
/// Force using commit-by-commit mode instead of PR grouping
69+
#[arg(long = "commit")]
70+
commit_mode: bool,
71+
},
72+
}

src/config.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::path::PathBuf;
77
/// Final resolved configuration for commitbot.
88
#[derive(Debug, Clone)]
99
pub struct Config {
10+
pub openai_api_key: String,
1011
pub model: String,
1112
}
1213

@@ -22,21 +23,29 @@ impl Config {
2223
let file_cfg = load_file_config().unwrap_or_default();
2324

2425
let model_cli = cli.model.clone();
26+
let api_key_cli = cli.api_key.clone();
2527
let model_env = env::var("COMMITBOT_MODEL").ok();
28+
let api_key_env = env::var("OPENAI_API_KEY").ok();
2629

2730
let model = model_cli
2831
.or(model_env)
2932
.or(file_cfg.model)
3033
.unwrap_or_else(|| "gpt-5-nano".to_string());
3134

32-
Config { model }
35+
let openai_api_key = api_key_cli
36+
.or(api_key_env)
37+
.or(file_cfg.openai_api_key)
38+
.expect("OPENAI_API_KEY must be set via env var or CLI");
39+
40+
Config { model, openai_api_key }
3341
}
3442
}
3543

3644
#[derive(Debug, Default, Deserialize)]
3745
struct FileConfig {
3846
/// Default model to use when not provided via CLI or env.
3947
pub model: Option<String>,
48+
pub openai_api_key: Option<String>,
4049
}
4150

4251
/// Return `~/.config/commitbot.toml`

0 commit comments

Comments
 (0)