@modelzen/feishu-codex-bridge 0.6.6 → 0.6.7-test.0
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/dist/cli.js +210 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -8509,7 +8509,7 @@ function withCodexHooksFeature(text) {
|
|
|
8509
8509
|
}
|
|
8510
8510
|
|
|
8511
8511
|
// src/service/update.ts
|
|
8512
|
-
import { existsSync as
|
|
8512
|
+
import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
|
|
8513
8513
|
import { dirname as dirname9, join as join15, resolve as resolve6 } from "path";
|
|
8514
8514
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
8515
8515
|
|
|
@@ -8523,7 +8523,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
8523
8523
|
|
|
8524
8524
|
// src/service/common.ts
|
|
8525
8525
|
init_paths();
|
|
8526
|
-
import { createReadStream, statSync as statSync2 } from "fs";
|
|
8526
|
+
import { appendFileSync, createReadStream, statSync as statSync2 } from "fs";
|
|
8527
8527
|
import { appendFile, mkdir as mkdir7, readFile as readFile9 } from "fs/promises";
|
|
8528
8528
|
import { dirname as dirname6, join as join11, resolve as resolve4 } from "path";
|
|
8529
8529
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -8538,6 +8538,13 @@ async function ensureLogFiles() {
|
|
|
8538
8538
|
await appendFile(serviceStdoutPath(), "");
|
|
8539
8539
|
await appendFile(serviceStderrPath(), "");
|
|
8540
8540
|
}
|
|
8541
|
+
function appendServiceErr(tag, line) {
|
|
8542
|
+
try {
|
|
8543
|
+
appendFileSync(serviceStderrPath(), `[${(/* @__PURE__ */ new Date()).toISOString()}] [${tag}] ${line}
|
|
8544
|
+
`);
|
|
8545
|
+
} catch {
|
|
8546
|
+
}
|
|
8547
|
+
}
|
|
8541
8548
|
function resolveCliBinPath() {
|
|
8542
8549
|
const distDir = dirname6(fileURLToPath2(import.meta.url));
|
|
8543
8550
|
return resolve4(distDir, "..", "bin", "feishu-codex-bridge.mjs");
|
|
@@ -8747,9 +8754,10 @@ function launchctlError(command, result) {
|
|
|
8747
8754
|
// src/service/win-startup.ts
|
|
8748
8755
|
init_paths();
|
|
8749
8756
|
import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
|
|
8750
|
-
import { openSync, readFileSync as readFileSync3, rmSync, writeFileSync } from "fs";
|
|
8757
|
+
import { existsSync as existsSync7, openSync, readFileSync as readFileSync3, renameSync, rmSync, writeFileSync } from "fs";
|
|
8751
8758
|
import { mkdir as mkdir9, writeFile as writeFile8 } from "fs/promises";
|
|
8752
8759
|
import { join as join13 } from "path";
|
|
8760
|
+
var RELAUNCH_TASK_NAME = "feishu-codex-bridge-relaunch";
|
|
8753
8761
|
var RUN_KEY_PATH = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
|
|
8754
8762
|
var RUN_KEY_NAME = "feishu-codex-bridge";
|
|
8755
8763
|
var SERVICE_ENV_FLAG = "FEISHU_CODEX_BRIDGE_SERVICE";
|
|
@@ -8779,14 +8787,16 @@ function buildLauncherVbs() {
|
|
|
8779
8787
|
""
|
|
8780
8788
|
].join("\r\n");
|
|
8781
8789
|
}
|
|
8782
|
-
function startNow() {
|
|
8790
|
+
function startNow(envPath) {
|
|
8783
8791
|
const out = openSync(serviceStdoutPath(), "a");
|
|
8784
8792
|
const err = openSync(serviceStderrPath(), "a");
|
|
8793
|
+
const overrides = { [SERVICE_ENV_FLAG]: "1" };
|
|
8794
|
+
if (envPath) overrides.PATH = envPath;
|
|
8785
8795
|
const child = spawn3(process.execPath, [resolveCliBinPath(), "run"], {
|
|
8786
8796
|
detached: true,
|
|
8787
8797
|
windowsHide: true,
|
|
8788
8798
|
stdio: ["ignore", out, err],
|
|
8789
|
-
env: mergeProcessEnv(process.env,
|
|
8799
|
+
env: mergeProcessEnv(process.env, overrides)
|
|
8790
8800
|
});
|
|
8791
8801
|
if (child.pid) writeFileSync(servicePidFile(), String(child.pid), "utf8");
|
|
8792
8802
|
child.unref();
|
|
@@ -8817,10 +8827,150 @@ async function restartWinStartup() {
|
|
|
8817
8827
|
throw new Error("\u767B\u5F55\u81EA\u542F\u672A\u5B89\u88C5\uFF08\u5148\u8FD0\u884C `feishu-codex-bridge start`\uFF09\u3002");
|
|
8818
8828
|
}
|
|
8819
8829
|
await ensureLogFiles();
|
|
8820
|
-
|
|
8821
|
-
|
|
8830
|
+
const oldPid = readServicePid();
|
|
8831
|
+
if (oldPid === null || !pidAlive(oldPid)) {
|
|
8832
|
+
startNow();
|
|
8833
|
+
return statusWinStartup();
|
|
8834
|
+
}
|
|
8835
|
+
writeRelaunchRequest({ oldPid, envPath: process.env.PATH ?? "", nonce: `${process.pid}-${Date.now()}` });
|
|
8836
|
+
if (!spawnTreeFreeRelauncher()) {
|
|
8837
|
+
clearRelaunchRequest();
|
|
8838
|
+
appendServiceErr("relaunch", `no tree-free backend (powershell/schtasks); kept old pid=${oldPid} running, did NOT restart`);
|
|
8839
|
+
throw new Error("\u65E0\u6CD5\u62C9\u8D77\u300C\u6811\u5916\u300D\u91CD\u542F\u8FDB\u7A0B\uFF08powershell \u4E0E schtasks \u5747\u4E0D\u53EF\u7528\uFF09\uFF1B\u5DF2\u4FDD\u7559\u65E7\u670D\u52A1\u7EE7\u7EED\u8FD0\u884C\uFF0C\u672A\u91CD\u542F\u3002");
|
|
8840
|
+
}
|
|
8841
|
+
appendServiceErr("relaunch", `submitted async relaunch for oldPid=${oldPid}`);
|
|
8822
8842
|
return statusWinStartup();
|
|
8823
8843
|
}
|
|
8844
|
+
function relaunchRequestFile() {
|
|
8845
|
+
return join13(paths.appDir, "relaunch.json");
|
|
8846
|
+
}
|
|
8847
|
+
function writeRelaunchRequest(req) {
|
|
8848
|
+
writeFileSync(relaunchRequestFile(), JSON.stringify(req), "utf8");
|
|
8849
|
+
}
|
|
8850
|
+
function clearRelaunchRequest() {
|
|
8851
|
+
rmSync(relaunchRequestFile(), { force: true });
|
|
8852
|
+
}
|
|
8853
|
+
function relaunchClaimFile() {
|
|
8854
|
+
return `${relaunchRequestFile()}.claim.${process.pid}`;
|
|
8855
|
+
}
|
|
8856
|
+
function claimRelaunchRequest() {
|
|
8857
|
+
const claim = relaunchClaimFile();
|
|
8858
|
+
try {
|
|
8859
|
+
renameSync(relaunchRequestFile(), claim);
|
|
8860
|
+
} catch {
|
|
8861
|
+
return null;
|
|
8862
|
+
}
|
|
8863
|
+
try {
|
|
8864
|
+
const r = JSON.parse(readFileSync3(claim, "utf8"));
|
|
8865
|
+
if (typeof r.oldPid === "number" && Number.isFinite(r.oldPid)) {
|
|
8866
|
+
return {
|
|
8867
|
+
oldPid: r.oldPid,
|
|
8868
|
+
envPath: typeof r.envPath === "string" ? r.envPath : "",
|
|
8869
|
+
nonce: String(r.nonce ?? "")
|
|
8870
|
+
};
|
|
8871
|
+
}
|
|
8872
|
+
} catch {
|
|
8873
|
+
}
|
|
8874
|
+
return null;
|
|
8875
|
+
}
|
|
8876
|
+
function clearRelaunchClaim() {
|
|
8877
|
+
rmSync(relaunchClaimFile(), { force: true });
|
|
8878
|
+
}
|
|
8879
|
+
function buildRelauncherPowershell(binPath = resolveCliBinPath(), nodePath = process.execPath) {
|
|
8880
|
+
const inner = `"${nodePath}" "${binPath}" __win-relaunch`;
|
|
8881
|
+
const lit = `'${inner.replace(/'/g, "''")}'`;
|
|
8882
|
+
return `$c=${lit}; try { Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine=$c } -ErrorAction Stop | Out-Null } catch { schtasks /create /tn ${RELAUNCH_TASK_NAME} /tr $c /sc ONCE /st 00:00 /f | Out-Null; schtasks /run /tn ${RELAUNCH_TASK_NAME} | Out-Null }`;
|
|
8883
|
+
}
|
|
8884
|
+
function powershellPath() {
|
|
8885
|
+
const root = process.env.SystemRoot || process.env.windir || "C:\\Windows";
|
|
8886
|
+
const p = join13(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
8887
|
+
return existsSync7(p) ? p : null;
|
|
8888
|
+
}
|
|
8889
|
+
function spawnTreeFreeRelauncher() {
|
|
8890
|
+
const ps = powershellPath();
|
|
8891
|
+
if (ps) {
|
|
8892
|
+
const errFd = openSync(serviceStderrPath(), "a");
|
|
8893
|
+
const child = spawn3(
|
|
8894
|
+
ps,
|
|
8895
|
+
["-NoProfile", "-NonInteractive", "-WindowStyle", "Hidden", "-Command", buildRelauncherPowershell()],
|
|
8896
|
+
{ detached: true, windowsHide: true, stdio: ["ignore", errFd, errFd] }
|
|
8897
|
+
);
|
|
8898
|
+
child.on("error", (e) => appendServiceErr("relaunch", `powershell spawn error: ${e.message}`));
|
|
8899
|
+
child.unref();
|
|
8900
|
+
return true;
|
|
8901
|
+
}
|
|
8902
|
+
appendServiceErr("relaunch", "powershell.exe not found; trying schtasks fallback");
|
|
8903
|
+
return spawnSchtasksRelauncher();
|
|
8904
|
+
}
|
|
8905
|
+
function spawnSchtasksRelauncher() {
|
|
8906
|
+
const tr = `"${process.execPath}" "${resolveCliBinPath()}" __win-relaunch`;
|
|
8907
|
+
const create = spawnSync2(
|
|
8908
|
+
"schtasks",
|
|
8909
|
+
["/create", "/tn", RELAUNCH_TASK_NAME, "/tr", tr, "/sc", "ONCE", "/st", "00:00", "/f"],
|
|
8910
|
+
{ encoding: "utf8", windowsHide: true }
|
|
8911
|
+
);
|
|
8912
|
+
if (create.status !== 0) {
|
|
8913
|
+
appendServiceErr("relaunch", `schtasks /create failed exit=${create.status ?? "?"} ${(create.stderr || "").trim()}`);
|
|
8914
|
+
return false;
|
|
8915
|
+
}
|
|
8916
|
+
const run = spawnSync2("schtasks", ["/run", "/tn", RELAUNCH_TASK_NAME], { encoding: "utf8", windowsHide: true });
|
|
8917
|
+
if (run.status !== 0) {
|
|
8918
|
+
appendServiceErr("relaunch", `schtasks /run failed exit=${run.status ?? "?"} ${(run.stderr || "").trim()}`);
|
|
8919
|
+
return false;
|
|
8920
|
+
}
|
|
8921
|
+
return true;
|
|
8922
|
+
}
|
|
8923
|
+
function defaultTaskkill(pid) {
|
|
8924
|
+
const r = spawnSync2("taskkill", ["/pid", String(pid), "/T", "/F"], { encoding: "utf8", windowsHide: true });
|
|
8925
|
+
return { status: r.status, stderr: (r.stderr || "").toString() };
|
|
8926
|
+
}
|
|
8927
|
+
async function runWinRelaunch(deps = {}) {
|
|
8928
|
+
const claim = deps.claimRequest ?? claimRelaunchRequest;
|
|
8929
|
+
const clearClaim = deps.clearRequest ?? clearRelaunchClaim;
|
|
8930
|
+
const alive = deps.pidAlive ?? pidAlive;
|
|
8931
|
+
const kill = deps.taskkill ?? defaultTaskkill;
|
|
8932
|
+
const start = deps.start ?? startNow;
|
|
8933
|
+
const sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
8934
|
+
const graceMs = deps.graceMs ?? 15e3;
|
|
8935
|
+
const pollMs = deps.pollMs ?? 200;
|
|
8936
|
+
const now = deps.now ?? (() => Date.now());
|
|
8937
|
+
const ensureLogs = deps.ensureLogs ?? ensureLogFiles;
|
|
8938
|
+
const logLine = deps.logLine ?? ((line) => appendServiceErr("relaunch", line));
|
|
8939
|
+
await ensureLogs();
|
|
8940
|
+
const req = claim();
|
|
8941
|
+
if (!req) {
|
|
8942
|
+
logLine("no relaunch request to claim (already handled by another relauncher, or none)");
|
|
8943
|
+
return;
|
|
8944
|
+
}
|
|
8945
|
+
try {
|
|
8946
|
+
logLine(`start oldPid=${req.oldPid} self=${process.pid}`);
|
|
8947
|
+
if (alive(req.oldPid)) {
|
|
8948
|
+
const r = kill(req.oldPid);
|
|
8949
|
+
logLine(`taskkill oldPid=${req.oldPid} exit=${r.status ?? "?"} ${r.stderr.trim()}`.trim());
|
|
8950
|
+
}
|
|
8951
|
+
const deadline = now() + graceMs;
|
|
8952
|
+
while (now() < deadline && alive(req.oldPid)) {
|
|
8953
|
+
await sleep(pollMs);
|
|
8954
|
+
}
|
|
8955
|
+
if (alive(req.oldPid)) {
|
|
8956
|
+
logLine(
|
|
8957
|
+
`ABORT: oldPid=${req.oldPid} still alive after ${graceMs}ms (elevated / access denied?); not starting new to avoid double instance`
|
|
8958
|
+
);
|
|
8959
|
+
return;
|
|
8960
|
+
}
|
|
8961
|
+
await sleep(300);
|
|
8962
|
+
start(req.envPath);
|
|
8963
|
+
logLine(`relaunched; new service.pid=${readServicePid() ?? "?"}`);
|
|
8964
|
+
} finally {
|
|
8965
|
+
clearClaim();
|
|
8966
|
+
if (process.platform === "win32") {
|
|
8967
|
+
try {
|
|
8968
|
+
spawnSync2("schtasks", ["/delete", "/tn", RELAUNCH_TASK_NAME, "/f"], { stdio: "ignore", windowsHide: true });
|
|
8969
|
+
} catch {
|
|
8970
|
+
}
|
|
8971
|
+
}
|
|
8972
|
+
}
|
|
8973
|
+
}
|
|
8824
8974
|
function statusWinStartup() {
|
|
8825
8975
|
const installed = isInstalled();
|
|
8826
8976
|
const pid = readServicePid();
|
|
@@ -8880,12 +9030,15 @@ function pidAlive(pid) {
|
|
|
8880
9030
|
function killService() {
|
|
8881
9031
|
const pid = readServicePid();
|
|
8882
9032
|
if (pid === null || !pidAlive(pid)) return;
|
|
8883
|
-
spawnSync2("taskkill", ["/pid", String(pid), "/T", "/F"], {
|
|
9033
|
+
const r = spawnSync2("taskkill", ["/pid", String(pid), "/T", "/F"], { encoding: "utf8", windowsHide: true });
|
|
9034
|
+
if (r.status !== 0) {
|
|
9035
|
+
appendServiceErr("kill", `taskkill pid=${pid} exit=${r.status ?? "?"} ${(r.stderr || "").toString().trim()}`);
|
|
9036
|
+
}
|
|
8884
9037
|
}
|
|
8885
9038
|
|
|
8886
9039
|
// src/service/systemd.ts
|
|
8887
9040
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
8888
|
-
import { existsSync as
|
|
9041
|
+
import { existsSync as existsSync8 } from "fs";
|
|
8889
9042
|
import { mkdir as mkdir10, rm as rm4, writeFile as writeFile9 } from "fs/promises";
|
|
8890
9043
|
import { homedir as homedir5 } from "os";
|
|
8891
9044
|
import { dirname as dirname8, join as join14 } from "path";
|
|
@@ -8989,7 +9142,7 @@ function statusSystemd() {
|
|
|
8989
9142
|
};
|
|
8990
9143
|
}
|
|
8991
9144
|
function unitExists() {
|
|
8992
|
-
return
|
|
9145
|
+
return existsSync8(systemdUnitPath());
|
|
8993
9146
|
}
|
|
8994
9147
|
function systemdActive() {
|
|
8995
9148
|
const r = spawnSync3("systemctl", ["--user", "is-active", SYSTEMD_UNIT_NAME], {
|
|
@@ -9064,7 +9217,7 @@ function packageName() {
|
|
|
9064
9217
|
return pkgJson().name ?? "@modelzen/feishu-codex-bridge";
|
|
9065
9218
|
}
|
|
9066
9219
|
function isDevSource() {
|
|
9067
|
-
return
|
|
9220
|
+
return existsSync9(join15(pkgRoot(), ".git"));
|
|
9068
9221
|
}
|
|
9069
9222
|
function isNewer(a, b) {
|
|
9070
9223
|
const pa = a.split(".").map((n) => Number.parseInt(n, 10) || 0);
|
|
@@ -9779,7 +9932,7 @@ init_paths();
|
|
|
9779
9932
|
init_paths();
|
|
9780
9933
|
init_logger();
|
|
9781
9934
|
import { mkdir as mkdir11 } from "fs/promises";
|
|
9782
|
-
import { existsSync as
|
|
9935
|
+
import { existsSync as existsSync10 } from "fs";
|
|
9783
9936
|
import { isAbsolute as isAbsolute2, join as join17, resolve as resolve7 } from "path";
|
|
9784
9937
|
|
|
9785
9938
|
// src/project/announcement.ts
|
|
@@ -9972,7 +10125,7 @@ function assertBackendUsable(backend, mode) {
|
|
|
9972
10125
|
async function resolveCwd(name, existingPath) {
|
|
9973
10126
|
if (existingPath) {
|
|
9974
10127
|
const cwd2 = isAbsolute2(existingPath) ? existingPath : resolve7(existingPath);
|
|
9975
|
-
if (!
|
|
10128
|
+
if (!existsSync10(cwd2)) throw new Error(`\u6587\u4EF6\u5939\u4E0D\u5B58\u5728\uFF1A${cwd2}`);
|
|
9976
10129
|
return { cwd: cwd2, blank: false };
|
|
9977
10130
|
}
|
|
9978
10131
|
const cwd = join17(paths.projectsRootDir, name);
|
|
@@ -14737,16 +14890,22 @@ async function doUpdate() {
|
|
|
14737
14890
|
}
|
|
14738
14891
|
const res = await installLatest();
|
|
14739
14892
|
log.info("daemon-control", "update-installed", { ok: res.ok });
|
|
14740
|
-
|
|
14893
|
+
appendServiceErr("daemon-control", `update-installed ok=${res.ok}`);
|
|
14894
|
+
if (!res.ok) {
|
|
14895
|
+
appendServiceErr("daemon-control", "install failed \u2014 keeping old version, not restarting");
|
|
14896
|
+
return;
|
|
14897
|
+
}
|
|
14741
14898
|
await doRestart("update");
|
|
14742
14899
|
}
|
|
14743
14900
|
async function doRestart(phase) {
|
|
14744
14901
|
if (!isServiceRunning()) {
|
|
14745
14902
|
log.info("daemon-control", "restart-skipped-no-service", { phase });
|
|
14903
|
+
appendServiceErr("daemon-control", `restart-skipped-no-service (phase=${phase}); service.pid \u672A\u6307\u5411\u5728\u8DD1\u7684 daemon`);
|
|
14746
14904
|
return;
|
|
14747
14905
|
}
|
|
14748
14906
|
await getServiceAdapter().restart();
|
|
14749
14907
|
log.info("daemon-control", "restart-issued", { phase });
|
|
14908
|
+
appendServiceErr("daemon-control", `restart-issued (phase=${phase})`);
|
|
14750
14909
|
}
|
|
14751
14910
|
|
|
14752
14911
|
// src/web/mount.ts
|
|
@@ -15495,6 +15654,9 @@ ${UI_PURE_JS}
|
|
|
15495
15654
|
var daemon = null; // /api/daemon
|
|
15496
15655
|
var diag = null; // /api/diagnosis \u7ED3\u679C\uFF08\u5F53\u524D bot \u7684\u63A2\u6D4B\uFF1B\u5207 Tab \u5FC5\u6E05\uFF09
|
|
15497
15656
|
var catalog = null; // /api/backends \u7F13\u5B58\uFF08\u540E\u7AEF\u7BA1\u7406\u5361 + \u9879\u76EE picker \u590D\u7528\uFF09
|
|
15657
|
+
var lastUpdate = null; // /api/update/check \u7ED3\u679C\u7F13\u5B58\uFF1A\u603B\u89C8 5s \u91CD\u6E32\u4E0D\u91CD\u67E5\uFF08\u6BCF\u6B21\u67E5\u90FD spawn npm view\uFF09
|
|
15658
|
+
var updateCheckedAt = 0; // \u4E0A\u6B21\u68C0\u67E5\u65F6\u95F4\u6233\uFF1B\u62FF\u5230\u7ED3\u679C\u8D85 30min\u3001\u8F6F\u5931\u8D25\u8D85 ~2min \u624D\u968F\u91CD\u6E32\u81EA\u52A8\u590D\u67E5
|
|
15659
|
+
var updateChecking = false;// in-flight \u95F8\uFF1Anpm view \u53EF\u80FD\u6570\u79D2~20s\uFF0C\u671F\u95F4 5s \u91CD\u6E32\u4E0D\u53E0\u53D1\u7B2C\u4E8C\u4E2A\u8BF7\u6C42
|
|
15498
15660
|
var drawerProject = null; // \u62BD\u5C49\u91CC\u6253\u5F00\u7684\u9879\u76EE\u540D
|
|
15499
15661
|
var diagBotId = null; // diag \u5C5E\u4E8E\u54EA\u4E2A bot\uFF08\u9632\u4E32\u53F0\uFF09
|
|
15500
15662
|
var bkDetailId = null; // \u540E\u7AEF Agent \u8BE6\u60C5\u89C6\u56FE\u5F53\u524D\u5C55\u5F00\u7684\u540E\u7AEF id\uFF08null=\u5217\u8868\uFF09
|
|
@@ -15693,6 +15855,14 @@ ${UI_PURE_JS}
|
|
|
15693
15855
|
fetch('/api/daemon').then(function (r) { return r.json(); })
|
|
15694
15856
|
.then(function (d) {
|
|
15695
15857
|
daemon = d;
|
|
15858
|
+
// \u8FD0\u884C\u4E2D\u7684\u5B9E\u9645\u7248\u672C\u4E00\u65E6\u8DDF\u7248\u672C\u68C0\u67E5\u7F13\u5B58\u91CC\u7684 current \u5BF9\u4E0D\u4E0A\uFF08\u591A\u534A\u662F\u521A\u66F4\u65B0+\u91CD\u542F\u5B8C\u6210\uFF09\uFF0C
|
|
15859
|
+
// \u5C31\u4F5C\u5E9F\u7F13\u5B58\u5E76\u5F53\u573A\u8865\u67E5\u4E00\u6B21\uFF08\u82E5\u5728\u603B\u89C8\u9875\uFF09\uFF0C\u628A\u300C\u6709\u65B0\u7248\u300D\u7ACB\u523B\u7FFB\u6210\u300C\u5DF2\u662F\u6700\u65B0\u7248\u300D\u2014\u2014\u4E0D\u7B49
|
|
15860
|
+
// \u4E0B\u4E00\u8F6E renderRoute\uFF0C\u6D88\u9664 loadState/loadDaemon \u540C\u5468\u671F\u7ADE\u6001\u5BFC\u81F4\u7684 ~10s \u5EF6\u8FDF\u4E0E\u6A2A\u5E45\u6B8B\u7559\u3002
|
|
15861
|
+
// \u53EA\u5728\u7248\u672C\u771F\u53D8\u65F6\u624D\u67E5\uFF08\u7A33\u6001 d.version===current\uFF09\uFF0C\u65E2\u7559\u4F4F\u66F4\u65B0\u540E\u7684\u5373\u65F6\u53CD\u9988\uFF0C\u53C8\u4E0D\u56DE\u5230 5s \u7A7A\u8F6C\u3002
|
|
15862
|
+
if (lastUpdate && d.version && d.version !== lastUpdate.current) {
|
|
15863
|
+
lastUpdate = null; updateCheckedAt = 0;
|
|
15864
|
+
if (parseRoute(location.hash).tab === 'overview') { var ub = $('updateBody'); if (ub) loadUpdate(ub); }
|
|
15865
|
+
}
|
|
15696
15866
|
if (parseRoute(location.hash).tab === 'overview') { var b = $('daemonBody'); if (b) renderDaemon(b); }
|
|
15697
15867
|
renderSidebarFoot();
|
|
15698
15868
|
renderGlobalSummary();
|
|
@@ -16006,7 +16176,14 @@ ${UI_PURE_JS}
|
|
|
16006
16176
|
daemonCard.appendChild(updateBody);
|
|
16007
16177
|
root.appendChild(daemonCard);
|
|
16008
16178
|
renderDaemon(daemonBody);
|
|
16009
|
-
|
|
16179
|
+
// \u7248\u672C\u68C0\u67E5\u4F1A\u5728\u670D\u52A1\u7AEF spawn\u300Cnpm view\u300D\uFF0C\u4E0D\u80FD\u8DDF\u7740 5s \u91CD\u6E32\u6BCF\u6B21\u90FD\u8DD1\uFF1A\u6709\u7F13\u5B58\u5C31\u76F4\u63A5\u6E32\uFF0C
|
|
16180
|
+
// \u53EA\u5728\u9996\u6B21\u6216\u7F13\u5B58\u8FC7\u671F\uFF0830min\uFF09\u65F6\u624D\u771F\u67E5\u4E00\u6B21\u3002\u624B\u52A8\u300C\u68C0\u67E5\u66F4\u65B0\u300D\u6309\u94AE\u4ECD\u5F3A\u5236\u5237\u65B0\u3002
|
|
16181
|
+
if (lastUpdate) {
|
|
16182
|
+
renderUpdate(updateBody, lastUpdate);
|
|
16183
|
+
if (Date.now() - updateCheckedAt > 30 * 60 * 1000) loadUpdate(updateBody);
|
|
16184
|
+
} else {
|
|
16185
|
+
loadUpdate(updateBody);
|
|
16186
|
+
}
|
|
16010
16187
|
|
|
16011
16188
|
// \u{1F916} \u673A\u5668\u4EBA\uFF08\u5728 Feishu Bridge \u5361\u4E0B\u9762\uFF0C\u5404\u81EA\u5360\u6EE1\u5BBD\u5EA6\uFF09
|
|
16012
16189
|
var botsCard = el('div', 'card');
|
|
@@ -16365,9 +16542,19 @@ ${UI_PURE_JS}
|
|
|
16365
16542
|
}
|
|
16366
16543
|
|
|
16367
16544
|
function loadUpdate(box) {
|
|
16545
|
+
if (updateChecking) return; // \u5728\u9014\u5C31\u4E0D\u53E0\u53D1\uFF1A\u6162\u68C0\u67E5\uFF08npm view \u6700\u957F 20s\uFF09\u671F\u95F4 5s \u91CD\u6E32\u4E0D\u91CD\u590D spawn
|
|
16546
|
+
updateChecking = true;
|
|
16547
|
+
updateCheckedAt = Date.now(); // \u4E50\u89C2\u5360\u4F4D\uFF1Ain-flight \u671F\u95F4 30min \u8FB9\u754C\u4E0D\u518D\u88AB\u53CD\u590D\u5224\u771F
|
|
16368
16548
|
fetch('/api/update/check').then(function (r) { return r.json(); })
|
|
16369
|
-
.then(function (u) {
|
|
16370
|
-
|
|
16549
|
+
.then(function (u) {
|
|
16550
|
+
lastUpdate = u;
|
|
16551
|
+
// \u8F6F\u5931\u8D25\uFF1A\u975E dev \u5374\u6CA1\u62FF\u5230 latest\uFF08\u591A\u534A registry \u4E0D\u53EF\u8FBE/\u8D85\u65F6\uFF0C\u670D\u52A1\u7AEF\u4ECD\u56DE 200\uFF09\uFF0C\u53EA\u7F13\u5B58 ~2min
|
|
16552
|
+
// \u4FBF\u81EA\u52A8\u590D\u67E5\uFF0C\u522B\u628A\u300C\u67E5\u8BE2\u5931\u8D25\u300D\u9489\u4F4F 30min\uFF1B\u62FF\u5230 latest \u6216 dev \u6A21\u5F0F\u624D\u6309\u5B8C\u6574 30min TTL\u3002
|
|
16553
|
+
updateCheckedAt = (u && (u.dev || u.latest)) ? Date.now() : Date.now() - 28 * 60 * 1000;
|
|
16554
|
+
renderUpdate(box, u);
|
|
16555
|
+
})
|
|
16556
|
+
.catch(function () { box.textContent = '\u26A0\uFE0F \u7248\u672C\u68C0\u67E5\u5931\u8D25\uFF08\u7F51\u7EDC\u6216 npm registry\uFF09'; })
|
|
16557
|
+
.then(function () { updateChecking = false; }); // finally\uFF1A\u65E0\u8BBA\u6210\u8D25\u90FD\u677E\u95F8
|
|
16371
16558
|
}
|
|
16372
16559
|
function renderUpdate(box, u) {
|
|
16373
16560
|
box.textContent = '';
|
|
@@ -18141,6 +18328,7 @@ async function runSupervisor(bots) {
|
|
|
18141
18328
|
const supervisorStartedAt = Date.now();
|
|
18142
18329
|
const cliEntry = process.argv[1];
|
|
18143
18330
|
if (!cliEntry) throw new Error("supervisor: \u65E0\u6CD5\u89E3\u6790 CLI \u5165\u53E3\uFF08process.argv[1] \u4E3A\u7A7A\uFF09");
|
|
18331
|
+
recordServicePid();
|
|
18144
18332
|
const childEnv = { ...process.env };
|
|
18145
18333
|
delete childEnv[SERVICE_ENV_FLAG];
|
|
18146
18334
|
let shuttingDown = false;
|
|
@@ -18407,6 +18595,7 @@ async function runOnboardingConsole() {
|
|
|
18407
18595
|
releaseLock = acquireSingleInstanceLock("__onboarding__");
|
|
18408
18596
|
} catch (err) {
|
|
18409
18597
|
if (err instanceof BridgeAlreadyRunningError) {
|
|
18598
|
+
clearServicePid();
|
|
18410
18599
|
console.error(`\u2717 ${err.message}`);
|
|
18411
18600
|
process.exitCode = 1;
|
|
18412
18601
|
return;
|
|
@@ -18475,6 +18664,7 @@ async function runSingle(botName) {
|
|
|
18475
18664
|
releaseLock = acquireSingleInstanceLock(cfg.accounts.app.id);
|
|
18476
18665
|
} catch (err) {
|
|
18477
18666
|
if (err instanceof BridgeAlreadyRunningError) {
|
|
18667
|
+
clearServicePid();
|
|
18478
18668
|
console.error(`\u2717 ${err.message}`);
|
|
18479
18669
|
log.info("run", "already-running", { pid: err.pid });
|
|
18480
18670
|
process.exitCode = 1;
|
|
@@ -19030,6 +19220,9 @@ program.command("web").description("\u672C\u673A Web \u63A7\u5236\u53F0\uFF08\u5
|
|
|
19030
19220
|
program.command("__daemon-control <action>", { hidden: true }).action(async (action) => {
|
|
19031
19221
|
await runDaemonControl(action);
|
|
19032
19222
|
});
|
|
19223
|
+
program.command("__win-relaunch", { hidden: true }).action(async () => {
|
|
19224
|
+
await runWinRelaunch();
|
|
19225
|
+
});
|
|
19033
19226
|
var bot = program.command("bot").description("\u98DE\u4E66\u673A\u5668\u4EBA\u7BA1\u7406\uFF08\u591A\u673A\u5668\u4EBA\uFF09");
|
|
19034
19227
|
bot.command("init [name]").description("\u6CE8\u518C\u4E00\u4E2A\u98DE\u4E66\u673A\u5668\u4EBA\u5E76\u6388\u6743\uFF08\u53EF\u9009\u77ED\u540D\uFF09").action(async (name) => {
|
|
19035
19228
|
await runBotInit(name);
|
package/package.json
CHANGED