Reduce runtime dependencies from 6 to 4#9
Conversation
Replace chalk with inline ANSI helpers, commander with node:util parseArgs, and micromatch with picomatch (already a transitive dep via fast-glob). Bumps version to 0.4.1.
There was a problem hiding this comment.
Pull request overview
This PR reduces direct runtime dependencies by replacing third-party CLI/color/glob utilities with Node built-ins and smaller libraries, and bumps the package version to 0.4.1.
Changes:
- Replace
commanderwithnode:utilparseArgsand update CLI help/version handling. - Replace
chalkwith small inline ANSI helpers for text output coloring. - Replace
micromatchwithpicomatch, and update dependency/lockfile/changelog/versioning.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/integration/cli.test.ts | Updates CLI version assertion to 0.4.1. |
| src/validator/glob.ts | Swaps micromatch-based matching for picomatch-based matching. |
| src/output/text.ts | Removes chalk and introduces inline ANSI formatting helpers. |
| src/cli.ts | Replaces commander with parseArgs, adds manual help text, bumps CLI version constant. |
| package.json | Removes chalk/commander/micromatch, adds picomatch and bumps version to 0.4.1. |
| package-lock.json | Reflects dependency removals/additions and version bump. |
| CHANGELOG.md | Adds 0.4.1 release notes and updates compare links. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const isMatch = picomatch(normalizedPattern, { | ||
| dot, | ||
| matchBase: !normalizedPattern.includes('/') |
There was a problem hiding this comment.
picomatch doesn’t support micromatch’s matchBase option; it will be ignored, which changes behavior for patterns without a / (previously they matched against basenames). To preserve the old semantics, switch to the picomatch equivalent (e.g., basename: true when the pattern has no path separator), or otherwise adjust matching logic so foo.txt matches dir/foo.txt like before.
| const isMatch = picomatch(normalizedPattern, { | |
| dot, | |
| matchBase: !normalizedPattern.includes('/') | |
| const hasPathSeparator = normalizedPattern.includes('/'); | |
| const isMatch = picomatch(normalizedPattern, { | |
| dot, | |
| ...(hasPathSeparator ? {} : { basename: true }) |
| import { parseArgs } from 'node:util'; | ||
| import fs from 'fs/promises'; |
There was a problem hiding this comment.
This switch to node:util parseArgs effectively requires Node versions where parseArgs is stable/available (noted in the PR description as 18.3+). However, package.json still declares node >=18.0.0, which can lead to runtime failures or unsupported behavior on 18.0–18.2. Consider bumping the engine requirement to >=18.3.0 (or add a small fallback/guard) so the published package matches the CLI’s runtime needs.
| include: { type: 'string' as const, multiple: true }, | ||
| exclude: { type: 'string' as const, multiple: true }, | ||
| 'skip-ignore-files': { type: 'boolean' as const, default: false }, | ||
| 'exclude-parsers': { type: 'string' as const, multiple: true }, | ||
| 'min-severity': { type: 'string' as const, default: 'medium' }, |
There was a problem hiding this comment.
parseArgs with multiple: true makes --include/--exclude/--exclude-parsers repeatable, but it does not accept the previous commander-style variadic form (e.g. --include a b from the README’s --include <glob...>), and extra values will be treated as positionals (scan paths). Either add backwards-compatible parsing for space-separated lists or update the public docs/help to clearly reflect the new required syntax.
| /** Inline ANSI color helpers (replaces chalk) */ | ||
| const ansi = (code: number, close: number) => (s: string) => `\x1b[${code}m${s}\x1b[${close}m`; | ||
| const gray = ansi(90, 39); | ||
| const yellow = ansi(33, 39); | ||
| const red = ansi(31, 39); | ||
| const cyan = ansi(36, 39); | ||
| const dim = ansi(2, 22); | ||
| const green = ansi(32, 39); |
There was a problem hiding this comment.
The new inline ANSI helpers always emit escape codes, whereas chalk previously disabled color automatically in non-TTY contexts and commonly respects NO_COLOR/TERM=dumb. This can introduce escape sequences in redirected output/files and CI logs. Consider gating coloring behind a simple “color enabled” check (TTY + env vars) and falling back to identity functions when disabled.
| const options = { | ||
| version: { type: 'boolean' as const, short: 'V' }, | ||
| help: { type: 'boolean' as const, short: 'h' }, | ||
| format: { type: 'string' as const, short: 'f', default: 'text' }, | ||
| output: { type: 'string' as const, short: 'o' }, | ||
| include: { type: 'string' as const, multiple: true }, | ||
| exclude: { type: 'string' as const, multiple: true }, | ||
| 'skip-ignore-files': { type: 'boolean' as const, default: false }, | ||
| 'exclude-parsers': { type: 'string' as const, multiple: true }, | ||
| 'min-severity': { type: 'string' as const, default: 'medium' }, | ||
| 'show-all': { type: 'boolean' as const, default: false }, | ||
| 'fail-on-stale': { type: 'boolean' as const, default: false }, | ||
| quiet: { type: 'boolean' as const, short: 'q', default: false }, | ||
| verbose: { type: 'boolean' as const, short: 'v', default: false }, | ||
| progress: { type: 'boolean' as const, default: true } | ||
| }; |
There was a problem hiding this comment.
CLI tests cover --include/--exclude with a single value, but there’s no coverage for the new parseArgs multi-value behavior (repeatable flags) or for the legacy --include a b style that commander previously supported. Adding an integration test for repeated --include/--exclude (and, if supported, the space-separated form) would prevent regressions in argument parsing.
Summary
chalkwith inline ANSI escape code helpers (~10 lines, covers all 6 used styles)commanderwith Node.js built-innode:util parseArgs(stable since Node 18.3)micromatchwithpicomatch(already a transitive dep viafast-glob)Before (6 deps): chalk, commander, fast-glob, micromatch, smol-toml, yaml
After (4 deps): fast-glob, picomatch, smol-toml, yaml
Test plan
npm run buildcompiles cleanlynpm run test— all 303 tests passnpm run selfcheck— CLI works end-to-endnpm ls --prod --depth=0confirms 4 direct dependencies