@neurocode-ai/desktop 1.18.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/AGENTS.md +4 -0
  2. package/README.md +19 -0
  3. package/electron-builder.config.test.ts +48 -0
  4. package/electron-builder.config.ts +146 -0
  5. package/electron.vite.config.ts +106 -0
  6. package/icons/README.md +14 -0
  7. package/icons/beta/128x128.png +0 -0
  8. package/icons/beta/128x128@2x.png +0 -0
  9. package/icons/beta/32x32.png +0 -0
  10. package/icons/beta/64x64.png +0 -0
  11. package/icons/beta/Square107x107Logo.png +0 -0
  12. package/icons/beta/Square142x142Logo.png +0 -0
  13. package/icons/beta/Square150x150Logo.png +0 -0
  14. package/icons/beta/Square284x284Logo.png +0 -0
  15. package/icons/beta/Square30x30Logo.png +0 -0
  16. package/icons/beta/Square310x310Logo.png +0 -0
  17. package/icons/beta/Square44x44Logo.png +0 -0
  18. package/icons/beta/Square71x71Logo.png +0 -0
  19. package/icons/beta/Square89x89Logo.png +0 -0
  20. package/icons/beta/StoreLogo.png +0 -0
  21. package/icons/beta/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  22. package/icons/beta/android/mipmap-hdpi/ic_launcher.png +0 -0
  23. package/icons/beta/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  24. package/icons/beta/android/mipmap-hdpi/ic_launcher_round.png +0 -0
  25. package/icons/beta/android/mipmap-mdpi/ic_launcher.png +0 -0
  26. package/icons/beta/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  27. package/icons/beta/android/mipmap-mdpi/ic_launcher_round.png +0 -0
  28. package/icons/beta/android/mipmap-xhdpi/ic_launcher.png +0 -0
  29. package/icons/beta/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  30. package/icons/beta/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
  31. package/icons/beta/android/mipmap-xxhdpi/ic_launcher.png +0 -0
  32. package/icons/beta/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  33. package/icons/beta/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  34. package/icons/beta/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
  35. package/icons/beta/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  36. package/icons/beta/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  37. package/icons/beta/android/values/ic_launcher_background.xml +4 -0
  38. package/icons/beta/dock.png +0 -0
  39. package/icons/beta/icon.icns +0 -0
  40. package/icons/beta/icon.ico +0 -0
  41. package/icons/beta/icon.png +0 -0
  42. package/icons/beta/ios/AppIcon-20x20@1x.png +0 -0
  43. package/icons/beta/ios/AppIcon-20x20@2x-1.png +0 -0
  44. package/icons/beta/ios/AppIcon-20x20@2x.png +0 -0
  45. package/icons/beta/ios/AppIcon-20x20@3x.png +0 -0
  46. package/icons/beta/ios/AppIcon-29x29@1x.png +0 -0
  47. package/icons/beta/ios/AppIcon-29x29@2x-1.png +0 -0
  48. package/icons/beta/ios/AppIcon-29x29@2x.png +0 -0
  49. package/icons/beta/ios/AppIcon-29x29@3x.png +0 -0
  50. package/icons/beta/ios/AppIcon-40x40@1x.png +0 -0
  51. package/icons/beta/ios/AppIcon-40x40@2x-1.png +0 -0
  52. package/icons/beta/ios/AppIcon-40x40@2x.png +0 -0
  53. package/icons/beta/ios/AppIcon-40x40@3x.png +0 -0
  54. package/icons/beta/ios/AppIcon-512@2x.png +0 -0
  55. package/icons/beta/ios/AppIcon-60x60@2x.png +0 -0
  56. package/icons/beta/ios/AppIcon-60x60@3x.png +0 -0
  57. package/icons/beta/ios/AppIcon-76x76@1x.png +0 -0
  58. package/icons/beta/ios/AppIcon-76x76@2x.png +0 -0
  59. package/icons/beta/ios/AppIcon-83.5x83.5@2x.png +0 -0
  60. package/icons/dev/128x128.png +0 -0
  61. package/icons/dev/128x128@2x.png +0 -0
  62. package/icons/dev/32x32.png +0 -0
  63. package/icons/dev/64x64.png +0 -0
  64. package/icons/dev/Square107x107Logo.png +0 -0
  65. package/icons/dev/Square142x142Logo.png +0 -0
  66. package/icons/dev/Square150x150Logo.png +0 -0
  67. package/icons/dev/Square284x284Logo.png +0 -0
  68. package/icons/dev/Square30x30Logo.png +0 -0
  69. package/icons/dev/Square310x310Logo.png +0 -0
  70. package/icons/dev/Square44x44Logo.png +0 -0
  71. package/icons/dev/Square71x71Logo.png +0 -0
  72. package/icons/dev/Square89x89Logo.png +0 -0
  73. package/icons/dev/StoreLogo.png +0 -0
  74. package/icons/dev/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  75. package/icons/dev/android/mipmap-hdpi/ic_launcher.png +0 -0
  76. package/icons/dev/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  77. package/icons/dev/android/mipmap-hdpi/ic_launcher_round.png +0 -0
  78. package/icons/dev/android/mipmap-mdpi/ic_launcher.png +0 -0
  79. package/icons/dev/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  80. package/icons/dev/android/mipmap-mdpi/ic_launcher_round.png +0 -0
  81. package/icons/dev/android/mipmap-xhdpi/ic_launcher.png +0 -0
  82. package/icons/dev/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  83. package/icons/dev/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
  84. package/icons/dev/android/mipmap-xxhdpi/ic_launcher.png +0 -0
  85. package/icons/dev/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  86. package/icons/dev/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  87. package/icons/dev/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
  88. package/icons/dev/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  89. package/icons/dev/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  90. package/icons/dev/android/values/ic_launcher_background.xml +4 -0
  91. package/icons/dev/dock.png +0 -0
  92. package/icons/dev/icon.icns +0 -0
  93. package/icons/dev/icon.ico +0 -0
  94. package/icons/dev/icon.png +0 -0
  95. package/icons/dev/ios/AppIcon-20x20@1x.png +0 -0
  96. package/icons/dev/ios/AppIcon-20x20@2x-1.png +0 -0
  97. package/icons/dev/ios/AppIcon-20x20@2x.png +0 -0
  98. package/icons/dev/ios/AppIcon-20x20@3x.png +0 -0
  99. package/icons/dev/ios/AppIcon-29x29@1x.png +0 -0
  100. package/icons/dev/ios/AppIcon-29x29@2x-1.png +0 -0
  101. package/icons/dev/ios/AppIcon-29x29@2x.png +0 -0
  102. package/icons/dev/ios/AppIcon-29x29@3x.png +0 -0
  103. package/icons/dev/ios/AppIcon-40x40@1x.png +0 -0
  104. package/icons/dev/ios/AppIcon-40x40@2x-1.png +0 -0
  105. package/icons/dev/ios/AppIcon-40x40@2x.png +0 -0
  106. package/icons/dev/ios/AppIcon-40x40@3x.png +0 -0
  107. package/icons/dev/ios/AppIcon-512@2x.png +0 -0
  108. package/icons/dev/ios/AppIcon-60x60@2x.png +0 -0
  109. package/icons/dev/ios/AppIcon-60x60@3x.png +0 -0
  110. package/icons/dev/ios/AppIcon-76x76@1x.png +0 -0
  111. package/icons/dev/ios/AppIcon-76x76@2x.png +0 -0
  112. package/icons/dev/ios/AppIcon-83.5x83.5@2x.png +0 -0
  113. package/icons/prod/128x128.png +0 -0
  114. package/icons/prod/128x128@2x.png +0 -0
  115. package/icons/prod/32x32.png +0 -0
  116. package/icons/prod/64x64.png +0 -0
  117. package/icons/prod/Square107x107Logo.png +0 -0
  118. package/icons/prod/Square142x142Logo.png +0 -0
  119. package/icons/prod/Square150x150Logo.png +0 -0
  120. package/icons/prod/Square284x284Logo.png +0 -0
  121. package/icons/prod/Square30x30Logo.png +0 -0
  122. package/icons/prod/Square310x310Logo.png +0 -0
  123. package/icons/prod/Square44x44Logo.png +0 -0
  124. package/icons/prod/Square71x71Logo.png +0 -0
  125. package/icons/prod/Square89x89Logo.png +0 -0
  126. package/icons/prod/StoreLogo.png +0 -0
  127. package/icons/prod/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  128. package/icons/prod/android/mipmap-hdpi/ic_launcher.png +0 -0
  129. package/icons/prod/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  130. package/icons/prod/android/mipmap-hdpi/ic_launcher_round.png +0 -0
  131. package/icons/prod/android/mipmap-mdpi/ic_launcher.png +0 -0
  132. package/icons/prod/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  133. package/icons/prod/android/mipmap-mdpi/ic_launcher_round.png +0 -0
  134. package/icons/prod/android/mipmap-xhdpi/ic_launcher.png +0 -0
  135. package/icons/prod/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  136. package/icons/prod/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
  137. package/icons/prod/android/mipmap-xxhdpi/ic_launcher.png +0 -0
  138. package/icons/prod/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  139. package/icons/prod/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  140. package/icons/prod/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
  141. package/icons/prod/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  142. package/icons/prod/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  143. package/icons/prod/android/values/ic_launcher_background.xml +4 -0
  144. package/icons/prod/dock.png +0 -0
  145. package/icons/prod/icon.icns +0 -0
  146. package/icons/prod/icon.ico +0 -0
  147. package/icons/prod/icon.png +0 -0
  148. package/icons/prod/ios/AppIcon-20x20@1x.png +0 -0
  149. package/icons/prod/ios/AppIcon-20x20@2x-1.png +0 -0
  150. package/icons/prod/ios/AppIcon-20x20@2x.png +0 -0
  151. package/icons/prod/ios/AppIcon-20x20@3x.png +0 -0
  152. package/icons/prod/ios/AppIcon-29x29@1x.png +0 -0
  153. package/icons/prod/ios/AppIcon-29x29@2x-1.png +0 -0
  154. package/icons/prod/ios/AppIcon-29x29@2x.png +0 -0
  155. package/icons/prod/ios/AppIcon-29x29@3x.png +0 -0
  156. package/icons/prod/ios/AppIcon-40x40@1x.png +0 -0
  157. package/icons/prod/ios/AppIcon-40x40@2x-1.png +0 -0
  158. package/icons/prod/ios/AppIcon-40x40@2x.png +0 -0
  159. package/icons/prod/ios/AppIcon-40x40@3x.png +0 -0
  160. package/icons/prod/ios/AppIcon-512@2x.png +0 -0
  161. package/icons/prod/ios/AppIcon-60x60@2x.png +0 -0
  162. package/icons/prod/ios/AppIcon-60x60@3x.png +0 -0
  163. package/icons/prod/ios/AppIcon-76x76@1x.png +0 -0
  164. package/icons/prod/ios/AppIcon-76x76@2x.png +0 -0
  165. package/icons/prod/ios/AppIcon-83.5x83.5@2x.png +0 -0
  166. package/package.json +75 -0
  167. package/resources/entitlements.plist +18 -0
  168. package/resources/linux/opencode-desktop.desktop +10 -0
  169. package/scripts/copy-bundles.ts +12 -0
  170. package/scripts/copy-icons.ts +12 -0
  171. package/scripts/copy-metainfo.ts +47 -0
  172. package/scripts/finalize-latest-json.ts +219 -0
  173. package/scripts/finalize-latest-yml.ts +124 -0
  174. package/scripts/prebuild.ts +10 -0
  175. package/scripts/predev.ts +5 -0
  176. package/scripts/prepare.ts +9 -0
  177. package/scripts/utils.ts +77 -0
  178. package/src/main/apps.ts +136 -0
  179. package/src/main/attachment-picker.test.ts +87 -0
  180. package/src/main/attachment-picker.ts +56 -0
  181. package/src/main/constants.ts +7 -0
  182. package/src/main/debug.ts +95 -0
  183. package/src/main/desktop-menu-actions.ts +84 -0
  184. package/src/main/env.d.ts +19 -0
  185. package/src/main/index.test.ts +37 -0
  186. package/src/main/index.ts +399 -0
  187. package/src/main/initialization.ts +6 -0
  188. package/src/main/install-state.test.ts +19 -0
  189. package/src/main/install-state.ts +8 -0
  190. package/src/main/ipc.ts +274 -0
  191. package/src/main/logging.ts +205 -0
  192. package/src/main/markdown.ts +16 -0
  193. package/src/main/menu.ts +67 -0
  194. package/src/main/migrate.ts +91 -0
  195. package/src/main/onboarding.ts +45 -0
  196. package/src/main/server.ts +238 -0
  197. package/src/main/shell-env.test.ts +50 -0
  198. package/src/main/shell-env.ts +101 -0
  199. package/src/main/sidecar.ts +157 -0
  200. package/src/main/store-cleanup.test.ts +93 -0
  201. package/src/main/store-cleanup.ts +94 -0
  202. package/src/main/store-keys.ts +7 -0
  203. package/src/main/store.ts +35 -0
  204. package/src/main/unresponsive.ts +70 -0
  205. package/src/main/updater-controller.test.ts +111 -0
  206. package/src/main/updater-controller.ts +97 -0
  207. package/src/main/updater-subscriptions.test.ts +16 -0
  208. package/src/main/updater-subscriptions.ts +20 -0
  209. package/src/main/updater.ts +85 -0
  210. package/src/main/window-registry.test.ts +91 -0
  211. package/src/main/window-registry.ts +47 -0
  212. package/src/main/window-state.ts +29 -0
  213. package/src/main/windows.ts +496 -0
  214. package/src/main/wsl/ipc.ts +103 -0
  215. package/src/main/wsl/policy.ts +33 -0
  216. package/src/main/wsl/runtime.ts +400 -0
  217. package/src/main/wsl/servers.test.ts +231 -0
  218. package/src/main/wsl/servers.ts +521 -0
  219. package/src/main/wsl/sidecar.ts +129 -0
  220. package/src/main/wsl/startup.ts +31 -0
  221. package/src/preload/index.ts +128 -0
  222. package/src/preload/types.ts +109 -0
  223. package/src/renderer/cli.ts +12 -0
  224. package/src/renderer/env.d.ts +10 -0
  225. package/src/renderer/html.test.ts +62 -0
  226. package/src/renderer/i18n/ar.ts +26 -0
  227. package/src/renderer/i18n/br.ts +27 -0
  228. package/src/renderer/i18n/bs.ts +28 -0
  229. package/src/renderer/i18n/da.ts +28 -0
  230. package/src/renderer/i18n/de.ts +28 -0
  231. package/src/renderer/i18n/en.ts +27 -0
  232. package/src/renderer/i18n/es.ts +27 -0
  233. package/src/renderer/i18n/fr.ts +28 -0
  234. package/src/renderer/i18n/index.ts +194 -0
  235. package/src/renderer/i18n/ja.ts +28 -0
  236. package/src/renderer/i18n/ko.ts +27 -0
  237. package/src/renderer/i18n/no.ts +28 -0
  238. package/src/renderer/i18n/pl.ts +28 -0
  239. package/src/renderer/i18n/ru.ts +27 -0
  240. package/src/renderer/i18n/uk.ts +28 -0
  241. package/src/renderer/i18n/zh.ts +26 -0
  242. package/src/renderer/i18n/zht.ts +26 -0
  243. package/src/renderer/index.html +21 -0
  244. package/src/renderer/index.tsx +464 -0
  245. package/src/renderer/initialization.test.ts +73 -0
  246. package/src/renderer/initialization.ts +22 -0
  247. package/src/renderer/onboarding.tsx +53 -0
  248. package/src/renderer/styles.css +0 -0
  249. package/src/renderer/webview-zoom.ts +138 -0
  250. package/src/renderer/wsl/connections.test.ts +43 -0
  251. package/src/renderer/wsl/connections.ts +28 -0
  252. package/sst-env.d.ts +10 -0
  253. package/tsconfig.json +23 -0
package/AGENTS.md ADDED
@@ -0,0 +1,4 @@
1
+ # Desktop package notes
2
+
3
+ - Renderer process should only call `window.api` from `src/preload`.
4
+ - Main process should register IPC handlers in `src/main/ipc.ts`.
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # OpenCode Desktop
2
+
3
+ The OpenCode Desktop app, built with Electron.
4
+
5
+ ## Development
6
+
7
+ ```bash
8
+ bun install
9
+ bun dev
10
+ ```
11
+
12
+ ## Build
13
+
14
+ Run the `build` script to build the app's JS assets, then `package` to
15
+ bundle the assets as an application. The resulting app will be in `dist/`.
16
+
17
+ ```bash
18
+ bun run build && bun run package
19
+ ```
@@ -0,0 +1,48 @@
1
+ import { expect, test } from "bun:test"
2
+ import type { Configuration } from "electron-builder"
3
+
4
+ const legacyDesktopEntry = "resources/linux/neurocode-desktop.desktop"
5
+
6
+ const channels = [
7
+ { channel: "dev", appId: "ai.neurocode.desktop.dev" },
8
+ { channel: "beta", appId: "ai.neurocode.desktop.beta" },
9
+ { channel: "prod", appId: "ai.neurocode.desktop" },
10
+ ] as const
11
+
12
+ for (const channel of channels) {
13
+ test(`uses one Linux desktop identity for ${channel.channel}`, async () => {
14
+ const previous = process.env.NEUROCODE_CHANNEL
15
+ process.env.NEUROCODE_CHANNEL = channel.channel
16
+
17
+ const module = await import(`./electron-builder.config.ts?channel=${channel.channel}`)
18
+ const config = module.default as Configuration
19
+
20
+ if (previous === undefined) delete process.env.NEUROCODE_CHANNEL
21
+ else process.env.NEUROCODE_CHANNEL = previous
22
+
23
+ expect(config.appId).toBe(channel.appId)
24
+ expect(config.extraMetadata?.desktopName).toBe(`${channel.appId}.desktop`)
25
+ expect(config.linux?.executableName).toBe(channel.appId)
26
+ expect(config.linux?.desktop?.entry?.StartupWMClass).toBe(channel.appId)
27
+ })
28
+ }
29
+
30
+ test("keeps a hidden prod launcher for old Linux pins", async () => {
31
+ const previous = process.env.NEUROCODE_CHANNEL
32
+ process.env.NEUROCODE_CHANNEL = "prod"
33
+
34
+ const module = await import("./electron-builder.config.ts?compat=prod")
35
+ const config = module.default as Configuration
36
+
37
+ if (previous === undefined) delete process.env.NEUROCODE_CHANNEL
38
+ else process.env.NEUROCODE_CHANNEL = previous
39
+
40
+ expect(config.deb?.fpm?.[0]).toEndWith(`${legacyDesktopEntry}=/usr/share/applications/neurocode-desktop.desktop`)
41
+ expect(config.rpm?.fpm?.[0]).toEndWith(`${legacyDesktopEntry}=/usr/share/applications/neurocode-desktop.desktop`)
42
+
43
+ const desktop = await Bun.file(legacyDesktopEntry).text()
44
+ expect(desktop).toContain("Exec=/opt/NeuroCode/ai.neurocode.desktop %U")
45
+ expect(desktop).toContain("Icon=ai.neurocode.desktop")
46
+ expect(desktop).toContain("StartupWMClass=ai.neurocode.desktop")
47
+ expect(desktop).toContain("NoDisplay=true")
48
+ })
@@ -0,0 +1,146 @@
1
+ import { execFile } from "node:child_process"
2
+ import path from "node:path"
3
+ import { fileURLToPath } from "node:url"
4
+ import { promisify } from "node:util"
5
+
6
+ import type { Configuration } from "electron-builder"
7
+
8
+ const execFileAsync = promisify(execFile)
9
+ const packageDir = path.dirname(fileURLToPath(import.meta.url))
10
+ const rootDir = path.resolve(packageDir, "../..")
11
+ const signScript = path.join(rootDir, "script", "sign-windows.ps1")
12
+ // The Electron 42 packaging update briefly installed Linux launchers/icons under
13
+ // "opencode-desktop". Keep that hidden desktop entry around so existing GNOME/KDE
14
+ // pins still resolve after the canonical app id changes back to ai.opencode.desktop.
15
+ const legacyDesktopEntry = path.join(packageDir, "resources", "linux", "opencode-desktop.desktop")
16
+ const legacyDesktopEntryFpm = `${legacyDesktopEntry}=/usr/share/applications/opencode-desktop.desktop`
17
+
18
+ async function signWindows(configuration: { path: string }) {
19
+ if (process.platform !== "win32") return
20
+ if (process.env.GITHUB_ACTIONS !== "true") return
21
+
22
+ await execFileAsync(
23
+ "pwsh",
24
+ ["-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", signScript, configuration.path],
25
+ { cwd: rootDir },
26
+ )
27
+ }
28
+
29
+ const channel = (() => {
30
+ const raw = process.env.OPENCODE_CHANNEL
31
+ if (raw === "dev" || raw === "beta" || raw === "prod") return raw
32
+ return "dev"
33
+ })()
34
+
35
+ const APP_IDS = {
36
+ dev: "ai.opencode.desktop.dev",
37
+ beta: "ai.opencode.desktop.beta",
38
+ prod: "ai.opencode.desktop",
39
+ } as const
40
+
41
+ const getBase = (appId: string): Configuration => ({
42
+ artifactName: "opencode-desktop-${os}-${arch}.${ext}",
43
+ directories: {
44
+ output: "dist",
45
+ buildResources: "resources",
46
+ },
47
+ // Linux launchers are .desktop files, so this is the desktop file name,
48
+ // not just the app id. For prod, app id "ai.opencode.desktop" becomes
49
+ // "ai.opencode.desktop.desktop".
50
+ // https://developer.gnome.org/documentation/guidelines/maintainer/integrating.html
51
+ // https://www.electron.build/docs/linux/
52
+ extraMetadata: {
53
+ desktopName: `${appId}.desktop`,
54
+ },
55
+ files: ["out/**/*", "resources/**/*"],
56
+ extraResources: [
57
+ {
58
+ from: "native/",
59
+ to: "native/",
60
+ filter: ["index.js", "index.d.ts", "build/Release/mac_window.node", "swift-build/**"],
61
+ },
62
+ ],
63
+ mac: {
64
+ category: "public.app-category.developer-tools",
65
+ icon: `resources/icons/icon.icns`,
66
+ hardenedRuntime: true,
67
+ gatekeeperAssess: false,
68
+ entitlements: "resources/entitlements.plist",
69
+ entitlementsInherit: "resources/entitlements.plist",
70
+ notarize: true,
71
+ target: ["dmg", "zip"],
72
+ },
73
+ dmg: {
74
+ sign: true,
75
+ },
76
+ protocols: {
77
+ name: "OpenCode",
78
+ schemes: ["opencode"],
79
+ },
80
+ win: {
81
+ icon: `resources/icons/icon.ico`,
82
+ signtoolOptions: {
83
+ sign: signWindows,
84
+ },
85
+ target: ["nsis"],
86
+ verifyUpdateCodeSignature: false,
87
+ },
88
+ nsis: {
89
+ oneClick: true,
90
+ perMachine: false,
91
+ installerIcon: `resources/icons/icon.ico`,
92
+ installerHeaderIcon: `resources/icons/icon.ico`,
93
+ },
94
+ linux: {
95
+ icon: `resources/icons`,
96
+ category: "Development",
97
+ executableName: appId,
98
+ desktop: {
99
+ entry: {
100
+ // Match the installed .desktop file and hicolor icon basename so
101
+ // Linux shells can associate the running Electron window with its launcher.
102
+ StartupWMClass: appId,
103
+ },
104
+ },
105
+ target: ["AppImage", "deb", "rpm"],
106
+ },
107
+ })
108
+
109
+ function getConfig() {
110
+ const appId = APP_IDS[channel]
111
+ const base = getBase(appId)
112
+
113
+ switch (channel) {
114
+ case "dev": {
115
+ return {
116
+ ...base,
117
+ appId,
118
+ productName: "OpenCode Dev",
119
+ rpm: { packageName: "opencode-dev" },
120
+ }
121
+ }
122
+ case "beta": {
123
+ return {
124
+ ...base,
125
+ appId,
126
+ productName: "OpenCode Beta",
127
+ protocols: { name: "OpenCode Beta", schemes: ["opencode"] },
128
+ publish: { provider: "github", owner: "anomalyco", repo: "opencode-beta", channel: "latest" },
129
+ rpm: { packageName: "opencode-beta" },
130
+ }
131
+ }
132
+ case "prod": {
133
+ return {
134
+ ...base,
135
+ appId,
136
+ productName: "OpenCode",
137
+ protocols: { name: "OpenCode", schemes: ["opencode"] },
138
+ publish: { provider: "github", owner: "anomalyco", repo: "opencode", channel: "latest" },
139
+ deb: { fpm: [legacyDesktopEntryFpm] },
140
+ rpm: { packageName: "opencode", fpm: [legacyDesktopEntryFpm] },
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ export default getConfig()
@@ -0,0 +1,106 @@
1
+ import { sentryVitePlugin } from "@sentry/vite-plugin"
2
+ import { defineConfig } from "electron-vite"
3
+ import appPlugin from "@neurocode-ai/app/vite"
4
+ import * as fs from "node:fs/promises"
5
+
6
+ const OPENCODE_SERVER_DIST = "../opencode/dist/node"
7
+
8
+ const channel = (() => {
9
+ const raw = process.env.OPENCODE_CHANNEL
10
+ if (raw === "dev" || raw === "beta" || raw === "prod") return raw
11
+ if (process.env.OPENCODE_CHANNEL === "latest") return "prod"
12
+ return "dev"
13
+ })()
14
+
15
+ const nodePtyPkg = `@lydell/node-pty-${process.platform}-${process.arch}`
16
+
17
+ const sentry =
18
+ process.env.SENTRY_AUTH_TOKEN && process.env.SENTRY_ORG && process.env.SENTRY_PROJECT
19
+ ? sentryVitePlugin({
20
+ authToken: process.env.SENTRY_AUTH_TOKEN,
21
+ org: process.env.SENTRY_ORG,
22
+ project: process.env.SENTRY_PROJECT,
23
+ telemetry: false,
24
+ release: {
25
+ name: process.env.SENTRY_RELEASE ?? process.env.VITE_SENTRY_RELEASE,
26
+ },
27
+ sourcemaps: {
28
+ assets: "./out/renderer/**",
29
+ filesToDeleteAfterUpload: "./out/renderer/**/*.map",
30
+ },
31
+ })
32
+ : false
33
+
34
+ export default defineConfig({
35
+ main: {
36
+ define: {
37
+ "import.meta.env.OPENCODE_CHANNEL": JSON.stringify(channel),
38
+ },
39
+ build: {
40
+ rollupOptions: {
41
+ input: { index: "src/main/index.ts", sidecar: "src/main/sidecar.ts" },
42
+ // Keep this identical to electron-vite's Node 20.11+ shim. Its regex insertion can
43
+ // corrupt bundled TypeScript, while a Rollup banner places the shim safely.
44
+ output: {
45
+ banner: `
46
+ // -- CommonJS Shims --
47
+ import __cjs_mod__ from 'node:module';
48
+ const __filename = import.meta.filename;
49
+ const __dirname = import.meta.dirname;
50
+ const require = __cjs_mod__.createRequire(import.meta.url);
51
+ `,
52
+ },
53
+ },
54
+ externalizeDeps: { include: [nodePtyPkg] },
55
+ },
56
+ plugins: [
57
+ {
58
+ name: "opencode:node-pty-narrower",
59
+ enforce: "pre",
60
+ resolveId(s) {
61
+ if (s === "@lydell/node-pty") return nodePtyPkg
62
+ },
63
+ },
64
+ {
65
+ name: "opencode:virtual-server-module",
66
+ enforce: "pre",
67
+ resolveId(id) {
68
+ if (id === "virtual:opencode-server") return this.resolve(`${OPENCODE_SERVER_DIST}/node.js`)
69
+ },
70
+ },
71
+ {
72
+ name: "opencode:copy-server-assets",
73
+ async writeBundle() {
74
+ for (const l of await fs.readdir(OPENCODE_SERVER_DIST)) {
75
+ if (!l.endsWith(".wasm")) continue
76
+ await fs.writeFile(`./out/main/chunks/${l}`, await fs.readFile(`${OPENCODE_SERVER_DIST}/${l}`))
77
+ }
78
+ },
79
+ },
80
+ ],
81
+ },
82
+ preload: {
83
+ build: {
84
+ rollupOptions: {
85
+ input: { index: "src/preload/index.ts" },
86
+ output: {
87
+ format: "cjs",
88
+ entryFileNames: "[name].js",
89
+ },
90
+ },
91
+ },
92
+ },
93
+ renderer: {
94
+ plugins: [appPlugin, sentry],
95
+ publicDir: "../../../app/public",
96
+ root: "src/renderer",
97
+ build: {
98
+ sourcemap: true,
99
+ rollupOptions: {
100
+ input: {
101
+ main: "src/renderer/index.html",
102
+ },
103
+ },
104
+ },
105
+ },
106
+ })
@@ -0,0 +1,14 @@
1
+ # Tauri Icons
2
+
3
+ Here's the process I've been using to create icons:
4
+
5
+ - Save source image as `app-icon.png` in `packages/desktop`
6
+ - `cd` to `packages/desktop`
7
+ - Run `bun tauri icon -o src-tauri/icons/{environment}`
8
+ - Use [Image2Icon](https://img2icnsapp.com/)'s 'Big Sur Icon' preset to generate an `icon.icns` file and place it in the appropriate icons folder
9
+
10
+ The Image2Icon step is necessary as the `icon.icns` generated by `app-icon.png` does not apply the shadow/padding expected by macOS,
11
+ so app icons appear larger than expected.
12
+
13
+ For unpackaged Electron on macOS, `app.dock.setIcon()` should use a PNG. Keep `dock.png` in each channel folder synced with the
14
+ extracted `icon_128x128@2x.png` from that channel's `icon.icns` so the dev Dock icon matches the packaged app inset.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
4
+ <background android:drawable="@color/ic_launcher_background"/>
5
+ </adaptive-icon>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ <color name="ic_launcher_background">#fff</color>
4
+ </resources>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
4
+ <background android:drawable="@color/ic_launcher_background"/>
5
+ </adaptive-icon>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ <color name="ic_launcher_background">#fff</color>
4
+ </resources>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file