chore(ui): make knip trustworthy and enforce dead-code in CI - #32727
Conversation
Greptile SummaryThis PR makes the existing
Confidence Score: 5/5Safe to merge — changes are limited to CI configuration, a linter config file, and a package.json dependency declaration; no production source code is touched. The diff is purely infrastructure: a CI step that runs knip, a knip config that removes documented false positives, and a package.json entry that formalises an already-used transitive dependency. The PR description includes before/after output confirming exit code 0, and the config choices are clearly reasoned. Nothing here affects runtime behaviour. No files require special attention.
|
| Filename | Overview |
|---|---|
| .github/workflows/test-litellm-ui-build.yml | Adds a knip dead-code check step to the frontend-lint job; correctly inherits the job-level working-directory: ui/litellm-dashboard and uses the same has_files guard as the existing lint steps. |
| ui/litellm-dashboard/knip.json | Fixes three false-positive sources (shadcn ui/ entry points, multiple playwright configs, explicit vitest plugin) and introduces a rules block that gates clean categories as errors and keeps noisy ones as warnings. |
| ui/litellm-dashboard/package.json | Promotes @ant-design/icons from an implicit transitive hoist to an explicit direct dependency at 5.6.1, eliminating 198 false "unlisted dependency" warnings from knip. |
| ui/litellm-dashboard/package-lock.json | Lockfile updated to record @ant-design/icons 5.6.1 as a direct dependency entry; no other substantive changes. |
Reviews (2): Last reviewed commit: "chore(ui): make knip trustworthy and enf..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
knip was producing garbage locally and was never wired into CI, so nobody trusted it. Two structural problems: it silently degrades when deps are missing (a partial worktree install flagged all 436 test files as unused), and its config had blind spots that surfaced as false positives. Fixes so a knip run means something: - Register every playwright config (serverRootPath + migration variants), not just the main one. serverRootPath.config.ts is invoked via --config in test_server_root_path.yml, which knip can't see; it was falsely flagged as an unused file - Treat src/components/ui/** as entry points. These are shadcn design-system primitives, intentionally part of the palette before every one is consumed; knip was flagging not-yet-used ones (e.g. select.tsx) as dead files and their sub-exports as unused. Marking the directory as the design-system surface is the correct fix, not deleting components someone is about to use - Declare @ant-design/icons as a direct dependency. It was imported in ~198 files but only resolved via antd hoisting, so every one showed up as an "unlisted dependency" - Add an explicit vitest plugin block so test-file classification no longer rides on auto-detection - Stage severities via rules: gate the now-clean categories (files, dependencies, unlisted, unresolved) as errors and keep exports/types/ duplicates as warnings, so CI enforces what's at zero today while the remaining findings ratchet down in follow-ups - Run npm run knip in the frontend-lint CI job, which installs with npm ci so it never sees a partial tree knip now exits 0 with the gated categories clean
a581eac to
012afc0
Compare
|
@greptileai re review |
…itellm_knip_confidence
e2eee36
into
litellm_internal_staging
Relevant issues
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Screenshots / Proof of Fix
knipwas already in the repo but never run in CI, so it had quietly rotted. Running it exposed two failure modes that made it untrustworthy: it silently degrades on a partial install (a fresh worktree that had not runnpm installflagged all 436 test files as unused), and even on a complete tree its config had blind spots that surfaced as false positives.Before, at base
27cf064556(fullnpm citree, previous config):After, at
012afc0c4d(this branch):Both false-positive files and the 198 phantom "unlisted" entries are gone, and the exit code is 0 because the remaining findings are staged as non-blocking warnings. The CI job installs with
npm ci, so it always runs against a complete tree and can never silently degradeType
🚄 Infrastructure
Changes
The goal is to make a green
kniprun actually mean something, then enforce it, rather than blindly deleting everything it lists (some of which is wrong)Config correctness, so findings are real:
serverRootPath.config.tsandmigration.serverRootPath.config.ts), not just the main one.serverRootPath.config.tsis invoked via--configintest_server_root_path.yml, which knip cannot statically see, so it was wrongly reported as an unused filesrc/components/ui/**as entry points. These are shadcn design-system primitives; some are intentionally added to the palette before every one has a consumer, and each exports its full sub-component family. knip was flagging the not-yet-used ones (e.g.select.tsx) as dead files and their exports as unused. Registering the directory as the design-system surface is the correct fix. The tradeoff is that knip will no longer flag a genuinely-abandonedui/primitive, which is an acceptable call for a vendored component kit@ant-design/iconsas a direct dependency. It is imported in ~198 files but only resolved through antd's hoisting, so each import showed up as an "unlisted dependency". This is a real fragility fix, not just noise suppressionvitestplugin block so test-file classification no longer depends on auto-detection (the exact thing that broke on partial installs)Governance, so it ratchets like the existing lint budgets:
rules: gate the categories that are clean today (files, dependencies, unlisted, unresolved) as errors, and keep exports/types/duplicates as warnings so they are visible without blocking. Follow-ups can flip each category to error as it is driven to zeronpm run knipin thefrontend-lintCI jobfrontend-lint(prettier + eslint + budgets + knip) out oftest-litellm-ui-build.ymland into its owntest-litellm-ui-lint.ymlnamed "UI Lint". It was sharing the build workflow's file, so its check surfaced as the misleading "UI Build Check / frontend-lint" despite doing no building; it now reads "UI Lint / frontend-lint". Whoever manages branch protection needs to update the required-check name from the old context to the new one so PRs don't strandNo code is deleted. Every file knip flagged turned out to be a false positive traceable to a config blind spot, which is the whole point: fix the tool so its output is trustworthy, rather than delete real code to satisfy a mis-tuned linter
The larger
Unused exports (100)/Unused exported types (158)lists are left for follow-up PRs; they need per-item verification (knip's static analysis has the same blind spots that produced theserverRootPathfalse positive here), so blind-deleting them is exactly what this PR is trying to avoid