cicy-desktop 2.1.367 → 2.1.368

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.
@@ -39,7 +39,7 @@
39
39
  setTimeout(check, 5000);
40
40
  })();
41
41
  </script>
42
- <script type="module" crossorigin src="./assets/index-BWZkvmvO.js"></script>
42
+ <script type="module" crossorigin src="./assets/index-gkbJ7Q2a.js"></script>
43
43
  <link rel="stylesheet" crossorigin href="./assets/index-CVk0uc2g.css">
44
44
  </head>
45
45
  <body>
@@ -143,7 +143,7 @@ async function sidecarToken() {
143
143
  if (!tok && process.platform === "win32") {
144
144
  try {
145
145
  tok = String(
146
- (await require("../sidecar/wsl-docker").readContainerToken(SIDECAR_PORT)) || ""
146
+ (await require("../sidecar/app-docker").readContainerToken(SIDECAR_PORT)) || ""
147
147
  ).trim();
148
148
  } catch (e) {
149
149
  log.warn(`[hub] sidecar token: ${e.message}`);
@@ -318,7 +318,7 @@ async function openTeam(id, opts = {}) {
318
318
  let token = (opts && opts.token) || "";
319
319
  if (!token) {
320
320
  if (isWinDockerTeam) {
321
- try { token = String(await require("../sidecar/wsl-docker").readContainerToken(localPort) || "").trim(); } catch (e) { log.warn(`[local-teams] open ${id}: container token read failed: ${e.message}`); }
321
+ try { token = String(await require("../sidecar/app-docker").readContainerToken(localPort) || "").trim(); } catch (e) { log.warn(`[local-teams] open ${id}: container token read failed: ${e.message}`); }
322
322
  if (!token) return { ok: false, error: "container_token_unavailable", hint: "cicy-code 容器还没就绪(读不到容器内的 token)。稍等几秒或用卡片菜单「重启」。" };
323
323
  } else if (isLocalUrl) {
324
324
  token = readGlobal()?.api_token || node.api_token || "";
@@ -34,7 +34,8 @@ const hostMihomo = require("../sidecar/host-mihomo"); // 宿主侧 mihomo ——
34
34
  // 按平台分发 Docker-版 cicy-code 的运行层:darwin → Colima,win32 → WSL2。两者同接口
35
35
  // (bootstrap/status/restart/stop/dockerRestart/recreate/update/upgrade/runContainer/
36
36
  // readContainerToken),所以下面的 handler 共用一份逻辑,只换底层模块。
37
- const appDocker = process.platform === "darwin" ? colimaDocker : wslDocker;
37
+ // win32 上再分:老机器 WSL2,新机器 QEMU(不靠 WSL,:8009)—— 见 sidecar/linux-backend.js。
38
+ const appDocker = require("../sidecar/app-docker");
38
39
  // Docker-版 cicy-code 只剩 Windows(WSL2)。(2026-06 回调): macOS 改回 native cicy-code
39
40
  // (:8008,colima 在 16G mac 上压垮内存被 jetsam 杀)→ darwin 不再走 docker,这里不放行,
40
41
  // 所有 docker:app-* handler / reconcile / chrome-proxy 在 mac 上全部 no-op,DockerCard 不显示。
@@ -582,6 +583,9 @@ function register({ sidecarLogPath } = {}) {
582
583
  // 否则 → WSL 卷 \\wsl$\<distro>\…\volumes\<vol>\_data(= 容器 /home/cicy)。
583
584
  ipcMain.handle("docker:open-dir", async (_e, which) => {
584
585
  if (!APP_DOCKER_SUPPORTED) return { ok: false, error: "unsupported" };
586
+ // QEMU 后端没有宿主共享目录(Windows 上的 QEMU 不支持 virtio-9p/virtiofs):C:\projects 没挂进容器,
587
+ // 卷在虚拟机磁盘里,资源管理器打不开。如实说,别打开一个和容器无关的目录。
588
+ if (appDocker.backend === "qemu") return { ok: false, error: "qemu_no_host_share", hint: "QEMU 版容器的文件在虚拟机里,请在 cicy-code 里或首页 Debian 终端里访问" };
585
589
  try {
586
590
  const { shell } = require("electron");
587
591
  let p;
@@ -236,14 +236,14 @@
236
236
  "menu": "Port settings",
237
237
  "title": "Port settings",
238
238
  "sub": "Extra ports (besides :8008) published so Windows can reach in-container services",
239
- "mainFixed": ":8008 · cicy-code (fixed)",
239
+ "mainFixed": ":{{p}} · cicy-code (fixed)",
240
240
  "add": "+ Add port",
241
241
  "ph": "Port 1-65535",
242
242
  "save": "Save & rebuild",
243
243
  "saving": "Saving…",
244
244
  "cancel": "Cancel",
245
245
  "hint": "Saving rebuilds the container (volume data kept) with a brief interruption",
246
- "invalid": "Invalid port (1-65535, not 8008, no duplicates)",
246
+ "invalid": "Invalid port (1-65535, not {{p}}, no duplicates)",
247
247
  "none": "No extra ports",
248
248
  "remove": "Remove"
249
249
  },
@@ -236,14 +236,14 @@
236
236
  "menu": "Réglage des ports",
237
237
  "title": "Réglage des ports",
238
238
  "sub": "Ports supplémentaires (hors :8008) publiés pour que Windows atteigne les services du conteneur",
239
- "mainFixed": ":8008 · cicy-code (fixe)",
239
+ "mainFixed": ":{{p}} · cicy-code (fixe)",
240
240
  "add": "+ Ajouter un port",
241
241
  "ph": "Port 1-65535",
242
242
  "save": "Enregistrer et reconstruire",
243
243
  "saving": "Enregistrement…",
244
244
  "cancel": "Annuler",
245
245
  "hint": "L'enregistrement reconstruit le conteneur (données du volume conservées), brève interruption",
246
- "invalid": "Port invalide (1-65535, pas 8008, sans doublon)",
246
+ "invalid": "Port invalide (1-65535, pas {{p}}, sans doublon)",
247
247
  "none": "Aucun port supplémentaire",
248
248
  "remove": "Retirer"
249
249
  },
@@ -236,14 +236,14 @@
236
236
  "menu": "ポート設定",
237
237
  "title": "ポート設定",
238
238
  "sub": ":8008 以外に公開し、Windows からコンテナ内サービスへ直接到達できるポート",
239
- "mainFixed": ":8008 · cicy-code(固定)",
239
+ "mainFixed": ":{{p}} · cicy-code(固定)",
240
240
  "add": "+ ポートを追加",
241
241
  "ph": "ポート 1-65535",
242
242
  "save": "保存して再構築",
243
243
  "saving": "保存中…",
244
244
  "cancel": "キャンセル",
245
245
  "hint": "保存するとコンテナを再構築します(ボリュームのデータは保持、短時間中断)",
246
- "invalid": "無効なポート(1-65535、8008 不可、重複不可)",
246
+ "invalid": "無効なポート(1-65535、{{p}} 不可、重複不可)",
247
247
  "none": "追加ポートなし",
248
248
  "remove": "削除"
249
249
  },
@@ -236,14 +236,14 @@
236
236
  "menu": "端口设置",
237
237
  "title": "端口设置",
238
238
  "sub": "除 :8008 外,额外发布、可从 Windows 直达容器内服务的端口",
239
- "mainFixed": ":8008 · cicy-code(固定)",
239
+ "mainFixed": ":{{p}} · cicy-code(固定)",
240
240
  "add": "+ 添加端口",
241
241
  "ph": "端口号 1-65535",
242
242
  "save": "保存并重建",
243
243
  "saving": "保存中…",
244
244
  "cancel": "取消",
245
245
  "hint": "保存会重建容器(volume 数据保留),会有短暂中断",
246
- "invalid": "有端口无效(1-65535,不能是 8008,不能重复)",
246
+ "invalid": "有端口无效(1-65535,不能是 {{p}},不能重复)",
247
247
  "none": "暂无额外端口",
248
248
  "remove": "移除"
249
249
  },
package/src/main.js CHANGED
@@ -6,6 +6,9 @@ const { default: contextMenu } = require("electron-context-menu");
6
6
  const fs = require("fs");
7
7
  const os = require("os");
8
8
  const path = require("path");
9
+ // 必须最先:决定 Windows 上 Docker-版 cicy-code 走 WSL(老机器)还是 QEMU(新机器 :8009),
10
+ // 并在任何模块读 CICY_DOCKER_APP_PORT 之前把端口定下来。见 sidecar/linux-backend.js。
11
+ require("./sidecar/linux-backend").init();
9
12
  const cicyCodeSidecar = require("./sidecar/cicy-code");
10
13
  const backendsIPC = require("./backends/ipc");
11
14
  const { openHomepage } = require("./backends/homepage-window");
@@ -0,0 +1,9 @@
1
+ // Copyright 2026 CiCy AI
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Docker-版 cicy-code 的运行层(同接口):darwin → Colima,win32 → WSL2(老机器)或 QEMU(新机器)。
5
+ // 选哪个见 linux-backend.js。调用方一律经这里拿,别再直接 require("./wsl-docker")。
6
+ const backend = require("./linux-backend").backend();
7
+ module.exports = process.platform === "darwin" ? require("./colima-docker")
8
+ : backend === "qemu" ? require("./qemu-docker")
9
+ : require("./wsl-docker");
@@ -0,0 +1,54 @@
1
+ // Copyright 2026 CiCy AI
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Windows 上 Docker-版 cicy-code 跑在哪:WSL2(老机器)还是 QEMU(新机器,不再用 WSL)。
5
+ //
6
+ // 规则(2026-10 定):已经装了 WSL 版的老机器不动;其余机器一律 QEMU,端口用 8009 —— 和老机器的
7
+ // 8008 用端口区分,一眼看得出走的哪套,也绝不撞车。判定结果写进 ~/cicy-ai/db/linux-backend.json,
8
+ // 之后不再变(避免某天装了 WSL 又被切回去)。CICY_LINUX_BACKEND=wsl|qemu 可强制覆盖。
9
+ //
10
+ // 必须在 main.js 最早处 init():sidecar-ipc 等模块在 require 时就读 CICY_DOCKER_APP_PORT。
11
+
12
+ const fs = require("fs");
13
+ const os = require("os");
14
+ const path = require("path");
15
+ const { execFileSync } = require("child_process");
16
+
17
+ const FILE = path.join(os.homedir(), "cicy-ai", "db", "linux-backend.json");
18
+ const DISTRO = process.env.CICY_WSL_DISTRO || "cicy-code-wsl";
19
+ const QEMU_PORT = 8009;
20
+ let _backend = null;
21
+
22
+ // 老机器的证据:WSL 注册表里有我们的发行版,或者之前算过的 docker 状态说装过。只读,不碰 wsl.exe。
23
+ function hasWslInstall() {
24
+ try {
25
+ execFileSync("reg", ["query", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Lxss", "/s", "/f", DISTRO, "/d", "/e"], { windowsHide: true, timeout: 8000, stdio: "ignore" });
26
+ return true;
27
+ } catch {}
28
+ try {
29
+ const j = JSON.parse(fs.readFileSync(path.join(os.homedir(), "cicy-ai", "db", "docker-status.json"), "utf8"));
30
+ if (j && (j.installed || j.running) && Number(j.port || 8008) === 8008) return true;
31
+ } catch {}
32
+ return false;
33
+ }
34
+
35
+ function decide() {
36
+ if (process.platform !== "win32") return "native";
37
+ const forced = String(process.env.CICY_LINUX_BACKEND || "").toLowerCase();
38
+ if (forced === "wsl" || forced === "qemu") return forced;
39
+ try { const j = JSON.parse(fs.readFileSync(FILE, "utf8")); if (j && (j.backend === "wsl" || j.backend === "qemu")) return j.backend; } catch {}
40
+ const b = hasWslInstall() ? "wsl" : "qemu";
41
+ try { fs.mkdirSync(path.dirname(FILE), { recursive: true }); fs.writeFileSync(FILE, JSON.stringify({ backend: b, decidedAt: new Date().toISOString() }, null, 2)); } catch {}
42
+ return b;
43
+ }
44
+
45
+ function init() {
46
+ if (_backend) return _backend;
47
+ _backend = decide();
48
+ if (_backend === "qemu" && !process.env.CICY_DOCKER_APP_PORT) process.env.CICY_DOCKER_APP_PORT = String(QEMU_PORT);
49
+ if (_backend === "qemu" && !process.env.CICY_SIDECAR_PORT) process.env.CICY_SIDECAR_PORT = process.env.CICY_DOCKER_APP_PORT;
50
+ return _backend;
51
+ }
52
+ function backend() { return _backend || init(); }
53
+
54
+ module.exports = { init, backend, QEMU_PORT, hasWslInstall };