@@ -6,8 +6,14 @@ import { promisify } from "node:util"
66import type { Configuration } from "electron-builder"
77
88const execFileAsync = promisify ( execFile )
9- const rootDir = path . resolve ( path . dirname ( fileURLToPath ( import . meta. url ) ) , "../.." )
9+ const packageDir = path . dirname ( fileURLToPath ( import . meta. url ) )
10+ const rootDir = path . resolve ( packageDir , "../.." )
1011const 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`
1117
1218async function signWindows ( configuration : { path : string } ) {
1319 if ( process . platform !== "win32" ) return
@@ -26,12 +32,26 @@ const channel = (() => {
2632 return "dev"
2733} ) ( )
2834
29- const getBase = ( ) : Configuration => ( {
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 => ( {
3042 artifactName : "opencode-desktop-${os}-${arch}.${ext}" ,
3143 directories : {
3244 output : "dist" ,
3345 buildResources : "resources" ,
3446 } ,
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+ } ,
3555 files : [ "out/**/*" , "resources/**/*" ] ,
3656 extraResources : [
3757 {
@@ -74,27 +94,35 @@ const getBase = (): Configuration => ({
7494 linux : {
7595 icon : `resources/icons` ,
7696 category : "Development" ,
77- executableName : "opencode-desktop" ,
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+ } ,
78105 target : [ "AppImage" , "deb" , "rpm" ] ,
79106 } ,
80107} )
81108
82109function getConfig ( ) {
83- const base = getBase ( )
110+ const appId = APP_IDS [ channel ]
111+ const base = getBase ( appId )
84112
85113 switch ( channel ) {
86114 case "dev" : {
87115 return {
88116 ...base ,
89- appId : "ai.opencode.desktop.dev" ,
117+ appId,
90118 productName : "OpenCode Dev" ,
91119 rpm : { packageName : "opencode-dev" } ,
92120 }
93121 }
94122 case "beta" : {
95123 return {
96124 ...base ,
97- appId : "ai.opencode.desktop.beta" ,
125+ appId,
98126 productName : "OpenCode Beta" ,
99127 protocols : { name : "OpenCode Beta" , schemes : [ "opencode" ] } ,
100128 publish : { provider : "github" , owner : "anomalyco" , repo : "opencode-beta" , channel : "latest" } ,
@@ -104,11 +132,12 @@ function getConfig() {
104132 case "prod" : {
105133 return {
106134 ...base ,
107- appId : "ai.opencode.desktop" ,
135+ appId,
108136 productName : "OpenCode" ,
109137 protocols : { name : "OpenCode" , schemes : [ "opencode" ] } ,
110138 publish : { provider : "github" , owner : "anomalyco" , repo : "opencode" , channel : "latest" } ,
111- rpm : { packageName : "opencode" } ,
139+ deb : { fpm : [ legacyDesktopEntryFpm ] } ,
140+ rpm : { packageName : "opencode" , fpm : [ legacyDesktopEntryFpm ] } ,
112141 }
113142 }
114143 }
0 commit comments