npx skills add ...
npx skills add mblode/agent-skills --skill dx-audit
Audits libraries, CLIs, and SDKs using 38 rules for public contracts, package exports, piped output, errors, and configuration. Use when asked to "audit my CLI", "review my SDK", or diagnose package type resolution.
npx skills add mblode/agent-skills --skill dx-audit
Audit or improve what developers import, run, configure, or read when something fails.
tidy), end-user UI (ui-design Audit mode), agent trust review (ax-audit), public site or docs agent scores (agent-ready), docs prose or a README (ghostwriter), repository architecture (codebase-architecture), or building a new CLI (scaffold-cli).Pick the narrowest mode the request supports, and write a one-line scope receipt before reading code:
| Mode | When | Output |
|---|---|---|
| Targeted (default) | a named or changed public surface | findings report, read-only |
| Fix | the user says fix, improve, simplify, or implement | localized edits inside the receipt, then verification |
| Exhaustive | the user explicitly asks for the whole package or every public surface | every material finding, partitioned by surface |
"DX", "gold standard", and "review holistically" do not by themselves widen a targeted audit into exhaustive. When several skills are invoked together, this one owns only the surfaces above.
Start from git diff against the normal base and keep only changed files reachable from a public entry point: package.json exports or bin, a command registry, an exported type, a documented config loader, or an observed error path. With no useful diff, use the command, export, error, or config the user named. A private helper enters scope only through a public caller.
--help, --version, one success path, one invalid-input path, and the same command with stdout piped (| cat) to see non-TTY behavior. Never trigger a real mutation to test DX; use --dry-run where it exists.npx publint and npx @arethetypeswrong/cli --pack . after a build. These inspect packaging, but packing may invoke lifecycle scripts. Inspect those scripts first or use a disposable checkout before calling --pack.Stop when the behavior is proven, disproven, private, or out of scope. External research is for an explicit comparison request or a named uncertainty local evidence cannot resolve; references/standards-map.md carries the standards this skill already leans on.
Read rules/_sections.md, then select prefixes by surface:
| Priority | Prefix | Category | Default impact | Rules |
|---|---|---|---|---|
| 1 | api- | Public API and SDK | CRITICAL | 7 |
| 2 | err- | Developer-facing errors | CRITICAL | 5 |
| 3 | cli- | CLI UX for humans and agents | HIGH | 13 |
| 4 | types- | Exported type ergonomics | HIGH | 5 |
| 5 | onboard- | Install and first run | HIGH | 5 |
| 6 | config- | Config ergonomics | MEDIUM | 3 |
| Surface | Prefixes |
|---|---|
| Public API entry point | api-, types-, reached err- paths |
| CLI command | cli-, reached err- paths |
| Exported declarations | types-, plus api- when behavior changed |
Install, package.json, first run | onboard- |
| Config loader | config-, reached err- paths |
Applicability outranks priority: a CLI-only audit never loads api- because API rules rank higher.
Targeted mode: list the filenames for the selected prefixes (the names are the checklist), look for concrete evidence, then open only the rule files a finding needs. Exhaustive mode: read every rule in the selected prefixes.
Capability gates, applied inside a selected prefix:
stdin applies when the command semantically accepts file or stream data.impact, copied exactly. Impact is the rule's declared consequence, not a confidence score: exit 0 on failure in one subcommand is still HIGH, because the CI gate it defeats is the same. Open the rule file before citing it, since an id cited from memory drifts from the file, and drop the citation if no such file exists.--json across a surface is one finding, not one per symbol.Audit requests are read-only. A fix request authorizes localized changes inside the receipt, not a redesign of adjacent docs, UI, or architecture.
List only files with findings; a clean surface gets one pass line naming the surfaces and rule files checked. In fix mode, replace Deferred with Changed and Verification (the exact commands or probes that passed). Length follows findings, not the template.
Re-open every touched or cited location, rerun the same probes and focused project checks, and reapply the same candidate rules. Match the evidence to the claim: a clean build does not prove CLI behavior, a runtime probe does not prove exported types, and only attw or a consumer-style tsc import proves a types resolution.
| File | Read when |
|---|---|
rules/_sections.md | Every audit, for prefix applicability and priority |
rules/<prefix>-*.md | A candidate has evidence, or exhaustive mode |
references/standards-map.md | A finding needs an external citation, the user asks why something is a rule, or a borderline call needs a tie-break |
rules/_template.md | Adding or editing a rule |
npx <pkg> and a global install probe the registry copy, not the working tree. --help, exit codes, and error strings then describe a released version. Build, then invoke the local entry point (node ./dist/cli.js).process.stdout.isTTY is undefined under a pipe, not false. A guard written as isTTY === false never disables color or spinners when piped, so ANSI codes reach the redirected file. Probe with | cat rather than trusting the guard.process.exit(1) right after console.log can truncate the output it was meant to explain. stdout writes are asynchronous when piped, so a CLI that prints usage and calls exit() can emit nothing under | cat. The fix is process.exitCode = 1 and a natural return (cli-exit-codes).exports map that reads correctly can still resolve wrong. "require" pointing at a .js file under "type": "module" masquerades as CJS, and a types condition listed after import is never reached. publint and attw catch both; reading the map does not (onboard-exports-resolve-typed).ui-design Audit mode: rendered end-user frontend quality and accessibilityax-audit: same files, different reader; asks whether an agent can operate and recover, where this skill asks whether a developer finds the surface ergonomicscaffold-cli: builds a new CLI with these patterns already in place; this skill audits what existstidy: general correctness and structure of a diffagent-ready: public HTTP/docs agent scores (AFDocs, Is Agentic, Is It Agent Ready); this skill audits the package once it existsghostwriter: documentation prose, README structure, and the first-reader narrativeagents-md: AGENTS.md and CLAUDE.md instruction filescodebase-architecture: repository structure and module contracts inside the repo, rather than the surface a package ships outwardMaintenance only: evals/evals.json and evals/evaluation-scenarios.md hold regression scenarios for changes to this skill; neither loads during a user task.
## DX Audit
Scope: `tool status` CLI; `err-`, `cli-`; 4 files inspected.
### Findings
- [HIGH] `cli-idempotent-resume` at `src/start.ts:42`: retrying the same target creates a second job.
Fix: return the existing job id and state unless the caller passes `--fresh`.
### Deferred
- 2 lower-impact config candidates were outside the locked CLI scope.