cicy-desktop 2.1.281 → 2.1.286
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/scripts/windows/add-team.html +54 -0
- package/src/app-updater.js +28 -4
- package/src/backends/homepage-preload.js +2 -0
- package/src/backends/homepage-react/assets/index-CZILCWSS.js +377 -0
- package/src/backends/homepage-react/index.html +1 -1
- package/src/backends/ipc.js +2 -0
- package/src/backends/local-teams.js +18 -4
- package/src/backends/sidecar-ipc.js +11 -1
- package/src/main.js +1 -1
- package/src/profiles/trusted-origins-store.js +35 -5
- package/src/sidecar/docker.js +35 -3
- package/src/sidecar/wsl-docker.js +1 -1
- package/src/utils/global-json.js +4 -0
- package/src/utils/rpc-guard.js +40 -9
- package/test/app-updater-auto.test.js +20 -0
- package/test/docker-preflight-and-always-allow.test.js +53 -0
- package/test/global-json-fresh-dir.test.js +17 -0
- package/test/local-teams-docker-token.test.js +18 -0
- package/test/rpc-guard-deny-cooldown.test.js +18 -0
- package/test/trusted-origins-underscore.test.js +11 -0
- package/workers/render/src/App.jsx +19 -1
- package/src/backends/homepage-react/assets/index-BzYBKzQW.js +0 -377
package/package.json
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>添加团队到 CiCy Desktop</title>
|
|
6
|
+
<style>
|
|
7
|
+
body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#0a0a0a;color:#e6e6e9;font:15px/1.5 system-ui,-apple-system,"Segoe UI","Microsoft YaHei",sans-serif}
|
|
8
|
+
.card{width:420px;max-width:92vw;background:#141416;border:1px solid rgba(255,255,255,.08);border-radius:14px;padding:26px 24px;box-shadow:0 20px 60px rgba(0,0,0,.5)}
|
|
9
|
+
h1{font-size:18px;margin:0 0 4px}
|
|
10
|
+
p.sub{margin:0 0 18px;color:#8b8b92;font-size:13px}
|
|
11
|
+
label{display:block;font-size:12px;color:#8b8b92;margin:10px 0 4px}
|
|
12
|
+
input{width:100%;box-sizing:border-box;height:36px;border:1px solid rgba(255,255,255,.1);border-radius:8px;background:#0a0a0a;color:#e6e6e9;padding:0 10px;font:13px ui-monospace,monospace;outline:0}
|
|
13
|
+
input:focus{border-color:#3b82f6}
|
|
14
|
+
button{margin-top:18px;width:100%;height:44px;border:0;border-radius:10px;background:#3b82f6;color:#fff;font-size:16px;font-weight:600;cursor:pointer}
|
|
15
|
+
button:hover{filter:brightness(1.08)}
|
|
16
|
+
.hint{margin-top:12px;font-size:12px;color:#8b8b92}
|
|
17
|
+
.hint code{color:#b4b4bb}
|
|
18
|
+
a{color:#9db0ff}
|
|
19
|
+
</style>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<div class="card">
|
|
23
|
+
<h1>添加团队到 CiCy Desktop</h1>
|
|
24
|
+
<p class="sub">点一下按钮即可;需先安装并至少启动过一次 CiCy Desktop。</p>
|
|
25
|
+
<label>团队地址 URL</label>
|
|
26
|
+
<input id="url" value="http://127.0.0.1:8008" spellcheck="false">
|
|
27
|
+
<label>名称</label>
|
|
28
|
+
<input id="title" value="My Team" spellcheck="false">
|
|
29
|
+
<label>Token(可选)</label>
|
|
30
|
+
<input id="token" value="" spellcheck="false" placeholder="留空则不带">
|
|
31
|
+
<button id="go">添加到 CiCy Desktop</button>
|
|
32
|
+
<div class="hint" id="hint">未登录也可以:团队只存本地,会出现在「我的团队」里。</div>
|
|
33
|
+
</div>
|
|
34
|
+
<script>
|
|
35
|
+
// 用 ?url=&title=&token= 预填,方便做成固定链接分发
|
|
36
|
+
const q = new URLSearchParams(location.search);
|
|
37
|
+
for (const k of ["url","title","token"]) if (q.get(k)) document.getElementById(k).value = q.get(k);
|
|
38
|
+
function link(){
|
|
39
|
+
const url = document.getElementById("url").value.trim();
|
|
40
|
+
const title = document.getElementById("title").value.trim();
|
|
41
|
+
const token = document.getElementById("token").value.trim();
|
|
42
|
+
let s = "cicy-desktop://addTeam?title=" + encodeURIComponent(title) + "&url=" + encodeURIComponent(url);
|
|
43
|
+
if (token) s += "&token=" + encodeURIComponent(token);
|
|
44
|
+
return s;
|
|
45
|
+
}
|
|
46
|
+
document.getElementById("go").onclick = () => {
|
|
47
|
+
const s = link();
|
|
48
|
+
document.getElementById("hint").innerHTML = "已请求打开 <code>" + s.replace(/&token=[^&]*/, "&token=***") + "</code><br>没反应?说明 CiCy Desktop 还没安装或没启动过一次。";
|
|
49
|
+
location.href = s;
|
|
50
|
+
};
|
|
51
|
+
if (q.get("auto") === "1") document.getElementById("go").click();
|
|
52
|
+
</script>
|
|
53
|
+
</body>
|
|
54
|
+
</html>
|
package/src/app-updater.js
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
const { app, shell } = require("electron");
|
|
18
18
|
const path = require("path");
|
|
19
19
|
const fs = require("fs");
|
|
20
|
+
const os = require("os");
|
|
21
|
+
const { readGlobalConfig, updateGlobalConfig } = require("./utils/global-json");
|
|
20
22
|
const https = require("https");
|
|
21
23
|
const log = require("electron-log");
|
|
22
24
|
const { OSS_RELEASES_BASE } = require("./sidecar/mirrors");
|
|
@@ -135,9 +137,23 @@ function download(url, dest, onProgress, redirects = 0) {
|
|
|
135
137
|
|
|
136
138
|
// ── 状态机 + 广播 ─────────────────────────────────────────────────────────────
|
|
137
139
|
let _win = null;
|
|
138
|
-
let _state = { status: "idle", version: null, current: null, progress: null, filePath: null, error: null };
|
|
140
|
+
let _state = { status: "idle", version: null, current: null, progress: null, filePath: null, error: null, autoUpdate: false, auto: false };
|
|
139
141
|
let _downloading = false;
|
|
140
142
|
|
|
143
|
+
// 「以后自动更新到最新版」开关,存 ~/cicy-ai/global.json desktopAutoUpdate(设备级,与账号无关)。
|
|
144
|
+
// 打开后 check() 发现新版直接下载 + 拉起安装器,不再弹「发现新版本」询问。
|
|
145
|
+
const GLOBAL_JSON = path.join(os.homedir(), "cicy-ai", "global.json");
|
|
146
|
+
function getAutoUpdate() {
|
|
147
|
+
try { return readGlobalConfig(GLOBAL_JSON)?.desktopAutoUpdate === true; } catch { return false; }
|
|
148
|
+
}
|
|
149
|
+
function setAutoUpdate(on) {
|
|
150
|
+
const v = on === true;
|
|
151
|
+
try { updateGlobalConfig(GLOBAL_JSON, (c) => ({ ...(c || {}), desktopAutoUpdate: v })); }
|
|
152
|
+
catch (e) { log.warn("[app-updater] setAutoUpdate failed:", e.message); }
|
|
153
|
+
broadcast({ autoUpdate: v });
|
|
154
|
+
return v;
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
function broadcast(patch) {
|
|
142
158
|
Object.assign(_state, patch);
|
|
143
159
|
try { if (_win && !_win.isDestroyed()) _win.webContents.send("app:update-state", _state); } catch {}
|
|
@@ -147,6 +163,7 @@ function getState() { return _state; }
|
|
|
147
163
|
function init(mainWin) {
|
|
148
164
|
_win = mainWin;
|
|
149
165
|
_state.current = app.getVersion();
|
|
166
|
+
_state.autoUpdate = getAutoUpdate();
|
|
150
167
|
setTimeout(() => check().catch(() => {}), 15_000); // 启动后探一次
|
|
151
168
|
setInterval(() => check().catch(() => {}), 30 * 60 * 1000); // 每 30 分钟
|
|
152
169
|
}
|
|
@@ -162,8 +179,15 @@ async function check() {
|
|
|
162
179
|
// 真能下(200),否则当成「还没就绪」继续显已是最新,避免用户点下载 404。
|
|
163
180
|
const { url } = assetFor(latest);
|
|
164
181
|
const ready = await headOk(url);
|
|
165
|
-
if (ready)
|
|
166
|
-
|
|
182
|
+
if (ready) {
|
|
183
|
+
broadcast({ status: "available", version: latest, current, progress: null, filePath: null, autoUpdate: getAutoUpdate(), auto: false });
|
|
184
|
+
if (getAutoUpdate()) {
|
|
185
|
+
log.info(`[app-updater] auto-update on → downloading ${latest} and installing without asking`);
|
|
186
|
+
broadcast({ auto: true });
|
|
187
|
+
await downloadUpdate();
|
|
188
|
+
if (_state.status === "ready") installNow();
|
|
189
|
+
}
|
|
190
|
+
} else { log.info(`[app-updater] ${latest} 版本号已更新但安装包未就位(HEAD 非 200):${url} — 暂不提示更新`); broadcast({ status: "up-to-date", version: current, current }); }
|
|
167
191
|
} else {
|
|
168
192
|
broadcast({ status: "up-to-date", version: latest || current, current });
|
|
169
193
|
}
|
|
@@ -215,4 +239,4 @@ function installNow() {
|
|
|
215
239
|
} catch (e) { log.warn("[app-updater] install failed:", e.message); }
|
|
216
240
|
}
|
|
217
241
|
|
|
218
|
-
module.exports = { init, check, getState, downloadUpdate, installNow };
|
|
242
|
+
module.exports = { init, check, getState, downloadUpdate, installNow, getAutoUpdate, setAutoUpdate };
|
|
@@ -237,6 +237,8 @@ contextBridge.exposeInMainWorld("cicy", {
|
|
|
237
237
|
checkUpdate: () => logInvoke("app:check-update"),
|
|
238
238
|
downloadUpdate:() => logInvoke("app:download-update"),
|
|
239
239
|
installUpdate: () => logInvoke("app:install-update"),
|
|
240
|
+
getAutoUpdate: () => logInvoke("app:auto-update-get"),
|
|
241
|
+
setAutoUpdate: (on) => logInvoke("app:auto-update-set", on === true),
|
|
240
242
|
onUpdateState: (cb) => {
|
|
241
243
|
const handler = (_e, state) => { try { cb(state); } catch {} };
|
|
242
244
|
ipcRenderer.on("app:update-state", handler);
|