npm package: @sjstrykr/dependency-cleaner
Description: CLI to scan and remove dependency folders (node_modules, __pycache__, etc.) by language
Author: sjstrykr
Latest version: 0.1.1

# dependency-cleaner

A CLI that scans a directory for dependency and cache folders (e.g. `node_modules`, `__pycache__`) based on the languages you choose, lets you pick which ones to remove in a list or tree view, then deletes them—either by moving to trash or permanently.

## Features

- **Multi-language support** — Choose one or more languages; the tool scans for that language’s dependency/cache folders only.
- **List and tree view** — View results as a flat list or a tree, then select folders to remove.
- **Select all / Select none** — Quickly select or clear all found folders.
- **Trash or permanent delete** — Move selected folders to the system trash (recoverable) or remove them permanently.
- **Safe defaults** — No changes until you confirm; optional trash keeps data recoverable.

## Installation

### Global install (recommended)

```bash
npm install -g dependency-cleaner
```

Then run:

```bash
dependency-cleaner
dependency-cleaner /path/to/project
```

### Requirements

- **Node.js** ≥ 18 (used when running the published CLI)
- For **development**: [Bun](https://bun.sh) (used as the bundler)

## Usage

```bash
dependency-cleaner [directory]
```

- **`directory`** — Path to the folder to scan. Defaults to the current directory (`.`) if omitted.

### Flow

1. **Choose languages** — Pick which languages to clean (e.g. Node.js, Python, Rust, Java). You can select multiple.
2. **Scan** — The CLI finds all matching dependency/cache folders under the given directory.
3. **View mode** — Choose **List** (flat list) or **Tree** (hierarchical view).
4. **Select folders** — Use the checkbox list to select folders to remove. Use **Select all** / **Select none** to toggle everything.
5. **Delete mode** — Choose **Trash** (recoverable) or **Permanent** (cannot be undone).
6. **Confirm** — Confirm how many folders will be affected, then the tool runs.

### Examples

```bash
# Scan current directory
dependency-cleaner

# Scan a specific project
dependency-cleaner ~/projects/my-app

# Scan relative path
dependency-cleaner ./packages/backend
```

### Initialize a config file

You can scaffold the global config file for custom directory names:

```bash
dependency-cleaner --init
```

This creates `~/.config/dependency-cleaner.config.json` with a template:

```json
{
  "dirNames": []
}
```

## Supported languages and folders

| Language            | Folders scanned |
|---------------------|-----------------|
| Node.js / JavaScript | `node_modules` |
| Python              | `__pycache__`, `venv`, `.venv`, `.mypy_cache`, `.pytest_cache`, `.ruff_cache` |
| Rust                | `target` |
| Java / Maven / Gradle | `target`, `build`, `.gradle`, `out` |

The scanner does not descend into these folders (e.g. it does not walk inside `node_modules`), so runs stay fast even in large trees.

## Configuration

In addition to the built-in language folder lists, you can define custom directory names in a single global config file:

- **Path:** `~/.config/dependency-cleaner.config.json`

Config schema:

```json
{
  "dirNames": ["custom_folder", "another_cache"]
}
```

- `dirNames` is an optional array of strings.
- Each entry is treated as an additional directory name to match (for all scans).
- Duplicate or empty names are ignored.

Custom `dirNames` are merged with the built-in language-specific folder names whenever the config file exists.

## Project structure

```
dependency-cleaner/
├── index.ts              # CLI entrypoint (shebang, args, orchestration)
├── language/
│   ├── types.ts          # Language type definition
│   ├── index.ts          # Registry of all languages
│   ├── node.ts
│   ├── python.ts
│   ├── rust.ts
│   └── java.ts
├── cli/
│   ├── scanner.ts        # Recursive scan for dependency folders
│   ├── prompts.ts        # Interactive prompts (languages, view, selection, delete mode)
│   ├── delete.ts         # Trash or permanent delete
│   ├── tree.ts           # Tree visualization for paths
│   └── constants.ts      # Shared constants and types
├── dist/                 # Build output (generated)
│   └── cli.js
├── package.json
├── tsconfig.json
└── README.md
```

## Development

### Setup

```bash
bun install
```

### Build

The CLI is written in TypeScript and bundled with Bun for Node:

```bash
bun run build
```

This produces `dist/cli.js`, which is what the `dependency-cleaner` bin points to. The bundle targets Node so end users only need Node.js, not Bun.

### Run locally

After building:

```bash
node dist/cli.js
node dist/cli.js /path/to/dir
```

Or link the package for a global `dependency-cleaner` during development:

```bash
bun run build
npm link
dependency-cleaner
```

### Adding a new language

1. Add a file under `language/`, e.g. `language/ruby.ts`:
   ```ts
   import type { Language } from "./types.js";
   export const ruby: Language = {
     id: "ruby",
     name: "Ruby",
     dirNames: ["vendor/bundle", ".bundle"],
   };
   ```
2. In `language/index.ts`, import the new language and add it to `allLanguages`.

## Publishing

### Push to GitHub

1. Update the `repository` URL in `package.json` to your repo (e.g. `https://github.com/your-username/dependency-cleaner.git`).
2. Initialize git (if not already), add files, and push:

```bash
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-username/dependency-cleaner.git
git push -u origin main
```

### Publish to npm

1. Create an [npm account](https://www.npmjs.com/signup) if you don’t have one.
2. Log in from the CLI: `npm login`.
3. Ensure `package.json` has the correct `name` (must be unique on npm) and `repository` URL.
4. Build and publish:

```bash
bun run build
npm publish
```

- The `prepublishOnly` script runs `bun run build` automatically before `npm publish`, so `dist/` is built even if you didn’t run `build` yourself.
- The `files` field in `package.json` limits the published package to `dist/`, so source and dev files are not included.

This project was vibe coded (built with AI assistance).

## License

MIT