diff --git a/llms.txt b/llms.txt deleted file mode 100644 index f84614e..0000000 --- a/llms.txt +++ /dev/null @@ -1,1066 +0,0 @@ -# ee - Environment Variable Management CLI - -> ee is a CLI tool that brings structure and validation to environment variable management. It uses `.ee` project configuration files, `.env` files, and optional schema files to define, validate, and deploy environment variables across environments. - -## Installation - -```bash -curl -sSfL https://ee.n1rna.net/install.sh | sh -``` - -Or build from source: - -```bash -git clone https://github.com/n1rna/ee-cli.git -cd ee-cli -go build -o ee ./cmd/ee -``` - -## AI Coding Agent Skill - -Instead of copying this file around, install the ee usage guide directly into the -convention your AI coding agent expects with `ee skill `: - -```bash -ee skill claude # -> .claude/skills/ee-usage/SKILL.md -ee skill cursor # -> .cursor/rules/ee-usage.mdc -ee skill copilot # -> .github/copilot-instructions.md -ee skill codex # -> AGENTS.md -ee skill opencode # -> AGENTS.md -ee skill all # install for every supported agent -``` - -The installed guide covers adding ee to a new project, working with a project that -already has ee configured, the file formats, and the full command reference. See -the `ee skill` command below for details. - -## Core Concepts - -### Project Configuration (`.ee` file) - -Every ee project has a `.ee` file (JSON) in the project root. It defines: -- **project**: Project name identifier -- **schema**: Variable definitions (inline or file reference) -- **environments**: Named environment configurations pointing to `.env` files -- **origins**: Remote targets for pushing secrets (GitHub, Cloudflare) - -### Environment Variables - -Variables are stored in standard `.env` files (KEY=VALUE format). Environments can reference a single `.env` file or stack multiple sources with later values overriding earlier ones. - -### Schemas - -Schemas define the expected structure of environment variables — types, defaults, required flags, and validation patterns. Schemas are loaded from YAML or JSON files referenced in the `.ee` file. - ---- - -## Project Configuration File Format - -The `.ee` file is JSON with this structure: - -```json -{ - "project": "my-api", - "schema": { - "ref": "./schema.yaml" - }, - "environments": { - "development": { - "env": ".env.development" - }, - "production": { - "env": ".env.production" - } - }, - "origins": { - "github": { - "type": "github", - "mode": "bundled", - "secret_name": "ENV_PRODUCTION", - "repo": "myorg/my-app", - "environment": "production" - } - } -} -``` - -### Schema Section - -The schema can be **inline** (variables defined directly) or a **file reference**. - -#### Inline Schema - -```json -{ - "schema": { - "variables": { - "DATABASE_URL": { - "name": "DATABASE_URL", - "type": "string", - "title": "Database connection URL", - "required": true - }, - "PORT": { - "name": "PORT", - "type": "number", - "title": "Server port", - "required": false, - "default": "3000" - }, - "DEBUG": { - "name": "DEBUG", - "type": "boolean", - "title": "Debug mode", - "required": false, - "default": "false" - } - } - } -} -``` - -#### File Reference Schema - -```json -{ - "schema": { - "ref": "./schema.yaml" - } -} -``` - -Supported reference formats: -- `./schema.yaml` or `../schema.yaml` — relative path -- `/absolute/path/schema.yaml` — absolute path -- `file://path/to/schema.yaml` — explicit file URI -- `schema.yaml` — plain filename (must have .yaml/.yml/.json extension) - -### Environment Section - -Each environment maps to `.env` file sources. - -#### Single Source - -```json -{ - "environments": { - "development": { - "env": ".env.development" - } - } -} -``` - -#### Multiple Sources (Stacking) - -Later sources override earlier ones: - -```json -{ - "environments": { - "production": { - "sources": [".env", ".env.production", ".env.secrets"] - } - } -} -``` - -#### Inline Values in Sources - -Sources can include inline key-value objects: - -```json -{ - "environments": { - "staging": { - "sources": [ - ".env", - ".env.staging", - { "LOG_LEVEL": "debug", "FEATURE_FLAG": "true" } - ] - } - } -} -``` - -### Origins Section - -Origins define remote targets for pushing secrets. - -#### GitHub Origin - -```json -{ - "origins": { - "github": { - "type": "github", - "mode": "bundled", - "secret_name": "ENV_PRODUCTION", - "repo": "myorg/my-app", - "environment": "production" - } - } -} -``` - -Fields: -- `type`: `"github"` (required) -- `mode`: `"bundled"` (default) or `"individual"` -- `secret_name`: Name for the bundled secret (default: `ENV_`) -- `repo`: GitHub repo in `owner/repo` format (default: current repo) -- `environment`: GitHub environment name for scoped secrets - -#### Cloudflare Origin - -```json -{ - "origins": { - "cloudflare": { - "type": "cloudflare", - "mode": "individual", - "worker": "my-worker" - } - } -} -``` - -Fields: -- `type`: `"cloudflare"` (required) -- `mode`: `"individual"` (default) or `"bundled"` -- `worker`: Cloudflare Worker name (required) - ---- - -## Schema File Format - -Schema files define variable structure in YAML or JSON. - -### YAML Schema Example - -```yaml -name: web-service -description: Schema for web service applications -variables: - - name: DATABASE_URL - title: Database connection URL - type: string - required: true - - name: PORT - title: Server port - type: number - required: false - default: "3000" - - name: DEBUG - title: Debug mode - type: boolean - required: false - default: "false" - - name: API_KEY - title: API authentication key - type: string - required: true - regex: "^[a-zA-Z0-9_-]+$" -``` - -### JSON Schema Example - -```json -{ - "name": "web-service", - "description": "Schema for web service applications", - "variables": [ - { - "name": "DATABASE_URL", - "type": "string", - "title": "Database connection URL", - "required": true - }, - { - "name": "PORT", - "type": "number", - "default": "3000", - "required": false - } - ] -} -``` - -### Variable Properties - -| Property | Type | Required | Description | -|------------|---------|----------|------------------------------------------------| -| `name` | string | yes | Variable name (e.g., `DATABASE_URL`) | -| `type` | string | yes | `string`, `number`, `boolean`, or `url` | -| `title` | string | no | Human-readable description | -| `required` | boolean | yes | Whether the variable must be set | -| `default` | string | no | Default value if not provided | -| `regex` | string | no | Validation regex pattern | - ---- - -## CLI Commands - -### `ee` (Root Command) - -Display and filter environment variables in the current shell. - -```bash -# Show all environment variables -ee - -# Filter by pattern -ee --filter 'NODE*' -ee --filter 'DB_*,DATABASE_*' - -# Exclude patterns (prefix with !) -ee --filter '!CLAUDE*,!PATH*' - -# Combine include and exclude -ee --filter 'NODE*,!NODE_OPTIONS' - -# Output as JSON -ee --format json - -# Output as dotenv -ee --format dotenv - -# Mask sensitive values (KEY, SECRET, TOKEN, PASSWORD, etc.) -ee --mask - -# Combine flags -ee --filter '*KEY*,*SECRET*' --mask --format json -``` - -**Flags:** -- `-I, --filter ` — Filter variables using wildcard patterns. Separators: `,`, `|`, `/`. Prefix with `!` to exclude. -- `-f, --format ` — Output format: `env` (default), `json`, `dotenv` -- `-m, --mask` — Replace sensitive values with `***MASKED***` - -**Pattern syntax:** Uses shell glob matching (`*` any chars, `?` single char, `[abc]` character class). - -**Filter logic:** -1. If a negative pattern matches → exclude -2. If any positive pattern matches → include -3. If only negative patterns exist → include everything except matches -4. If positive patterns exist → only include matches - ---- - -### `ee init [project-name]` - -Initialize a new ee project. - -```bash -# Initialize with current directory name -ee init - -# Initialize with specific name -ee init my-api - -# Initialize with schema file reference -ee init my-api --schema ./schema.yaml - -# Initialize with inline variables -ee init my-api \ - --var "DATABASE_URL:string:Database URL:true" \ - --var "PORT:number:Server port:false:3000" - -# Overwrite existing .ee file -ee init my-api --force -``` - -**Flags:** -- `-s, --schema ` — Schema file reference -- `--var ` — Inline variable in `name:type:title:required[:default]` format (repeatable) -- `-f, --force` — Overwrite existing `.ee` file -- `-q, --quiet` — Suppress output - -**What it creates:** -- `.ee` configuration file -- `.env.development` sample file -- `.env.production` sample file -- Default inline schema with `NODE_ENV`, `PORT`, `DEBUG` if no schema specified - ---- - -### `ee apply [-- command [args...]]` - -Apply environment variables from project environments or `.env` files. - -```bash -# Start a new shell with development environment -ee apply development - -# Run a command with production environment -ee apply production -- npm start -ee apply development -- npm test - -# Apply a .env file directly (no .ee file needed) -ee apply .env -ee apply .env.staging -ee apply /path/to/.env.production -- node server.js - -# Preview what would be applied (dry-run) -ee apply development --dry-run -ee apply development --dry-run --format json -ee apply development --dry-run --format dotenv - -# Export environment to file -ee apply production --dry-run --format dotenv > .env.prod -ee apply production --dry-run --format json > config.json -``` - -**Flags:** -- `-d, --dry-run` — Show variables without applying -- `-f, --format ` — Dry-run output format: `env` (default), `dotenv`, `json` -- `-q, --quiet` — Suppress informational output - -**Alias:** `ee a` is shorthand for `ee apply` - -**How it detects file vs environment:** -- Starts with `.`, `/`, or `~` → treated as file path -- File exists on disk → treated as file path -- Otherwise → treated as project environment name (requires `.ee` file) - -**How environments resolve:** -1. Find the environment definition in `.ee` -2. If `env` field set → load that single `.env` file -3. If `sources` array set → merge all sources left-to-right (later overrides earlier) -4. Apply variables to a new shell or run the specified command - ---- - -### `ee verify` - -Verify project configuration against schema and environment files. - -```bash -# Verify current project -ee verify - -# Verify with detailed output -ee verify --verbose - -# Verify specific environment only -ee verify --env development - -# Auto-fix issues (create missing files, add missing variables) -ee verify --fix -``` - -**Flags:** -- `--fix` — Auto-fix detected issues -- `--verbose` — Show detailed output including warnings -- `--env ` — Verify only one environment -- `--quiet` — Suppress output - -**What it checks:** -- Schema file can be loaded (if referenced) -- Each environment has a corresponding `.env` file -- Required variables from schema are present in `.env` files -- Variables in `.env` files match schema definitions - -**What `--fix` does:** -- Creates missing `.env` files with schema defaults -- Appends missing required variables to existing `.env` files - ---- - -### `ee hydrate ` - -Generate an env file by resolving schema variables from the current shell environment. - -```bash -# Print hydrated env to stdout -ee hydrate development - -# Write to file -ee hydrate development -o .env - -# Output as JSON -ee hydrate development -f json - -# Output as YAML -ee hydrate development -f yaml -o config.yaml -``` - -**Flags:** -- `-o, --output ` — Write to file instead of stdout -- `-f, --format ` — Output format: `dotenv` (default), `json`, `yaml` - -**Resolution order for each schema variable:** -1. Current shell environment value (if set) -2. Schema default value -3. Empty string (warns for required variables) - ---- - -### `ee push [origin] ` - -Push environment secrets to a remote origin (GitHub or Cloudflare). - -```bash -# Push to the only configured origin -ee push production - -# Push to a specific origin by name -ee push github production - -# Preview what would be pushed -ee push production --dry-run - -# Override push mode -ee push production --mode individual -ee push production --mode bundled -``` - -**Flags:** -- `--dry-run` — Preview without pushing -- `--quiet` — Suppress output -- `--mode ` — Override push mode: `bundled` or `individual` - -**Push modes:** -- **bundled** (default for GitHub): All secrets combined into a single multi-line `KEY=VALUE` secret. Compatible with [ee-action](https://github.com/n1rna/ee-action) GitHub Action. -- **individual** (default for Cloudflare): Each secret pushed as a separate key-value pair. - -**Prerequisites:** -- GitHub: `gh` CLI installed and authenticated (`gh auth login`) -- Cloudflare: `wrangler` CLI installed and authenticated (`wrangler login`) - ---- - -### `ee auth [tool]` - -Check authentication status for origin CLI tools. - -```bash -# Check all tools used by configured origins -ee auth - -# Check specific tool -ee auth gh -ee auth wrangler -``` - -**Supported tools:** -- `gh` — GitHub CLI (checks `gh auth status`) -- `wrangler` — Cloudflare Wrangler (checks `wrangler whoami`) - ---- - -### `ee skill ` - -Install the ee usage guide as a skill for an AI coding agent, so it knows how to -work with ee in the current project. - -```bash -# Install for a specific agent -ee skill claude -ee skill cursor --force - -# Install for every supported agent -ee skill all - -# List supported agents -ee skill --list - -# Print the guide to stdout instead of writing a file -ee skill claude --print -``` - -**Supported agents and install paths:** - -| Agent | Path | Format | -|------------|---------------------------------------|----------------------------| -| `claude` | `.claude/skills/ee-usage/SKILL.md` | Skill with YAML frontmatter | -| `cursor` | `.cursor/rules/ee-usage.mdc` | Rule with YAML frontmatter | -| `copilot` | `.github/copilot-instructions.md` | Plain markdown | -| `codex` | `AGENTS.md` | Plain markdown | -| `opencode` | `AGENTS.md` | Plain markdown | -| `all` | all of the above | — | - -**Flags:** -- `-f, --force` — Overwrite an existing skill file -- `-l, --list` — List supported agents and exit -- `-p, --print` — Print the guide to stdout instead of writing a file -- `-q, --quiet` — Suppress non-error output - ---- - -## Common Workflows - -### Setting Up a New Project - -```bash -# 1. Create project directory -mkdir my-api && cd my-api - -# 2. Create a schema file -cat > schema.yaml << 'EOF' -name: my-api -description: API service configuration -variables: - - name: DATABASE_URL - type: string - title: Database connection string - required: true - - name: PORT - type: number - title: Server port - required: false - default: "3000" - - name: NODE_ENV - type: string - title: Node environment - required: true - default: "development" - - name: JWT_SECRET - type: string - title: JWT signing secret - required: true -EOF - -# 3. Initialize project with schema -ee init my-api --schema ./schema.yaml - -# 4. Edit the generated .env files -# .env.development and .env.production were created with defaults - -# 5. Verify configuration -ee verify --verbose - -# 6. Use the environment -ee apply development -- npm start -``` - -### Multi-Environment Configuration - -`.ee` file: -```json -{ - "project": "my-app", - "schema": { "ref": "./schema.yaml" }, - "environments": { - "development": { - "sources": [".env", ".env.development"] - }, - "staging": { - "sources": [".env", ".env.staging"] - }, - "production": { - "sources": [".env", ".env.production", ".env.secrets"] - } - } -} -``` - -`.env` (shared base): -``` -APP_NAME=my-app -LOG_FORMAT=json -``` - -`.env.development`: -``` -DATABASE_URL=postgres://localhost:5432/myapp_dev -PORT=3000 -DEBUG=true -``` - -`.env.production`: -``` -DATABASE_URL=postgres://prod-host:5432/myapp -PORT=8080 -DEBUG=false -``` - -```bash -# Apply development -ee apply development -- npm run dev - -# Export production config -ee apply production --dry-run --format dotenv > .env.prod - -# Compare environments -diff <(ee apply development --dry-run) <(ee apply production --dry-run) -``` - -### Pushing Secrets to GitHub - -`.ee` file: -```json -{ - "project": "my-app", - "schema": { "ref": "./schema.yaml" }, - "environments": { - "production": { "env": ".env.production" } - }, - "origins": { - "github": { - "type": "github", - "mode": "bundled", - "secret_name": "ENV_PRODUCTION", - "repo": "myorg/my-app", - "environment": "production" - } - } -} -``` - -```bash -# Check authentication -ee auth gh - -# Preview what would be pushed -ee push github production --dry-run - -# Push secrets -ee push github production -``` - -### Pushing Secrets to Cloudflare Workers - -`.ee` file: -```json -{ - "project": "my-worker", - "schema": { "ref": "./schema.yaml" }, - "environments": { - "production": { "env": ".env.production" } - }, - "origins": { - "cloudflare": { - "type": "cloudflare", - "mode": "individual", - "worker": "my-worker" - } - } -} -``` - -```bash -# Check authentication -ee auth wrangler - -# Push individual secrets -ee push cloudflare production -``` - -### Inspecting Current Environment - -```bash -# See all environment variables -ee - -# Find database-related variables -ee --filter 'DB_*,DATABASE_*,POSTGRES_*' - -# See all URLs -ee --filter '*_URL,*_ENDPOINT' - -# Audit secrets (masked) -ee --filter '*KEY*,*SECRET*,*TOKEN*,*PASSWORD*' --mask - -# Export current environment -ee --format dotenv > current.env -ee --format json > environment.json - -# Filter and export -ee --filter 'APP_*,!*SECRET*' --format dotenv > safe-config.env -``` - -### CI/CD Integration - -```bash -# Validate environment before deployment -ee verify --env production - -# Generate .env file for Docker -ee apply production --dry-run --format dotenv > .env -docker-compose --env-file .env up - -# Push secrets to GitHub Actions -ee push github production -``` - -### GitHub Actions with ee-action - -The recommended way to use `ee` in GitHub Actions is with the [ee-action](https://github.com/n1rna/ee-action) composite action. - -**Workflow:** -1. Push secrets from your local machine using `ee push github production` (bundled mode) -2. In your GitHub Actions workflow, use `ee-action` to hydrate environment files from the bundled secret - -```yaml -# .github/workflows/deploy.yml -name: Deploy -on: - push: - branches: [main] - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Prepare environment - uses: n1rna/ee-action@v1 - with: - environment: production - config_path: .ee - env_file: .env.production - gh_secret: ${{ secrets.ENV_PRODUCTION }} - - # .env.production is now available for subsequent steps - - run: docker build --env-file .env.production -t myapp . -``` - -**Multi-service example** (separate .ee configs per service): - -```yaml -steps: - - uses: actions/checkout@v4 - - - name: Prepare web environment - uses: n1rna/ee-action@v1 - with: - environment: production - config_path: .ee.web - env_file: .env.web.production - gh_secret: ${{ secrets.ENV_FILE_WEB }} - - - name: Prepare API environment - uses: n1rna/ee-action@v1 - with: - environment: production - config_path: .ee.api - env_file: .env.api.production - gh_secret: ${{ secrets.ENV_FILE_API }} -``` - -**JSON output for application config:** - -```yaml -- name: Generate JSON config - uses: n1rna/ee-action@v1 - with: - environment: production - config_path: .ee - env_file: config.json - gh_secret: ${{ secrets.ENV_PRODUCTION }} - format: json -``` - -**Pinning a specific ee version:** - -```yaml -- uses: n1rna/ee-action@v1 - with: - environment: production - config_path: .ee - env_file: .env - gh_secret: ${{ secrets.ENV_PRODUCTION }} - ee_version: v0.8.2 -``` - ---- - -## GitHub Actions (ee-action) Reference - -[ee-action](https://github.com/n1rna/ee-action) provides two reusable GitHub Actions for the ee CLI: - -| Action | Usage | Description | -|--------|-------|-------------| -| **Hydrate** | `n1rna/ee-action@v1` | Generate env files from GitHub secrets + schema defaults | -| **Push** | `n1rna/ee-action/push@v1` | Push env secrets to GitHub or Cloudflare | - -### Hydrate Action (`n1rna/ee-action@v1`) - -Generates environment files from a bundled GitHub secret using `ee hydrate`. - -**How it works:** -1. Installs the ee CLI from GitHub releases (auto-detects OS and architecture) -2. Writes `gh_secret` (a multi-line `KEY=VALUE` string) to a temp file -3. Runs `ee apply` on the temp file to load the secret values as environment variables -4. Runs `ee hydrate` in that context to resolve schema variables and produce the output file -5. Cleans up the temp file - -**Inputs:** - -| Input | Required | Default | Description | -|-------|----------|---------|-------------| -| `environment` | Yes | — | Target environment name passed to `ee hydrate` | -| `config_path` | Yes | — | Path to the `.ee` config file | -| `env_file` | Yes | — | Output file path for the generated env file | -| `gh_secret` | Yes | — | Multi-line `KEY=VALUE` string from a GitHub secret | -| `format` | No | `dotenv` | Output format: `dotenv`, `json`, `yaml` | -| `ee_version` | No | `latest` | ee CLI version to install (e.g., `v0.8.2`) | - -### Push Action (`n1rna/ee-action/push@v1`) - -Pushes environment secrets from `.env` files to GitHub Actions secrets or Cloudflare Workers. Useful when you have a repo dedicated to managing environment files and want to sync them to remote targets on commit. - -**How it works:** -1. Installs the ee CLI from GitHub releases (auto-detects OS and architecture) -2. Installs wrangler if a Cloudflare API token is provided -3. Runs `ee push` with the configured origin, environment, and mode - -**Inputs:** - -| Input | Required | Default | Description | -|-------|----------|---------|-------------| -| `environment` | Yes | — | Target environment name to push | -| `config_path` | No | `.ee` | Path to the `.ee` config file | -| `origin` | No | *(auto)* | Origin name (auto-resolved if only one configured) | -| `mode` | No | *(from config)* | Override push mode: `bundled` or `individual` | -| `dry_run` | No | `false` | Preview what would be pushed without executing | -| `gh_token` | No | — | GitHub token for `gh` CLI (required for GitHub origins) | -| `cloudflare_api_token` | No | — | Cloudflare API token for `wrangler` (required for Cloudflare origins) | -| `ee_version` | No | `latest` | ee CLI version to install | - -**Push to GitHub:** - -```yaml -- name: Push secrets to GitHub - uses: n1rna/ee-action/push@v1 - with: - environment: production - config_path: .ee - origin: github - gh_token: ${{ secrets.GH_PAT }} -``` - -> Note: `GITHUB_TOKEN` cannot create/update secrets in other repos. Use a PAT with `repo` scope. - -**Push to Cloudflare Workers:** - -```yaml -- name: Push secrets to Cloudflare - uses: n1rna/ee-action/push@v1 - with: - environment: production - config_path: .ee - origin: cloudflare - cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }} -``` - -### End-to-End Workflow - -**Central env repo** pushes secrets to targets on commit: - -```yaml -# env-repo/.github/workflows/sync-secrets.yml -name: Sync Secrets -on: - push: - branches: [main] - -jobs: - push-secrets: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Push API secrets to GitHub - uses: n1rna/ee-action/push@v1 - with: - environment: production - config_path: .ee.api - origin: github - gh_token: ${{ secrets.GH_PAT }} - - - name: Push worker secrets to Cloudflare - uses: n1rna/ee-action/push@v1 - with: - environment: production - config_path: .ee.worker - origin: cloudflare - cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }} -``` - -**Consuming repo** hydrates the secrets at deploy time: - -```yaml -# app-repo/.github/workflows/deploy.yml -steps: - - uses: actions/checkout@v4 - - - name: Prepare environment - uses: n1rna/ee-action@v1 - with: - environment: production - config_path: .ee - env_file: .env.production - gh_secret: ${{ secrets.ENV_PRODUCTION }} - - - run: docker build --env-file .env.production -t myapp . -``` - ---- - -## .env File Format - -Standard KEY=VALUE format with optional annotations: - -```bash -# schema: ./schema.yaml - -# title: Database connection URL -# type: string -# required: true -DATABASE_URL=postgres://localhost:5432/myapp - -# title: Server port -# type: number -# default: 3000 -PORT=3000 - -# title: Debug mode -# type: boolean -# default: false -DEBUG=true -``` - -Annotations (in comments above the variable) are used by `ee init` and `ee verify --fix` to generate documented `.env` files. They are optional and don't affect variable loading. - ---- - -## Global Flags - -These flags work with all commands: - -- `-c, --config ` — Path to `.ee` file (default: `.ee` in current directory) -- `--debug` — Enable debug output -- `--version` — Show version - ---- - -## File Organization Best Practices - -**Commit to version control:** -- `.ee` — project configuration -- `schema.yaml` — variable schema -- `.env` — shared non-secret base config -- `.env.development` — development defaults (non-secret) - -**Add to `.gitignore`:** -``` -.env.local -.env.*.local -.env.secrets -*.secret.env -``` - -**Use source stacking for secrets:** -```json -{ - "environments": { - "production": { - "sources": [".env", ".env.production", ".env.secrets"] - } - } -} -``` - -Keep secrets in `.env.secrets` (gitignored) and push them to origins with `ee push`.