Skip to content

chore(template): dependency cleanup - #59

Merged
faw01 merged 9 commits into
mainfrom
chore/template-cleanup
Jul 12, 2026
Merged

chore(template): dependency cleanup#59
faw01 merged 9 commits into
mainfrom
chore/template-cleanup

Conversation

@faw01

@faw01 faw01 commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • Remove 21 verified-unused dependencies across the template apps/packages and the root design system (fallow findings; runtime-provided deps like sharp, import-in-the-middle, and expo-* kept)
  • Consolidate the Convex client providers (provider.tsx / provider.native.tsx) behind a shared factory, keeping the platform env vars, client options, and "use client" boundary intact
  • Extract a shared scaffoldTemplate helper for the CLI init and e2e scaffold scripts; stop exporting rewriteBunTokens
  • Simplify the worst-complexity functions in generate-stories.ts (behavior-preserving)
  • Add a changeset for a create-mf2-app patch release

Test plan

  • bun test scripts/ in apps/cli — 118 pass
  • bun run check (biome) clean at root and on template files
  • tsgo --strict clean on generate-stories.ts; convex package typecheck clean
  • Bugbot review — no bugs found

Note

Low Risk
Mostly dependency pruning, internal refactors, and scaffold deduplication; Convex provider behavior is intended to stay equivalent across web and native.

Overview
This PR trims the scaffolded monorepo template by dropping verified-unused dependencies from multiple apps/packages (and mirrors the same cleanup on the root design-system package), while keeping runtime-provided deps like sharp and Sentry instrumentation packages. AI-related packages move to the template root package.json with an @ai-sdk/provider-utils override; @repo/backend drops direct ai / @ai-sdk/gateway in favor of @repo/ai.

Convex web and native providers now share createConvexComponents in provider.shared.tsx, so each entry file only sets env URL, client options, and the "use client" boundary.

CLI scaffolding copies the template through a new scaffoldTemplate helper used by init and e2e-scaffold (optional tolerant dotfile renames); rewriteBunTokens is no longer exported. Story generation refactors generate-stories.ts into smaller helpers without intended behavior change. A create-mf2-app patch changeset is included; agent commit guidelines no longer require CodeRabbit before commit.

Reviewed by Cursor Bugbot for commit c1aca5a. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Project initialization and end-to-end scaffolding now use a consistent setup process, including dotfiles and skills.
  • Bug Fixes

    • Improved handling of template files during project creation.
    • Convex configuration now behaves consistently across web and native projects.
  • Improvements

    • Generated templates include fewer unused dependencies, resulting in cleaner installations.
    • Story generation and import processing are more reliable, with improved handling of skipped or failing examples.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The CLI now uses a shared template scaffolding helper. Convex providers share a factory, story generation is reorganized into parsing and healing helpers, unused template dependencies are removed, and a patch changeset is added.

Changes

Template runtime and generation

Layer / File(s) Summary
Centralized template scaffolding
apps/cli/scripts/utils.ts, apps/cli/scripts/init.ts, apps/cli/scripts/e2e-scaffold.ts, apps/cli/scripts/init.test.ts
Template copying, skill materialization, and dotfile renaming are consolidated in scaffoldTemplate, with callers and ordering assertions updated.
Shared Convex provider factory
apps/cli/template/packages/convex/provider.shared.tsx, apps/cli/template/packages/convex/provider.tsx, apps/cli/template/packages/convex/provider.native.tsx
Web and native providers obtain their Convex components and configuration hook from a shared factory.
Story generation pipeline
apps/cli/template/scripts/generate-stories.ts
Import parsing, source rewriting, hook detection, import merging, and typecheck-driven regeneration are reorganized into dedicated helpers and tables.
Template dependency and release updates
apps/cli/template/apps/*/package.json, apps/cli/template/packages/*/package.json, packages/design-system/package.json, .changeset/heavy-lamps-repeat.md
Unused dependencies are removed from template applications and packages, and a patch changeset is added.

Contributor workflow

Layer / File(s) Summary
Contributor checklist update
.agents/AGENTS.md
Removes the checklist instruction to run the review command before committing.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

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.
Description check ⚠️ Warning The description doesn't follow the required template sections like Related Issues, Checklist, Screenshots, or Additional Notes. Add the repository template sections with a Description, Related Issues link, completed checklist, optional screenshots, and any additional notes.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title matches the primary dependency-cleanup focus of the pull request, even though it omits the refactor details.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/template-cleanup

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.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/cli/template/scripts/generate-stories.ts (1)

349-393: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Type-only named imports silently lose the type keyword when a default import is present.

renderNamedSegment omits per-name type prefixes whenever allType is true (Line 353-355), on the assumption the caller will use the import type { ... } wrapper. But renderImport only takes that wrapper path when !pi.defaultName (Line 386). If a parsed import has both a default name and named specifiers that are all type-only (e.g. import Foo, { type Bar } from "mod"), the result becomes import Foo, { Bar } from "mod"; — the type qualifier is dropped, turning a type-only import into a value import. This is directly reachable from a single demo source file (no merge needed), and would surface as a typecheck failure under isolatedModules/verbatimModuleSyntax, which the heal loop can't fix by dropping a demo (it's an import-level issue, not tied to one story), potentially exhausting MAX_HEAL_PASSES and requiring manual fixes.

🐛 Proposed fix
-function renderNamedSegment(named: NamedImport[]): {
-  allType: boolean;
-  text: string;
-} {
-  const allType = named.every((n) => n.isType);
-  const names = named.map((n) => {
-    const typePrefix = !allType && n.isType ? "type " : "";
+function renderNamedSegment(
+  named: NamedImport[],
+  forceIndividualPrefix = false
+): {
+  allType: boolean;
+  text: string;
+} {
+  const allType = named.every((n) => n.isType);
+  const useIndividualPrefix = forceIndividualPrefix || !allType;
+  const names = named.map((n) => {
+    const typePrefix = useIndividualPrefix && n.isType ? "type " : "";
     return n.alias
       ? `${typePrefix}${n.name} as ${n.alias}`
       : `${typePrefix}${n.name}`;
   });
   if (pi.named.length > 0) {
-    const { allType, text } = renderNamedSegment(pi.named);
+    const { allType, text } = renderNamedSegment(
+      pi.named,
+      Boolean(pi.defaultName)
+    );
     if (allType && !pi.defaultName) {
       return `import type ${text} from "${pi.source}";`;
     }
     segments.push(text);
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/cli/template/scripts/generate-stories.ts` around lines 349 - 393,
Preserve type-only named import qualifiers when rendering an import that also
has a default name. Update renderNamedSegment and/or renderImport so all-type
named specifiers use per-name “type” prefixes whenever pi.defaultName is
present, while retaining the import type wrapper for named-only imports.
🧹 Nitpick comments (1)
apps/cli/template/scripts/generate-stories.ts (1)

313-347: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

SKIPPED_IMPORT_SOURCES mostly dead code — already intercepted earlier.

4 of the 5 entries here (@/hooks/use-media-query, @/hooks/use-copy-to-clipboard, @/examples/radix/hooks/use-mobile, @/registry/new-york-v4/hooks/use-mobile) are identical to the sources in HOOK_SOURCE_FLAGS (Line 556-561). Since markHookSource runs first in processExampleImports (Line 586) and continues on match, transformImportSource never actually sees these sources — only @/components/language-selector is reachable here. Keeping both lists risks them diverging silently (e.g. someone updates one list assuming it's authoritative).

♻️ Proposed cleanup
 const SKIPPED_IMPORT_SOURCES = new Set([
-  "`@/hooks/use-media-query`",
-  "`@/hooks/use-copy-to-clipboard`",
-  "`@/examples/radix/hooks/use-mobile`",
-  "`@/registry/new-york-v4/hooks/use-mobile`",
   "`@/components/language-selector`",
 ]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/cli/template/scripts/generate-stories.ts` around lines 313 - 347, Remove
the four hook entries duplicated by HOOK_SOURCE_FLAGS from
SKIPPED_IMPORT_SOURCES, leaving only `@/components/language-selector` for
transformImportSource to skip. Keep markHookSource as the authoritative handling
for those hook sources and preserve the existing transformImportSource behavior
for the remaining entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@apps/cli/template/scripts/generate-stories.ts`:
- Around line 349-393: Preserve type-only named import qualifiers when rendering
an import that also has a default name. Update renderNamedSegment and/or
renderImport so all-type named specifiers use per-name “type” prefixes whenever
pi.defaultName is present, while retaining the import type wrapper for
named-only imports.

---

Nitpick comments:
In `@apps/cli/template/scripts/generate-stories.ts`:
- Around line 313-347: Remove the four hook entries duplicated by
HOOK_SOURCE_FLAGS from SKIPPED_IMPORT_SOURCES, leaving only
`@/components/language-selector` for transformImportSource to skip. Keep
markHookSource as the authoritative handling for those hook sources and preserve
the existing transformImportSource behavior for the remaining entry.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a1cdfbc5-3e87-41f5-b78a-1e4929186754

📥 Commits

Reviewing files that changed from the base of the PR and between 88d8bcd and ccdb1ce.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (21)
  • .agents/AGENTS.md
  • .changeset/heavy-lamps-repeat.md
  • apps/cli/scripts/e2e-scaffold.ts
  • apps/cli/scripts/init.test.ts
  • apps/cli/scripts/init.ts
  • apps/cli/scripts/utils.ts
  • apps/cli/template/apps/api/package.json
  • apps/cli/template/apps/app/package.json
  • apps/cli/template/apps/desktop/package.json
  • apps/cli/template/apps/mobile/package.json
  • apps/cli/template/apps/storybook/package.json
  • apps/cli/template/apps/web/package.json
  • apps/cli/template/packages/backend/package.json
  • apps/cli/template/packages/convex/package.json
  • apps/cli/template/packages/convex/provider.native.tsx
  • apps/cli/template/packages/convex/provider.shared.tsx
  • apps/cli/template/packages/convex/provider.tsx
  • apps/cli/template/packages/design-system/package.json
  • apps/cli/template/packages/next-config/package.json
  • apps/cli/template/scripts/generate-stories.ts
  • packages/design-system/package.json
💤 Files with no reviewable changes (4)
  • apps/cli/template/packages/convex/package.json
  • apps/cli/template/packages/backend/package.json
  • .agents/AGENTS.md
  • apps/cli/template/packages/next-config/package.json

@faw01
faw01 merged commit e0e34a2 into main Jul 12, 2026
6 checks passed
@faw01
faw01 deleted the chore/template-cleanup branch July 12, 2026 13:30
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