# CLAUDE.md

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

## Project Overview

Rust CLI for deploying and managing StackAI's 50+ service Docker Compose platform on enterprise customer infrastructure (Ubuntu 24.04, 64GB RAM, 16 cores). Fortune 500 customers with 99.9% uptime SLA.

## Build & Development Commands

```bash
# Build and run
cargo run -- --help
cargo run -- deploy status
cargo run -- diagnose doctor

# Use cargo aliases (defined in .cargo/config.toml)
cargo lint        # Clippy with warnings as errors
cargo format      # Check formatting
cargo fformat     # Fix formatting
cargo test-all    # All tests with output
cargo test-verbose # Single-threaded with output

# Run specific test
cargo test vault::tests::test_encrypt_decrypt

# CI checks (what pre-commit runs)
cargo lint && cargo test-all && cargo ci-audit && cargo ci-deny

# Build release
cargo br          # Linux musl release build
```

## Safe Testing (Isolated Environment)

**Never modify real `~/.config/stackai/` during development:**

```bash
export XDG_CONFIG_HOME=$(mktemp -d)
cargo run -- init --license TEST_KEY
# Cleanup: rm -rf "$XDG_CONFIG_HOME"
```

## Command Contract (Immutable - 5 Commands Only)

```
stackai init                    # Complete bootstrap
stackai deploy {start,stop,status,logs,restart}
stackai config {domains,tls,secrets,registry,saml,sso,env}
stackai system {backup,restore,update,migrate,pull,build,cleanup,prune,templates,releases,import}
stackai diagnose {doctor,support,info}
```

**Never add new top-level commands. Never use deprecated names like `install`, `configure`, `start`, `stop`.**

## Architecture

```
src/
├── main.rs              # Entry point → dispatch
├── cli.rs               # Clap command structure
├── commands/            # Command implementations
│   ├── init.rs          # stackai init
│   ├── deploy/          # deploy {start,stop,status,logs,restart}
│   ├── config/          # config {domains,tls,secrets,...}
│   ├── system/          # system {backup,restore,update,...}
│   ├── diagnose/        # diagnose {doctor,support,info}
│   └── mod.rs           # Shared utilities (print_*, prompt_*)
├── docker.rs            # Bollard Docker API
├── compose.rs           # docker-compose.yaml parsing
├── vault.rs             # AES-256-GCM encrypted secrets
├── config.rs            # YAML config management
└── validation.rs        # Input validation
```

**4-layer service stack:**

* L1 Databases: postgres, mongodb, weaviate, redis, minio
* L2 Supabase: kong, auth, realtime, storage, studio, pooler
* L3 Backend: stackend, celery, temporal workers, unstructured
* L4 Frontend: nginx, stackweb

## Key Files

* `~/.config/stackai/docker-compose.yaml` - Generated by CLI, don't edit manually
* `~/.config/stackai/.env` - Generated secrets
* `~/.config/stackai/secrets.vault` - License-key encrypted vault
* `config/versions.json` - Platform version → service version mappings
* `config/.release` - Current deployed platform version

## Crate Conventions

| Purpose    | Use                     | Avoid                     |
| ---------- | ----------------------- | ------------------------- |
| CLI        | clap 4.5 derive         | structopt                 |
| Async      | tokio + futures-util    | std::thread blocking      |
| Docker     | bollard + compose\_spec | shelling out for core ops |
| Prompts    | inquire                 | dialoguer                 |
| Progress   | indicatif               | manual spinners           |
| Encryption | aes-gcm + argon2        | keyring                   |
| Errors     | anyhow + thiserror      | panic!/unwrap             |

## Adding a New Subcommand

1. Add variant to enum in `cli.rs`
2. Create `src/commands/{group}/newcmd.rs`
3. Export in `src/commands/{group}/mod.rs`
4. Wire dispatch in parent handler
5. Add tests in the module

## Pre-commit Checks

The repo has pre-commit hooks that run: format, lint, tests, audit, deny. All must pass before commit.

## Migration from Legacy

Import from `stackai-auto-docker` to CLI-managed deployment:

```bash
cd /path/to/legacy/stackai-auto-docker && docker compose down
stackai system import --source /path/to/legacy/stackai-auto-docker --force
sudo stackai deploy start
```

**What happens:**

* Copies volume data (postgres, mongodb, weaviate, minio, redis) → `~/.config/stackai/data/`
* Imports `.env` → encrypts secrets to `secrets.vault`
* Auto-generates `kong.yaml` with correct service names (supabase-auth, not auth)
* Detects & copies Let's Encrypt certs from `/etc/letsencrypt/live/*/`

**TLS certs:**

```bash
# Let's Encrypt wildcard certificate (recommended for production)
stackai config tls letsencrypt --email you@company.com

# Or install existing certs manually
stackai config tls install --cert /path/to/cert.pem --key /path/to/key.pem

# Or copy certs directly
sudo cp -L /etc/letsencrypt/live/DOMAIN/fullchain.pem ~/.config/stackai/config/nginx/certs/stackai.crt
sudo cp -L /etc/letsencrypt/live/DOMAIN/privkey.pem ~/.config/stackai/config/nginx/certs/stackai.key
```

## Deployment (Auto-Release)

Every push to `main` automatically produces a release:

1. **`version-check`** compares `Cargo.toml` version vs latest `v*` tag
   * If `Cargo.toml` version > latest tag → uses that version as-is
   * If `Cargo.toml` version ≤ latest tag → auto-bumps patch (e.g. 0.1.3 → 0.1.4), commits, pushes
   * Bot bump commits (`chore: bump version to *`) are skipped to prevent loops
2. **CI runs** (fmt, clippy, test, security, build) using the resolved ref
3. **Release** tags the version, bundles CLI + `config/` to S3, creates GitHub release

| Scenario                              | What happens                           |
| ------------------------------------- | -------------------------------------- |
| PR to main                            | CI only — no version check, no release |
| Merge PR (Cargo.toml unchanged)       | Auto-bumps patch, builds, releases     |
| Merge PR (Cargo.toml bumped to 1.0.0) | Detects 1.0.0 > tag, builds, releases  |
| Manual workflow\_dispatch             | CI only — no release                   |

To do a **major/minor bump**, update `Cargo.toml` version in your PR before merging.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.stackai.com/stackai-auto-cli/claude.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
