@aurelienbbn/conformance-core

中文文档
0.2.0发布于 2026/10/16MITTypeScriptES Module构建来源已验证近 30 天下载 2262

Stack-agnostic repo hygiene conformance checks, packaged as a Vitest suite.

原始使用文档
文档目录13 节
  1. A report never confuses "no violations" with "no evidence"
  2. Three entry points
  3. Checks
  4. dependency-overlap
  5. duplication-budget
  6. dead-exports
  7. closed-design-system-probe
  8. tsconfig-strictness
  9. instruction-blocks
  10. Options
  11. Migration
  12. Registered contract inventory
  13. Credited concepts

@aurelienbbn/conformance-core

npm downloads CI license node

6 repo-hygiene checks for any TypeScript repo. Plain functions or one Vitest file.

// conformance.test.ts
import { coreConformance } from "@aurelienbbn/conformance-core/vitest";

coreConformance({ root: process.cwd(), tsconfigStrictness: {} });

vitest is an optional peer (>=4.1.11 <6.0.0); Node ^22.19.0 || ^24.11.0.

A report never confuses "no violations" with "no evidence"

skipped      excluded by skipChecks · CSS probe or tsconfig gate unconfigured
unsupported  tool absent (jscpd, knip) · no tsconfig found
failed       timeout · bad report · throw · bad options   (tools cap at 120 s, Vitest tests at 125 s)
evaluated    ran to completion, can still hold violations

report.status   failed      any error finding or failed check
                incomplete  any check not evaluated
                passed      otherwise  (configured static checks, not whole-project compliance)
EvaluationVitest test
skipped · unsupported warning⏭️ skipped, warning printed
unsupported error (requireTool, requireKnipConfig, explicit tsconfig files)❌ fails
failed❌ fails, even with warning severity
evaluated: errors · warnings only❌ fails · ✅ passes

Three entry points

import { runCoreConformance, runCoreConformanceReport } from "@aurelienbbn/conformance-core";

const findings = await runCoreConformance({
  root: process.cwd(),
  skipChecks: ["duplication-budget"],
}); // legacy, same severities
const report = await runCoreConformanceReport({ root: process.cwd() }); // { status, checks[], findings[] }

coreConformance (/vitest) makes one test per check. Finding: check, severity, message, path?, docs URL, evaluation when evidence is missing.

Full example, sample report, other exports
coreConformance({
  root: process.cwd(),
  duplication: { maxClones: 0 },
  deadExports: { requireKnipConfig: true },
  closedDesignSystem: {
    stylesheet: "theme.css",
    requiredSelectors: [".token"],
    forbiddenSelectors: [".raw"],
    buildCommand: [
      process.execPath,
      "-e",
      "require('node:fs').writeFileSync(process.argv[1], '.token {}')",
      "{output}",
    ],
  },
  tsconfigStrictness: {
    waivers: {
      exactOptionalPropertyTypes: "Vendor SDK typings assign undefined to optional fields.",
    },
  },
});

runCoreConformanceReport({ root, tsconfigStrictness: {}, skipChecks: ["duplication-budget"] }) on a workspace, trimmed:

{
  "status": "failed",
  "checks": [
    { "check": "dependency-overlap", "status": "evaluated", "findings": [] },
    {
      "check": "duplication-budget",
      "status": "skipped",
      "reason": "Excluded by skipChecks.",
      "findings": []
    },
    {
      "check": "closed-design-system-probe",
      "status": "skipped",
      "reason": "No CSS build/selector probe configured.",
      "findings": []
    },
    {
      "check": "tsconfig-strictness",
      "status": "evaluated",
      "findings": [
        {
          "check": "tsconfig-strictness",
          "severity": "error",
          "message": "packages/agentlint-plugin-core/tsconfig.json: `noUncheckedIndexedAccess` is unset; set it to true in compilerOptions.",
          "path": "packages/agentlint-plugin-core/tsconfig.json",
          "docs": "https://github.com/aurelienbobenrieth/harness/tree/main/packages/conformance-core#tsconfig-strictness"
        }
      ]
    }
  ]
}

Also exported: coreChecks, activeChecks, and each check object (dependencyOverlap, duplicationBudget, deadExports, closedDesignSystemProbe, tsconfigStrictness, instructionBlocks).

Checks

dependency-overlap

Built-in families warn (tools can be complementary); your dependencyOverlapGroups replace them and error; [] disables. Each root and workspace package.json judged alone.

The 30 built-in families, workspace discovery

Reads dependencies + devDependencies. Workspaces: pnpm-workspace.yaml packages: literal paths and single-level dir/* only; negations and deeper globs ignored.

dayjs date-fns moment luxon
axios got ky node-fetch superagent
uuid nanoid cuid cuid2 @paralleldrive/cuid2 ulid
zod yup joi ajv superstruct valibot arktype
lodash lodash-es ramda remeda es-toolkit
chalk picocolors kleur colorette ansis
dotenv dotenv-flow
jest vitest
winston pino bunyan loglevel consola
glob fast-glob globby tinyglobby
commander yargs cac citty meow
inquirer @inquirer/prompts prompts @clack/prompts enquirer
p-limit p-queue p-map promise-pool @supercharge/promise-pool
yaml js-yaml
papaparse csv-parse fast-csv
prisma drizzle-orm kysely knex typeorm sequelize
ws socket.io
immer mutative
zustand jotai valtio @xstate/store
fs-extra graceful-fs
semver compare-versions
marked markdown-it remark micromark
cheerio parse5 linkedom node-html-parser
execa zx tinyexec
rimraf del
cross-env env-cmd
nodemon tsx-watch watchexec
mime mime-types
deepmerge defu ts-deepmerge
query-string qs

duplication-budget

jscpd, ignoring node_modules, dist, coverage, .git. Over budget: ❌ with the top 3 clones. Malformed clone rows fail under any budget.

dead-exports

knip --reporter json: unused files, exports, types, namespace, enum, and class members (10 listed). Report shapes checked first. Default: no knip config still runs; absent knip warns; timeout or bad output fails.

closed-design-system-probe

A finite selector probe, not proof of exhaustive closure. Exact required/forbidden selectors in your parsed build output. No default builder, no implicit install; the builder must include the probe inputs. Timeout, nonzero exit, no output, invalid CSS → failed.

[!WARNING] Windows: pass a native executable or node plus the tool's JS entrypoint. Shell shims (.cmd, .bat, npx, npm, pnpm, yarn) are rejected.

Recipe: close a Tailwind v4 theme and prove it
  1. Put --*: initial in the top-level @theme (Tailwind theme docs) so only your tokens generate utilities, then migrate affected uses. Static utilities and arbitrary values still work: this closes the token set, not the class list.
  2. Probe stylesheet: an isolated file importing the real one and requesting allowed and forbidden classes through @source inline(...) (syntax). Without it, a missing selector may only mean "never discovered".
  3. Build with the pinned local CLI as an executable plus argument array; never a downloaded floating CLI. buildCommand is required because core conformance has no framework default.
  4. Wire it like the example.

For a full class allowlist, also check class construction and arbitrary values in source. A failed build or missing tool means unevaluated, never "forbidden absent". Keep probe candidates out of production source.

tsconfig-strictness

A loosened tsconfig silently degrades type-aware lint (no-unnecessary-condition, strict-boolean-expressions, no-unsafe-*), and no AST rule sees JSON. Checks effective options after extends; messages name the file that set each value.

Requires strict: true written down, never inherited; noUncheckedIndexedAccess, exactOptionalPropertyTypes, verbatimModuleSyntax, erasableSyntaxOnly true; no strict-family flag off; no ignoreDeprecations, whatever its value.

Strict family, default files, waivers, failure modes, extends resolution
  • Strict family: strictNullChecks, noImplicitAny, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, strictBuiltinIteratorReturn, noImplicitThis, useUnknownInCatchVariables, alwaysStrict.
  • erasableSyntaxOnly replaces a family of enum/namespace/parameter-property lint rules with a compiler guarantee.
  • Default files: tsconfig.json + tsconfig.*.json in the root and every pnpm workspace package, minus solution files ("files": [], no include) and configs that only serve as another checked config's extends base.
  • additionalRequiredFlags: more flags that must be true, e.g. noImplicitOverride.
InputResult
waiver (flag → reason ≥ 3 words)⚠️ warning repeating the reason in every report
waiver for a flag the check doesn't own, or reason < 3 wordsthrows (failed evaluation in the report)
waiver matching nothing⚠️ stale-waiver warning
missing or circular extends, unreadable or malformed file❌ failed evaluation, never a pass
listed file missing❌ failed
no tsconfig discovered⚠️ unsupported (❌ error when files is explicit)

extends resolution: relative paths with or without .json; arrays, later entries winning; package specifiers from node_modules (scoped too) via string exports targets or the manifest tsconfig field; JSONC comments, trailing commas, a BOM. Reads JSON only: no tsc run, no TypeScript install needed.

instruction-blocks

A rule the agent must follow on every reply belongs in the file it always loads, yet should be written once. Each configured block in AGENTS.md (or file) must hold its source file's exact text between <!-- harness:<name>:start --> and <!-- harness:<name>:end -->. Line endings and surrounding blank lines are ignored; anything else is drift.

instructionBlocks: {
  blocks: {
    communication: ".agents/skills/communication/core.md";
  }
}
InputResult
block text differs from source❌ drifted, recopy the source
no markers, unclosed, end before start, repeated markers❌ names the markers to add
instructions file missing❌
source missing, empty blocks, non-kebab block namethrows (failed evaluation)
markers for a block you didn't configureignored

Options

OptionDefaultNotes
skipChecks[]unknown IDs throw
dependencyOverlapGroups30 familiesyours replace them
duplication.maxClones · .minLines · .minTokens0 · 8 · 60safe integers; maxClones ≥ 0, others > 0
duplication.ignorePatterns[]generated/vendor globs
duplication.requireToolfalseabsent jscpd or bad run → ❌
deadExports.requireKnipConfigfalseno config (knip.json(c), .knip.json(c), knip(.config).ts/js, package.json#knip), tool, or output → ❌
closedDesignSystemunset (skipped)stylesheet, buildCommand argv with {stylesheet} {output}, requiredSelectors, forbiddenSelectors
tsconfigStrictnessunset (skipped){} = defaults; files, additionalRequiredFlags, waivers
instructionBlocksunset (skipped)blocks (name → root-relative source), file (default AGENTS.md)

Migration

  • Unknown skipChecks IDs throw instead of silently losing the exception: fix the misspelling.
  • Absent optional tools are skipped tests; bad output or failed runs fail. Both could pass as warning-only tests before.
  • Duplication limits must be finite safe integers; malformed jscpd rows fail even under a generous budget.

Registered contract inventory

Generated from package exports by pnpm catalog. Rule-specific options and limitations are described above and in the source tests.

Rule/checkTrigger or review scope
closed-design-system-probeThe built CSS contains every owned token utility and excludes configured forbidden selectors.
dead-exportsNo unused files or exports remain in the codebase (knip).
dependency-overlapOnly one package per known-duplicate dependency family may be installed.
duplication-budgetCopy-pasted blocks stay within the configured clone budget (jscpd).
instruction-blocksMarked blocks in the agent instructions file match their source files exactly.
tsconfig-strictnessResolved tsconfig files keep the strict compiler baseline with no strict-family flag switched off.

Credited concepts

  • ai-automation by Sandro Maglione (inspiration, independently re-implemented)
  • code-slop by asyrafhussin (MIT, concept re-implemented)
  • desloppify by Peter O'Malley (concept only, no code reuse)

版本与发布记录

@aurelienbbn/conformance-core 共发布 4 个版本,首次发布于 2026/09/25;过去 12 个月发布了 4 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.2.0latest2026/10/1622 天前
0.1.22026/10/1424 天前
0.1.12026/09/251 个月前
0.1.02026/09/251 个月前

关于 @aurelienbbn/conformance-core 的常见问题

@aurelienbbn/conformance-core 是什么?

Stack-agnostic repo hygiene conformance checks, packaged as a Vitest suite.

如何安装 @aurelienbbn/conformance-core?

在项目目录运行 npm install @aurelienbbn/conformance-core,或使用 pnpm add / yarn add / bun add。

@aurelienbbn/conformance-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@aurelienbbn/conformance-core 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@aurelienbbn/conformance-core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^22.19.0 || ^24.11.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@aurelienbbn/conformance-core 可以商用吗?

@aurelienbbn/conformance-core 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@aurelienbbn/conformance-core 的下载量有多少?

根据 npm 官方下载统计,@aurelienbbn/conformance-core 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,262 次,日均约 75 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aurelienbbn/conformance-core 还在维护吗?

最新版本 0.2.0 发布于 2026/10/16(22 天前);至今共发布 4 个版本,其中过去 12 个月发布了 4 个;首次发布于 2026/09/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。