plugins/lt-dev/skills/running-check-script/SKILL.md
Single source of truth for running the package.json `check` script across lt-dev review and rebase workflows. Defines discovery (multi-package monorepo aware), the iterate-until-green auto-fix loop, the mandatory audit-finding fix escalation ladder, residual classification (Accepted vs Critical), test-duplication avoidance, and report formatting. Activates whenever an agent or command needs to validate runnability via `check` — currently used by `/lt-dev:review`, `code-reviewer`, `branch-rebaser`, and `test-reviewer`. NOT for general npm package maintenance (use maintaining-npm-packages). NOT for the rebase orchestration itself (use rebasing-branches).
npx skillsauth add lennetech/claude-code running-check-scriptInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
check ScriptThis skill is the single source of truth for executing the package.json check script in lt-dev workflows. Every reviewer, rebaser, and orchestrator that needs to guarantee project runnability must follow this procedure verbatim — duplicating the rules across agents leads to drift.
Goal: A truly green
checkrun (exit 0) is a non-negotiable prerequisite for any review or rebase to be considered complete. The only acceptable residual is an upstream dependency vulnerability where the full fix escalation ladder has been exhausted.
| Caller | Phase | Trigger |
|--------|-------|---------|
| /lt-dev:review | Phase 1.5 | Before spawning any specialized reviewer |
| lt-dev:code-reviewer | Phase 1.5 | Before single-pass review (skip if orchestrator already ran it) |
| lt-dev:branch-rebaser | Phase 6.5 | After lint/format, before tests |
| lt-dev:test-reviewer | (input briefing) | Honors the skip semantics defined here |
check scriptsUse the dedicated helper script (located in the lt-dev plugin):
bash "${CLAUDE_PLUGIN_ROOT}/scripts/discover-check-scripts.sh" "$(pwd)"
Output is TSV, one project per line:
<package.json path>\t<check script>\t<includes_tests:yes|no>\t<package manager>
The helper:
git ls-files "package.json" "**/package.json" so it respects .gitignore and skips node_modulesjq → node -e → grep+sed fallback chain (works even without jq installed)"check": "pnpm run ci" → looks up ci)check transitively invokes a test runner (test, vitest, jest, playwright)pnpm-lock.yaml → pnpm, etc.; default pnpm)If the helper returns nothing → no project defines check → skip the rest of this skill.
check per projectFor each discovered project, cd into its directory and run the check script with the detected package manager:
cd "$(dirname <package.json path>)"
<package manager> run check
Capture stdout, stderr, and exit code. Track an iteration counter starting at 1.
If a project's check exits non-zero:
Read + Edit. Includes pre-existing errors unrelated to the diff — runnability overrides scope boundaries.check from scratch. Never trust partial state.check exits 0 → done for this projectWhen pnpm audit / npm audit / yarn audit (invoked by check) reports a vulnerability, you MUST exhaust this ladder before classifying the finding as Accepted. Re-run check after every step.
| # | Step | Command (pnpm / npm / yarn) |
|---|------|------------------------------|
| 1 | Update to latest compatible | pnpm update <pkg> / npm update <pkg> / yarn upgrade <pkg> |
| 2 | Automatic remediation | pnpm audit --fix / npm audit fix / yarn audit --fix |
| 3 | Force semver-major upgrade | pnpm audit --fix --force / npm audit fix --force |
| 4 | Bump direct dep to next major if advisory lists fix there | pnpm add <pkg>@<major> / npm install <pkg>@<major> / yarn add <pkg>@<major> |
| 5 | Force a transitive dep version | pnpm.overrides / resolutions (yarn) / overrides (npm) block in package.json, then re-install |
| 6 | Replace the package | Switch to a maintained alternative if abandoned |
A finding may only be classified as Accepted after every applicable step has been tried and verified, with documented evidence that no patched version exists anywhere in the ecosystem.
Only after a project has STALLED (and, for audit findings, only after the escalation ladder is exhausted):
| Residual type | Treatment | |---------------|-----------| | Vulnerable dependency where the full ladder has been tried and no patched version exists (verified via registry, advisory database, upstream repo) | Accepted Residual — document with package name, advisory ID, ladder steps tried, why each failed, evidence of unfixability. NOT a blocker. | | Vulnerable dependency where the ladder has NOT been fully tried | Critical blocker — the loop is not allowed to terminate until the ladder is exhausted. | | Any other residual (typecheck, lint, build, test, import, etc.) | Critical blocker — add to Remediation Catalog with Critical priority. |
Never use any of the following to silence errors:
git commit --no-verify@ts-ignore, @ts-expect-error, @ts-nocheckeslint-disable, eslint-disable-next-line, eslint-disable-line/* istanbul ignore */it.skip(...), describe.skip(...), test.skip(...) in test files--passWithNoTests flags on the test commandoxlint-disable directives to suppress real findingsThe ONLY permitted "non-fix" is an upstream dependency vulnerability where the escalation ladder has been fully exhausted. Everything else must be fixed at the root.
check-server-start.sh failure modes (Nitro/Nest port hazards)The starter check pipeline ends with bash scripts/check-server-start.sh, which boots the production build and waits for the readiness log. Three known failure modes — all surface as the same symptom (ERR_SOCKET_BAD_PORT from node:net) but have different root causes:
Nitro PORT-string bug (App side): the script must use NITRO_PORT=$FREE_PORT, never PORT=$FREE_PORT. Some Nitro versions read process.env.PORT without parseInt and crash; NITRO_PORT is the documented Nitro-specific knob, goes through Nitro's own env loader, and is coerced to number reliably. Nest does not have this issue — NSC__PORT is fine on the API side.
lerna/nx ANSI-injection (BOTH api and app, only when check is invoked from a workspace runner): the runner wraps subprocess stdout and may inject ANSI color escape sequences (\x1b[33m...\x1b[39m) into command output. A naive FREE_PORT=$(node -e "...console.log(p)") captures the codes too. A naive tr -cd '0-9' makes it worse — the codes contain digits (33, 39) themselves, producing nonsense ports like 335454639. The only correct fix is to strip the ANSI sequence pattern explicitly with sed:
FREE_PORT=$(node -e "..." | sed $'s/\x1b\\[[0-9;]*m//g' | tr -d '[:space:]')
Phantom Unix-domain-sockets named [33m12345[39m next to the package.json (mode srwx): leftover from earlier failed runs. When Nest's port-parser fell through "string with weird chars" → "treat as Unix socket path", it actually bound a socket file. cleanup() SIGTERM kills the process, the file stays. Delete with:
rm -f $'\x1b[33m'*$'\x1b[39m'
Then re-run check.
These hazards are documented in detail in the modernizing-toolchain skill (Phase 6). When a check run fails with ERR_SOCKET_BAD_PORT, the first triage step is to confirm the script in question already has both the NITRO_PORT and ANSI-strip fixes applied.
Tests must not run twice if check already covered them on an unchanged working tree.
After each project completes Step 3 with a GREEN result, record a post-check baseline:
git -C <project-dir> rev-parse HEAD # commit baseline
git -C <project-dir> status --porcelain # working-tree baseline
A subsequent test phase (e.g. branch-rebaser Phase 7, code-reviewer Phase 5, test-reviewer) may skip running tests for a project when ALL of the following hold:
check as includes_tests=yesgit rev-parse HEAD matches the baseline (no new commits)git status --porcelain matches the baseline (no working-tree changes since)If any condition fails → run tests as normal.
Every caller must include this block in its final report:
### Check Script Results
| Project | Script | Iterations | Initial Errors | Auto-Fixed | Accepted | Final Status |
|---------|--------|------------|----------------|------------|----------|--------------|
| projects/api | pnpm run check | 3 | 7 | 6 | 1 | ⚠️ (1 accepted) |
| projects/app | pnpm run check | 1 | 0 | 0 | 0 | ✅ |
**Fixes applied:**
- `projects/api/src/modules/user/user.service.ts:42` — Removed unused `LoggerService` import (pre-existing)
- `projects/api/src/modules/auth/auth.controller.ts:18` — Fixed implicit `any` on `req` parameter (introduced in diff)
**Check Script — Accepted Residuals** (escalation ladder exhausted):
- `projects/api`: `[email protected]` — GHSA-xxxx-yyyy-zzzz (Moderate)
- Ladder steps tried: (1) `pnpm update` — no newer version, (2) `audit --fix` — no fix available, (3) `--force` — same, (4) next major doesn't exist, (5) no override target, (6) no maintained alternative
- Evidence: registry shows latest = 1.2.3, no advisory fix listed
**Check Script — Unresolved** (Critical blockers):
- _(none)_
When /lt-dev:review delegates a small diff to lt-dev:code-reviewer, the orchestrator has already executed this skill in Phase 1.5. To avoid a duplicate run, the orchestrator passes:
SKIP running-check-script — orchestrator already ran it. Pre-computed Check Script Results block:
<paste full block from Step 8 verbatim>
The agent then skips Steps 1–7 and pastes the block verbatim into its report.
| Element | Relationship |
|---------|--------------|
| Script: scripts/discover-check-scripts.sh | Discovery helper (Step 1) |
| Command: /lt-dev:review | Orchestrator caller (Phase 1.5) |
| Agent: code-reviewer | Single-pass caller (Phase 1.5) |
| Agent: branch-rebaser | Rebase caller (Phase 6.5) |
| Agent: test-reviewer | Honors skip semantics from Step 7 |
| Skill: maintaining-npm-packages | Owns the broader package maintenance ladder; this skill borrows Step 4 from there |
| Skill: rebasing-branches | Strategy for rebases; defers check execution to this skill |
development
Single source of truth for the lenne.tech fullstack production-readiness checklist. Defines the eight pillars (configuration & secrets, observability & logging, health & lifecycle, security hardening, data durability, resilience under load, deployment hygiene, runbook & rollback) with concrete file/line evidence requirements per pillar, severity classification (Critical / Major / Minor), and a canonical machine-parseable report block. Activates whenever an agent or command needs to gate a release on production-readiness — currently used by /lt-dev:production-ready, lt-dev:production-readiness-orchestrator, and the devops-reviewer (read-only). NOT for OWASP-style code-level security review (use security-reviewer). NOT for npm dependency audits (use maintaining-npm-packages).
development
Single source of truth for executing GitLab CI/CD pipelines locally with the same image, env vars, and service containers as the real runner — so pipeline failures are caught before push. Defines pipeline discovery (.gitlab-ci.yml + includes), per-job execution via gitlab-runner exec, service-container orchestration (Mongo, Redis, MailHog), env injection without secrets, cache/artifact handling, and a job-by-job verdict report. Also describes the GitHub Actions equivalent via act for projects that mirror to GitHub. Activates whenever an agent or command needs to validate that the CI pipeline will pass — currently used by /lt-dev:production-ready and lt-dev:production-readiness-orchestrator. NOT for running the local check script (use running-check-script). NOT for writing or refactoring CI configs (use the devops agent).
development
Single source of truth for designing, running, and interpreting k6 load tests against lenne.tech fullstack APIs. Defines installation paths (brew, docker, npm), the three canonical scenarios (smoke / load / soak), endpoint discovery from the generated SDK, realistic Better-Auth login flows, threshold defaults for ~10 concurrent users (p95 < 500ms, error rate < 1%, http_req_failed < 1%), result interpretation, and the optimisation ladder when the system fails (DB indices, query rewrites, caching, connection pool sizing, rate-limit relaxation, payload trimming). Activates whenever an agent or command needs to validate that the API is stable for ~10 concurrent users performing many actions in short time, or to detect performance regressions via k6. Currently used by /lt-dev:production-ready, lt-dev:production-readiness-orchestrator, and lt-dev:performance-reviewer. NOT for Lighthouse frontend performance (use a11y-reviewer). NOT for unit performance assertions (use the test runner directly).
tools
Migrates lenne.tech projects from the legacy jest+eslint+prettier toolchain to the current vitest+oxlint+oxfmt baseline used by nest-server-starter and nuxt-base-starter. Covers swc decoratorMetadata config, the @Prop union-type fix for SWC, supertest default-import correction, ESM/CJS interop, the Nitro PORT-vs-NITRO_PORT bug, ANSI escape stripping in workspace runners (lerna/nx), free-port logic for check-server-start.sh, the offers-pattern config.env.ts (NSC__-only + fail-fast + auto-derived appUrl), and the multi-phase check-envs.sh smoke test. Activates whenever someone is migrating an existing project to the new toolchain, debugging "Cannot determine a type for the X field" Mongoose errors, ERR_SOCKET_BAD_PORT crashes from check-server-start, or wants to align an existing project with the current starter conventions.