cicy-desktop 2.1.174 → 2.1.176

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.174",
3
+ "version": "2.1.176",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -82,12 +82,6 @@ async function startFromRuntime({ logPath, port }) {
82
82
  CICY_CODE_PORT: String(port),
83
83
  PORT: String(port),
84
84
  };
85
- if (process.platform === "win32") {
86
- try {
87
- const msys = runtime.binPath("msys2") || runtime.ensureFromBundle("msys2");
88
- if (msys) env.CICY_MSYS_ROOT = msys; // w-10084 exe 探测约定
89
- } catch {}
90
- }
91
85
  const c = spawn(exe, ["--desktop"], { stdio, detached: false, windowsHide: true, env });
92
86
  console.log(`[cicy-code-sidecar] spawned runtime ${exe} --desktop (v${runtime.currentVersion("cicy-code")}) pid=${c.pid} port=${port}`);
93
87
  c.on("exit", (code, signal) => {
@@ -141,8 +135,8 @@ async function start({ logPath, port = DEFAULT_PORT, force = false, version = nu
141
135
  PORT: String(port),
142
136
  };
143
137
  // --helper removed (主人指令): Windows now runs cicy-code in normal mode (full
144
- // tmux-based multi-agent via the bundled MSYS2 runtime), same as mac/linux —
145
- // no longer the single headless 团队助手.
138
+ // tmux-based multi-agent), same as mac/linux — no longer the single headless
139
+ // 团队助手.
146
140
  const args = ["--desktop"];
147
141
  child = spawn(exe, args, { stdio, detached: false, windowsHide: true, env });
148
142
  console.log(`[cicy-code-sidecar] spawned ${exe} ${args.join(" ")} pid=${child.pid} port=${port} log=${logPath || "(none)"}`);
@@ -247,10 +247,18 @@ Drop files here for CiCy agents to read; files agents write to Share show up her
247
247
 
248
248
  function shareMountArg() {
249
249
  try {
250
- const share = path.join(os.homedir(), "Desktop", "Share");
250
+ // 主人: Share 真实目录放 ~/cicy-ai/Share —— 不能用 ~/Desktop:macOS TCC 挡着 colima(VM)
251
+ // 访问 Desktop/Documents/Downloads,docker 建挂载源时报 'mkdir …/Desktop: operation not
252
+ // permitted' → 容器起不来。~/cicy-ai 非 TCC、colima 能挂。再在 Desktop 放个软链(桌面可见;
253
+ // 失败无所谓,真实目录已可用)。
254
+ const share = path.join(os.homedir(), "cicy-ai", "Share");
251
255
  fs.mkdirSync(share, { recursive: true });
252
256
  const readme = path.join(share, "readme.md");
253
257
  if (!fs.existsSync(readme)) { try { fs.writeFileSync(readme, SHARE_README); } catch {} }
258
+ try {
259
+ const link = path.join(os.homedir(), "Desktop", "Share");
260
+ if (!fs.existsSync(link)) fs.symlinkSync(share, link);
261
+ } catch {}
254
262
  return `-v '${share}':/home/cicy/cicy-ai/Share`;
255
263
  } catch { return ""; }
256
264
  }
@@ -266,9 +274,19 @@ async function runContainer({ port = 8009, container = "cicy-code-docker-8009",
266
274
  // docker-only 后 mihomo 只在容器里,这些口不暴露则主机系统 Chrome 的代理 127.0.0.1:(20000+N)
267
275
  // 连不上。默认 20001-20032(32 个 profile),CICY_CHROME_PROXY_PORTS 可调。
268
276
  const CHROME_PROXY_PORTS = process.env.CICY_CHROME_PROXY_PORTS || "20001-20032";
269
- const cmd = `run -d --name ${container} --restart unless-stopped ${PLATFORM_FLAG} ` +
270
- `-p 127.0.0.1:${port}:8008 -p 127.0.0.1:${CHROME_PROXY_PORTS}:${CHROME_PROXY_PORTS} -e CICY_PUBLIC=1 -v ${volume}:/home/cicy ${shareMountArg()} ${envArgs} ${IMAGE}`;
271
- await dk(cmd, { timeout: 90000 });
277
+ const mk = (s) => `run -d --name ${container} --restart unless-stopped ${PLATFORM_FLAG} ` +
278
+ `-p 127.0.0.1:${port}:8008 -p 127.0.0.1:${CHROME_PROXY_PORTS}:${CHROME_PROXY_PORTS} -e CICY_PUBLIC=1 -v ${volume}:/home/cicy ${s} ${envArgs} ${IMAGE}`;
279
+ const share = shareMountArg();
280
+ try {
281
+ await dk(mk(share), { timeout: 90000 });
282
+ } catch (e) {
283
+ if (!share) throw e;
284
+ // 兜底: 带 Share 启动失败(如 macOS TCC 挡 colima 访问挂载源)→ 去掉 Share 重试,保证容器
285
+ // 一定能起(Share 只是附加共享目录,不该挡住整个服务). 主人: '容器起不来' 的修复.
286
+ console.warn(`[colima] 带 Share 启动失败,去掉 Share 重试: ${e.message}`);
287
+ try { await dk(`rm -f ${container}`, { timeout: 20000 }); } catch {}
288
+ await dk(mk(""), { timeout: 90000 });
289
+ }
272
290
  return { started: true };
273
291
  }
274
292
 
@@ -2,10 +2,8 @@
2
2
  // WSL. (2026-06 方向变更: the Docker route in docker.js is transitional and
3
3
  // being retired; this module replaces it once stable.)
4
4
  //
5
- // The exe is a native Go build (w-10084's line). It shells out to a slim
6
- // bundled MSYS2 (bash/tmux/coreutils…) which it locates itself via
7
- // CICY_MSYS_ROOT probing — nothing to do here beyond optionally passing the
8
- // env through. Known exe-side behaviors we rely on:
5
+ // The exe is a native Go build (w-10084's line). Known exe-side behaviors we
6
+ // rely on:
9
7
  // - reads PORT / CICY_CODE_PORT for the listen port
10
8
  // - missing optional deps degrade to warnings (never os.Exit)
11
9
  // - cold tmux-server start may need ConPTY (w-10084's ensureTmuxServer, WIP)
@@ -1,12 +1,11 @@
1
1
  // Runtime Bundle v1 — versioned component store for everything cicy-desktop
2
- // runs locally (cicy-code, mihomo, and on Windows the slim MSYS2 tree).
2
+ // runs locally (cicy-code, mihomo).
3
3
  //
4
4
  // Layout:
5
5
  // ~/cicy-ai/runtime/
6
6
  // versions.json { "<comp>": { "current": "<ver>" }, ... }
7
7
  // cicy-code/<ver>/cicy-code(.exe)
8
8
  // mihomo/<ver>/mihomo(.exe)
9
- // msys2/<ver>/usr/bin/bash.exe (win32 only, directory component)
10
9
  //
11
10
  // Sourcing order:
12
11
  // 1. first run: copy out of cicy-desktop's own node_modules — the platform
@@ -32,8 +31,8 @@ const IS_WIN = process.platform === "win32";
32
31
 
33
32
  // npm subpackage platform suffix. NOTE: Windows is "windows" not "win32" —
34
33
  // npm's spam filter 403s NEW package names containing 'win32', so EVERY cicy
35
- // subpackage (code/mihomo/msys2) is published as *-windows-*. This must match
36
- // the published names exactly or both the bundled-dir lookup AND the npm-pull
34
+ // subpackage (code/mihomo) is published as *-windows-*. This must match the
35
+ // published names exactly or both the bundled-dir lookup AND the npm-pull
37
36
  // fallback fail (a 404 that stranded first start on Windows).
38
37
  function plat() {
39
38
  const osStr = IS_WIN ? "windows" : process.platform === "darwin" ? "darwin" : "linux";
@@ -42,7 +41,6 @@ function plat() {
42
41
  }
43
42
 
44
43
  // kind "bin": single executable at the package root.
45
- // kind "dir": a directory tree (msys2) — `check` is the file proving it's intact.
46
44
  const COMPONENTS = {
47
45
  "cicy-code": {
48
46
  kind: "bin",
@@ -54,12 +52,6 @@ const COMPONENTS = {
54
52
  pkg: () => `cicy-mihomo-${plat()}`,
55
53
  bin: () => (IS_WIN ? "mihomo.exe" : "mihomo"),
56
54
  },
57
- "msys2": {
58
- kind: "dir",
59
- winOnly: true,
60
- pkg: () => "cicy-msys2-windows-x64",
61
- check: path.join("usr", "bin", "bash.exe"),
62
- },
63
55
  };
64
56
 
65
57
  function readVersions() {
@@ -83,19 +75,13 @@ function versionDir(comp, ver) {
83
75
  return path.join(RUNTIME_DIR, comp, ver);
84
76
  }
85
77
 
86
- // Absolute path of the component's current payload the executable for "bin"
87
- // components, the root dir for "dir" components. null when not installed.
78
+ // Absolute path of the component's current executable. null when not installed.
88
79
  function binPath(comp) {
89
80
  const c = COMPONENTS[comp];
90
81
  const ver = currentVersion(comp);
91
82
  if (!c || !ver) return null;
92
- const p = c.kind === "dir" ? versionDir(comp, ver) : path.join(versionDir(comp, ver), c.bin());
93
- const probe = c.kind === "dir" ? path.join(p, c.check) : p;
94
- return fs.existsSync(probe) ? p : null;
95
- }
96
-
97
- function cpDirSync(src, dst) {
98
- fs.cpSync(src, dst, { recursive: true });
83
+ const p = path.join(versionDir(comp, ver), c.bin());
84
+ return fs.existsSync(p) ? p : null;
99
85
  }
100
86
 
101
87
  // Install a payload directory as <comp>@<ver> and return the version dir.
@@ -108,31 +94,10 @@ function installPayload(comp, ver, payloadDir) {
108
94
  const staging = dst + ".staging";
109
95
  fs.rmSync(staging, { recursive: true, force: true });
110
96
  fs.mkdirSync(staging, { recursive: true });
111
- if (c.kind === "dir") {
112
- // The 118MB+ MSYS2 tree ships as a single .tar.gz inside the npm package
113
- // (npm handles one big file far better than 10k tiny ones). Extract it;
114
- // otherwise the payload is already an unpacked tree → copy.
115
- const tgz = (() => { try { return fs.readdirSync(payloadDir).find((f) => /\.tar\.gz$/i.test(f)); } catch { return null; } })();
116
- if (tgz) {
117
- require("child_process").execFileSync("tar", ["-xzf", path.join(payloadDir, tgz), "-C", staging], { windowsHide: true });
118
- } else {
119
- cpDirSync(payloadDir, staging);
120
- }
121
- if (!fs.existsSync(path.join(staging, c.check))) {
122
- // the tree may be nested one level (package/msys64/usr/... or root/usr/...)
123
- const sub = fs.readdirSync(staging).find((d) =>
124
- fs.existsSync(path.join(staging, d, c.check)));
125
- if (!sub) { fs.rmSync(staging, { recursive: true, force: true }); throw new Error(`${comp}: ${c.check} missing in package`); }
126
- fs.renameSync(path.join(staging, sub), staging + ".inner");
127
- fs.rmSync(staging, { recursive: true, force: true });
128
- fs.renameSync(staging + ".inner", staging);
129
- }
130
- } else {
131
- const src = path.join(payloadDir, c.bin());
132
- if (!fs.existsSync(src)) { fs.rmSync(staging, { recursive: true, force: true }); throw new Error(`${comp}: ${c.bin()} missing in package`); }
133
- fs.copyFileSync(src, path.join(staging, c.bin()));
134
- if (!IS_WIN) fs.chmodSync(path.join(staging, c.bin()), 0o755);
135
- }
97
+ const src = path.join(payloadDir, c.bin());
98
+ if (!fs.existsSync(src)) { fs.rmSync(staging, { recursive: true, force: true }); throw new Error(`${comp}: ${c.bin()} missing in package`); }
99
+ fs.copyFileSync(src, path.join(staging, c.bin()));
100
+ if (!IS_WIN) fs.chmodSync(path.join(staging, c.bin()), 0o755);
136
101
  fs.renameSync(staging, dst);
137
102
  return dst;
138
103
  }
@@ -175,7 +140,7 @@ function bundledPkgDir(comp) {
175
140
  // sourcing from the bundled subpackage. Never touches the network.
176
141
  function ensureFromBundle(comp) {
177
142
  const c = COMPONENTS[comp];
178
- if (!c || (c.winOnly && !IS_WIN)) return null;
143
+ if (!c) return null;
179
144
  const existing = binPath(comp);
180
145
  if (existing) return existing;
181
146
  const pkgDir = bundledPkgDir(comp);