@modelzen/feishu-codex-bridge 0.6.6 → 0.6.7-test.1
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 +244 -37
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -8509,8 +8509,8 @@ function withCodexHooksFeature(text) {
|
|
|
8509
8509
|
}
|
|
8510
8510
|
|
|
8511
8511
|
// src/service/update.ts
|
|
8512
|
-
import { existsSync as
|
|
8513
|
-
import { dirname as
|
|
8512
|
+
import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
|
|
8513
|
+
import { dirname as dirname10, join as join15, resolve as resolve6 } from "path";
|
|
8514
8514
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
8515
8515
|
|
|
8516
8516
|
// src/service/launchd.ts
|
|
@@ -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, filePath = serviceStderrPath()) {
|
|
8542
|
+
try {
|
|
8543
|
+
appendFileSync(filePath, `[${(/* @__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
|
-
import { join as join13 } from "path";
|
|
8759
|
+
import { dirname as dirname8, 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,16 +8787,20 @@ function buildLauncherVbs() {
|
|
|
8779
8787
|
""
|
|
8780
8788
|
].join("\r\n");
|
|
8781
8789
|
}
|
|
8782
|
-
function startNow() {
|
|
8783
|
-
const
|
|
8784
|
-
const
|
|
8790
|
+
function startNow(opts = {}) {
|
|
8791
|
+
const dir = opts.appDir ?? paths.appDir;
|
|
8792
|
+
const out = openSync(join13(dir, "service.log"), "a");
|
|
8793
|
+
const err = openSync(join13(dir, "service.err.log"), "a");
|
|
8794
|
+
const overrides = { [SERVICE_ENV_FLAG]: "1" };
|
|
8795
|
+
if (opts.envPath) overrides.PATH = opts.envPath;
|
|
8796
|
+
if (opts.userProfile) overrides.USERPROFILE = opts.userProfile;
|
|
8785
8797
|
const child = spawn3(process.execPath, [resolveCliBinPath(), "run"], {
|
|
8786
8798
|
detached: true,
|
|
8787
8799
|
windowsHide: true,
|
|
8788
8800
|
stdio: ["ignore", out, err],
|
|
8789
|
-
env: mergeProcessEnv(process.env,
|
|
8801
|
+
env: mergeProcessEnv(process.env, overrides)
|
|
8790
8802
|
});
|
|
8791
|
-
if (child.pid) writeFileSync(
|
|
8803
|
+
if (child.pid) writeFileSync(join13(dir, "service.pid"), String(child.pid), "utf8");
|
|
8792
8804
|
child.unref();
|
|
8793
8805
|
}
|
|
8794
8806
|
async function installWinStartup() {
|
|
@@ -8817,10 +8829,162 @@ async function restartWinStartup() {
|
|
|
8817
8829
|
throw new Error("\u767B\u5F55\u81EA\u542F\u672A\u5B89\u88C5\uFF08\u5148\u8FD0\u884C `feishu-codex-bridge start`\uFF09\u3002");
|
|
8818
8830
|
}
|
|
8819
8831
|
await ensureLogFiles();
|
|
8820
|
-
|
|
8821
|
-
|
|
8832
|
+
const oldPid = readServicePid();
|
|
8833
|
+
if (oldPid === null || !pidAlive(oldPid)) {
|
|
8834
|
+
startNow();
|
|
8835
|
+
return statusWinStartup();
|
|
8836
|
+
}
|
|
8837
|
+
const reqPath = relaunchRequestFile();
|
|
8838
|
+
writeRelaunchRequest({
|
|
8839
|
+
oldPid,
|
|
8840
|
+
envPath: process.env.PATH ?? "",
|
|
8841
|
+
userProfile: process.env.USERPROFILE ?? "",
|
|
8842
|
+
nonce: `${process.pid}-${Date.now()}`
|
|
8843
|
+
});
|
|
8844
|
+
if (!spawnTreeFreeRelauncher(reqPath)) {
|
|
8845
|
+
clearRelaunchRequest();
|
|
8846
|
+
appendServiceErr("relaunch", `no tree-free backend (powershell/schtasks); kept old pid=${oldPid} running, did NOT restart`);
|
|
8847
|
+
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");
|
|
8848
|
+
}
|
|
8849
|
+
appendServiceErr("relaunch", `submitted async relaunch for oldPid=${oldPid}`);
|
|
8822
8850
|
return statusWinStartup();
|
|
8823
8851
|
}
|
|
8852
|
+
function relaunchRequestFile() {
|
|
8853
|
+
return join13(paths.appDir, "relaunch.json");
|
|
8854
|
+
}
|
|
8855
|
+
function writeRelaunchRequest(req) {
|
|
8856
|
+
writeFileSync(relaunchRequestFile(), JSON.stringify(req), "utf8");
|
|
8857
|
+
}
|
|
8858
|
+
function clearRelaunchRequest() {
|
|
8859
|
+
rmSync(relaunchRequestFile(), { force: true });
|
|
8860
|
+
}
|
|
8861
|
+
function claimRelaunchRequest(reqPath) {
|
|
8862
|
+
const claim = `${reqPath}.claim.${process.pid}`;
|
|
8863
|
+
try {
|
|
8864
|
+
renameSync(reqPath, claim);
|
|
8865
|
+
} catch {
|
|
8866
|
+
return null;
|
|
8867
|
+
}
|
|
8868
|
+
try {
|
|
8869
|
+
const r = JSON.parse(readFileSync3(claim, "utf8"));
|
|
8870
|
+
if (typeof r.oldPid === "number" && Number.isFinite(r.oldPid)) {
|
|
8871
|
+
return {
|
|
8872
|
+
oldPid: r.oldPid,
|
|
8873
|
+
envPath: typeof r.envPath === "string" ? r.envPath : "",
|
|
8874
|
+
userProfile: typeof r.userProfile === "string" ? r.userProfile : "",
|
|
8875
|
+
nonce: String(r.nonce ?? "")
|
|
8876
|
+
};
|
|
8877
|
+
}
|
|
8878
|
+
} catch {
|
|
8879
|
+
}
|
|
8880
|
+
return null;
|
|
8881
|
+
}
|
|
8882
|
+
function clearRelaunchClaim(reqPath) {
|
|
8883
|
+
rmSync(`${reqPath}.claim.${process.pid}`, { force: true });
|
|
8884
|
+
}
|
|
8885
|
+
function buildRelauncherPowershell(reqPath, binPath = resolveCliBinPath(), nodePath = process.execPath) {
|
|
8886
|
+
const inner = `"${nodePath}" "${binPath}" __win-relaunch "${reqPath}"`;
|
|
8887
|
+
const lit = `'${inner.replace(/'/g, "''")}'`;
|
|
8888
|
+
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 }`;
|
|
8889
|
+
}
|
|
8890
|
+
function encodePowershellCommand(script) {
|
|
8891
|
+
return Buffer.from(script, "utf16le").toString("base64");
|
|
8892
|
+
}
|
|
8893
|
+
function powershellPath() {
|
|
8894
|
+
const root = process.env.SystemRoot || process.env.windir || "C:\\Windows";
|
|
8895
|
+
const p = join13(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
8896
|
+
return existsSync7(p) ? p : null;
|
|
8897
|
+
}
|
|
8898
|
+
function spawnTreeFreeRelauncher(reqPath) {
|
|
8899
|
+
const ps = powershellPath();
|
|
8900
|
+
if (ps) {
|
|
8901
|
+
const errFd = openSync(serviceStderrPath(), "a");
|
|
8902
|
+
const child = spawn3(
|
|
8903
|
+
ps,
|
|
8904
|
+
["-NoProfile", "-NonInteractive", "-WindowStyle", "Hidden", "-EncodedCommand", encodePowershellCommand(buildRelauncherPowershell(reqPath))],
|
|
8905
|
+
{ detached: true, windowsHide: true, stdio: ["ignore", errFd, errFd] }
|
|
8906
|
+
);
|
|
8907
|
+
child.on("error", (e) => appendServiceErr("relaunch", `powershell spawn error: ${e.message}`));
|
|
8908
|
+
child.unref();
|
|
8909
|
+
return true;
|
|
8910
|
+
}
|
|
8911
|
+
appendServiceErr("relaunch", "powershell.exe not found; trying schtasks fallback");
|
|
8912
|
+
return spawnSchtasksRelauncher(reqPath);
|
|
8913
|
+
}
|
|
8914
|
+
function spawnSchtasksRelauncher(reqPath) {
|
|
8915
|
+
const tr = `"${process.execPath}" "${resolveCliBinPath()}" __win-relaunch "${reqPath}"`;
|
|
8916
|
+
const create = spawnSync2(
|
|
8917
|
+
"schtasks",
|
|
8918
|
+
["/create", "/tn", RELAUNCH_TASK_NAME, "/tr", tr, "/sc", "ONCE", "/st", "00:00", "/f"],
|
|
8919
|
+
{ encoding: "utf8", windowsHide: true }
|
|
8920
|
+
);
|
|
8921
|
+
if (create.status !== 0) {
|
|
8922
|
+
appendServiceErr("relaunch", `schtasks /create failed exit=${create.status ?? "?"} ${(create.stderr || "").trim()}`);
|
|
8923
|
+
return false;
|
|
8924
|
+
}
|
|
8925
|
+
const run = spawnSync2("schtasks", ["/run", "/tn", RELAUNCH_TASK_NAME], { encoding: "utf8", windowsHide: true });
|
|
8926
|
+
if (run.status !== 0) {
|
|
8927
|
+
appendServiceErr("relaunch", `schtasks /run failed exit=${run.status ?? "?"} ${(run.stderr || "").trim()}`);
|
|
8928
|
+
return false;
|
|
8929
|
+
}
|
|
8930
|
+
return true;
|
|
8931
|
+
}
|
|
8932
|
+
function defaultTaskkill(pid) {
|
|
8933
|
+
const r = spawnSync2("taskkill", ["/pid", String(pid), "/T", "/F"], { encoding: "utf8", windowsHide: true });
|
|
8934
|
+
return { status: r.status, stderr: (r.stderr || "").toString() };
|
|
8935
|
+
}
|
|
8936
|
+
async function runWinRelaunch(deps = {}) {
|
|
8937
|
+
const reqPath = deps.requestPath ?? relaunchRequestFile();
|
|
8938
|
+
const appDir2 = dirname8(reqPath);
|
|
8939
|
+
const claim = deps.claimRequest ?? claimRelaunchRequest;
|
|
8940
|
+
const clearClaim = deps.clearRequest ?? clearRelaunchClaim;
|
|
8941
|
+
const alive = deps.pidAlive ?? pidAlive;
|
|
8942
|
+
const kill = deps.taskkill ?? defaultTaskkill;
|
|
8943
|
+
const start = deps.start ?? startNow;
|
|
8944
|
+
const sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
8945
|
+
const graceMs = deps.graceMs ?? 15e3;
|
|
8946
|
+
const pollMs = deps.pollMs ?? 200;
|
|
8947
|
+
const now = deps.now ?? (() => Date.now());
|
|
8948
|
+
const ensureLogs = deps.ensureLogs ?? ensureLogFiles;
|
|
8949
|
+
const logLine = deps.logLine ?? ((line) => appendServiceErr("relaunch", line, join13(appDir2, "service.err.log")));
|
|
8950
|
+
try {
|
|
8951
|
+
await ensureLogs();
|
|
8952
|
+
} catch {
|
|
8953
|
+
}
|
|
8954
|
+
const req = claim(reqPath);
|
|
8955
|
+
if (!req) {
|
|
8956
|
+
logLine("no relaunch request to claim (already handled by another relauncher, or none)");
|
|
8957
|
+
return;
|
|
8958
|
+
}
|
|
8959
|
+
try {
|
|
8960
|
+
logLine(`start oldPid=${req.oldPid} self=${process.pid}`);
|
|
8961
|
+
if (alive(req.oldPid)) {
|
|
8962
|
+
const r = kill(req.oldPid);
|
|
8963
|
+
logLine(`taskkill oldPid=${req.oldPid} exit=${r.status ?? "?"} ${r.stderr.trim()}`.trim());
|
|
8964
|
+
}
|
|
8965
|
+
const deadline = now() + graceMs;
|
|
8966
|
+
while (now() < deadline && alive(req.oldPid)) {
|
|
8967
|
+
await sleep(pollMs);
|
|
8968
|
+
}
|
|
8969
|
+
if (alive(req.oldPid)) {
|
|
8970
|
+
logLine(
|
|
8971
|
+
`ABORT: oldPid=${req.oldPid} still alive after ${graceMs}ms (elevated / access denied?); not starting new to avoid double instance`
|
|
8972
|
+
);
|
|
8973
|
+
return;
|
|
8974
|
+
}
|
|
8975
|
+
await sleep(300);
|
|
8976
|
+
start({ appDir: appDir2, envPath: req.envPath, userProfile: req.userProfile });
|
|
8977
|
+
logLine(`relaunched; new daemon started (appDir=${appDir2})`);
|
|
8978
|
+
} finally {
|
|
8979
|
+
clearClaim(reqPath);
|
|
8980
|
+
if (process.platform === "win32") {
|
|
8981
|
+
try {
|
|
8982
|
+
spawnSync2("schtasks", ["/delete", "/tn", RELAUNCH_TASK_NAME, "/f"], { stdio: "ignore", windowsHide: true });
|
|
8983
|
+
} catch {
|
|
8984
|
+
}
|
|
8985
|
+
}
|
|
8986
|
+
}
|
|
8987
|
+
}
|
|
8824
8988
|
function statusWinStartup() {
|
|
8825
8989
|
const installed = isInstalled();
|
|
8826
8990
|
const pid = readServicePid();
|
|
@@ -8880,15 +9044,18 @@ function pidAlive(pid) {
|
|
|
8880
9044
|
function killService() {
|
|
8881
9045
|
const pid = readServicePid();
|
|
8882
9046
|
if (pid === null || !pidAlive(pid)) return;
|
|
8883
|
-
spawnSync2("taskkill", ["/pid", String(pid), "/T", "/F"], {
|
|
9047
|
+
const r = spawnSync2("taskkill", ["/pid", String(pid), "/T", "/F"], { encoding: "utf8", windowsHide: true });
|
|
9048
|
+
if (r.status !== 0) {
|
|
9049
|
+
appendServiceErr("kill", `taskkill pid=${pid} exit=${r.status ?? "?"} ${(r.stderr || "").toString().trim()}`);
|
|
9050
|
+
}
|
|
8884
9051
|
}
|
|
8885
9052
|
|
|
8886
9053
|
// src/service/systemd.ts
|
|
8887
9054
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
8888
|
-
import { existsSync as
|
|
9055
|
+
import { existsSync as existsSync8 } from "fs";
|
|
8889
9056
|
import { mkdir as mkdir10, rm as rm4, writeFile as writeFile9 } from "fs/promises";
|
|
8890
9057
|
import { homedir as homedir5 } from "os";
|
|
8891
|
-
import { dirname as
|
|
9058
|
+
import { dirname as dirname9, join as join14 } from "path";
|
|
8892
9059
|
var SYSTEMD_UNIT_NAME = "feishu-codex-bridge.service";
|
|
8893
9060
|
function systemdUnitPath() {
|
|
8894
9061
|
const base = process.env.XDG_CONFIG_HOME ?? join14(homedir5(), ".config");
|
|
@@ -8946,7 +9113,7 @@ function ensureSystemdOrThrow() {
|
|
|
8946
9113
|
async function installSystemd() {
|
|
8947
9114
|
ensureSystemdOrThrow();
|
|
8948
9115
|
const unitPath = systemdUnitPath();
|
|
8949
|
-
await mkdir10(
|
|
9116
|
+
await mkdir10(dirname9(unitPath), { recursive: true });
|
|
8950
9117
|
await ensureLogFiles();
|
|
8951
9118
|
await writeFile9(unitPath, buildUnit(), "utf8");
|
|
8952
9119
|
const reload = runSystemctl(["daemon-reload"]);
|
|
@@ -8989,7 +9156,7 @@ function statusSystemd() {
|
|
|
8989
9156
|
};
|
|
8990
9157
|
}
|
|
8991
9158
|
function unitExists() {
|
|
8992
|
-
return
|
|
9159
|
+
return existsSync8(systemdUnitPath());
|
|
8993
9160
|
}
|
|
8994
9161
|
function systemdActive() {
|
|
8995
9162
|
const r = spawnSync3("systemctl", ["--user", "is-active", SYSTEMD_UNIT_NAME], {
|
|
@@ -9048,7 +9215,7 @@ function isServiceRunning() {
|
|
|
9048
9215
|
// src/service/update.ts
|
|
9049
9216
|
var NPM2 = "npm";
|
|
9050
9217
|
function pkgRoot() {
|
|
9051
|
-
return resolve6(
|
|
9218
|
+
return resolve6(dirname10(fileURLToPath4(import.meta.url)), "..");
|
|
9052
9219
|
}
|
|
9053
9220
|
function pkgJson() {
|
|
9054
9221
|
try {
|
|
@@ -9064,7 +9231,7 @@ function packageName() {
|
|
|
9064
9231
|
return pkgJson().name ?? "@modelzen/feishu-codex-bridge";
|
|
9065
9232
|
}
|
|
9066
9233
|
function isDevSource() {
|
|
9067
|
-
return
|
|
9234
|
+
return existsSync9(join15(pkgRoot(), ".git"));
|
|
9068
9235
|
}
|
|
9069
9236
|
function isNewer(a, b) {
|
|
9070
9237
|
const pa = a.split(".").map((n) => Number.parseInt(n, 10) || 0);
|
|
@@ -9710,9 +9877,9 @@ function buildUsageShareCard(data, opts = {}) {
|
|
|
9710
9877
|
init_paths();
|
|
9711
9878
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
9712
9879
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync5, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
9713
|
-
import { dirname as
|
|
9880
|
+
import { dirname as dirname11 } from "path";
|
|
9714
9881
|
function publishWebConsole(rec, file = paths.webConsoleFile) {
|
|
9715
|
-
mkdirSync2(
|
|
9882
|
+
mkdirSync2(dirname11(file), { recursive: true });
|
|
9716
9883
|
try {
|
|
9717
9884
|
unlinkSync(file);
|
|
9718
9885
|
} catch {
|
|
@@ -9752,7 +9919,7 @@ function stableWebConsoleToken(file = paths.webTokenFile) {
|
|
|
9752
9919
|
}
|
|
9753
9920
|
const token = randomUUID4();
|
|
9754
9921
|
try {
|
|
9755
|
-
mkdirSync2(
|
|
9922
|
+
mkdirSync2(dirname11(file), { recursive: true });
|
|
9756
9923
|
try {
|
|
9757
9924
|
unlinkSync(file);
|
|
9758
9925
|
} catch {
|
|
@@ -9779,7 +9946,7 @@ init_paths();
|
|
|
9779
9946
|
init_paths();
|
|
9780
9947
|
init_logger();
|
|
9781
9948
|
import { mkdir as mkdir11 } from "fs/promises";
|
|
9782
|
-
import { existsSync as
|
|
9949
|
+
import { existsSync as existsSync10 } from "fs";
|
|
9783
9950
|
import { isAbsolute as isAbsolute2, join as join17, resolve as resolve7 } from "path";
|
|
9784
9951
|
|
|
9785
9952
|
// src/project/announcement.ts
|
|
@@ -9972,7 +10139,7 @@ function assertBackendUsable(backend, mode) {
|
|
|
9972
10139
|
async function resolveCwd(name, existingPath) {
|
|
9973
10140
|
if (existingPath) {
|
|
9974
10141
|
const cwd2 = isAbsolute2(existingPath) ? existingPath : resolve7(existingPath);
|
|
9975
|
-
if (!
|
|
10142
|
+
if (!existsSync10(cwd2)) throw new Error(`\u6587\u4EF6\u5939\u4E0D\u5B58\u5728\uFF1A${cwd2}`);
|
|
9976
10143
|
return { cwd: cwd2, blank: false };
|
|
9977
10144
|
}
|
|
9978
10145
|
const cwd = join17(paths.projectsRootDir, name);
|
|
@@ -10063,7 +10230,7 @@ async function leaveChat(channel, chatId) {
|
|
|
10063
10230
|
init_paths();
|
|
10064
10231
|
import { mkdir as mkdir12, readFile as readFile11, rename as rename5, writeFile as writeFile10 } from "fs/promises";
|
|
10065
10232
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
10066
|
-
import { dirname as
|
|
10233
|
+
import { dirname as dirname12 } from "path";
|
|
10067
10234
|
var FILE_VERSION3 = 2;
|
|
10068
10235
|
var LEGACY_V1_SESSION_FIELD = "codexThreadId";
|
|
10069
10236
|
function migrate(raw) {
|
|
@@ -10099,7 +10266,7 @@ function withLock2(fn) {
|
|
|
10099
10266
|
return run;
|
|
10100
10267
|
}
|
|
10101
10268
|
async function write2(sessions) {
|
|
10102
|
-
await mkdir12(
|
|
10269
|
+
await mkdir12(dirname12(paths.sessionsFile), { recursive: true });
|
|
10103
10270
|
const tmp = `${paths.sessionsFile}.tmp-${process.pid}-${randomUUID5()}`;
|
|
10104
10271
|
const body = { version: FILE_VERSION3, sessions };
|
|
10105
10272
|
await writeFile10(tmp, `${JSON.stringify(body, null, 2)}
|
|
@@ -10715,7 +10882,7 @@ function weaveSender(text, sender) {
|
|
|
10715
10882
|
// src/bot/comments.ts
|
|
10716
10883
|
init_logger();
|
|
10717
10884
|
import { mkdir as mkdir14, readdir as readdir4, readFile as readFile12, writeFile as writeFile11 } from "fs/promises";
|
|
10718
|
-
import { dirname as
|
|
10885
|
+
import { dirname as dirname13, join as join19 } from "path";
|
|
10719
10886
|
var SUPPORTED_FILE_TYPES = /* @__PURE__ */ new Set(["doc", "docx", "sheet", "bitable"]);
|
|
10720
10887
|
var REPLY_MAX_CHARS = 2e3;
|
|
10721
10888
|
function apiErrCode(err) {
|
|
@@ -10847,7 +11014,7 @@ async function loadCommentInstructions(masterFile) {
|
|
|
10847
11014
|
return existing.trim() ? existing : DEFAULT_COMMENT_INSTRUCTIONS;
|
|
10848
11015
|
} catch {
|
|
10849
11016
|
}
|
|
10850
|
-
await mkdir14(
|
|
11017
|
+
await mkdir14(dirname13(masterFile), { recursive: true }).catch(() => void 0);
|
|
10851
11018
|
await writeFile11(masterFile, DEFAULT_COMMENT_INSTRUCTIONS, "utf8").catch(() => void 0);
|
|
10852
11019
|
return DEFAULT_COMMENT_INSTRUCTIONS;
|
|
10853
11020
|
}
|
|
@@ -10859,7 +11026,7 @@ async function syncCommentInstructions(cwd, instructions) {
|
|
|
10859
11026
|
]);
|
|
10860
11027
|
}
|
|
10861
11028
|
async function saveCommentInstructions(masterFile, content) {
|
|
10862
|
-
await mkdir14(
|
|
11029
|
+
await mkdir14(dirname13(masterFile), { recursive: true });
|
|
10863
11030
|
await writeFile11(masterFile, content, "utf8");
|
|
10864
11031
|
}
|
|
10865
11032
|
function renderCommentInstructions(template, tenant, fileType, fileToken) {
|
|
@@ -14130,7 +14297,7 @@ init_logger();
|
|
|
14130
14297
|
// src/admin/host.ts
|
|
14131
14298
|
init_paths();
|
|
14132
14299
|
import { readdir as readdir5, stat as stat4 } from "fs/promises";
|
|
14133
|
-
import { dirname as
|
|
14300
|
+
import { dirname as dirname14, join as join21, resolve as resolve8 } from "path";
|
|
14134
14301
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
14135
14302
|
import { arch, platform as platform2, release } from "os";
|
|
14136
14303
|
function toDaemonStatus(opts) {
|
|
@@ -14182,7 +14349,7 @@ async function collectHostDoctor(logsDir2 = join21(paths.appDir, "logs")) {
|
|
|
14182
14349
|
};
|
|
14183
14350
|
}
|
|
14184
14351
|
function resolveCliBinPath3() {
|
|
14185
|
-
const distDir =
|
|
14352
|
+
const distDir = dirname14(fileURLToPath5(import.meta.url));
|
|
14186
14353
|
return resolve8(distDir, "..", "bin", "feishu-codex-bridge.mjs");
|
|
14187
14354
|
}
|
|
14188
14355
|
function buildDaemonControlCommand(action, binPath = resolveCliBinPath3(), nodePath = process.execPath) {
|
|
@@ -14737,16 +14904,22 @@ async function doUpdate() {
|
|
|
14737
14904
|
}
|
|
14738
14905
|
const res = await installLatest();
|
|
14739
14906
|
log.info("daemon-control", "update-installed", { ok: res.ok });
|
|
14740
|
-
|
|
14907
|
+
appendServiceErr("daemon-control", `update-installed ok=${res.ok}`);
|
|
14908
|
+
if (!res.ok) {
|
|
14909
|
+
appendServiceErr("daemon-control", "install failed \u2014 keeping old version, not restarting");
|
|
14910
|
+
return;
|
|
14911
|
+
}
|
|
14741
14912
|
await doRestart("update");
|
|
14742
14913
|
}
|
|
14743
14914
|
async function doRestart(phase) {
|
|
14744
14915
|
if (!isServiceRunning()) {
|
|
14745
14916
|
log.info("daemon-control", "restart-skipped-no-service", { phase });
|
|
14917
|
+
appendServiceErr("daemon-control", `restart-skipped-no-service (phase=${phase}); service.pid \u672A\u6307\u5411\u5728\u8DD1\u7684 daemon`);
|
|
14746
14918
|
return;
|
|
14747
14919
|
}
|
|
14748
14920
|
await getServiceAdapter().restart();
|
|
14749
14921
|
log.info("daemon-control", "restart-issued", { phase });
|
|
14922
|
+
appendServiceErr("daemon-control", `restart-issued (phase=${phase})`);
|
|
14750
14923
|
}
|
|
14751
14924
|
|
|
14752
14925
|
// src/web/mount.ts
|
|
@@ -15495,6 +15668,9 @@ ${UI_PURE_JS}
|
|
|
15495
15668
|
var daemon = null; // /api/daemon
|
|
15496
15669
|
var diag = null; // /api/diagnosis \u7ED3\u679C\uFF08\u5F53\u524D bot \u7684\u63A2\u6D4B\uFF1B\u5207 Tab \u5FC5\u6E05\uFF09
|
|
15497
15670
|
var catalog = null; // /api/backends \u7F13\u5B58\uFF08\u540E\u7AEF\u7BA1\u7406\u5361 + \u9879\u76EE picker \u590D\u7528\uFF09
|
|
15671
|
+
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
|
|
15672
|
+
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
|
|
15673
|
+
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
15674
|
var drawerProject = null; // \u62BD\u5C49\u91CC\u6253\u5F00\u7684\u9879\u76EE\u540D
|
|
15499
15675
|
var diagBotId = null; // diag \u5C5E\u4E8E\u54EA\u4E2A bot\uFF08\u9632\u4E32\u53F0\uFF09
|
|
15500
15676
|
var bkDetailId = null; // \u540E\u7AEF Agent \u8BE6\u60C5\u89C6\u56FE\u5F53\u524D\u5C55\u5F00\u7684\u540E\u7AEF id\uFF08null=\u5217\u8868\uFF09
|
|
@@ -15693,6 +15869,14 @@ ${UI_PURE_JS}
|
|
|
15693
15869
|
fetch('/api/daemon').then(function (r) { return r.json(); })
|
|
15694
15870
|
.then(function (d) {
|
|
15695
15871
|
daemon = d;
|
|
15872
|
+
// \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
|
|
15873
|
+
// \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
|
|
15874
|
+
// \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
|
|
15875
|
+
// \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
|
|
15876
|
+
if (lastUpdate && d.version && d.version !== lastUpdate.current) {
|
|
15877
|
+
lastUpdate = null; updateCheckedAt = 0;
|
|
15878
|
+
if (parseRoute(location.hash).tab === 'overview') { var ub = $('updateBody'); if (ub) loadUpdate(ub); }
|
|
15879
|
+
}
|
|
15696
15880
|
if (parseRoute(location.hash).tab === 'overview') { var b = $('daemonBody'); if (b) renderDaemon(b); }
|
|
15697
15881
|
renderSidebarFoot();
|
|
15698
15882
|
renderGlobalSummary();
|
|
@@ -16006,7 +16190,14 @@ ${UI_PURE_JS}
|
|
|
16006
16190
|
daemonCard.appendChild(updateBody);
|
|
16007
16191
|
root.appendChild(daemonCard);
|
|
16008
16192
|
renderDaemon(daemonBody);
|
|
16009
|
-
|
|
16193
|
+
// \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
|
|
16194
|
+
// \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
|
|
16195
|
+
if (lastUpdate) {
|
|
16196
|
+
renderUpdate(updateBody, lastUpdate);
|
|
16197
|
+
if (Date.now() - updateCheckedAt > 30 * 60 * 1000) loadUpdate(updateBody);
|
|
16198
|
+
} else {
|
|
16199
|
+
loadUpdate(updateBody);
|
|
16200
|
+
}
|
|
16010
16201
|
|
|
16011
16202
|
// \u{1F916} \u673A\u5668\u4EBA\uFF08\u5728 Feishu Bridge \u5361\u4E0B\u9762\uFF0C\u5404\u81EA\u5360\u6EE1\u5BBD\u5EA6\uFF09
|
|
16012
16203
|
var botsCard = el('div', 'card');
|
|
@@ -16365,9 +16556,19 @@ ${UI_PURE_JS}
|
|
|
16365
16556
|
}
|
|
16366
16557
|
|
|
16367
16558
|
function loadUpdate(box) {
|
|
16559
|
+
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
|
|
16560
|
+
updateChecking = true;
|
|
16561
|
+
updateCheckedAt = Date.now(); // \u4E50\u89C2\u5360\u4F4D\uFF1Ain-flight \u671F\u95F4 30min \u8FB9\u754C\u4E0D\u518D\u88AB\u53CD\u590D\u5224\u771F
|
|
16368
16562
|
fetch('/api/update/check').then(function (r) { return r.json(); })
|
|
16369
|
-
.then(function (u) {
|
|
16370
|
-
|
|
16563
|
+
.then(function (u) {
|
|
16564
|
+
lastUpdate = u;
|
|
16565
|
+
// \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
|
|
16566
|
+
// \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
|
|
16567
|
+
updateCheckedAt = (u && (u.dev || u.latest)) ? Date.now() : Date.now() - 28 * 60 * 1000;
|
|
16568
|
+
renderUpdate(box, u);
|
|
16569
|
+
})
|
|
16570
|
+
.catch(function () { box.textContent = '\u26A0\uFE0F \u7248\u672C\u68C0\u67E5\u5931\u8D25\uFF08\u7F51\u7EDC\u6216 npm registry\uFF09'; })
|
|
16571
|
+
.then(function () { updateChecking = false; }); // finally\uFF1A\u65E0\u8BBA\u6210\u8D25\u90FD\u677E\u95F8
|
|
16371
16572
|
}
|
|
16372
16573
|
function renderUpdate(box, u) {
|
|
16373
16574
|
box.textContent = '';
|
|
@@ -18141,6 +18342,7 @@ async function runSupervisor(bots) {
|
|
|
18141
18342
|
const supervisorStartedAt = Date.now();
|
|
18142
18343
|
const cliEntry = process.argv[1];
|
|
18143
18344
|
if (!cliEntry) throw new Error("supervisor: \u65E0\u6CD5\u89E3\u6790 CLI \u5165\u53E3\uFF08process.argv[1] \u4E3A\u7A7A\uFF09");
|
|
18345
|
+
recordServicePid();
|
|
18144
18346
|
const childEnv = { ...process.env };
|
|
18145
18347
|
delete childEnv[SERVICE_ENV_FLAG];
|
|
18146
18348
|
let shuttingDown = false;
|
|
@@ -18274,7 +18476,7 @@ async function runSupervisor(bots) {
|
|
|
18274
18476
|
// src/core/single-instance.ts
|
|
18275
18477
|
init_paths();
|
|
18276
18478
|
import { mkdirSync as mkdirSync4, readFileSync as readFileSync6, statSync as statSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
18277
|
-
import { dirname as
|
|
18479
|
+
import { dirname as dirname15 } from "path";
|
|
18278
18480
|
var CLAIM_ATTEMPTS = 5;
|
|
18279
18481
|
var PID_REUSE_SLACK_MS = 15e3;
|
|
18280
18482
|
var EMPTY_LOCK_STALE_MS = 2e3;
|
|
@@ -18320,7 +18522,7 @@ function isLiveHolder(rec, appId) {
|
|
|
18320
18522
|
return true;
|
|
18321
18523
|
}
|
|
18322
18524
|
function acquireSingleInstanceLock(appId, file = paths.processesFile) {
|
|
18323
|
-
mkdirSync4(
|
|
18525
|
+
mkdirSync4(dirname15(file), { recursive: true });
|
|
18324
18526
|
const record = { pid: process.pid, appId, startedAt: Date.now() };
|
|
18325
18527
|
for (let attempt = 0; attempt < CLAIM_ATTEMPTS; attempt++) {
|
|
18326
18528
|
try {
|
|
@@ -18407,6 +18609,7 @@ async function runOnboardingConsole() {
|
|
|
18407
18609
|
releaseLock = acquireSingleInstanceLock("__onboarding__");
|
|
18408
18610
|
} catch (err) {
|
|
18409
18611
|
if (err instanceof BridgeAlreadyRunningError) {
|
|
18612
|
+
clearServicePid();
|
|
18410
18613
|
console.error(`\u2717 ${err.message}`);
|
|
18411
18614
|
process.exitCode = 1;
|
|
18412
18615
|
return;
|
|
@@ -18475,6 +18678,7 @@ async function runSingle(botName) {
|
|
|
18475
18678
|
releaseLock = acquireSingleInstanceLock(cfg.accounts.app.id);
|
|
18476
18679
|
} catch (err) {
|
|
18477
18680
|
if (err instanceof BridgeAlreadyRunningError) {
|
|
18681
|
+
clearServicePid();
|
|
18478
18682
|
console.error(`\u2717 ${err.message}`);
|
|
18479
18683
|
log.info("run", "already-running", { pid: err.pid });
|
|
18480
18684
|
process.exitCode = 1;
|
|
@@ -19030,6 +19234,9 @@ program.command("web").description("\u672C\u673A Web \u63A7\u5236\u53F0\uFF08\u5
|
|
|
19030
19234
|
program.command("__daemon-control <action>", { hidden: true }).action(async (action) => {
|
|
19031
19235
|
await runDaemonControl(action);
|
|
19032
19236
|
});
|
|
19237
|
+
program.command("__win-relaunch [requestPath]", { hidden: true }).action(async (requestPath) => {
|
|
19238
|
+
await runWinRelaunch({ requestPath });
|
|
19239
|
+
});
|
|
19033
19240
|
var bot = program.command("bot").description("\u98DE\u4E66\u673A\u5668\u4EBA\u7BA1\u7406\uFF08\u591A\u673A\u5668\u4EBA\uFF09");
|
|
19034
19241
|
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
19242
|
await runBotInit(name);
|
package/package.json
CHANGED