Skip to content

chore(ci): make knip a blocking dead-code gate + burn down 587 -> 5 baselined issues - #2135

Merged
2witstudios merged 17 commits into
masterfrom
pu/knip-ci
Jul 19, 2026
Merged

2witstudios merged 17 commits into
masterfrom
pu/knip-ci

Conversation

@2witstudios

@2witstudios 2witstudios commented Jul 19, 2026 •

Copy link
Copy Markdown
Owner

Summary

From the 2026-07-17 solo-tells audit (cheap-fix #10: "Turn knip on in CI and burn down the 100-file dead list"). knip was installed and configured but never enforced — dead code just accumulated (100 unused files, 164 unused exports, 55 unused deps per the audit's raw count).

This PR:

  1. Wires knip into the lint CI job as a blocking gate with a monotonic baseline/ratchet (scripts/knip-ratchet.mjs, knip-baseline.json) — bun run knip:check fails only on issues not already in the baseline; bun run knip:ratchet regenerates it after cleanup and refuses to let it grow.
  2. Fixes real knip.json config drift found while generating the baseline (stale entry globs pointing at long-deleted barrel files, missing Capacitor/eslint-stack ignores, a missing packages/cli bin entry, a missing src/components/ui/** vendored-kit ignore for apps/admin) — this alone dropped the raw baseline from 587 to 411 before any actual code was deleted.
  3. Burns the resulting baseline down from 411 to 5 across 9 follow-up commits/PRs, each independently verified (repo-wide grep for dynamic require()/import() before any deletion, full uncached typecheck+lint after).

What's deleted

~19,000 lines of dead code: a 26-file unused "AI Elements" UI kit (zero imports since 2025-12-15), an orphaned version-history UI + its backing /versions/compare API route, a dead ToolBuilder/JsonSchemaBuilder/OpenAPIImportDialog cluster, 45 unused marketing shadcn components + 22 unused deps, abandoned AI SDK 7 migration deps, ~150 unused exports/types, and assorted smaller dead files.

Near-misses caught (things that looked dead but weren't)

  • apps/web/src/lib/auth/platform-storage/{desktop,ios,web}-storage.ts — reached only via runtime require() inside platform-detection branches; knip's static analysis can't trace that. Reclassified as a knip ignore, not deleted — deleting would have broken desktop/iOS auth storage.
  • packages/cli/src/{bin.ts,bin-pagespace-mcp.ts} — the CLI's actual binaries (package.json bin field), invisible to knip's default entry detection. Added an explicit workspace entry instead of letting a sweep delete them.
  • Capacitor plugins in apps/android/apps/ios package.json — auto-linked natively, never imported in TS. ignoreDependencies, not removal.
  • apps/web/src/lib/repositories/global-machine-config-repository.ts etc. "using" PageAgentConfig — turned out to be JSDoc prose references, not real imports; the type genuinely was unused, but its docstring flagged it as forward-looking design work for in-flight Terminal epics, so it's baselined rather than deleted.
  • packages/cli's tokensList/tokensListHandler (and the revoke/device-token equivalents) — look like accidental duplicate exports, are actually an intentional two-tier naming convention (bare name = published library API, Handler suffix = what the CLI router imports). Baselined rather than "fixed."
  • Merging master's drift (9 commits, including a newly-merged broadcast admin UI feature) exposed that an earlier commit in this series had removed post/AudienceDefinitionInput/BroadcastActionInput because they were genuinely unused in this branch — the broadcast admin UI didn't exist yet when that commit ran. Restored exactly what's needed, left everything else that's still actually dead removed.

Final state (5 deliberately-baselined issues, not oversights)

  • capacitor-bridge.ts: none remaining (isAndroid/getInjectedPlatform/callNative were genuinely dead — test-only usage — and removed)
  • 4 "duplicate exports" that are the intentional CLI naming convention described above
  • 1 "unused type" (PageAgentConfig) that's documented in-repo as forward-looking contract work for active Terminal epics

Test plan

  • bun run knip:check passes (5 issues, all within baseline)
  • Full-repo, uncached bunx turbo run typecheck --force — 16/16 clean
  • Full-repo, uncached bunx turbo run lint --force — 14/14 clean
  • Targeted test suites for every file this PR series touched directly (capacitor-bridge: 23/23, admin broadcasts: 28/28) pass
  • CI Security Test Suite, CodeQL, Static Security Analysis, Secret Scanning, Dependency Audit — green
  • CI ci / Unit Tests (DB-backed) — running
  • CI ci / Lint & TypeScript Check (includes knip:check) — running

Post-open updates

master is a fast-moving target (this repo merges continuously) — reconciled two waves of drift after opening this PR, each with real, non-mechanical conflicts:

  • Wave 1 (9 commits): apps/web/src/components/version-history/{VersionHistoryItem,VersionHistoryPanel}.tsx conflicted modify/delete — a concurrent, unrelated toast-migration commit touched them right before this PR's deletion landed. Confirmed via git log/grep it was a mechanical bulk edit, not a revival; kept the deletion. Also restored 3 admin exports (post/AudienceDefinitionInput/BroadcastActionInput) that an earlier commit in this series had removed as unused — correct at the time, but master's newly-merged broadcast admin UI (which didn't exist yet in that commit's branch) needs them. Two PRs in flight, neither could see the other's need.
  • Wave 2 (13 commits): apps/control-plane/package.json + apps/realtime/package.json conflicted — master's Sentry crash-reporting commit re-added dotenv/cookie next to its new @sentry/node dep in both files (same class of parallel-PR collision). Verified both are still genuinely unused post-merge; kept @sentry/node, dropped both. Also added a knip ignore for apps/web/src/__fixtures__/eslint-unbounded-findmany/** — intentional TDD fixtures for a new lint rule, meant to be linted not imported.

Automated review (2 threads, both addressed): a Codex-based reviewer caught two real bugs in scripts/knip-ratchet.mjs — (1) duplicates entries are nested arrays of group members, not flat {name} objects, so the fingerprint logic collapsed every duplicate-export group in a file onto the same identical fingerprint (fixed: fingerprint the whole group by its sorted member names); (2) check mode only suggested running knip:ratchet when the baseline could shrink but still exited 0, so a stale fingerprint for now-fixed dead code stayed permitted indefinitely (fixed: check mode now fails when the baseline can shrink, verified with a scenario test). Both replied to with the exact fix commit; left unresolved for the bot to re-verify against the new commits rather than self-resolving.

Baseline unaffected (still 5, same deliberately-kept issues) — all reconciliation was fingerprint-format/drift bookkeeping, not new dead code.

https://claude.ai/code/session_019fX3BVrtbTHdcjHT8Cevxi

2witstudios and others added 14 commits July 18, 2026 12:11
Wires knip into the lint job as a blocking check via a baseline/ratchet
script (scripts/knip-ratchet.mjs), modeled on scripts/coverage-ratchet.mjs.
knip:check fails only on issues not already in knip-baseline.json;
knip:ratchet regenerates the baseline after cleanup, refusing to let it grow.

Also fixes real knip.json config drift found while generating the baseline:
- packages/lib and packages/db entry globs pointed at deleted barrel files
  (src/index.ts, src/server.ts, src/client.ts) instead of the packages'
  actual ~320/70 subpath exports, badly inflating unused-exports/types counts
- apps/android and apps/ios Capacitor plugins were false-positive "unused
  deps" (auto-linked natively, never imported in TS)
- packages/cli's bin.ts/bin-pagespace-mcp.ts (package.json "bin" field)
  had no matching knip entry, so they showed as unused files
- 14 stale ignoreDependencies entries and 4 redundant entry patterns
  already covered by knip's built-in plugins

Baseline lands at 408 real issues (down from a raw 587 before the config
fixes). Follow-up PRs against this branch burn that down to zero.
…are route (#2116)

The VersionHistoryPanel/VersionHistoryItem components and their barrel were
knip-baselined as unused; the /api/pages/[pageId]/versions/compare route's
only caller was that UI (knip can't flag route.ts files — manual audit
finding). RollbackConfirmDialog.tsx stays: it's live via ActivityItem and
SidebarActivityTab. Removes the route's now-stale AUDIT_EXEMPT_ROUTES entry
and ratchets the knip baseline down by the 3 UI files.


Claude-Session: https://claude.ai/code/session_01ABo3G5XFj1jDWgx4jEhF8D

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Removes ToolBuilder.tsx, JsonSchemaBuilder.tsx, and OpenAPIImportDialog.tsx —
an unreferenced closed cluster (they import only each other and shared UI
primitives) — and drops their three entries from the knip baseline.


Claude-Session: https://claude.ai/code/session_01X9MVgoceVrAtKxpzM6BdBc

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The vendored "AI Elements" kit under apps/web/src/components/ai/ui/ was
mostly dead: 26 of its 30 components had zero imports anywhere in the
repo (verified by knip and a full-repo grep including dynamic imports).
The four live files — code-block.tsx, conversation.tsx, tool.tsx,
web-preview.tsx — are kept, along with their test.

Baseline shrinks by 26 entries via knip:ratchet.


Claude-Session: https://claude.ai/code/session_01XdBnRUGsKhJnkq7DjheNmg

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…marketing) (#2119)

Removes 15 unused dependencies, adds 4 missing (unlisted) ones, removes
3 orphaned package.json exports subpaths, and encodes 7 knip false
positives as ignoreDependencies. Baseline shrinks 405 -> 361.

Removed deps:
- apps/web: @ai-sdk/anthropic, @ai-sdk/google, @ai-sdk/openai,
  @ai-sdk/xai (abandoned AI SDK 7 migration remnants), pg, recharts,
  @xyflow/react, @radix-ui/react-accordion, embla-carousel-react
- apps/control-plane: dotenv
- apps/processor: @aws-sdk/s3-request-presigner, ts-node
- apps/realtime: cookie
- packages/lib: mammoth, pdf-parse-debugging-disabled

Added (were unlisted):
- root: drizzle-orm, pg (scripts/ imports)
- apps/web: server-only
- apps/admin: postcss

Orphaned exports removed (source deleted in earlier refactors):
- packages/lib ./services/sandbox/lifecycle (14f50df)
- packages/lib ./services/rate-limit-cache (e5659ae)
- packages/db ./schema/sandbox-sessions (88b10b4)
plus lib's matching dangling typesVersions entries.

knip.json ignoreDependencies (false positives, mirroring apps/web's
existing pattern):
- apps/admin eslint stack (used by `next lint` + eslint.config.mjs)
- apps/android + apps/ios `web` (turbo build-order dep for cap sync)
- packages/lib react-dom (peer-dep host for @react-email/render)

Left alone: apps/web tokenlens + @radix-ui/react-hover-card — their
only importers are knip-dead but still-typechecked files, and nothing
else declares them, so removal breaks typecheck until a dead-file
deletion PR lands.


Claude-Session: https://claude.ai/code/session_014q2Rfkf5PFkjiacLKLGXoD

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…eps (#2118)

Pure deletion PR in the knip-baseline burn-down series. Every removed file
was flagged unused by knip and verified to have no references anywhere in
apps/marketing (including dynamic imports and cross-imports — the only
importers of these files were other files in the same deletion set). Each
removed dependency was imported only by the deleted files. Marketing build
passes; knip baseline shrinks 405 → 338.


Claude-Session: https://claude.ai/code/session_011RdhxswpnTxfygoeSm46gz

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
apps/web/src/components/ui/{accordion,carousel}.tsx had zero real
consumers (carousel.tsx's only consumer, ai/ui/inline-citation.tsx, was
deleted in the AI Elements cleanup). They were invisible to knip
(src/components/ui/** is knip-ignored) and only kept typechecking because
apps/marketing still declared @radix-ui/react-accordion/embla-carousel-react
and bun's hoisting gave web a free resolution path — a path removed by the
marketing + deps-sweep cleanup PRs. Deleting them removes the fragile
cross-workspace hoisting dependency entirely.
- apps/marketing: add ignoreDependencies for its eslint stack (same
  FlatCompat-resolved-but-not-imported pattern already ignored for
  apps/web/apps/admin); add postcss/postcss-load-config as explicit
  devDeps instead of relying on hoisting from another workspace
- apps/admin: add src/components/ui/** to knip ignore, matching
  apps/web/apps/marketing convention for vendored shadcn kits — was
  producing 13 false-positive "unused export" entries
- apps/web: remove tokenlens + @radix-ui/react-hover-card (only
  consumers were the already-deleted ai/ui/* files); delete
  components/ui/hover-card.tsx (zero real consumers, same
  knip-ignored-but-dead pattern as the accordion/carousel cleanup)

Baseline: 262 -> 241.
- vitest.workspace.ts: 'setupFiles: ./src/test/setup.ts' resolves fine
  at runtime (vitest remaps it relative to the web project's
  root: './apps/web'), but knip resolves it relative to
  vitest.workspace.ts's own location instead — false positive, added
  ignoreUnresolved.
- scripts/__tests__/changelog-shell-safety.test.ts: tested a module tree
  (scripts/changelog/*) deleted wholesale in 5c47614 ("remove stale
  docs/, prune cross-references") — the test was never cleaned up
  alongside it. Deleted. Note: root package.json's "changelog:generate"
  script still points at the deleted scripts/changelog/index.ts and is
  therefore broken — left as-is, this is a pre-existing, already-known
  issue (not a dead-code/knip finding) and out of scope here.

Baseline: 241 -> 237.
…lags (#2122)

Deleted 13 genuinely dead files (zero references anywhere in the repo,
confirmed via repo-wide grep for imports, dynamic require()/import(),
and string-keyed lookups):

- apps/control-plane/src/repositories/index.ts (dead barrel; createTenantRepository
  is imported directly from ./tenant-repository everywhere)
- apps/web/src/components/layout/left-sidebar/DriveList.tsx
- apps/web/src/components/layout/left-sidebar/workspace-selector.tsx
- apps/web/src/components/layout/right-sidebar/ai-assistant/SidebarSettingsTab.tsx
- apps/web/src/components/shared/AuthButtons.tsx (superseded by OAuthButtons)
- apps/web/src/components/shared/ContactForm.tsx (superseded by marketing's own ContactForm)
- apps/web/src/components/tasks/TaskMobileCard.tsx
- apps/web/src/components/tasks/task-hooks.ts
- apps/web/src/hooks/useDirectUpload.ts (superseded by useAttachmentUpload + lib/upload/*)
- apps/web/src/lib/ai/types/global-prompt.ts (superseded by admin's local copy of the type)
- apps/web/src/lib/repositories/index.ts (dead barrel; individual repository files are
  imported directly everywhere)
- apps/web/src/lib/tabs/index.ts (dead barrel; individual tab modules are imported directly)
- packages/lib/src/email-templates/TenantProvisioningCompleteEmail.tsx

Kept 3 files that are genuinely reachable only through mechanisms knip's static
analysis can't trace, and reclassified them in knip.json instead of deleting:

- apps/web/src/test/next-server-stub.ts — resolved via vitest.config.ts's
  resolve.alias substitute for 'next/server'; added to apps/web's ignore list.
- apps/e2e/support/mock-server-main.ts — invoked as a shell command
  (`bun run support/mock-server-main.ts`) by Playwright's webServer config;
  added a new apps/e2e workspace block with it in ignore.
- packages/db/src/migrate-pending-invites.ts — standalone CLI script invoked via
  the package.json `migrate-pending-invites` script; added to packages/db's entry
  list alongside its sibling scripts (migrate.ts, migrate-admin.ts, provision-admin-users.ts).

Ran `bun run knip:ratchet` to lock in the shrink (237 -> 221 baseline issues).
Verified with a full `bunx turbo run typecheck --force` and `bunx turbo run lint --force`
across the whole repo (not just affected workspaces).


Claude-Session: https://claude.ai/code/session_01HX9rxrXVhWCJVdU3haUciU

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…exports (#2132)

* chore(knip): PR8b — resolve remaining unused exports/types/duplicate-exports

Removed unused export keywords, dead symbols, and duplicate export forms
(named + default) flagged by knip across web, admin, marketing, desktop,
control-plane, realtime, e2e, and the lib/sdk packages. Deleted six fully
dead component files and VoiceModeOverlay.tsx (zero importers repo-wide;
prior pass had stripped its exports but left the file in place).

Every removed symbol was cross-checked with a repo-wide ripgrep sweep for
remaining consumers before deletion.

* chore(knip): fix cascade breakage from PR8b + ratchet baseline

Merging pu/knip-ci's tip exposed 4 new knip flags plus a handful of
typecheck/lint errors caused by symbols becoming dead only after PR8b's
exports were stripped (a removed component/type left its sibling
constant, prop type, or union member with zero remaining consumers).

- apps/desktop/fetch-proxy-types.ts: FetchProxyResponse union was itself
  dead (verified: no repo-wide consumer), which cascaded to its four
  member interfaces once removed — deleted all five.
- apps/web/lib/mentions/mentionConfig.ts: MentionConfigManager's removal
  in PR8b left `globalConfig`/DEFAULT_GLOBAL_CONFIG/GlobalMentionConfig
  with no reader — deleted.
- apps/web/lib/utils/formatters.ts: LANGUAGE_EXTENSION_MAP was only used
  by a function already removed in PR8b — deleted.
- apps/web/lib/monitoring/monitoring-types.ts: last remaining interface
  (MonitoringWidgetProps) had zero consumers after DetailedWidgetProps
  was removed; the admin app has its own separate copy that's very much
  alive, this web-only copy was dead — deleted the whole file.
- apps/web/components/ai/ui/tool.tsx: ToolInputProps/ToolOutputProps
  types were only used by the ToolInput/ToolOutput components PR8b
  removed — deleted.
- apps/web/lib/editor/pagination: getPageSize had zero importers outside
  its own dead barrel re-export — deleted.
- apps/admin/lib/auth/auth-fetch.ts: fetchJSON had zero callers anywhere
  in the admin app — deleted (unrelated to the merge, pre-existing).

Ratcheted knip-baseline.json: 221 -> 8 issues. The remaining 8 are
deliberately left alone (not oversights):
- capacitor-bridge.ts (isAndroid, getInjectedPlatform, callNative):
  exercised by a dedicated test suite via dynamic import; removing
  would break the tests, and this reads as a stable platform-detection
  surface not yet called from every code path.
- page-agent-repository.ts PageAgentConfig: explicitly documented in
  its own comment as a forward-looking contract for sibling Terminal
  PRs to build against.
- replay-dedupe.ts MAX_ANCHOR_BYTES/MAX_DISCARDABLE_GIVEUP_BYTES:
  semantically distinct constants that are intentionally equal by
  design (documented in a comment), not an accidental alias.
- cli keys/list.ts and keys/revoke.ts handler/Handler pairs: explicitly
  documented as split so tests can call the plain function without
  going through the router.
- device-auth-helpers.ts createDeviceToken/createWebDeviceToken:
  @deprecated alias with an active migration still in progress across
  real call sites (device/register, google/callback, apple/callback) —
  a behavior migration, not an export-hygiene fix.

Verified with `rm -rf apps/*/.next && bunx turbo run typecheck --force`
and `bunx turbo run lint --force` across the whole repo (both clean),
plus the affected unit test suites.
apps/web/src/lib/capacitor-bridge.ts: isAndroid, getInjectedPlatform,
callNative had zero real callers in application code — only exercised
by their own dedicated unit tests (test-only usage doesn't count per
this repo's knip config). Removed the functions and their test blocks;
23/23 tests in capacitor-bridge.test.ts still pass.

Baseline: 8 -> 5. The remaining 5 are deliberately kept, not oversights:

- 4 "duplicate exports" (tokensList/tokensListHandler,
  tokensRevoke/tokensRevokeHandler in packages/cli, and
  createDeviceToken/createWebDeviceToken in apps/web) follow an
  intentional two-tier naming convention — bare name is the reusable
  business-logic function (part of @pagespace/cli's published library
  API), Handler-suffixed alias is what the CLI router imports. A
  generic duplicate-export detector can't distinguish that from an
  accidental leftover alias; consolidating risks breaking external
  consumers of a published package.
- 1 "unused type" (PageAgentConfig in page-agent-repository.ts) is
  explicitly documented as "the contract sibling Terminal PRs
  (tool-group, settings UI, session routing) build against" — active
  in-flight design work, not dead code.

knip:check / typecheck / lint all clean, full repo, uncached.
# Conflicts:
#	apps/web/src/components/version-history/VersionHistoryItem.tsx
#	apps/web/src/components/version-history/VersionHistoryPanel.tsx
Merging master's broadcast admin UI feature (#2107) into pu/knip-ci
surfaced real breakage: PR8b had removed post/fetchJSON from
auth-fetch.ts and AudienceDefinitionInput/BroadcastActionInput from
broadcasts/schema.ts because they had zero consumers *in PR8b's
branch* — the broadcast admin UI didn't exist there yet. Two PRs
landing in parallel, neither could see the other's need for these.

Restored exactly what master's broadcast-composer.tsx/composer-form.ts
actually import; left `del` and `TemplateCreateInput` removed since
nothing currently uses either (verified via repo-wide grep — the one
`del(` hit was `stripe.customers.del`, unrelated).

Full repo typecheck (16/16) + lint (14/14) clean; 28/28 broadcast
component tests pass.
@coderabbitai

coderabbitai Bot commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 134 files, which is 34 over the limit of 100.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 20243552-21c0-4037-8b60-2356b8888e43

📥 Commits

Reviewing files that changed from the base of the PR and between 11f1fc2 and dfb84db.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (238)
  • .github/workflows/ci.yml
  • apps/admin/package.json
  • apps/admin/src/components/admin/broadcasts/composer-form.ts
  • apps/admin/src/components/admin/broadcasts/types.ts
  • apps/admin/src/lib/auth/auth-fetch.ts
  • apps/admin/src/lib/auth/cookie-config.ts
  • apps/admin/src/lib/auth/csrf-validation.ts
  • apps/admin/src/lib/broadcasts/schema.ts
  • apps/control-plane/package.json
  • apps/control-plane/src/repositories/index.ts
  • apps/control-plane/src/validation/tenant-validation.ts
  • apps/desktop/src/main/auth-session.ts
  • apps/desktop/src/main/command-resolver.ts
  • apps/desktop/src/shared/fetch-proxy-types.ts
  • apps/e2e/support/db.ts
  • apps/marketing/package.json
  • apps/marketing/src/components/DeviceFrame.tsx
  • apps/marketing/src/components/ui/accordion.tsx
  • apps/marketing/src/components/ui/alert-dialog.tsx
  • apps/marketing/src/components/ui/alert.tsx
  • apps/marketing/src/components/ui/aspect-ratio.tsx
  • apps/marketing/src/components/ui/avatar.tsx
  • apps/marketing/src/components/ui/badge.tsx
  • apps/marketing/src/components/ui/breadcrumb.tsx
  • apps/marketing/src/components/ui/button-group.tsx
  • apps/marketing/src/components/ui/calendar.tsx
  • apps/marketing/src/components/ui/carousel.tsx
  • apps/marketing/src/components/ui/chart.tsx
  • apps/marketing/src/components/ui/collapsible.tsx
  • apps/marketing/src/components/ui/combobox.tsx
  • apps/marketing/src/components/ui/context-menu.tsx
  • apps/marketing/src/components/ui/direction.tsx
  • apps/marketing/src/components/ui/drawer.tsx
  • apps/marketing/src/components/ui/dropdown-menu.tsx
  • apps/marketing/src/components/ui/empty.tsx
  • apps/marketing/src/components/ui/field.tsx
  • apps/marketing/src/components/ui/form.tsx
  • apps/marketing/src/components/ui/hover-card.tsx
  • apps/marketing/src/components/ui/input-group.tsx
  • apps/marketing/src/components/ui/input-otp.tsx
  • apps/marketing/src/components/ui/item.tsx
  • apps/marketing/src/components/ui/kbd.tsx
  • apps/marketing/src/components/ui/menubar.tsx
  • apps/marketing/src/components/ui/native-select.tsx
  • apps/marketing/src/components/ui/navigation-menu.tsx
  • apps/marketing/src/components/ui/pagination.tsx
  • apps/marketing/src/components/ui/popover.tsx
  • apps/marketing/src/components/ui/progress.tsx
  • apps/marketing/src/components/ui/radio-group.tsx
  • apps/marketing/src/components/ui/resizable.tsx
  • apps/marketing/src/components/ui/select.tsx
  • apps/marketing/src/components/ui/separator.tsx
  • apps/marketing/src/components/ui/sidebar.tsx
  • apps/marketing/src/components/ui/skeleton.tsx
  • apps/marketing/src/components/ui/slider.tsx
  • apps/marketing/src/components/ui/sonner.tsx
  • apps/marketing/src/components/ui/spinner.tsx
  • apps/marketing/src/components/ui/switch.tsx
  • apps/marketing/src/components/ui/tabs.tsx
  • apps/marketing/src/components/ui/toggle-group.tsx
  • apps/marketing/src/components/ui/toggle.tsx
  • apps/marketing/src/components/ui/tooltip.tsx
  • apps/marketing/src/lib/credits.ts
  • apps/marketing/src/lib/schema.tsx
  • apps/processor/package.json
  • apps/realtime/package.json
  • apps/realtime/src/per-event-auth.ts
  • apps/web/package.json
  • apps/web/src/app/api/__tests__/security-audit-coverage.test.ts
  • apps/web/src/app/api/commands/command-route-helpers.ts
  • apps/web/src/app/api/pages/[pageId]/versions/compare/__tests__/route.test.ts
  • apps/web/src/app/api/pages/[pageId]/versions/compare/route.ts
  • apps/web/src/components/activity/utils.ts
  • apps/web/src/components/ai/chat/input/ChatInput.tsx
  • apps/web/src/components/ai/chat/input/ChatTextarea.tsx
  • apps/web/src/components/ai/chat/input/InputActions.tsx
  • apps/web/src/components/ai/chat/input/ProviderModelSelector.tsx
  • apps/web/src/components/ai/chat/layouts/ChatLayout.tsx
  • apps/web/src/components/ai/shared/ReadOnlyToggle.tsx
  • apps/web/src/components/ai/shared/chat/ChatErrorBanner.tsx
  • apps/web/src/components/ai/shared/chat/tool-calls/CompactTaskManagementRenderer.tsx
  • apps/web/src/components/ai/shared/chat/tool-calls/DocumentRenderer.tsx
  • apps/web/src/components/ai/shared/chat/tool-calls/FileTreeRenderer.tsx
  • apps/web/src/components/ai/shared/chat/tool-calls/TaskManagementRenderer.tsx
  • apps/web/src/components/ai/shared/chat/tool-calls/content-utils.ts
  • apps/web/src/components/ai/shared/chat/tool-calls/index.ts
  • apps/web/src/components/ai/shared/index.ts
  • apps/web/src/components/ai/ui/Image.tsx
  • apps/web/src/components/ai/ui/artifact.tsx
  • apps/web/src/components/ai/ui/canvas.tsx
  • apps/web/src/components/ai/ui/chain-of-thought.tsx
  • apps/web/src/components/ai/ui/checkpoint.tsx
  • apps/web/src/components/ai/ui/code-block.tsx
  • apps/web/src/components/ai/ui/confirmation.tsx
  • apps/web/src/components/ai/ui/connection.tsx
  • apps/web/src/components/ai/ui/context.tsx
  • apps/web/src/components/ai/ui/controls.tsx
  • apps/web/src/components/ai/ui/conversation.tsx
  • apps/web/src/components/ai/ui/edge.tsx
  • apps/web/src/components/ai/ui/inline-citation.tsx
  • apps/web/src/components/ai/ui/loader.tsx
  • apps/web/src/components/ai/ui/message.tsx
  • apps/web/src/components/ai/ui/model-selector.tsx
  • apps/web/src/components/ai/ui/node.tsx
  • apps/web/src/components/ai/ui/open-in-chat.tsx
  • apps/web/src/components/ai/ui/panel.tsx
  • apps/web/src/components/ai/ui/plan.tsx
  • apps/web/src/components/ai/ui/prompt-input.tsx
  • apps/web/src/components/ai/ui/queue.tsx
  • apps/web/src/components/ai/ui/reasoning.tsx
  • apps/web/src/components/ai/ui/shimmer.tsx
  • apps/web/src/components/ai/ui/sources.tsx
  • apps/web/src/components/ai/ui/suggestion.tsx
  • apps/web/src/components/ai/ui/task.tsx
  • apps/web/src/components/ai/ui/tool.tsx
  • apps/web/src/components/ai/ui/toolbar.tsx
  • apps/web/src/components/ai/ui/web-preview.tsx
  • apps/web/src/components/ai/voice/VoiceCallPanel.tsx
  • apps/web/src/components/ai/voice/VoiceModeBorder.tsx
  • apps/web/src/components/ai/voice/VoiceModeOverlay.tsx
  • apps/web/src/components/ai/voice/VoiceModeSettings.tsx
  • apps/web/src/components/ai/voice/index.ts
  • apps/web/src/components/auth/GoogleOneTap.tsx
  • apps/web/src/components/billing/StripeProvider.tsx
  • apps/web/src/components/calendar/calendar-types.ts
  • apps/web/src/components/commands/CommandPicker.tsx
  • apps/web/src/components/commands/CommandPickerPortal.tsx
  • apps/web/src/components/consent/CookieBanner.tsx
  • apps/web/src/components/integrations/JsonSchemaBuilder.tsx
  • apps/web/src/components/integrations/OpenAPIImportDialog.tsx
  • apps/web/src/components/integrations/ToolBuilder.tsx
  • apps/web/src/components/layout/LayoutErrorBoundary.tsx
  • apps/web/src/components/layout/NavigationProvider.tsx
  • apps/web/src/components/layout/left-sidebar/DriveList.tsx
  • apps/web/src/components/layout/left-sidebar/workspace-selector.tsx
  • apps/web/src/components/layout/middle-content/page-views/channel/ChannelInput.tsx
  • apps/web/src/components/layout/middle-content/page-views/channel/ChannelInputFooter.tsx
  • apps/web/src/components/layout/middle-content/page-views/channel/MessageDropZone.tsx
  • apps/web/src/components/layout/middle-content/page-views/task-list/task-list-types.ts
  • apps/web/src/components/layout/middle-content/page-views/thread/ThreadPanel.tsx
  • apps/web/src/components/layout/right-sidebar/ai-assistant/SidebarSettingsTab.tsx
  • apps/web/src/components/layout/tabs/TabBar.tsx
  • apps/web/src/components/mentions/MentionPicker.tsx
  • apps/web/src/components/mentions/MentionPickerPortal.tsx
  • apps/web/src/components/providers/ConsentProvider.tsx
  • apps/web/src/components/shared/AuthButtons.tsx
  • apps/web/src/components/shared/ContactForm.tsx
  • apps/web/src/components/shared/MessageHoverToolbar.tsx
  • apps/web/src/components/shared/MessageInput.tsx
  • apps/web/src/components/shared/MessageReactions.tsx
  • apps/web/src/components/tasks/FilterComponents.tsx
  • apps/web/src/components/tasks/TaskMobileCard.tsx
  • apps/web/src/components/tasks/task-hooks.ts
  • apps/web/src/components/ui/accordion.tsx
  • apps/web/src/components/ui/carousel.tsx
  • apps/web/src/components/ui/hover-card.tsx
  • apps/web/src/components/version-history/VersionHistoryItem.tsx
  • apps/web/src/components/version-history/VersionHistoryPanel.tsx
  • apps/web/src/components/version-history/index.ts
  • apps/web/src/hooks/useDirectUpload.ts
  • apps/web/src/hooks/usePerformanceMonitor.ts
  • apps/web/src/hooks/usePermissions.ts
  • apps/web/src/hooks/useSpeechRecognition.ts
  • apps/web/src/hooks/useVoiceMode.ts
  • apps/web/src/lib/__tests__/capacitor-bridge.test.ts
  • apps/web/src/lib/ai/core/ai-providers-config.ts
  • apps/web/src/lib/ai/core/ai-tools.ts
  • apps/web/src/lib/ai/core/complete-request-builder.ts
  • apps/web/src/lib/ai/core/mcp-tool-converter.ts
  • apps/web/src/lib/ai/core/mention-processor.ts
  • apps/web/src/lib/ai/core/message-utils.ts
  • apps/web/src/lib/ai/core/model-capabilities.ts
  • apps/web/src/lib/ai/core/schema-introspection.ts
  • apps/web/src/lib/ai/core/stream-abort-registry.ts
  • apps/web/src/lib/ai/core/tool-filtering.ts
  • apps/web/src/lib/ai/shared/agent-conversations.ts
  • apps/web/src/lib/ai/types/global-prompt.ts
  • apps/web/src/lib/analytics/client-tracker.ts
  • apps/web/src/lib/auth/auth-fetch.ts
  • apps/web/src/lib/auth/auth-helpers.ts
  • apps/web/src/lib/auth/oauth-state.ts
  • apps/web/src/lib/auth/platform-storage/index.ts
  • apps/web/src/lib/billing/billing-visibility.ts
  • apps/web/src/lib/billing/index.ts
  • apps/web/src/lib/capacitor-bridge.ts
  • apps/web/src/lib/editor/pagination/constants.ts
  • apps/web/src/lib/editor/pagination/index.ts
  • apps/web/src/lib/editor/pagination/utils.ts
  • apps/web/src/lib/haptics.ts
  • apps/web/src/lib/integrations/google-calendar/sync-service.ts
  • apps/web/src/lib/integrations/google-calendar/token-refresh.ts
  • apps/web/src/lib/integrations/zoom/webhook-event-types.ts
  • apps/web/src/lib/machines/agent-terminals-runtime.ts
  • apps/web/src/lib/mentions/mentionConfig.ts
  • apps/web/src/lib/monitoring/index.ts
  • apps/web/src/lib/monitoring/monitoring-types.ts
  • apps/web/src/lib/navigation/app-navigation.ts
  • apps/web/src/lib/repositories/auth-repository.ts
  • apps/web/src/lib/repositories/chat-message-repository.ts
  • apps/web/src/lib/repositories/connection-invite-repository.ts
  • apps/web/src/lib/repositories/conversation-repository.ts
  • apps/web/src/lib/repositories/drive-invite-repository.ts
  • apps/web/src/lib/repositories/index.ts
  • apps/web/src/lib/repositories/page-agent-repository.ts
  • apps/web/src/lib/repositories/page-invite-repository.ts
  • apps/web/src/lib/repositories/session-repository.ts
  • apps/web/src/lib/sandbox/sprites-client.ts
  • apps/web/src/lib/security/safe-path.ts
  • apps/web/src/lib/subscription/credits.ts
  • apps/web/src/lib/tabs/index.ts
  • apps/web/src/lib/tree/sortable-tree.ts
  • apps/web/src/lib/url-state.ts
  • apps/web/src/lib/utils/formatters.ts
  • apps/web/src/lib/utils/utils.ts
  • apps/web/src/lib/websocket/calendar-events.ts
  • apps/web/src/lib/websocket/socket-utils.ts
  • apps/web/src/lib/websocket/ws-connections.ts
  • apps/web/src/lib/websocket/ws-message-schemas.ts
  • apps/web/src/lib/websocket/ws-security.ts
  • apps/web/src/services/api/index.ts
  • apps/web/src/services/api/page-reorder-service.ts
  • apps/web/src/services/api/page-service.ts
  • apps/web/src/services/api/permission-management-service.ts
  • apps/web/src/stores/useMultiSelectStore.ts
  • apps/web/src/stores/useTabsStore.ts
  • apps/web/src/stores/useVoiceModeStore.ts
  • apps/web/src/test/socket-mocks.ts
  • apps/web/src/types/mentions.ts
  • knip-baseline.json
  • knip.json
  • package.json
  • packages/db/package.json
  • packages/lib/package.json
  • packages/lib/src/email-templates/TenantProvisioningCompleteEmail.tsx
  • packages/lib/src/logging/logger-types.ts
  • packages/sdk/src/transport/build-request.ts
  • scripts/__tests__/changelog-shell-safety.test.ts
  • scripts/knip-ratchet.mjs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Review on demand using usage pricing
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pu/knip-ci

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b72a3f3e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/knip-ratchet.mjs Outdated
Comment thread scripts/knip-ratchet.mjs Outdated
# Conflicts:
#	apps/control-plane/package.json
#	apps/realtime/package.json
#	bun.lock
Merged 13 more master commits (task-board crash-prevention epic
phases 1-8, Sentry crash reporting, payment receipt emails). Two
real conflicts:

- apps/control-plane/package.json, apps/realtime/package.json: the
  Sentry commit (#2131) re-added dotenv/cookie next to its new
  @sentry/node dependency in both files — same class of parallel-PR
  collision as the earlier admin/broadcast one. Verified via grep:
  still zero real consumers of dotenv (control-plane) or cookie
  (realtime) post-merge. Kept @sentry/node, dropped both.
- knip flagged 2 new "unused files": apps/web/src/__fixtures__/
  eslint-unbounded-findmany/*.ts. These are intentional TDD fixtures
  for a new no-restricted-syntax ESLint rule (#2129, relocated by
  #2136) — files meant to be *linted*, not imported; their pass/fail
  lint state is the test itself. Added a knip.json ignore rather than
  treating them as dead code.

Baseline unchanged at 5. Full uncached typecheck (16/16) + lint
(14/14) clean.
Two real bugs flagged by automated PR review on #2135:

1. knip's `duplicates` entries are arrays of group members (each group
   is 2+ symbols that are the same export under different names), not
   flat {name} objects like every other category. The old code did
   `item?.name` on the group array itself, which is always undefined,
   so every duplicate group in a file collapsed onto the identical
   `duplicates::file::` fingerprint. A file with two distinct duplicate
   groups would only ever register one — the second would silently
   match the already-baselined (empty-name) fingerprint. Fixed by
   fingerprinting the whole group as its sorted, comma-joined member
   names.

2. Check mode printed a "you could shrink the baseline" suggestion but
   still exited 0. A stale fingerprint for now-fixed dead code remains
   permitted indefinitely — reintroducing that exact dead code later
   would silently pass CI. Check mode now fails when the baseline can
   shrink, same severity as finding a new issue; verified with a
   scenario test (injected a stale fingerprint, confirmed check mode
   fails with a clear message, confirmed it passes clean once removed).

Regenerated knip-baseline.json with the corrected duplicate
fingerprints (same 5 issues, now uniquely identified). knip:check /
full typecheck / full lint / scripts lint all clean.
@2witstudios
2witstudios merged commit 3bc461c into master Jul 19, 2026
10 checks passed
@2witstudios
2witstudios deleted the pu/knip-ci branch July 19, 2026 21:42
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.

1 participant