diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..4f43c0f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,27 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Development Commands + +- `cargo run -- ` - Run CLI during development +- `cargo test` - Run tests +- `cargo lint-fix` - Fix linting issues automatically (run after making changes) +- `cargo fmt` - Format code (run after making changes) +- `cargo clippy` - Check for linting issues +- `nix-shell` - Enter dev environment with dependencies + +## Architecture + +- **Commands**: `src/commands/` - CLI commands using clap derives, each with `exec()` function +- **Controllers**: `src/controllers/` - Business logic for Railway entities (project, service, deployment) +- **GraphQL**: `src/gql/` - Generated type-safe queries/mutations for Railway API +- **Config**: `src/config.rs` - Authentication and project settings +- **Workspace**: `src/workspace.rs` - Multi-project context handling + +### Command System +Commands use a macro system in `main.rs`. The `commands!` macro generates routing for modules in `src/commands/`. + +### Authentication +- Project tokens via `RAILWAY_TOKEN` environment variable +- User tokens via OAuth flow stored in config directory diff --git a/src/commands/add.rs b/src/commands/add.rs index 9f9778b..377ad62 100644 --- a/src/commands/add.rs +++ b/src/commands/add.rs @@ -204,12 +204,12 @@ fn prompt_name(service: Option>) -> Result> { Ok(None) } } else if std::io::stdout().is_terminal() { - return Ok(Some(prompt_text_with_placeholder_if_blank( + Ok(Some(prompt_text_with_placeholder_if_blank( "Enter a service name", "", "", )?) - .filter(|s| !s.trim().is_empty())); + .filter(|s| !s.trim().is_empty())) } else { fake_select("Enter a service name", ""); Ok(None) diff --git a/src/util/check_update.rs b/src/util/check_update.rs index 6a669c8..5c470c9 100644 --- a/src/util/check_update.rs +++ b/src/util/check_update.rs @@ -5,19 +5,11 @@ use dirs::home_dir; use super::compare_semver::compare_semver; -#[derive(serde::Serialize, serde::Deserialize)] +#[derive(serde::Serialize, serde::Deserialize, Default)] pub struct UpdateCheck { pub last_update_check: Option>, pub latest_version: Option, } -impl Default for UpdateCheck { - fn default() -> Self { - Self { - last_update_check: None, - latest_version: None, - } - } -} impl UpdateCheck { pub fn write(&self) -> anyhow::Result<()> { let home = home_dir().context("Failed to get home directory")?; @@ -64,7 +56,7 @@ pub async fn check_update(force: bool) -> anyhow::Result> { let response = response.json::().await?; let latest_version = response.tag_name.trim_start_matches('v'); - match compare_semver(env!("CARGO_PKG_VERSION"), &latest_version) { + match compare_semver(env!("CARGO_PKG_VERSION"), latest_version) { Ordering::Less => { let update = UpdateCheck { last_update_check: Some(chrono::Utc::now()),