Files
initiative/specs/007-add-knip/plan.md

4.3 KiB

Implementation Plan: Add Knip Unused Code Detection

Branch: 007-add-knip | Date: 2026-03-05 | Spec: spec.md Input: Feature specification from /specs/007-add-knip/spec.md

Summary

Add Knip v5 as a root devDependency to detect unused files, exports, dependencies, devDependencies, and types across the pnpm workspace. Configure it with a workspace-aware knip.json, expose a standalone pnpm knip command, and integrate it into the existing pnpm check quality gate so it runs on every commit via Lefthook.

Technical Context

Language/Version: TypeScript 5.x (strict mode, verbatimModuleSyntax) Primary Dependencies: Knip v5 (new), Biome 2.0, Vitest, Vite 6, React 19 Storage: N/A Testing: Vitest (existing); manual verification of Knip output Target Platform: Node.js (developer tooling) Project Type: pnpm monorepo (packages/domain, packages/application, apps/web) Performance Goals: N/A (developer-time static analysis) Constraints: Must pass on the current codebase with zero false positives Scale/Scope: 3 workspace packages

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

Principle Status Notes
I. Deterministic Domain Core PASS No domain changes.
II. Layered Architecture PASS No layer changes; Knip is root-level tooling only.
III. Agent Boundary PASS No agent layer involved.
IV. Clarification-First PASS Feature is well-defined; no ambiguities.
V. Escalation Gates PASS Implementing per spec.
VI. MVP Baseline Language PASS No scope restrictions introduced.
VII. No Gameplay Rules PASS Tooling feature only.
Dev Workflow: Automated checks PASS Knip becomes part of the merge gate (pnpm check).

Post-design re-check: All gates still pass. No design decisions impact domain, layers, or architectural boundaries.

Project Structure

Documentation (this feature)

specs/007-add-knip/
├── spec.md
├── plan.md              # This file
├── research.md
├── data-model.md
├── quickstart.md
└── checklists/
    └── requirements.md

Source Code (repository root)

# Files modified
package.json             # Add knip devDep, add "knip" script, update "check" script

# Files created
knip.json                # Root-level Knip workspace configuration

Structure Decision: No new source directories. This feature only adds a config file and modifies the root package.json scripts. The existing monorepo structure (packages/*, apps/*) is referenced by Knip's workspace config but not changed.

Implementation Details

1. Install Knip

Add knip as a root devDependency:

pnpm add -Dw knip

2. Create knip.json

Root-level configuration leveraging auto-detection:

{
  "$schema": "https://unpkg.com/knip@5/schema.json",
  "entry": ["scripts/*.mjs"],
  "workspaces": {
    "packages/*": {},
    "apps/*": {}
  }
}

Knip auto-detects:

  • pnpm workspace packages from pnpm-workspace.yaml
  • Entry points from each package.json (main, exports, types)
  • TypeScript config from tsconfig.json files (including project references)
  • Vitest test patterns from vitest.config.ts
  • Vite config and plugins from vite.config.ts
  • Biome config from biome.json

3. Update package.json Scripts

Add standalone command and integrate into quality gate:

{
  "scripts": {
    "knip": "knip",
    "check": "knip && biome check . && tsc --build && vitest run"
  }
}

Knip runs first because it's fast and catches structural issues before heavier checks.

4. Validate

  1. Run pnpm knip — must pass clean on the current codebase (SC-002).
  2. If false positives appear, tune knip.json with ignore, ignoreDependencies, or plugin-specific overrides.
  3. Run pnpm check — full gate must pass (SC-001).
  4. Introduce an intentional unused export → verify pnpm knip catches it (SC-001).
  5. Remove the intentional unused export → verify clean again.

5. Update Agent Context

Run .specify/scripts/bash/update-agent-context.sh claude to register Knip as a project technology.

Complexity Tracking

No constitution violations. No complexity justifications needed.