Repository navigation
Adopt Knip with staged cleanup and blocking CI checks #147
Description
Goal
Adopt Knip to identify unused code/dependencies, clean confirmed existing findings, and prevent regressions in CI. Deliver separately reviewable PRs targeting CopilotKit/OpenDots, not the contributor's fork as the destination.
This is an implementation plan, not a report from an actual Knip run. No dependencies were installed or application code changed during planning.
Current project context
Checked against upstream main at 625452e06cde74cb25b0ce319e2c1be0488f5a5f:
- Single private ESM npm package, no workspaces; Node >=24, CI uses Node 24.
- React/Vite client, Node/Hono server, separate browser runtime using Playwright.
- Existing CI: npm ci → formatting → lint → typecheck → tests → build.
- No conventional source codegen/build prerequisite identified; validate Knip before building in a clean checkout.
Scope and safety policy
- Default mode is primary, including tests/tooling. Production mode is complementary, with all runtime roots validated before enforcement.
- Fix discovery/resolution before cleanup or suppression. Exceptions must be narrow, justified and revisable; no global exports/types exclusions, issue-count budgets, or broad autofix.
- Remove unnecessary export modifiers, not implementations still used within their file.
- Remove unused
eslint-plugin-react-hooks; do not enable new React Hooks lint rules here. - Check peers, global types, CLI/config usage, overrides, dynamic imports and external consumers before removal. Protect legitimate
@tiptap/pm,@types/*, PostCSS/tooling and runtime Playwright usage. - A production-only finding does not authorize deleting code legitimately used by tests/tooling in default mode.
- Respect .gitignore. Keep credentials, databases, generated reports and internal planning notes out of commits. Implement from an isolated upstream checkout without incorporating unrelated local lockfile changes.
- No unrelated upgrades, application behavior changes or extra opt-in cycle/namespace/member analyses.
PR 1 — Configuration, discovery and report-only CI
- Validate published Knip 6.41.0 against Node 24 / TS 6 / Vite 8 / ESLint 10; add an exact devDependency and update the npm lockfile.
- Add static
knip.jsonwith v6 schema; verify automatic Vite/Vitest/TypeScript/ESLint/Prettier discovery, scripts and both tsconfigs. - Add
npm run knip→knip, andnpm run knip:production→knip --production. - Protect production roots with trailing
!patterns:src/client/main.tsx!,src/server/index.ts!,src/browser/index.ts!,public/theme.js!,deployment/computers/harden-supervisor.mjs!. Production mode must not depend on discovery of development/browser npm scripts. - Delimit project files:
src/{client,server,browser,shared}/**/*.{ts,tsx}!,src/build/**/*.ts,tests/**/*.{ts,tsx,js},public/**/*.js!,deployment/computers/**/*.mjs!,*.{js,ts}. Plugins retain responsibility for their configs/tests; do not turn every source/fixture into an entrypoint or force development tooling into production. - Use
--debugin both modes to validate entries, resolution, lazy imports, URL-loaded theme JS, Docker-invoked patch, and tests involving string/data-URL imports. Playwright here is runtime, not an @playwright/test suite. - Check the nonexistent
main: "index.js"metadata; correct it only if it interferes with discovery, without inventing an entrypoint. - Record a sanitized baseline here: category/mode, count, files, and disposition (discovery correction, confirmed removal, legitimate exception).
- Add both commands to existing CI after npm ci and before build, initially with
--no-exit-code --reporter symbols --reporter github-actions. Do not use blanket continue-on-error: operational/config-load errors still fail. - Add
docs/knip.md, link it from CONTRIBUTING.md, and document commands, entry maintenance, triage and exception reasons.
Acceptance: all roots accounted for; both modes work before build in a fresh checkout without application credentials; malformed configuration returns exit 2 even in report-only mode; existing formatting/lint/typecheck/tests/build pass. No application-code cleanup in this PR.
PRs 2.x — Confirmed cleanup by category/area
Order: files → dependencies → exports/types, rerunning analysis after each batch. Skip empty cleanup PRs when a category has no confirmed findings.
- Files: verify imports, HTML, scripts, Docker and filesystem references before deletion; correct discovery for legitimate external entrypoints.
- Dependencies: remove
eslint-plugin-react-hooksafter reconfirming no usage/configuration; remove other packages only with evidence. Update the lockfile without unrelated churn; validate peers/runtime/types in a clean install. - Exports/types: remove redundant exports while preserving local functions and framework/SDK callbacks. Review complete default-category results, not just the exports filter.
- Preserve legitimate test/tooling use when interpreting production-only findings; document precise exceptions.
- Maintain per-finding decisions and link each PR here.
Candidates to investigate, not confirmed findings: Empty in TaskPresentation.tsx, the slackIdentity reexport in platform.ts, and local-only exports in TaskPresentation, slash-commands and dark-theme. This list is not deletion authorization.
Acceptance per PR: justified removals; both Knip modes rerun; clean installation and formatter/lint/typecheck/tests/build pass; relevant telemetry/deployment/theme/Slack/editor tests and UI smoke checks exercised. Any necessary behavior change requires regression coverage and explicit review.
Final PR — Blocking CI and maintenance
- Reach zero unaccounted findings in applicable default categories in both validated modes; resolve stale config hints.
- Add
--treat-config-hints-as-errorsto both scripts; remove--no-exit-codefrom CI, retaining readable output/annotations. - In a disposable checkout, independently introduce an orphan TS file, an unused export in a consumed module, and an unused runtime dependency. Prove findings and exit 1 in both modes; report-only returns 0 for findings, malformed config returns 2.
- Remove temporary probes and prove both commands and the existing CI chain return to green. Do not commit probes/reports.
- Ask maintainers to confirm the existing
checkjob is required by merge rules. A failing workflow alone does not prove merge protection; do not change rulesets without administrative authorization. - Update maintenance docs and this issue with PR links, justified exceptions and merge-protection confirmation/status.
Record a genuine production compatibility blocker here before changing the agreed final goal. Intermediate PRs reference this issue; only the final PR closes it after satisfying acceptance criteria.
Activity
DevJoaoLopes commentedon Oct 13, 2026
Stage 1 is ready for review: #148 — Knip configuration and report-only CI.
The exact PR commit was verified in a fresh checkout: npm ci, formatting, lint, typecheck, 302 tests across 48 files, both Knip report-only modes before build, and production build all passed.
Baseline for the published stage:
No configuration hints remain. The next PRs will address the unused lint dependency and confirmed exports/types separately, preserving regression-test consumers. Blocking CI follows only after cleanup; this issue remains open.
Before the final enforcement stage, maintainers should confirm that the existing
checkjob is required by merge rules.