Skip to content

Add code-health PR check (dead-code delta)#2019

Merged
GregorShear merged 2 commits into
mainfrom
claude/code-health-checks
Jul 2, 2026
Merged

Add code-health PR check (dead-code delta)#2019
GregorShear merged 2 commits into
mainfrom
claude/code-health-checks

Conversation

@GregorShear

@GregorShear GregorShear commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Code-health check: dead-code delta on every PR

Adds a GitHub Action that runs Knip on the PR head and its base, then posts a sticky comment with the difference — which unused files / exports / types / dependencies this PR introduces vs. removes.

@GregorShear GregorShear requested a review from a team as a code owner July 1, 2026 15:24
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

⚪ Code Health

No change to the dead-code surface.

60 Unused files

File imported nowhere — delete (or import) it.

     src/pages/NoGrants.tsx
     src/pages/OAuth.tsx
     src/services/encryption.ts
     src/hooks/useDelay.ts
     src/hooks/useDraft.ts
     src/hooks/useExpressWorkflowAuth.ts
     src/types/global.ts
     src/types/vitest.ts
     src/components/graphics/PoweredByEstuaryWatermark.tsx
     src/components/graphs/TaskHoursByMonthGraph.tsx
…and 50 more

157 Unused exports

Exported symbol with no references outside its own file — un-export it, or delete it if unused entirely

     src/context/Theme.tsx : sample_blue
     src/context/Theme.tsx : successDark
     src/context/Theme.tsx : infoMain
     src/context/Theme.tsx : logoColors
     src/context/Theme.tsx : chipDraggableIndex
     src/context/Theme.tsx : headerLinkIndex
     src/context/Theme.tsx : intensifiedOutlineThick
     src/context/Theme.tsx : tableAlternateRowsSx
     src/context/Theme.tsx : draggableChipIconSx
     src/context/Theme.tsx : hiddenButAccessibleInput
…and 147 more

103 Unused exported types

Exported type with no references outside its own file — un-export it, or delete it if unused entirely

     src/utils/dataPlane-utils.ts : ErrorFlags
     src/test/test-utils.tsx : AllTheProvidersProps
     src/stores/Tables/Store.ts : StatsSchema
     src/api/liveSpecsExt.ts : CaptureQueryWithSpec
     src/api/liveSpecsExt.ts : MaterializationQuery
     src/api/liveSpecsExt.ts : MaterializationQueryWithSpec
     src/api/liveSpecsExt.ts : CollectionQuery
     src/api/liveSpecsExt.ts : LiveSpecsExtQuery_DetailsForm
     src/api/liveSpecsExt.ts : LiveSpecsExtQuery_DataPlaneAuthReq
     src/api/liveSpecsExt.ts : LiveSpecsExtQuery_Latest
…and 93 more

14 Unused exported enum members

An enum member referenced nowhere

     src/services/supabase.ts : CONNECTOR_TAGS
     src/services/supabase.ts : DRAFTS_EXT
     src/services/supabase.ts : TASKS_BY_DAY
     src/stores/names.ts : QUEUED_TASKS
     src/stores/Tables/hooks.ts : accessGrants
     src/stores/Tables/hooks.ts : accessLinks
     src/stores/Tables/hooks.ts : billing
     src/stores/Tables/hooks.ts : connectors
     src/stores/Tables/hooks.ts : entitySelector
     src/stores/Tables/hooks.ts : prefixes
…and 4 more

5 Unused dependencies

In package.json but never imported

     package.json : @mui/lab
     package.json : @testing-library/jest-dom
     package.json : @urql/exchange-retry
     package.json : logrocket-react
     package.json : stripe

3 Unused devDependencies

In package.json devDependencies but never used

     package.json : @types/logrocket-react
     package.json : @types/react-inspector
     package.json : sharp

@GregorShear GregorShear force-pushed the claude/code-health-checks branch 6 times, most recently from 4b402dc to f34b363 Compare July 1, 2026 20:37

@jshearer jshearer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude found at least one "structural" problem with the code that it claims will cause false-positive signals.

This (dead code detection) is a genuinely hard problem to get right, and isn't even wholly solvable in a dynamic language like Typescript. I'm not sure that the juice is worth the squeeze here...

Also, what's up with that typing version bump? Maybe a no-op, but seems relevant.

Comment thread package-lock.json Outdated
"version": "20.17.30",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz",
"integrity": "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==",
"version": "26.0.1",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This lockfile silently bumps the hoisted @types/node from 20.17.30 to 26.0.1 — a six-major jump in the typings tsc resolves for src/ — in a PR that only adds knip.

package.json doesn't pin @types/node and tsconfig has no types allowlist, so after merge everyone's next npm ci typechecks against Node 26 typings (e.g. NodeJS.Timeout/global signature changes), potentially breaking npm run typecheck on main for an unrelated-looking PR. Suggest pinning/deduping @types/node back to 20.x in the lockfile before merging

Comment thread .github/scripts/knip-delta.mjs Outdated
Comment thread .github/scripts/knip-delta.mjs Outdated
Comment thread .github/scripts/knip-classify.mjs Outdated
# only changes config (like the one that introduces this check)
# doesn't manufacture a phantom delta. The ruler is constant;
# only source differences register. Falls back to base's config.
git checkout --quiet ${{ github.event.pull_request.head.sha }} -- knip.json 2>/dev/null || true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "constant ruler" pin covers only knip.json, but knip's effective config also includes tsconfig.json and package.json (plugin auto-detection, package.json#knip), which are never pinned — so a PR changing tsconfig paths or dependency lists can still manufacture a phantom delta today. And if config ever moves to knip.ts/package.json#knip, this checkout fails silently via || true and base/head measure with different configs.

Not a today-bug (the check is informational and the fallback is documented), but the failure mode is exactly the one this pin was written to prevent — a red +N on a config-only PR that teaches people to distrust the check. Worth either pinning the wider config surface or at least echoing a warning into the report when the pin path diverges.

@GregorShear GregorShear force-pushed the claude/code-health-checks branch 3 times, most recently from 718324d to a4152a1 Compare July 2, 2026 15:03
@GregorShear

GregorShear commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

I'm feeling pretty tolerant of an imperfect tool here - it's only meant to give visibility on existing unused code, and will help us identify code orphaned by future changes.

false negatives (orphaned code missed by the check) will just leave dead code in the project, and false positives can be ignored - if we get so many false positives that the check is useless, we can just turn it off.

@GregorShear GregorShear force-pushed the claude/code-health-checks branch from a4152a1 to 604416d Compare July 2, 2026 20:20
@GregorShear

Copy link
Copy Markdown
Contributor Author

Discussed this on a call w/ Joseph - we agreed that presenting the bare Knip output is a stronger first pass, and we can refine/reclassify the categories later, if needed

@GregorShear GregorShear requested a review from jshearer July 2, 2026 21:16
@GregorShear GregorShear merged commit 4db2dbe into main Jul 2, 2026
8 checks passed
@GregorShear GregorShear deleted the claude/code-health-checks branch July 2, 2026 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants