npkill Agent Skills & AI Rules

GitHub

List any node_modules ๐Ÿ“ฆ dir in your system and how heavy they are. You can then select which ones you want to erase to free up space ๐Ÿงน

9,174 stars TypeScript TypeScript 1 file ยท ~8,304 tokens #cli#command-line#developer-tools#hacktoberfest#javascript#module#node#nodejs
RAW Rules
1 Discovered Rules โ€ข ~1,718 Estimated Tokens
Loading skill content...

API Interface Contract & Specifications

API.md project-spec ~1,718 tokens
Raw
# NPKill API

This document does not include all project documentation at this stage. It brings together the basic concepts.
For more details see the project interfaces.

- [NPKill API](#npkill-api)
  - [Interface: `Npkill`](#interface-npkill)
    - [`startScan$(rootPath, options?)`](#startscanrootpath-options)
    - [`stopScan()`](#stopscan)
    - [`getSize$(path, options?)`](#getsizepath-options)
    - [`getNewestFile$(path)`](#getnewestfilepath)
    - [`delete$(path, options?)`](#deletepath-options)
    - [`getLogs$()`](#getlogs)
    - [`isValidRootFolder(path)`](#isvalidrootfolderpath)
    - [`getVersion()`](#getversion)
  - [Interfaces & Types](#interfaces-types)
    - [`ScanOptions`](#scanoptions)
    - [`ScanFoundFolder`](#scanfoundfolder)
    - [`RiskAnalysis`](#riskanalysis)
    - [`GetSizeOptions`](#getsizeoptions)
    - [`GetSizeResult`](#getsizeresult)
    - [`GetNewestFileResult`](#getnewestfileresult)
    - [`DeleteOptions`](#deleteoptions)
  - [Usage Example](#usage-example)

---

## Interface: `Npkill`

The core of the system is the `NpkillInterface`. It offers methods to:

- Scan folders recursively.
- Get metadata about folders (size, last modified).
- Perform safe deletions.
- Stream logs and validate folders.

### `startScan$(rootPath, options?)`

Starts a recursive scan from a given root folder.

- **Parameters**:
  - `rootPath`: `string` โ€” Folder to start scanning from.
  - `options`: [`ScanOptions`](#scanoptions) โ€” Optional scan configuration.

- **Returns**: `Observable<ScanFoundFolder>`
- **Description**: Emits each matching folder as it's found.

---

### `stopScan()`

Stops any ongoing scan and releases resources.

---

### `getSize$(path, options?)`

Returns the total size of a directory.

- **Parameters**:
  - `path`: `string` โ€” Path to folder.
  - `options`: [`GetSizeOptions`](#getsizeoptions)

- **Returns**: `Observable<GetSizeResult>`

---

### `getNewestFile$(path)`

Gets the most recently modified file inside a directory (recursively).

- **Parameters**:
  - `path`: `string`

- **Returns**: `Observable<GetNewestFileResult | null>`

---

### `delete$(path, options?)`

Deletes a folder, optionally as a dry-run. Only allowed if the folder is within the `target` of the initial scan.

- **Parameters**:
  - `path`: `string`
  - `options`: [`DeleteOptions`](#deleteoptions)

- **Returns**: `Observable<DeleteResult>`
- **Throws**: If the path is outside the original target.

---

### `getLogs$()`

Streams internal log entries.

- **Returns**: `Observable<LogEntry[]>`

---

### `isValidRootFolder(path)`

Validates whether a folder is suitable for scanning.

- **Parameters**:
  - `path`: `string`

- **Returns**: [`IsValidRootFolderResult`](#isvalidrootfolderresult)

---

### `getVersion()`

Returns the current version of npkill from `package.json`.

- **Returns**: `string`

---

## Interfaces & Types

---

### `ScanOptions`

```ts
interface ScanOptions {
  targets: string[];
  exclude?: string[];
  sortBy?: 'path' | 'size' | 'age';
  performRiskAnalysis?: boolean; // Default: true
}
```

---

### `ScanFoundFolder`

```ts
interface ScanFoundFolder {
  path: string;
  riskAnalysis?: RiskAnalysis;
}
```

---

### `RiskAnalysis`

Determines whether a result is safe to delete. That is, if it is likely to belong to some application and deleting it could break it.

```ts
interface RiskAnalysis {
  isSensitive: boolean;
  reason?: string;
}
```

---

### `GetSizeOptions`

```ts
interface GetSizeOptions {
  unit?: 'bytes'; // Default: 'bytes'
}
```

---

### `GetSizeResult`

```ts
interface GetSizeResult {
  size: number;
  unit: 'bytes';
}
```

---

### `GetNewestFileResult`

```ts
interface GetNewestFileResult {
  path: string;
  name: string;
  timestamp: number;
}
```

---

### `DeleteOptions`

```ts
interface DeleteOptions {
  dryRun?: boolean;
}
```

---

## Usage Example

This is a minimal example where:

1. it will start a search for `.nx` folders.
2. Get the most recent file
3. Get the total size of the directory

```ts
import { Npkill } from 'npkill';
import { mergeMap, filter, map } from 'rxjs';

const npkill = new Npkill();

let files: {
  path: string;
  size: number;
  newestFile: string;
}[] = [];

npkill
  .startScan$('/home/user/projects/', { target: '.nx' })
  .pipe(
    // Step 1: For each scan result, get the newest file
    mergeMap((scanResult) =>
      npkill.getNewestFile$(scanResult.path).pipe(
        // Step 2: If no newest file, skip this result
        filter((newestFile) => newestFile !== null),
        // Step 3: Combine scanResult and newestFile
        map((newestFile) => ({
          path: scanResult.path,
          newestFile: newestFile.path,
        })),
      ),
    ),
    // Step 4: For each result, get the folder size
    mergeMap((result) =>
      npkill.getSize$(result.path).pipe(
        map(({ size }) => ({
          ...result,
          size,
        })),
      ),
    ),
  )
  .subscribe({
    next: (result) => {
      files.push(result);
    },
    complete: () => {
      console.log('โœ… Scan complete. Found folders:', files.length);
      console.table(files);
      console.log(JSON.stringify(files));
    },
  });
```

Output:

```bash
โœ… Scan complete. Found folders: 3
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ (index) โ”‚ path                                      โ”‚ newestFile                                                               โ”‚ size    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 0       โ”‚ '/home/user/projects/hello-world/.nx'     โ”‚ '/home/user/projects/hello-world/.nx/cache/18.3.4-nx.linux-x64-gnu.node' โ”‚ 9388032 โ”‚
โ”‚ 1       โ”‚ '/home/user/projects/another-project/.nx' โ”‚ '/home/user/projects/another-project/.nx/workspace-data/d/daemon.log'    โ”‚ 3182592 โ”‚
โ”‚ 2       โ”‚ '/home/user/projects/ARCHIVED/demo/.nx'   โ”‚ '/home/user/projects/ARCHIVED/demo/.nx/cache/d/daemon.log'               โ”‚ 2375680 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
[
  {
    "path": "/home/user/projects/hello-world/.nx",
    "newestFile": "/home/user/projects/hello-world/.nx/cache/18.3.4-nx.linux-x64-gnu.node",
    "size": 9388032
  },
  {
    "path": "/home/user/projects/another-project/.nx",
    "newestFile": "/home/user/projects/another-project/.nx/workspace-data/d/daemon.log",
    "size": 3182592
  },
  ........
]
```