Add CLAUDE.md with development guidance (#661)

* Add CLAUDE.md with development guidance

Provides essential commands and architecture overview for Claude Code to work effectively in this repository.

* Fix clippy warnings

Apply automatic fixes from cargo lint-fix.

* Update CLAUDE.md and apply code formatting

Add guidance to run cargo fmt after making changes and apply formatting.
This commit is contained in:
Jake Runzer 2025-09-09 20:20:10 -04:00 committed by GitHub
parent 3ffa987b62
commit 273072a69f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 12 deletions

27
CLAUDE.md Normal file
View file

@ -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 -- <args>` - 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

View file

@ -204,12 +204,12 @@ fn prompt_name(service: Option<Option<String>>) -> Result<Option<String>> {
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",
"<leave blank for randomly generated>",
"<randomly generated>",
)?)
.filter(|s| !s.trim().is_empty()));
.filter(|s| !s.trim().is_empty()))
} else {
fake_select("Enter a service name", "<randomly generated>");
Ok(None)

View file

@ -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<chrono::DateTime<chrono::Utc>>,
pub latest_version: Option<String>,
}
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<Option<String>> {
let response = response.json::<GithubApiRelease>().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()),