Files
2026-05-27 23:29:53 +01:00

4.7 KiB

Tasks: enterprise-server-linter

Change ID: enterprise-server-linter Package: @suaveplan/linter Target path: server/infra/linter Prerequisites on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/logger


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create directory tree per proposal.md.
  • package.json at 0.1.0, "sideEffects": false, exports:
    • ".": main barrel
    • "./presets/base": "./presets/base.json"
    • "./presets/library": "./presets/library.json"
    • "./presets/react": "./presets/react.json"
    • "./presets/node": "./presets/node.json"
    • "./presets/test": "./presets/test.json"
    • "./runner": runner subpath
  • Deps: @suaveplan/error workspace:^, @suaveplan/types workspace:^, @suaveplan/logger workspace:^, zod catalog:forms, @opentelemetry/api catalog:observability, @biomejs/biome catalog:build, tslib catalog:build.
  • DevDeps: vitest catalog:testing, @vitest/coverage-istanbul catalog:testing, @suaveplan/testing workspace:^.
  • tsconfig.json extending library-node.json; vitest.config.ts with createTestConfig().
  • Scripts: lint, typecheck, test, test:coverage, build, docs:check.

2. Preset JSON files

  • Write presets/base.json: Biome config extending Biome recommended; enables linter rules for correctness, complexity, suspicious; format with tabs, double quotes, trailing commas; max line width 120.
  • Write presets/library.json: extends base; stricter TypeScript rules (no explicit any, no unsafe member access), required return types.
  • Write presets/react.json: extends library; enables JSX rules; allows JSX a11y overrides.
  • Write presets/node.json: extends library; allows Node.js process, globals.
  • Write presets/test.json: extends base; relaxes return-type and explicit-any rules inside test files; allows describe/it/expect globals.

3. Types and errors

  • Define LinterOptions, LintResult, LintDiagnostic and Zod schemas in src/types/linter.types.ts.
  • Write linter.types.md (≥200 words, both examples, API reference).
  • src/error-codes.ts: three codes; registerLinterErrorCodes(); eager call.

4. Linter runner

  • Implement LinterRunner in src/runner/linter-runner/linter-runner.ts:
    • Spawn Biome CLI via Bun.spawn(['biome', 'check', '--reporter=json', ...targets]) with configPath arg when provided.
    • Parse JSON output into LintResult. Map Biome diagnostic fields to LintDiagnostic.
    • check(targets): biome check — returns diagnostics without fixing.
    • fix(targets): biome check --apply — applies safe fixes.
    • format(targets): biome format --write — formats files.
    • Non-zero exit code with no JSON output: throw LINTER_EXECUTION_FAILED.
    • OTel counter linter.runs_total with command and passed; histogram linter.duration_ms.
  • Write linter-runner.types.ts.
  • Write linter-runner.test.ts (≤500 lines): check passes on valid TS file; check fails on file with intentional error; fix resolves auto-fixable issues; invalid target throws LINTER_INVALID_TARGET. Use real temp file with known content.
  • Write linter-runner.md (≥200 words, simple + advanced, API reference).

5. Integration tests

  • tests/integration.test.ts: create a temp TypeScript file with a lint violation; run check → expect passed: false; run fix → expect fixed; run format → expect formatted output; { timeout: 30000 }.

6. Docs + verify + publish

  • Root README.md: preset usage in biome.json, programmatic API quick-start, preset comparison table, API table.
  • bunx turbo lint --filter=@suaveplan/linter — zero errors.
  • bunx turbo typecheck --filter=@suaveplan/linter — zero errors.
  • bunx turbo test --filter=@suaveplan/linter — all pass.
  • bunx turbo test:coverage --filter=@suaveplan/linter — 100%.
  • bun scripts/publish.ts --package @suaveplan/linter.
  • Update CLAUDE.md; archive to openspec/archive/2026-04-24-enterprise-server-linter/.