Skip to content

Commit 2fa1e87

Browse files
committed
feat: add Windows (NSIS) build support
1 parent b15dced commit 2fa1e87

4 files changed

Lines changed: 59 additions & 4 deletions

File tree

.github/workflows/build.yml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,40 @@ jobs:
7373
path: release/*.dmg
7474
retention-days: 30
7575

76+
build-windows:
77+
runs-on: windows-latest
78+
steps:
79+
- uses: actions/checkout@v4
80+
81+
- uses: oven-sh/setup-bun@v2
82+
with:
83+
bun-version: latest
84+
85+
- name: Install dependencies
86+
run: bun install --frozen-lockfile
87+
88+
- name: Lint
89+
run: bun run lint:check
90+
91+
- name: Typecheck
92+
run: bun run typecheck
93+
94+
- name: Build frontend
95+
run: bun run build
96+
97+
- name: Package .exe (NSIS)
98+
run: bunx electron-builder --win nsis --publish never
99+
100+
- name: Upload .exe artifact
101+
uses: actions/upload-artifact@v4
102+
with:
103+
name: windows-nsis
104+
path: release/*.exe
105+
retention-days: 30
106+
76107
release:
77108
if: startsWith(github.ref, 'refs/tags/v')
78-
needs: [build-linux, build-mac]
109+
needs: [build-linux, build-mac, build-windows]
79110
runs-on: ubuntu-latest
80111
permissions:
81112
contents: write
@@ -93,3 +124,4 @@ jobs:
93124
artifacts/linux-deb/*.deb
94125
artifacts/mac-dmg-x64/*.dmg
95126
artifacts/mac-dmg-arm64/*.dmg
127+
artifacts/windows-nsis/*.exe

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ OpenGUI wraps the OpenCode server in an Electron shell with a React frontend, gi
3636
- **Syntax highlighting** - code blocks rendered with shiki, theme-aware
3737
- **Math rendering** - LaTeX/KaTeX support in assistant responses
3838
- **Dark/light theme** - system-aware with manual toggle
39-
- **Cross-platform** - builds for Linux (.deb) and macOS (.dmg)
39+
- **Cross-platform** - builds for Linux (.deb), macOS (.dmg), and Windows (.exe NSIS installer)
4040

4141
## Prerequisites
4242

@@ -96,6 +96,16 @@ Build a `.dmg` installer (macOS):
9696
bun run dist:mac
9797
```
9898

99+
Build a `.exe` installer (Windows):
100+
101+
```bash
102+
bun run dist:win
103+
```
104+
105+
> **Windows prerequisite**: The [OpenCode CLI](https://opencode.ai) must be installed and available on your PATH (or at `%USERPROFILE%\.opencode\bin\opencode.exe`). OpenGUI does not bundle the CLI.
106+
107+
> **Note**: Windows builds are unsigned. Windows SmartScreen will warn on first launch - click "More info" then "Run anyway".
108+
99109
## Architecture
100110

101111
```

package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
"dist": "bunx electron-builder --linux deb",
2121
"dist:mac": "bunx electron-builder --mac dmg",
2222
"dist:mac:arm64": "bunx electron-builder --mac dmg --arm64",
23+
"dist:win": "bunx electron-builder --win nsis",
24+
"dist:win:portable": "bunx electron-builder --win portable",
2325
"typecheck": "bunx tsc --noEmit",
2426
"lint": "bunx --bun biome check --write",
2527
"lint:check": "bunx --bun biome check",
@@ -46,6 +48,17 @@
4648
"dmg": {
4749
"icon": "assets/icon.icns"
4850
},
51+
"win": {
52+
"target": "nsis",
53+
"icon": "assets/icon.png"
54+
},
55+
"nsis": {
56+
"oneClick": false,
57+
"allowToChangeInstallationDirectory": true,
58+
"createDesktopShortcut": true,
59+
"createStartMenuShortcut": true,
60+
"shortcutName": "OpenGUI"
61+
},
4962
"files": [
5063
"dist/**/*",
5164
"!dist/**/*.map",

src/lib/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ export function getPrimaryAgents(agents: Agent[]): Agent[] {
6666
});
6767
}
6868

69-
/** Extract the trailing directory name from an absolute path. */
69+
/** Extract the trailing directory name from an absolute path (cross-platform). */
7070
export function getProjectName(directory: string, fallback = "repo"): string {
71-
const parts = directory.replace(/\/+$/, "").split("/");
71+
const parts = directory.replace(/[/\\]+$/, "").split(/[/\\]/);
7272
return parts[parts.length - 1] || fallback;
7373
}
7474

0 commit comments

Comments
 (0)