Skip to content

fix: hoist shared devDeps, remove unused deps, add knip config - #3

Merged
beeeku merged 3 commits into
masterfrom
fix/hoist-devdeps-cleanup
Mar 20, 2026
Merged

beeeku merged 3 commits into
masterfrom
fix/hoist-devdeps-cleanup

Conversation

@beeeku

@beeeku beeeku commented Mar 20, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Remove expect-type from 18 workspace packages (never imported in any test file)
  • Hoist typescript, vitest, @cloudflare/workers-types, and bunup to root package.json only — bun workspaces makes root devDeps available to all packages, eliminating duplication across 21 packages
  • Remove export keyword from red, green, yellow, blue in packages/cli/src/utils.ts — these are only used internally by success(), warn(), error(), info() functions
  • Add knip.json at project root for ongoing dead code detection
  • Include e2e/dependency-audit.test.ts for structural validation of dependency declarations

Test plan

  • bun install — lockfile regenerated successfully
  • bun run typecheck — 25/25 tasks pass
  • bun run build — 21/21 tasks pass
  • bun run test — 21/21 tasks pass
  • bunx knip — runs with new config, fewer false positives

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor

    • All packages now publish as ES modules only; CommonJS exports and top-level mains removed
    • Simplified package entrypoints
    • Internal CLI color helpers no longer exported (reduces public surface)
  • New Features

    • Added an end-to-end dependency audit test
    • Added knip workspace configuration to analyze package entry points
  • Chores

    • Added dependency validation infrastructure
    • Task config tweaks (CI/task outputs and dependencies) and devDependency adjustments

@github-actions

github-actions Bot commented Mar 20, 2026 •

Copy link
Copy Markdown
Contributor

Bundle Size Report

Package Base PR Delta
@workkit/ai 43KiB 43KiB no change
@workkit/ai-gateway 56KiB 56KiB no change
@workkit/api 82KiB 82KiB no change
@workkit/astro 18KiB 18KiB no change
@workkit/auth 48KiB 48KiB no change
@workkit/cache 38KiB 38KiB no change
@workkit/cli 107KiB 107KiB -28B
@workkit/cron 49KiB 49KiB no change
@workkit/crypto 26KiB 26KiB no change
@workkit/d1 90KiB 90KiB no change
@workkit/do 26KiB 26KiB no change
@workkit/env 43KiB 43KiB no change
@workkit/errors 40KiB 40KiB no change
@workkit/hono 25KiB 25KiB no change
@workkit/kv 33KiB 33KiB no change
@workkit/queue 21KiB 21KiB no change
@workkit/r2 57KiB 57KiB no change
@workkit/ratelimit 32KiB 32KiB no change
@workkit/remix 34KiB 34KiB no change
@workkit/testing 102KiB 102KiB no change
@workkit/types 19KiB 19KiB no change

@coderabbitai

coderabbitai Bot commented Mar 20, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@beeeku has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 38 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5d4bd379-253c-4c52-9273-d04fc1525095

📥 Commits

Reviewing files that changed from the base of the PR and between 31ba1da and 5c7f46a.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (25)
  • e2e/dependency-audit.test.ts
  • integrations/astro/package.json
  • integrations/hono/package.json
  • integrations/remix/package.json
  • knip.json
  • package.json
  • packages/ai-gateway/package.json
  • packages/ai/package.json
  • packages/api/package.json
  • packages/auth/package.json
  • packages/cache/package.json
  • packages/cli/package.json
  • packages/cli/src/utils.ts
  • packages/cron/package.json
  • packages/crypto/package.json
  • packages/d1/package.json
  • packages/do/package.json
  • packages/env/package.json
  • packages/errors/package.json
  • packages/kv/package.json
  • packages/queue/package.json
  • packages/r2/package.json
  • packages/ratelimit/package.json
  • packages/testing/package.json
  • packages/types/package.json
📝 Walkthrough

Walkthrough

Removed CommonJS outputs and mappings across the monorepo, pruned devDependencies, added a dependency-audit e2e test, introduced knip configuration for unused-dependency detection, adjusted turbo tasks, and made several CLI color helpers internal.

Changes

Cohort / File(s) Summary
Build configurations (ESM-only)
packages/*/bunup.config.ts, integrations/*/bunup.config.ts
Changed format from ["esm","cjs"] → ["esm"] across packages/integrations; CJS bundles no longer emitted.
Package manifests: exports & devDeps
packages/*/package.json, integrations/*/package.json
Removed exports["."].require (.d.cts/.cjs) and top-level "main" fields; pruned or removed devDependencies entries in many packages.
Dependency placement & removals
packages/cache/package.json, packages/crypto/package.json, packages/cli/package.json, integrations/remix/package.json
Removed @workkit/types/@workkit/errors from runtime dependencies in cache/crypto; moved CLI workspace packages to devDependencies; moved @standard-schema/spec from dependencies → peerDependencies in remix.
CLI runtime exports
packages/cli/src/utils.ts
Made red, green, yellow, blue color helpers non-exported (internal); cyan remains exported.
Dependency-audit tests
e2e/dependency-audit.test.ts
Added Vitest E2E test asserting presence/absence of specific deps across workspace package.json files.
Unused-dependency detection config
knip.json
Added knip config with workspace scopes, entry globs, TS project globs, and ignore rules (excludes **/bunup.config.ts).
Monorepo task config
turbo.json
Removed dependsOn: ["build"] from test; added "outputs": [] to typecheck and lint.
Root devDependency addition
package.json
Added expect-type@^1.1.0 to root devDependencies.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hopped through code at morning light,
ESM trimmed tidy, CJS took flight,
Tests now watch what packages keep,
Knip sniffs crumbs before they heap.
A tiny rabbit cheers the tight new sweep!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically summarizes the main changes: hoisting shared devDependencies, removing unused dependencies, and adding a knip configuration for dead-code detection.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/hoist-devdeps-cleanup

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
e2e/dependency-audit.test.ts (3)

23-43: Consider consolidating repeated readPkg calls within each test group.

The tests for @workkit/cache and @workkit/crypto each call readPkg twice for the same package. This can be consolidated for efficiency and reduced I/O.

♻️ Consolidated test structure example
   describe('unused runtime dependencies are removed', () => {
-    it('@workkit/cache has no `@workkit/types` in dependencies', () => {
-      const pkg = readPkg('packages/cache')
-      expect(pkg.dependencies ?? {}).not.toHaveProperty('@workkit/types')
-    })
-
-    it('@workkit/cache has no `@workkit/errors` in dependencies', () => {
+    it('@workkit/cache has no `@workkit/types` or `@workkit/errors` in dependencies', () => {
       const pkg = readPkg('packages/cache')
+      expect(pkg.dependencies ?? {}).not.toHaveProperty('@workkit/types')
       expect(pkg.dependencies ?? {}).not.toHaveProperty('@workkit/errors')
     })
 
-    it('@workkit/crypto has no `@workkit/types` in dependencies', () => {
-      const pkg = readPkg('packages/crypto')
-      expect(pkg.dependencies ?? {}).not.toHaveProperty('@workkit/types')
-    })
-
-    it('@workkit/crypto has no `@workkit/errors` in dependencies', () => {
+    it('@workkit/crypto has no `@workkit/types` or `@workkit/errors` in dependencies', () => {
       const pkg = readPkg('packages/crypto')
+      expect(pkg.dependencies ?? {}).not.toHaveProperty('@workkit/types')
       expect(pkg.dependencies ?? {}).not.toHaveProperty('@workkit/errors')
     })
   })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/dependency-audit.test.ts` around lines 23 - 43, In the "unused runtime
dependencies are removed" tests, avoid calling readPkg twice per package; for
each package (packages/cache and packages/crypto) call readPkg once and reuse
the returned pkg variable in the two assertions. Locate the describe block and
update the tests that reference readPkg('packages/cache') and
readPkg('packages/crypto') so each it(...) first assigns const pkg =
readPkg(...) and then performs expect(pkg.dependencies ??
{}).not.toHaveProperty(...) for both '@workkit/types' and '@workkit/errors'.

57-67: Same consolidation opportunity for remix tests.

Similar to the cache/crypto tests, these two tests read the same package.json separately.

♻️ Consolidated remix test
   describe('@standard-schema/spec is a peerDep in remix, not a dep', () => {
-    it('@workkit/remix has `@standard-schema/spec` in peerDependencies', () => {
-      const pkg = readPkg('integrations/remix')
-      expect(pkg.peerDependencies).toHaveProperty('@standard-schema/spec')
-    })
-
-    it('@workkit/remix does not have `@standard-schema/spec` in dependencies', () => {
+    it('@workkit/remix has `@standard-schema/spec` in peerDependencies, not dependencies', () => {
       const pkg = readPkg('integrations/remix')
+      expect(pkg.peerDependencies).toHaveProperty('@standard-schema/spec')
       expect(pkg.dependencies ?? {}).not.toHaveProperty('@standard-schema/spec')
     })
   })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/dependency-audit.test.ts` around lines 57 - 67, The two tests under the
describe block repeatedly call readPkg('integrations/remix'); consolidate by
calling readPkg once (e.g., in a beforeAll or at the top of the describe) and
reusing the resulting pkg for both assertions; update the tests that currently
call readPkg (the it blocks checking
expect(pkg.peerDependencies).toHaveProperty('@standard-schema/spec') and
expect(pkg.dependencies ?? {}).not.toHaveProperty('@standard-schema/spec')) to
use the shared pkg variable instead.

5-8: Consider using import.meta for ESM compatibility.

__dirname is a CommonJS global not natively available in ESM modules. While Vitest's transformation typically provides it, this creates an implicit dependency on the test runner's behavior. For explicit ESM compatibility:

♻️ Suggested ESM-native approach
 import { describe, it, expect } from 'vitest'
 import { readFileSync } from 'fs'
 import path from 'path'
+import { fileURLToPath } from 'url'
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
 
 function readPkg(relPath: string) {
   const full = path.resolve(__dirname, '..', relPath, 'package.json')
   return JSON.parse(readFileSync(full, 'utf-8'))
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/dependency-audit.test.ts` around lines 5 - 8, The readPkg function uses
the CommonJS __dirname which breaks in ESM; change it to derive the test file
directory from import.meta.url by using fileURLToPath(import.meta.url) and
path.dirname, then build the package.json path (replace the
path.resolve(__dirname, ...) call in readPkg). Also add the import for
fileURLToPath from 'url' at the top of the module and ensure readPkg still
returns JSON.parse(readFileSync(full, 'utf-8')).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@knip.json`:
- Around line 8-9: The entry configuration currently includes "src/*.ts" which
is too broad and prevents dead-code detection; update the knip.json so that
"entry" only lists true public/runtime roots (keep "src/index.ts" but remove
"src/*.ts") and move implementation patterns like "src/*.ts" into the "project"
array (e.g., ensure "project" contains "src/**/*.ts" and/or "src/*.ts") so
per-file implementation files (client.ts, fallback.ts, retry.ts, stream.ts,
tokens.ts) are treated as project sources not entry roots.

---

Nitpick comments:
In `@e2e/dependency-audit.test.ts`:
- Around line 23-43: In the "unused runtime dependencies are removed" tests,
avoid calling readPkg twice per package; for each package (packages/cache and
packages/crypto) call readPkg once and reuse the returned pkg variable in the
two assertions. Locate the describe block and update the tests that reference
readPkg('packages/cache') and readPkg('packages/crypto') so each it(...) first
assigns const pkg = readPkg(...) and then performs expect(pkg.dependencies ??
{}).not.toHaveProperty(...) for both '@workkit/types' and '@workkit/errors'.
- Around line 57-67: The two tests under the describe block repeatedly call
readPkg('integrations/remix'); consolidate by calling readPkg once (e.g., in a
beforeAll or at the top of the describe) and reusing the resulting pkg for both
assertions; update the tests that currently call readPkg (the it blocks checking
expect(pkg.peerDependencies).toHaveProperty('@standard-schema/spec') and
expect(pkg.dependencies ?? {}).not.toHaveProperty('@standard-schema/spec')) to
use the shared pkg variable instead.
- Around line 5-8: The readPkg function uses the CommonJS __dirname which breaks
in ESM; change it to derive the test file directory from import.meta.url by
using fileURLToPath(import.meta.url) and path.dirname, then build the
package.json path (replace the path.resolve(__dirname, ...) call in readPkg).
Also add the import for fileURLToPath from 'url' at the top of the module and
ensure readPkg still returns JSON.parse(readFileSync(full, 'utf-8')).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d090b191-e6d2-432e-af3d-b67d7da4c393

📥 Commits

Reviewing files that changed from the base of the PR and between 5727169 and a172867.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (46)
  • e2e/dependency-audit.test.ts
  • integrations/astro/bunup.config.ts
  • integrations/astro/package.json
  • integrations/hono/bunup.config.ts
  • integrations/hono/package.json
  • integrations/remix/bunup.config.ts
  • integrations/remix/package.json
  • knip.json
  • packages/ai-gateway/bunup.config.ts
  • packages/ai-gateway/package.json
  • packages/ai/bunup.config.ts
  • packages/ai/package.json
  • packages/api/bunup.config.ts
  • packages/api/package.json
  • packages/auth/bunup.config.ts
  • packages/auth/package.json
  • packages/cache/bunup.config.ts
  • packages/cache/package.json
  • packages/cli/bunup.config.ts
  • packages/cli/package.json
  • packages/cli/src/utils.ts
  • packages/cron/bunup.config.ts
  • packages/cron/package.json
  • packages/crypto/bunup.config.ts
  • packages/crypto/package.json
  • packages/d1/bunup.config.ts
  • packages/d1/package.json
  • packages/do/bunup.config.ts
  • packages/do/package.json
  • packages/env/bunup.config.ts
  • packages/env/package.json
  • packages/errors/bunup.config.ts
  • packages/errors/package.json
  • packages/kv/bunup.config.ts
  • packages/kv/package.json
  • packages/queue/bunup.config.ts
  • packages/queue/package.json
  • packages/r2/bunup.config.ts
  • packages/r2/package.json
  • packages/ratelimit/bunup.config.ts
  • packages/ratelimit/package.json
  • packages/testing/bunup.config.ts
  • packages/testing/package.json
  • packages/types/bunup.config.ts
  • packages/types/package.json
  • turbo.json
💤 Files with no reviewable changes (3)
  • packages/d1/package.json
  • packages/queue/package.json
  • packages/testing/package.json

Comment thread knip.json Outdated
beeeku and others added 3 commits March 21, 2026 00:15
- Remove `expect-type` from 18 packages (never used in any test file)
- Hoist typescript, vitest, @cloudflare/workers-types, bunup to root
  package.json only (bun workspaces provides them to all packages)
- Remove `export` from red/green/yellow/blue in packages/cli/src/utils.ts
  (only used internally by success/warn/error/info functions)
- Add knip.json for ongoing dead code detection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The audit incorrectly flagged expect-type as unused. It's actually imported
in 14 test files across 9 packages (api, cron, do, queue, ratelimit, types,
astro, hono). Adding to root since devDeps were hoisted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove "src/*.ts" from entry — it was treating all top-level source files
as entry points, preventing dead code detection. Implementation files
(client.ts, retry.ts, etc.) are already covered by "project": ["src/**/*.ts"].

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@beeeku
beeeku force-pushed the fix/hoist-devdeps-cleanup branch from a757602 to 5c7f46a Compare March 20, 2026 18:45
@beeeku
beeeku merged commit 9fb600b into master Mar 20, 2026
7 checks passed
@beeeku
beeeku deleted the fix/hoist-devdeps-cleanup branch March 20, 2026 18:47
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