11#! /usr/bin/env bash
2- # Detects eager imports of AI SDK packages in main process
3- # These packages are large and must be lazy-loaded to maintain fast startup time
2+ # Detects eager imports of heavy packages in startup-critical and renderer/worker files
3+ #
4+ # Main process: AI SDK packages must be lazy-loaded to maintain fast startup (<4s)
5+ # Renderer/Worker: Large data files (models.json) and ai-tokenizer must never be imported
46
57set -euo pipefail
68
7- # Files that should NOT have eager AI SDK imports
9+ # Files that should NOT have eager AI SDK imports (main process)
810CRITICAL_FILES=(
911 " src/main.ts"
1012 " src/config.ts"
1113 " src/preload.ts"
1214)
1315
14- # Packages that should be lazily loaded
15- BANNED_IMPORTS =(
16+ # Packages banned in main process (lazy load only)
17+ BANNED_MAIN_IMPORTS =(
1618 " @ai-sdk/anthropic"
1719 " @ai-sdk/openai"
1820 " @ai-sdk/google"
1921 " ai"
2022)
2123
24+ # Packages banned in renderer/worker (never import)
25+ BANNED_RENDERER_IMPORTS=(
26+ " ai-tokenizer"
27+ )
28+
29+ # Files banned in renderer/worker (large data files)
30+ BANNED_RENDERER_FILES=(
31+ " models.json"
32+ )
33+
2234failed=0
2335
24- echo " Checking for eager AI SDK imports in critical startup files..."
36+ echo " ==> Checking for eager AI SDK imports in main process critical files..."
2537
2638for file in " ${CRITICAL_FILES[@]} " ; do
2739 if [ ! -f " $file " ]; then
2840 continue
2941 fi
3042
31- for pkg in " ${BANNED_IMPORTS [@]} " ; do
43+ for pkg in " ${BANNED_MAIN_IMPORTS [@]} " ; do
3244 # Check for top-level imports (not dynamic)
3345 if grep -E " ^import .* from ['\" ]$pkg " " $file " > /dev/null 2>&1 ; then
3446 echo " ❌ EAGER IMPORT DETECTED: $file imports '$pkg '"
4052
4153# Also check dist/main.js for require() calls (if it exists)
4254if [ -f " dist/main.js" ]; then
43- echo " Checking bundled main.js for eager requires..."
44- for pkg in " ${BANNED_IMPORTS [@]} " ; do
55+ echo " ==> Checking bundled main.js for eager requires..."
56+ for pkg in " ${BANNED_MAIN_IMPORTS [@]} " ; do
4557 if grep " require(\" $pkg \" )" dist/main.js > /dev/null 2>&1 ; then
4658 echo " ❌ BUNDLED EAGER IMPORT: dist/main.js requires '$pkg '"
4759 echo " This means a critical file is importing AI SDK eagerly"
@@ -50,12 +62,79 @@ if [ -f "dist/main.js" ]; then
5062 done
5163fi
5264
65+ echo " ==> Checking for banned imports in renderer/worker files..."
66+
67+ # Find all TypeScript files in renderer-only directories
68+ RENDERER_DIRS=(
69+ " src/components"
70+ " src/contexts"
71+ " src/hooks"
72+ " src/stores"
73+ " src/utils/ui"
74+ " src/utils/tokens/tokenStats.worker.ts"
75+ " src/utils/tokens/tokenStatsCalculatorApproximate.ts"
76+ )
77+
78+ for dir in " ${RENDERER_DIRS[@]} " ; do
79+ if [ ! -e " $dir " ]; then
80+ continue
81+ fi
82+
83+ # Find all .ts/.tsx files in this directory
84+ while IFS= read -r -d ' ' file; do
85+ # Check for banned packages
86+ for pkg in " ${BANNED_RENDERER_IMPORTS[@]} " ; do
87+ if grep -E " from ['\" ]$pkg " " $file " > /dev/null 2>&1 ; then
88+ echo " ❌ RENDERER IMPORT DETECTED: $file imports '$pkg '"
89+ echo " ai-tokenizer must never be imported in renderer (8MB+)"
90+ failed=1
91+ fi
92+ done
93+
94+ # Check for banned files (e.g., models.json)
95+ for banned_file in " ${BANNED_RENDERER_FILES[@]} " ; do
96+ if grep -E " from ['\" ].*$banned_file " " $file " > /dev/null 2>&1 ; then
97+ echo " ❌ LARGE FILE IMPORT: $file imports '$banned_file '"
98+ echo " $banned_file is 701KB and must not be in renderer/worker"
99+ failed=1
100+ fi
101+ done
102+ done < <( find " $dir " -type f \( -name " *.ts" -o -name " *.tsx" \) -print0)
103+ done
104+
105+ # Check bundled worker if it exists
106+ if [ -f dist/tokenStats.worker-* .js ]; then
107+ WORKER_FILE=$( find dist -name ' tokenStats.worker-*.js' | head -1)
108+ WORKER_SIZE=$( wc -c < " $WORKER_FILE " | tr -d ' ' )
109+
110+ echo " ==> Checking worker bundle for heavy imports..."
111+
112+ # If worker is suspiciously large (>50KB), likely has models.json or ai-tokenizer
113+ if (( WORKER_SIZE > 51200 )) ; then
114+ echo " ❌ WORKER TOO LARGE: $WORKER_FILE is ${WORKER_SIZE} bytes (>50KB)"
115+ echo " This suggests models.json (701KB) or ai-tokenizer leaked in"
116+
117+ # Try to identify what's in there
118+ if grep -q " models.json" " $WORKER_FILE " 2> /dev/null || \
119+ strings " $WORKER_FILE " 2> /dev/null | grep -q " anthropic\|openai" | head -10; then
120+ echo " Found model names in bundle - likely models.json"
121+ fi
122+ failed=1
123+ fi
124+ fi
125+
53126if [ $failed -eq 1 ]; then
54127 echo " "
55- echo " To fix: Use dynamic imports instead:"
56- echo " ✅ const { createAnthropic } = await import('@ai-sdk/anthropic');"
57- echo " ❌ import { createAnthropic } from '@ai-sdk/anthropic';"
128+ echo " Fix suggestions:"
129+ echo " Main process: Use dynamic imports"
130+ echo " ✅ const { createAnthropic } = await import('@ai-sdk/anthropic');"
131+ echo " ❌ import { createAnthropic } from '@ai-sdk/anthropic';"
132+ echo " "
133+ echo " Renderer/Worker: Never import heavy packages"
134+ echo " ❌ import { getModelStats } from './modelStats'; // imports models.json"
135+ echo " ❌ import AITokenizer from 'ai-tokenizer'; // 8MB package"
136+ echo " ✅ Use approximations or IPC to main process"
58137 exit 1
59138fi
60139
61- echo " ✅ No eager AI SDK imports detected"
140+ echo " ✅ No banned imports detected"
0 commit comments