cicy-desktop 2.1.101 → 2.1.102
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 +1 -1
- package/src/sidecar/docker.js +38 -2
package/package.json
CHANGED
package/src/sidecar/docker.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// https://r2.deepfetch.de5.net/docker/cicy-code-latest.tar.gz
|
|
9
9
|
//
|
|
10
10
|
// The container maps :8008 and persists ~/cicy-ai in a named volume.
|
|
11
|
-
const { execFile, spawn } = require("child_process");
|
|
11
|
+
const { execFile, execFileSync, spawn } = require("child_process");
|
|
12
12
|
const https = require("https");
|
|
13
13
|
const http = require("http");
|
|
14
14
|
const fs = require("fs");
|
|
@@ -449,6 +449,35 @@ function launchElevated(exe, args, { emit } = {}) {
|
|
|
449
449
|
});
|
|
450
450
|
}
|
|
451
451
|
|
|
452
|
+
// Docker Desktop on Windows needs a WSL2 (or Hyper-V) backend — without it the
|
|
453
|
+
// engine never starts and `docker version` can't reach the daemon, so the card
|
|
454
|
+
// hangs on "正在启动 Docker Desktop". Detect a missing WSL. `wsl` prints UTF-16
|
|
455
|
+
// and a fresh Windows without the feature says "未安装 / not installed / can be
|
|
456
|
+
// installed by running wsl.exe --install".
|
|
457
|
+
function wslMissing() {
|
|
458
|
+
if (process.platform !== "win32") return false;
|
|
459
|
+
try {
|
|
460
|
+
const out = execFileSync("wsl", ["--status"], { timeout: 8000, windowsHide: true, encoding: "utf16le", stdio: ["ignore", "pipe", "pipe"] });
|
|
461
|
+
return /未安装|not installed|--install/i.test(String(out));
|
|
462
|
+
} catch (e) {
|
|
463
|
+
const s = String((e.stdout || "") + (e.stderr || ""));
|
|
464
|
+
if (/未安装|not installed|--install/i.test(s)) return true;
|
|
465
|
+
return false; // wsl present but errored for another reason — assume OK
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Ensure the WSL2 backend exists; install it (elevated) if missing. Returns
|
|
470
|
+
// { ok } when present, or { needsReboot } after kicking off `wsl --install`
|
|
471
|
+
// (which requires admin + a Windows reboot before Docker can use it).
|
|
472
|
+
async function ensureWsl({ emit } = {}) {
|
|
473
|
+
if (!wslMissing()) return { ok: true };
|
|
474
|
+
emit && emit({ phase: "install-docker", status: "running", message: "Docker 需要 WSL2 后端,正在安装 WSL(请在管理员授权框点「是」,装完需重启 Windows)…" });
|
|
475
|
+
// --no-distribution: just the WSL2 platform (Docker brings its own distro);
|
|
476
|
+
// falls back to plain `wsl --install` on older builds that reject the flag.
|
|
477
|
+
await launchElevated("wsl", ["--install", "--no-distribution"], { emit });
|
|
478
|
+
return { ok: false, needsReboot: true };
|
|
479
|
+
}
|
|
480
|
+
|
|
452
481
|
// One-shot, idempotent, resumable bootstrap of the whole local-team stack on
|
|
453
482
|
// Windows: install Docker (if missing) → load the base image (if missing) →
|
|
454
483
|
// start the container → wait for :8008. Every step CHECKS first and SKIPS if
|
|
@@ -470,10 +499,14 @@ async function bootstrap({ onProgress, port = 8008, container = CONTAINER, volum
|
|
|
470
499
|
// re-download/re-run the installer (主人: 装了就别再下 Docker Desktop 了).
|
|
471
500
|
emit({ phase: "install-docker", status: "running", message: "Docker 已安装,正在启动 Docker Desktop…" });
|
|
472
501
|
if (needImage) imgDl = downloadImageTarball({ emit }).catch((e) => { emit({ phase: "image", status: "error", message: `镜像下载失败:${e.message}` }); return null; });
|
|
502
|
+
// Docker Desktop installed but the engine needs the WSL2 backend — install
|
|
503
|
+
// it (elevated) if missing; it requires a reboot before the daemon can run.
|
|
504
|
+
const wsl1 = await ensureWsl({ emit });
|
|
505
|
+
if (wsl1.needsReboot) { emit({ phase: "install-docker", status: "error", message: "WSL2 正在安装——装好后请【重启 Windows】,重启后回来点「重试」即可继续。" }); return { ok: false, reason: "wsl_reboot_required" }; }
|
|
473
506
|
startDockerDesktop();
|
|
474
507
|
const up = await waitUntil(dockerOk, { totalMs: 300000, everyMs: 5000 });
|
|
475
508
|
if (!up) {
|
|
476
|
-
emit({ phase: "install-docker", status: "error", message: "Docker Desktop
|
|
509
|
+
emit({ phase: "install-docker", status: "error", message: "Docker Desktop 启动超时——确认 Docker 图标变绿(首次可能要重启 Windows),再点「重试」" });
|
|
477
510
|
return { ok: false, reason: "docker_not_ready" };
|
|
478
511
|
}
|
|
479
512
|
emit({ phase: "install-docker", status: "done", message: "Docker 就绪" });
|
|
@@ -482,6 +515,9 @@ async function bootstrap({ onProgress, port = 8008, container = CONTAINER, volum
|
|
|
482
515
|
// running + the daemon coming up (主人: 装 Docker 的同时下载 R2 镜像).
|
|
483
516
|
if (needImage) imgDl = downloadImageTarball({ emit }).catch((e) => { emit({ phase: "image", status: "error", message: `镜像下载失败:${e.message}` }); return null; });
|
|
484
517
|
await installDocker({ emit, dest: installDest });
|
|
518
|
+
// Docker Desktop needs WSL2 — install it (elevated) if missing; reboot first.
|
|
519
|
+
const wsl2 = await ensureWsl({ emit });
|
|
520
|
+
if (wsl2.needsReboot) { emit({ phase: "install-docker", status: "error", message: "Docker 和 WSL2 已装好——请【重启 Windows】,重启后回来点「重试」即可继续。" }); return { ok: false, reason: "wsl_reboot_required" }; }
|
|
485
521
|
// A silent install doesn't auto-launch the daemon — explicitly start Docker
|
|
486
522
|
// Desktop once its exe lands so the user doesn't have to (主人: 安装启动有问题).
|
|
487
523
|
emit({ phase: "install-docker", status: "running", message: "启动 Docker Desktop…" });
|