cicy-desktop 2.1.70 → 2.1.72
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/.cicy-code-ref +1 -1
- package/.github/workflows/linux-app-release.yml +3 -0
- package/.github/workflows/mac-app-release.yml +3 -0
- package/.github/workflows/npm-publish.yml +32 -0
- package/.github/workflows/windows-exe-release.yml +3 -0
- package/package.json +8 -9
- package/scripts/sync-runtime-deps.cjs +54 -0
- package/src/backends/homepage-react/assets/index-BpljolQs.js +365 -0
- package/src/backends/homepage-react/assets/{index-BniEbx_j.css → index-C9AZlTew.css} +1 -1
- package/src/backends/homepage-react/index.html +2 -2
- package/src/backends/local-teams.js +42 -4
- package/src/backends/sidecar-ipc.js +23 -1
- package/src/i18n/locales/en.json +9 -7
- package/src/i18n/locales/zh-CN.json +9 -7
- package/src/sidecar/cicy-code.js +49 -111
- package/src/sidecar/localbin.js +133 -0
- package/src/sidecar/native.js +3 -1
- package/workers/render/src/App.css +156 -10
- package/workers/render/src/App.jsx +254 -39
- package/.env.dev +0 -7
- package/src/backends/homepage-react/assets/index-B8gGhz8B.js +0 -365
- package/workers/render.bak.20260528-2338/DESIGN_v2.md +0 -254
- package/workers/render.bak.20260528-2338/index.html +0 -12
- package/workers/render.bak.20260528-2338/package-lock.json +0 -827
- package/workers/render.bak.20260528-2338/package.json +0 -19
- package/workers/render.bak.20260528-2338/public/_headers +0 -5
- package/workers/render.bak.20260528-2338/public/manifest.json +0 -6
- package/workers/render.bak.20260528-2338/src/App.css +0 -224
- package/workers/render.bak.20260528-2338/src/App.jsx +0 -1028
- package/workers/render.bak.20260528-2338/src/api.js +0 -285
- package/workers/render.bak.20260528-2338/src/cicycode-ops.js +0 -222
- package/workers/render.bak.20260528-2338/src/components/BackendCard.css +0 -299
- package/workers/render.bak.20260528-2338/src/components/BackendCard.jsx +0 -133
- package/workers/render.bak.20260528-2338/src/components/BackendModal.css +0 -161
- package/workers/render.bak.20260528-2338/src/components/BackendModal.jsx +0 -199
- package/workers/render.bak.20260528-2338/src/components/Button.css +0 -72
- package/workers/render.bak.20260528-2338/src/components/Button.jsx +0 -37
- package/workers/render.bak.20260528-2338/src/components/Card.css +0 -42
- package/workers/render.bak.20260528-2338/src/components/Card.jsx +0 -21
- package/workers/render.bak.20260528-2338/src/components/Icon.jsx +0 -30
- package/workers/render.bak.20260528-2338/src/components/Menu.css +0 -55
- package/workers/render.bak.20260528-2338/src/components/Menu.jsx +0 -91
- package/workers/render.bak.20260528-2338/src/components/SidecarBanner.css +0 -79
- package/workers/render.bak.20260528-2338/src/components/SidecarBanner.jsx +0 -84
- package/workers/render.bak.20260528-2338/src/components/StatusChip.css +0 -19
- package/workers/render.bak.20260528-2338/src/components/StatusChip.jsx +0 -31
- package/workers/render.bak.20260528-2338/src/components/Toast.css +0 -31
- package/workers/render.bak.20260528-2338/src/components/Toast.jsx +0 -23
- package/workers/render.bak.20260528-2338/src/components/WslSetupBanner.css +0 -464
- package/workers/render.bak.20260528-2338/src/components/WslSetupBanner.jsx +0 -716
- package/workers/render.bak.20260528-2338/src/dockerInstaller.js +0 -0
- package/workers/render.bak.20260528-2338/src/i18n/en.json +0 -116
- package/workers/render.bak.20260528-2338/src/i18n/fr.json +0 -116
- package/workers/render.bak.20260528-2338/src/i18n/index.js +0 -69
- package/workers/render.bak.20260528-2338/src/i18n/ja.json +0 -116
- package/workers/render.bak.20260528-2338/src/i18n/zh-CN.json +0 -121
- package/workers/render.bak.20260528-2338/src/main.js +0 -475
- package/workers/render.bak.20260528-2338/src/main.jsx +0 -18
- package/workers/render.bak.20260528-2338/src/style.css +0 -275
- package/workers/render.bak.20260528-2338/src/styles/base.css +0 -98
- package/workers/render.bak.20260528-2338/src/styles/tokens.css +0 -90
- package/workers/render.bak.20260528-2338/src/tos.js +0 -72
- package/workers/render.bak.20260528-2338/src/worker.js +0 -40
- package/workers/render.bak.20260528-2338/src/wslInstaller.js +0 -1563
- package/workers/render.bak.20260528-2338/vite.config.js +0 -36
- package/workers/render.bak.20260528-2338/wrangler.toml +0 -17
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// ~/.local/bin install model for the cicy-code daemon binary.
|
|
2
|
+
//
|
|
3
|
+
// 主人指令 (2026-06): cicy-desktop OWNS the binary. It is bundled per-platform
|
|
4
|
+
// (an optionalDependency of cicy-desktop). On first run we copy the bundled,
|
|
5
|
+
// version-named binary into ~/.local/bin/cicy-code-<ver>-<plat> and point
|
|
6
|
+
// ~/.local/bin/cicy-code at it (symlink on mac/linux; a plain COPY on Windows —
|
|
7
|
+
// symlink/junction perms there are a minefield). The daemon is ALWAYS run from
|
|
8
|
+
// that stable ~/.local/bin/cicy-code path — never `npx cicy-code`, which would
|
|
9
|
+
// reuse a stale globally-installed copy and shadow updates.
|
|
10
|
+
//
|
|
11
|
+
// Updates use npm ONLY as a download channel: `npm pack` the per-platform
|
|
12
|
+
// subpackage (sha512-verified), extract the binary, copy it in as a NEW
|
|
13
|
+
// version-named file, then re-point the cicy-code link (re-copy on Windows).
|
|
14
|
+
|
|
15
|
+
const fs = require("fs");
|
|
16
|
+
const os = require("os");
|
|
17
|
+
const path = require("path");
|
|
18
|
+
const { execFile } = require("child_process");
|
|
19
|
+
|
|
20
|
+
const IS_WIN = process.platform === "win32";
|
|
21
|
+
const REGISTRY = process.env.CICY_NPM_REGISTRY || "https://registry.npmmirror.com";
|
|
22
|
+
const LOCAL_BIN = path.join(os.homedir(), ".local", "bin");
|
|
23
|
+
|
|
24
|
+
function plat() {
|
|
25
|
+
const osStr = IS_WIN ? "windows" : process.platform === "darwin" ? "darwin" : "linux";
|
|
26
|
+
const arch = process.arch === "arm64" ? "arm64" : "x64";
|
|
27
|
+
return `${osStr}-${arch}`;
|
|
28
|
+
}
|
|
29
|
+
const PKG = () => `cicy-code-${plat()}`;
|
|
30
|
+
const BIN = IS_WIN ? "cicy-code.exe" : "cicy-code";
|
|
31
|
+
const LINK = path.join(LOCAL_BIN, IS_WIN ? "cicy-code.exe" : "cicy-code");
|
|
32
|
+
const versioned = (ver) => path.join(LOCAL_BIN, `cicy-code-${ver}-${plat()}${IS_WIN ? ".exe" : ""}`);
|
|
33
|
+
|
|
34
|
+
function npmExec(args, timeout = 600000) {
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
execFile("npm", args, { windowsHide: true, timeout, shell: IS_WIN }, (err, stdout, stderr) =>
|
|
37
|
+
err ? reject(new Error(String(stderr || err.message).slice(0, 300))) : resolve(String(stdout)));
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Latest published version of the per-platform subpackage.
|
|
42
|
+
async function latestVersion() {
|
|
43
|
+
return (await npmExec(["view", PKG(), "version", `--registry=${REGISTRY}`], 30000)).trim();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Point ~/.local/bin/cicy-code at a version-named binary: symlink on POSIX, a
|
|
47
|
+
// plain copy on Windows.
|
|
48
|
+
function linkTo(verBinPath) {
|
|
49
|
+
fs.mkdirSync(LOCAL_BIN, { recursive: true });
|
|
50
|
+
try { fs.rmSync(LINK, { force: true }); } catch {}
|
|
51
|
+
if (IS_WIN) {
|
|
52
|
+
fs.copyFileSync(verBinPath, LINK);
|
|
53
|
+
} else {
|
|
54
|
+
fs.symlinkSync(verBinPath, LINK);
|
|
55
|
+
}
|
|
56
|
+
return LINK;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function placeBinary(srcBin, ver) {
|
|
60
|
+
if (!fs.existsSync(srcBin)) throw new Error(`source binary missing: ${srcBin}`);
|
|
61
|
+
fs.mkdirSync(LOCAL_BIN, { recursive: true });
|
|
62
|
+
const dst = versioned(ver);
|
|
63
|
+
fs.copyFileSync(srcBin, dst);
|
|
64
|
+
if (!IS_WIN) fs.chmodSync(dst, 0o755);
|
|
65
|
+
linkTo(dst);
|
|
66
|
+
return { exe: LINK, target: dst, version: ver };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// The bundled per-platform subpackage shipped inside cicy-desktop (zero network).
|
|
70
|
+
function bundledPkgDir() {
|
|
71
|
+
const candidates = [
|
|
72
|
+
path.join(__dirname, "..", "..", "node_modules", PKG()), // npm install layout
|
|
73
|
+
path.join(process.resourcesPath || "", "runtime-pkgs", PKG()), // packaged (NSIS/dmg) layout
|
|
74
|
+
];
|
|
75
|
+
for (const p of candidates) {
|
|
76
|
+
try { if (fs.existsSync(path.join(p, "package.json"))) return p; } catch {}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Install the binary from the bundled subpackage. null when not bundled.
|
|
82
|
+
function fromBundle() {
|
|
83
|
+
const dir = bundledPkgDir();
|
|
84
|
+
if (!dir) return null;
|
|
85
|
+
let ver;
|
|
86
|
+
try { ver = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8")).version; } catch { return null; }
|
|
87
|
+
const src = path.join(dir, BIN);
|
|
88
|
+
if (!fs.existsSync(src)) return null;
|
|
89
|
+
if (fs.existsSync(versioned(ver))) { linkTo(versioned(ver)); return { exe: LINK, version: ver }; }
|
|
90
|
+
return placeBinary(src, ver);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Download <pkg>@<ver> via `npm pack` and install it into ~/.local/bin. npm is
|
|
94
|
+
// ONLY the download channel — we copy the binary out and run it from ~/.local/bin.
|
|
95
|
+
async function fetchToLocalBin(ver, { emit } = {}) {
|
|
96
|
+
const e = emit || (() => {});
|
|
97
|
+
if (fs.existsSync(versioned(ver))) { linkTo(versioned(ver)); return { exe: LINK, version: ver }; }
|
|
98
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "cicy-cc-"));
|
|
99
|
+
try {
|
|
100
|
+
e({ phase: "download", status: "running", message: `下载 cicy-code ${ver}…` });
|
|
101
|
+
const out = await npmExec(["pack", `${PKG()}@${ver}`, `--registry=${REGISTRY}`, "--pack-destination", tmp]);
|
|
102
|
+
const tgz = path.join(tmp, out.trim().split("\n").pop().trim());
|
|
103
|
+
await new Promise((resolve, reject) =>
|
|
104
|
+
execFile("tar", ["-xzf", tgz, "-C", tmp], { windowsHide: true, timeout: 120000 }, (err) => (err ? reject(err) : resolve())));
|
|
105
|
+
const res = placeBinary(path.join(tmp, "package", BIN), ver);
|
|
106
|
+
e({ phase: "download", status: "done", message: `cicy-code ${ver} 就绪` });
|
|
107
|
+
return res;
|
|
108
|
+
} finally {
|
|
109
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ~/.local/bin/cicy-code, if it exists.
|
|
114
|
+
function currentLink() {
|
|
115
|
+
return fs.existsSync(LINK) ? LINK : null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Ensure ~/.local/bin/cicy-code exists and points at a usable binary.
|
|
119
|
+
// - already linked → reuse (unless force)
|
|
120
|
+
// - else bundled subpackage (zero network, the "pre-installed" path)
|
|
121
|
+
// - else download latest (or a pinned version) via npm
|
|
122
|
+
async function ensure({ version = null, force = false, emit = null } = {}) {
|
|
123
|
+
if (!force && currentLink()) return { exe: LINK };
|
|
124
|
+
const pin = version && version !== "latest" ? version : null;
|
|
125
|
+
if (!force && !pin) {
|
|
126
|
+
const b = fromBundle();
|
|
127
|
+
if (b) return b;
|
|
128
|
+
}
|
|
129
|
+
const ver = pin || (await latestVersion());
|
|
130
|
+
return fetchToLocalBin(ver, { emit });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
module.exports = { LOCAL_BIN, LINK, plat, versioned, latestVersion, fromBundle, fetchToLocalBin, currentLink, ensure };
|
package/src/sidecar/native.js
CHANGED
|
@@ -140,7 +140,9 @@ async function start({ port = 8008, logPath = null, emit, version = null } = {})
|
|
|
140
140
|
PORT: String(port),
|
|
141
141
|
CICY_CODE_PORT: String(port),
|
|
142
142
|
};
|
|
143
|
-
|
|
143
|
+
// --helper=1: on Windows, boot as the single headless cicy 团队助手 on w-1001
|
|
144
|
+
// (开机即团队助手). The flag is a no-op on cicy-code builds that don't support it.
|
|
145
|
+
const child = spawn(exe, ["--helper=1"], { stdio, detached: true, windowsHide: true, env });
|
|
144
146
|
child.unref();
|
|
145
147
|
try { fs.writeFileSync(PID_FILE, String(child.pid)); } catch {}
|
|
146
148
|
console.log(`[native-sidecar] spawned ${exe} pid=${child.pid} port=${port} log=${logPath || "(none)"}`);
|
|
@@ -734,24 +734,145 @@ body {
|
|
|
734
734
|
word-break: break-word;
|
|
735
735
|
}
|
|
736
736
|
|
|
737
|
-
/*
|
|
738
|
-
.
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
.
|
|
745
|
-
|
|
737
|
+
/* Toast: floating op feedback (更新/启动/重启 progress + result), bottom-right,
|
|
738
|
+
stacked. Replaces the old in-card progress line — feedback floats over the UI. */
|
|
739
|
+
.toast-host {
|
|
740
|
+
position: fixed; right: 16px; bottom: 16px; z-index: 9999;
|
|
741
|
+
display: flex; flex-direction: column; gap: 8px;
|
|
742
|
+
max-width: min(360px, calc(100vw - 32px)); pointer-events: none;
|
|
743
|
+
}
|
|
744
|
+
.toast {
|
|
745
|
+
pointer-events: auto; position: relative;
|
|
746
|
+
display: flex; flex-direction: column; gap: 6px;
|
|
747
|
+
padding: 10px 30px 10px 12px;
|
|
748
|
+
font-size: 12.5px; line-height: 1.4; color: var(--text, #e6eaf0);
|
|
749
|
+
background: rgba(22, 26, 33, 0.96);
|
|
750
|
+
border: 1px solid rgba(125, 135, 150, 0.22);
|
|
751
|
+
border-left: 3px solid var(--accent, #3b82f6);
|
|
752
|
+
border-radius: 10px;
|
|
753
|
+
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.42);
|
|
754
|
+
backdrop-filter: blur(8px);
|
|
755
|
+
animation: toast-in 0.18s ease;
|
|
756
|
+
}
|
|
757
|
+
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
|
|
758
|
+
.toast[data-status="error"] { border-left-color: #f87171; }
|
|
759
|
+
.toast[data-status="error"] .toast__msg { color: #f87171; }
|
|
760
|
+
.toast[data-status="done"] { border-left-color: #4ade80; }
|
|
761
|
+
.toast[data-status="done"] .toast__msg { color: #4ade80; }
|
|
762
|
+
.toast__msg { word-break: break-word; }
|
|
763
|
+
.toast__x {
|
|
764
|
+
position: absolute; top: 6px; right: 8px;
|
|
765
|
+
background: none; border: none; cursor: pointer; padding: 0;
|
|
766
|
+
font-size: 15px; line-height: 1; color: var(--text-dim, #9da7b3);
|
|
767
|
+
}
|
|
768
|
+
.toast__x:hover { color: var(--text, #e6eaf0); }
|
|
769
|
+
.toast__bar {
|
|
746
770
|
display: block; height: 4px; border-radius: 2px;
|
|
747
771
|
background: rgba(125, 135, 150, 0.25); overflow: hidden;
|
|
748
772
|
}
|
|
749
|
-
.
|
|
773
|
+
.toast__bar > span {
|
|
750
774
|
display: block; height: 100%; border-radius: 2px;
|
|
751
775
|
background: var(--accent, #3b82f6);
|
|
752
776
|
transition: width 0.25s ease;
|
|
753
777
|
}
|
|
754
778
|
|
|
779
|
+
/* ── 更新 drawer: bottom sheet with live log + 阶段 + 重试 ───────────────── */
|
|
780
|
+
.drawer-scrim {
|
|
781
|
+
position: fixed; inset: 0; z-index: 10000;
|
|
782
|
+
display: flex; align-items: flex-end; justify-content: center;
|
|
783
|
+
background: rgba(6, 8, 12, 0.5); backdrop-filter: blur(2px);
|
|
784
|
+
animation: drawer-fade 0.18s ease;
|
|
785
|
+
}
|
|
786
|
+
@keyframes drawer-fade { from { opacity: 0; } to { opacity: 1; } }
|
|
787
|
+
.drawer {
|
|
788
|
+
width: min(560px, calc(100vw - 24px)); max-height: 76vh;
|
|
789
|
+
display: flex; flex-direction: column;
|
|
790
|
+
margin-bottom: 12px;
|
|
791
|
+
background: rgba(20, 24, 31, 0.98);
|
|
792
|
+
border: 1px solid rgba(125, 135, 150, 0.2);
|
|
793
|
+
border-radius: 16px 16px 12px 12px;
|
|
794
|
+
box-shadow: 0 -10px 44px rgba(0, 0, 0, 0.5);
|
|
795
|
+
overflow: hidden;
|
|
796
|
+
animation: drawer-up 0.24s cubic-bezier(0.22, 1, 0.36, 1);
|
|
797
|
+
}
|
|
798
|
+
@keyframes drawer-up { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
|
|
799
|
+
.drawer__head {
|
|
800
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
801
|
+
padding: 14px 14px 12px 16px;
|
|
802
|
+
border-bottom: 1px solid rgba(125, 135, 150, 0.14);
|
|
803
|
+
}
|
|
804
|
+
.drawer__title { display: flex; align-items: center; gap: 11px; }
|
|
805
|
+
.drawer__spark {
|
|
806
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
807
|
+
width: 26px; height: 26px; border-radius: 8px; font-size: 14px; font-weight: 700;
|
|
808
|
+
background: rgba(91, 141, 247, 0.16); color: var(--brand, #5b8df7);
|
|
809
|
+
}
|
|
810
|
+
.drawer__spark--done { background: rgba(74, 222, 128, 0.16); color: #4ade80; }
|
|
811
|
+
.drawer__spark--error { background: rgba(248, 113, 113, 0.16); color: #f87171; }
|
|
812
|
+
.drawer__h { font-size: 13.5px; font-weight: 650; color: var(--text, #e6eaf0); }
|
|
813
|
+
.drawer__sub { font-size: 11.5px; color: var(--text-dim, #9da7b3); margin-top: 1px; }
|
|
814
|
+
.drawer__x {
|
|
815
|
+
background: none; border: none; cursor: pointer; padding: 2px 6px;
|
|
816
|
+
font-size: 19px; line-height: 1; color: var(--text-dim, #9da7b3); border-radius: 6px;
|
|
817
|
+
}
|
|
818
|
+
.drawer__x:hover:not(:disabled) { color: var(--text, #e6eaf0); background: rgba(125, 135, 150, 0.12); }
|
|
819
|
+
.drawer__x:disabled { opacity: 0.35; cursor: default; }
|
|
820
|
+
|
|
821
|
+
.drawer__steps { display: flex; align-items: center; gap: 0; padding: 14px 18px 4px; }
|
|
822
|
+
.drawer__step { display: flex; align-items: center; gap: 7px; color: var(--text-dim, #9da7b3); font-size: 12px; }
|
|
823
|
+
.drawer__step-dot {
|
|
824
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
825
|
+
width: 20px; height: 20px; border-radius: 50%; font-size: 11px; font-weight: 700;
|
|
826
|
+
border: 1.5px solid rgba(125, 135, 150, 0.35); color: var(--text-dim, #9da7b3);
|
|
827
|
+
background: transparent; flex: none;
|
|
828
|
+
}
|
|
829
|
+
.drawer__step-bar { width: 30px; height: 1.5px; background: rgba(125, 135, 150, 0.25); margin: 0 8px; }
|
|
830
|
+
.drawer__step.is-active .drawer__step-dot { border-color: var(--brand, #5b8df7); color: var(--brand, #5b8df7); box-shadow: 0 0 0 3px rgba(91, 141, 247, 0.18); }
|
|
831
|
+
.drawer__step.is-active .drawer__step-label { color: var(--text, #e6eaf0); }
|
|
832
|
+
.drawer__step.is-done .drawer__step-dot { border-color: #4ade80; color: #06210f; background: #4ade80; }
|
|
833
|
+
.drawer__step.is-done .drawer__step-bar { background: rgba(74, 222, 128, 0.5); }
|
|
834
|
+
.drawer__step.is-error .drawer__step-dot { border-color: #f87171; color: #f87171; }
|
|
835
|
+
|
|
836
|
+
.drawer__log {
|
|
837
|
+
flex: 1; min-height: 96px; overflow-y: auto;
|
|
838
|
+
margin: 10px 14px; padding: 10px 12px;
|
|
839
|
+
background: rgba(10, 12, 16, 0.7); border: 1px solid rgba(125, 135, 150, 0.12); border-radius: 10px;
|
|
840
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11.5px; line-height: 1.7;
|
|
841
|
+
}
|
|
842
|
+
.drawer__log-empty { color: var(--text-dim, #9da7b3); }
|
|
843
|
+
.drawer__line { display: flex; align-items: baseline; gap: 8px; padding: 1px 0; }
|
|
844
|
+
.drawer__t { color: #6b7686; flex: none; font-variant-numeric: tabular-nums; }
|
|
845
|
+
.drawer__badge {
|
|
846
|
+
flex: none; padding: 0 6px; border-radius: 4px; font-size: 10px; font-weight: 600;
|
|
847
|
+
background: rgba(91, 141, 247, 0.16); color: #8fb0f5;
|
|
848
|
+
}
|
|
849
|
+
.drawer__badge--swap { background: rgba(245, 158, 11, 0.16); color: #f5b342; }
|
|
850
|
+
.drawer__badge--done { background: rgba(74, 222, 128, 0.16); color: #6ee79b; }
|
|
851
|
+
.drawer__linemsg { color: var(--text, #e6eaf0); word-break: break-word; }
|
|
852
|
+
.drawer__line[data-status="error"] .drawer__linemsg { color: #f87171; }
|
|
853
|
+
.drawer__line[data-status="done"] .drawer__linemsg { color: #6ee79b; }
|
|
854
|
+
.drawer__line[data-status="skip"] .drawer__linemsg { color: var(--text-dim, #9da7b3); }
|
|
855
|
+
|
|
856
|
+
.drawer__hint {
|
|
857
|
+
margin: 0 14px 8px; padding: 8px 12px;
|
|
858
|
+
background: rgba(245, 158, 11, 0.1); border: 1px solid rgba(245, 158, 11, 0.28); border-radius: 8px;
|
|
859
|
+
color: #f5b342; font-size: 11.5px; line-height: 1.5;
|
|
860
|
+
}
|
|
861
|
+
.drawer__foot {
|
|
862
|
+
display: flex; align-items: center; gap: 8px;
|
|
863
|
+
padding: 12px 14px; border-top: 1px solid rgba(125, 135, 150, 0.14);
|
|
864
|
+
}
|
|
865
|
+
.drawer__foot-status { font-size: 12.5px; color: var(--text-dim, #9da7b3); margin-right: auto; }
|
|
866
|
+
.drawer__foot-status.is-error { color: #f87171; }
|
|
867
|
+
.drawer__foot-status.is-done { color: #4ade80; }
|
|
868
|
+
.drawer__btn {
|
|
869
|
+
padding: 7px 16px; border-radius: 8px; cursor: pointer; font-size: 12.5px; font-weight: 550;
|
|
870
|
+
background: rgba(125, 135, 150, 0.14); border: 1px solid rgba(125, 135, 150, 0.2); color: var(--text, #e6eaf0);
|
|
871
|
+
}
|
|
872
|
+
.drawer__btn:hover { background: rgba(125, 135, 150, 0.22); }
|
|
873
|
+
.drawer__btn.is-accent { background: var(--brand, #5b8df7); border-color: var(--brand, #5b8df7); color: #fff; }
|
|
874
|
+
.drawer__btn.is-accent:hover { filter: brightness(1.08); }
|
|
875
|
+
|
|
755
876
|
/* HTTPS 审计 CA 授权卡片 (合规 opt-in) */
|
|
756
877
|
.mitm-card {
|
|
757
878
|
border: 1px solid rgba(125, 135, 150, 0.22);
|
|
@@ -761,6 +882,31 @@ body {
|
|
|
761
882
|
background: rgba(30, 36, 46, 0.4);
|
|
762
883
|
}
|
|
763
884
|
.mitm-card--on { border-color: rgba(74, 222, 128, 0.35); background: rgba(22, 40, 30, 0.4); }
|
|
885
|
+
|
|
886
|
+
/* 已启用 = 低调小 pill,固定在右上角,不占首页正文 */
|
|
887
|
+
.mitm-pill {
|
|
888
|
+
position: fixed; top: 64px; right: 16px; z-index: 9998;
|
|
889
|
+
-webkit-app-region: no-drag;
|
|
890
|
+
display: inline-flex; align-items: center; gap: 8px;
|
|
891
|
+
padding: 4px 6px 4px 11px;
|
|
892
|
+
border-radius: 999px; width: fit-content; max-width: calc(100vw - 32px);
|
|
893
|
+
background: rgba(20, 30, 24, 0.85);
|
|
894
|
+
border: 1px solid rgba(74, 222, 128, 0.3);
|
|
895
|
+
backdrop-filter: blur(8px);
|
|
896
|
+
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
|
|
897
|
+
font-size: 12px; line-height: 1;
|
|
898
|
+
}
|
|
899
|
+
.mitm-pill__dot {
|
|
900
|
+
width: 7px; height: 7px; border-radius: 50%; flex: none;
|
|
901
|
+
background: #4ade80; box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.16);
|
|
902
|
+
}
|
|
903
|
+
.mitm-pill__dot[data-busy="1"] { background: #9da7b3; box-shadow: 0 0 0 3px rgba(157, 167, 179, 0.16); }
|
|
904
|
+
.mitm-pill__text { color: var(--text-dim, #9da7b3); white-space: nowrap; }
|
|
905
|
+
.mitm-pill__off {
|
|
906
|
+
background: none; border: none; cursor: pointer;
|
|
907
|
+
color: #6b7686; font-size: 11.5px; padding: 3px 7px; border-radius: 999px;
|
|
908
|
+
}
|
|
909
|
+
.mitm-pill__off:hover { color: #f87171; background: rgba(248, 113, 113, 0.1); }
|
|
764
910
|
.mitm-card__head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
|
|
765
911
|
.mitm-card__dot { width: 8px; height: 8px; border-radius: 50%; background: #9da7b3; flex: 0 0 auto; }
|
|
766
912
|
.mitm-card__dot[data-state="on"] { background: #4ade80; box-shadow: 0 0 6px rgba(74, 222, 128, 0.6); }
|