cicy-desktop 2.1.132 → 2.1.134

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.
@@ -62,19 +62,9 @@ jobs:
62
62
  - name: Install Electron build dependencies
63
63
  run: npm install --save-dev --no-audit electron@41.0.2 electron-builder@26.7.0
64
64
 
65
- # Installer builds bundle the prebuilt SPA at src/backends/homepage-react.
66
- # vite outputs to workers/render/dist, so rebuild + copy here — otherwise the
67
- # AppImage ships a STALE homepage (e.g. missing the version badge). Mirrors npm-publish.yml.
68
- - name: Build homepage SPA → src/backends/homepage-react
69
- shell: bash
70
- run: |
71
- cd workers/render
72
- npm install --no-audit --no-fund
73
- npm run build
74
- cd ../..
75
- rm -rf src/backends/homepage-react/assets src/backends/homepage-react/index.html
76
- cp -r workers/render/dist/. src/backends/homepage-react/
77
- echo "homepage bundle: $(grep -o 'assets/index-[A-Za-z0-9_-]*\.js' src/backends/homepage-react/index.html)"
65
+ # NOTE: the homepage SPA is rebuilt automatically by the prebuild:linux npm
66
+ # hook (scripts/build-homepage.cjs) right before `npm run build:linux` below,
67
+ # so the AppImage can never ship a stale homepage. No explicit step needed.
78
68
 
79
69
  - name: Build Linux app (deb + AppImage)
80
70
  shell: bash
@@ -70,19 +70,9 @@ jobs:
70
70
  - name: Install Electron build dependencies in project directory
71
71
  run: npm install --save-dev --no-audit electron@41.0.2 electron-builder@26.7.0
72
72
 
73
- # Installer builds bundle the prebuilt SPA at src/backends/homepage-react.
74
- # vite outputs to workers/render/dist, so rebuild + copy here — otherwise the
75
- # dmg ships a STALE homepage (e.g. missing the version badge). Mirrors npm-publish.yml.
76
- - name: Build homepage SPA → src/backends/homepage-react
77
- shell: bash
78
- run: |
79
- cd workers/render
80
- npm install --no-audit --no-fund
81
- npm run build
82
- cd ../..
83
- rm -rf src/backends/homepage-react/assets src/backends/homepage-react/index.html
84
- cp -r workers/render/dist/. src/backends/homepage-react/
85
- echo "homepage bundle: $(grep -o 'assets/index-[A-Za-z0-9_-]*\.js' src/backends/homepage-react/index.html)"
73
+ # NOTE: the homepage SPA is rebuilt automatically by the prebuild:mac npm
74
+ # hook (scripts/build-homepage.cjs) right before `npm run build:mac` below,
75
+ # so the dmg can never ship a stale homepage. No explicit step needed.
86
76
 
87
77
  - name: Prepare macOS icon
88
78
  shell: bash
@@ -26,20 +26,11 @@ jobs:
26
26
  - name: Sync runtime deps to latest (cicy-code + cicy-mihomo; drop msys2)
27
27
  run: node scripts/sync-runtime-deps.cjs
28
28
 
29
- # The shipped homepage is the prebuilt SPA at src/backends/homepage-react.
30
- # vite outputs to workers/render/dist, so rebuild + copy it here — otherwise
31
- # the package ships a STALE homepage (this is exactly how the Docker card
32
- # lingered after it was removed in source). Always build from source on publish.
33
- - name: Build homepage SPA src/backends/homepage-react
34
- run: |
35
- cd workers/render
36
- npm install --no-audit --no-fund
37
- npm run build
38
- cd ../..
39
- rm -rf src/backends/homepage-react/assets src/backends/homepage-react/index.html
40
- cp -r workers/render/dist/. src/backends/homepage-react/
41
- echo "homepage bundle: $(grep -o 'assets/index-[A-Za-z0-9_-]*\.js' src/backends/homepage-react/index.html)"
42
-
29
+ # NOTE: the homepage SPA is rebuilt from source automatically by the
30
+ # prepublishOnly npm hook (scripts/build-homepage.cjs) during `npm publish`
31
+ # below, so the package can never ship a stale homepage (this is how the
32
+ # Docker card lingered, and how the version badge went missing). No explicit
33
+ # step needed one mechanism (npm lifecycle) covers npm + all installers.
43
34
  - name: Publish cicy-desktop to npm
44
35
  run: npm publish --access public
45
36
  env:
@@ -32,19 +32,9 @@ jobs:
32
32
  - name: Install Electron build dependencies in project directory
33
33
  run: npm install --save-dev --no-audit electron@41.0.2 electron-builder@26.7.0
34
34
 
35
- # Installer builds bundle the prebuilt SPA at src/backends/homepage-react.
36
- # vite outputs to workers/render/dist, so rebuild + copy here — otherwise the
37
- # exe ships a STALE homepage (e.g. missing the version badge). Mirrors npm-publish.yml.
38
- - name: Build homepage SPA → src/backends/homepage-react
39
- shell: bash
40
- run: |
41
- cd workers/render
42
- npm install --no-audit --no-fund
43
- npm run build
44
- cd ../..
45
- rm -rf src/backends/homepage-react/assets src/backends/homepage-react/index.html
46
- cp -r workers/render/dist/. src/backends/homepage-react/
47
- echo "homepage bundle: $(grep -o 'assets/index-[A-Za-z0-9_-]*\.js' src/backends/homepage-react/index.html)"
35
+ # NOTE: the homepage SPA is rebuilt automatically by the prebuild:win npm
36
+ # hook (scripts/build-homepage.cjs) right before `npm run build:win` below,
37
+ # so the exe can never ship a stale homepage. No explicit step needed.
48
38
 
49
39
  - name: Prepare Windows icon
50
40
  shell: powershell
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cicy-desktop",
3
- "version": "2.1.132",
3
+ "version": "2.1.134",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -17,6 +17,11 @@
17
17
  "test:ls": "node tests/test-ls.js",
18
18
  "build": "electron-builder --publish never",
19
19
  "build:ui": "cd packages/ui-react && npm install && npm run build",
20
+ "build:homepage": "node scripts/build-homepage.cjs",
21
+ "prebuild:win": "node scripts/build-homepage.cjs",
22
+ "prebuild:mac": "node scripts/build-homepage.cjs",
23
+ "prebuild:linux": "node scripts/build-homepage.cjs",
24
+ "prepublishOnly": "node scripts/build-homepage.cjs",
20
25
  "build:win": "electron-builder --win",
21
26
  "build:mac": "electron-builder --mac",
22
27
  "build:linux": "electron-builder --linux"
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ // Single source of truth for producing the SHIPPED homepage.
3
+ //
4
+ // The app loads src/backends/homepage-react/ (a prebuilt SPA snapshot). The
5
+ // SOURCE lives in workers/render/. These are two different things and WILL
6
+ // drift apart unless the snapshot is rebuilt from source — which is exactly
7
+ // how a stale homepage (missing the version badge) shipped before.
8
+ //
9
+ // This script rebuilds the snapshot from source. It is wired into every
10
+ // release path via npm lifecycle hooks (prebuild:win/mac/linux + prepublishOnly),
11
+ // so the shipped homepage can NEVER lag behind workers/render — locally or in CI.
12
+ // Cross-platform (pure node fs/cp): runs on the maintainer's Windows box too.
13
+
14
+ const { execSync } = require("child_process");
15
+ const fs = require("fs");
16
+ const path = require("path");
17
+
18
+ const ROOT = path.join(__dirname, "..");
19
+ const RENDER = path.join(ROOT, "workers", "render");
20
+ const DIST = path.join(RENDER, "dist");
21
+ const DEST = path.join(ROOT, "src", "backends", "homepage-react");
22
+
23
+ function run(cmd, cwd) {
24
+ console.log(`[build-homepage] $ ${cmd} (in ${path.relative(ROOT, cwd) || "."})`);
25
+ execSync(cmd, { cwd, stdio: "inherit" });
26
+ }
27
+
28
+ // 1) build the SPA from source (install deps on a cold runner)
29
+ if (!fs.existsSync(path.join(RENDER, "node_modules"))) {
30
+ run("npm install --no-audit --no-fund", RENDER);
31
+ }
32
+ run("npm run build", RENDER);
33
+
34
+ // 2) replace the shipped snapshot with the fresh build (clean, not merge —
35
+ // so old hashed assets don't pile up)
36
+ fs.rmSync(path.join(DEST, "assets"), { recursive: true, force: true });
37
+ fs.rmSync(path.join(DEST, "index.html"), { force: true });
38
+ fs.mkdirSync(DEST, { recursive: true });
39
+ fs.cpSync(DIST, DEST, { recursive: true });
40
+
41
+ // 3) report which bundle shipped (visible in CI logs)
42
+ const html = fs.readFileSync(path.join(DEST, "index.html"), "utf8");
43
+ const m = html.match(/assets\/index-[A-Za-z0-9_-]*\.js/);
44
+ console.log(`[build-homepage] shipped bundle: ${m ? m[0] : "(hash not found!)"}`);
@@ -137,7 +137,7 @@ async function startLogin({ onResult } = {}) {
137
137
  // browser, locked-down shell) openExternal silently fails and the user is
138
138
  // left stuck "等回调" with no recourse — so we ALSO return the url to the
139
139
  // renderer (below) to show a manual "open / copy this link" fallback.
140
- shell.openExternal(url).catch((e) => log.warn(`[auth-loopback] openExternal failed: ${e.message}`));
140
+ require("./open-external").openExternalRobust(url).catch((e) => log.warn(`[auth-loopback] open failed: ${e.message}`));
141
141
 
142
142
  _timeoutHandle = setTimeout(() => {
143
143
  try { onResult && onResult({ error: "timeout" }); } catch {}
@@ -199,10 +199,12 @@ function register(opts = {}) {
199
199
  });
200
200
 
201
201
  // --- shell / app / tos / logs (last rebuild!) ---
202
- ipcMain.handle("shell:open-external", (_e, url) => {
202
+ ipcMain.handle("shell:open-external", async (_e, url) => {
203
203
  if (!url) return false;
204
- shell.openExternal(String(url));
205
- return true;
204
+ // Robust open: shell.openExternal silently fails on some Windows profiles;
205
+ // fall back to rundll32/explorer/start (the "手动打开" button uses this too).
206
+ const { openExternalRobust } = require("./open-external");
207
+ return await openExternalRobust(url);
206
208
  });
207
209
  ipcMain.handle("app:quit", () => {
208
210
  setTimeout(() => app.quit(), 100);
@@ -0,0 +1,50 @@
1
+ // Robust "open this URL in the system browser".
2
+ //
3
+ // electron's shell.openExternal silently fails on some Windows setups — a fresh
4
+ // user profile, a locked-down shell, or console-launched (npx) electron — leaving
5
+ // browser-login stuck ("点了没反应"). When it fails we fall back to the OS URL
6
+ // openers directly. Order matters: rundll32 / explorer / open / xdg-open take the
7
+ // URL as a SINGLE argv (no shell parsing), so the login URL's `&`/`?` query params
8
+ // survive. `cmd start` is last because cmd treats `&` as a command separator.
9
+
10
+ const { shell } = require("electron");
11
+ const { spawn } = require("child_process");
12
+ const log = require("electron-log");
13
+
14
+ function trySpawn(cmd, args) {
15
+ try {
16
+ const child = spawn(cmd, args, { detached: true, stdio: "ignore", windowsHide: true });
17
+ child.on("error", (err) => log.warn(`[open-external] ${cmd} error: ${err.message}`));
18
+ child.unref();
19
+ return true;
20
+ } catch (e) {
21
+ log.warn(`[open-external] spawn ${cmd} threw: ${e.message}`);
22
+ return false;
23
+ }
24
+ }
25
+
26
+ // Returns true if SOME mechanism was dispatched (best-effort — the OS may still
27
+ // have no default browser, which no opener can fix; the renderer always also
28
+ // shows a copy-link fallback).
29
+ async function openExternalRobust(rawUrl) {
30
+ const url = String(rawUrl || "");
31
+ if (!url) return false;
32
+
33
+ try {
34
+ await shell.openExternal(url);
35
+ return true;
36
+ } catch (e) {
37
+ log.warn(`[open-external] shell.openExternal failed, falling back: ${e && e.message}`);
38
+ }
39
+
40
+ if (process.platform === "win32") {
41
+ // FileProtocolHandler + explorer pass the URL untouched (good for query strings).
42
+ if (trySpawn("rundll32", ["url.dll,FileProtocolHandler", url])) return true;
43
+ if (trySpawn("explorer.exe", [url])) return true;
44
+ return trySpawn("cmd", ["/c", "start", "", url]);
45
+ }
46
+ if (process.platform === "darwin") return trySpawn("open", [url]);
47
+ return trySpawn("xdg-open", [url]);
48
+ }
49
+
50
+ module.exports = { openExternalRobust };