# `bin` ## Purpose `bin.ts` is the executable entry point installed by `package.json` as the `suaveplan-lint` binary. It is intentionally a one-line wrapper around `runCli` from `@suaveplan/linter/cli`: the wrapper calls the pure CLI function with `process.argv.slice(2)`, then translates the resolved `{ code }` into `process.exit`. Keeping `process.exit` out of every other file in the package means tests and embedded callers never accidentally terminate their host process, but the shipped binary still behaves like a conventional Unix tool — exit non-zero on failure, zero on success. ## Features - Tiny — fewer than ten lines, no dependencies beyond `cli`. - Surfaces unhandled exceptions (anything `runCli` didn't catch as a `LinterError`) via `process.stderr` then exits with code 2 so operators can distinguish CLI parse failures (code 1) from completely unexpected crashes (code 2). - Uses `.then` rather than `await` to support compilers (and Vite's esbuild target) that don't permit top-level await — the binary is built into ESM via the same Vite pipeline as the rest of the package, and that pipeline targets `es2020`. ## Usage: Basic ```bash bunx suaveplan-lint --help bunx suaveplan-lint --fix bunx suaveplan-lint "docs/**/*.md" ``` ## Usage: Advanced Embed the same logic in a custom CLI without spawning a subprocess: ```ts import { runCli } from "@suaveplan/linter/cli"; const { code } = await runCli(["--fix", "docs/*.md"], { out: (line) => console.error(line), }); process.exit(code); ``` ## API Reference The binary has no public API surface beyond the `suaveplan-lint` shell entry. Implementation is `runCli(process.argv.slice(2))` followed by `process.exit(code)`. Unhandled rejections trigger `process.exit(2)` after writing the error to stderr. ## Implementation Notes - The `#!/usr/bin/env node` shebang is preserved by Vite's `entryFileNames` configuration. Bun also accepts the same shebang line. - `runCli` already catches `LinterError` and writes a one-line summary via the injected `out` sink (defaulting to `console.log`); the `.then` rejection handler exists for any error type `runCli` did not handle — historically zero, but the wrapper exists so a future refactor that throws an unrelated `TypeError` from a helper still produces a useful exit code instead of an unhandled-rejection crash. - The `bin` field in `package.json` points at `./dist/bin.js`, which is emitted by the Vite build alongside the other ESM entries with the shebang intact.