# Bin field or entry point is correctly configured

- **Pattern:** `ab-000657` (`cli-quality.config-distribution.bin-field`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000657
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000657)

## Why it matters

A `bin` field pointing to `./dist/cli.js` when no `dist/` directory exists is a package that installs successfully and then fails on first invocation with `env: node: No such file or directory` or `Cannot find module`. Pointing `bin` at a `.ts` file is worse — `npx mytool` dies with a syntax error on the first `import` statement. Users uninstall immediately and leave a one-star review. This is the single most common CLI publish-to-npm failure mode.

## Severity rationale

Critical because a broken entry point makes the CLI uninstallable or non-executable on every user's first try.

## Remediation

Set `bin` in `package.json` to the compiled JS file, wire a `prepublishOnly` build script, and include the output directory in `files`. Verify `dist/cli.js` exists after `npm run build`:

```json
{
  "bin": { "mytool": "./dist/cli.js" },
  "files": ["dist"],
  "scripts": {
    "build": "tsc",
    "prepublishOnly": "npm run build"
  }
}
```

## Detection

- **ID:** `bin-field`
- **Severity:** `critical`
- **What to look for:** Count all package.json files. For each, check the distribution entry point configuration for the detected language:
  - **Node.js:** `bin` field in `package.json` — must point to a file that exists. If `"bin": "./dist/cli.js"`, verify `dist/cli.js` exists or is produced by the build step. If using TypeScript, the bin field must point to the compiled JS, not the `.ts` source.
  - **Python:** `[project.scripts]` in `pyproject.toml`, or `console_scripts` in `setup.cfg`/`setup.py`. Must point to a valid `module:function` path.
  - **Go:** `package main` with `func main()` in the expected location (`cmd/toolname/main.go` or root `main.go`).
  - **Rust:** `[[bin]]` in `Cargo.toml` or default `src/main.rs`. `name` field must be set if not using default.
- **Pass criteria:** The entry point configuration exists, points to a valid file/function, and the file is either present in source or produced by the build step listed in `package.json` scripts — at least 1 bin field entry must be defined in the root package.json. Report: "X package.json files found, Y have bin field configured."
- **Fail criteria:** No entry point configuration, or the configured path points to a nonexistent file, or `bin` points to a `.ts` file (will fail on execution), or the entry point module/function doesn't exist.
- **Skip (N/A) when:** All checks skip when no CLI entry point is detected.
- **Detail on fail:** `"package.json bin field points to './dist/cli.js' but no dist/ directory exists and no build script is configured"` or `"bin field points to 'src/cli.ts' — TypeScript files cannot be executed directly as CLI entry points"`
- **Remediation:** The bin field is what makes your CLI installable and executable:

  ```json
  // package.json — correct bin field
  {
    "name": "my-cli-tool",
    "bin": {
      "mytool": "./dist/cli.js"
    },
    "scripts": {
      "build": "tsc",
      "prepublishOnly": "npm run build"
    },
    "files": ["dist"]
  }
  ```

  ```toml
  # pyproject.toml — correct script entry point
  [project.scripts]
  mytool = "my_tool.cli:main"
  ```

  ```toml
  # Cargo.toml — binary target
  [[bin]]
  name = "mytool"
  path = "src/main.rs"
  ```

Taxons: reference-integrity, operational-readiness

HTML version: https://auditbuffet.com/patterns/ab-000657
