cicy-desktop 2.1.197 → 2.1.199

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.
Files changed (44) hide show
  1. package/.github/workflows/build-wsl-package.yml +1 -1
  2. package/.github/workflows/linux-app-release.yml +2 -2
  3. package/.github/workflows/mac-app-release.yml +2 -2
  4. package/bin/cicy-desktop +47 -47
  5. package/package.json +7 -7
  6. package/scripts/mac-allinone/install.command +1 -1
  7. package/scripts/sync-runtime-deps.cjs +1 -1
  8. package/src/backends/homepage-preload.js +8 -4
  9. package/src/backends/homepage-react/assets/index-Dnp76yv5.js +377 -0
  10. package/src/backends/homepage-react/assets/index-jCKMeNVk.css +1 -0
  11. package/src/backends/homepage-react/index.html +2 -2
  12. package/src/backends/homepage-window.js +2 -2
  13. package/src/backends/ipc.js +14 -2
  14. package/src/backends/local-teams.js +40 -39
  15. package/src/backends/sidecar-ipc.js +103 -69
  16. package/src/backends/window-manager.js +1 -1
  17. package/src/cloud/cloud-client.js +4 -4
  18. package/src/i18n/locales/en.json +125 -7
  19. package/src/i18n/locales/fr.json +125 -7
  20. package/src/i18n/locales/ja.json +125 -7
  21. package/src/i18n/locales/zh-CN.json +125 -7
  22. package/src/main.js +13 -10
  23. package/src/sidecar/cicy-code.js +98 -140
  24. package/src/sidecar/colima-docker.js +25 -25
  25. package/src/sidecar/docker.js +20 -20
  26. package/src/sidecar/host-mihomo.js +14 -9
  27. package/src/sidecar/localbin.js +17 -7
  28. package/src/sidecar/native.js +2 -2
  29. package/src/sidecar/runtime.js +1 -1
  30. package/src/sidecar/version.js +1 -1
  31. package/src/sidecar/wsl-docker.js +126 -55
  32. package/src/tabbrowser/newtab-protocol.js +1 -1
  33. package/src/tools/desktop-snapshot-tools.js +1 -1
  34. package/src/tools/tab-browser-tools.js +52 -9
  35. package/src/utils/app-icon.js +1 -1
  36. package/src/utils/brand-host-electron.js +1 -1
  37. package/src/utils/context-menu-options.js +65 -19
  38. package/src/utils/desktop-snapshot.js +2 -2
  39. package/src/utils/rpc-audit.js +3 -2
  40. package/src/utils/window-utils.js +2 -2
  41. package/workers/render/src/App.css +11 -5
  42. package/workers/render/src/App.jsx +313 -154
  43. package/src/backends/homepage-react/assets/index-C2eZCaPp.js +0 -377
  44. package/src/backends/homepage-react/assets/index-CyUwy5Um.css +0 -1
@@ -55,7 +55,7 @@ jobs:
55
55
 
56
56
  - name: Build WSL rootfs (Ubuntu + Docker, image NOT baked)
57
57
  run: |
58
- # 主人: image NO LONGER baked into the rootfs. wsl-docker.bootstrap downloads +
58
+ # image NO LONGER baked into the rootfs. wsl-docker.bootstrap downloads +
59
59
  # docker-loads cicy-code-latest.tar.gz at setup (像 mac/colima 那样) → WSL 也拿最新
60
60
  # 烤制镜像,且镜像更新不必重下整个 rootfs(rootfs=Ubuntu+Docker 很少变,瘦了 ~169MB)。
61
61
  docker pull "${{ inputs.image }}"
@@ -23,7 +23,7 @@ jobs:
23
23
  node-version: "20"
24
24
  cache: "npm"
25
25
 
26
- # cicy-code is NOT built-from-source here anymore (主人 2026-06): bundled
26
+ # cicy-code is NOT built-from-source here anymore (2026-06): bundled
27
27
  # sidecar = the per-platform optionalDependency, seeded by localbin at runtime.
28
28
  # The .cicy-code-ref source-build → vendor/cicy-code path was stale + never
29
29
  # packaged, so it's removed. Sync just pins optionalDeps to latest.
@@ -36,7 +36,7 @@ jobs:
36
36
  - name: Install Electron build dependencies
37
37
  run: npm install --save-dev --no-audit electron@41.0.2 electron-builder@26.7.0
38
38
 
39
- # 主人(2026-06 关键修复): runner 是 x64,npm 只装 linux-x64 的 cicy-code/mihomo →
39
+ # (2026-06 关键修复): runner 是 x64,npm 只装 linux-x64 的 cicy-code/mihomo →
40
40
  # linux-arm64 用户的包里塞的是 x64 二进制。强制把两个 linux 架构都装进 node_modules,
41
41
  # electron-builder 两架构都打包,localbin 按用户机器选。必须在所有 npm install 之后。
42
42
  - name: Bundle BOTH linux arches of cicy-code/mihomo (runner is single-arch)
@@ -23,7 +23,7 @@ jobs:
23
23
  node-version: "20"
24
24
  cache: "npm"
25
25
 
26
- # cicy-code is NOT built-from-source here anymore. 主人(2026-06): the bundled
26
+ # cicy-code is NOT built-from-source here anymore. (2026-06): the bundled
27
27
  # sidecar = the per-platform optionalDependency (cicy-code-<plat>, prebuilt +
28
28
  # arm64 linker-adhoc-signed), seeded at runtime by localbin.fromBundle. The old
29
29
  # .cicy-code-ref source-build → vendor/cicy-code path was stale + never packaged
@@ -38,7 +38,7 @@ jobs:
38
38
  - name: Install Electron build dependencies in project directory
39
39
  run: npm install --save-dev --no-audit electron@41.0.2 electron-builder@26.7.0
40
40
 
41
- # 主人(2026-06 关键修复): macos-latest runner 是 arm64,`npm install` 的 os/cpu
41
+ # (2026-06 关键修复): macos-latest runner 是 arm64,`npm install` 的 os/cpu
42
42
  # 过滤只装 arm64 的 cicy-code/mihomo 子包 → x64(Intel)的 .pkg 里塞的也是 arm64
43
43
  # 二进制 → Intel fresh 装没 :8008(实测 josephs)。这里强制把 BOTH darwin 架构都
44
44
  # 装进 node_modules(--force 绕过 EBADPLATFORM),让 electron-builder 两架构都打包,
package/bin/cicy-desktop CHANGED
@@ -138,7 +138,7 @@ function provisionElectronFromMirror(bundledDir) {
138
138
  const { zip, exe } = electronArtifact();
139
139
  const { url, src } = electronZipUrl();
140
140
  const curl = isWindows ? "curl.exe" : "curl";
141
- // 缓存到 ~/Downloads(主人:下到 Downloads,下过就别再下,最好断点续传):
141
+ // 缓存到 ~/Downloads(下到 Downloads,下过就别再下,最好断点续传):
142
142
  // • 已完整(大小==远端)→ 直接复用,不再下;
143
143
  // • 没下全(部分)→ curl -C - 断点续传;
144
144
  // • 没有 → 全新下载。下完保留 zip,不删,下次免下。
@@ -149,10 +149,10 @@ function provisionElectronFromMirror(bundledDir) {
149
149
  let localSz = 0; try { localSz = fs.statSync(dest).size; } catch {}
150
150
  const complete = localSz >= 50 * 1024 * 1024 && (!expected || localSz === expected);
151
151
  if (complete) {
152
- console.log(`✓ 复用已下载的 Electron:${dest}`);
152
+ console.log(`[ok] 复用已下载的 Electron:${dest}`);
153
153
  } else {
154
154
  const resuming = localSz > 0;
155
- console.log(`⬇️ 下载 Electron ${ELECTRON_VERSION}(来源:${src}${resuming ? ",断点续传" : ""})→ ${dest}`);
155
+ console.log(` 下载 Electron ${ELECTRON_VERSION}(来源:${src}${resuming ? ",断点续传" : ""})→ ${dest}`);
156
156
  // -C - 断点续传(部分则 206 续,缺则 200 全下);-# 进度条;inherit 让进度条画到终端。
157
157
  execFileSync(curl, ["-fL", "-#", "-C", "-", "--retry", "5", "--retry-delay", "2", "--connect-timeout", "20", "-o", dest, url], { stdio: "inherit" });
158
158
  try { localSz = fs.statSync(dest).size; } catch {}
@@ -170,7 +170,7 @@ function provisionElectronFromMirror(bundledDir) {
170
170
  try { fs.chmodSync(path.join(distDir, exe), 0o755); } catch {}
171
171
  }
172
172
  fs.writeFileSync(path.join(bundledDir, "path.txt"), exe);
173
- // 不删 dest:留在 ~/Downloads 缓存,下次免下(主人:下过就别再下)。
173
+ // 不删 dest:留在 ~/Downloads 缓存,下次免下(下过就别再下)。
174
174
  }
175
175
 
176
176
  // Make sure a USABLE electron exists before spawning the worker. A pre-existing
@@ -213,14 +213,14 @@ function ensureElectron() {
213
213
  // which is broken on win32 + node 24 (@electron-internal extract-zip native
214
214
  // binding "intentionally not published" → "Cannot find native binding").
215
215
  try { ensureMinimalElectronPkg(bundledDir); }
216
- catch (e) { console.warn(`⚠️ could not set up electron dir ${bundledDir}: ${e.message}`); return; }
217
- console.log(`⚙️ Fetching Electron ${ELECTRON_VERSION} from mirror (one-time)…`);
216
+ catch (e) { console.warn(`[warn] could not set up electron dir ${bundledDir}: ${e.message}`); return; }
217
+ console.log(`[setup] Fetching Electron ${ELECTRON_VERSION} from mirror (one-time)…`);
218
218
  try {
219
219
  provisionElectronFromMirror(bundledDir);
220
220
  if (electronBinaryHealthy(bundledDir)) return;
221
- console.warn(`⚠️ Electron provisioned but health check still failing.`);
221
+ console.warn(`[warn] Electron provisioned but health check still failing.`);
222
222
  } catch (e) {
223
- console.warn(`⚠️ Electron provision from mirror failed: ${e.message}`);
223
+ console.warn(`[warn] Electron provision from mirror failed: ${e.message}`);
224
224
  }
225
225
  }
226
226
 
@@ -268,7 +268,7 @@ for (let i = 0; i < args.length; i++) {
268
268
  } else if (arg === "-v" || arg === "--version") {
269
269
  showVersion = true;
270
270
  } else if (arg === "-j" || arg === "--json") {
271
- console.error(" --json is only supported by cicy-rpc");
271
+ console.error("[x] --json is only supported by cicy-rpc");
272
272
  process.exit(1);
273
273
  } else if (arg === "-cn" || arg === "--cn") {
274
274
  useCNMirror = true;
@@ -289,12 +289,12 @@ for (let i = 0; i < args.length; i++) {
289
289
  }
290
290
 
291
291
  if (!Number.isFinite(masterPort) || masterPort <= 0) {
292
- console.error(" Invalid --master-port value");
292
+ console.error("[x] Invalid --master-port value");
293
293
  process.exit(1);
294
294
  }
295
295
 
296
296
  if (!Number.isFinite(workerPort) || workerPort <= 0) {
297
- console.error(" Invalid --port value");
297
+ console.error("[x] Invalid --port value");
298
298
  process.exit(1);
299
299
  }
300
300
 
@@ -306,9 +306,9 @@ if (showVersion) {
306
306
  if (useCNMirror) {
307
307
  try {
308
308
  execSync("npm config set registry https://registry.npmmirror.com", { stdio: "inherit" });
309
- console.log("📦 Using CN npm mirror: https://registry.npmmirror.com");
309
+ console.log("[npm] Using CN npm mirror: https://registry.npmmirror.com");
310
310
  } catch (err) {
311
- console.error(" Failed to set npm mirror:", err.message);
311
+ console.error("[x] Failed to set npm mirror:", err.message);
312
312
  }
313
313
  }
314
314
 
@@ -349,13 +349,13 @@ RPC commands moved to: cicy-rpc`);
349
349
  }
350
350
 
351
351
  function update() {
352
- console.log("🔄 Updating cicy...");
352
+ console.log("[update] Updating cicy...");
353
353
  try {
354
354
  execSync("git pull", { cwd: PACKAGE_ROOT, stdio: "inherit" });
355
355
  execSync("npm install", { cwd: PACKAGE_ROOT, stdio: "inherit" });
356
- console.log(" cicy updated successfully");
356
+ console.log("[ok] cicy updated successfully");
357
357
  } catch (err) {
358
- console.error(" Update failed:", err.message);
358
+ console.error("[x] Update failed:", err.message);
359
359
  process.exit(1);
360
360
  }
361
361
  }
@@ -458,7 +458,7 @@ async function stopPid(pid, label) {
458
458
  try {
459
459
  process.kill(pid, "SIGTERM");
460
460
  } catch (error) {
461
- console.error(`❌ Failed to stop ${label}: ${error.message}`);
461
+ console.error(`[x] Failed to stop ${label}: ${error.message}`);
462
462
  return false;
463
463
  }
464
464
 
@@ -473,7 +473,7 @@ async function stopPid(pid, label) {
473
473
  process.kill(pid, "SIGKILL");
474
474
  return true;
475
475
  } catch (error) {
476
- console.error(`❌ Failed to force stop ${label}: ${error.message}`);
476
+ console.error(`[x] Failed to force stop ${label}: ${error.message}`);
477
477
  return false;
478
478
  }
479
479
  }
@@ -516,7 +516,7 @@ function killAllElectronProcesses() {
516
516
  }
517
517
 
518
518
  function hardCleanupBeforeStart({ masterPort, workerPort }) {
519
- console.log("🧹 Cleaning up previous instance…");
519
+ console.log("[cleanup] Cleaning up previous instance…");
520
520
  killListenersByPort(masterPort);
521
521
  killListenersByPort(workerPort);
522
522
  killAllElectronProcesses();
@@ -526,7 +526,7 @@ function startForegroundCluster() {
526
526
  hardCleanupBeforeStart({ masterPort, workerPort });
527
527
  ensureDesktopCommandFile();
528
528
  startWorkerOnly({ workerPort }).catch((error) => {
529
- console.error(`❌ Failed to start worker: ${error.message}`);
529
+ console.error(`[x] Failed to start worker: ${error.message}`);
530
530
  process.exit(1);
531
531
  });
532
532
  }
@@ -538,19 +538,19 @@ function executeCommand(cmd) {
538
538
  break;
539
539
  case "stop":
540
540
  stop().catch((error) => {
541
- console.error(`❌ Failed to stop cicy worker: ${error.message}`);
541
+ console.error(`[x] Failed to stop cicy worker: ${error.message}`);
542
542
  process.exit(1);
543
543
  });
544
544
  break;
545
545
  case "status":
546
546
  status().catch((error) => {
547
- console.error(`❌ Failed to get cicy worker status: ${error.message}`);
547
+ console.error(`[x] Failed to get cicy worker status: ${error.message}`);
548
548
  process.exit(1);
549
549
  });
550
550
  break;
551
551
  case "restart":
552
552
  restart().catch((error) => {
553
- console.error(`❌ Failed to restart cicy worker: ${error.message}`);
553
+ console.error(`[x] Failed to restart cicy worker: ${error.message}`);
554
554
  process.exit(1);
555
555
  });
556
556
  break;
@@ -633,7 +633,7 @@ function ensureMacDesktopApp() {
633
633
  fs.copyFileSync(icns, path.join(appDir, "Contents", "Resources", "applet.icns"));
634
634
  }
635
635
  try { const t = new Date(); fs.utimesSync(appDir, t, t); } catch {}
636
- console.log(`📎 Desktop shortcut: ${appDir}`);
636
+ console.log(`[shortcut] Desktop shortcut: ${appDir}`);
637
637
  } finally {
638
638
  try { fs.unlinkSync(tmp); } catch {}
639
639
  }
@@ -654,7 +654,7 @@ Terminal=false
654
654
  Categories=Development;
655
655
  `);
656
656
  fs.chmodSync(file, 0o755);
657
- console.log(`📎 Desktop shortcut: ${file}`);
657
+ console.log(`[shortcut] Desktop shortcut: ${file}`);
658
658
  }
659
659
 
660
660
  function ensureWindowsShortcut() {
@@ -682,7 +682,7 @@ $s.Save()
682
682
  `);
683
683
  try {
684
684
  execSync(`powershell -NoProfile -ExecutionPolicy Bypass -File "${ps}"`, { stdio: "ignore" });
685
- console.log(`📎 Desktop shortcut: ${lnk}`);
685
+ console.log(`[shortcut] Desktop shortcut: ${lnk}`);
686
686
  } finally {
687
687
  try { fs.unlinkSync(ps); } catch {}
688
688
  }
@@ -946,9 +946,9 @@ async function startWorkerOnly({ workerPort }) {
946
946
  // httpEnabled=automationEnabled), so don't advertise http://localhost:PORT or
947
947
  // the /console/chrome UI: those URLs are dead unless CICY_DESKTOP_HTTP=1/--mcp.
948
948
  // Renderer RPC goes through electronRPC injected in preload, not this port.
949
- console.log("🚀 Starting CiCy Desktop…");
950
- console.log(`📄 Token file: ${tokenManager.getConfigPath()}`);
951
- console.log("🛑 Press Ctrl+C to stop processes started by this command");
949
+ console.log("[start] Starting CiCy Desktop…");
950
+ console.log(`[token] Token file: ${tokenManager.getConfigPath()}`);
951
+ console.log("[stop] Press Ctrl+C to stop processes started by this command");
952
952
 
953
953
  const electronSpawn = resolveElectronSpawn();
954
954
  const workerChild = spawn(
@@ -1000,7 +1000,7 @@ async function startWorkerOnly({ workerPort }) {
1000
1000
 
1001
1001
  workerChild.once("exit", async (code, signal) => {
1002
1002
  if (shuttingDown) return;
1003
- console.error(`❌ Worker exited (code=${code}, signal=${signal})`);
1003
+ console.error(`[x] Worker exited (code=${code}, signal=${signal})`);
1004
1004
  await handleShutdown(code || 1);
1005
1005
  });
1006
1006
  }
@@ -1021,24 +1021,24 @@ async function startMasterCluster({ masterPort, workerPort }) {
1021
1021
  startedAt: new Date().toISOString(),
1022
1022
  });
1023
1023
 
1024
- console.log(`🚀 Target master ${masterBaseUrl}`);
1025
- console.log(`📄 Token file: ${tokenManager.getConfigPath()}`);
1024
+ console.log(`[start] Target master ${masterBaseUrl}`);
1025
+ console.log(`[token] Token file: ${tokenManager.getConfigPath()}`);
1026
1026
 
1027
1027
  const masterRunning = await checkMaster(masterBaseUrl);
1028
1028
  if (masterRunning) {
1029
1029
  const worker = await findReusableWorker(masterBaseUrl, workerPort);
1030
1030
  if (worker) {
1031
1031
  await focusExistingWorker(worker, `http://localhost:${workerPort}`, workerUiUrl);
1032
- console.log(" Reused existing master and worker, focused Electron window");
1032
+ console.log("[ok] Reused existing master and worker, focused Electron window");
1033
1033
  return;
1034
1034
  }
1035
1035
  }
1036
1036
 
1037
- console.log("🛑 Press Ctrl+C to stop processes started by this command");
1037
+ console.log("[stop] Press Ctrl+C to stop processes started by this command");
1038
1038
 
1039
1039
  let masterChild = null;
1040
1040
  if (!masterRunning) {
1041
- console.log(`🚀 Starting master on ${masterBaseUrl}`);
1041
+ console.log(`[start] Starting master on ${masterBaseUrl}`);
1042
1042
  masterChild = spawn(process.execPath, [MASTER_ENTRY], {
1043
1043
  cwd: PACKAGE_ROOT,
1044
1044
  env: {
@@ -1060,10 +1060,10 @@ async function startMasterCluster({ masterPort, workerPort }) {
1060
1060
 
1061
1061
  await waitForMasterReady(masterChild, masterPort);
1062
1062
  } else {
1063
- console.log("♻️ Reusing existing master");
1063
+ console.log("[reuse] Reusing existing master");
1064
1064
  }
1065
1065
 
1066
- console.log(`🚀 Starting worker on http://localhost:${workerPort}`);
1066
+ console.log(`[start] Starting worker on http://localhost:${workerPort}`);
1067
1067
  const workerChild = await startWorker({ workerPort, masterBaseUrl, token, workerUiUrl });
1068
1068
 
1069
1069
  writeClusterState({
@@ -1095,14 +1095,14 @@ async function startMasterCluster({ masterPort, workerPort }) {
1095
1095
  if (masterChild) {
1096
1096
  masterChild.once("exit", async (code, signal) => {
1097
1097
  if (shuttingDown) return;
1098
- console.error(`❌ Master exited (code=${code}, signal=${signal})`);
1098
+ console.error(`[x] Master exited (code=${code}, signal=${signal})`);
1099
1099
  await handleShutdown(code || 1);
1100
1100
  });
1101
1101
  }
1102
1102
 
1103
1103
  workerChild.once("exit", async (code, signal) => {
1104
1104
  if (shuttingDown) return;
1105
- console.error(`❌ Worker exited (code=${code}, signal=${signal})`);
1105
+ console.error(`[x] Worker exited (code=${code}, signal=${signal})`);
1106
1106
  await handleShutdown(code || 1);
1107
1107
  });
1108
1108
  }
@@ -1127,7 +1127,7 @@ function getClusterLogFiles(workerPort) {
1127
1127
  async function stop() {
1128
1128
  const state = getRunningClusterState();
1129
1129
  if (!state) {
1130
- console.log(" cicy worker is not running");
1130
+ console.log("[x] cicy worker is not running");
1131
1131
  clearClusterState();
1132
1132
  return;
1133
1133
  }
@@ -1137,20 +1137,20 @@ async function stop() {
1137
1137
  clearClusterState();
1138
1138
 
1139
1139
  if (stoppedMaster || stoppedWorker) {
1140
- console.log(`✅ cicy worker stopped (pid:${state.workerPid || "-"})`);
1140
+ console.log(`[ok] cicy worker stopped (pid:${state.workerPid || "-"})`);
1141
1141
  } else {
1142
- console.log(" cicy worker is not running");
1142
+ console.log("[x] cicy worker is not running");
1143
1143
  }
1144
1144
  }
1145
1145
 
1146
1146
  async function status() {
1147
1147
  const state = getRunningClusterState();
1148
1148
  if (!state) {
1149
- console.log(" cicy worker is not running");
1149
+ console.log("[x] cicy worker is not running");
1150
1150
  return;
1151
1151
  }
1152
1152
 
1153
- console.log(" cicy worker is running");
1153
+ console.log("[ok] cicy worker is running");
1154
1154
  console.log(
1155
1155
  `- worker pid: ${state.workerPid || "reused external"} (${state.workerRunning ? "running" : "stopped"})`
1156
1156
  );
@@ -1173,7 +1173,7 @@ function logs() {
1173
1173
  );
1174
1174
 
1175
1175
  if (!logFiles.length) {
1176
- console.log(" No worker logs found");
1176
+ console.log("[x] No worker logs found");
1177
1177
  console.log(`- logs dir: ${LOGS_DIR}`);
1178
1178
  console.log(
1179
1179
  `- expected worker log: ${path.join(LOGS_DIR, `cicy-desktop-${workerPortForLogs}.log`)}`
@@ -1182,10 +1182,10 @@ function logs() {
1182
1182
  }
1183
1183
 
1184
1184
  if (state) {
1185
- console.log(" Following cicy worker logs");
1185
+ console.log("[ok] Following cicy worker logs");
1186
1186
  console.log(`- worker url: http://localhost:${state.workerPort}`);
1187
1187
  } else {
1188
- console.log("⚠️ Worker is not currently running, showing latest available logs");
1188
+ console.log("[warn] Worker is not currently running, showing latest available logs");
1189
1189
  }
1190
1190
  logFiles.forEach((filePath) => console.log(`- ${filePath}`));
1191
1191
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cicy-desktop",
3
- "version": "2.1.197",
3
+ "version": "2.1.199",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -137,14 +137,14 @@
137
137
  "zod": "3.25",
138
138
  "electron-updater": "6.6.2"
139
139
  },
140
- "//optionalDependencies": "主人(2026-06 回调): mac/linux 改回 native cicy-code(:8008,colima 在 16G mac 上压垮内存)→ 重新内置 cicy-code-<plat> / cicy-mihomo-<plat>,localbin.fromBundle 零网络 seed(npm 仅作更新通道,带 npmmirror→npmjs 回退)。这些由 scripts/sync-runtime-deps.cjs 在 tag-push 时同步到最新版。npm 的 os/cpu 字段保证每个平台只装自己那份。Windows 仍走 docker(WSL :8009),它那份 cicy-code-windows 用不到但 bundle 着无害。",
140
+ "//optionalDependencies": "(2026-06 回调): mac/linux 改回 native cicy-code(:8008,colima 在 16G mac 上压垮内存)→ 重新内置 cicy-code-<plat> / cicy-mihomo-<plat>,localbin.fromBundle 零网络 seed(npm 仅作更新通道,带 npmmirror→npmjs 回退)。这些由 scripts/sync-runtime-deps.cjs 在 tag-push 时同步到最新版。npm 的 os/cpu 字段保证每个平台只装自己那份。Windows 仍走 docker(WSL :8009),它那份 cicy-code-windows 用不到但 bundle 着无害。",
141
141
  "optionalDependencies": {
142
142
  "electron": "41.0.3",
143
- "cicy-code-darwin-x64": "2.3.28",
144
- "cicy-code-darwin-arm64": "2.3.28",
145
- "cicy-code-linux-x64": "2.3.28",
146
- "cicy-code-linux-arm64": "2.3.28",
147
- "cicy-code-windows-x64": "2.3.28",
143
+ "cicy-code-darwin-x64": "2.3.36",
144
+ "cicy-code-darwin-arm64": "2.3.36",
145
+ "cicy-code-linux-x64": "2.3.36",
146
+ "cicy-code-linux-arm64": "2.3.36",
147
+ "cicy-code-windows-x64": "2.3.36",
148
148
  "cicy-mihomo-darwin-x64": "1.10.4",
149
149
  "cicy-mihomo-darwin-arm64": "1.10.4",
150
150
  "cicy-mihomo-linux-x64": "1.10.4",
@@ -45,7 +45,7 @@ xattr -cr "$DEST_APP" 2>/dev/null || true
45
45
  codesign --force --deep --sign - "$DEST_APP" 2>/dev/null || \
46
46
  echo " (codesign 警告可忽略,quarantine 已清即可打开)"
47
47
 
48
- # 桌面快捷方式(主人: 要快捷方式)+ 启动台/Spotlight 已自动收录(在 /Applications 里)
48
+ # 桌面快捷方式(要快捷方式)+ 启动台/Spotlight 已自动收录(在 /Applications 里)
49
49
  ln -sfn "$DEST_APP" "$HOME/Desktop/$APP_NAME.app" 2>/dev/null && echo "==> 桌面快捷方式已建" || true
50
50
 
51
51
  # ── 3) (可选)预暂存 docker 包 —— 仅当 bundle 里带了 docker/ 时(全离线包)。
@@ -3,7 +3,7 @@
3
3
  // cicy-mihomo subpackages, so every cicy-desktop build/publish bundles the
4
4
  // newest binaries. Run in CI before install/build (and before `npm publish`).
5
5
  //
6
- // 主人指令 (2026-06-08): Windows no longer ships msys2/tmux — the win sidecar
6
+ // (2026-06-08): Windows no longer ships msys2/tmux — the win sidecar
7
7
  // runs the single headless 团队助手 (--helper), so cicy-msys2-* is DROPPED here.
8
8
  //
9
9
  // Usage: node scripts/sync-runtime-deps.cjs (writes package.json in place)
@@ -157,9 +157,9 @@ contextBridge.exposeInMainWorld("cicy", {
157
157
  ipcRenderer.on("docker:bootstrap-progress", handler);
158
158
  return () => ipcRenderer.removeListener("docker:bootstrap-progress", handler);
159
159
  },
160
- // Docker-版 cicy-code on :8009 (the homepage "Docker cicy-code" card).
160
+ // Docker-版 cicy-code on :8008 (the homepage "Docker cicy-code" card).
161
161
  // appStatus → { installed, running, port, platform }; appBootstrap installs
162
- // Docker (if missing, installer → Desktop) + starts the :8009 container,
162
+ // Docker (if missing, installer → Desktop) + starts the :8008 container,
163
163
  // streaming phase/progress on 'docker:app-progress'.
164
164
  appStatus: () => logInvoke("docker:app-status"),
165
165
  appRedetect: () => logInvoke("docker:app-redetect"), // 「重试检测」: FORCE a fresh probe (appStatus only reads cache)
@@ -168,12 +168,13 @@ contextBridge.exposeInMainWorld("cicy", {
168
168
  appDockerRestart: () => logInvoke("docker:app-docker-restart"), // docker restart 整个容器
169
169
  appRecreate: () => logInvoke("docker:app-recreate"), // 删容器+重建(换 key,需 confirm)
170
170
  appAuthorizeHostSsh: () => logInvoke("docker:app-authorize-host-ssh"), // 仅 macOS:授权容器经 SSH 访问 Mac
171
- appChromeProxy: (on) => logInvoke("docker:app-chrome-proxy", on), // 开关:宿主 mihomo 给系统 Chrome 当 per-profile 代理
172
171
  appUpdate: () => logInvoke("docker:app-update"),
173
172
  appStop: () => logInvoke("docker:app-stop"),
174
173
  appUpgrade: () => logInvoke("docker:app-upgrade"),
175
- // Open :8009 with the live container token (refuses if it can't read it).
174
+ // Open :8008 with the live container token (refuses if it can't read it).
176
175
  appOpen: () => logInvoke("docker:app-open"),
176
+ openDir: (which) => logInvoke("docker:open-dir", which), // "projects"→C:\projects, 否则 WSL 卷
177
+
177
178
  onAppProgress: (cb) => {
178
179
  const handler = (_e, ev) => { try { cb(ev); } catch {} };
179
180
  ipcRenderer.on("docker:app-progress", handler);
@@ -212,6 +213,9 @@ contextBridge.exposeInMainWorld("cicy", {
212
213
  reload: (url, title) => logInvoke("tabs:reload", { url, title }),
213
214
  reloadIfOpen: (url, title) => logInvoke("tabs:reloadIfOpen", { url, title }),
214
215
  activateIfOpen: (url) => logInvoke("tabs:activateIfOpen", { url }),
216
+ // 开在指定 profile(accountIdx → persist:sandbox-N)的 tab 里。cicy-ai 云端页面
217
+ // 开在 profile 1(走 proxy),不再用系统浏览器。
218
+ openIn: (accountIdx, url, title) => logInvoke("tabs:openIn", { accountIdx, url, title }),
215
219
  },
216
220
 
217
221
  // ------- new bridges (last rebuild!) -------