cicy-desktop 2.1.166 → 2.1.167

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.166",
3
+ "version": "2.1.167",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -46,24 +46,9 @@ const APP_PORT = Number(process.env.CICY_DOCKER_APP_PORT || 8009);
46
46
  const APP_CONTAINER = process.env.CICY_DOCKER_APP_CONTAINER || `cicy-code-docker-${APP_PORT}`;
47
47
  const APP_VOLUME = process.env.CICY_DOCKER_APP_VOLUME || `cicy-team-${APP_PORT}`;
48
48
  const APP_MOUNT = process.env.CICY_DOCKER_APP_MOUNT || "/home/cicy";
49
- // 8008 and 8009 are ONE team (主人), so :8009 reaches the LLM through the cicy
50
- // gateway using 8008's TEAM key the `sk-cicy-…` apiKey already minted in 8008's
51
- // global.json providers (NOT the api_token, which is only the local access
52
- // credential). 8008 is up by the time the Docker card is used, so the key is
53
- // ready — we just read it and pass it to the container. Same key ⇒ same billing.
49
+ // :8009 docker 的网关 endpoint。key 不再从 :8008 借(native 已退役)—— 容器只用它
50
+ // 自己独立云端 team key(见 ensureDockerTeam / appOpts)。
54
51
  const GATEWAY_ENDPOINT = process.env.CICY_AI_GATEWAY_LLM_ENDPOINT || "https://gateway.cicy-ai.com";
55
- function readLocalGatewayKey() {
56
- try {
57
- const p = path.join(os.homedir(), "cicy-ai", "global.json");
58
- const g = JSON.parse(fs.readFileSync(p, "utf8"));
59
- const items = (g.providers && g.providers.items) || [];
60
- const pick =
61
- items.find((it) => it && it.apiKey && String(it.url || "").includes("gateway.cicy-ai.com")) ||
62
- items.find((it) => it && it.key === "defaultAnthropic" && it.apiKey) ||
63
- items.find((it) => it && it.apiKey);
64
- return pick ? String(pick.apiKey || "") : "";
65
- } catch { return ""; }
66
- }
67
52
 
68
53
  // ── Docker 独立云端 team ──────────────────────────────────────────────────────
69
54
  // 主人令(2026-06-21):每个 Docker 容器要有自己独立的云端 team(8008 那个本机
@@ -80,7 +65,7 @@ let dockerTeamReg = null; // { teamId, title, apiKey } — 缓存,appOpts 读它
80
65
 
81
66
  // 确保这个 docker(按 volume)有独立云端 team;返回 { teamId, title, apiKey } 或 null。
82
67
  async function ensureDockerTeam() {
83
- if (!cc || !cc.loginToken || !cc.loginToken()) return null; // 未登录 → appOpts 回退 8008 key
68
+ if (!cc || !cc.loginToken || !cc.loginToken()) return null; // 未登录 → 先不带 key,登录后重建容器再补(绝不借 8008)
84
69
  try {
85
70
  const store = readDockerTeams();
86
71
  let rec = store[APP_VOLUME];
@@ -143,7 +128,7 @@ function register({ sidecarLogPath } = {}) {
143
128
  // the 444MB rootfs) or unknown (WSL not answering — let the next tick retry).
144
129
  if (s.installed && !s.running && !s.unknown) {
145
130
  log.info("[docker-daemon] installed but :8009 down → auto-starting (bootstrap idempotent)");
146
- try { await appDocker.bootstrap(appOpts()); } catch (e) { log.warn(`[docker-daemon] auto-start failed: ${e.message}`); }
131
+ try { await appDocker.bootstrap(await appOpts()); } catch (e) { log.warn(`[docker-daemon] auto-start failed: ${e.message}`); }
147
132
  await refreshDockerStatus();
148
133
  }
149
134
  } finally { _dockerDaemonBusy = false; }
@@ -234,15 +219,15 @@ function register({ sidecarLogPath } = {}) {
234
219
  return s;
235
220
  });
236
221
 
237
- // Common run options for the :8009 instance: its own container/volume + the
238
- // LLM gateway env keyed by the 8008 team's token. (WSL: whole-home mount via
239
- // -v <volume>:/home/cicy inside wsl-docker.)
240
- const appOpts = () => {
241
- // Docker 独立 team 的网关 key 优先(ensureDockerTeam 已缓存);未登录/未建成功
242
- // 时回退 8008 key,保证容器仍有 LLM key 可用。
243
- const gwKey = (dockerTeamReg && dockerTeamReg.apiKey) || readLocalGatewayKey();
222
+ // Common run options for the :8009 instance: its own container/volume + the LLM
223
+ // gateway env. 主人: :8009 必须用「它自己独立云端 team」的 key —— ensureDockerTeam
224
+ // 没建就建(createTeam),用那个 teamId key。绝不借别人的(native :8008 已退役,
225
+ // 没得借,也不许借)。所以 appOpts async:先 await ensureDockerTeam,确保容器启动
226
+ // 前自己的 key 已就位;拿不到(未登录)就先不带 key,登录后「重建 Docker」再带上。
227
+ const appOpts = async () => {
228
+ await ensureDockerTeam().catch(() => {});
244
229
  const env = { CICY_AI_GATEWAY_LLM_ENDPOINT: GATEWAY_ENDPOINT };
245
- if (gwKey) env.CICY_AI_GATEWAY_LLM_API_KEY = gwKey;
230
+ if (dockerTeamReg && dockerTeamReg.apiKey) env.CICY_AI_GATEWAY_LLM_API_KEY = dockerTeamReg.apiKey;
246
231
  return { port: APP_PORT, container: APP_CONTAINER, volume: APP_VOLUME, env };
247
232
  };
248
233
  // Register the running :8009 instance as a (custom) team so the card's "打开"
@@ -303,7 +288,7 @@ function register({ sidecarLogPath } = {}) {
303
288
  try {
304
289
  await ensureDockerTeam(); // 启动前先确保独立云端 team + 拿到它的网关 key(appOpts 用)
305
290
  const result = await appDocker.bootstrap({
306
- ...appOpts(),
291
+ ...(await appOpts()),
307
292
  onProgress: (ev) => { try { e.sender.send("docker:app-progress", ev); } catch {} },
308
293
  });
309
294
  if (result && result.ok) await registerAppTeam();
@@ -330,7 +315,7 @@ function register({ sidecarLogPath } = {}) {
330
315
  ipcMain.handle("docker:app-recreate", async () => {
331
316
  try {
332
317
  await ensureDockerTeam();
333
- await appDocker.recreate({ ...appOpts() });
318
+ await appDocker.recreate({ ...(await appOpts()) });
334
319
  await registerAppTeam();
335
320
  return { ok: true };
336
321
  } catch (e) { return { ok: false, error: e.message }; }
@@ -360,7 +345,7 @@ function register({ sidecarLogPath } = {}) {
360
345
  try {
361
346
  await ensureDockerTeam();
362
347
  const result = await appDocker.upgrade({
363
- ...appOpts(),
348
+ ...(await appOpts()),
364
349
  onProgress: (ev) => { try { e.sender.send("docker:app-progress", ev); } catch {} },
365
350
  });
366
351
  if (result && result.ok) await registerAppTeam();
package/src/main.js CHANGED
@@ -880,6 +880,21 @@ electronApp.whenReady().then(async () => {
880
880
  // 主人: native :8008 退役 —— 不再起本机 cicy-code、不再 watchdog 保活、不再把它
881
881
  // 自动注册成「本地团队」。cicy-code 只在 docker 容器里跑(Docker 卡,:8009 那套不变,
882
882
  // 由 sidecar-ipc 自己管理)。cicyCodeSidecar 仍保留供 :8008 探活/版本查询用。
883
+ //
884
+ // 升级清理:历史遗留的「本地团队」(http://127.0.0.1:8008)节点现在是死的(native 没了),
885
+ // 它那张连不上的卡得删掉。只删这个 native :8008 节点;docker :8009 + 自定义团队不动。
886
+ (async () => {
887
+ try {
888
+ const lt = require("./backends/local-teams");
889
+ const teams = await lt.list().catch(() => []);
890
+ for (const t of (teams || [])) {
891
+ if (/\/\/127\.0\.0\.1:8008(\/|$|\b)/.test(String(t.base_url || ""))) {
892
+ await lt.removeTeam(t.id).catch(() => {});
893
+ log.info(`[migrate] removed retired native :8008 team ${t.id}`);
894
+ }
895
+ }
896
+ } catch {}
897
+ })();
883
898
 
884
899
  // Backend launcher: app menu + IPC handlers. Menu adds a Backends top-level
885
900
  // entry; IPC powers the launcher window (src/backends/launcher.html).