Skip to content

Add desktop packaging workflows#1

Merged
weidu12123 merged 1 commit into
mainfrom
desktop-v4-release
May 23, 2026
Merged

Add desktop packaging workflows#1
weidu12123 merged 1 commit into
mainfrom
desktop-v4-release

Conversation

@weidu12123
Copy link
Copy Markdown
Owner

Summary

  • Add Electron desktop runtime support and packaging scripts for Windows desktop builds.
  • Add desktop settings integration for background mode/autostart and desktop login bypass.
  • Add a manually triggered macOS DMG release workflow for x64 and arm64 runners.

Test plan

  • Verified pushed branch exists on GitHub.
  • Ran lightweight token/config checks for desktop runtime and macOS workflow files.
  • Run Release macOS Desktop workflow after this PR is merged.

Add Electron desktop packaging support and a GitHub Actions workflow so v4.0.0 can produce Windows desktop bundles and unsigned macOS DMG artifacts.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 issues found across 14 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/build-electron-macos.js">

<violation number="1" location="scripts/build-electron-macos.js:187">
P2: DMG-only check too weak. Build can pass with missing backend files. Add required backend file checks before declaring package ready.</violation>
</file>

<file name="scripts/build-electron.js">

<violation number="1" location="scripts/build-electron.js:37">
P1: Windows npm/npx call builds one unquoted shell string. Paths with spaces break arg parsing. Pass args separately to spawnSync.</violation>

<violation number="2" location="scripts/build-electron.js:148">
P2: `--no-node-runtime` path always fails later. Readiness check still hard-requires `node/node.exe`. Make that check conditional.</violation>
</file>

<file name="frontend/src/utils/desktop.ts">

<violation number="1" location="frontend/src/utils/desktop.ts:44">
P1: Do not trust URL param for desktop detection. Easy spoof, login gate bypass. Remove query-string fallback.</violation>
</file>

<file name="electron/main.js">

<violation number="1" location="electron/main.js:172">
P2: Health check accepts 4xx as ready. Wrong process on that port can pass startup and app loads broken target. Accept only 2xx.</violation>

<violation number="2" location="electron/main.js:213">
P2: Settings file path uses app backend install dir. User prefs can be lost on update and writes are fragile on packaged installs. Store prefs in userData.</violation>
</file>

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Comment thread scripts/build-electron.js
const env = { ...process.env, CSC_IDENTITY_AUTO_DISCOVERY: 'false' };
const useWindowsShell = process.platform === 'win32' && (command === 'npm' || command === 'npx');
const result = useWindowsShell
? spawnSync([command, ...commandArgs].join(' '), { cwd, stdio: 'inherit', shell: true, env })
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Windows npm/npx call builds one unquoted shell string. Paths with spaces break arg parsing. Pass args separately to spawnSync.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/build-electron.js, line 37:

<comment>Windows npm/npx call builds one unquoted shell string. Paths with spaces break arg parsing. Pass args separately to spawnSync.</comment>

<file context>
@@ -0,0 +1,241 @@
+  const env = { ...process.env, CSC_IDENTITY_AUTO_DISCOVERY: 'false' };
+  const useWindowsShell = process.platform === 'win32' && (command === 'npm' || command === 'npx');
+  const result = useWindowsShell
+    ? spawnSync([command, ...commandArgs].join(' '), { cwd, stdio: 'inherit', shell: true, env })
+    : spawnSync(command, commandArgs, { cwd, stdio: 'inherit', env });
+
</file context>

}

export function isDesktopRuntime(): boolean {
return Boolean(tauriCore() || electronBridge() || window.__ONESHELL_RUNTIME__ === 'desktop' || new URLSearchParams(window.location.search).get('runtime') === 'desktop');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Do not trust URL param for desktop detection. Easy spoof, login gate bypass. Remove query-string fallback.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/src/utils/desktop.ts, line 44:

<comment>Do not trust URL param for desktop detection. Easy spoof, login gate bypass. Remove query-string fallback.</comment>

<file context>
@@ -0,0 +1,78 @@
+}
+
+export function isDesktopRuntime(): boolean {
+  return Boolean(tauriCore() || electronBridge() || window.__ONESHELL_RUNTIME__ === 'desktop' || new URLSearchParams(window.location.search).get('runtime') === 'desktop');
+}
+
</file context>

}

function assertMacOutputReady() {
const dmgPath = path.join(outputDir, `1Shell-v${version}-mac-${macArch}.dmg`);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: DMG-only check too weak. Build can pass with missing backend files. Add required backend file checks before declaring package ready.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/build-electron-macos.js, line 187:

<comment>DMG-only check too weak. Build can pass with missing backend files. Add required backend file checks before declaring package ready.</comment>

<file context>
@@ -0,0 +1,204 @@
+}
+
+function assertMacOutputReady() {
+  const dmgPath = path.join(outputDir, `1Shell-v${version}-mac-${macArch}.dmg`);
+  if (!fs.existsSync(dmgPath)) {
+    throw new Error(`macOS desktop package is incomplete, missing: ${path.relative(ROOT, dmgPath)}`);
</file context>

Comment thread scripts/build-electron.js
const requiredFiles = [
'1Shell.cmd',
'server.js',
path.join('node', 'node.exe'),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: --no-node-runtime path always fails later. Readiness check still hard-requires node/node.exe. Make that check conditional.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/build-electron.js, line 148:

<comment>`--no-node-runtime` path always fails later. Readiness check still hard-requires `node/node.exe`. Make that check conditional.</comment>

<file context>
@@ -0,0 +1,241 @@
+  const requiredFiles = [
+    '1Shell.cmd',
+    'server.js',
+    path.join('node', 'node.exe'),
+    path.join('node_modules', 'dotenv', 'package.json'),
+    path.join('node_modules', 'better-sqlite3', 'package.json'),
</file context>
Suggested change
path.join('node', 'node.exe'),
...(hasFlag('--no-node-runtime') ? [] : [path.join('node', 'node.exe')]),

Comment thread electron/main.js
}

function getDesktopSettingsPath() {
return path.join(backendRoot, 'data', 'desktop-settings.json');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Settings file path uses app backend install dir. User prefs can be lost on update and writes are fragile on packaged installs. Store prefs in userData.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At electron/main.js, line 213:

<comment>Settings file path uses app backend install dir. User prefs can be lost on update and writes are fragile on packaged installs. Store prefs in userData.</comment>

<file context>
@@ -0,0 +1,397 @@
+}
+
+function getDesktopSettingsPath() {
+  return path.join(backendRoot, 'data', 'desktop-settings.json');
+}
+
</file context>

Comment thread electron/main.js
function probe() {
const req = http.get(healthUrl, res => {
res.resume();
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 500) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Health check accepts 4xx as ready. Wrong process on that port can pass startup and app loads broken target. Accept only 2xx.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At electron/main.js, line 172:

<comment>Health check accepts 4xx as ready. Wrong process on that port can pass startup and app loads broken target. Accept only 2xx.</comment>

<file context>
@@ -0,0 +1,397 @@
+    function probe() {
+      const req = http.get(healthUrl, res => {
+        res.resume();
+        if (res.statusCode && res.statusCode >= 200 && res.statusCode < 500) {
+          resolve();
+          return;
</file context>

@weidu12123 weidu12123 merged commit 3b98a16 into main May 23, 2026
4 checks passed
@weidu12123 weidu12123 deleted the desktop-v4-release branch May 23, 2026 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant