cicy-desktop 2.1.61 → 2.1.63
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,27 +1,20 @@
|
|
|
1
1
|
// Homepage window — primary CiCy Desktop window. Singleton; closing it
|
|
2
2
|
// does NOT quit the app.
|
|
3
3
|
//
|
|
4
|
-
// URL selection (HARDCODED — no env/dev-URL switch, no Vite):
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// dependency, no mixed-content concerns when embedding the team-assistant
|
|
10
|
-
// webview (the cicy-desktop preload's IPC bridge still attaches).
|
|
4
|
+
// URL selection (HARDCODED — no env/dev-URL switch, no Vite): ALL platforms
|
|
5
|
+
// load the bundled local file:// SPA — works offline, fast, no remote
|
|
6
|
+
// dependency, no mixed-content concerns when embedding the team-assistant
|
|
7
|
+
// webview (the cicy-desktop preload's IPC bridge still attaches). The remote
|
|
8
|
+
// Cloudflare worker is only a fallback if the bundled SPA fails to load.
|
|
11
9
|
|
|
12
10
|
const path = require("path");
|
|
13
11
|
const { BrowserWindow } = require("electron");
|
|
14
12
|
const log = require("electron-log");
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
// - mac/linux: the bundled file:// SPA (offline, fast, no remote dependency).
|
|
18
|
-
// - Windows: the remote Cloudflare worker (Win release cadence is slower
|
|
19
|
-
// than render's, so it loads the homepage remotely).
|
|
20
|
-
const REMOTE_URL = "https://desktop.cicy-ai.com/"; // Cloudflare worker (remote homepage)
|
|
14
|
+
const REMOTE_URL = "https://desktop.cicy-ai.com/"; // Cloudflare worker (fallback only)
|
|
21
15
|
const LOCAL_INDEX = path.join(__dirname, "homepage-react", "index.html");
|
|
22
16
|
|
|
23
17
|
function pickHomepageURL() {
|
|
24
|
-
if (process.platform === "win32") return REMOTE_URL;
|
|
25
18
|
return `file://${LOCAL_INDEX}`;
|
|
26
19
|
}
|
|
27
20
|
|
|
@@ -83,16 +76,13 @@ async function openHomepage() {
|
|
|
83
76
|
homepage.webContents.on("console-message", (_e, level, msg, line, source) => {
|
|
84
77
|
if (level >= 1) console.log(`[homepage:console L${line}] ${msg} (${source})`);
|
|
85
78
|
});
|
|
86
|
-
// If the
|
|
87
|
-
//
|
|
79
|
+
// If the bundled file:// SPA fails to load (corrupt/missing install), fall
|
|
80
|
+
// back to the remote Cloudflare homepage so the window never stays blank.
|
|
88
81
|
homepage.webContents.on("did-fail-load", (_e, code, desc, url) => {
|
|
89
82
|
console.error(`[homepage] did-fail-load ${code} ${desc} ${url}`);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (url && url.startsWith(REMOTE_URL.replace(/\/$/, "")) && url !== fallback) {
|
|
94
|
-
log.warn(`[homepage] remote homepage unreachable, falling back to ${fallback}`);
|
|
95
|
-
homepage.loadURL(fallback);
|
|
83
|
+
if (url && url.startsWith("file://")) {
|
|
84
|
+
log.warn(`[homepage] bundled homepage failed, falling back to ${REMOTE_URL}`);
|
|
85
|
+
homepage.loadURL(REMOTE_URL);
|
|
96
86
|
}
|
|
97
87
|
});
|
|
98
88
|
homepage.on("closed", () => { homepage = null; });
|
|
@@ -50,11 +50,17 @@ function register({ sidecarLogPath } = {}) {
|
|
|
50
50
|
onProgress: (ev) => { try { e.sender.send("docker:bootstrap-progress", ev); } catch {} },
|
|
51
51
|
});
|
|
52
52
|
// Healthy local stack → make sure it shows up as a team ("本地团队就加
|
|
53
|
-
// 上去了"). addTeam dedups by host:port, so re-runs are no-ops.
|
|
53
|
+
// 上去了"). addTeam dedups by host:port, so re-runs are no-ops. The
|
|
54
|
+
// api_token must be the CONTAINER's own (volume global.json) — the
|
|
55
|
+
// host's token is a different credential and fails verify.
|
|
54
56
|
if (result && result.ok) {
|
|
55
57
|
try {
|
|
56
58
|
const lt = require("./local-teams");
|
|
57
|
-
await
|
|
59
|
+
const tok = await docker.readContainerToken(PORT);
|
|
60
|
+
await lt.addTeam({
|
|
61
|
+
base_url: `http://127.0.0.1:${PORT}`, name: "本地团队",
|
|
62
|
+
...(tok ? { api_token: tok } : {}),
|
|
63
|
+
});
|
|
58
64
|
} catch { /* best-effort — the stack itself is up */ }
|
|
59
65
|
}
|
|
60
66
|
return result;
|
package/src/sidecar/docker.js
CHANGED
|
@@ -189,6 +189,20 @@ async function ensureDownloaded(url, dest, mirror, { emit, phase, label } = {})
|
|
|
189
189
|
});
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
// The container's cicy-code mints its own api_token in its volume-persisted
|
|
193
|
+
// global.json — the HOST's global.json token is a different credential and
|
|
194
|
+
// won't verify. Read the real one out of whatever container publishes :port
|
|
195
|
+
// (works for adopted legacy-named containers too).
|
|
196
|
+
async function readContainerToken(port = 8008) {
|
|
197
|
+
try {
|
|
198
|
+
const { stdout } = await run(["ps", "--filter", `publish=${port}`, "--format", "{{.Names}}"]);
|
|
199
|
+
const name = stdout.trim().split("\n")[0];
|
|
200
|
+
if (!name) return "";
|
|
201
|
+
const r = await run(["exec", name, "cat", "/home/cicy/cicy-ai/global.json"], { timeout: 10000 });
|
|
202
|
+
return (JSON.parse(r.stdout).api_token || "");
|
|
203
|
+
} catch { return ""; }
|
|
204
|
+
}
|
|
205
|
+
|
|
192
206
|
// HTTP /health probe of the container on :port.
|
|
193
207
|
function probeHealth(port = 8008, timeoutMs = 2500) {
|
|
194
208
|
return new Promise((resolve) => {
|
|
@@ -358,4 +372,4 @@ async function bootstrap({ onProgress, port = 8008 } = {}) {
|
|
|
358
372
|
return { ok: healthy, container: CONTAINER };
|
|
359
373
|
}
|
|
360
374
|
|
|
361
|
-
module.exports = { start, stop, checkStatus, loadImage, imagePresent, dockerOk, installDocker, bootstrap, probeHealth };
|
|
375
|
+
module.exports = { start, stop, checkStatus, loadImage, imagePresent, dockerOk, installDocker, bootstrap, probeHealth, readContainerToken };
|