stack-onboarding-typescript — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited stack-onboarding-typescript (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Per-stack reference for the base variant. Companion to agents/onboarding/idiom-advisor.md.
| Concern | Recommendation |
|---|---|
| Test runner | vitest (preferred for ESM) or jest (universal) |
| Package manager | pnpm (preferred for monorepos) or npm (universal) or yarn |
| Build tool | tsc (type-check); swc / esbuild / vite for emit |
| Type checker | tsc --noEmit --strict (the build IS the typecheck) |
| Linter | eslint with @typescript-eslint |
| Formatter | prettier |
| Min Node | 20 LTS for new projects (native fetch, web crypto, ESM stable) |
vitest # watch mode (default)
vitest run # one-shot
vitest run src/foo.test.ts # single file
vitest run -t "test name substring" # name filter
vitest run --coverage # coverage (v8 / istanbul)vitest.config.ts:
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
environment: "node", // or "jsdom" for browser-like
globals: true, // makes describe/it/expect global
},
});jest
jest src/foo.test.ts
jest -t "test name substring"
jest --coverageFor TS support: ts-jest or @swc/jest. Vitest handles TS natively without setup.
pnpm install # install per pnpm-lock.yaml
pnpm add express # add dep
pnpm add -D vitest # add dev dep
pnpm -r build # run build in every workspace pkg
pnpm -F @org/pkg test # filter to single packagepnpm-workspace.yaml:
packages:
- "packages/*"
- "apps/*"npm install
npm install express
npm install -D vitest
npm test
npm run <script>Mixed adoption; pnpm is usually the better default for new projects.
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"exactOptionalPropertyTypes": true,
"noEmit": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}strict: true enables all strict checks. noUncheckedIndexedAccess adds | undefined to indexed access — prevents many off-by-one bugs.
tsc --noEmit # type-check; no JS outputswc src -d dist
esbuild src/index.ts --bundle --outdir=distvite build # production build
vite # dev server (HMR)eslint src/
eslint --fix src/
prettier --check src/
prettier --write src/.eslintrc.cjs extending @typescript-eslint/recommended. Run prettier last; eslint catches semantic issues, prettier owns purely cosmetic.
any opts out of type-checking. Use unknown and narrow; or // @ts-expect-error <reason> if genuinely intentional.Promise<T> — silently passes the promise object as the value. ESLint rule no-floating-promises catches this.=== (ESLint eqeqeq).=== null checks that miss undefined cases."type": "module" in package.json); legacy: CJS. Mixing requires careful import / require handling and dual-build packages.strict: true per file using // @ts-strict (or per-project escalation).value as Foo does NOT validate; use a runtime validator (Zod, Valibot) at trust boundaries.type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle":
return Math.PI * s.radius ** 2;
case "square":
return s.side ** 2;
}
}Compiler enforces exhaustive switch. Add a never default for forward-compat.
Promise.all for Parallel Asyncconst [user, orders, prefs] = await Promise.all([
fetchUser(id),
fetchOrders(id),
fetchPrefs(id),
]);Promise.allSettled if you want all results regardless of failures.
const COLORS = ["red", "green", "blue"] as const;
type Color = (typeof COLORS)[number]; // "red" | "green" | "blue"import { z } from "zod";
const CreateUser = z.object({
email: z.string().email(),
age: z.number().int().min(0).max(150),
});
type CreateUser = z.infer<typeof CreateUser>;
const parsed = CreateUser.parse(req.body); // throws ZodError on invalidCounterpart for Python's Pydantic; same role.
type UserId = string & { readonly __brand: "UserId" };
type OrderId = string & { readonly __brand: "OrderId" };Prevents accidentally swapping UserId and OrderId at call sites; runtime is just string.
tsc --noEmit --strict to verify type-graph health; eslint to surface lint issues.packages/<pkg>/) or by feature directory; each shard ≤500 LOC load-bearing logic.vitest run per shard (fail-fast); tsc --noEmit on changed packages.tsc --noEmit --strict (zero errors), eslint (zero errors), vitest run --coverage (coverage threshold), pnpm audit (no high-severity vulns).exactOptionalPropertyTypes, Result<T, E> patterns).pnpm build; verify dist/; npm version <major|minor|patch> (or pnpm equivalent); pnpm publish.agents/generic/db-specialist.md — for TS DB drivers (pg, prisma, drizzle, kysely)agents/generic/api-specialist.md — for TS HTTP frameworks (express, fastify, Hono, NestJS)agents/generic/ai-specialist.md — for TS LLM SDKs (openai, anthropic, Vercel AI SDK)Deepen with: monorepo build orchestration (Turborepo, Nx); deno / bun runtimes (alternatives to Node); browser bundling depth (Vite vs Rollup vs webpack); React Server Components patterns.
Origin: 2026-05-06 v2.21.0 base-variant Phase 1 STARTER.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.