@zqagent/core 0.2.8 → 0.2.11
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/README.md +2 -0
- package/README.oss.en.md +1 -1
- package/README.oss.md +1 -1
- package/README.oss.zh-TW.md +1 -1
- package/dist/cli/index.cjs +733 -351
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +739 -357
- package/dist/cli/index.js.map +1 -1
- package/dist/server/index.cjs +167 -43
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js +167 -43
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.cjs
CHANGED
|
@@ -3741,10 +3741,10 @@ var OpenAIProvider = class {
|
|
|
3741
3741
|
let timer;
|
|
3742
3742
|
try {
|
|
3743
3743
|
for (; ; ) {
|
|
3744
|
-
const idle = new Promise((
|
|
3744
|
+
const idle = new Promise((resolve24) => {
|
|
3745
3745
|
timer = setTimeout(() => {
|
|
3746
3746
|
onIdle();
|
|
3747
|
-
|
|
3747
|
+
resolve24({ timedOut: true });
|
|
3748
3748
|
}, idleMs);
|
|
3749
3749
|
});
|
|
3750
3750
|
const next = iter.next();
|
|
@@ -6065,12 +6065,12 @@ function makeSink(maxBuffer) {
|
|
|
6065
6065
|
};
|
|
6066
6066
|
}
|
|
6067
6067
|
function execAsync(file, argv, opts = {}) {
|
|
6068
|
-
return new Promise((
|
|
6068
|
+
return new Promise((resolve24) => {
|
|
6069
6069
|
const maxBuffer = opts.maxBuffer ?? DEFAULT_MAX_BUFFER;
|
|
6070
6070
|
const out = makeSink(maxBuffer);
|
|
6071
6071
|
const err = makeSink(maxBuffer);
|
|
6072
6072
|
if (opts.signal?.aborted) {
|
|
6073
|
-
|
|
6073
|
+
resolve24({
|
|
6074
6074
|
status: null,
|
|
6075
6075
|
stdout: Buffer.alloc(0),
|
|
6076
6076
|
stderr: Buffer.alloc(0),
|
|
@@ -6091,7 +6091,7 @@ function execAsync(file, argv, opts = {}) {
|
|
|
6091
6091
|
windowsHide: true
|
|
6092
6092
|
});
|
|
6093
6093
|
} catch (e) {
|
|
6094
|
-
|
|
6094
|
+
resolve24({
|
|
6095
6095
|
status: null,
|
|
6096
6096
|
stdout: Buffer.alloc(0),
|
|
6097
6097
|
stderr: Buffer.alloc(0),
|
|
@@ -6128,7 +6128,7 @@ function execAsync(file, argv, opts = {}) {
|
|
|
6128
6128
|
};
|
|
6129
6129
|
if (aborted) result.aborted = true;
|
|
6130
6130
|
if (spawnError) result.error = spawnError;
|
|
6131
|
-
|
|
6131
|
+
resolve24(result);
|
|
6132
6132
|
};
|
|
6133
6133
|
const killAndSettle = () => {
|
|
6134
6134
|
killTree(child.pid);
|
|
@@ -10094,6 +10094,38 @@ function countRawEscapes(chunk) {
|
|
|
10094
10094
|
for (const ch of cleaned) if (ch === "\x1B") escCount++;
|
|
10095
10095
|
return escCount;
|
|
10096
10096
|
}
|
|
10097
|
+
function patchReadlineHistoryNav(rl2) {
|
|
10098
|
+
const iface = rl2;
|
|
10099
|
+
const orig = iface._ttyWrite;
|
|
10100
|
+
let draft = null;
|
|
10101
|
+
iface._ttyWrite = function(s, key) {
|
|
10102
|
+
const k = key;
|
|
10103
|
+
const name = k?.name;
|
|
10104
|
+
const plainArrow = (name === "up" || name === "down") && !k?.ctrl && !k?.meta && !k?.shift;
|
|
10105
|
+
if (plainArrow) {
|
|
10106
|
+
if (name === "up" && iface.historyIndex === -1) {
|
|
10107
|
+
draft = { line: iface.line, cursor: iface.cursor };
|
|
10108
|
+
}
|
|
10109
|
+
if (iface.cursor > 0) {
|
|
10110
|
+
iface._moveCursor(-iface.cursor);
|
|
10111
|
+
}
|
|
10112
|
+
}
|
|
10113
|
+
const prevHistoryIndex = iface.historyIndex;
|
|
10114
|
+
orig.call(rl2, s, key);
|
|
10115
|
+
if (plainArrow && name === "down" && prevHistoryIndex >= 0 && iface.historyIndex === -1) {
|
|
10116
|
+
const saved = draft;
|
|
10117
|
+
draft = null;
|
|
10118
|
+
if (saved) {
|
|
10119
|
+
iface.line = saved.line;
|
|
10120
|
+
iface.cursor = Math.min(saved.cursor, saved.line.length);
|
|
10121
|
+
iface._refreshLine?.();
|
|
10122
|
+
}
|
|
10123
|
+
}
|
|
10124
|
+
};
|
|
10125
|
+
rl2.on("line", () => {
|
|
10126
|
+
draft = null;
|
|
10127
|
+
});
|
|
10128
|
+
}
|
|
10097
10129
|
var PASTE_PLACEHOLDER_PREFIX = "\u7C98\u8D34\u6587\u672C #";
|
|
10098
10130
|
var InputRouter = class {
|
|
10099
10131
|
rl;
|
|
@@ -10218,8 +10250,8 @@ var InputRouter = class {
|
|
|
10218
10250
|
}
|
|
10219
10251
|
/** 询问一行:显示 prompt,返回该行内容 */
|
|
10220
10252
|
ask(prompt) {
|
|
10221
|
-
return new Promise((
|
|
10222
|
-
this.pendingAsks.push({ prompt, resolve:
|
|
10253
|
+
return new Promise((resolve24) => {
|
|
10254
|
+
this.pendingAsks.push({ prompt, resolve: resolve24 });
|
|
10223
10255
|
this.pumpAsks();
|
|
10224
10256
|
});
|
|
10225
10257
|
}
|
|
@@ -10316,16 +10348,16 @@ var import_chalk2 = __toESM(require("chalk"), 1);
|
|
|
10316
10348
|
var BRAND_TEXT = "ZQAGENT";
|
|
10317
10349
|
var BRAND_TAGLINE = "ZQAgent \xB7 AI Agent CLI";
|
|
10318
10350
|
var GLYPHS = {
|
|
10319
|
-
Z: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588
|
|
10320
|
-
Q: [" \u2588\u2588\u2588\u2588\u2588\u2588
|
|
10321
|
-
A: [" \u2588\u2588\u2588\u2588\u2588\
|
|
10322
|
-
G: [" \u2588\u2588\u2588\u2588\u2588\u2588
|
|
10323
|
-
E: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588
|
|
10324
|
-
N: ["\u2588\u2588\u2588\
|
|
10325
|
-
T: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588
|
|
10351
|
+
Z: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588\u2588 ", " \u2588\u2588\u2588 ", " \u2588\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", " "],
|
|
10352
|
+
Q: [" \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588", "\u2588\u2588 \u2588\u2588", "\u2588\u2588 \u2584\u2584 \u2588\u2588", " \u2588\u2588\u2588\u2588\u2588\u2588 ", " \u2580\u2580 "],
|
|
10353
|
+
A: [" \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588", "\u2588\u2588 \u2588\u2588", "\u2588\u2588 \u2588\u2588", " "],
|
|
10354
|
+
G: [" \u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588 \u2588\u2588\u2588", "\u2588\u2588 \u2588\u2588", " \u2588\u2588\u2588\u2588\u2588\u2588 ", " "],
|
|
10355
|
+
E: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 ", "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ", " "],
|
|
10356
|
+
N: ["\u2588\u2588 \u2588\u2588", "\u2588\u2588\u2588 \u2588\u2588", "\u2588\u2588\u2588\u2588 \u2588\u2588", "\u2588\u2588 \u2588\u2588 \u2588\u2588", "\u2588\u2588 \u2588\u2588\u2588\u2588", " "],
|
|
10357
|
+
T: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " "]
|
|
10326
10358
|
};
|
|
10327
10359
|
var GLYPH_ROWS = 6;
|
|
10328
|
-
var GLYPH_COLS =
|
|
10360
|
+
var GLYPH_COLS = 9;
|
|
10329
10361
|
var GRADIENT = [
|
|
10330
10362
|
[34, 211, 238],
|
|
10331
10363
|
[99, 102, 241],
|
|
@@ -10481,7 +10513,7 @@ function renderTerminalTutorial() {
|
|
|
10481
10513
|
|
|
10482
10514
|
// src/cli/link.ts
|
|
10483
10515
|
init_cjs_shims();
|
|
10484
|
-
var
|
|
10516
|
+
var path22 = __toESM(require("path"), 1);
|
|
10485
10517
|
|
|
10486
10518
|
// src/server/store.ts
|
|
10487
10519
|
init_cjs_shims();
|
|
@@ -10891,11 +10923,186 @@ async function hubEnrollByAccount(baseUrl, input) {
|
|
|
10891
10923
|
|
|
10892
10924
|
// src/cli/serve-instances.ts
|
|
10893
10925
|
init_cjs_shims();
|
|
10894
|
-
var
|
|
10926
|
+
var import_node_child_process5 = require("child_process");
|
|
10927
|
+
var fs19 = __toESM(require("fs"), 1);
|
|
10928
|
+
var os5 = __toESM(require("os"), 1);
|
|
10929
|
+
var path21 = __toESM(require("path"), 1);
|
|
10930
|
+
|
|
10931
|
+
// src/update/platform.ts
|
|
10932
|
+
init_cjs_shims();
|
|
10895
10933
|
var fs18 = __toESM(require("fs"), 1);
|
|
10934
|
+
var os4 = __toESM(require("os"), 1);
|
|
10896
10935
|
var path20 = __toESM(require("path"), 1);
|
|
10936
|
+
var import_node_child_process4 = require("child_process");
|
|
10937
|
+
var import_node_module3 = require("module");
|
|
10938
|
+
function currentVersion() {
|
|
10939
|
+
const injected = "0.2.11"?.trim();
|
|
10940
|
+
if (injected) return injected;
|
|
10941
|
+
try {
|
|
10942
|
+
const req2 = (0, import_node_module3.createRequire)(importMetaUrl);
|
|
10943
|
+
const pkg = req2("../../package.json");
|
|
10944
|
+
if (pkg?.version) return pkg.version;
|
|
10945
|
+
} catch {
|
|
10946
|
+
}
|
|
10947
|
+
return "dev";
|
|
10948
|
+
}
|
|
10949
|
+
function isSeaRuntime() {
|
|
10950
|
+
if (process.env.ZQAGENT_SEA === "1") return true;
|
|
10951
|
+
const base = path20.basename(process.execPath).toLowerCase().replace(/\.exe$/, "");
|
|
10952
|
+
return base !== "node" && base !== "nodejs";
|
|
10953
|
+
}
|
|
10954
|
+
var DEFAULT_SERVICE_NAME = "zqagent";
|
|
10955
|
+
var DEFAULT_SERVICE_LABEL = "com.zqagent.node";
|
|
10956
|
+
function serviceManagerFromCgroup(cgroup, serviceName = DEFAULT_SERVICE_NAME) {
|
|
10957
|
+
const unitName = `${serviceName}.service`;
|
|
10958
|
+
for (const line of cgroup.split("\n")) {
|
|
10959
|
+
const idx = line.lastIndexOf(":");
|
|
10960
|
+
if (idx < 0) continue;
|
|
10961
|
+
const unitPath = line.slice(idx + 1).trim();
|
|
10962
|
+
if (unitPath.split("/").includes(unitName)) return "systemd";
|
|
10963
|
+
}
|
|
10964
|
+
return null;
|
|
10965
|
+
}
|
|
10966
|
+
function launchdDomain() {
|
|
10967
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : -1;
|
|
10968
|
+
return uid === 0 ? "system" : `gui/${uid}`;
|
|
10969
|
+
}
|
|
10970
|
+
function launchdLabel() {
|
|
10971
|
+
return process.env.ZQAGENT_SERVICE_LABEL?.trim() || DEFAULT_SERVICE_LABEL;
|
|
10972
|
+
}
|
|
10973
|
+
function launchdPlistPath() {
|
|
10974
|
+
const label = launchdLabel();
|
|
10975
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : -1;
|
|
10976
|
+
if (uid === 0) return `/Library/LaunchDaemons/${label}.plist`;
|
|
10977
|
+
return path20.join(os4.homedir(), "Library", "LaunchAgents", `${label}.plist`);
|
|
10978
|
+
}
|
|
10979
|
+
function serviceManagerFromLaunchctl(output, pid, execPath, sea = true) {
|
|
10980
|
+
const pidMatch = /^\s*pid = (\d+)\s*$/m.exec(output);
|
|
10981
|
+
if (pidMatch && Number(pidMatch[1]) === pid) return "launchd";
|
|
10982
|
+
const program = /^\s*program = (.+?)\s*$/m.exec(output);
|
|
10983
|
+
if (program) {
|
|
10984
|
+
const shown = program[1].replace(/^"|"$/g, "");
|
|
10985
|
+
if (path20.resolve(shown) === path20.resolve(execPath)) return "launchd";
|
|
10986
|
+
}
|
|
10987
|
+
if (!sea && /^\s*state = /m.test(output)) return "launchd";
|
|
10988
|
+
return null;
|
|
10989
|
+
}
|
|
10990
|
+
function parseLaunchdEnvironment(xml) {
|
|
10991
|
+
const out = {};
|
|
10992
|
+
const marker = xml.indexOf("<key>EnvironmentVariables</key>");
|
|
10993
|
+
if (marker < 0) return out;
|
|
10994
|
+
const open = xml.indexOf("<dict>", marker);
|
|
10995
|
+
if (open < 0) return out;
|
|
10996
|
+
const close = xml.indexOf("</dict>", open);
|
|
10997
|
+
if (close < 0) return out;
|
|
10998
|
+
const body = xml.slice(open + "<dict>".length, close);
|
|
10999
|
+
for (const m of body.matchAll(/<key>([^<]+)<\/key>\s*<string>([^<]*)<\/string>/g)) {
|
|
11000
|
+
out[m[1]] = m[2];
|
|
11001
|
+
}
|
|
11002
|
+
return out;
|
|
11003
|
+
}
|
|
11004
|
+
function detectServiceManager() {
|
|
11005
|
+
if (process.platform === "darwin") return detectLaunchd();
|
|
11006
|
+
if (process.platform !== "linux") return null;
|
|
11007
|
+
const serviceName = process.env.ZQAGENT_SERVICE_NAME?.trim() || DEFAULT_SERVICE_NAME;
|
|
11008
|
+
try {
|
|
11009
|
+
return serviceManagerFromCgroup(
|
|
11010
|
+
fs18.readFileSync("/proc/self/cgroup", "utf8"),
|
|
11011
|
+
serviceName
|
|
11012
|
+
);
|
|
11013
|
+
} catch {
|
|
11014
|
+
return null;
|
|
11015
|
+
}
|
|
11016
|
+
}
|
|
11017
|
+
function detectLaunchd() {
|
|
11018
|
+
try {
|
|
11019
|
+
const res = (0, import_node_child_process4.spawnSync)(
|
|
11020
|
+
"launchctl",
|
|
11021
|
+
["print", `${launchdDomain()}/${launchdLabel()}`],
|
|
11022
|
+
{ encoding: "utf8", timeout: 3e3 }
|
|
11023
|
+
);
|
|
11024
|
+
if (res.status !== 0 || !res.stdout) return null;
|
|
11025
|
+
return serviceManagerFromLaunchctl(
|
|
11026
|
+
res.stdout,
|
|
11027
|
+
process.pid,
|
|
11028
|
+
process.execPath,
|
|
11029
|
+
isSeaRuntime()
|
|
11030
|
+
);
|
|
11031
|
+
} catch {
|
|
11032
|
+
return null;
|
|
11033
|
+
}
|
|
11034
|
+
}
|
|
11035
|
+
function serviceManager() {
|
|
11036
|
+
const v = process.env.ZQAGENT_SERVICE_MANAGER?.trim().toLowerCase();
|
|
11037
|
+
if (v === "systemd" || v === "launchd") return v;
|
|
11038
|
+
return detectServiceManager();
|
|
11039
|
+
}
|
|
11040
|
+
function parseServiceEnvironment(raw) {
|
|
11041
|
+
const out = {};
|
|
11042
|
+
for (const token of raw.trim().split(/\s+/)) {
|
|
11043
|
+
const idx = token.indexOf("=");
|
|
11044
|
+
if (idx > 0) out[token.slice(0, idx)] = token.slice(idx + 1);
|
|
11045
|
+
}
|
|
11046
|
+
return out;
|
|
11047
|
+
}
|
|
11048
|
+
var cachedServiceEnv = null;
|
|
11049
|
+
function readServiceEnvironment() {
|
|
11050
|
+
const serviceName = process.env.ZQAGENT_SERVICE_NAME?.trim() || DEFAULT_SERVICE_NAME;
|
|
11051
|
+
try {
|
|
11052
|
+
const res = (0, import_node_child_process4.spawnSync)(
|
|
11053
|
+
"systemctl",
|
|
11054
|
+
["show", serviceName, "--property=Environment", "--value", "--no-pager"],
|
|
11055
|
+
{ encoding: "utf8", timeout: 3e3 }
|
|
11056
|
+
);
|
|
11057
|
+
if (res.status !== 0 || !res.stdout) return {};
|
|
11058
|
+
return parseServiceEnvironment(res.stdout);
|
|
11059
|
+
} catch {
|
|
11060
|
+
return {};
|
|
11061
|
+
}
|
|
11062
|
+
}
|
|
11063
|
+
function serviceEnvValue(key) {
|
|
11064
|
+
if (process.platform === "darwin") {
|
|
11065
|
+
if (serviceManager() !== "launchd") return void 0;
|
|
11066
|
+
cachedLaunchdEnv ??= readLaunchdEnvironment();
|
|
11067
|
+
return cachedLaunchdEnv[key];
|
|
11068
|
+
}
|
|
11069
|
+
if (process.platform !== "linux") return void 0;
|
|
11070
|
+
if (serviceManager() !== "systemd") return void 0;
|
|
11071
|
+
cachedServiceEnv ??= readServiceEnvironment();
|
|
11072
|
+
return cachedServiceEnv[key];
|
|
11073
|
+
}
|
|
11074
|
+
var cachedLaunchdEnv = null;
|
|
11075
|
+
function readLaunchdEnvironment() {
|
|
11076
|
+
try {
|
|
11077
|
+
return parseLaunchdEnvironment(fs18.readFileSync(launchdPlistPath(), "utf8"));
|
|
11078
|
+
} catch {
|
|
11079
|
+
return {};
|
|
11080
|
+
}
|
|
11081
|
+
}
|
|
11082
|
+
function selfUpdateCapability(hasPublicKey) {
|
|
11083
|
+
if (!isSeaRuntime()) {
|
|
11084
|
+
return {
|
|
11085
|
+
ok: false,
|
|
11086
|
+
reason: "\u5F53\u524D\u4E0D\u662F\u5355\u6587\u4EF6\uFF08SEA\uFF09\u5F62\u6001\uFF1A\u8BF7\u7528 npm \u5347\u7EA7\uFF08npm i -g @zqagent/core@latest\uFF09"
|
|
11087
|
+
};
|
|
11088
|
+
}
|
|
11089
|
+
if (!serviceManager()) {
|
|
11090
|
+
return {
|
|
11091
|
+
ok: false,
|
|
11092
|
+
reason: "\u672A\u88AB systemd/launchd \u6258\u7BA1\uFF1A\u8BF7\u7528 deploy/service/install.sh \u5B89\u88C5\uFF0C\u6216\u624B\u52A8\u5347\u7EA7"
|
|
11093
|
+
};
|
|
11094
|
+
}
|
|
11095
|
+
if (!hasPublicKey) {
|
|
11096
|
+
return { ok: false, reason: "\u672A\u914D\u7F6E ZQAGENT_UPDATE_PUBKEY\uFF0C\u65E0\u6CD5\u9A8C\u7B7E\uFF0C\u5DF2\u7981\u7528\u81EA\u52A8\u66F4\u65B0" };
|
|
11097
|
+
}
|
|
11098
|
+
return { ok: true };
|
|
11099
|
+
}
|
|
11100
|
+
|
|
11101
|
+
// src/cli/serve-instances.ts
|
|
10897
11102
|
var DEFAULT_SERVE_HOST = "127.0.0.1";
|
|
10898
11103
|
var DEFAULT_SERVE_PORT = 8787;
|
|
11104
|
+
var DEFAULT_SERVICE_NAME2 = "zqagent";
|
|
11105
|
+
var DEFAULT_SERVICE_LABEL2 = "com.zqagent.node";
|
|
10899
11106
|
function serveSubcommandIndex(argv) {
|
|
10900
11107
|
for (let i = 1; i < argv.length; i++) {
|
|
10901
11108
|
if (argv[i].startsWith("-")) continue;
|
|
@@ -10930,18 +11137,43 @@ function parseServeArgs(argv) {
|
|
|
10930
11137
|
return { dataDir, host, port };
|
|
10931
11138
|
}
|
|
10932
11139
|
function buildHotCandidates(explicitDataDir, discovered, fallback) {
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
}
|
|
10936
|
-
const out = [{ dataDir: path20.resolve(DEFAULT_DATA_DIR), ...fallback }];
|
|
10937
|
-
for (const inst of discovered) {
|
|
11140
|
+
const out = [];
|
|
11141
|
+
const push = (inst) => {
|
|
10938
11142
|
if (!out.some((o) => o.dataDir === inst.dataDir)) out.push(inst);
|
|
10939
|
-
}
|
|
11143
|
+
};
|
|
11144
|
+
if (explicitDataDir) push({ dataDir: path21.resolve(explicitDataDir), ...fallback });
|
|
11145
|
+
for (const inst of discovered) if (inst.managed) push(inst);
|
|
11146
|
+
for (const inst of discovered) if (!inst.managed) push(inst);
|
|
11147
|
+
if (!explicitDataDir) push({ dataDir: path21.resolve(DEFAULT_DATA_DIR), ...fallback });
|
|
10940
11148
|
return out;
|
|
10941
11149
|
}
|
|
11150
|
+
function isWindowsAbsolute(p) {
|
|
11151
|
+
return /^[A-Za-z]:[\\/]/.test(p) || /^\\\\/.test(p);
|
|
11152
|
+
}
|
|
11153
|
+
function isAbsolutePath(p) {
|
|
11154
|
+
return path21.isAbsolute(p) || isWindowsAbsolute(p);
|
|
11155
|
+
}
|
|
11156
|
+
function normalizePath(p) {
|
|
11157
|
+
return isWindowsAbsolute(p) ? path21.win32.normalize(p) : path21.normalize(p);
|
|
11158
|
+
}
|
|
11159
|
+
function parseServeCommandLine(line) {
|
|
11160
|
+
if (!/(?:^|\s)["']?serve["']?(?=\s|$)/.test(line)) return null;
|
|
11161
|
+
const m = /--data-dir(?:=|\s+)(?:"([^"]+)"|'([^']+)'|(.+?))(?=\s+--\w|\s*$)/.exec(line);
|
|
11162
|
+
const rawDataDir = (m?.[1] ?? m?.[2] ?? m?.[3] ?? "").trim();
|
|
11163
|
+
if (!rawDataDir || !isAbsolutePath(rawDataDir)) return null;
|
|
11164
|
+
const host = /--host(?:=|\s+)(?:"([^"]+)"|'([^']+)'|(\S+))/.exec(line);
|
|
11165
|
+
const rawHost = (host?.[1] ?? host?.[2] ?? host?.[3] ?? DEFAULT_SERVE_HOST).trim();
|
|
11166
|
+
const portMatch = /--port(?:=|\s+)(\d+)/.exec(line);
|
|
11167
|
+
const port = Number(portMatch?.[1] ?? DEFAULT_SERVE_PORT);
|
|
11168
|
+
return {
|
|
11169
|
+
dataDir: normalizePath(rawDataDir),
|
|
11170
|
+
host: rawHost === "0.0.0.0" || rawHost === "::" || rawHost === "" ? DEFAULT_SERVE_HOST : rawHost,
|
|
11171
|
+
port: Number.isFinite(port) && port > 0 ? port : DEFAULT_SERVE_PORT
|
|
11172
|
+
};
|
|
11173
|
+
}
|
|
10942
11174
|
function processCwd(pid) {
|
|
10943
11175
|
try {
|
|
10944
|
-
return
|
|
11176
|
+
return fs19.readlinkSync(`/proc/${pid}/cwd`);
|
|
10945
11177
|
} catch {
|
|
10946
11178
|
return null;
|
|
10947
11179
|
}
|
|
@@ -10949,7 +11181,7 @@ function processCwd(pid) {
|
|
|
10949
11181
|
function processEnv(pid) {
|
|
10950
11182
|
const out = {};
|
|
10951
11183
|
try {
|
|
10952
|
-
const raw =
|
|
11184
|
+
const raw = fs19.readFileSync(`/proc/${pid}/environ`, "utf-8");
|
|
10953
11185
|
for (const entry of raw.split("\0")) {
|
|
10954
11186
|
const eq = entry.indexOf("=");
|
|
10955
11187
|
if (eq > 0) out[entry.slice(0, eq)] = entry.slice(eq + 1);
|
|
@@ -10960,14 +11192,24 @@ function processEnv(pid) {
|
|
|
10960
11192
|
}
|
|
10961
11193
|
function resolveDataDir(rawDataDir, cwd, env3) {
|
|
10962
11194
|
const pick = rawDataDir ?? env3.DATA_DIR ?? null;
|
|
10963
|
-
if (pick) return
|
|
10964
|
-
return cwd ?
|
|
11195
|
+
if (pick) return path21.isAbsolute(pick) ? path21.normalize(pick) : cwd ? path21.resolve(cwd, pick) : null;
|
|
11196
|
+
return cwd ? path21.resolve(cwd, DEFAULT_DATA_DIR) : null;
|
|
11197
|
+
}
|
|
11198
|
+
function isManagedBySystemd(pid, env3) {
|
|
11199
|
+
if (env3.ZQAGENT_SERVICE_MANAGER?.trim()) return true;
|
|
11200
|
+
try {
|
|
11201
|
+
const cgroup = fs19.readFileSync(`/proc/${pid}/cgroup`, "utf-8");
|
|
11202
|
+
const serviceName = env3.ZQAGENT_SERVICE_NAME?.trim() || "zqagent";
|
|
11203
|
+
return serviceManagerFromCgroup(cgroup, serviceName) !== null;
|
|
11204
|
+
} catch {
|
|
11205
|
+
return false;
|
|
11206
|
+
}
|
|
10965
11207
|
}
|
|
10966
11208
|
function discoverFromProc() {
|
|
10967
11209
|
const out = [];
|
|
10968
11210
|
let pids;
|
|
10969
11211
|
try {
|
|
10970
|
-
pids =
|
|
11212
|
+
pids = fs19.readdirSync("/proc");
|
|
10971
11213
|
} catch {
|
|
10972
11214
|
return out;
|
|
10973
11215
|
}
|
|
@@ -10976,50 +11218,186 @@ function discoverFromProc() {
|
|
|
10976
11218
|
const pid = Number(name);
|
|
10977
11219
|
if (pid === process.pid) continue;
|
|
10978
11220
|
let argv;
|
|
11221
|
+
let env3;
|
|
10979
11222
|
try {
|
|
10980
|
-
argv =
|
|
11223
|
+
argv = fs19.readFileSync(`/proc/${pid}/cmdline`, "utf-8").split("\0").filter(Boolean);
|
|
11224
|
+
env3 = processEnv(pid);
|
|
10981
11225
|
} catch {
|
|
10982
11226
|
continue;
|
|
10983
11227
|
}
|
|
10984
11228
|
const parsed = parseServeArgs(argv);
|
|
10985
11229
|
if (!parsed) continue;
|
|
10986
|
-
const dataDir = resolveDataDir(parsed.dataDir, processCwd(pid),
|
|
11230
|
+
const dataDir = resolveDataDir(parsed.dataDir, processCwd(pid), env3);
|
|
10987
11231
|
if (!dataDir) continue;
|
|
10988
|
-
out.push({
|
|
11232
|
+
out.push({
|
|
11233
|
+
dataDir,
|
|
11234
|
+
host: parsed.host,
|
|
11235
|
+
port: parsed.port,
|
|
11236
|
+
managed: isManagedBySystemd(pid, env3)
|
|
11237
|
+
});
|
|
10989
11238
|
}
|
|
10990
11239
|
return out;
|
|
10991
11240
|
}
|
|
10992
11241
|
function discoverFromPs() {
|
|
10993
11242
|
const out = [];
|
|
10994
|
-
const res = (0,
|
|
11243
|
+
const res = (0, import_node_child_process5.spawnSync)("ps", ["-axo", "command="], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
|
|
10995
11244
|
if (res.status !== 0 || !res.stdout) return out;
|
|
10996
11245
|
for (const line of res.stdout.split("\n")) {
|
|
10997
|
-
|
|
10998
|
-
|
|
10999
|
-
|
|
11000
|
-
|
|
11001
|
-
|
|
11002
|
-
|
|
11003
|
-
|
|
11246
|
+
const inst = parseServeCommandLine(line);
|
|
11247
|
+
if (inst) out.push(inst);
|
|
11248
|
+
}
|
|
11249
|
+
return out;
|
|
11250
|
+
}
|
|
11251
|
+
function discoverFromWindows() {
|
|
11252
|
+
const out = [];
|
|
11253
|
+
const script = `[Console]::OutputEncoding=[Text.Encoding]::UTF8; Get-CimInstance Win32_Process -Filter "Name='zqagent.exe' OR Name='node.exe'" | ForEach-Object { $_.CommandLine }`;
|
|
11254
|
+
const res = (0, import_node_child_process5.spawnSync)(
|
|
11255
|
+
"powershell.exe",
|
|
11256
|
+
["-NoProfile", "-NonInteractive", "-Command", script],
|
|
11257
|
+
{ encoding: "utf-8", timeout: 15e3, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
11258
|
+
);
|
|
11259
|
+
if (res.status !== 0 || !res.stdout) return out;
|
|
11260
|
+
for (const line of res.stdout.replace(/^\uFEFF/, "").split(/\r?\n/)) {
|
|
11261
|
+
const inst = parseServeCommandLine(line);
|
|
11262
|
+
if (inst) out.push(inst);
|
|
11263
|
+
}
|
|
11264
|
+
return out;
|
|
11265
|
+
}
|
|
11266
|
+
function decodeXmlEntities(s) {
|
|
11267
|
+
return s.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&");
|
|
11268
|
+
}
|
|
11269
|
+
function parseLaunchdProgramArguments(xml) {
|
|
11270
|
+
const marker = xml.indexOf("<key>ProgramArguments</key>");
|
|
11271
|
+
if (marker < 0) return [];
|
|
11272
|
+
const open = xml.indexOf("<array>", marker);
|
|
11273
|
+
if (open < 0) return [];
|
|
11274
|
+
const close = xml.indexOf("</array>", open);
|
|
11275
|
+
if (close < 0) return [];
|
|
11276
|
+
return [...xml.slice(open + "<array>".length, close).matchAll(/<string>([^<]*)<\/string>/g)].map(
|
|
11277
|
+
(m) => decodeXmlEntities(m[1])
|
|
11278
|
+
);
|
|
11279
|
+
}
|
|
11280
|
+
function launchdServiceInstances() {
|
|
11281
|
+
if (process.platform !== "darwin") return [];
|
|
11282
|
+
const label = process.env.ZQAGENT_SERVICE_LABEL?.trim() || DEFAULT_SERVICE_LABEL2;
|
|
11283
|
+
const plists = [
|
|
11284
|
+
`/Library/LaunchDaemons/${label}.plist`,
|
|
11285
|
+
path21.join(os5.homedir(), "Library", "LaunchAgents", `${label}.plist`)
|
|
11286
|
+
];
|
|
11287
|
+
const out = [];
|
|
11288
|
+
for (const plist of plists) {
|
|
11289
|
+
let xml;
|
|
11290
|
+
try {
|
|
11291
|
+
xml = fs19.readFileSync(plist, "utf-8");
|
|
11292
|
+
} catch {
|
|
11293
|
+
continue;
|
|
11294
|
+
}
|
|
11295
|
+
const parsed = parseServeArgs(parseLaunchdProgramArguments(xml));
|
|
11296
|
+
if (!parsed?.dataDir || !isAbsolutePath(parsed.dataDir)) continue;
|
|
11004
11297
|
out.push({
|
|
11005
|
-
dataDir:
|
|
11006
|
-
host:
|
|
11007
|
-
port:
|
|
11298
|
+
dataDir: normalizePath(parsed.dataDir),
|
|
11299
|
+
host: parsed.host,
|
|
11300
|
+
port: parsed.port,
|
|
11301
|
+
managed: true
|
|
11008
11302
|
});
|
|
11009
11303
|
}
|
|
11010
11304
|
return out;
|
|
11011
11305
|
}
|
|
11306
|
+
function parseSystemdUnit(text) {
|
|
11307
|
+
let dataDir = null;
|
|
11308
|
+
let host = DEFAULT_SERVE_HOST;
|
|
11309
|
+
let port = DEFAULT_SERVE_PORT;
|
|
11310
|
+
for (const line of text.split("\n")) {
|
|
11311
|
+
const trimmed = line.trim();
|
|
11312
|
+
if (trimmed.startsWith("WorkingDirectory=")) {
|
|
11313
|
+
const v = trimmed.slice("WorkingDirectory=".length).trim();
|
|
11314
|
+
if (v && isAbsolutePath(v)) dataDir = v;
|
|
11315
|
+
} else if (trimmed.startsWith("ExecStart=")) {
|
|
11316
|
+
const tokens = trimmed.slice("ExecStart=".length).trim().split(/\s+/).map((t) => t.replace(/^["']|["']$/g, ""));
|
|
11317
|
+
const parsed = parseServeArgs(tokens);
|
|
11318
|
+
if (!parsed) continue;
|
|
11319
|
+
if (parsed.dataDir && isAbsolutePath(parsed.dataDir)) dataDir = parsed.dataDir;
|
|
11320
|
+
host = parsed.host;
|
|
11321
|
+
port = parsed.port;
|
|
11322
|
+
}
|
|
11323
|
+
}
|
|
11324
|
+
if (!dataDir) return null;
|
|
11325
|
+
return { dataDir: normalizePath(dataDir), host, port, managed: true };
|
|
11326
|
+
}
|
|
11327
|
+
function systemdServiceInstances() {
|
|
11328
|
+
if (process.platform !== "linux") return [];
|
|
11329
|
+
const unit = process.env.ZQAGENT_SERVICE_NAME?.trim() || DEFAULT_SERVICE_NAME2;
|
|
11330
|
+
const configHome = process.env.XDG_CONFIG_HOME?.trim() || path21.join(os5.homedir(), ".config");
|
|
11331
|
+
const units = [
|
|
11332
|
+
`/etc/systemd/system/${unit}.service`,
|
|
11333
|
+
path21.join(configHome, "systemd", "user", `${unit}.service`)
|
|
11334
|
+
];
|
|
11335
|
+
const out = [];
|
|
11336
|
+
for (const file of units) {
|
|
11337
|
+
let text;
|
|
11338
|
+
try {
|
|
11339
|
+
text = fs19.readFileSync(file, "utf-8");
|
|
11340
|
+
} catch {
|
|
11341
|
+
continue;
|
|
11342
|
+
}
|
|
11343
|
+
const inst = parseSystemdUnit(text);
|
|
11344
|
+
if (inst) out.push(inst);
|
|
11345
|
+
}
|
|
11346
|
+
return out;
|
|
11347
|
+
}
|
|
11348
|
+
function windowsServiceInstances() {
|
|
11349
|
+
if (process.platform !== "win32") return [];
|
|
11350
|
+
const appdata = process.env.APPDATA?.trim();
|
|
11351
|
+
if (!appdata) return [];
|
|
11352
|
+
const base = path21.join(appdata, "zqagent");
|
|
11353
|
+
try {
|
|
11354
|
+
const raw = fs19.readFileSync(path21.join(base, "runtime", "service.json"), "utf-8");
|
|
11355
|
+
const v = JSON.parse(raw);
|
|
11356
|
+
const dataDir = v.dataDir && isAbsolutePath(v.dataDir) ? v.dataDir : base;
|
|
11357
|
+
const port = Number(v.port);
|
|
11358
|
+
return [
|
|
11359
|
+
{
|
|
11360
|
+
dataDir: normalizePath(dataDir),
|
|
11361
|
+
host: DEFAULT_SERVE_HOST,
|
|
11362
|
+
port: Number.isFinite(port) && port > 0 ? port : DEFAULT_SERVE_PORT,
|
|
11363
|
+
managed: true
|
|
11364
|
+
}
|
|
11365
|
+
];
|
|
11366
|
+
} catch {
|
|
11367
|
+
return [];
|
|
11368
|
+
}
|
|
11369
|
+
}
|
|
11370
|
+
function mergeServeInstances(discovered, managed) {
|
|
11371
|
+
const out = [];
|
|
11372
|
+
const push = (inst) => {
|
|
11373
|
+
if (!out.some((o) => o.dataDir === inst.dataDir)) out.push(inst);
|
|
11374
|
+
};
|
|
11375
|
+
for (const inst of discovered) {
|
|
11376
|
+
const hit = managed.find((m) => m.dataDir === inst.dataDir);
|
|
11377
|
+
push(hit ? { ...inst, managed: true } : inst);
|
|
11378
|
+
}
|
|
11379
|
+
for (const inst of managed) push(inst);
|
|
11380
|
+
return out;
|
|
11381
|
+
}
|
|
11012
11382
|
function discoverRunningServeInstances() {
|
|
11013
|
-
const found = process.platform === "linux" ? discoverFromProc() : discoverFromPs();
|
|
11014
|
-
const
|
|
11015
|
-
return found
|
|
11016
|
-
if (seen.has(inst.dataDir)) return false;
|
|
11017
|
-
seen.add(inst.dataDir);
|
|
11018
|
-
return true;
|
|
11019
|
-
});
|
|
11383
|
+
const found = process.platform === "linux" ? discoverFromProc() : process.platform === "win32" ? discoverFromWindows() : discoverFromPs();
|
|
11384
|
+
const declared = process.platform === "linux" ? systemdServiceInstances() : process.platform === "win32" ? windowsServiceInstances() : launchdServiceInstances();
|
|
11385
|
+
return mergeServeInstances(found, declared);
|
|
11020
11386
|
}
|
|
11021
11387
|
|
|
11022
11388
|
// src/cli/link.ts
|
|
11389
|
+
function expandHome(p) {
|
|
11390
|
+
const home = process.env.HOME || process.env.USERPROFILE;
|
|
11391
|
+
if (!home) return p;
|
|
11392
|
+
if (p === "~") return home;
|
|
11393
|
+
if (p.startsWith("~/") || p.startsWith("~\\")) return path22.join(home, p.slice(2));
|
|
11394
|
+
return p;
|
|
11395
|
+
}
|
|
11396
|
+
function installDataDirHint() {
|
|
11397
|
+
if (process.platform === "darwin") return "$HOME/Library/Application Support/zqagent";
|
|
11398
|
+
if (process.platform === "win32") return "%APPDATA%\\zqagent";
|
|
11399
|
+
return "/var/lib/zqagent\uFF08\u9700 root\uFF1B\u666E\u901A\u7528\u6237\u7528 ~/.zqagent_data\uFF09";
|
|
11400
|
+
}
|
|
11023
11401
|
function parseLinkArgs(argv) {
|
|
11024
11402
|
const out = {};
|
|
11025
11403
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -11092,20 +11470,47 @@ async function enrollViaServer(host, port, adminKey, opts) {
|
|
|
11092
11470
|
}
|
|
11093
11471
|
return payload?.data;
|
|
11094
11472
|
}
|
|
11473
|
+
function hotWarnings(inst, running) {
|
|
11474
|
+
const warnings = [];
|
|
11475
|
+
const managed = running.filter((r) => r.managed && r.dataDir !== inst.dataDir);
|
|
11476
|
+
if (!inst.managed && managed.length > 0) {
|
|
11477
|
+
warnings.push(
|
|
11478
|
+
`\u51ED\u636E\u5199\u5165\u4E86\u975E\u6258\u7BA1\u5B9E\u4F8B ${inst.dataDir}\uFF0C\u4F46\u672C\u673A\u6258\u7BA1\u670D\u52A1\u4F7F\u7528\u7684\u662F ${managed.map((m) => m.dataDir).join("\u3001")}\u3002`
|
|
11479
|
+
);
|
|
11480
|
+
warnings.push(
|
|
11481
|
+
"\u6258\u7BA1\u670D\u52A1\u8BFB\u4E0D\u5230\u8FD9\u4EFD\u51ED\u636E\uFF08\u91CD\u542F\u540E\u4E5F\u4E0D\u4F1A\u81EA\u52A8\u4E0A\u7EBF\uFF09\uFF0C\u8BF7\u7528 --data-dir \u6307\u5411\u5B83\u7684\u6570\u636E\u76EE\u5F55\u91CD\u65B0\u63A5\u5165\u3002"
|
|
11482
|
+
);
|
|
11483
|
+
}
|
|
11484
|
+
const others = [...new Set(running.map((r) => r.dataDir).filter((d) => d !== inst.dataDir))];
|
|
11485
|
+
if (others.length > 0) {
|
|
11486
|
+
warnings.push(`\u672C\u673A\u8FD8\u6709\u5176\u5B83\u8FD0\u884C\u4E2D\u7684\u8282\u70B9\u5B9E\u4F8B\uFF08\u672A\u5199\u5165\u51ED\u636E\uFF09\uFF1A${others.join("\u3001")}\u3002`);
|
|
11487
|
+
}
|
|
11488
|
+
return warnings;
|
|
11489
|
+
}
|
|
11095
11490
|
async function linkNode(opts) {
|
|
11096
|
-
const
|
|
11491
|
+
const rawDataDir = opts.dataDir?.trim() || process.env.DATA_DIR?.trim() || void 0;
|
|
11492
|
+
const explicitDataDir = rawDataDir ? expandHome(rawDataDir) : void 0;
|
|
11097
11493
|
const host = opts.host?.trim() || process.env.HOST?.trim() || DEFAULT_SERVE_HOST;
|
|
11098
11494
|
const port = opts.port ?? Number(process.env.PORT ?? DEFAULT_SERVE_PORT);
|
|
11099
|
-
const
|
|
11495
|
+
const running = discoverRunningServeInstances();
|
|
11496
|
+
const candidates = buildHotCandidates(explicitDataDir, running, { host, port });
|
|
11100
11497
|
for (const inst of candidates) {
|
|
11101
11498
|
const store2 = new Store(inst.dataDir);
|
|
11102
11499
|
const adminKey = process.env.ADMIN_API_KEY ?? store2.loadAdminKey();
|
|
11103
11500
|
if (!adminKey) continue;
|
|
11104
11501
|
if (!await probeServer(inst.host, inst.port, adminKey)) continue;
|
|
11105
11502
|
const status = await enrollViaServer(inst.host, inst.port, adminKey, opts);
|
|
11106
|
-
return {
|
|
11503
|
+
return {
|
|
11504
|
+
mode: "hot",
|
|
11505
|
+
...status,
|
|
11506
|
+
dataDir: inst.dataDir,
|
|
11507
|
+
managed: inst.managed,
|
|
11508
|
+
warnings: hotWarnings(inst, running)
|
|
11509
|
+
};
|
|
11107
11510
|
}
|
|
11108
|
-
const
|
|
11511
|
+
const managedDir = running.find((r) => r.managed)?.dataDir;
|
|
11512
|
+
const dataDir = path22.resolve(explicitDataDir ?? managedDir ?? DEFAULT_DATA_DIR);
|
|
11513
|
+
const targetedService = !explicitDataDir && Boolean(managedDir) && dataDir === managedDir;
|
|
11109
11514
|
const store = new Store(dataDir);
|
|
11110
11515
|
const nodeId = ensureNodeId(store);
|
|
11111
11516
|
const cred = await hubEnrollByCode(opts.hubUrl, {
|
|
@@ -11113,25 +11518,45 @@ async function linkNode(opts) {
|
|
|
11113
11518
|
nodeId,
|
|
11114
11519
|
label: opts.label
|
|
11115
11520
|
});
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11521
|
+
try {
|
|
11522
|
+
store.saveFleetCredential({
|
|
11523
|
+
...cred,
|
|
11524
|
+
label: opts.label ?? cred.label,
|
|
11525
|
+
enrolledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11526
|
+
});
|
|
11527
|
+
} catch (e) {
|
|
11528
|
+
const err = e;
|
|
11529
|
+
if (err.code === "EACCES" || err.code === "EPERM") {
|
|
11530
|
+
throw new Error(
|
|
11531
|
+
`\u65E0\u6CD5\u5199\u5165\u6570\u636E\u76EE\u5F55 ${dataDir}\uFF08${err.code}: ${err.message}\uFF09
|
|
11532
|
+
\u8BE5\u76EE\u5F55\u5F53\u524D\u7528\u6237\u6CA1\u6709\u5199\u6743\u9650\u3002\u4E24\u79CD\u6539\u6CD5\uFF1A
|
|
11533
|
+
1) \u53BB\u6389 --data-dir\uFF0C\u8BA9 link \u81EA\u52A8\u53D1\u73B0\u672C\u673A\u8FD0\u884C\u7684\u8282\u70B9\uFF08\u63A8\u8350\uFF09\uFF1B
|
|
11534
|
+
2) \u7528\u5F53\u524D\u7528\u6237\u53EF\u5199\u7684\u76EE\u5F55\uFF0C\u672C\u5E73\u53F0\u5B89\u88C5\u811A\u672C\u9ED8\u8BA4\uFF1A${installDataDirHint()}
|
|
11535
|
+
\uFF08\u63A5\u5165\u7801\u4E00\u6B21\u6027\uFF0C\u9700\u8981\u91CD\u65B0\u751F\u6210\uFF09`
|
|
11536
|
+
);
|
|
11537
|
+
}
|
|
11538
|
+
throw e;
|
|
11539
|
+
}
|
|
11540
|
+
const otherRunningDirs = [
|
|
11541
|
+
...new Set(running.map((r) => r.dataDir).filter((d) => d !== dataDir))
|
|
11542
|
+
];
|
|
11121
11543
|
return {
|
|
11122
11544
|
mode: "saved",
|
|
11123
11545
|
nodeId,
|
|
11124
11546
|
gatewayUrl: cred.gatewayUrl,
|
|
11125
11547
|
label: opts.label,
|
|
11126
11548
|
dataDir,
|
|
11127
|
-
explicitDataDir: Boolean(explicitDataDir)
|
|
11549
|
+
explicitDataDir: Boolean(explicitDataDir),
|
|
11550
|
+
runningServiceDirs: otherRunningDirs,
|
|
11551
|
+
targetedService
|
|
11128
11552
|
};
|
|
11129
11553
|
}
|
|
11130
11554
|
function printLinkHelp() {
|
|
11131
|
-
cliLog("\u7528\u6CD5: zqagent link --hub <url> --code <\u6CE8\u518C\u7801> [--label \u540D\u79F0]
|
|
11555
|
+
cliLog("\u7528\u6CD5: zqagent link --hub <url> --code <\u6CE8\u518C\u7801> [--label \u540D\u79F0]");
|
|
11132
11556
|
cliLog(" \u5728 Hub \u7528\u6237\u4E2D\u5FC3\u751F\u6210\u4E00\u6B21\u6027\u6CE8\u518C\u7801\u540E\uFF0C\u4E8E\u8282\u70B9\u673A\u5668\u6267\u884C\u672C\u547D\u4EE4\u5373\u53EF\u63A5\u5165\u3002");
|
|
11133
|
-
cliLog(" \u5DF2\
|
|
11134
|
-
cliLog(" \
|
|
11557
|
+
cliLog(" \u672C\u673A\u5DF2\u88C5\u8282\u70B9\u670D\u52A1\uFF08install.sh / \u684C\u9762\u7AEF\uFF09\u65F6\u4F1A\u81EA\u52A8\u53D1\u73B0\u5B83\u7684\u6570\u636E\u76EE\u5F55\u5E76\u70ED\u63A5\u5165\uFF0C");
|
|
11558
|
+
cliLog(" \u4E0D\u9700\u8981\u624B\u52A8\u6307\u5B9A --data-dir\uFF1B\u670D\u52A1\u6CA1\u5728\u8FD0\u884C\u65F6\u4F1A\u5199\u5165\u5B83\u7684\u76EE\u5F55\uFF0C\u4E0B\u6B21\u542F\u52A8\u5373\u63A5\u5165\u3002");
|
|
11559
|
+
cliLog(" \u4EC5\u5F53\u672C\u673A\u5B8C\u5168\u6CA1\u6709\u670D\u52A1\u65F6\u624D\u9700\u8981 --data-dir \u6307\u5B9A\u76EE\u5F55\uFF08\u4E0B\u6B21\u542F\u52A8 serve \u65F6\u751F\u6548\uFF09\u3002");
|
|
11135
11560
|
}
|
|
11136
11561
|
async function runLinkCommand(argv) {
|
|
11137
11562
|
const args = parseLinkArgs(argv);
|
|
@@ -11159,20 +11584,36 @@ async function runLinkCommand(argv) {
|
|
|
11159
11584
|
cliLog("\u2705 \u5DF2\u63A5\u5165 Hub\uFF08\u70ED\u63A5\u5165\uFF0C\u514D\u91CD\u542F\uFF09");
|
|
11160
11585
|
cliLog(` \u8282\u70B9: ${r.nodeId}${r.label ? ` (${r.label})` : ""}`);
|
|
11161
11586
|
cliLog(` \u7F51\u5173: ${r.gatewayUrl ?? "\uFF08\u672A\u4E0B\u53D1\uFF09"} \u5728\u7EBF: ${r.online ? "\u662F" : "\u8FDE\u63A5\u4E2D\u2026"}`);
|
|
11162
|
-
cliLog(` \u6570\u636E\u76EE\u5F55: ${r.dataDir}`);
|
|
11587
|
+
cliLog(` \u6570\u636E\u76EE\u5F55: ${r.dataDir}${r.managed ? "\uFF08\u6258\u7BA1\u670D\u52A1\uFF0C\u5F00\u673A\u81EA\u542F\uFF09" : ""}`);
|
|
11588
|
+
if (r.warnings.length > 0) {
|
|
11589
|
+
cliLog("");
|
|
11590
|
+
for (const w of r.warnings) cliLog(`\u26A0\uFE0F ${w}`);
|
|
11591
|
+
}
|
|
11163
11592
|
} else {
|
|
11164
11593
|
cliLog("\u2705 \u63A5\u5165\u51ED\u636E\u5DF2\u4FDD\u5B58\uFF08\u672C\u673A\u6682\u65E0\u8FD0\u884C\u4E2D\u7684 server\uFF09");
|
|
11165
11594
|
cliLog(` \u8282\u70B9: ${r.nodeId}`);
|
|
11166
11595
|
cliLog(` \u7F51\u5173: ${r.gatewayUrl ?? "\uFF08\u672A\u4E0B\u53D1\uFF09"}`);
|
|
11167
11596
|
cliLog(` \u6570\u636E\u76EE\u5F55: ${r.dataDir}`);
|
|
11168
11597
|
cliLog(" \u4E0B\u6B21\u542F\u52A8 server \u5373\u81EA\u52A8\u63A5\u5165\uFF1B\u6216\u8FD0\u884C zqagent serve \u5E38\u9A7B\u4E3A\u8282\u70B9\u3002");
|
|
11169
|
-
if (
|
|
11598
|
+
if (r.targetedService) {
|
|
11170
11599
|
cliLog("");
|
|
11171
|
-
cliLog("\
|
|
11172
|
-
cliLog("
|
|
11173
|
-
cliLog("
|
|
11174
|
-
|
|
11175
|
-
cliLog("
|
|
11600
|
+
cliLog("\u2705 \u51ED\u636E\u5DF2\u5199\u5165\u672C\u673A\u6258\u7BA1\u670D\u52A1\u7684\u6570\u636E\u76EE\u5F55\uFF0C\u670D\u52A1\u542F\u52A8\u65F6\u81EA\u52A8\u63A5\u5165\uFF0C\u65E0\u9700 --data-dir\u3002");
|
|
11601
|
+
cliLog(" \u7ACB\u5373\u751F\u6548\uFF1A\u91CD\u542F\u8BE5\u670D\u52A1\uFF08Linux: systemctl restart zqagent\uFF1B");
|
|
11602
|
+
cliLog(" macOS: launchctl kickstart -k gui/$(id -u)/com.zqagent.node\uFF09\u3002");
|
|
11603
|
+
} else if (r.runningServiceDirs.length > 0) {
|
|
11604
|
+
cliLog("");
|
|
11605
|
+
cliLog("\u26A0\uFE0F \u672C\u673A\u6709\u6B63\u5728\u8FD0\u884C\u7684\u8282\u70B9\uFF0C\u4F46\u6570\u636E\u76EE\u5F55\u4E0E\u672C\u6B21\u5199\u5165\u7684\u4E0D\u4E00\u81F4\uFF1A");
|
|
11606
|
+
cliLog(` \u672C\u6B21\u5199\u5165: ${r.dataDir}`);
|
|
11607
|
+
for (const d of r.runningServiceDirs) cliLog(` \u670D\u52A1\u4F7F\u7528: ${d}`);
|
|
11608
|
+
cliLog(" \u6B63\u5728\u8FD0\u884C\u7684\u670D\u52A1\u8BFB\u4E0D\u5230\u8FD9\u4EFD\u51ED\u636E\uFF0CHub \u4F1A\u4E00\u76F4\u663E\u793A\u672A\u63A5\u5165\u3002");
|
|
11609
|
+
cliLog(" \u8BF7\u786E\u8BA4\u670D\u52A1\u7684\u6570\u636E\u76EE\u5F55\u540E\u91CD\u65B0\u6267\u884C\uFF08\u63A5\u5165\u7801\u4E00\u6B21\u6027\uFF0C\u9700\u8981\u91CD\u65B0\u751F\u6210\uFF09\uFF1A");
|
|
11610
|
+
cliLog(` zqagent link --hub <Hub\u5730\u5740> --code <\u65B0\u63A5\u5165\u7801> --data-dir "${r.runningServiceDirs[0]}"`);
|
|
11611
|
+
} else if (!r.explicitDataDir) {
|
|
11612
|
+
cliLog("");
|
|
11613
|
+
cliLog("\u26A0\uFE0F \u672A\u53D1\u73B0\u672C\u673A\u8282\u70B9\u670D\u52A1\uFF0C\u51ED\u636E\u5199\u5165\u4E86\u5F53\u524D\u76EE\u5F55\u4E0B\u7684 .zqagent_data\u3002");
|
|
11614
|
+
cliLog(" \u5982\u679C\u8FD9\u53F0\u673A\u5668\u6253\u7B97\u957F\u671F\u8FD0\u884C\u8282\u70B9\uFF0C\u8BF7\u5148\u5B89\u88C5\u5F00\u673A\u670D\u52A1\uFF0C\u4E4B\u540E link \u4F1A\u81EA\u52A8\u5199\u5165\u5B83\u7684\u76EE\u5F55\uFF1A");
|
|
11615
|
+
cliLog(" curl -fsSL https://agent.cd-zq.com/install.sh | sh");
|
|
11616
|
+
cliLog(` \uFF08\u670D\u52A1\u9ED8\u8BA4\u6570\u636E\u76EE\u5F55\uFF1A${installDataDirHint()}\uFF09`);
|
|
11176
11617
|
}
|
|
11177
11618
|
}
|
|
11178
11619
|
return true;
|
|
@@ -11192,7 +11633,7 @@ var path37 = __toESM(require("path"), 1);
|
|
|
11192
11633
|
|
|
11193
11634
|
// src/server/session.ts
|
|
11194
11635
|
init_cjs_shims();
|
|
11195
|
-
var
|
|
11636
|
+
var path25 = __toESM(require("path"), 1);
|
|
11196
11637
|
var import_async_hooks = require("async_hooks");
|
|
11197
11638
|
|
|
11198
11639
|
// src/server/mcpConfig.ts
|
|
@@ -11373,8 +11814,8 @@ function resolveSessionProvider(store, tenant, providerId) {
|
|
|
11373
11814
|
|
|
11374
11815
|
// src/server/usage.ts
|
|
11375
11816
|
init_cjs_shims();
|
|
11376
|
-
var
|
|
11377
|
-
var
|
|
11817
|
+
var fs21 = __toESM(require("fs"), 1);
|
|
11818
|
+
var path24 = __toESM(require("path"), 1);
|
|
11378
11819
|
var LEDGER_RETENTION_MONTHS = 12;
|
|
11379
11820
|
var USAGE_SCHEMA = 1;
|
|
11380
11821
|
var DEFAULT_PRICING = {
|
|
@@ -11455,15 +11896,15 @@ function retainedMonths(now = /* @__PURE__ */ new Date()) {
|
|
|
11455
11896
|
return out;
|
|
11456
11897
|
}
|
|
11457
11898
|
function atomicWrite(file, content) {
|
|
11458
|
-
|
|
11899
|
+
fs21.mkdirSync(path24.dirname(file), { recursive: true });
|
|
11459
11900
|
const tmp = `${file}.tmp`;
|
|
11460
|
-
|
|
11461
|
-
|
|
11901
|
+
fs21.writeFileSync(tmp, content, "utf-8");
|
|
11902
|
+
fs21.renameSync(tmp, file);
|
|
11462
11903
|
}
|
|
11463
11904
|
var UsageLedger = class {
|
|
11464
11905
|
constructor(root) {
|
|
11465
11906
|
this.root = root;
|
|
11466
|
-
this.dir =
|
|
11907
|
+
this.dir = path24.join(root, "usage");
|
|
11467
11908
|
}
|
|
11468
11909
|
root;
|
|
11469
11910
|
dir;
|
|
@@ -11476,18 +11917,18 @@ var UsageLedger = class {
|
|
|
11476
11917
|
return this.dir;
|
|
11477
11918
|
}
|
|
11478
11919
|
ledgerFile(month) {
|
|
11479
|
-
return
|
|
11920
|
+
return path24.join(this.ledgerDir, `ledger-${month}.jsonl`);
|
|
11480
11921
|
}
|
|
11481
11922
|
get rollupFile() {
|
|
11482
|
-
return
|
|
11923
|
+
return path24.join(this.ledgerDir, "rollup.json");
|
|
11483
11924
|
}
|
|
11484
11925
|
get pricingFile() {
|
|
11485
|
-
return
|
|
11926
|
+
return path24.join(this.ledgerDir, "pricing.json");
|
|
11486
11927
|
}
|
|
11487
11928
|
// ===================== 初始化 =====================
|
|
11488
11929
|
init(now = /* @__PURE__ */ new Date()) {
|
|
11489
11930
|
if (this.inited) return;
|
|
11490
|
-
|
|
11931
|
+
fs21.mkdirSync(this.ledgerDir, { recursive: true });
|
|
11491
11932
|
this.pricing = this.loadPricing();
|
|
11492
11933
|
this.rollup = this.loadRollup(now);
|
|
11493
11934
|
this.pruneLedgers(now);
|
|
@@ -11495,7 +11936,7 @@ var UsageLedger = class {
|
|
|
11495
11936
|
}
|
|
11496
11937
|
loadPricing() {
|
|
11497
11938
|
try {
|
|
11498
|
-
const raw =
|
|
11939
|
+
const raw = fs21.readFileSync(this.pricingFile, "utf-8");
|
|
11499
11940
|
const parsed = JSON.parse(raw);
|
|
11500
11941
|
const vendors = {};
|
|
11501
11942
|
for (const v of /* @__PURE__ */ new Set([
|
|
@@ -11524,7 +11965,7 @@ var UsageLedger = class {
|
|
|
11524
11965
|
}
|
|
11525
11966
|
loadRollup(now) {
|
|
11526
11967
|
try {
|
|
11527
|
-
const raw =
|
|
11968
|
+
const raw = fs21.readFileSync(this.rollupFile, "utf-8");
|
|
11528
11969
|
const parsed = JSON.parse(raw);
|
|
11529
11970
|
return {
|
|
11530
11971
|
schema: USAGE_SCHEMA,
|
|
@@ -11551,10 +11992,10 @@ var UsageLedger = class {
|
|
|
11551
11992
|
const keep = retainedMonths(now);
|
|
11552
11993
|
let changed = false;
|
|
11553
11994
|
try {
|
|
11554
|
-
for (const f of
|
|
11995
|
+
for (const f of fs21.readdirSync(this.ledgerDir)) {
|
|
11555
11996
|
const m = /^ledger-(\d{4}-\d{2})\.jsonl$/.exec(f);
|
|
11556
11997
|
if (m && !keep.has(m[1])) {
|
|
11557
|
-
|
|
11998
|
+
fs21.unlinkSync(path24.join(this.ledgerDir, f));
|
|
11558
11999
|
}
|
|
11559
12000
|
}
|
|
11560
12001
|
} catch {
|
|
@@ -11631,7 +12072,7 @@ var UsageLedger = class {
|
|
|
11631
12072
|
};
|
|
11632
12073
|
const line = JSON.stringify(rec) + "\n";
|
|
11633
12074
|
try {
|
|
11634
|
-
|
|
12075
|
+
fs21.appendFileSync(this.ledgerFile(monthOf(rec.ts)), line);
|
|
11635
12076
|
} catch (e) {
|
|
11636
12077
|
console.error(`[usage] \u5199\u8D26\u672C\u5931\u8D25: ${String(e)}`);
|
|
11637
12078
|
}
|
|
@@ -11803,10 +12244,10 @@ var UsageLedger = class {
|
|
|
11803
12244
|
const rows = [];
|
|
11804
12245
|
for (const month of months) {
|
|
11805
12246
|
const file = this.ledgerFile(month);
|
|
11806
|
-
if (!
|
|
12247
|
+
if (!fs21.existsSync(file)) continue;
|
|
11807
12248
|
let content = "";
|
|
11808
12249
|
try {
|
|
11809
|
-
content =
|
|
12250
|
+
content = fs21.readFileSync(file, "utf-8");
|
|
11810
12251
|
} catch {
|
|
11811
12252
|
continue;
|
|
11812
12253
|
}
|
|
@@ -11915,10 +12356,10 @@ var UsageLedger = class {
|
|
|
11915
12356
|
const seen = /* @__PURE__ */ new Set();
|
|
11916
12357
|
for (const month of this.monthsInRange("", "")) {
|
|
11917
12358
|
const file = this.ledgerFile(month);
|
|
11918
|
-
if (!
|
|
12359
|
+
if (!fs21.existsSync(file)) continue;
|
|
11919
12360
|
let content = "";
|
|
11920
12361
|
try {
|
|
11921
|
-
content =
|
|
12362
|
+
content = fs21.readFileSync(file, "utf-8");
|
|
11922
12363
|
} catch {
|
|
11923
12364
|
continue;
|
|
11924
12365
|
}
|
|
@@ -12023,11 +12464,11 @@ function isAffirmative(answer) {
|
|
|
12023
12464
|
return /^(yes|approve|同意|批准|允许|确定|可以|好的|确认)/.test(a);
|
|
12024
12465
|
}
|
|
12025
12466
|
function defer() {
|
|
12026
|
-
let
|
|
12467
|
+
let resolve24;
|
|
12027
12468
|
const promise = new Promise((r) => {
|
|
12028
|
-
|
|
12469
|
+
resolve24 = r;
|
|
12029
12470
|
});
|
|
12030
|
-
return { promise, resolve:
|
|
12471
|
+
return { promise, resolve: resolve24 };
|
|
12031
12472
|
}
|
|
12032
12473
|
var SessionManager = class {
|
|
12033
12474
|
constructor(store, approvalTimeoutMs = APPROVAL_TIMEOUT_MS, opts = {}) {
|
|
@@ -12599,11 +13040,11 @@ data: ${JSON.stringify({ sessionId, seq: entry.seq, ts: entry.ts, data: entry.da
|
|
|
12599
13040
|
status: "pending",
|
|
12600
13041
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12601
13042
|
};
|
|
12602
|
-
const { promise, resolve:
|
|
13043
|
+
const { promise, resolve: resolve24 } = defer();
|
|
12603
13044
|
const timer = setTimeout(() => {
|
|
12604
13045
|
this._recycleApproval(rt, id);
|
|
12605
13046
|
}, this.approvalTimeoutMs);
|
|
12606
|
-
rt.pendingApprovals.set(id, { promise, resolve:
|
|
13047
|
+
rt.pendingApprovals.set(id, { promise, resolve: resolve24, record, timer });
|
|
12607
13048
|
rt.approvals.set(id, record);
|
|
12608
13049
|
this._setStatus(rt, "waiting_approval");
|
|
12609
13050
|
this._persist(rt);
|
|
@@ -12681,11 +13122,11 @@ data: ${JSON.stringify({ sessionId, seq: entry.seq, ts: entry.ts, data: entry.da
|
|
|
12681
13122
|
status: "pending",
|
|
12682
13123
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12683
13124
|
};
|
|
12684
|
-
const { promise, resolve:
|
|
13125
|
+
const { promise, resolve: resolve24 } = defer();
|
|
12685
13126
|
const timer = setTimeout(() => {
|
|
12686
13127
|
this._recycleQuestion(rt, qid);
|
|
12687
13128
|
}, this.approvalTimeoutMs);
|
|
12688
|
-
rt.pendingQuestions.set(qid, { promise, resolve:
|
|
13129
|
+
rt.pendingQuestions.set(qid, { promise, resolve: resolve24, record, timer });
|
|
12689
13130
|
rt.questions.set(qid, record);
|
|
12690
13131
|
this._setStatus(rt, "waiting_question");
|
|
12691
13132
|
this._persist(rt);
|
|
@@ -12994,7 +13435,7 @@ data: ${JSON.stringify(entry.data)}
|
|
|
12994
13435
|
if (rt.mcpReady) {
|
|
12995
13436
|
await Promise.race([
|
|
12996
13437
|
rt.mcpReady,
|
|
12997
|
-
new Promise((
|
|
13438
|
+
new Promise((resolve24) => setTimeout(resolve24, 15e3))
|
|
12998
13439
|
]).catch(() => void 0);
|
|
12999
13440
|
}
|
|
13000
13441
|
for await (const event of gen) {
|
|
@@ -13229,7 +13670,7 @@ data: ${JSON.stringify(entry.data)}
|
|
|
13229
13670
|
softThresholdPct: parseRatio(process.env.COMPACTION_SOFT_THRESHOLD_PCT),
|
|
13230
13671
|
capTokens: parseOptionalPositiveNumber(process.env.COMPACTION_CAP_TOKENS) ?? null,
|
|
13231
13672
|
// 超预算工具结果按租户/工作区隔离落盘(多租户共用一个状态目录会混内容)
|
|
13232
|
-
toolResultDir:
|
|
13673
|
+
toolResultDir: path25.join(workspace, ".agent", "tool-results")
|
|
13233
13674
|
});
|
|
13234
13675
|
engine.setApprover(this._makeApprover(rt));
|
|
13235
13676
|
const mcpConfigs = loadServerMcpConfigs(tenant);
|
|
@@ -13410,11 +13851,11 @@ var ApiError = class extends Error {
|
|
|
13410
13851
|
// src/server/routes.ts
|
|
13411
13852
|
init_cjs_shims();
|
|
13412
13853
|
var import_http = require("http");
|
|
13413
|
-
var
|
|
13854
|
+
var path30 = __toESM(require("path"), 1);
|
|
13414
13855
|
|
|
13415
13856
|
// src/server/projects.ts
|
|
13416
13857
|
init_cjs_shims();
|
|
13417
|
-
var
|
|
13858
|
+
var path26 = __toESM(require("path"), 1);
|
|
13418
13859
|
var DEFAULT_MODEL = () => process.env.OPENAI_MODEL || process.env.MODEL || "gpt-4o";
|
|
13419
13860
|
function toProjectSummary(store, tenant) {
|
|
13420
13861
|
return {
|
|
@@ -13547,9 +13988,9 @@ function createProject(store, input) {
|
|
|
13547
13988
|
if (store.loadTenant(id)) {
|
|
13548
13989
|
throw new ApiError(409, "project_exists", `\u9879\u76EE ${id} \u5DF2\u5B58\u5728`);
|
|
13549
13990
|
}
|
|
13550
|
-
const workspaceRoot = typeof raw.workspaceRoot === "string" && raw.workspaceRoot.trim() ?
|
|
13991
|
+
const workspaceRoot = typeof raw.workspaceRoot === "string" && raw.workspaceRoot.trim() ? path26.resolve(raw.workspaceRoot.trim()) : void 0;
|
|
13551
13992
|
const explicitName = typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : "";
|
|
13552
|
-
const defaultName = workspaceRoot ?
|
|
13993
|
+
const defaultName = workspaceRoot ? path26.basename(workspaceRoot) : id;
|
|
13553
13994
|
const tenant = {
|
|
13554
13995
|
id,
|
|
13555
13996
|
name: explicitName || defaultName,
|
|
@@ -13579,7 +14020,7 @@ function buildNodeInfo(store, opts) {
|
|
|
13579
14020
|
nodeId: opts.nodeId ?? ensureNodeId2(store),
|
|
13580
14021
|
platform: process.platform,
|
|
13581
14022
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
13582
|
-
version: "0.2.
|
|
14023
|
+
version: "0.2.11",
|
|
13583
14024
|
admin: opts.admin,
|
|
13584
14025
|
projects: opts.projects
|
|
13585
14026
|
};
|
|
@@ -13758,34 +14199,34 @@ async function handleHubProxy(req2, res) {
|
|
|
13758
14199
|
|
|
13759
14200
|
// src/server/fsBrowser.ts
|
|
13760
14201
|
init_cjs_shims();
|
|
13761
|
-
var
|
|
13762
|
-
var
|
|
13763
|
-
var
|
|
14202
|
+
var fs22 = __toESM(require("fs"), 1);
|
|
14203
|
+
var os6 = __toESM(require("os"), 1);
|
|
14204
|
+
var path27 = __toESM(require("path"), 1);
|
|
13764
14205
|
var MAX_ENTRIES = 2e3;
|
|
13765
14206
|
var DEFAULT_SEARCH_LIMIT = 200;
|
|
13766
14207
|
var MAX_SEARCH_LIMIT = 1e3;
|
|
13767
14208
|
function listDirs(input) {
|
|
13768
|
-
const base = (input ?? "").trim() ||
|
|
13769
|
-
const target =
|
|
14209
|
+
const base = (input ?? "").trim() || os6.homedir();
|
|
14210
|
+
const target = path27.resolve(base);
|
|
13770
14211
|
let st;
|
|
13771
14212
|
try {
|
|
13772
|
-
st =
|
|
14213
|
+
st = fs22.statSync(target);
|
|
13773
14214
|
} catch {
|
|
13774
14215
|
throw new Error(`\u8DEF\u5F84\u4E0D\u5B58\u5728: ${target}`);
|
|
13775
14216
|
}
|
|
13776
14217
|
if (!st.isDirectory()) throw new Error(`\u4E0D\u662F\u76EE\u5F55: ${target}`);
|
|
13777
14218
|
let dirents;
|
|
13778
14219
|
try {
|
|
13779
|
-
dirents =
|
|
14220
|
+
dirents = fs22.readdirSync(target, { withFileTypes: true });
|
|
13780
14221
|
} catch {
|
|
13781
14222
|
throw new Error(`\u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\uFF08\u6743\u9650\u4E0D\u8DB3\uFF1F\uFF09: ${target}`);
|
|
13782
14223
|
}
|
|
13783
14224
|
const entries = dirents.map((d) => {
|
|
13784
|
-
const full =
|
|
14225
|
+
const full = path27.join(target, d.name);
|
|
13785
14226
|
let isDir = d.isDirectory();
|
|
13786
14227
|
if (d.isSymbolicLink()) {
|
|
13787
14228
|
try {
|
|
13788
|
-
isDir =
|
|
14229
|
+
isDir = fs22.statSync(full).isDirectory();
|
|
13789
14230
|
} catch {
|
|
13790
14231
|
}
|
|
13791
14232
|
}
|
|
@@ -13794,7 +14235,7 @@ function listDirs(input) {
|
|
|
13794
14235
|
entries.sort(
|
|
13795
14236
|
(a, b) => a.type === b.type ? a.name.localeCompare(b.name) : a.type === "dir" ? -1 : 1
|
|
13796
14237
|
);
|
|
13797
|
-
const parentDir =
|
|
14238
|
+
const parentDir = path27.dirname(target);
|
|
13798
14239
|
return {
|
|
13799
14240
|
path: target,
|
|
13800
14241
|
parent: parentDir !== target ? parentDir : null,
|
|
@@ -13825,7 +14266,7 @@ var NAME_CACHE_MAX_DIRS = 4;
|
|
|
13825
14266
|
var NAME_CACHE_MAX_ENTRIES = 5e4;
|
|
13826
14267
|
var nameCache = /* @__PURE__ */ new Map();
|
|
13827
14268
|
function invalidateDirNames(target) {
|
|
13828
|
-
nameCache.delete(
|
|
14269
|
+
nameCache.delete(path27.resolve(target));
|
|
13829
14270
|
}
|
|
13830
14271
|
async function loadDirNames(target) {
|
|
13831
14272
|
const now = Date.now();
|
|
@@ -13837,7 +14278,7 @@ async function loadDirNames(target) {
|
|
|
13837
14278
|
}
|
|
13838
14279
|
let dirents;
|
|
13839
14280
|
try {
|
|
13840
|
-
dirents = await
|
|
14281
|
+
dirents = await fs22.promises.readdir(target, { withFileTypes: true });
|
|
13841
14282
|
} catch {
|
|
13842
14283
|
throw new Error(`\u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\uFF08\u6743\u9650\u4E0D\u8DB3\uFF1F\uFF09: ${target}`);
|
|
13843
14284
|
}
|
|
@@ -13860,22 +14301,22 @@ async function loadDirNames(target) {
|
|
|
13860
14301
|
return entries;
|
|
13861
14302
|
}
|
|
13862
14303
|
async function toDirEntry(dir, e) {
|
|
13863
|
-
const full =
|
|
14304
|
+
const full = path27.join(dir, e.name);
|
|
13864
14305
|
let isDir = e.isDir;
|
|
13865
14306
|
if (e.isLink) {
|
|
13866
14307
|
try {
|
|
13867
|
-
isDir = (await
|
|
14308
|
+
isDir = (await fs22.promises.stat(full)).isDirectory();
|
|
13868
14309
|
} catch {
|
|
13869
14310
|
}
|
|
13870
14311
|
}
|
|
13871
14312
|
return { name: e.name, path: full, type: isDir ? "dir" : "file" };
|
|
13872
14313
|
}
|
|
13873
14314
|
async function searchDirs(input, query, limit) {
|
|
13874
|
-
const base = (input ?? "").trim() ||
|
|
13875
|
-
const target =
|
|
14315
|
+
const base = (input ?? "").trim() || os6.homedir();
|
|
14316
|
+
const target = path27.resolve(base);
|
|
13876
14317
|
let st;
|
|
13877
14318
|
try {
|
|
13878
|
-
st = await
|
|
14319
|
+
st = await fs22.promises.stat(target);
|
|
13879
14320
|
} catch {
|
|
13880
14321
|
throw new Error(`\u8DEF\u5F84\u4E0D\u5B58\u5728: ${target}`);
|
|
13881
14322
|
}
|
|
@@ -13905,7 +14346,7 @@ async function searchDirs(input, query, limit) {
|
|
|
13905
14346
|
);
|
|
13906
14347
|
const hit = scored.slice(0, max);
|
|
13907
14348
|
const entries = await Promise.all(hit.map(({ entry }) => toDirEntry(target, entry)));
|
|
13908
|
-
const parentDir =
|
|
14349
|
+
const parentDir = path27.dirname(target);
|
|
13909
14350
|
return {
|
|
13910
14351
|
path: target,
|
|
13911
14352
|
parent: parentDir !== target ? parentDir : null,
|
|
@@ -13916,52 +14357,52 @@ async function searchDirs(input, query, limit) {
|
|
|
13916
14357
|
};
|
|
13917
14358
|
}
|
|
13918
14359
|
function makeDirIn(parentInput, name) {
|
|
13919
|
-
const parent =
|
|
14360
|
+
const parent = path27.resolve((parentInput ?? "").trim() || os6.homedir());
|
|
13920
14361
|
const clean = (name ?? "").trim();
|
|
13921
14362
|
if (!clean) throw new Error("\u76EE\u5F55\u540D\u4E0D\u80FD\u4E3A\u7A7A");
|
|
13922
14363
|
if (clean === "." || clean === "..") throw new Error("\u76EE\u5F55\u540D\u975E\u6CD5");
|
|
13923
|
-
const target =
|
|
13924
|
-
const rel =
|
|
13925
|
-
if (!rel || rel.startsWith("..") ||
|
|
14364
|
+
const target = path27.resolve(parent, clean);
|
|
14365
|
+
const rel = path27.relative(parent, target);
|
|
14366
|
+
if (!rel || rel.startsWith("..") || path27.isAbsolute(rel)) {
|
|
13926
14367
|
throw new Error("\u76EE\u5F55\u540D\u4E0D\u80FD\u8D8A\u51FA\u5F53\u524D\u76EE\u5F55");
|
|
13927
14368
|
}
|
|
13928
14369
|
let st = null;
|
|
13929
14370
|
try {
|
|
13930
|
-
st =
|
|
14371
|
+
st = fs22.statSync(target);
|
|
13931
14372
|
} catch {
|
|
13932
14373
|
st = null;
|
|
13933
14374
|
}
|
|
13934
14375
|
if (st && !st.isDirectory()) throw new Error(`\u5DF2\u5B58\u5728\u540C\u540D\u6587\u4EF6: ${target}`);
|
|
13935
14376
|
try {
|
|
13936
|
-
|
|
14377
|
+
fs22.mkdirSync(target, { recursive: true });
|
|
13937
14378
|
} catch (e) {
|
|
13938
14379
|
throw new Error(`\u521B\u5EFA\u76EE\u5F55\u5931\u8D25: ${e instanceof Error ? e.message : String(e)}`);
|
|
13939
14380
|
}
|
|
13940
14381
|
invalidateDirNames(parent);
|
|
13941
|
-
return { name:
|
|
14382
|
+
return { name: path27.basename(target), path: target, type: "dir" };
|
|
13942
14383
|
}
|
|
13943
14384
|
|
|
13944
14385
|
// src/server/projectFiles.ts
|
|
13945
14386
|
init_cjs_shims();
|
|
13946
|
-
var
|
|
13947
|
-
var
|
|
14387
|
+
var fs23 = __toESM(require("fs"), 1);
|
|
14388
|
+
var path28 = __toESM(require("path"), 1);
|
|
13948
14389
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
13949
14390
|
var MAX_DOWNLOAD_BYTES = 16 * 1024 * 1024;
|
|
13950
14391
|
var MAX_ENTRIES2 = 2e3;
|
|
13951
14392
|
function toPosix(p) {
|
|
13952
|
-
return p.split(
|
|
14393
|
+
return p.split(path28.sep).join("/");
|
|
13953
14394
|
}
|
|
13954
14395
|
function projectRoot(workspaceRoot) {
|
|
13955
14396
|
const r = (workspaceRoot ?? "").trim();
|
|
13956
14397
|
if (!r) {
|
|
13957
14398
|
throw new Error("\u9879\u76EE\u672A\u8BBE\u7F6E\u5DE5\u4F5C\u533A\u76EE\u5F55\uFF08workspaceRoot\uFF09\uFF0C\u65E0\u6CD5\u6D4F\u89C8\u6587\u4EF6");
|
|
13958
14399
|
}
|
|
13959
|
-
const abs =
|
|
13960
|
-
if (!
|
|
14400
|
+
const abs = path28.resolve(r);
|
|
14401
|
+
if (!fs23.existsSync(abs)) {
|
|
13961
14402
|
throw new Error(`\u5DE5\u4F5C\u533A\u76EE\u5F55\u4E0D\u5B58\u5728: ${abs}`);
|
|
13962
14403
|
}
|
|
13963
14404
|
try {
|
|
13964
|
-
return
|
|
14405
|
+
return fs23.realpathSync(abs);
|
|
13965
14406
|
} catch {
|
|
13966
14407
|
return abs;
|
|
13967
14408
|
}
|
|
@@ -13979,37 +14420,37 @@ function listProjectFiles(workspaceRoot, relPath) {
|
|
|
13979
14420
|
const dir = resolveWithin(base, relPath ?? "");
|
|
13980
14421
|
let st;
|
|
13981
14422
|
try {
|
|
13982
|
-
st =
|
|
14423
|
+
st = fs23.statSync(dir);
|
|
13983
14424
|
} catch {
|
|
13984
|
-
throw new Error(`\u76EE\u5F55\u4E0D\u5B58\u5728: ${toPosix(
|
|
14425
|
+
throw new Error(`\u76EE\u5F55\u4E0D\u5B58\u5728: ${toPosix(path28.relative(base, dir)) || "/"}`);
|
|
13985
14426
|
}
|
|
13986
14427
|
if (!st.isDirectory()) throw new Error("\u76EE\u6807\u4E0D\u662F\u76EE\u5F55");
|
|
13987
14428
|
let dirents;
|
|
13988
14429
|
try {
|
|
13989
|
-
dirents =
|
|
14430
|
+
dirents = fs23.readdirSync(dir, { withFileTypes: true });
|
|
13990
14431
|
} catch {
|
|
13991
14432
|
throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\uFF08\u6743\u9650\u4E0D\u8DB3\uFF1F\uFF09");
|
|
13992
14433
|
}
|
|
13993
14434
|
const entries = dirents.map((d) => {
|
|
13994
|
-
const full =
|
|
14435
|
+
const full = path28.join(dir, d.name);
|
|
13995
14436
|
let isDir = d.isDirectory();
|
|
13996
14437
|
if (d.isSymbolicLink()) {
|
|
13997
14438
|
try {
|
|
13998
|
-
isDir =
|
|
14439
|
+
isDir = fs23.statSync(full).isDirectory();
|
|
13999
14440
|
} catch {
|
|
14000
14441
|
}
|
|
14001
14442
|
}
|
|
14002
14443
|
let size = 0;
|
|
14003
14444
|
let mtime = "";
|
|
14004
14445
|
try {
|
|
14005
|
-
const s =
|
|
14446
|
+
const s = fs23.statSync(full);
|
|
14006
14447
|
size = s.size;
|
|
14007
14448
|
mtime = s.mtime.toISOString();
|
|
14008
14449
|
} catch {
|
|
14009
14450
|
}
|
|
14010
14451
|
return {
|
|
14011
14452
|
name: d.name,
|
|
14012
|
-
path: toPosix(
|
|
14453
|
+
path: toPosix(path28.relative(base, full)),
|
|
14013
14454
|
type: isDir ? "dir" : "file",
|
|
14014
14455
|
size,
|
|
14015
14456
|
mtime
|
|
@@ -14018,12 +14459,12 @@ function listProjectFiles(workspaceRoot, relPath) {
|
|
|
14018
14459
|
entries.sort(
|
|
14019
14460
|
(a, b) => a.type === b.type ? a.name.localeCompare(b.name) : a.type === "dir" ? -1 : 1
|
|
14020
14461
|
);
|
|
14021
|
-
const relDir = toPosix(
|
|
14022
|
-
const parentAbs =
|
|
14462
|
+
const relDir = toPosix(path28.relative(base, dir));
|
|
14463
|
+
const parentAbs = path28.dirname(dir);
|
|
14023
14464
|
return {
|
|
14024
14465
|
root: base,
|
|
14025
14466
|
path: relDir,
|
|
14026
|
-
parent: isWithinRoot(base, parentAbs) ? toPosix(
|
|
14467
|
+
parent: isWithinRoot(base, parentAbs) ? toPosix(path28.relative(base, parentAbs)) : null,
|
|
14027
14468
|
entries: entries.slice(0, MAX_ENTRIES2)
|
|
14028
14469
|
};
|
|
14029
14470
|
}
|
|
@@ -14032,17 +14473,17 @@ function readProjectFile(workspaceRoot, relPath) {
|
|
|
14032
14473
|
const file = resolveWithin(base, relPath ?? "");
|
|
14033
14474
|
let st;
|
|
14034
14475
|
try {
|
|
14035
|
-
st =
|
|
14476
|
+
st = fs23.statSync(file);
|
|
14036
14477
|
} catch {
|
|
14037
14478
|
throw new Error("\u6587\u4EF6\u4E0D\u5B58\u5728");
|
|
14038
14479
|
}
|
|
14039
14480
|
if (!st.isFile()) throw new Error("\u76EE\u6807\u4E0D\u662F\u6587\u4EF6");
|
|
14040
|
-
const buf =
|
|
14481
|
+
const buf = fs23.readFileSync(file);
|
|
14041
14482
|
const binary = isBinary(buf);
|
|
14042
14483
|
const truncated = buf.length > MAX_FILE_BYTES;
|
|
14043
14484
|
const slice = truncated ? buf.subarray(0, MAX_FILE_BYTES) : buf;
|
|
14044
14485
|
return {
|
|
14045
|
-
path: toPosix(
|
|
14486
|
+
path: toPosix(path28.relative(base, file)),
|
|
14046
14487
|
size: st.size,
|
|
14047
14488
|
binary,
|
|
14048
14489
|
truncated,
|
|
@@ -14054,7 +14495,7 @@ function downloadProjectFile(workspaceRoot, relPath) {
|
|
|
14054
14495
|
const file = resolveWithin(base, relPath ?? "");
|
|
14055
14496
|
let st;
|
|
14056
14497
|
try {
|
|
14057
|
-
st =
|
|
14498
|
+
st = fs23.statSync(file);
|
|
14058
14499
|
} catch {
|
|
14059
14500
|
throw new Error("\u6587\u4EF6\u4E0D\u5B58\u5728");
|
|
14060
14501
|
}
|
|
@@ -14062,10 +14503,10 @@ function downloadProjectFile(workspaceRoot, relPath) {
|
|
|
14062
14503
|
if (st.size > MAX_DOWNLOAD_BYTES) {
|
|
14063
14504
|
throw new Error(`\u6587\u4EF6\u8D85\u8FC7\u4E0B\u8F7D\u4E0A\u9650\uFF08${MAX_DOWNLOAD_BYTES / (1024 * 1024)}MB\uFF09`);
|
|
14064
14505
|
}
|
|
14065
|
-
const buf =
|
|
14506
|
+
const buf = fs23.readFileSync(file);
|
|
14066
14507
|
return {
|
|
14067
|
-
path: toPosix(
|
|
14068
|
-
name:
|
|
14508
|
+
path: toPosix(path28.relative(base, file)),
|
|
14509
|
+
name: path28.basename(file),
|
|
14069
14510
|
size: buf.length,
|
|
14070
14511
|
base64: buf.toString("base64")
|
|
14071
14512
|
};
|
|
@@ -14087,12 +14528,12 @@ function writeProjectFile(workspaceRoot, relPath, content) {
|
|
|
14087
14528
|
throw new Error("\u5185\u5BB9\u8D85\u8FC7 2MB \u4E0A\u9650\uFF0C\u65E0\u6CD5\u4FDD\u5B58");
|
|
14088
14529
|
}
|
|
14089
14530
|
try {
|
|
14090
|
-
|
|
14091
|
-
|
|
14531
|
+
fs23.mkdirSync(path28.dirname(file), { recursive: true });
|
|
14532
|
+
fs23.writeFileSync(file, buf);
|
|
14092
14533
|
} catch (e) {
|
|
14093
14534
|
throw new Error(`\u5199\u5165\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
14094
14535
|
}
|
|
14095
|
-
return { path: toPosix(
|
|
14536
|
+
return { path: toPosix(path28.relative(base, file)), size: buf.length };
|
|
14096
14537
|
}
|
|
14097
14538
|
function createProjectDir(workspaceRoot, relPath) {
|
|
14098
14539
|
const base = projectRoot(workspaceRoot);
|
|
@@ -14100,26 +14541,26 @@ function createProjectDir(workspaceRoot, relPath) {
|
|
|
14100
14541
|
if (!rel) throw new Error("\u76EE\u5F55\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");
|
|
14101
14542
|
const dir = resolveWithin(base, rel);
|
|
14102
14543
|
try {
|
|
14103
|
-
|
|
14544
|
+
fs23.mkdirSync(dir, { recursive: true });
|
|
14104
14545
|
} catch (e) {
|
|
14105
14546
|
throw new Error(`\u521B\u5EFA\u76EE\u5F55\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
14106
14547
|
}
|
|
14107
|
-
return { path: toPosix(
|
|
14548
|
+
return { path: toPosix(path28.relative(base, dir)) };
|
|
14108
14549
|
}
|
|
14109
14550
|
function createProjectFile(workspaceRoot, relPath, content = "") {
|
|
14110
14551
|
const base = projectRoot(workspaceRoot);
|
|
14111
14552
|
const rel = (relPath ?? "").trim();
|
|
14112
14553
|
if (!rel) throw new Error("\u6587\u4EF6\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");
|
|
14113
14554
|
const file = resolveWithin(base, rel);
|
|
14114
|
-
if (
|
|
14555
|
+
if (fs23.existsSync(file)) throw new Error("\u6587\u4EF6\u5DF2\u5B58\u5728");
|
|
14115
14556
|
const buf = Buffer.from(String(content ?? ""), "utf-8");
|
|
14116
14557
|
try {
|
|
14117
|
-
|
|
14118
|
-
|
|
14558
|
+
fs23.mkdirSync(path28.dirname(file), { recursive: true });
|
|
14559
|
+
fs23.writeFileSync(file, buf);
|
|
14119
14560
|
} catch (e) {
|
|
14120
14561
|
throw new Error(`\u521B\u5EFA\u6587\u4EF6\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
14121
14562
|
}
|
|
14122
|
-
return { path: toPosix(
|
|
14563
|
+
return { path: toPosix(path28.relative(base, file)), size: buf.length };
|
|
14123
14564
|
}
|
|
14124
14565
|
function searchProjectFiles(workspaceRoot, query) {
|
|
14125
14566
|
const base = projectRoot(workspaceRoot);
|
|
@@ -14142,7 +14583,7 @@ function searchProjectFiles(workspaceRoot, query) {
|
|
|
14142
14583
|
if (out.length >= LIMIT) return;
|
|
14143
14584
|
let dirents;
|
|
14144
14585
|
try {
|
|
14145
|
-
dirents =
|
|
14586
|
+
dirents = fs23.readdirSync(dir, { withFileTypes: true });
|
|
14146
14587
|
} catch {
|
|
14147
14588
|
return;
|
|
14148
14589
|
}
|
|
@@ -14153,7 +14594,7 @@ function searchProjectFiles(workspaceRoot, query) {
|
|
|
14153
14594
|
let isDir = d.isDirectory();
|
|
14154
14595
|
if (d.isSymbolicLink()) {
|
|
14155
14596
|
try {
|
|
14156
|
-
isDir =
|
|
14597
|
+
isDir = fs23.statSync(path28.join(dir, d.name)).isDirectory();
|
|
14157
14598
|
} catch {
|
|
14158
14599
|
isDir = false;
|
|
14159
14600
|
}
|
|
@@ -14161,7 +14602,7 @@ function searchProjectFiles(workspaceRoot, query) {
|
|
|
14161
14602
|
if (d.name.toLowerCase().includes(q)) {
|
|
14162
14603
|
out.push({ path: rel, type: isDir ? "dir" : "file" });
|
|
14163
14604
|
}
|
|
14164
|
-
if (isDir) walk(
|
|
14605
|
+
if (isDir) walk(path28.join(dir, d.name), rel);
|
|
14165
14606
|
}
|
|
14166
14607
|
};
|
|
14167
14608
|
walk(base, "");
|
|
@@ -14170,8 +14611,8 @@ function searchProjectFiles(workspaceRoot, query) {
|
|
|
14170
14611
|
|
|
14171
14612
|
// src/server/projectOps.ts
|
|
14172
14613
|
init_cjs_shims();
|
|
14173
|
-
var
|
|
14174
|
-
var
|
|
14614
|
+
var os7 = __toESM(require("os"), 1);
|
|
14615
|
+
var path29 = __toESM(require("path"), 1);
|
|
14175
14616
|
var MAX_STDOUT2 = 2e4;
|
|
14176
14617
|
var MAX_STDERR2 = 1e4;
|
|
14177
14618
|
var MAX_BUFFER3 = 1024 * 1024 * 5;
|
|
@@ -14185,7 +14626,7 @@ function resolveInvocation2(spec, prepared) {
|
|
|
14185
14626
|
}
|
|
14186
14627
|
function workRoot(workspaceRoot) {
|
|
14187
14628
|
const r = (workspaceRoot ?? "").trim();
|
|
14188
|
-
return r ?
|
|
14629
|
+
return r ? path29.resolve(r) : os7.homedir();
|
|
14189
14630
|
}
|
|
14190
14631
|
async function runProjectCommand(workspaceRoot, command, timeoutSeconds) {
|
|
14191
14632
|
const cmd = String(command ?? "");
|
|
@@ -14496,11 +14937,11 @@ function projectStats(manager, tenantId) {
|
|
|
14496
14937
|
|
|
14497
14938
|
// src/server/nodeHost.ts
|
|
14498
14939
|
init_cjs_shims();
|
|
14499
|
-
var
|
|
14500
|
-
var
|
|
14940
|
+
var fs24 = __toESM(require("fs"), 1);
|
|
14941
|
+
var os8 = __toESM(require("os"), 1);
|
|
14501
14942
|
function diskInfo(pathStr) {
|
|
14502
14943
|
try {
|
|
14503
|
-
const st =
|
|
14944
|
+
const st = fs24.statfsSync(pathStr);
|
|
14504
14945
|
return {
|
|
14505
14946
|
path: pathStr,
|
|
14506
14947
|
total: Number(st.blocks) * Number(st.bsize),
|
|
@@ -14512,7 +14953,7 @@ function diskInfo(pathStr) {
|
|
|
14512
14953
|
}
|
|
14513
14954
|
function networkInfo() {
|
|
14514
14955
|
const out = [];
|
|
14515
|
-
const ifaces =
|
|
14956
|
+
const ifaces = os8.networkInterfaces();
|
|
14516
14957
|
for (const [name, list] of Object.entries(ifaces)) {
|
|
14517
14958
|
for (const info of list ?? []) {
|
|
14518
14959
|
out.push({
|
|
@@ -14563,23 +15004,23 @@ function overview(store, manager) {
|
|
|
14563
15004
|
return { projects, sessions: { total, running, waiting, items }, usage: { tokensIn, tokensOut } };
|
|
14564
15005
|
}
|
|
14565
15006
|
function buildNodeHost(store, manager, diskPath) {
|
|
14566
|
-
const cpus2 =
|
|
15007
|
+
const cpus2 = os8.cpus();
|
|
14567
15008
|
const ov = overview(store, manager);
|
|
14568
15009
|
return {
|
|
14569
15010
|
nodeId: store.loadNodeId() ?? "",
|
|
14570
|
-
hostname:
|
|
15011
|
+
hostname: os8.hostname(),
|
|
14571
15012
|
platform: process.platform,
|
|
14572
15013
|
arch: process.arch,
|
|
14573
|
-
release:
|
|
14574
|
-
uptimeSec: Math.round(
|
|
14575
|
-
version: "0.2.
|
|
15014
|
+
release: os8.release(),
|
|
15015
|
+
uptimeSec: Math.round(os8.uptime()),
|
|
15016
|
+
version: "0.2.11",
|
|
14576
15017
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
14577
15018
|
cpu: {
|
|
14578
15019
|
count: cpus2.length,
|
|
14579
15020
|
model: cpus2[0]?.model ?? "",
|
|
14580
|
-
loadAvg:
|
|
15021
|
+
loadAvg: os8.loadavg().map((n) => Math.round(n * 100) / 100)
|
|
14581
15022
|
},
|
|
14582
|
-
memory: { total:
|
|
15023
|
+
memory: { total: os8.totalmem(), free: os8.freemem() },
|
|
14583
15024
|
network: networkInfo(),
|
|
14584
15025
|
disk: diskInfo(diskPath || process.cwd()),
|
|
14585
15026
|
...ov
|
|
@@ -14616,7 +15057,7 @@ function saveNotifications(tenant, secretBox, notifications) {
|
|
|
14616
15057
|
var API_PREFIX = "/api/v1";
|
|
14617
15058
|
var MAX_BODY_BYTES = 10 * 1024 * 1024;
|
|
14618
15059
|
function readBody(req2) {
|
|
14619
|
-
return new Promise((
|
|
15060
|
+
return new Promise((resolve24, reject) => {
|
|
14620
15061
|
const chunks = [];
|
|
14621
15062
|
let size = 0;
|
|
14622
15063
|
req2.on("data", (c) => {
|
|
@@ -14629,9 +15070,9 @@ function readBody(req2) {
|
|
|
14629
15070
|
chunks.push(c);
|
|
14630
15071
|
});
|
|
14631
15072
|
req2.on("end", () => {
|
|
14632
|
-
if (chunks.length === 0) return
|
|
15073
|
+
if (chunks.length === 0) return resolve24(void 0);
|
|
14633
15074
|
try {
|
|
14634
|
-
|
|
15075
|
+
resolve24(JSON.parse(Buffer.concat(chunks).toString("utf-8")));
|
|
14635
15076
|
} catch {
|
|
14636
15077
|
reject(new ApiError(400, "bad_request", "\u8BF7\u6C42\u4F53\u4E0D\u662F\u5408\u6CD5 JSON"));
|
|
14637
15078
|
}
|
|
@@ -15147,8 +15588,18 @@ function createApp(store, manager, opts = {}) {
|
|
|
15147
15588
|
applyProvidersPatch(tenant, raw);
|
|
15148
15589
|
if (typeof raw.workspaceRoot === "string") {
|
|
15149
15590
|
const ws = raw.workspaceRoot.trim();
|
|
15150
|
-
|
|
15151
|
-
|
|
15591
|
+
const next = ws ? path30.resolve(ws) : void 0;
|
|
15592
|
+
if (tenant.workspaceRoot) {
|
|
15593
|
+
if (next !== tenant.workspaceRoot) {
|
|
15594
|
+
throw new ApiError(
|
|
15595
|
+
409,
|
|
15596
|
+
"workspace_locked",
|
|
15597
|
+
"\u8BE5\u9879\u76EE\u5DF2\u8BBE\u7F6E\u5DE5\u4F5C\u76EE\u5F55\uFF0C\u4E0D\u80FD\u518D\u4FEE\u6539"
|
|
15598
|
+
);
|
|
15599
|
+
}
|
|
15600
|
+
} else if (next) {
|
|
15601
|
+
tenant.workspaceRoot = next;
|
|
15602
|
+
}
|
|
15152
15603
|
}
|
|
15153
15604
|
if (typeof raw.name === "string" && raw.name.trim()) {
|
|
15154
15605
|
tenant.name = raw.name.trim();
|
|
@@ -16124,7 +16575,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
16124
16575
|
json(res, 200, {
|
|
16125
16576
|
status: "ok",
|
|
16126
16577
|
// 版本让运维/探针能确认线上跑的是哪个构建(更新与回滚据此判断)
|
|
16127
|
-
version: "0.2.
|
|
16578
|
+
version: "0.2.11",
|
|
16128
16579
|
features: { mcp: hasServerMcpConfig() }
|
|
16129
16580
|
});
|
|
16130
16581
|
return;
|
|
@@ -16219,7 +16670,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
16219
16670
|
|
|
16220
16671
|
// src/server/fleet/FleetNodeBridge.ts
|
|
16221
16672
|
init_cjs_shims();
|
|
16222
|
-
var
|
|
16673
|
+
var os9 = __toESM(require("os"), 1);
|
|
16223
16674
|
var import_node_perf_hooks = require("perf_hooks");
|
|
16224
16675
|
|
|
16225
16676
|
// src/server/fleet/FleetCommands.ts
|
|
@@ -16240,8 +16691,8 @@ async function cachedFetchModels(baseURL, apiKey) {
|
|
|
16240
16691
|
try {
|
|
16241
16692
|
result = await Promise.race([
|
|
16242
16693
|
fetchModels(baseURL, apiKey),
|
|
16243
|
-
new Promise((
|
|
16244
|
-
const t = setTimeout(() =>
|
|
16694
|
+
new Promise((resolve24) => {
|
|
16695
|
+
const t = setTimeout(() => resolve24(null), MODEL_FETCH_TIMEOUT_MS);
|
|
16245
16696
|
t.unref?.();
|
|
16246
16697
|
})
|
|
16247
16698
|
]);
|
|
@@ -16266,8 +16717,8 @@ async function cachedFetchModelsEnriched(baseURL, apiKey, preferred) {
|
|
|
16266
16717
|
if (!target) return r;
|
|
16267
16718
|
const ctx = await Promise.race([
|
|
16268
16719
|
fetchModelContext(baseURL, apiKey, target),
|
|
16269
|
-
new Promise((
|
|
16270
|
-
const t = setTimeout(() =>
|
|
16720
|
+
new Promise((resolve24) => {
|
|
16721
|
+
const t = setTimeout(() => resolve24(void 0), MODEL_FETCH_TIMEOUT_MS);
|
|
16271
16722
|
t.unref?.();
|
|
16272
16723
|
})
|
|
16273
16724
|
]);
|
|
@@ -17396,13 +17847,13 @@ var EVENT_FLUSH_MAX_EVENTS = 60;
|
|
|
17396
17847
|
var EVENT_FLUSH_MAX_BYTES = 200 * 1024;
|
|
17397
17848
|
var LOOP_LAG_WARN_MS = 2e3;
|
|
17398
17849
|
function withTimeout(p, ms) {
|
|
17399
|
-
return new Promise((
|
|
17850
|
+
return new Promise((resolve24, reject) => {
|
|
17400
17851
|
const timer = setTimeout(() => reject(new Error(`\u5B50\u6307\u4EE4\u8D85\u65F6\uFF08${ms}ms\uFF09`)), ms);
|
|
17401
17852
|
timer.unref?.();
|
|
17402
17853
|
p.then(
|
|
17403
17854
|
(v) => {
|
|
17404
17855
|
clearTimeout(timer);
|
|
17405
|
-
|
|
17856
|
+
resolve24(v);
|
|
17406
17857
|
},
|
|
17407
17858
|
(e) => {
|
|
17408
17859
|
clearTimeout(timer);
|
|
@@ -17413,7 +17864,7 @@ function withTimeout(p, ms) {
|
|
|
17413
17864
|
}
|
|
17414
17865
|
function primaryIp() {
|
|
17415
17866
|
let v6;
|
|
17416
|
-
for (const infos of Object.values(
|
|
17867
|
+
for (const infos of Object.values(os9.networkInterfaces())) {
|
|
17417
17868
|
for (const info of infos ?? []) {
|
|
17418
17869
|
if (info.internal) continue;
|
|
17419
17870
|
if (info.family === "IPv4") return info.address;
|
|
@@ -17762,7 +18213,7 @@ var FleetNodeBridge = class {
|
|
|
17762
18213
|
label: this.opts.deps.store.loadNodeLabel() ?? void 0,
|
|
17763
18214
|
platform: process.platform,
|
|
17764
18215
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
17765
|
-
version: "0.2.
|
|
18216
|
+
version: "0.2.11",
|
|
17766
18217
|
ip: primaryIp()
|
|
17767
18218
|
};
|
|
17768
18219
|
}
|
|
@@ -17817,7 +18268,7 @@ var FleetNodeBridge = class {
|
|
|
17817
18268
|
label: this.opts.deps.store.loadNodeLabel() ?? void 0,
|
|
17818
18269
|
platform: process.platform,
|
|
17819
18270
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
17820
|
-
version: "0.2.
|
|
18271
|
+
version: "0.2.11",
|
|
17821
18272
|
ip: primaryIp(),
|
|
17822
18273
|
projects,
|
|
17823
18274
|
totals,
|
|
@@ -18586,8 +19037,8 @@ init_cjs_shims();
|
|
|
18586
19037
|
|
|
18587
19038
|
// src/server/qq/bindings.ts
|
|
18588
19039
|
init_cjs_shims();
|
|
18589
|
-
var
|
|
18590
|
-
var
|
|
19040
|
+
var fs25 = __toESM(require("fs"), 1);
|
|
19041
|
+
var path31 = __toESM(require("path"), 1);
|
|
18591
19042
|
function conversationKey(target) {
|
|
18592
19043
|
switch (target.kind) {
|
|
18593
19044
|
case "c2c":
|
|
@@ -18626,12 +19077,12 @@ var QqBindingsStore = class _QqBindingsStore {
|
|
|
18626
19077
|
cache = null;
|
|
18627
19078
|
/** 基于 DATA_DIR 构造 */
|
|
18628
19079
|
static in(dataDir) {
|
|
18629
|
-
return new _QqBindingsStore(
|
|
19080
|
+
return new _QqBindingsStore(path31.join(dataDir, "qq", "bindings.json"));
|
|
18630
19081
|
}
|
|
18631
19082
|
load() {
|
|
18632
19083
|
if (this.cache) return this.cache;
|
|
18633
19084
|
try {
|
|
18634
|
-
const raw = JSON.parse(
|
|
19085
|
+
const raw = JSON.parse(fs25.readFileSync(this.file, "utf-8"));
|
|
18635
19086
|
this.cache = {
|
|
18636
19087
|
conversations: raw.conversations ?? {}
|
|
18637
19088
|
};
|
|
@@ -18663,8 +19114,8 @@ var QqBindingsStore = class _QqBindingsStore {
|
|
|
18663
19114
|
return null;
|
|
18664
19115
|
}
|
|
18665
19116
|
persist() {
|
|
18666
|
-
|
|
18667
|
-
|
|
19117
|
+
fs25.mkdirSync(path31.dirname(this.file), { recursive: true });
|
|
19118
|
+
fs25.writeFileSync(this.file, JSON.stringify(this.cache, null, 2), "utf-8");
|
|
18668
19119
|
}
|
|
18669
19120
|
};
|
|
18670
19121
|
|
|
@@ -19076,8 +19527,8 @@ ${lines.join("\n")}`, msgId);
|
|
|
19076
19527
|
|
|
19077
19528
|
// src/server/qq/QqManager.ts
|
|
19078
19529
|
init_cjs_shims();
|
|
19079
|
-
var
|
|
19080
|
-
var
|
|
19530
|
+
var fs26 = __toESM(require("fs"), 1);
|
|
19531
|
+
var path32 = __toESM(require("path"), 1);
|
|
19081
19532
|
var QqManager = class {
|
|
19082
19533
|
constructor(opts) {
|
|
19083
19534
|
this.opts = opts;
|
|
@@ -19086,7 +19537,7 @@ var QqManager = class {
|
|
|
19086
19537
|
adapter = null;
|
|
19087
19538
|
config = null;
|
|
19088
19539
|
get configFile() {
|
|
19089
|
-
return
|
|
19540
|
+
return path32.join(this.opts.dataDir, "qq", "config.json");
|
|
19090
19541
|
}
|
|
19091
19542
|
/** 启动:读配置(env 优先,其次文件),有则建连接 */
|
|
19092
19543
|
start() {
|
|
@@ -19124,7 +19575,7 @@ var QqManager = class {
|
|
|
19124
19575
|
/** 清空配置:删除文件 + 断开 */
|
|
19125
19576
|
clearConfig() {
|
|
19126
19577
|
try {
|
|
19127
|
-
|
|
19578
|
+
fs26.rmSync(this.configFile, { force: true });
|
|
19128
19579
|
} catch {
|
|
19129
19580
|
}
|
|
19130
19581
|
this.stop();
|
|
@@ -19166,7 +19617,7 @@ var QqManager = class {
|
|
|
19166
19617
|
}
|
|
19167
19618
|
_readConfigFile() {
|
|
19168
19619
|
try {
|
|
19169
|
-
const raw = JSON.parse(
|
|
19620
|
+
const raw = JSON.parse(fs26.readFileSync(this.configFile, "utf-8"));
|
|
19170
19621
|
if (raw.appId && raw.appSecret) {
|
|
19171
19622
|
return {
|
|
19172
19623
|
appId: raw.appId,
|
|
@@ -19179,8 +19630,8 @@ var QqManager = class {
|
|
|
19179
19630
|
return null;
|
|
19180
19631
|
}
|
|
19181
19632
|
_persistConfig(cfg) {
|
|
19182
|
-
|
|
19183
|
-
|
|
19633
|
+
fs26.mkdirSync(path32.dirname(this.configFile), { recursive: true });
|
|
19634
|
+
fs26.writeFileSync(this.configFile, JSON.stringify(cfg, null, 2), "utf-8");
|
|
19184
19635
|
}
|
|
19185
19636
|
};
|
|
19186
19637
|
|
|
@@ -19234,11 +19685,11 @@ var path36 = __toESM(require("path"), 1);
|
|
|
19234
19685
|
// src/update/downloader.ts
|
|
19235
19686
|
init_cjs_shims();
|
|
19236
19687
|
var import_node_crypto5 = require("crypto");
|
|
19237
|
-
var
|
|
19688
|
+
var fs27 = __toESM(require("fs"), 1);
|
|
19238
19689
|
var import_node_stream2 = require("stream");
|
|
19239
19690
|
var import_promises2 = require("stream/promises");
|
|
19240
|
-
var
|
|
19241
|
-
var
|
|
19691
|
+
var import_node_child_process6 = require("child_process");
|
|
19692
|
+
var path33 = __toESM(require("path"), 1);
|
|
19242
19693
|
|
|
19243
19694
|
// src/update/manifest.ts
|
|
19244
19695
|
init_cjs_shims();
|
|
@@ -19294,8 +19745,10 @@ var PLATFORM_NAMES = {
|
|
|
19294
19745
|
linux: "linux",
|
|
19295
19746
|
win32: "windows"
|
|
19296
19747
|
};
|
|
19748
|
+
var LIBC_VARIANT = "";
|
|
19297
19749
|
function platformKey(platform = process.platform, arch = process.arch) {
|
|
19298
|
-
|
|
19750
|
+
const base = `${PLATFORM_NAMES[platform] ?? platform}-${arch}`;
|
|
19751
|
+
return LIBC_VARIANT ? `${base}-${LIBC_VARIANT}` : base;
|
|
19299
19752
|
}
|
|
19300
19753
|
var SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
19301
19754
|
function isRecord(v) {
|
|
@@ -19413,8 +19866,8 @@ async function fetchManifest(url, publicKey, opts = {}) {
|
|
|
19413
19866
|
async function downloadBinary(bin, destPath, log = () => {
|
|
19414
19867
|
}) {
|
|
19415
19868
|
const partPath = `${destPath}.part`;
|
|
19416
|
-
|
|
19417
|
-
|
|
19869
|
+
fs27.mkdirSync(path33.dirname(destPath), { recursive: true });
|
|
19870
|
+
fs27.rmSync(partPath, { force: true });
|
|
19418
19871
|
let res;
|
|
19419
19872
|
try {
|
|
19420
19873
|
res = await fetch(bin.url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS2) });
|
|
@@ -19439,30 +19892,30 @@ async function downloadBinary(bin, destPath, log = () => {
|
|
|
19439
19892
|
yield chunk;
|
|
19440
19893
|
}
|
|
19441
19894
|
},
|
|
19442
|
-
|
|
19895
|
+
fs27.createWriteStream(partPath, { mode: 493 })
|
|
19443
19896
|
);
|
|
19444
19897
|
} catch (err) {
|
|
19445
|
-
|
|
19898
|
+
fs27.rmSync(partPath, { force: true });
|
|
19446
19899
|
return { error: `\u4E0B\u8F7D\u4E2D\u65AD\uFF1A${err.message}` };
|
|
19447
19900
|
}
|
|
19448
19901
|
const actual = hash.digest("hex");
|
|
19449
19902
|
if (actual !== bin.sha256) {
|
|
19450
|
-
|
|
19903
|
+
fs27.rmSync(partPath, { force: true });
|
|
19451
19904
|
return { error: `SHA-256 \u4E0D\u5339\u914D\uFF08\u671F\u671B ${bin.sha256.slice(0, 12)}\u2026\uFF0C\u5B9E\u9645 ${actual.slice(0, 12)}\u2026\uFF09` };
|
|
19452
19905
|
}
|
|
19453
19906
|
if (expected && bytes !== expected) {
|
|
19454
|
-
|
|
19907
|
+
fs27.rmSync(partPath, { force: true });
|
|
19455
19908
|
return { error: `\u4EA7\u7269\u5927\u5C0F\u4E0D\u5339\u914D\uFF08\u671F\u671B ${expected}\uFF0C\u5B9E\u9645 ${bytes}\uFF09` };
|
|
19456
19909
|
}
|
|
19457
|
-
|
|
19458
|
-
|
|
19459
|
-
|
|
19460
|
-
log(`\u5DF2\u4E0B\u8F7D ${
|
|
19910
|
+
fs27.rmSync(destPath, { force: true });
|
|
19911
|
+
fs27.renameSync(partPath, destPath);
|
|
19912
|
+
fs27.chmodSync(destPath, 493);
|
|
19913
|
+
log(`\u5DF2\u4E0B\u8F7D ${path33.basename(destPath)}\uFF08${Math.round(bytes / 1024 / 1024)}MB\uFF0C\u6821\u9A8C\u901A\u8FC7\uFF09`);
|
|
19461
19914
|
return { bytes };
|
|
19462
19915
|
}
|
|
19463
19916
|
function selfCheck(binPath, expectedVersion) {
|
|
19464
19917
|
try {
|
|
19465
|
-
const r = (0,
|
|
19918
|
+
const r = (0, import_node_child_process6.spawnSync)(binPath, ["--version"], {
|
|
19466
19919
|
timeout: 2e4,
|
|
19467
19920
|
encoding: "utf-8",
|
|
19468
19921
|
env: { ...process.env, ZQAGENT_AUTO_UPDATE: "0" }
|
|
@@ -19479,104 +19932,6 @@ function selfCheck(binPath, expectedVersion) {
|
|
|
19479
19932
|
}
|
|
19480
19933
|
}
|
|
19481
19934
|
|
|
19482
|
-
// src/update/platform.ts
|
|
19483
|
-
init_cjs_shims();
|
|
19484
|
-
var fs27 = __toESM(require("fs"), 1);
|
|
19485
|
-
var path33 = __toESM(require("path"), 1);
|
|
19486
|
-
var import_node_child_process6 = require("child_process");
|
|
19487
|
-
var import_node_module3 = require("module");
|
|
19488
|
-
function currentVersion() {
|
|
19489
|
-
const injected = "0.2.8"?.trim();
|
|
19490
|
-
if (injected) return injected;
|
|
19491
|
-
try {
|
|
19492
|
-
const req2 = (0, import_node_module3.createRequire)(importMetaUrl);
|
|
19493
|
-
const pkg = req2("../../package.json");
|
|
19494
|
-
if (pkg?.version) return pkg.version;
|
|
19495
|
-
} catch {
|
|
19496
|
-
}
|
|
19497
|
-
return "dev";
|
|
19498
|
-
}
|
|
19499
|
-
function isSeaRuntime() {
|
|
19500
|
-
if (process.env.ZQAGENT_SEA === "1") return true;
|
|
19501
|
-
const base = path33.basename(process.execPath).toLowerCase().replace(/\.exe$/, "");
|
|
19502
|
-
return base !== "node" && base !== "nodejs";
|
|
19503
|
-
}
|
|
19504
|
-
var DEFAULT_SERVICE_NAME = "zqagent";
|
|
19505
|
-
function serviceManagerFromCgroup(cgroup, serviceName = DEFAULT_SERVICE_NAME) {
|
|
19506
|
-
const unitName = `${serviceName}.service`;
|
|
19507
|
-
for (const line of cgroup.split("\n")) {
|
|
19508
|
-
const idx = line.lastIndexOf(":");
|
|
19509
|
-
if (idx < 0) continue;
|
|
19510
|
-
const unitPath = line.slice(idx + 1).trim();
|
|
19511
|
-
if (unitPath.split("/").includes(unitName)) return "systemd";
|
|
19512
|
-
}
|
|
19513
|
-
return null;
|
|
19514
|
-
}
|
|
19515
|
-
function detectServiceManager() {
|
|
19516
|
-
if (process.platform !== "linux") return null;
|
|
19517
|
-
const serviceName = process.env.ZQAGENT_SERVICE_NAME?.trim() || DEFAULT_SERVICE_NAME;
|
|
19518
|
-
try {
|
|
19519
|
-
return serviceManagerFromCgroup(
|
|
19520
|
-
fs27.readFileSync("/proc/self/cgroup", "utf8"),
|
|
19521
|
-
serviceName
|
|
19522
|
-
);
|
|
19523
|
-
} catch {
|
|
19524
|
-
return null;
|
|
19525
|
-
}
|
|
19526
|
-
}
|
|
19527
|
-
function serviceManager() {
|
|
19528
|
-
const v = process.env.ZQAGENT_SERVICE_MANAGER?.trim().toLowerCase();
|
|
19529
|
-
if (v === "systemd" || v === "launchd") return v;
|
|
19530
|
-
return detectServiceManager();
|
|
19531
|
-
}
|
|
19532
|
-
function parseServiceEnvironment(raw) {
|
|
19533
|
-
const out = {};
|
|
19534
|
-
for (const token of raw.trim().split(/\s+/)) {
|
|
19535
|
-
const idx = token.indexOf("=");
|
|
19536
|
-
if (idx > 0) out[token.slice(0, idx)] = token.slice(idx + 1);
|
|
19537
|
-
}
|
|
19538
|
-
return out;
|
|
19539
|
-
}
|
|
19540
|
-
var cachedServiceEnv = null;
|
|
19541
|
-
function readServiceEnvironment() {
|
|
19542
|
-
const serviceName = process.env.ZQAGENT_SERVICE_NAME?.trim() || DEFAULT_SERVICE_NAME;
|
|
19543
|
-
try {
|
|
19544
|
-
const res = (0, import_node_child_process6.spawnSync)(
|
|
19545
|
-
"systemctl",
|
|
19546
|
-
["show", serviceName, "--property=Environment", "--value", "--no-pager"],
|
|
19547
|
-
{ encoding: "utf8", timeout: 3e3 }
|
|
19548
|
-
);
|
|
19549
|
-
if (res.status !== 0 || !res.stdout) return {};
|
|
19550
|
-
return parseServiceEnvironment(res.stdout);
|
|
19551
|
-
} catch {
|
|
19552
|
-
return {};
|
|
19553
|
-
}
|
|
19554
|
-
}
|
|
19555
|
-
function serviceEnvValue(key) {
|
|
19556
|
-
if (process.platform !== "linux") return void 0;
|
|
19557
|
-
if (serviceManager() !== "systemd") return void 0;
|
|
19558
|
-
cachedServiceEnv ??= readServiceEnvironment();
|
|
19559
|
-
return cachedServiceEnv[key];
|
|
19560
|
-
}
|
|
19561
|
-
function selfUpdateCapability(hasPublicKey) {
|
|
19562
|
-
if (!isSeaRuntime()) {
|
|
19563
|
-
return {
|
|
19564
|
-
ok: false,
|
|
19565
|
-
reason: "\u5F53\u524D\u4E0D\u662F\u5355\u6587\u4EF6\uFF08SEA\uFF09\u5F62\u6001\uFF1A\u8BF7\u7528 npm \u5347\u7EA7\uFF08npm i -g @zqagent/core@latest\uFF09"
|
|
19566
|
-
};
|
|
19567
|
-
}
|
|
19568
|
-
if (!serviceManager()) {
|
|
19569
|
-
return {
|
|
19570
|
-
ok: false,
|
|
19571
|
-
reason: "\u672A\u88AB systemd/launchd \u6258\u7BA1\uFF1A\u8BF7\u7528 deploy/service/install.sh \u5B89\u88C5\uFF0C\u6216\u624B\u52A8\u5347\u7EA7"
|
|
19572
|
-
};
|
|
19573
|
-
}
|
|
19574
|
-
if (!hasPublicKey) {
|
|
19575
|
-
return { ok: false, reason: "\u672A\u914D\u7F6E ZQAGENT_UPDATE_PUBKEY\uFF0C\u65E0\u6CD5\u9A8C\u7B7E\uFF0C\u5DF2\u7981\u7528\u81EA\u52A8\u66F4\u65B0" };
|
|
19576
|
-
}
|
|
19577
|
-
return { ok: true };
|
|
19578
|
-
}
|
|
19579
|
-
|
|
19580
19935
|
// src/update/installer.ts
|
|
19581
19936
|
init_cjs_shims();
|
|
19582
19937
|
var fs29 = __toESM(require("fs"), 1);
|
|
@@ -19942,11 +20297,11 @@ var UpdateController = class {
|
|
|
19942
20297
|
const minUptime = num("ZQAGENT_UPDATE_MIN_UPTIME_MS", 10 * 60 * 1e3);
|
|
19943
20298
|
const idleMs = num("ZQAGENT_UPDATE_IDLE_MS", 60 * 1e3);
|
|
19944
20299
|
let idleSince = null;
|
|
19945
|
-
return new Promise((
|
|
20300
|
+
return new Promise((resolve24) => {
|
|
19946
20301
|
const timer = setInterval(() => {
|
|
19947
20302
|
if (this.stopped) {
|
|
19948
20303
|
clearInterval(timer);
|
|
19949
|
-
|
|
20304
|
+
resolve24(false);
|
|
19950
20305
|
return;
|
|
19951
20306
|
}
|
|
19952
20307
|
if (Date.now() - this.startedAt < minUptime || !this.opts.isIdle()) {
|
|
@@ -19956,7 +20311,7 @@ var UpdateController = class {
|
|
|
19956
20311
|
idleSince ??= Date.now();
|
|
19957
20312
|
if (Date.now() - idleSince >= idleMs) {
|
|
19958
20313
|
clearInterval(timer);
|
|
19959
|
-
|
|
20314
|
+
resolve24(true);
|
|
19960
20315
|
}
|
|
19961
20316
|
}, 1e3);
|
|
19962
20317
|
timer.unref();
|
|
@@ -20137,6 +20492,46 @@ function exitWhenOrphaned() {
|
|
|
20137
20492
|
}, 1500);
|
|
20138
20493
|
timer.unref();
|
|
20139
20494
|
}
|
|
20495
|
+
var PORT_FALLBACK_LIMIT = 20;
|
|
20496
|
+
function listenWithPortFallback(server, startPort, host, dataDir, limit = PORT_FALLBACK_LIMIT) {
|
|
20497
|
+
return new Promise((resolve24, reject) => {
|
|
20498
|
+
let attempts = 0;
|
|
20499
|
+
const tryListen = (port) => {
|
|
20500
|
+
server.removeAllListeners("listening");
|
|
20501
|
+
const onError = (err) => {
|
|
20502
|
+
if (err.code === "EADDRINUSE" && attempts < limit) {
|
|
20503
|
+
attempts += 1;
|
|
20504
|
+
const next = port + 1;
|
|
20505
|
+
console.warn(`[server] \u7AEF\u53E3 ${port} \u5DF2\u88AB\u5360\u7528\uFF08EADDRINUSE\uFF09\uFF0C\u5C1D\u8BD5 ${next} \u2026`);
|
|
20506
|
+
tryListen(next);
|
|
20507
|
+
return;
|
|
20508
|
+
}
|
|
20509
|
+
server.removeListener("error", onError);
|
|
20510
|
+
console.error(
|
|
20511
|
+
`[server] \u65E0\u6CD5\u76D1\u542C ${host}:${port}\uFF1A${err.message}` + (err.code === "EADDRINUSE" ? `\uFF08\u5DF2\u5C1D\u8BD5 ${attempts + 1} \u4E2A\u7AEF\u53E3\u5747\u88AB\u5360\u7528\uFF09` : "")
|
|
20512
|
+
);
|
|
20513
|
+
reject(err);
|
|
20514
|
+
};
|
|
20515
|
+
server.once("error", onError);
|
|
20516
|
+
server.listen(port, host, () => {
|
|
20517
|
+
server.removeListener("error", onError);
|
|
20518
|
+
const addr = server.address();
|
|
20519
|
+
const actualPort = typeof addr === "object" && addr !== null ? addr.port : port;
|
|
20520
|
+
if (actualPort !== startPort) {
|
|
20521
|
+
console.warn(`[server] \u5DF2\u6539\u7528\u7AEF\u53E3 ${actualPort}\uFF08\u539F\u5B9A ${startPort} \u88AB\u5360\u7528\uFF09`);
|
|
20522
|
+
}
|
|
20523
|
+
try {
|
|
20524
|
+
fs31.mkdirSync(dataDir, { recursive: true });
|
|
20525
|
+
fs31.writeFileSync(path37.join(dataDir, "server-port"), `${actualPort}
|
|
20526
|
+
`);
|
|
20527
|
+
} catch {
|
|
20528
|
+
}
|
|
20529
|
+
resolve24(actualPort);
|
|
20530
|
+
});
|
|
20531
|
+
};
|
|
20532
|
+
tryListen(startPort);
|
|
20533
|
+
});
|
|
20534
|
+
}
|
|
20140
20535
|
function startServer(opts = {}) {
|
|
20141
20536
|
const dataDir = path37.resolve(opts.dataDir ?? env2("DATA_DIR") ?? DEFAULT_DATA_DIR);
|
|
20142
20537
|
const port = opts.port ?? Number(env2("PORT") ?? 8787);
|
|
@@ -20362,11 +20757,11 @@ function startServer(opts = {}) {
|
|
|
20362
20757
|
server.timeout = 0;
|
|
20363
20758
|
server.keepAliveTimeout = 65e3;
|
|
20364
20759
|
server.headersTimeout = 66e3;
|
|
20365
|
-
const ready = new Promise((
|
|
20366
|
-
server
|
|
20760
|
+
const ready = new Promise((resolve24, reject) => {
|
|
20761
|
+
listenWithPortFallback(server, port, host, dataDir).then((actualPort) => {
|
|
20367
20762
|
const info = {
|
|
20368
20763
|
host,
|
|
20369
|
-
port,
|
|
20764
|
+
port: actualPort,
|
|
20370
20765
|
dataDir,
|
|
20371
20766
|
adminKey,
|
|
20372
20767
|
fleetNodeId: fleet ? fleet.getNodeId() : void 0,
|
|
@@ -20379,8 +20774,8 @@ function startServer(opts = {}) {
|
|
|
20379
20774
|
printReady(info, qq);
|
|
20380
20775
|
}
|
|
20381
20776
|
updater?.start();
|
|
20382
|
-
|
|
20383
|
-
});
|
|
20777
|
+
resolve24(info);
|
|
20778
|
+
}, reject);
|
|
20384
20779
|
});
|
|
20385
20780
|
return {
|
|
20386
20781
|
store,
|
|
@@ -20516,7 +20911,7 @@ async function runWizard(rl2, store, opts) {
|
|
|
20516
20911
|
}
|
|
20517
20912
|
async function askHidden(rl2, prompt) {
|
|
20518
20913
|
if (!process.stdin.isTTY) return (await rl2.question(prompt)).trim();
|
|
20519
|
-
return new Promise((
|
|
20914
|
+
return new Promise((resolve24) => {
|
|
20520
20915
|
const saved = process.stdin.listeners("data");
|
|
20521
20916
|
process.stdin.removeAllListeners("data");
|
|
20522
20917
|
cliWrite(prompt);
|
|
@@ -20538,13 +20933,13 @@ async function askHidden(rl2, prompt) {
|
|
|
20538
20933
|
if (ch === "\r" || ch === "\n") {
|
|
20539
20934
|
cleanup();
|
|
20540
20935
|
cliWrite("\n");
|
|
20541
|
-
|
|
20936
|
+
resolve24(buf);
|
|
20542
20937
|
return;
|
|
20543
20938
|
}
|
|
20544
20939
|
if (ch === "") {
|
|
20545
20940
|
cleanup();
|
|
20546
20941
|
cliWrite("\n");
|
|
20547
|
-
|
|
20942
|
+
resolve24("");
|
|
20548
20943
|
return;
|
|
20549
20944
|
}
|
|
20550
20945
|
if (ch === "\x7F" || ch === "\b") {
|
|
@@ -20733,7 +21128,7 @@ function updateSessionMetaFile(stateDir2, sessionId, patch) {
|
|
|
20733
21128
|
// src/cli/debug.ts
|
|
20734
21129
|
init_cjs_shims();
|
|
20735
21130
|
var fs33 = __toESM(require("fs"), 1);
|
|
20736
|
-
var
|
|
21131
|
+
var os10 = __toESM(require("os"), 1);
|
|
20737
21132
|
var path41 = __toESM(require("path"), 1);
|
|
20738
21133
|
var LOG_NAME = "zqagent-debug.log";
|
|
20739
21134
|
var TRUTHY = /^(1|true|yes|on)$/i;
|
|
@@ -20747,7 +21142,7 @@ function resolveLogFile() {
|
|
|
20747
21142
|
const explicit = process.env.ZQAGENT_DEBUG_LOG;
|
|
20748
21143
|
if (explicit) return path41.resolve(explicit);
|
|
20749
21144
|
const dir = process.env.ZQAGENT_DEBUG_DIR;
|
|
20750
|
-
return path41.join(dir ? path41.resolve(dir) :
|
|
21145
|
+
return path41.join(dir ? path41.resolve(dir) : os10.tmpdir(), LOG_NAME);
|
|
20751
21146
|
}
|
|
20752
21147
|
function enableDebug(argv = process.argv) {
|
|
20753
21148
|
if (enabled) return true;
|
|
@@ -21185,27 +21580,14 @@ var _exitHandler = null;
|
|
|
21185
21580
|
rl.on("SIGINT", () => {
|
|
21186
21581
|
_exitHandler?.();
|
|
21187
21582
|
});
|
|
21188
|
-
|
|
21189
|
-
const iface = rl;
|
|
21190
|
-
const orig = iface._ttyWrite;
|
|
21191
|
-
iface._ttyWrite = function(s, key) {
|
|
21192
|
-
const k = key;
|
|
21193
|
-
if (k && (k.name === "up" || k.name === "down") && !k.ctrl && !k.meta && !k.shift) {
|
|
21194
|
-
if (iface.cursor > 0) {
|
|
21195
|
-
iface._moveCursor(-iface.cursor);
|
|
21196
|
-
}
|
|
21197
|
-
}
|
|
21198
|
-
orig.call(rl, s, key);
|
|
21199
|
-
};
|
|
21200
|
-
}
|
|
21201
|
-
patchReadlineHistoryNav();
|
|
21583
|
+
patchReadlineHistoryNav(rl);
|
|
21202
21584
|
dlog("init", "\u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210\uFF08readline / \u8F93\u5165\u8DEF\u7531 / \u5386\u53F2\u5BFC\u822A\u5C31\u7EEA\uFF09");
|
|
21203
21585
|
function question(prompt) {
|
|
21204
21586
|
return inputRouter.ask(prompt);
|
|
21205
21587
|
}
|
|
21206
21588
|
function readPassword(prompt) {
|
|
21207
21589
|
if (!process.stdin.isTTY) return question(prompt);
|
|
21208
|
-
return new Promise((
|
|
21590
|
+
return new Promise((resolve24) => {
|
|
21209
21591
|
const savedDataListeners = process.stdin.listeners("data");
|
|
21210
21592
|
process.stdin.removeAllListeners("data");
|
|
21211
21593
|
cliWrite(prompt);
|
|
@@ -21221,13 +21603,13 @@ function readPassword(prompt) {
|
|
|
21221
21603
|
if (ch === "\r" || ch === "\n") {
|
|
21222
21604
|
cleanup();
|
|
21223
21605
|
cliWrite("\n");
|
|
21224
|
-
|
|
21606
|
+
resolve24(buf);
|
|
21225
21607
|
return;
|
|
21226
21608
|
}
|
|
21227
21609
|
if (ch === "") {
|
|
21228
21610
|
cleanup();
|
|
21229
21611
|
cliWrite("\n");
|
|
21230
|
-
|
|
21612
|
+
resolve24("");
|
|
21231
21613
|
return;
|
|
21232
21614
|
}
|
|
21233
21615
|
if (ch === "\x7F" || ch === "\b") {
|
|
@@ -21662,7 +22044,7 @@ async function offerTerminalSetup(engine, canUseAgent) {
|
|
|
21662
22044
|
}
|
|
21663
22045
|
var KNOWN_SUBCOMMANDS = /* @__PURE__ */ new Set(["link", "serve", "update"]);
|
|
21664
22046
|
function cliVersion() {
|
|
21665
|
-
const env3 = "0.2.
|
|
22047
|
+
const env3 = "0.2.11"?.trim();
|
|
21666
22048
|
if (env3) return env3;
|
|
21667
22049
|
try {
|
|
21668
22050
|
const req2 = (0, import_module.createRequire)(importMetaUrl);
|