-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwindows-dark-title-bar.patch
More file actions
363 lines (334 loc) · 14 KB
/
windows-dark-title-bar.patch
File metadata and controls
363 lines (334 loc) · 14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
diff --git BUILD_WINDOWS.md BUILD_WINDOWS.md
index fdd4ee8..910231f 100644
--- BUILD_WINDOWS.md
+++ BUILD_WINDOWS.md
@@ -1,37 +1,119 @@
# Building 1Code for Windows
-## Issue: Cross-Compilation Limitation
-
-Building Windows packages from Linux/WSL is not supported because the project uses native modules (`better-sqlite3` and `node-pty`) that require platform-specific compilation.
+## Quick Build Process
-## Solutions
-
-### Option 1: Build on Windows (Recommended)
+### Step-by-Step Build Instructions
-1. **Clone the repository on Windows:**
+1. **Clone the repository:**
```powershell
git clone https://github.com/21st-dev/1code.git
cd 1code
```
-2. **Install Bun on Windows:**
- - Download from: https://bun.sh/
- - Or use: `powershell -c "irm bun.sh/install.ps1 | iex"`
+2. **Install Bun (if not installed):**
+ ```powershell
+ powershell -c "irm bun.sh/install.ps1 | iex"
+ ```
3. **Install dependencies:**
```powershell
- bun install
+ bun install --ignore-scripts
```
+ > **Note:** Using `--ignore-scripts` skips native module compilation, which requires Visual Studio Build Tools. The pre-built modules will be used instead.
-4. **Build the app:**
+4. **Download Claude binary (required for agent functionality):**
+ ```powershell
+ bun run claude:download
+ ```
+
+5. **Build the application:**
```powershell
bun run build
+ ```
+ This compiles TypeScript and creates the `out/` directory with:
+ - `out/main/index.js` - Main Electron process
+ - `out/renderer/` - UI application files
+ - `out/preload/index.js` - Preload scripts
+
+ **Note:** This step only compiles the source code. It does NOT create a new executable.
+
+6. **Package the application (REQUIRED to create executable):**
+ ```powershell
+ bun run package
+ ```
+ This creates an unpacked version in `release/win-unpacked/` with `1Code.exe`.
+
+ **IMPORTANT:** After making code changes, you MUST run BOTH `build` AND `package`:
+ - `build` compiles your changes to JavaScript
+ - `package` creates the actual executable with your changes
+ - The `1Code.exe` file timestamp only updates after running `package`
+
+ Or for a portable zip:
+ ```powershell
bun run package:win
```
-5. **Output location:**
- - Windows installer (NSIS): `release/1Code Setup 0.0.14.exe`
- - Portable version: `release/1Code-0.0.14-win.zip`
+## How 1Code.exe is Created
+
+The `1Code.exe` executable is generated by **electron-builder** during the packaging step. Here's the process:
+
+1. **Source Compilation** (`bun run build`):
+ - TypeScript files are compiled to JavaScript
+ - React/UI code is bundled and optimized
+ - Output goes to `out/` directory
+ - **This does NOT create the executable** - it only compiles source code
+
+2. **Packaging** (`bun run package`):
+ - **This is the step that creates `1Code.exe`**
+ - **The executable file timestamp only updates after this step**
+ - `electron-builder` reads configuration from `package.json`:
+ - `"productName": "1Code"` - Application name
+ - `"executableName": "1Code"` - Executable filename
+ - `"appId": "dev.21st.agents"` - Application identifier
+ - Electron-builder bundles:
+ - Electron runtime (Chromium + Node.js)
+ - Your compiled code from `out/main/index.js` (main process)
+ - Your UI from `out/renderer/` (renderer process)
+ - All dependencies and native modules
+ - Resources (Claude binary, migrations, icons)
+ - Creates `1Code.exe` in `release/win-unpacked/`
+
+3. **What's Inside 1Code.exe:**
+ - Electron runtime (Chromium browser engine + Node.js)
+ - Your application code (packaged in `app.asar`)
+ - Native modules (`better-sqlite3`, `node-pty`) - unpacked from `asar`
+ - All required DLLs and resources
+ - Claude binary in `resources/bin/claude.exe`
+
+The executable is a self-contained application that doesn't require installation - you can run it directly from `release/win-unpacked/1Code.exe`.
+
+## Output Locations
+
+- **Unpacked version:** `release/win-unpacked/1Code.exe`
+- **Portable zip:** `release/1Code-0.0.19-win.zip` (when using `bun run package:win`)
+
+## Building Without Visual Studio Build Tools
+
+The project can be built **without** Visual Studio Build Tools by:
+
+1. Setting `"npmRebuild": false` in `package.json` (already configured)
+2. Using `bun install --ignore-scripts` to skip postinstall native module compilation
+3. Relying on pre-built native modules that come with the packages
+
+This works because:
+- `better-sqlite3` includes pre-built binaries for Windows
+- `node-pty` includes prebuilds for Windows
+- Electron-builder unpacks these modules during packaging
+
+## Issue: Cross-Compilation Limitation
+
+Building Windows packages from Linux/WSL is not supported because the project uses native modules (`better-sqlite3` and `node-pty`) that require platform-specific compilation.
+
+## Alternative Solutions
+
+### Option 1: Build on Windows (Recommended)
+
+Follow the steps above on a Windows machine.
### Option 2: Use GitHub Actions / CI/CD
@@ -73,17 +155,23 @@ If you're on WSL2, you can:
2. Copy the built source code to Windows
3. Run the build commands in Windows PowerShell
-## Current Status
+## Troubleshooting
+
+### Native Module Issues
-✅ **Source code compiled** - The TypeScript has been built successfully
-❌ **Windows packaging failed** - Native modules need Windows build environment
+If you encounter errors about missing native modules:
+- Ensure `"npmRebuild": false` is set in `package.json`
+- Use `bun install --ignore-scripts` to skip compilation
+- The pre-built modules should work without Visual Studio Build Tools
-## Next Steps
+### Build Configuration
-1. **Transfer to Windows machine** or use CI/CD
-2. **Run `bun run package:win`** on Windows
-3. **Find installer** in `release/` directory
+The build configuration is in `package.json` under the `"build"` section:
+- Windows target: `"portable"` (creates unpacked directory)
+- Icon: `build/icon.ico`
+- Output: `release/` directory
+- Native modules are unpacked from asar: `better-sqlite3`, `node-pty`, `@anthropic-ai/claude-agent-sdk`
---
-**Note:** The built source code is in `/root/github-repos/1code/out/` and can be transferred to Windows for packaging.
+**Note:** The built application is self-contained and can be distributed by copying the entire `release/win-unpacked/` directory.
diff --git CLAUDE.md CLAUDE.md
index 24a633f..266ef04 100644
--- CLAUDE.md
+++ CLAUDE.md
@@ -13,17 +13,23 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
bun run dev # Start Electron with hot reload
# Build
-bun run build # Compile app
-bun run package # Package for current platform (dir)
+bun run build # Compile app (TypeScript → JavaScript, bundles React)
+bun run package # Package for current platform (dir) - CREATES EXECUTABLE
bun run package:mac # Build macOS (DMG + ZIP)
bun run package:win # Build Windows (NSIS + portable)
-bun run package:linux # Build Linux (AppImage + DEB)
+bun run package:linux # Build Linux (AppImage + DEB)
# Database (Drizzle + SQLite)
bun run db:generate # Generate migrations from schema
bun run db:push # Push schema directly (dev only)
```
+**IMPORTANT: After making code changes, you MUST run BOTH commands to get a new executable:**
+1. `bun run build` - Compiles source code to `out/` directory
+2. `bun run package` - Creates the executable (`1Code.exe` on Windows) in `release/win-unpacked/`
+
+**The executable timestamp only updates after running `package`.** Running only `build` compiles the code but doesn't create a new executable.
+
## Architecture
```
@@ -181,12 +187,14 @@ export APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx" # App-specific passwor
bun run release
# Or step by step:
-bun run build # Compile TypeScript
-bun run package:mac # Build, sign & notarize macOS app
+bun run build # Compile TypeScript (creates out/ directory)
+bun run package:mac # Build, sign & notarize macOS app (creates executable)
bun run dist:manifest # Generate latest-mac.yml manifests
./scripts/upload-release-wrangler.sh # Upload to R2 CDN
```
+**Note:** Always run both `build` and `package` commands. `build` compiles source code, `package` creates the executable.
+
### Bump Version Before Release
```bash
diff --git package.json package.json
index 7281d93..9c77fdb 100644
--- package.json
+++ package.json
@@ -122,7 +122,7 @@
"build": {
"appId": "dev.21st.agents",
"productName": "1Code",
- "npmRebuild": true,
+ "npmRebuild": false,
"win": {
"target": [
"portable"
@@ -213,14 +213,6 @@
],
"iconSize": 80
},
- "win": {
- "target": [
- "portable"
- ],
- "icon": "build/icon.ico",
- "sign": null,
- "executableName": "1Code"
- },
"linux": {
"target": [
"AppImage",
diff --git src/main/windows/main.ts src/main/windows/main.ts
index d593867..40679e5 100644
--- src/main/windows/main.ts
+++ src/main/windows/main.ts
@@ -63,6 +63,7 @@ function registerIpcHandlers(getWindow: () => BrowserWindow | null): void {
"window:is-fullscreen",
() => getWindow()?.isFullScreen() ?? false,
)
+ // Window theme handler removed - using frameless window on Windows with custom title bar
// Traffic light visibility control (for hybrid native/custom approach)
ipcMain.handle(
@@ -245,6 +246,11 @@ export function createMainWindow(): BrowserWindow {
titleBarStyle: process.platform === "darwin" ? "hiddenInset" : "default",
trafficLightPosition:
process.platform === "darwin" ? { x: 15, y: 12 } : undefined,
+ // Windows: Use frameless window to hide native title bar completely
+ ...(process.platform === "win32" && {
+ frame: false, // Remove native title bar
+ autoHideMenuBar: true, // Hide menu bar (user can press Alt to show)
+ }),
webPreferences: {
preload: join(__dirname, "../preload/index.js"),
nodeIntegration: false,
@@ -280,6 +286,7 @@ export function createMainWindow(): BrowserWindow {
if (process.platform === "darwin") {
window.setWindowButtonVisibility(true)
}
+ // Windows: frameless window, no title bar overlay needed
window.show()
})
@@ -355,7 +362,10 @@ export function createMainWindow(): BrowserWindow {
if (process.platform === "darwin") {
window.setWindowButtonVisibility(true)
}
+ // Windows: frameless window, custom title bar in renderer
})
+
+ // Windows: frameless window, custom title bar in renderer handles theme
window.webContents.on(
"did-fail-load",
(_event, errorCode, errorDescription) => {
diff --git src/preload/index.ts src/preload/index.ts
index ec8ee8d..68a81c0 100644
--- src/preload/index.ts
+++ src/preload/index.ts
@@ -74,6 +74,7 @@ contextBridge.exposeInMainWorld("desktopApi", {
windowIsFullscreen: () => ipcRenderer.invoke("window:is-fullscreen"),
setTrafficLightVisibility: (visible: boolean) =>
ipcRenderer.invoke("window:set-traffic-light-visibility", visible),
+ setWindowTheme: (isDark: boolean) => ipcRenderer.invoke("window:set-theme", isDark),
// Window events
onFullscreenChange: (callback: (isFullscreen: boolean) => void) => {
@@ -183,6 +184,7 @@ export interface DesktopApi {
windowToggleFullscreen: () => Promise<void>
windowIsFullscreen: () => Promise<boolean>
setTrafficLightVisibility: (visible: boolean) => Promise<void>
+ setWindowTheme: (isDark: boolean) => Promise<void>
onFullscreenChange: (callback: (isFullscreen: boolean) => void) => () => void
onFocusChange: (callback: (isFocused: boolean) => void) => () => void
zoomIn: () => Promise<void>
diff --git src/renderer/features/layout/agents-layout.tsx src/renderer/features/layout/agents-layout.tsx
index 7a94c48..c30f97c 100644
--- src/renderer/features/layout/agents-layout.tsx
+++ src/renderer/features/layout/agents-layout.tsx
@@ -24,6 +24,7 @@ import { ResizableSidebar } from "../../components/ui/resizable-sidebar"
import { AgentsSidebar } from "../sidebar/agents-sidebar"
import { AgentsContent } from "../agents/ui/agents-content"
import { UpdateBanner } from "../../components/update-banner"
+import { WindowsTitleBar } from "../../components/windows-title-bar"
import { useUpdateChecker } from "../../lib/hooks/use-update-checker"
import { useAgentSubChatStore } from "../../lib/stores/sub-chat-store"
@@ -223,8 +224,11 @@ export function AgentsLayout() {
onClose={() => setShortcutsOpen(false)}
/>
<ClaudeLoginModal />
- <div className="flex w-full h-full relative overflow-hidden bg-background select-none">
- {/* Left Sidebar (Agents) */}
+ <div className="flex flex-col w-full h-full relative overflow-hidden bg-background select-none">
+ {/* Windows Title Bar (only on Windows) */}
+ <WindowsTitleBar />
+ <div className="flex flex-1 overflow-hidden">
+ {/* Left Sidebar (Agents) */}
<ResizableSidebar
isOpen={!isMobile && sidebarOpen}
onClose={handleCloseSidebar}
@@ -247,9 +251,10 @@ export function AgentsLayout() {
/>
</ResizableSidebar>
- {/* Main Content */}
- <div className="flex-1 overflow-hidden flex flex-col min-w-0">
- <AgentsContent />
+ {/* Main Content */}
+ <div className="flex-1 overflow-hidden flex flex-col min-w-0">
+ <AgentsContent />
+ </div>
</div>
{/* Update Banner */}
diff --git src/renderer/lib/themes/theme-provider.tsx src/renderer/lib/themes/theme-provider.tsx
index d6781fa..acf8269 100644
--- src/renderer/lib/themes/theme-provider.tsx
+++ src/renderer/lib/themes/theme-provider.tsx
@@ -208,6 +208,8 @@ export function VSCodeThemeProvider({ children }: VSCodeThemeProviderProps) {
removeCSSVariables()
}
}, [fullThemeData, selectedThemeId, setNextTheme])
+
+ // Windows: Using frameless window with custom title bar, no theme sync needed
// Get terminal theme
const terminalTheme = useMemo((): ITheme => {