cicy-desktop 2.1.240 → 2.1.241

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.240",
3
+ "version": "2.1.241",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -139,10 +139,10 @@
139
139
  "//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
140
  "optionalDependencies": {
141
141
  "electron": "41.0.3",
142
- "cicy-code-darwin-x64": "2.3.202",
143
- "cicy-code-darwin-arm64": "2.3.202",
144
- "cicy-code-linux-x64": "2.3.202",
145
- "cicy-code-linux-arm64": "2.3.202",
142
+ "cicy-code-darwin-x64": "2.3.203",
143
+ "cicy-code-darwin-arm64": "2.3.203",
144
+ "cicy-code-linux-x64": "2.3.203",
145
+ "cicy-code-linux-arm64": "2.3.203",
146
146
  "cicy-code-windows-x64": "2.3.193",
147
147
  "cicy-mihomo-darwin-x64": "1.10.4",
148
148
  "cicy-mihomo-darwin-arm64": "1.10.4",
@@ -572,8 +572,10 @@ async function pullCustomTeams() {
572
572
  for (const [k, v] of Object.entries(nodes)) { if (v?.cloud_team_id != null) byCloudId[String(v.cloud_team_id)] = k; }
573
573
  let added = 0, updated = 0;
574
574
  for (const t of list.teams) {
575
- if (t.kind !== "custom") continue;
576
- const host = String(t.host_url || t.hostUrl || "").trim();
575
+ // custom teams (remote URL) OR any team with a zero-trust gateway address:
576
+ // gateway teams are reached at <slug>.gw.cicy-ai.com (preferred over host_url).
577
+ if (t.kind !== "custom" && !t.gateway_url) continue;
578
+ const host = String(t.gateway_url || t.host_url || t.hostUrl || "").trim();
577
579
  if (!host) continue;
578
580
  const tid = t.teamId || t.id || null;
579
581
  const localId = tid != null ? byCloudId[String(tid)] : null;
@@ -1099,4 +1101,26 @@ function avatarForUrl(url) {
1099
1101
  return "";
1100
1102
  }
1101
1103
 
1102
- module.exports = { list, openTeam, reloadTeam, closeLocalWindows, addTeam, removeTeam, updateTeam, upgradeTeam, syncAllLocalTeams, setAvatar, getAvatars, avatarForUrl };
1104
+ // Remove teams tied to a cloud ACCOUNT (remote base_url pulled from the cloud
1105
+ // via pullCustomTeams, or user-added remote nodes) so switching/leaving an account
1106
+ // doesn't leak them onto the next user. LOCAL machine teams on THIS device
1107
+ // (localhost base_url) are kept — they belong to the box, not the account. The
1108
+ // next login re-pulls the new account's own teams fresh.
1109
+ async function purgeAccountTeams() {
1110
+ let removed = 0;
1111
+ try {
1112
+ await writeNodes((nodes) => {
1113
+ for (const id of Object.keys(nodes)) {
1114
+ let host = "";
1115
+ try { host = new URL(String(nodes[id]?.base_url || "")).hostname.toLowerCase(); } catch {}
1116
+ const isLocal = host === "" || host === "127.0.0.1" || host === "localhost" || host === "::1";
1117
+ if (!isLocal) { delete nodes[id]; removed++; }
1118
+ }
1119
+ return nodes;
1120
+ });
1121
+ } catch (e) { log.warn(`[local-teams] purgeAccountTeams failed: ${e.message}`); }
1122
+ if (removed) { _cache = null; _cacheUntil = 0; log.info(`[local-teams] purged ${removed} account team(s) (login/logout)`); }
1123
+ return removed;
1124
+ }
1125
+
1126
+ module.exports = { list, openTeam, reloadTeam, closeLocalWindows, addTeam, removeTeam, updateTeam, upgradeTeam, syncAllLocalTeams, purgeAccountTeams, setAvatar, getAvatars, avatarForUrl };
package/src/main.js CHANGED
@@ -998,6 +998,17 @@ electronApp.whenReady().then(async () => {
998
998
  // renderer. A completed email login is thus indistinguishable downstream.
999
999
  const onAuthResult = (payload) => {
1000
1000
  if (payload && payload.token) {
1001
+ // Account isolation: if a DIFFERENT user is signing in, drop the previous
1002
+ // account's cloud/remote teams so they don't leak onto this account. The
1003
+ // login below re-pulls this account's own teams fresh. Local machine
1004
+ // teams (localhost) are kept — they belong to the device.
1005
+ try {
1006
+ const prevUid = String((readGlobalConfig(GLOBAL_JSON)?.desktopAuth?.userId) || "");
1007
+ const nextUid = payload.userId != null ? String(payload.userId) : "";
1008
+ if (prevUid && nextUid && prevUid !== nextUid) {
1009
+ require("./backends/local-teams").purgeAccountTeams().catch(() => {});
1010
+ }
1011
+ } catch {}
1001
1012
  saveDesktopAuth(payload);
1002
1013
  // Now that we have a real owner-bound login token, report this
1003
1014
  // machine to the cloud (best-effort; safe to call repeatedly —
@@ -1067,6 +1078,8 @@ electronApp.whenReady().then(async () => {
1067
1078
  __ipcMainAuth.handle("auth:logout", () => {
1068
1079
  try {
1069
1080
  updateGlobalConfig(GLOBAL_JSON, (c) => { delete c.desktopAuth; return c; });
1081
+ // Drop this account's cloud/remote teams on logout (local machines stay).
1082
+ require("./backends/local-teams").purgeAccountTeams().catch(() => {});
1070
1083
  log.info("[auth] desktop login cleared (explicit logout)");
1071
1084
  } catch (e) { log.warn(`[auth] logout clear failed: ${e.message}`); }
1072
1085
  return { ok: true };
@@ -143,7 +143,15 @@ async function start({ port = 8008, logPath = null, emit, version = null } = {})
143
143
  };
144
144
  // --helper removed : boot cicy-code in normal mode (full tmux-based
145
145
  // multi-agent), not the single headless 团队助手.
146
- const child = spawn(exe, ["--desktop"], { stdio, detached: true, windowsHide: true, env });
146
+ const args = ["--desktop"];
147
+ // Host role: if a zero-trust gateway is provisioned (~/cicy-ai/db/gateway.json
148
+ // with url+token), boot with --gateway so this machine dials OUT and becomes
149
+ // reachable through the gateway (no inbound port). Absent → plain local boot.
150
+ try {
151
+ const gwPath = require("path").join(require("os").homedir(), "cicy-ai", "db", "gateway.json");
152
+ if (require("fs").existsSync(gwPath)) args.push("--gateway");
153
+ } catch { /* best-effort */ }
154
+ const child = spawn(exe, args, { stdio, detached: true, windowsHide: true, env });
147
155
  child.unref();
148
156
  try { fs.writeFileSync(PID_FILE, String(child.pid)); } catch {}
149
157
  console.log(`[native-sidecar] spawned ${exe} --desktop pid=${child.pid} port=${port} log=${logPath || "(none)"}`);