Skip to content

Commit 9748622

Browse files
ochafikclaude
andauthored
fix: Windows compatibility - bun as optional dep, cross-env for examples (#145)
* fix: Windows compatibility for npm scripts and cross-platform CI Fixes #142 - Windows PowerShell install bug Changes: - Replace single quotes with escaped double quotes in generate:schemas (cmd.exe passes single quotes literally, breaking prettier glob matching) - Simplify prettier scripts: remove redundant --ignore-path flags (prettier auto-loads .gitignore and .prettierignore by default) - Remove $(pwd) from prettier scripts (bash-only syntax) - Add cross-platform CI matrix: Linux x64, Windows x64, macOS ARM64, macOS x64 - Use shell: bash for grep commands in CI (not available in Windows cmd.exe) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: remove bun npm package from all workspaces The bun npm package tries to install platform-specific binaries which fails on Windows CI. Since bun is installed via oven-sh/setup-bun action in CI (and developers install it globally), we don't need the npm package. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: skip examples:build on Windows (uses Unix-only INPUT=... syntax) The examples use `INPUT=mcp-app.html vite build` which is bash syntax for setting environment variables. This doesn't work on Windows cmd.exe. Since examples aren't published to npm, we can skip building them on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: force LF line endings for cross-platform prettier consistency Git on Windows auto-converts line endings to CRLF, causing prettier to report formatting issues. Force LF for all text files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: add test for git-based npm install (cross-platform) This verifies that `npm install git+https://...` works on all platforms, which triggers the prepare script and requires bun to be available. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: add Linux ARM64 and Windows ARM64 to CI matrix - Added ubuntu-24.04-arm (Linux ARM64) - Added windows-11-arm (Windows ARM64) Note: WSL is not available on GitHub-hosted runners (requires nested virtualization which isn't supported). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: disable Windows ARM64 (Bun lacks stable ARM64 binaries) The oven-sh/setup-bun action fails with 404 when trying to download Bun for Windows ARM64. Re-enable when Bun adds proper support. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: add Windows WSL build test Uses Vampire/setup-wsl action to install Ubuntu-24.04 in WSL and run the full build/test cycle. This tests the Linux-in-Windows scenario that was reported in issue #142. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: fix WSL build - install unzip for Bun installer 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: add setup-bun to publish.yml workflow The pkg-pr-new publish workflow was missing bun setup, causing "bun: not found" errors during npm ci (which triggers prepare script). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: enable Windows ARM64 with x64-baseline Bun (via emulation) Windows ARM64 can run x64 binaries via emulation. Use bun-download-url to force x64-baseline build since native ARM64 Bun isn't available yet. Reference: oven-sh/bun#9824 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: remove macOS x64 (macos-13 runner retired) The macos-13 based runner images are now retired. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * docs: add Bun installation instructions per platform Documents that Bun is required for development, with platform-specific install commands in collapsible sections. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * docs: note Bun requirement in README examples section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: add bun as optional dependency (no global install required) - Add @oven/bun-* platform packages as optionalDependencies - Create postinstall script to set up bun binary from optional deps - Handle Windows ARM64 by downloading x64-baseline for emulation - Remove setup-bun from CI workflows (npm install handles it now) - Remove manual Bun install instructions from docs This alternative approach eliminates the need for global Bun installation or setup-bun action in CI. npm install automatically installs the platform-appropriate bun binary. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * chore: add debug logging to setup-bun script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * chore: force stdout flush in setup-bun for CI debugging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * chore: add more debugging to setup-bun 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * chore: remove accidental test artifacts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * chore: run setup-bun in prepare script (before build) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: use cross-env for Windows-compatible example builds - Add cross-env to devDependencies - Update all example package.json scripts to use cross-env for INPUT and NODE_ENV - Enable examples:build on Windows in CI (no longer Unix-only) - Add examples:build to WSL CI job 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * chore: remove unused imports in setup-bun.mjs Address github-code-quality bot comments. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: use run-bun.mjs wrapper for prepare hook compatibility During npm install's prepare hook, node_modules/.bin is not in PATH, so calling 'bun' directly fails. The new run-bun.mjs wrapper finds bun at node_modules/.bin/bun and runs it with the correct path. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: restore setup-bun action for build jobs - Add setup-bun action to build and test-git-install jobs - Disable Windows ARM64 (Bun doesn't support this platform) - Add bun installation to WSL build 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: remove bun devDep, add libc detection for Linux ARM64 - Remove 'bun' from devDependencies (its postinstall fails on Windows ARM64) - Add libc detection (glibc vs musl) to setup-bun.mjs - Only try compatible binaries based on detected libc - Re-enable Windows ARM64 in CI (now uses x64 emulation fallback) - Remove setup-bun action from CI (no longer needed) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: simplify WSL build - let setup-bun.mjs handle bun installation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
1 parent ce95bb2 commit 9748622

File tree

17 files changed

+555
-158
lines changed

17 files changed

+555
-158
lines changed

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
# Force LF line endings for all text files (for consistent prettier formatting)
2+
* text=auto eol=lf
3+
14
package-lock.json linguist-generated=true
25
src/generated/** linguist-generated=true

.github/workflows/ci.yml

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,43 @@ permissions:
1111

1212
jobs:
1313
build:
14-
runs-on: ubuntu-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
include:
18+
- os: ubuntu-latest
19+
name: Linux x64
20+
- os: ubuntu-24.04-arm
21+
name: Linux ARM64
22+
- os: windows-latest
23+
name: Windows x64
24+
- os: windows-11-arm
25+
name: Windows ARM64
26+
- os: macos-latest
27+
name: macOS ARM64
28+
29+
name: Build (${{ matrix.name }})
30+
runs-on: ${{ matrix.os }}
31+
1532
steps:
1633
- uses: actions/checkout@v4
1734

1835
- name: Verify no private URLs in package-lock.json
36+
shell: bash
1937
run: '! grep -E "\"resolved\": \"https?://" package-lock.json | grep -v registry.npmjs.org'
2038

21-
- uses: oven-sh/setup-bun@v2
22-
with:
23-
bun-version: latest
24-
2539
- uses: actions/setup-node@v4
2640
with:
2741
node-version: "20"
2842

2943
- run: npm install
3044

31-
- run: npm run build:all
45+
- run: npm run build
46+
47+
- run: npm run examples:build
3248

3349
- name: Verify generated schemas are up-to-date
50+
shell: bash
3451
run: |
3552
npm run generate:schemas
3653
git diff --exit-code src/generated/ || (echo "Generated schemas are out of date. Run 'npm run generate:schemas' and commit." && exit 1)
@@ -67,3 +84,67 @@ jobs:
6784
name: test-results
6885
path: test-results/
6986
retention-days: 7
87+
88+
# Test build in Windows WSL (Ubuntu)
89+
build-wsl:
90+
name: Build (Windows WSL)
91+
runs-on: windows-latest
92+
93+
steps:
94+
- uses: actions/checkout@v4
95+
96+
- uses: Vampire/setup-wsl@v5
97+
with:
98+
distribution: Ubuntu-24.04
99+
100+
- name: Install Node.js in WSL
101+
shell: wsl-bash {0}
102+
run: |
103+
sudo apt-get update
104+
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
105+
sudo apt-get install -y nodejs
106+
107+
- name: Build and test in WSL
108+
shell: wsl-bash {0}
109+
run: |
110+
npm install
111+
npm run build
112+
npm run examples:build
113+
npm test
114+
npm run prettier
115+
116+
# Test that the package can be installed from git (triggers prepare script)
117+
test-git-install:
118+
strategy:
119+
fail-fast: false
120+
matrix:
121+
include:
122+
- os: ubuntu-latest
123+
name: Linux x64
124+
- os: ubuntu-24.04-arm
125+
name: Linux ARM64
126+
- os: windows-latest
127+
name: Windows x64
128+
- os: windows-11-arm
129+
name: Windows ARM64
130+
- os: macos-latest
131+
name: macOS ARM64
132+
133+
name: Test git install (${{ matrix.name }})
134+
runs-on: ${{ matrix.os }}
135+
136+
steps:
137+
- uses: actions/setup-node@v4
138+
with:
139+
node-version: "20"
140+
141+
- name: Create test project and install from git
142+
shell: bash
143+
run: |
144+
mkdir test-project
145+
cd test-project
146+
npm init -y
147+
# Install from the PR branch
148+
npm install "git+https://github.com/${{ github.repository }}#${{ github.head_ref || github.ref_name }}"
149+
# Verify the package is usable (ESM import)
150+
node --input-type=module -e "import { App } from '@modelcontextprotocol/ext-apps'; console.log('Import successful:', typeof App)"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ The [`examples/`](https://github.com/modelcontextprotocol/ext-apps/tree/main/exa
5555

5656
To run all examples together:
5757

58-
```
58+
```bash
5959
npm install
6060
npm run examples:start
6161
```

examples/basic-host/package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
"version": "1.0.0",
55
"type": "module",
66
"scripts": {
7-
"build": "concurrently 'INPUT=index.html vite build' 'INPUT=sandbox.html vite build'",
8-
"watch": "concurrently 'INPUT=index.html vite build --watch' 'INPUT=sandbox.html vite build --watch'",
7+
"build": "concurrently \"cross-env INPUT=index.html vite build\" \"cross-env INPUT=sandbox.html vite build\"",
8+
"watch": "concurrently \"cross-env INPUT=index.html vite build --watch\" \"cross-env INPUT=sandbox.html vite build --watch\"",
99
"serve": "bun serve.ts",
10-
"start": "NODE_ENV=development npm run build && npm run serve",
11-
"dev": "NODE_ENV=development concurrently 'npm run watch' 'npm run serve'"
10+
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
11+
"dev": "cross-env NODE_ENV=development concurrently \"npm run watch\" \"npm run serve\""
1212
},
1313
"dependencies": {
1414
"@modelcontextprotocol/ext-apps": "../..",
@@ -23,7 +23,6 @@
2323
"@types/react": "^19.2.2",
2424
"@types/react-dom": "^19.2.2",
2525
"@vitejs/plugin-react": "^4.3.4",
26-
"bun": "^1.3.2",
2726
"concurrently": "^9.2.1",
2827
"cors": "^2.8.5",
2928
"express": "^5.1.0",

examples/basic-server-react/package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"build": "INPUT=mcp-app.html vite build",
8-
"watch": "INPUT=mcp-app.html vite build --watch",
7+
"build": "cross-env INPUT=mcp-app.html vite build",
8+
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
99
"serve": "bun server.ts",
10-
"start": "NODE_ENV=development npm run build && npm run serve",
11-
"dev": "NODE_ENV=development concurrently 'npm run watch' 'npm run serve'"
10+
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
11+
"dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'"
1212
},
1313
"dependencies": {
1414
"@modelcontextprotocol/ext-apps": "../..",
@@ -24,7 +24,6 @@
2424
"@types/react": "^19.2.2",
2525
"@types/react-dom": "^19.2.2",
2626
"@vitejs/plugin-react": "^4.3.4",
27-
"bun": "^1.3.2",
2827
"concurrently": "^9.2.1",
2928
"cors": "^2.8.5",
3029
"express": "^5.1.0",

examples/basic-server-vanillajs/package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"build": "INPUT=mcp-app.html vite build",
8-
"watch": "INPUT=mcp-app.html vite build --watch",
7+
"build": "cross-env INPUT=mcp-app.html vite build",
8+
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
99
"serve": "bun server.ts",
10-
"start": "NODE_ENV=development npm run build && npm run serve",
11-
"dev": "NODE_ENV=development concurrently 'npm run watch' 'npm run serve'"
10+
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
11+
"dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'"
1212
},
1313
"dependencies": {
1414
"@modelcontextprotocol/ext-apps": "../..",
@@ -19,7 +19,6 @@
1919
"@types/cors": "^2.8.19",
2020
"@types/express": "^5.0.0",
2121
"@types/node": "^22.0.0",
22-
"bun": "^1.3.2",
2322
"concurrently": "^9.2.1",
2423
"cors": "^2.8.5",
2524
"express": "^5.1.0",

examples/budget-allocator-server/package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"build": "INPUT=mcp-app.html vite build",
8-
"watch": "INPUT=mcp-app.html vite build --watch",
7+
"build": "cross-env INPUT=mcp-app.html vite build",
8+
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
99
"serve:http": "bun server.ts",
1010
"serve:stdio": "bun server.ts --stdio",
1111
"start": "npm run start:http",
12-
"start:http": "NODE_ENV=development npm run build && npm run serve:http",
13-
"start:stdio": "NODE_ENV=development npm run build && npm run serve:stdio",
14-
"dev": "NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'"
12+
"start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http",
13+
"start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio",
14+
"dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'"
1515
},
1616
"dependencies": {
1717
"@modelcontextprotocol/ext-apps": "../..",
@@ -23,7 +23,6 @@
2323
"@types/cors": "^2.8.19",
2424
"@types/express": "^5.0.0",
2525
"@types/node": "^22.0.0",
26-
"bun": "^1.3.2",
2726
"concurrently": "^9.2.1",
2827
"cors": "^2.8.5",
2928
"express": "^5.1.0",

examples/cohort-heatmap-server/package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"build": "INPUT=mcp-app.html vite build",
8-
"watch": "INPUT=mcp-app.html vite build --watch",
7+
"build": "cross-env INPUT=mcp-app.html vite build",
8+
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
99
"serve:http": "bun server.ts",
1010
"serve:stdio": "bun server.ts --stdio",
1111
"start": "npm run start:http",
12-
"start:http": "NODE_ENV=development npm run build && npm run serve:http",
13-
"start:stdio": "NODE_ENV=development npm run build && npm run serve:stdio",
14-
"dev": "NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'"
12+
"start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http",
13+
"start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio",
14+
"dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'"
1515
},
1616
"dependencies": {
1717
"@modelcontextprotocol/ext-apps": "../..",
@@ -27,7 +27,6 @@
2727
"@types/react": "^19.2.2",
2828
"@types/react-dom": "^19.2.2",
2929
"@vitejs/plugin-react": "^4.3.4",
30-
"bun": "^1.3.2",
3130
"concurrently": "^9.2.1",
3231
"cors": "^2.8.5",
3332
"express": "^5.1.0",

examples/customer-segmentation-server/package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"build": "INPUT=mcp-app.html vite build",
8-
"watch": "INPUT=mcp-app.html vite build --watch",
7+
"build": "cross-env INPUT=mcp-app.html vite build",
8+
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
99
"serve:http": "bun server.ts",
1010
"serve:stdio": "bun server.ts --stdio",
1111
"start": "npm run start:http",
12-
"start:http": "NODE_ENV=development npm run build && npm run serve:http",
13-
"start:stdio": "NODE_ENV=development npm run build && npm run serve:stdio",
14-
"dev": "NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'"
12+
"start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http",
13+
"start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio",
14+
"dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'"
1515
},
1616
"dependencies": {
1717
"@modelcontextprotocol/ext-apps": "../..",
@@ -23,7 +23,6 @@
2323
"@types/cors": "^2.8.19",
2424
"@types/express": "^5.0.0",
2525
"@types/node": "^22.0.0",
26-
"bun": "^1.3.2",
2726
"concurrently": "^9.2.1",
2827
"cors": "^2.8.5",
2928
"express": "^5.1.0",

examples/scenario-modeler-server/package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"build": "INPUT=mcp-app.html vite build",
8-
"watch": "INPUT=mcp-app.html vite build --watch",
7+
"build": "cross-env INPUT=mcp-app.html vite build",
8+
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
99
"serve:http": "bun server.ts",
1010
"serve:stdio": "bun server.ts --stdio",
1111
"start": "npm run start:http",
12-
"start:http": "NODE_ENV=development npm run build && npm run serve:http",
13-
"start:stdio": "NODE_ENV=development npm run build && npm run serve:stdio",
14-
"dev": "NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'"
12+
"start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http",
13+
"start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio",
14+
"dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'"
1515
},
1616
"dependencies": {
1717
"@modelcontextprotocol/ext-apps": "../..",
@@ -28,7 +28,6 @@
2828
"@types/react": "^19.2.2",
2929
"@types/react-dom": "^19.2.2",
3030
"@vitejs/plugin-react": "^4.3.4",
31-
"bun": "^1.3.2",
3231
"concurrently": "^9.2.1",
3332
"cors": "^2.8.5",
3433
"express": "^5.1.0",

0 commit comments

Comments
 (0)