cicy-desktop 2.1.61 → 2.1.63

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cicy-desktop",
3
- "version": "2.1.61",
3
+ "version": "2.1.63",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -1,27 +1,20 @@
1
1
  // Homepage window — primary CiCy Desktop window. Singleton; closing it
2
2
  // does NOT quit the app.
3
3
  //
4
- // URL selection (HARDCODED — no env/dev-URL switch, no Vite):
5
- // - Windows: the remote Cloudflare worker https://desktop.cicy-ai.comkeeps
6
- // Win shipping without rebuilding (Win release cadence is slower than
7
- // render's). Falls back to the local file:// SPA if unreachable.
8
- // - Mac/Linux: the bundled local SPA file:// works offline, fast, no remote
9
- // dependency, no mixed-content concerns when embedding the team-assistant
10
- // webview (the cicy-desktop preload's IPC bridge still attaches).
4
+ // URL selection (HARDCODED — no env/dev-URL switch, no Vite): ALL platforms
5
+ // load the bundled local file:// SPA works offline, fast, no remote
6
+ // dependency, no mixed-content concerns when embedding the team-assistant
7
+ // webview (the cicy-desktop preload's IPC bridge still attaches). The remote
8
+ // Cloudflare worker is only a fallback if the bundled SPA fails to load.
11
9
 
12
10
  const path = require("path");
13
11
  const { BrowserWindow } = require("electron");
14
12
  const log = require("electron-log");
15
13
 
16
- // Hardcoded homepage source no Vite / CICY_HOMEPAGE_URL dev-URL switch.
17
- // - mac/linux: the bundled file:// SPA (offline, fast, no remote dependency).
18
- // - Windows: the remote Cloudflare worker (Win release cadence is slower
19
- // than render's, so it loads the homepage remotely).
20
- const REMOTE_URL = "https://desktop.cicy-ai.com/"; // Cloudflare worker (remote homepage)
14
+ const REMOTE_URL = "https://desktop.cicy-ai.com/"; // Cloudflare worker (fallback only)
21
15
  const LOCAL_INDEX = path.join(__dirname, "homepage-react", "index.html");
22
16
 
23
17
  function pickHomepageURL() {
24
- if (process.platform === "win32") return REMOTE_URL;
25
18
  return `file://${LOCAL_INDEX}`;
26
19
  }
27
20
 
@@ -83,16 +76,13 @@ async function openHomepage() {
83
76
  homepage.webContents.on("console-message", (_e, level, msg, line, source) => {
84
77
  if (level >= 1) console.log(`[homepage:console L${line}] ${msg} (${source})`);
85
78
  });
86
- // If the dev URL (Vite / SSH tunnel) is unreachable, fall back to the
87
- // local bundled file:// SPA so the window never stays blank.
79
+ // If the bundled file:// SPA fails to load (corrupt/missing install), fall
80
+ // back to the remote Cloudflare homepage so the window never stays blank.
88
81
  homepage.webContents.on("did-fail-load", (_e, code, desc, url) => {
89
82
  console.error(`[homepage] did-fail-load ${code} ${desc} ${url}`);
90
- const fallback = `file://${LOCAL_INDEX}`;
91
- // If the remote (Windows) Cloudflare homepage is unreachable, fall back to
92
- // the bundled local SPA so the window never stays blank.
93
- if (url && url.startsWith(REMOTE_URL.replace(/\/$/, "")) && url !== fallback) {
94
- log.warn(`[homepage] remote homepage unreachable, falling back to ${fallback}`);
95
- homepage.loadURL(fallback);
83
+ if (url && url.startsWith("file://")) {
84
+ log.warn(`[homepage] bundled homepage failed, falling back to ${REMOTE_URL}`);
85
+ homepage.loadURL(REMOTE_URL);
96
86
  }
97
87
  });
98
88
  homepage.on("closed", () => { homepage = null; });
@@ -50,11 +50,17 @@ function register({ sidecarLogPath } = {}) {
50
50
  onProgress: (ev) => { try { e.sender.send("docker:bootstrap-progress", ev); } catch {} },
51
51
  });
52
52
  // Healthy local stack → make sure it shows up as a team ("本地团队就加
53
- // 上去了"). addTeam dedups by host:port, so re-runs are no-ops.
53
+ // 上去了"). addTeam dedups by host:port, so re-runs are no-ops. The
54
+ // api_token must be the CONTAINER's own (volume global.json) — the
55
+ // host's token is a different credential and fails verify.
54
56
  if (result && result.ok) {
55
57
  try {
56
58
  const lt = require("./local-teams");
57
- await lt.addTeam({ base_url: `http://127.0.0.1:${PORT}`, name: "本地团队" });
59
+ const tok = await docker.readContainerToken(PORT);
60
+ await lt.addTeam({
61
+ base_url: `http://127.0.0.1:${PORT}`, name: "本地团队",
62
+ ...(tok ? { api_token: tok } : {}),
63
+ });
58
64
  } catch { /* best-effort — the stack itself is up */ }
59
65
  }
60
66
  return result;
@@ -189,6 +189,20 @@ async function ensureDownloaded(url, dest, mirror, { emit, phase, label } = {})
189
189
  });
190
190
  }
191
191
 
192
+ // The container's cicy-code mints its own api_token in its volume-persisted
193
+ // global.json — the HOST's global.json token is a different credential and
194
+ // won't verify. Read the real one out of whatever container publishes :port
195
+ // (works for adopted legacy-named containers too).
196
+ async function readContainerToken(port = 8008) {
197
+ try {
198
+ const { stdout } = await run(["ps", "--filter", `publish=${port}`, "--format", "{{.Names}}"]);
199
+ const name = stdout.trim().split("\n")[0];
200
+ if (!name) return "";
201
+ const r = await run(["exec", name, "cat", "/home/cicy/cicy-ai/global.json"], { timeout: 10000 });
202
+ return (JSON.parse(r.stdout).api_token || "");
203
+ } catch { return ""; }
204
+ }
205
+
192
206
  // HTTP /health probe of the container on :port.
193
207
  function probeHealth(port = 8008, timeoutMs = 2500) {
194
208
  return new Promise((resolve) => {
@@ -358,4 +372,4 @@ async function bootstrap({ onProgress, port = 8008 } = {}) {
358
372
  return { ok: healthy, container: CONTAINER };
359
373
  }
360
374
 
361
- module.exports = { start, stop, checkStatus, loadImage, imagePresent, dockerOk, installDocker, bootstrap, probeHealth };
375
+ module.exports = { start, stop, checkStatus, loadImage, imagePresent, dockerOk, installDocker, bootstrap, probeHealth, readContainerToken };