2323# AVOID CONDITIONAL BRANCHES (if/else) IN BUILD TARGETS AT ALL COSTS.
2424# Branches reduce reproducibility - builds should fail fast with clear errors
2525# if dependencies are missing, not silently fall back to different behavior.
26+ # Platform detection for cross-platform compatibility
27+ ifeq ($(OS ) ,Windows_NT)
28+ # Windows: Use npm/npx because $(RUNNER) doesn't correctly pass arguments on Windows
29+ RUNNER := npx
30+ else
31+ # Non-Windows: Use $(RUNNER) for better performance
32+ RUNNER := bun x
33+ endif
2634
2735# Enable parallel execution by default (only if user didn't specify -j)
2836ifeq (,$(filter -j% ,$(MAKEFLAGS ) ) )
@@ -97,8 +105,9 @@ help: ## Show this help message
97105
98106# # Development
99107dev : node_modules/.installed build-main # # Start development server (Vite + tsgo watcher for 10x faster type checking)
100- @bun x concurrently -k \
101- " bun x concurrently \" $( TSGO) -w -p tsconfig.main.json\" \" bun x tsc-alias -w -p tsconfig.main.json\" " \
108+ @# On Windows, use npm run because bun x doesn't correctly pass arguments
109+ @$(RUNNER ) concurrently -k \
110+ " $( RUNNER) concurrently \" $( TSGO) -w -p tsconfig.main.json\" \" $( RUNNER) tsc-alias -w -p tsconfig.main.json\" " \
102111 " vite"
103112
104113dev-server : node_modules/.installed build-main # # Start server mode with hot reload (backend :3000 + frontend :5173). Use VITE_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0 for remote access
@@ -107,15 +116,16 @@ dev-server: node_modules/.installed build-main ## Start server mode with hot rel
107116 @echo " Frontend (with HMR): http://$( or $( VITE_HOST) ,localhost) :$( or $( VITE_PORT) ,5173) "
108117 @echo " "
109118 @echo " For remote access: make dev-server VITE_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0"
110- @bun x concurrently -k \
111- " bun x concurrently \" $( TSGO) -w -p tsconfig.main.json\" \" bun x tsc-alias -w -p tsconfig.main.json\" " \
112- " bun x nodemon --watch dist/main.js --watch dist/main-server.js --delay 500ms --exec 'node dist/main.js server --host $( or $( BACKEND_HOST) ,localhost) --port $( or $( BACKEND_PORT) ,3000) '" \
119+ @# On Windows, use npm run because bun x doesn't correctly pass arguments
120+ @$(RUNNER ) concurrently -k \
121+ " $( RUNNER) concurrently \" $( TSGO) -w -p tsconfig.main.json\" \" $( RUNNER) tsc-alias -w -p tsconfig.main.json\" " \
122+ " $( RUNNER) nodemon --watch dist/main.js --watch dist/main-server.js --delay 500ms --exec 'node dist/main.js server --host $( or $( BACKEND_HOST) ,localhost) --port $( or $( BACKEND_PORT) ,3000) '" \
113123 " CMUX_VITE_HOST=$( or $( VITE_HOST) ,127.0.0.1) CMUX_VITE_PORT=$( or $( VITE_PORT) ,5173) VITE_BACKEND_URL=http://$( or $( BACKEND_HOST) ,localhost) :$( or $( BACKEND_PORT) ,3000) vite"
114124
115125
116126
117127start : node_modules/.installed build-main build-preload build-static # # Build and start Electron app
118- @bun x electron --remote-debugging-port=9222 .
128+ @$( RUNNER ) electron --remote-debugging-port=9222 .
119129
120130# # Build targets (can run in parallel)
121131build : node_modules/.installed src/version.ts build-renderer build-main build-preload build-icons build-static # # Build all targets
@@ -125,7 +135,7 @@ build-main: node_modules/.installed dist/main.js ## Build main process
125135dist/main.js : src/version.ts tsconfig.main.json tsconfig.json $(TS_SOURCES )
126136 @echo " Building main process..."
127137 @NODE_ENV=production $(TSGO ) -p tsconfig.main.json
128- @NODE_ENV=production bun x tsc-alias -p tsconfig.main.json
138+ @NODE_ENV=production $( RUNNER ) tsc-alias -p tsconfig.main.json
129139
130140build-preload : node_modules/.installed dist/preload.js # # Build preload script
131141
@@ -140,7 +150,7 @@ dist/preload.js: src/preload.ts $(TS_SOURCES)
140150
141151build-renderer : node_modules/.installed src/version.ts # # Build renderer process
142152 @echo " Building renderer..."
143- @bun x vite build
153+ @$( RUNNER ) vite build
144154
145155build-static : # # Copy static assets to dist
146156 @echo " Copying static assets..."
@@ -192,15 +202,16 @@ lint-fix: node_modules/.installed ## Run linter with --fix
192202 @./scripts/lint.sh --fix
193203
194204typecheck : node_modules/.installed src/version.ts # # Run TypeScript type checking (uses tsgo for 10x speedup)
195- @bun x concurrently -g \
205+ @# On Windows, use npm run because bun x doesn't correctly pass arguments
206+ @$(RUNNER ) concurrently -g \
196207 " $( TSGO) --noEmit" \
197208 " $( TSGO) --noEmit -p tsconfig.main.json"
198209
199210check-deadcode : node_modules/.installed # # Check for potential dead code (manual only, not in static-check)
200211 @echo " Checking for potential dead code with ts-prune..."
201212 @echo " (Note: Some unused exports are legitimate - types, public APIs, entry points, etc.)"
202213 @echo " "
203- @bun x ts-prune -i ' (test|spec|mock|bench|debug|storybook)' \
214+ @$( RUNNER ) ts-prune -i ' (test|spec|mock|bench|debug|storybook)' \
204215 | grep -v " used in module" \
205216 | grep -v " src/App.tsx.*default" \
206217 | grep -v " src/types/" \
@@ -210,7 +221,7 @@ check-deadcode: node_modules/.installed ## Check for potential dead code (manual
210221# # Testing
211222test-integration : node_modules/.installed build-main # # Run all tests (unit + integration)
212223 @bun test src
213- @TEST_INTEGRATION=1 bun x jest tests
224+ @TEST_INTEGRATION=1 $( RUNNER ) jest tests
214225
215226test-unit : node_modules/.installed build-main # # Run unit tests
216227 @bun test src
@@ -225,52 +236,52 @@ test-coverage: ## Run tests with coverage
225236
226237test-e2e : # # Run end-to-end tests
227238 @$(MAKE ) build
228- @CMUX_E2E_LOAD_DIST=1 CMUX_E2E_SKIP_BUILD=1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 bun x playwright test --project=electron $(PLAYWRIGHT_ARGS )
239+ @CMUX_E2E_LOAD_DIST=1 CMUX_E2E_SKIP_BUILD=1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 $( RUNNER ) playwright test --project=electron $(PLAYWRIGHT_ARGS )
229240
230241# # Distribution
231242dist : build # # Build distributable packages
232- @bun x electron-builder --publish never
243+ @$( RUNNER ) electron-builder --publish never
233244
234245# Parallel macOS builds - notarization happens concurrently
235246dist-mac : build # # Build macOS distributables (x64 + arm64)
236247 @if [ -n " $$ CSC_LINK" ]; then \
237248 echo " 🔐 Code signing enabled - building sequentially to avoid keychain conflicts..." ; \
238- bun x electron-builder --mac --x64 --publish never && \
239- bun x electron-builder --mac --arm64 --publish never; \
249+ $( RUNNER ) electron-builder --mac --x64 --publish never && \
250+ $( RUNNER ) electron-builder --mac --arm64 --publish never; \
240251 else \
241252 echo " Building macOS architectures in parallel..." ; \
242- bun x electron-builder --mac --x64 --publish never & pid1=$$ ! ; \
243- bun x electron-builder --mac --arm64 --publish never & pid2=$$ ! ; \
253+ $( RUNNER ) electron-builder --mac --x64 --publish never & pid1=$$ ! ; \
254+ $( RUNNER ) electron-builder --mac --arm64 --publish never & pid2=$$ ! ; \
244255 wait $$ pid1 && wait $$ pid2; \
245256 fi
246257 @echo " ✅ Both architectures built successfully"
247258
248259dist-mac-release : build # # Build and publish macOS distributables (x64 + arm64)
249260 @if [ -n " $$ CSC_LINK" ]; then \
250261 echo " 🔐 Code signing enabled - building sequentially to avoid keychain conflicts..." ; \
251- bun x electron-builder --mac --x64 --publish always && \
252- bun x electron-builder --mac --arm64 --publish always; \
262+ $( RUNNER ) electron-builder --mac --x64 --publish always && \
263+ $( RUNNER ) electron-builder --mac --arm64 --publish always; \
253264 else \
254265 echo " Building and publishing macOS architectures in parallel..." ; \
255- bun x electron-builder --mac --x64 --publish always & pid1=$$ ! ; \
256- bun x electron-builder --mac --arm64 --publish always & pid2=$$ ! ; \
266+ $( RUNNER ) electron-builder --mac --x64 --publish always & pid1=$$ ! ; \
267+ $( RUNNER ) electron-builder --mac --arm64 --publish always & pid2=$$ ! ; \
257268 wait $$ pid1 && wait $$ pid2; \
258269 fi
259270 @echo " ✅ Both architectures built and published successfully"
260271
261272dist-mac-x64 : build # # Build macOS x64 distributable only
262273 @echo " Building macOS x64..."
263- @bun x electron-builder --mac --x64 --publish never
274+ @$( RUNNER ) electron-builder --mac --x64 --publish never
264275
265276dist-mac-arm64 : build # # Build macOS arm64 distributable only
266277 @echo " Building macOS arm64..."
267- @bun x electron-builder --mac --arm64 --publish never
278+ @$( RUNNER ) electron-builder --mac --arm64 --publish never
268279
269280dist-win : build # # Build Windows distributable
270- @bun x electron-builder --win --publish never
281+ @$( RUNNER ) electron-builder --win --publish never
271282
272283dist-linux : build # # Build Linux distributable
273- @bun x electron-builder --linux --publish never
284+ @$( RUNNER ) electron-builder --linux --publish never
274285
275286# # VS Code Extension (delegates to vscode/Makefile)
276287
@@ -293,19 +304,19 @@ docs-watch: ## Watch and rebuild documentation
293304# # Storybook
294305storybook : node_modules/.installed # # Start Storybook development server
295306 $(check_node_version )
296- @bun x storybook dev -p 6006 $(STORYBOOK_OPEN_FLAG )
307+ @$( RUNNER ) storybook dev -p 6006 $(STORYBOOK_OPEN_FLAG )
297308
298309storybook-build : node_modules/.installed src/version.ts # # Build static Storybook
299310 $(check_node_version )
300- @bun x storybook build
311+ @$( RUNNER ) storybook build
301312
302313test-storybook : node_modules/.installed # # Run Storybook interaction tests (requires Storybook to be running or built)
303314 $(check_node_version )
304- @bun x test-storybook
315+ @$( RUNNER ) test-storybook
305316
306317chromatic : node_modules/.installed # # Run Chromatic for visual regression testing
307318 $(check_node_version )
308- @bun x chromatic --exit-zero-on-changes
319+ @$( RUNNER ) chromatic --exit-zero-on-changes
309320
310321# # Benchmarks
311322benchmark-terminal : # # Run Terminal-Bench with the cmux agent (use TB_DATASET/TB_SAMPLE_SIZE/TB_TIMEOUT/TB_ARGS to customize)
0 commit comments