Metadata-Version: 2.4
Name: envscope
Version: 1.0.0
Summary: A terminal UI for inspecting .env drift, duplicates, and unsafe values.
Author: Envscope Maintainers
License-Expression: MIT
Keywords: dotenv,environment,secrets,textual,tui
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pathspec>=0.12.1
Requires-Dist: rich>=14.0.0
Requires-Dist: textual>=6.6.0
Provides-Extra: dev
Requires-Dist: build>=1.2.0; extra == "dev"
Requires-Dist: pyinstaller>=6.0.0; extra == "dev"
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: twine>=6.0.0; extra == "dev"
Dynamic: license-file

# envscope

![envscope banner](banner.png)

envscope is a terminal UI for inspecting `.env` files in a project. It compares real environment files against their matching `.env.example`, `.env.sample`, or `.env.template` files and shows configuration drift directly inside an interactive terminal app.

It is built for developers who want to quickly answer:

- Which required environment variables are missing?
- Which local variables are not declared in the example file?
- Did any file define the same key twice?
- Are required values blank?
- Did a real secret leak into an example file, or did a weak placeholder remain in a real `.env` file?

envscope is TUI-only. Launching `envscope` opens the terminal application; this version does not include a headless, CI, or subcommand-based workflow.

## Installation

The primary install path is PyPI with `pipx`.

Install with `pipx install envscope`.

Upgrade with `pipx upgrade envscope`.

You can also install into an active Python environment with `pip install envscope`, but `pipx` is recommended so the app stays isolated from project dependencies.

## Launch

Run `envscope` from the project you want to inspect.

By default, the picker starts at the current working directory. You can select a different project directory from inside the TUI before scanning.

From a source checkout, you can also launch without installing the package:

- Windows PowerShell: `.\run.ps1`
- Windows Command Prompt: `run.cmd`
- macOS/Linux: `sh run.sh`

The picker includes a file explorer. Selecting a directory updates the project path; selecting an `.env` file uses that file's parent directory.

This repository also includes a gitignored local sample project in `test/` with `.env`, `.env.example`, `.env.local`, and `.env.production` files for manual TUI testing.

## TUI Walkthrough

### 1. Project Picker

The first screen asks for the project directory to inspect. It defaults to the directory where `envscope` was launched.

After confirmation, envscope walks the project while respecting `.gitignore`-style patterns and skipping common generated or dependency directories such as `node_modules`, `.git`, `venv`, `dist`, and `build`.

The scope list also shows scan diagnostics: visited files and directories, skipped paths, and incomplete scopes where env-like files were found but no valid comparison pair exists.

### 2. Scope List

envscope groups discovered files by directory into scopes.

A scope is valid when one directory contains at least one example-like file and at least one real environment file. Example-like files include `.env.example`, `.env.sample`, and `.env.template`.

Common layouts supported:

- Flat projects with `.env` and `.env.example` at the root.
- Multi-variant flat projects with files such as `.env`, `.env.local`, and `.env.production` compared against one root `.env.example`.
- Monorepos with separate pairs such as `frontend/.env` plus `frontend/.env.example` and `backend/.env` plus `backend/.env.example`.

If a scope contains multiple real environment files, envscope compares all candidates by default. You can adjust the selected candidates before opening the diff.

### 3. Diff View

The diff view shows findings for each selected real environment file. When multiple candidates are selected, each candidate appears in its own tab.

Findings are grouped into:

- Missing: keys present in the example file but absent from the real environment file.
- Extra: keys present in the real environment file but absent from the example file.
- Duplicate: the same key appears more than once in one file.
- Empty but required: a key exists in the real environment file but its value is blank while the example indicates that a real value is expected.
- Insecure: risky values found in either direction, including real secrets committed to example files and weak placeholder values left in real environment files.

Use search and severity filters to narrow large result sets. Selecting a finding shows details including file, line, rule id, message, and a remediation hint.

Secret-like values are masked by default. Press `r` in the diff view to explicitly reveal only the selected insecure finding, and press `r` again to mask it.

### 4. Summary

The summary screen aggregates active and suppressed findings across all discovered scopes. It is intended for quickly reviewing project health, checking which scopes need attention, and exporting a masked Markdown report from inside the TUI.

## Finding Categories

### Missing Keys

A missing key exists in an example file but not in the real environment file being compared. This usually means a local setup, deployment environment, or teammate machine may be missing required configuration.

### Extra Keys

An extra key exists in a real environment file but not in its example file. This can mean the example file is stale, or the real environment file contains obsolete configuration.

### Duplicate Keys

A duplicate key appears more than once in the same file. Since environment parsers commonly use the last value, duplicates can hide mistakes and make behavior hard to predict.

### Empty but Required Keys

An empty-but-required key exists in the real environment file but has no value while the example file uses a placeholder that suggests the value is required.

### Insecure Values

envscope checks for two kinds of insecure values:

- Real secrets in example files, such as AWS keys, GitHub tokens, private key headers, JWTs, Stripe live keys, Slack tokens, and high-entropy strings.
- Weak or placeholder values in real environment files, such as `password123`, `changeme`, `admin`, `secret`, `test`, or blank required secrets.

## Configuration

Projects may define `.envscope.toml` at the project root.

Configuration is optional. The default behavior should be useful without a config file.

Supported configuration areas:

- Custom ignore globs for project-specific generated directories or files.
- Custom secret patterns for organization-specific tokens or credential formats.
- Adjustments to built-in secret detection rules when a project has known false positives.
- Suppression rules for intentional findings, with a required reason.

Configuration must not change envscope into a headless or CI tool. It only customizes how the TUI scans and classifies findings.

Example:

```toml
[scan]
ignore_globs = ["generated/", "tmp/"]

[secrets]
patterns = ["company_[A-Za-z0-9]{24,}"]
weak_values = ["notsecure"]

[[suppressions]]
file_glob = "frontend/.env.example"
key = "EXAMPLE_TOKEN"
rule_id = "secret.high_entropy"
reason = "Documented fake token used in onboarding"
```

Suppressed findings remain visible in the TUI and export, but they are counted separately from active findings.

## Development

Install the project with development dependencies:

```bash
uv sync --extra dev
```

Run tests:

```bash
uv run pytest
```

Launch from the working tree:

```bash
uv run envscope
```

## Build for PyPI

Build the source distribution and wheel:

```bash
uv run python -m build
```

Check the built distributions:

```bash
uv run python -m twine check dist/*
```

Upload when you are ready to publish:

```bash
uv run python -m twine upload dist/*
```
