# Command Options & Feature Proposals
## π 1. 컀맨λ μ΅μ
μ μ
### A. Ask λͺ
λ Ήμ΄ μ΅μ
```rust
Ask {
/// Question to ask
question: String,
/// Stream response (live output)
#[arg(short = 's', long = "stream")]
stream: bool,
}
```
**μ¬μ© μμ:**
```bash
doum ask "Explain Rust" --stream # μ€μκ° μ€νΈλ¦¬λ°
```
---
### B. Suggest λͺ
λ Ήμ΄ μ΅μ
```rust
Suggest {
/// Request description
request: String,
/// Number of suggestions to generate
#[arg(short = 'n', long = "num", default_value = "3")]
num_suggestions: usize,
}
```
**μ¬μ© μμ:**
```bash
doum suggest "monitor CPU" --num 5 # 5κ° μ μ μμ±
```
---
### D. Secret λͺ
λ Ήμ΄ μ΅μ
```rust
Secret {
/// List all configured secrets (masked)
#[arg(short = 'l', long = "list")]
list: bool,
/// Delete/remove secret
#[arg(short = 'd', long = "delete")]
delete: bool,
/// Verify secret (test API call)
#[arg(short = 'v', long = "verify")]
verify: bool,
}
```
**μ¬μ© μμ:**
```bash
doum secret --list # λͺ¨λ secret μν νμΈ
doum secret openai --verify # OpenAI API ν€ κ²μ¦
doum secret anthropic --delete # Anthropic secret μμ
```
---
### E. Switch λͺ
λ Ήμ΄ μ΅μ
```rust
Switch {
/// Show current selection
#[arg(short = 's', long = "show")]
show: bool,
}
```
**μ¬μ© μμ:**
```bash
doum switch --show # νμ¬ provider/model νμ
```
---
### F. Global μ΅μ
```rust
#[derive(Parser, Debug)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
/// Auto mode input
#[arg(value_name = "INPUT")]
pub input: Option<String>,
/// Verbose output (debug info)
#[arg(short = 'v', long = "verbose", global = true)]
pub verbose: bool,
/// Quiet mode (minimal output)
#[arg(short = 'q', long = "quiet", global = true)]
pub quiet: bool,
/// Use specific provider for this command
#[arg(long = "provider", global = true)]
pub provider_override: Option<String>,
/// Use specific model for this command
#[arg(long = "model", global = true)]
pub model_override: Option<String>,
/// Disable web search for this command
#[arg(long = "no-web-search", global = true)]
pub no_web_search: bool,
}
```
**μ¬μ© μμ:**
```bash
doum ask "What is Rust?" --verbose # λλ²κ·Έ μ 보 νμ
doum suggest "find files" --quiet # μ΅μ μΆλ ₯
doum ask "latest news" --provider anthropic # μΌνμ± provider λ³κ²½
doum suggest "list processes" --model gpt-5-mini # μΌνμ± model λ³κ²½
doum ask "Define AI" --no-web-search # μΉ κ²μ λΉνμ±ν
```
---
## π 2. μΆκ° λͺ
λ Ήμ΄ μ μ
### A. `history` - λͺ
λ Ή μ΄λ ₯ κ΄λ¦¬
```bash
doum history [OPTIONS]
```
**μ΅μ
:**
```rust
History {
/// Show last N commands
#[arg(short = 'n', default_value = "10")]
num: usize,
/// Search history
#[arg(short = 's', long = "search")]
search: Option<String>,
/// Clear history
#[arg(long = "clear")]
clear: bool,
/// Re-run command by ID
#[arg(short = 'r', long = "rerun")]
rerun: Option<usize>,
}
```
**μ¬μ© μμ:**
```bash
doum history # μ΅κ·Ό 10κ° νμ
doum history -n 50 # μ΅κ·Ό 50κ°
doum history --search "docker" # "docker" ν¬ν¨ κ²μ
doum history --clear # μ΄λ ₯ μμ
```
**μ μ₯ νμ** (`~/.config/doum-cli/history.json`):
```json
[
{
"id": 1,
"timestamp": "2025-11-26T14:30:22Z",
"command": "ask",
"input": "What is Docker?",
"provider": "openai",
"model": "gpt-5",
"success": true
}
]
```
---
### B. `upgrade` - μλ μ
λ°μ΄νΈ
```bash
doum upgrade [OPTIONS]
```
**μ΅μ
:**
```rust
Upgrade {
/// Check for updates without installing
#[arg(short = 'c', long = "check")]
check: bool,
/// Upgrade to specific version
#[arg(short = 'v', long = "version")]
version: Option<String>,
}
```
**λμ:**
1. GitHub Releases API νμΈ
2. νμ¬ λ²μ κ³Ό λΉκ΅
3. μ λ²μ μ΄ μμΌλ©΄ λ€μ΄λ‘λ λ° μ€μΉ
**μ¬μ© μμ:**
```bash
doum upgrade # μ΅μ λ²μ μΌλ‘ μ
λ°μ΄νΈ
doum upgrade --check # μ
λ°μ΄νΈ κ°λ₯ μ¬λΆλ§ νμΈ
doum upgrade --version 0.2.5 # νΉμ λ²μ μΌλ‘
```
**ꡬν μμ΄λμ΄:**
```rust
// src/cli/upgrade.rs
use reqwest;
use semver::Version;
pub async fn check_for_updates() -> Result<Option<String>> {
let current = env!("CARGO_PKG_VERSION");
let url = "https://api.github.com/repos/junhyungL/doum-cli/releases/latest";
let response: serde_json::Value = reqwest::get(url).await?.json().await?;
let latest = response["tag_name"].as_str().unwrap().trim_start_matches('v');
if Version::parse(latest)? > Version::parse(current)? {
Ok(Some(latest.to_string()))
} else {
Ok(None)
}
}
```
---
### C. `context` - 컨ν
μ€νΈ κ΄λ¦¬
```bash
doum context [OPTIONS]
```
**κΈ°λ₯:**
- νμ¬ λλ ν 리μ νμΌ/ꡬ쑰λ₯Ό LLM 컨ν
μ€νΈλ‘ ν¬ν¨
- νλ‘μ νΈλ³ 컨ν
μ€νΈ μ μ₯
**μ΅μ
:**
```rust
Context {
/// Add files to context
#[arg(short = 'a', long = "add")]
add: Vec<PathBuf>,
/// Show current context
#[arg(short = 's', long = "show")]
show: bool,
}
```
**μ¬μ© μμ:**
```bash
doum context --add src/**/*.rs # Rust νμΌ μΆκ°
doum context --show # νμ¬ μ»¨ν
μ€νΈ νμ
doum ask "Refactor this code" --with-context # 컨ν
μ€νΈ ν¬ν¨ μ§λ¬Έ
```
---
## π 3. λ²μ κ΄λ¦¬ λ°©λ² μ μ
### A. Semantic Versioning (semver)
```toml
[package]
version = "0.1.0" # MAJOR.MINOR.PATCH
```
**κ·μΉ:**
- **MAJOR**: Breaking changes (config νμ λ³κ²½ λ±)
- **MINOR**: μ κΈ°λ₯ μΆκ° (μ λͺ
λ Ήμ΄, μ΅μ
)
- **PATCH**: λ²κ·Έ μμ
---
### B. Upgrade λͺ
λ Ήμ΄ κ΅¬ν
**Cargo.toml**:
```toml
[dependencies]
self_update = "0.39" # μλ μ
λ°μ΄νΈ λΌμ΄λΈλ¬λ¦¬
```
**src/cli/upgrade.rs**:
```rust
use self_update::backends::github::{ReleaseList, Update};
use self_update::cargo_crate_version;
pub fn handle_upgrade_command(check_only: bool, force: bool) -> Result<()> {
let current_version = cargo_crate_version!();
println!("π Checking for updates...");
println!("Current version: {}", current_version);
let releases = ReleaseList::configure()
.repo_owner("junhyungL")
.repo_name("doum-cli")
.build()?
.fetch()?;
if let Some(latest) = releases.first() {
let latest_version = latest.version.trim_start_matches('v');
if latest_version > current_version || force {
if check_only {
println!("β¨ New version available: {}", latest_version);
return Ok(());
}
println!("π₯ Downloading version {}...", latest_version);
Update::configure()
.repo_owner("junhyungL")
.repo_name("doum-cli")
.bin_name("doum")
.current_version(current_version)
.build()?
.update()?;
println!("β
Successfully upgraded to {}", latest_version);
} else {
println!("β
Already up-to-date!");
}
}
Ok(())
}
```
---