@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.
- package/AGENTS.md +4 -0
- package/README.md +19 -0
- package/electron-builder.config.test.ts +48 -0
- package/electron-builder.config.ts +146 -0
- package/electron.vite.config.ts +106 -0
- package/icons/README.md +14 -0
- package/icons/beta/128x128.png +0 -0
- package/icons/beta/128x128@2x.png +0 -0
- package/icons/beta/32x32.png +0 -0
- package/icons/beta/64x64.png +0 -0
- package/icons/beta/Square107x107Logo.png +0 -0
- package/icons/beta/Square142x142Logo.png +0 -0
- package/icons/beta/Square150x150Logo.png +0 -0
- package/icons/beta/Square284x284Logo.png +0 -0
- package/icons/beta/Square30x30Logo.png +0 -0
- package/icons/beta/Square310x310Logo.png +0 -0
- package/icons/beta/Square44x44Logo.png +0 -0
- package/icons/beta/Square71x71Logo.png +0 -0
- package/icons/beta/Square89x89Logo.png +0 -0
- package/icons/beta/StoreLogo.png +0 -0
- package/icons/beta/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/icons/beta/android/mipmap-hdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/mipmap-mdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/mipmap-xhdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/values/ic_launcher_background.xml +4 -0
- package/icons/beta/dock.png +0 -0
- package/icons/beta/icon.icns +0 -0
- package/icons/beta/icon.ico +0 -0
- package/icons/beta/icon.png +0 -0
- package/icons/beta/ios/AppIcon-20x20@1x.png +0 -0
- package/icons/beta/ios/AppIcon-20x20@2x-1.png +0 -0
- package/icons/beta/ios/AppIcon-20x20@2x.png +0 -0
- package/icons/beta/ios/AppIcon-20x20@3x.png +0 -0
- package/icons/beta/ios/AppIcon-29x29@1x.png +0 -0
- package/icons/beta/ios/AppIcon-29x29@2x-1.png +0 -0
- package/icons/beta/ios/AppIcon-29x29@2x.png +0 -0
- package/icons/beta/ios/AppIcon-29x29@3x.png +0 -0
- package/icons/beta/ios/AppIcon-40x40@1x.png +0 -0
- package/icons/beta/ios/AppIcon-40x40@2x-1.png +0 -0
- package/icons/beta/ios/AppIcon-40x40@2x.png +0 -0
- package/icons/beta/ios/AppIcon-40x40@3x.png +0 -0
- package/icons/beta/ios/AppIcon-512@2x.png +0 -0
- package/icons/beta/ios/AppIcon-60x60@2x.png +0 -0
- package/icons/beta/ios/AppIcon-60x60@3x.png +0 -0
- package/icons/beta/ios/AppIcon-76x76@1x.png +0 -0
- package/icons/beta/ios/AppIcon-76x76@2x.png +0 -0
- package/icons/beta/ios/AppIcon-83.5x83.5@2x.png +0 -0
- package/icons/dev/128x128.png +0 -0
- package/icons/dev/128x128@2x.png +0 -0
- package/icons/dev/32x32.png +0 -0
- package/icons/dev/64x64.png +0 -0
- package/icons/dev/Square107x107Logo.png +0 -0
- package/icons/dev/Square142x142Logo.png +0 -0
- package/icons/dev/Square150x150Logo.png +0 -0
- package/icons/dev/Square284x284Logo.png +0 -0
- package/icons/dev/Square30x30Logo.png +0 -0
- package/icons/dev/Square310x310Logo.png +0 -0
- package/icons/dev/Square44x44Logo.png +0 -0
- package/icons/dev/Square71x71Logo.png +0 -0
- package/icons/dev/Square89x89Logo.png +0 -0
- package/icons/dev/StoreLogo.png +0 -0
- package/icons/dev/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/icons/dev/android/mipmap-hdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/mipmap-mdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/mipmap-xhdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/values/ic_launcher_background.xml +4 -0
- package/icons/dev/dock.png +0 -0
- package/icons/dev/icon.icns +0 -0
- package/icons/dev/icon.ico +0 -0
- package/icons/dev/icon.png +0 -0
- package/icons/dev/ios/AppIcon-20x20@1x.png +0 -0
- package/icons/dev/ios/AppIcon-20x20@2x-1.png +0 -0
- package/icons/dev/ios/AppIcon-20x20@2x.png +0 -0
- package/icons/dev/ios/AppIcon-20x20@3x.png +0 -0
- package/icons/dev/ios/AppIcon-29x29@1x.png +0 -0
- package/icons/dev/ios/AppIcon-29x29@2x-1.png +0 -0
- package/icons/dev/ios/AppIcon-29x29@2x.png +0 -0
- package/icons/dev/ios/AppIcon-29x29@3x.png +0 -0
- package/icons/dev/ios/AppIcon-40x40@1x.png +0 -0
- package/icons/dev/ios/AppIcon-40x40@2x-1.png +0 -0
- package/icons/dev/ios/AppIcon-40x40@2x.png +0 -0
- package/icons/dev/ios/AppIcon-40x40@3x.png +0 -0
- package/icons/dev/ios/AppIcon-512@2x.png +0 -0
- package/icons/dev/ios/AppIcon-60x60@2x.png +0 -0
- package/icons/dev/ios/AppIcon-60x60@3x.png +0 -0
- package/icons/dev/ios/AppIcon-76x76@1x.png +0 -0
- package/icons/dev/ios/AppIcon-76x76@2x.png +0 -0
- package/icons/dev/ios/AppIcon-83.5x83.5@2x.png +0 -0
- package/icons/prod/128x128.png +0 -0
- package/icons/prod/128x128@2x.png +0 -0
- package/icons/prod/32x32.png +0 -0
- package/icons/prod/64x64.png +0 -0
- package/icons/prod/Square107x107Logo.png +0 -0
- package/icons/prod/Square142x142Logo.png +0 -0
- package/icons/prod/Square150x150Logo.png +0 -0
- package/icons/prod/Square284x284Logo.png +0 -0
- package/icons/prod/Square30x30Logo.png +0 -0
- package/icons/prod/Square310x310Logo.png +0 -0
- package/icons/prod/Square44x44Logo.png +0 -0
- package/icons/prod/Square71x71Logo.png +0 -0
- package/icons/prod/Square89x89Logo.png +0 -0
- package/icons/prod/StoreLogo.png +0 -0
- package/icons/prod/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/icons/prod/android/mipmap-hdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/mipmap-mdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/mipmap-xhdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/values/ic_launcher_background.xml +4 -0
- package/icons/prod/dock.png +0 -0
- package/icons/prod/icon.icns +0 -0
- package/icons/prod/icon.ico +0 -0
- package/icons/prod/icon.png +0 -0
- package/icons/prod/ios/AppIcon-20x20@1x.png +0 -0
- package/icons/prod/ios/AppIcon-20x20@2x-1.png +0 -0
- package/icons/prod/ios/AppIcon-20x20@2x.png +0 -0
- package/icons/prod/ios/AppIcon-20x20@3x.png +0 -0
- package/icons/prod/ios/AppIcon-29x29@1x.png +0 -0
- package/icons/prod/ios/AppIcon-29x29@2x-1.png +0 -0
- package/icons/prod/ios/AppIcon-29x29@2x.png +0 -0
- package/icons/prod/ios/AppIcon-29x29@3x.png +0 -0
- package/icons/prod/ios/AppIcon-40x40@1x.png +0 -0
- package/icons/prod/ios/AppIcon-40x40@2x-1.png +0 -0
- package/icons/prod/ios/AppIcon-40x40@2x.png +0 -0
- package/icons/prod/ios/AppIcon-40x40@3x.png +0 -0
- package/icons/prod/ios/AppIcon-512@2x.png +0 -0
- package/icons/prod/ios/AppIcon-60x60@2x.png +0 -0
- package/icons/prod/ios/AppIcon-60x60@3x.png +0 -0
- package/icons/prod/ios/AppIcon-76x76@1x.png +0 -0
- package/icons/prod/ios/AppIcon-76x76@2x.png +0 -0
- package/icons/prod/ios/AppIcon-83.5x83.5@2x.png +0 -0
- package/package.json +75 -0
- package/resources/entitlements.plist +18 -0
- package/resources/linux/opencode-desktop.desktop +10 -0
- package/scripts/copy-bundles.ts +12 -0
- package/scripts/copy-icons.ts +12 -0
- package/scripts/copy-metainfo.ts +47 -0
- package/scripts/finalize-latest-json.ts +219 -0
- package/scripts/finalize-latest-yml.ts +124 -0
- package/scripts/prebuild.ts +10 -0
- package/scripts/predev.ts +5 -0
- package/scripts/prepare.ts +9 -0
- package/scripts/utils.ts +77 -0
- package/src/main/apps.ts +136 -0
- package/src/main/attachment-picker.test.ts +87 -0
- package/src/main/attachment-picker.ts +56 -0
- package/src/main/constants.ts +7 -0
- package/src/main/debug.ts +95 -0
- package/src/main/desktop-menu-actions.ts +84 -0
- package/src/main/env.d.ts +19 -0
- package/src/main/index.test.ts +37 -0
- package/src/main/index.ts +399 -0
- package/src/main/initialization.ts +6 -0
- package/src/main/install-state.test.ts +19 -0
- package/src/main/install-state.ts +8 -0
- package/src/main/ipc.ts +274 -0
- package/src/main/logging.ts +205 -0
- package/src/main/markdown.ts +16 -0
- package/src/main/menu.ts +67 -0
- package/src/main/migrate.ts +91 -0
- package/src/main/onboarding.ts +45 -0
- package/src/main/server.ts +238 -0
- package/src/main/shell-env.test.ts +50 -0
- package/src/main/shell-env.ts +101 -0
- package/src/main/sidecar.ts +157 -0
- package/src/main/store-cleanup.test.ts +93 -0
- package/src/main/store-cleanup.ts +94 -0
- package/src/main/store-keys.ts +7 -0
- package/src/main/store.ts +35 -0
- package/src/main/unresponsive.ts +70 -0
- package/src/main/updater-controller.test.ts +111 -0
- package/src/main/updater-controller.ts +97 -0
- package/src/main/updater-subscriptions.test.ts +16 -0
- package/src/main/updater-subscriptions.ts +20 -0
- package/src/main/updater.ts +85 -0
- package/src/main/window-registry.test.ts +91 -0
- package/src/main/window-registry.ts +47 -0
- package/src/main/window-state.ts +29 -0
- package/src/main/windows.ts +496 -0
- package/src/main/wsl/ipc.ts +103 -0
- package/src/main/wsl/policy.ts +33 -0
- package/src/main/wsl/runtime.ts +400 -0
- package/src/main/wsl/servers.test.ts +231 -0
- package/src/main/wsl/servers.ts +521 -0
- package/src/main/wsl/sidecar.ts +129 -0
- package/src/main/wsl/startup.ts +31 -0
- package/src/preload/index.ts +128 -0
- package/src/preload/types.ts +109 -0
- package/src/renderer/cli.ts +12 -0
- package/src/renderer/env.d.ts +10 -0
- package/src/renderer/html.test.ts +62 -0
- package/src/renderer/i18n/ar.ts +26 -0
- package/src/renderer/i18n/br.ts +27 -0
- package/src/renderer/i18n/bs.ts +28 -0
- package/src/renderer/i18n/da.ts +28 -0
- package/src/renderer/i18n/de.ts +28 -0
- package/src/renderer/i18n/en.ts +27 -0
- package/src/renderer/i18n/es.ts +27 -0
- package/src/renderer/i18n/fr.ts +28 -0
- package/src/renderer/i18n/index.ts +194 -0
- package/src/renderer/i18n/ja.ts +28 -0
- package/src/renderer/i18n/ko.ts +27 -0
- package/src/renderer/i18n/no.ts +28 -0
- package/src/renderer/i18n/pl.ts +28 -0
- package/src/renderer/i18n/ru.ts +27 -0
- package/src/renderer/i18n/uk.ts +28 -0
- package/src/renderer/i18n/zh.ts +26 -0
- package/src/renderer/i18n/zht.ts +26 -0
- package/src/renderer/index.html +21 -0
- package/src/renderer/index.tsx +464 -0
- package/src/renderer/initialization.test.ts +73 -0
- package/src/renderer/initialization.ts +22 -0
- package/src/renderer/onboarding.tsx +53 -0
- package/src/renderer/styles.css +0 -0
- package/src/renderer/webview-zoom.ts +138 -0
- package/src/renderer/wsl/connections.test.ts +43 -0
- package/src/renderer/wsl/connections.ts +28 -0
- package/sst-env.d.ts +10 -0
- package/tsconfig.json +23 -0
package/AGENTS.md
ADDED
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
|
+
})
|
package/icons/README.md
ADDED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|