agentleFS
eai-orgeai-org/agent-toolkit/skills/run-nx-checks/SKILL.md

run-nx-checks

Skill85 starsChanged 21 days agoMITView on GitHub

Run nx format, lint, typecheck, test, and build on affected or specified projects, then fix unambiguous failures

  • Reads credentials
  • Deletes or force-pushes

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. About 0 are common, 8 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈8

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Run format, lint, typecheck, test, build.

    line 13
  2. Distinctive:

    Default project scope = affected.

    line 22
  3. Very specific:

    Run nx commands from wherever nx.json lives in this repo (commonly the root.

    line 29
  4. Distinctive:

    Keep the Nx daemon warm so the project graph is reused across targets:

    line 34
  5. Distinctive:

    Never guess on anything judgment-laden: test failure that could be a real bug vs.

    line 77
  6. Distinctive:

    Keep changes minimal and scoped to the failure.

    line 81
  7. Distinctive:

    After fixing, re-run the same step command.

    line 82
  8. Very specific:

    Always prefix each task-running nx command (steps 1–5 and the flaky retry.

    line 114
  9. Very specific:

    If the user explicitly passed --remote-cache, drop the prefix.

    line 125
  10. Very specific:

    Do not add --skip-nx-cache (nor NX_SKIP_NX_CACHE=true) to any command — it bypasses the local cache too, making every run slower for no …

    line 132
  11. Distinctive:

    Write the env vars literally at the start of each such command, exactly as in the steps below.

    line 138
  12. Very specific:

    every file the run changed: hand-fixed (from your own edits — file plus one line on what and why) and tool-applied (lint --fix, …

    line 191
  13. Distinctive:

    Never report a bare "checks passed": an unlisted failure, skipped target or unmentioned edit reads as green and the caller can't act on it.

    line 197

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Run Nx Checks

Run format, lint, typecheck, test, build. Fix unambiguous failures. Report anything judgment-laden and every file you changed.

Arguments

$ARGUMENTS — optional, space-separated: [cpuCount] [projectName] [--remote-cache]. Number token → cpuCount. Non-number, non-flag token → projectName. --remote-cache flag → opt back into the remote cache by dropping the remote-cache-off prefix. Default cpuCount = cores - 4 (min 1); count cores with node -p 'os.cpus().length'. Default project scope = affected. Default remote-cache state = off (see Steps).

$base, $cpuCount, $projectName and $snap in the commands below are placeholders: substitute their values (a fresh shell per Bash tool call holds none of them).

Workspace

Run nx commands from wherever nx.json lives in this repo (commonly the root; in some repos a subdirectory).

Setup (before step 1)

Keep the Nx daemon warm so the project graph is reused across targets:

NX_DAEMON=true npx nx daemon --start >/dev/null 2>&1 || true

Snapshot the dirty files, so the final report can name every file the run changes (hash-object without -w writes nothing); substitute the printed path for $snap there:

snap=$(mktemp -d "${TMPDIR:-/tmp}/nx-checks.XXXXXX") && git ls-files -z -mo --exclude-standard | while IFS= read -r -d '' f; do echo "$(git hash-object "$f" 2>/dev/null) $f"; done > "$snap/before.txt" && echo "snap=$snap"

Affected base

nx affected and format:write diff against the local default branch, which is often stale or missing. $projectName replaces only the affected commands, so resolve the base in both modes. NX_BASE set: skip this section and omit --base from every command below; Nx reads it and a deliberate env setting wins. Otherwise resolve the remote-tracking ref once and substitute the printed ref for $base in every affected, format:write and show projects --affected command below:

base=$(node -p 'const j=require("./nx.json"); j.defaultBase ?? j.affected?.defaultBase ?? "main"' 2>/dev/null || echo main)
base=${base#remotes/}; [[ $base == */* ]] || base="origin/$base"
GIT_TERMINAL_PROMPT=0 GIT_SSH_COMMAND='ssh -o BatchMode=yes -o ConnectTimeout=15' git fetch --quiet "${base%%/*}" "${base#*/}" || echo "fetch failed: base may be stale"
git rev-parse --verify --quiet "$base" >/dev/null && echo "base=$base" || echo "no such ref: omit --base"
  • Omit --base when the ref is missing (Nx falls back to defaultBase).
  • Never pass --head. With both flags Nx diffs two commits and ignores uncommitted and untracked files, so an agent's unstaged edits vanish and every check passes vacuously.
  • A failed fetch is not a failure: continue on the current ref, flag "base may be stale" in the final report, and never retry outside the sandbox for it.

Why: affected-base-rationale.md.

Fix rule

  • Apply only mechanical/unambiguous fixes: lint auto-fix output, missing imports/types, obvious type errors, test expectations that mirror a clear code change. An assertion or snapshot update is mechanical only when the failing expectation names a value the working-tree diff changed on purpose; edit that expectation by hand. Never pass -u/--updateSnapshot to a target.
  • Never guess on anything judgment-laden: test failure that could be a real bug vs. an outdated assertion, errors pointing at unrelated areas, pre-existing failures unrelated to recent work, anything where multiple plausible fixes exist. Running forked, you can't ask mid-run: leave such failures unfixed and carry them, with your analysis, into the final report.
  • Keep changes minimal and scoped to the failure. No drive-by refactors.
  • After fixing, re-run the same step command; the local cache replays the untouched projects. Repeat until clean or only judgment-laden failures remain.

Affected scope — sanity-check before step 1

Affected runs only (no $projectName); they can balloon. Before step 1, check scope with the graph-only npx nx show projects --affected --base=$base (fast, no build):

  • Sandbox .env false positives. The sandbox denies reading **/.env; nx affected hashes changed files, so an unreadable .env reads as changed and marks its project affected. Repos with .env-bearing apps (e.g. apps/*-api) thus drag those into every affected run and build them for nothing. Tell-tale: run git status; it prints <path>/.env: Operation not permitted for exactly those projects. Fix: add --exclude=<their project names> to every affected command (format:write takes none) and list them as excluded in the final report, naming any real edits they hold. Never re-run them outside the sandbox yourself; the user can, to include them.
  • Large fan-out. Large = more than half of npx nx show projects | wc -l or more than 20 projects, whichever is lower, counting affected projects after the .env exclusions (e.g. a widely-shared lib change rippling across the workspace). Don't build the world unprompted: skip steps 3–5 and report the project count and list in the final report so the user can re-run with $projectName.

Steps

Scope is mandatory — never narrow it yourself. With no $projectName argument, every target runs at full scope — nx affected for lint/typecheck/test/build, whole-changeset format:write. The single-project forms in the steps below apply only when the user explicitly passed $projectName. Never substitute nx run <proj>:<target>, nx <target> <changedLib>, or file-scoped format --files for the affected sweep: that skips every other affected project — exactly where a shared-lib change regresses (a dependent project whose tests import the changed lib).

Always prefix each task-running nx command (steps 1–5 and the flaky retry; daemon and show projects run no tasks) with the remote-cache-off env vars inline: NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache. NX_SKIP_REMOTE_CACHE turns off every remote cache on Nx 20.4 and later; the other two cover earlier versions and Powerpack. Unknown vars are no-ops, so the prefix is safe whatever remote-cache backend (if any) the repo uses.

The invariant: remote cache always off (unless the user passed --remote-cache), local cache always on — always disable, never autodetect (a passing shell-side auth check doesn't predict the in-process credential chain). Why: remote-cache-rationale.md.

If the user explicitly passed --remote-cache, drop the prefix. Expect pipeline hits on build (same --configuration) and typecheck; on test only in the single-project form and the flaky retry (the affected run's --maxWorkers=1 is a hashed override); never on lint (--fix) — keep the flags regardless.

Always keep the local cache on. The env vars above disable only the remote read-through cache; the local Nx cache must stay enabled so unchanged targets are replayed instead of re-run. Do not add --skip-nx-cache (nor NX_SKIP_NX_CACHE=true) to any command — it bypasses the local cache too, making every run slower for no benefit. The only valid reason to pass --skip-nx-cache is a specific, stated need to bypass the local cache — e.g. investigating a failure you suspect is caused by a stale cache entry. In that case, scope it to the single command under investigation and say why; never use it as the default.

Write the env vars literally at the start of each such command, exactly as in the steps below. Do not rely on export — each Bash tool call is a fresh shell, so exports do not carry across calls (true for any nx env var). Never stash the prefix in a shell variable (NX_OFF="…"; $NX_OFF npx nx … fails with "command not found": expanded variables are not parsed as assignments).

  1. Lint — NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx affected -t lint --base=$base --parallel=$cpuCount --fix (or NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx lint $projectName --fix).
  2. Format — NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx format:write --base=$base (both modes).
  3. Typecheck — NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx affected -t typecheck --base=$base --parallel=$cpuCount (or NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx typecheck $projectName --parallel=$cpuCount). Without the target, affected runs nothing and exits 0 and the single-project form errors with "cannot find configuration": report typecheck as n/a, never as failing.
  4. Test — NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx affected -t test --base=$base --parallel=$cpuCount --maxWorkers=1 (or NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx test $projectName).
  5. Build — NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx affected -t build --base=$base --configuration=production --parallel=$cpuCount (or NX_SKIP_REMOTE_CACHE=true NX_NO_CLOUD=true NX_POWERPACK_CACHE_MODE=no-cache npx nx build $projectName --configuration=production --parallel=$cpuCount).

Apply the fix rule on any failure in steps 1–5 (a test failure: retry once first, see Flaky tests). A failure left unfixed never stops the run: carry on with the next step.

Flags per target

Why --configuration=production and --maxWorkers=1: flags-rationale.md.

  • --maxWorkers=1 on the test step only. Forwarding it to lint (ESLint) or build (esbuild) fails as an unknown option.
  • Affected/run-many only, not single-project. With one project there's no project-level fan-out, so capping to one worker just serializes it — let a single project use all cores.
  • Same reason, --parallel is dropped from single-project lint and test (one task each — no fan-out). It stays on single-project typecheck and build, because both fan out across the whole dependency chain: build has dependsOn: ["^build"] and the inferred typecheck dependsOn: ["^typecheck"].

Flaky tests — retry once to classify

A failed test target may be flaky, not a real break. On a test failure, re-run that one target once in step 4's single-project form, prefixed like the steps (… npx nx test <project>). If it then passes (or, with Nx Cloud on, Nx prints NX detected a flaky task), it's flaky — don't try to "fix" it; record it as a flaky project:target for the report. If it fails the same way again, treat it as real under the Fix rule.

Final report (mandatory)

This skill runs in a forked context, so its final message is the only channel back to the caller. End with:

  • the affected base used: the resolved ref, NX_BASE and its value, or omitted because the ref is missing; flag a failed fetch as possibly stale;
  • per target (lint / format / typecheck / test / build): clean, n/a, skipped (with the reason — for large fan-out, the project count and list; for .env false positives, the excluded projects), or each failing project:target with its cause, plus any flaky project:target;
  • every file the run changed: hand-fixed (from your own edits — file plus one line on what and why) and tool-applied (lint --fix, format:write — every other file that differs or is new when the Setup snapshot's git ls-files pipeline, not its mktemp, is re-run into $snap/after.txt and the two files are diffed; then rm -rf "$snap": a finished run leaves nothing in TMPDIR).

Never report a bare "checks passed": an unlisted failure, skipped target or unmentioned edit reads as green and the caller can't act on it.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.