Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Cargo aliases (simpler alternative to cargo-make)
# Usage: cargo <alias-name>
# Examples: cargo b (build), cargo r (run), cargo t (test), cargo cl (clippy)

[alias]
# Build aliases
b = "build"
br = "build --release"
c = "check"

# Run aliases
r = "run"
rr = "run --release"

# Test aliases
t = "test"
tt = "test -- --nocapture"

# Linting/formatting
cl = "clippy -- -D warnings"
f = "fmt"
fc = "fmt -- --check"

# Clean
clean-all = "clean"

# Combined tasks (use scripts/pre-commit.sh for combined workflow)
# Note: Cargo aliases don't support shell operators like &&
# Run these commands separately:
# cargo fmt
# cargo clippy -- -D warnings
# cargo test
39 changes: 39 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
dev-debug.log

# Dependency directories
node_modules/

# Environment variables
.env

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# OS specific
.DS_Store


# Added by cargo

/target

# Local config files
.clai.toml

# TaskMaster (local to developer, not tracked in Git)
.taskmaster/

# Cursor IDE (local to developer, not tracked in Git)
.cursor/
72 changes: 72 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

clai is a CLI tool that converts natural language into shell commands using AI. It follows Unix philosophy: simple, composable, and privacy-respecting. Users provide instructions like `clai "find all rust files modified today"` and get executable shell commands back.

## Build and Development Commands

```bash
cargo build # Debug build
cargo build --release # Release build
cargo test # Run all tests
cargo test <test_name> # Run a single test
cargo clippy -- -D warnings # Lint (warnings are errors)
cargo fmt # Format code
cargo bench --features bench # Run benchmarks
cargo run -- "instruction" # Run with an instruction
```

Pre-commit checks (run before committing):
```bash
./scripts/pre-commit.sh # Runs fmt, clippy, and tests
```

## Architecture

### Core Flow

`main.rs` orchestrates the pipeline:
1. Parse CLI args → `cli/mod.rs` (clap-based)
2. Load config → `config/` (layered: .clai.toml > ~/.config/clai/config.toml > /etc/clai/config.toml)
3. Gather context → `context/` (system info, cwd, files, shell history, stdin)
4. Build prompt → `ai/prompt.rs`
5. Call AI provider → `ai/providers/` (OpenRouter via provider chain)
6. Safety check → `safety/` (dangerous command detection with regex patterns)
7. Output or execute → `output/`, `safety/interactive.rs`

### Key Modules

- **ai/**: AI provider abstraction with async traits. `handler.rs` orchestrates generation, `chain.rs` manages provider fallback, `providers/openrouter.rs` is the primary implementation.
- **config/**: Layered config system. `paths.rs` discovers config files, `loader.rs` loads/validates TOML, `merger.rs` combines configs, `cache.rs` provides lazy caching.
- **context/**: Gathers system context for prompts. `gatherer.rs` orchestrates, individual modules handle system info, directory scanning, shell history, and stdin.
- **safety/**: Dangerous command detection. `patterns.rs` defines regex patterns, `detector.rs` matches commands, `confirmation.rs` and `interactive.rs` handle user prompts.
- **error/**: Typed errors with exit codes (1=general, 2=usage, 3=config, 4=API, 5=safety, 130=interrupted).

### Design Patterns

- **Pure functions preferred**: Most functions are pure transformations. I/O is isolated to main.rs and handler functions.
- **Immutable Config**: Config struct is immutable after creation from CLI args.
- **Strict stdout/stderr**: stdout = commands only (for piping), stderr = logs/warnings.
- **Async with tokio**: AI calls use async/await with reqwest.

## Configuration

Environment variables:
- `OPENROUTER_API_KEY` - Required for AI provider
- `NO_COLOR` - Disable colored output

Config file locations (highest to lowest priority):
1. `./.clai.toml` (project-local)
2. `~/.config/clai/config.toml` (user)
3. `/etc/clai/config.toml` (system)

## Testing

Tests are co-located in the same files as implementation (`#[cfg(test)]` modules). Run specific test file with:
```bash
cargo test --lib config::tests
cargo test --lib safety::tests
```
138 changes: 138 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Contributing to clai

## Development Setup

### Prerequisites

- Rust 1.70+
- OpenRouter API key (for testing AI features)

```bash
git clone https://github.com/Vedaant-Rajoo/clAI.git
cd clAI
cargo build

# Install Git hooks (recommended)
./scripts/install-hooks.sh
```

### Running

```bash
cargo run -- "your instruction"
```

## Project Structure

```
src/
Comment on lines +27 to +28
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language identifier to fenced code block.

The code block at line 27 lacks a language identifier, causing markdown linting failures.

🔎 Proposed fix
-```
+```text
 src/
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
src/
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

27-27: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In @CONTRIBUTING.md around lines 27 - 28, The fenced code block that currently
contains just "src/" is missing a language identifier and triggers markdown
linting; update the fenced block that contains "src/" to include a language tag
(for example use "text" or "bash") after the opening triple backticks so the
block becomes a properly labeled fenced code block.

├── main.rs # Entry point
├── lib.rs # Library exports
├── cli/ # Argument parsing
├── config/ # Configuration loading
├── context/ # System/directory context gathering
├── ai/ # AI provider abstraction
│ └── providers/ # OpenRouter, etc.
├── safety/ # Dangerous command detection
└── error/ # Error types and exit codes
```

## Commands

```bash
cargo build # Debug build
cargo build --release # Release build
cargo test # Run tests
cargo clippy # Lint
cargo fmt # Format
cargo bench --features bench # Run benchmarks
```

## Configuration

### Environment Variables

| Variable | Description |
| -------------------- | ---------------------- |
| `OPENROUTER_API_KEY` | API key for OpenRouter |
| `NO_COLOR` | Disable colored output |

### Config File Locations

1. `./.clai.toml` (project-local, highest priority)
2. `~/.config/clai/config.toml` (user)
3. `/etc/clai/config.toml` (system)

Comment on lines +62 to +65
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Document XDG_CONFIG_HOME support in config file precedence.

The implementation in src/config/paths.rs supports $XDG_CONFIG_HOME/clai/config.toml as the second priority, but this is not reflected in the documentation.

🔎 Proposed fix

Update the list to include all four locations:

 1. `./.clai.toml` (project-local, highest priority)
-2. `~/.config/clai/config.toml` (user)
-3. `/etc/clai/config.toml` (system)
+2. `$XDG_CONFIG_HOME/clai/config.toml` (if XDG_CONFIG_HOME is set)
+3. `~/.config/clai/config.toml` (fallback if XDG_CONFIG_HOME not set)
+4. `/etc/clai/config.toml` (system, lowest priority)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1. `./.clai.toml` (project-local, highest priority)
2. `~/.config/clai/config.toml` (user)
3. `/etc/clai/config.toml` (system)
1. `./.clai.toml` (project-local, highest priority)
2. `$XDG_CONFIG_HOME/clai/config.toml` (if XDG_CONFIG_HOME is set)
3. `~/.config/clai/config.toml` (fallback if XDG_CONFIG_HOME not set)
4. `/etc/clai/config.toml` (system, lowest priority)
🤖 Prompt for AI Agents
In @CONTRIBUTING.md around lines 62 - 65, Update the CONTRIBUTING.md config
precedence list to reflect the implementation in src/config/paths.rs by adding
the XDG_CONFIG_HOME entry: include `$XDG_CONFIG_HOME/clai/config.toml` as the
second priority (after `./.clai.toml`), shifting the user and system paths
accordingly so the four locations match the code: `./.clai.toml`,
`$XDG_CONFIG_HOME/clai/config.toml`, `~/.config/clai/config.toml`, and
`/etc/clai/config.toml`.

### Full Config Example

```toml
[provider]
default = "openrouter"
api-key = "${OPENROUTER_API_KEY}"

[provider.openrouter]
model = "qwen/qwen3-coder"

[context]
max-history = 3
max-files = 10

[safety]
confirm-dangerous = true
dangerous-patterns = [
"rm -rf",
"sudo.*rm",
".*> /dev/sd[a-z]",
]

[ui]
interactive = true
color = "auto"
```

## Exit Codes

| Code | Meaning |
| ---- | ----------------------------------------- |
| 0 | Success |
| 1 | General error |
| 2 | Usage error |
| 3 | Configuration error |
| 4 | API error |
| 5 | Safety error (dangerous command rejected) |
| 130 | Interrupted (Ctrl+C) |

## Pull Request Process

1. Fork and create a feature branch
2. Install Git hooks: `./scripts/install-hooks.sh` (if not already done)
3. Make changes
4. The pre-commit hook will automatically run checks before each commit:
- Format code with `cargo fmt`
- Run `cargo clippy -- -D warnings`
- Run `cargo test`
5. If you need to bypass the hook temporarily: `git commit --no-verify`
6. Submit PR

### Manual Checks

If you haven't installed the Git hooks, run these commands before committing:

```bash
./scripts/pre-commit.sh # Run all checks
```

Or individually:

```bash
cargo fmt # Format code
cargo clippy -- -D warnings # Check lints
cargo test # Run tests
```

## Code Style

- Follow `cargo fmt` formatting
- Use `cargo clippy` for lints
- Write tests for new features
- Document public APIs
Loading