@zqagent/core 0.2.11 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.cjs +3665 -3178
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +3662 -3175
- package/dist/cli/index.js.map +1 -1
- package/dist/server/index.cjs +308 -117
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js +308 -117
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -2180,12 +2180,12 @@ var MUTATING_TOOLS = /* @__PURE__ */ new Set([
|
|
|
2180
2180
|
]);
|
|
2181
2181
|
function parseReadFileSpan(content) {
|
|
2182
2182
|
const body = content.replace(/^\[tool output truncated:[^\n]*\]\n\n/, "");
|
|
2183
|
-
let
|
|
2183
|
+
let path37;
|
|
2184
2184
|
let start;
|
|
2185
2185
|
let end;
|
|
2186
2186
|
try {
|
|
2187
2187
|
const obj = JSON.parse(body);
|
|
2188
|
-
|
|
2188
|
+
path37 = obj.path;
|
|
2189
2189
|
start = obj.start_line;
|
|
2190
2190
|
end = obj.end_line;
|
|
2191
2191
|
} catch {
|
|
@@ -2194,14 +2194,14 @@ function parseReadFileSpan(content) {
|
|
|
2194
2194
|
const m = new RegExp(`"${key}"\\s*:\\s*(\\d+)`).exec(body);
|
|
2195
2195
|
return m ? Number(m[1]) : void 0;
|
|
2196
2196
|
};
|
|
2197
|
-
|
|
2197
|
+
path37 = str2("path");
|
|
2198
2198
|
start = num2("start_line");
|
|
2199
2199
|
end = num2("end_line");
|
|
2200
2200
|
}
|
|
2201
|
-
if (typeof
|
|
2201
|
+
if (typeof path37 !== "string" || !path37) return null;
|
|
2202
2202
|
if (typeof start !== "number" || typeof end !== "number") return null;
|
|
2203
2203
|
if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
|
|
2204
|
-
return { path:
|
|
2204
|
+
return { path: path37, start, end };
|
|
2205
2205
|
}
|
|
2206
2206
|
function addSpan(spans, start, end) {
|
|
2207
2207
|
spans.push([start, end]);
|
|
@@ -3818,9 +3818,9 @@ var TurnEngine = class _TurnEngine {
|
|
|
3818
3818
|
return;
|
|
3819
3819
|
}
|
|
3820
3820
|
if (result && typeof result === "object") {
|
|
3821
|
-
const
|
|
3822
|
-
if (
|
|
3823
|
-
this._producedFiles.push(
|
|
3821
|
+
const path37 = result.path;
|
|
3822
|
+
if (path37) {
|
|
3823
|
+
this._producedFiles.push(path37);
|
|
3824
3824
|
return;
|
|
3825
3825
|
}
|
|
3826
3826
|
const changed = result.changed_files;
|
|
@@ -5147,10 +5147,10 @@ var OpenAIProvider = class {
|
|
|
5147
5147
|
let timer;
|
|
5148
5148
|
try {
|
|
5149
5149
|
for (; ; ) {
|
|
5150
|
-
const idle = new Promise((
|
|
5150
|
+
const idle = new Promise((resolve20) => {
|
|
5151
5151
|
timer = setTimeout(() => {
|
|
5152
5152
|
onIdle();
|
|
5153
|
-
|
|
5153
|
+
resolve20({ timedOut: true });
|
|
5154
5154
|
}, idleMs);
|
|
5155
5155
|
});
|
|
5156
5156
|
const next = iter.next();
|
|
@@ -5778,12 +5778,12 @@ function makeSink(maxBuffer) {
|
|
|
5778
5778
|
};
|
|
5779
5779
|
}
|
|
5780
5780
|
function execAsync(file, argv, opts = {}) {
|
|
5781
|
-
return new Promise((
|
|
5781
|
+
return new Promise((resolve20) => {
|
|
5782
5782
|
const maxBuffer = opts.maxBuffer ?? DEFAULT_MAX_BUFFER;
|
|
5783
5783
|
const out = makeSink(maxBuffer);
|
|
5784
5784
|
const err = makeSink(maxBuffer);
|
|
5785
5785
|
if (opts.signal?.aborted) {
|
|
5786
|
-
|
|
5786
|
+
resolve20({
|
|
5787
5787
|
status: null,
|
|
5788
5788
|
stdout: Buffer.alloc(0),
|
|
5789
5789
|
stderr: Buffer.alloc(0),
|
|
@@ -5804,7 +5804,7 @@ function execAsync(file, argv, opts = {}) {
|
|
|
5804
5804
|
windowsHide: true
|
|
5805
5805
|
});
|
|
5806
5806
|
} catch (e) {
|
|
5807
|
-
|
|
5807
|
+
resolve20({
|
|
5808
5808
|
status: null,
|
|
5809
5809
|
stdout: Buffer.alloc(0),
|
|
5810
5810
|
stderr: Buffer.alloc(0),
|
|
@@ -5841,7 +5841,7 @@ function execAsync(file, argv, opts = {}) {
|
|
|
5841
5841
|
};
|
|
5842
5842
|
if (aborted) result.aborted = true;
|
|
5843
5843
|
if (spawnError) result.error = spawnError;
|
|
5844
|
-
|
|
5844
|
+
resolve20(result);
|
|
5845
5845
|
};
|
|
5846
5846
|
const killAndSettle = () => {
|
|
5847
5847
|
killTree(child.pid);
|
|
@@ -7736,18 +7736,18 @@ function makeApplyPatch(workspace) {
|
|
|
7736
7736
|
return { changed_files: changedFiles, added_files: addedFiles, deleted_files: deletedFiles, file_count: fileCount };
|
|
7737
7737
|
};
|
|
7738
7738
|
}
|
|
7739
|
-
function applyPatchHunks(oldLines, chunks,
|
|
7739
|
+
function applyPatchHunks(oldLines, chunks, path37) {
|
|
7740
7740
|
let newLines = [...oldLines];
|
|
7741
7741
|
let cursor = 0;
|
|
7742
7742
|
for (const chunk of chunks) {
|
|
7743
7743
|
const oldBlock = chunk.filter((l) => l[0] === " " || l[0] === "-").map((l) => l.slice(1));
|
|
7744
7744
|
const newBlock = chunk.filter((l) => l[0] === " " || l[0] === "+").map((l) => l.slice(1));
|
|
7745
7745
|
if (!oldBlock.length) {
|
|
7746
|
-
throw new Error(`\u8865\u4E01 hunk \u5FC5\u987B\u5305\u542B\u4E0A\u4E0B\u6587\u6216\u5220\u9664\u884C: ${
|
|
7746
|
+
throw new Error(`\u8865\u4E01 hunk \u5FC5\u987B\u5305\u542B\u4E0A\u4E0B\u6587\u6216\u5220\u9664\u884C: ${path37}`);
|
|
7747
7747
|
}
|
|
7748
7748
|
const matchStart = findBlockMatch(newLines, oldBlock, cursor);
|
|
7749
7749
|
if (matchStart === -1) {
|
|
7750
|
-
throw new Error(`\u8865\u4E01\u4E0A\u4E0B\u6587\u4E0D\u5339\u914D: ${
|
|
7750
|
+
throw new Error(`\u8865\u4E01\u4E0A\u4E0B\u6587\u4E0D\u5339\u914D: ${path37}`);
|
|
7751
7751
|
}
|
|
7752
7752
|
const matchEnd = matchStart + oldBlock.length;
|
|
7753
7753
|
newLines.splice(matchStart, oldBlock.length, ...newBlock);
|
|
@@ -9840,11 +9840,11 @@ function isAffirmative(answer) {
|
|
|
9840
9840
|
return /^(yes|approve|同意|批准|允许|确定|可以|好的|确认)/.test(a);
|
|
9841
9841
|
}
|
|
9842
9842
|
function defer() {
|
|
9843
|
-
let
|
|
9843
|
+
let resolve20;
|
|
9844
9844
|
const promise = new Promise((r) => {
|
|
9845
|
-
|
|
9845
|
+
resolve20 = r;
|
|
9846
9846
|
});
|
|
9847
|
-
return { promise, resolve:
|
|
9847
|
+
return { promise, resolve: resolve20 };
|
|
9848
9848
|
}
|
|
9849
9849
|
var SessionManager = class {
|
|
9850
9850
|
constructor(store, approvalTimeoutMs = APPROVAL_TIMEOUT_MS, opts = {}) {
|
|
@@ -10416,11 +10416,11 @@ data: ${JSON.stringify({ sessionId, seq: entry.seq, ts: entry.ts, data: entry.da
|
|
|
10416
10416
|
status: "pending",
|
|
10417
10417
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10418
10418
|
};
|
|
10419
|
-
const { promise, resolve:
|
|
10419
|
+
const { promise, resolve: resolve20 } = defer();
|
|
10420
10420
|
const timer = setTimeout(() => {
|
|
10421
10421
|
this._recycleApproval(rt, id);
|
|
10422
10422
|
}, this.approvalTimeoutMs);
|
|
10423
|
-
rt.pendingApprovals.set(id, { promise, resolve:
|
|
10423
|
+
rt.pendingApprovals.set(id, { promise, resolve: resolve20, record, timer });
|
|
10424
10424
|
rt.approvals.set(id, record);
|
|
10425
10425
|
this._setStatus(rt, "waiting_approval");
|
|
10426
10426
|
this._persist(rt);
|
|
@@ -10498,11 +10498,11 @@ data: ${JSON.stringify({ sessionId, seq: entry.seq, ts: entry.ts, data: entry.da
|
|
|
10498
10498
|
status: "pending",
|
|
10499
10499
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10500
10500
|
};
|
|
10501
|
-
const { promise, resolve:
|
|
10501
|
+
const { promise, resolve: resolve20 } = defer();
|
|
10502
10502
|
const timer = setTimeout(() => {
|
|
10503
10503
|
this._recycleQuestion(rt, qid);
|
|
10504
10504
|
}, this.approvalTimeoutMs);
|
|
10505
|
-
rt.pendingQuestions.set(qid, { promise, resolve:
|
|
10505
|
+
rt.pendingQuestions.set(qid, { promise, resolve: resolve20, record, timer });
|
|
10506
10506
|
rt.questions.set(qid, record);
|
|
10507
10507
|
this._setStatus(rt, "waiting_question");
|
|
10508
10508
|
this._persist(rt);
|
|
@@ -10811,7 +10811,7 @@ data: ${JSON.stringify(entry.data)}
|
|
|
10811
10811
|
if (rt.mcpReady) {
|
|
10812
10812
|
await Promise.race([
|
|
10813
10813
|
rt.mcpReady,
|
|
10814
|
-
new Promise((
|
|
10814
|
+
new Promise((resolve20) => setTimeout(resolve20, 15e3))
|
|
10815
10815
|
]).catch(() => void 0);
|
|
10816
10816
|
}
|
|
10817
10817
|
for await (const event of gen) {
|
|
@@ -11396,7 +11396,7 @@ function buildNodeInfo(store, opts) {
|
|
|
11396
11396
|
nodeId: opts.nodeId ?? ensureNodeId(store),
|
|
11397
11397
|
platform: process.platform,
|
|
11398
11398
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
11399
|
-
version: "0.2.
|
|
11399
|
+
version: "0.2.15",
|
|
11400
11400
|
admin: opts.admin,
|
|
11401
11401
|
projects: opts.projects
|
|
11402
11402
|
};
|
|
@@ -11480,8 +11480,8 @@ function hubProxyEnabled(host) {
|
|
|
11480
11480
|
const h = (host ?? "127.0.0.1").trim();
|
|
11481
11481
|
return h === "127.0.0.1" || h === "localhost" || h === "::1";
|
|
11482
11482
|
}
|
|
11483
|
-
function isHubProxyPath(
|
|
11484
|
-
return
|
|
11483
|
+
function isHubProxyPath(path37) {
|
|
11484
|
+
return path37.startsWith(HUB_PROXY_PREFIX);
|
|
11485
11485
|
}
|
|
11486
11486
|
function decodeTarget(enc) {
|
|
11487
11487
|
try {
|
|
@@ -12389,7 +12389,7 @@ function buildNodeHost(store, manager, diskPath) {
|
|
|
12389
12389
|
arch: process.arch,
|
|
12390
12390
|
release: os6.release(),
|
|
12391
12391
|
uptimeSec: Math.round(os6.uptime()),
|
|
12392
|
-
version: "0.2.
|
|
12392
|
+
version: "0.2.15",
|
|
12393
12393
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
12394
12394
|
cpu: {
|
|
12395
12395
|
count: cpus2.length,
|
|
@@ -12433,7 +12433,7 @@ function saveNotifications(tenant, secretBox, notifications) {
|
|
|
12433
12433
|
var API_PREFIX = "/api/v1";
|
|
12434
12434
|
var MAX_BODY_BYTES = 10 * 1024 * 1024;
|
|
12435
12435
|
function readBody(req2) {
|
|
12436
|
-
return new Promise((
|
|
12436
|
+
return new Promise((resolve20, reject) => {
|
|
12437
12437
|
const chunks = [];
|
|
12438
12438
|
let size = 0;
|
|
12439
12439
|
req2.on("data", (c) => {
|
|
@@ -12446,9 +12446,9 @@ function readBody(req2) {
|
|
|
12446
12446
|
chunks.push(c);
|
|
12447
12447
|
});
|
|
12448
12448
|
req2.on("end", () => {
|
|
12449
|
-
if (chunks.length === 0) return
|
|
12449
|
+
if (chunks.length === 0) return resolve20(void 0);
|
|
12450
12450
|
try {
|
|
12451
|
-
|
|
12451
|
+
resolve20(JSON.parse(Buffer.concat(chunks).toString("utf-8")));
|
|
12452
12452
|
} catch {
|
|
12453
12453
|
reject(new ApiError(400, "bad_request", "\u8BF7\u6C42\u4F53\u4E0D\u662F\u5408\u6CD5 JSON"));
|
|
12454
12454
|
}
|
|
@@ -12759,7 +12759,25 @@ function createApp(store, manager, opts = {}) {
|
|
|
12759
12759
|
ok(res, opts.fleet.status());
|
|
12760
12760
|
}
|
|
12761
12761
|
},
|
|
12762
|
-
//
|
|
12762
|
+
// 修改本机节点显示名:写本地配置并立即上报;已接入 Hub 时同步 Hub 记录。
|
|
12763
|
+
// `zqagent rename` 在有 server 在跑时走这里(热生效,免重启)。
|
|
12764
|
+
{
|
|
12765
|
+
method: "POST",
|
|
12766
|
+
pattern: ["fleet", "label"],
|
|
12767
|
+
adminOnly: true,
|
|
12768
|
+
fn: async (_req, res, { body }) => {
|
|
12769
|
+
if (!opts.fleet) {
|
|
12770
|
+
throw new ApiError(503, "fleet_disabled", "\u8282\u70B9\u7BA1\u7406\u63A7\u5236\u5668\u672A\u542F\u7528");
|
|
12771
|
+
}
|
|
12772
|
+
const raw = body ?? {};
|
|
12773
|
+
const label2 = typeof raw.label === "string" ? raw.label.trim() : "";
|
|
12774
|
+
if (!label2) {
|
|
12775
|
+
throw new ApiError(400, "bad_request", "label \u4E0D\u80FD\u4E3A\u7A7A");
|
|
12776
|
+
}
|
|
12777
|
+
ok(res, await opts.fleet.rename(label2));
|
|
12778
|
+
}
|
|
12779
|
+
},
|
|
12780
|
+
// 运行时热接入:凭一次性注册码或 Hub 账号接入(落盘 fleet.json + 立即连接,免重启)
|
|
12763
12781
|
{
|
|
12764
12782
|
method: "POST",
|
|
12765
12783
|
pattern: ["fleet", "enroll"],
|
|
@@ -12771,15 +12789,42 @@ function createApp(store, manager, opts = {}) {
|
|
|
12771
12789
|
const raw = body ?? {};
|
|
12772
12790
|
const hubUrl2 = String(raw.hubUrl ?? "").trim().replace(/\/$/, "");
|
|
12773
12791
|
const code = String(raw.code ?? "").trim();
|
|
12774
|
-
|
|
12775
|
-
|
|
12792
|
+
const email = String(raw.email ?? "").trim();
|
|
12793
|
+
const phone = String(raw.phone ?? "").trim();
|
|
12794
|
+
const password = String(raw.password ?? "");
|
|
12795
|
+
const smsCode = String(raw.smsCode ?? "").trim();
|
|
12796
|
+
const hasAccount = Boolean(email || phone);
|
|
12797
|
+
if (!hubUrl2) {
|
|
12798
|
+
throw new ApiError(400, "bad_request", "hubUrl \u5FC5\u586B");
|
|
12799
|
+
}
|
|
12800
|
+
if (code && hasAccount) {
|
|
12801
|
+
throw new ApiError(400, "bad_request", "code \u4E0E\u8D26\u53F7\u51ED\u636E\u53EA\u80FD\u4E8C\u9009\u4E00");
|
|
12802
|
+
}
|
|
12803
|
+
if (!code && !hasAccount) {
|
|
12804
|
+
throw new ApiError(400, "bad_request", "\u9700\u8981 code\uFF0C\u6216 email/phone + password/smsCode");
|
|
12805
|
+
}
|
|
12806
|
+
if (hasAccount && !password && !smsCode) {
|
|
12807
|
+
throw new ApiError(400, "bad_request", "\u8D26\u53F7\u63A5\u5165\u9700\u8981 password \u6216 smsCode");
|
|
12776
12808
|
}
|
|
12777
12809
|
const label2 = typeof raw.label === "string" ? raw.label.trim() : void 0;
|
|
12778
12810
|
try {
|
|
12779
|
-
ok(
|
|
12811
|
+
ok(
|
|
12812
|
+
res,
|
|
12813
|
+
await opts.fleet.enroll({
|
|
12814
|
+
hubUrl: hubUrl2,
|
|
12815
|
+
code: code || void 0,
|
|
12816
|
+
account: hasAccount ? {
|
|
12817
|
+
email: email || void 0,
|
|
12818
|
+
phone: phone || void 0,
|
|
12819
|
+
password: password || void 0,
|
|
12820
|
+
smsCode: smsCode || void 0
|
|
12821
|
+
} : void 0,
|
|
12822
|
+
label: label2
|
|
12823
|
+
})
|
|
12824
|
+
);
|
|
12780
12825
|
} catch (e) {
|
|
12781
12826
|
const code2 = e.code;
|
|
12782
|
-
const status = code2 === "code_expired" ? 410 : code2 === "code_used" || code2 === "node_taken" ? 409 : code2 === "not_found" ? 404 : code2 === "plan_limit" || code2 === "subscription_required" ? 402 : 400;
|
|
12827
|
+
const status = code2 === "code_expired" ? 410 : code2 === "unauthorized" ? 401 : code2 === "account_disabled" ? 403 : code2 === "code_used" || code2 === "node_taken" ? 409 : code2 === "not_found" ? 404 : code2 === "plan_limit" || code2 === "subscription_required" ? 402 : 400;
|
|
12783
12828
|
const msg = e instanceof Error ? e.message : String(e);
|
|
12784
12829
|
throw new ApiError(
|
|
12785
12830
|
status,
|
|
@@ -13925,10 +13970,10 @@ function createApp(store, manager, opts = {}) {
|
|
|
13925
13970
|
function handle(req2, res) {
|
|
13926
13971
|
const startedAt = Date.now();
|
|
13927
13972
|
const url = new URL(req2.url ?? "/", "http://localhost");
|
|
13928
|
-
const
|
|
13973
|
+
const path37 = url.pathname;
|
|
13929
13974
|
const method = req2.method ?? "GET";
|
|
13930
13975
|
console.log(
|
|
13931
|
-
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} \u2192 ${method} ${
|
|
13976
|
+
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} \u2192 ${method} ${path37}${url.search}`
|
|
13932
13977
|
);
|
|
13933
13978
|
let tenantId = null;
|
|
13934
13979
|
let logged = false;
|
|
@@ -13936,7 +13981,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
13936
13981
|
if (logged) return;
|
|
13937
13982
|
logged = true;
|
|
13938
13983
|
console.log(
|
|
13939
|
-
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} \u2190 ${method} ${
|
|
13984
|
+
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} \u2190 ${method} ${path37} ${extra} (${Date.now() - startedAt}ms) tenant=${tenantId ?? "-"}`
|
|
13940
13985
|
);
|
|
13941
13986
|
};
|
|
13942
13987
|
res.on("finish", () => logDone(`HTTP ${res.statusCode}`));
|
|
@@ -13947,16 +13992,16 @@ function createApp(store, manager, opts = {}) {
|
|
|
13947
13992
|
res.end();
|
|
13948
13993
|
return;
|
|
13949
13994
|
}
|
|
13950
|
-
if (req2.method === "GET" &&
|
|
13995
|
+
if (req2.method === "GET" && path37 === "/healthz") {
|
|
13951
13996
|
json(res, 200, {
|
|
13952
13997
|
status: "ok",
|
|
13953
13998
|
// 版本让运维/探针能确认线上跑的是哪个构建(更新与回滚据此判断)
|
|
13954
|
-
version: "0.2.
|
|
13999
|
+
version: "0.2.15",
|
|
13955
14000
|
features: { mcp: hasServerMcpConfig() }
|
|
13956
14001
|
});
|
|
13957
14002
|
return;
|
|
13958
14003
|
}
|
|
13959
|
-
if (hubProxyEnabled(opts.host) && isHubProxyPath(
|
|
14004
|
+
if (hubProxyEnabled(opts.host) && isHubProxyPath(path37)) {
|
|
13960
14005
|
void handleHubProxy(req2, res).catch(() => {
|
|
13961
14006
|
if (!res.headersSent) {
|
|
13962
14007
|
res.writeHead(502, { "Content-Type": "application/json; charset=utf-8" });
|
|
@@ -13967,11 +14012,11 @@ function createApp(store, manager, opts = {}) {
|
|
|
13967
14012
|
});
|
|
13968
14013
|
return;
|
|
13969
14014
|
}
|
|
13970
|
-
if (!
|
|
14015
|
+
if (!path37.startsWith(API_PREFIX)) {
|
|
13971
14016
|
json(res, 404, { error: { code: "not_found", message: "\u672A\u77E5\u8DEF\u5F84" } });
|
|
13972
14017
|
return;
|
|
13973
14018
|
}
|
|
13974
|
-
const segs =
|
|
14019
|
+
const segs = path37.slice(API_PREFIX.length).split("/").filter(Boolean);
|
|
13975
14020
|
const apiKey = extractApiKey(req2);
|
|
13976
14021
|
if (!apiKey) {
|
|
13977
14022
|
json(res, 401, {
|
|
@@ -14036,7 +14081,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
14036
14081
|
).catch((err) => {
|
|
14037
14082
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14038
14083
|
console.log(
|
|
14039
|
-
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} ! ${method} ${
|
|
14084
|
+
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} ! ${method} ${path37} ERROR: ${msg}`
|
|
14040
14085
|
);
|
|
14041
14086
|
error(res, err);
|
|
14042
14087
|
});
|
|
@@ -14067,8 +14112,8 @@ async function cachedFetchModels(baseURL, apiKey) {
|
|
|
14067
14112
|
try {
|
|
14068
14113
|
result = await Promise.race([
|
|
14069
14114
|
fetchModels(baseURL, apiKey),
|
|
14070
|
-
new Promise((
|
|
14071
|
-
const t = setTimeout(() =>
|
|
14115
|
+
new Promise((resolve20) => {
|
|
14116
|
+
const t = setTimeout(() => resolve20(null), MODEL_FETCH_TIMEOUT_MS);
|
|
14072
14117
|
t.unref?.();
|
|
14073
14118
|
})
|
|
14074
14119
|
]);
|
|
@@ -14093,8 +14138,8 @@ async function cachedFetchModelsEnriched(baseURL, apiKey, preferred) {
|
|
|
14093
14138
|
if (!target) return r;
|
|
14094
14139
|
const ctx = await Promise.race([
|
|
14095
14140
|
fetchModelContext(baseURL, apiKey, target),
|
|
14096
|
-
new Promise((
|
|
14097
|
-
const t = setTimeout(() =>
|
|
14141
|
+
new Promise((resolve20) => {
|
|
14142
|
+
const t = setTimeout(() => resolve20(void 0), MODEL_FETCH_TIMEOUT_MS);
|
|
14098
14143
|
t.unref?.();
|
|
14099
14144
|
})
|
|
14100
14145
|
]);
|
|
@@ -15288,13 +15333,13 @@ var EVENT_FLUSH_MAX_EVENTS = 60;
|
|
|
15288
15333
|
var EVENT_FLUSH_MAX_BYTES = 200 * 1024;
|
|
15289
15334
|
var LOOP_LAG_WARN_MS = 2e3;
|
|
15290
15335
|
function withTimeout(p, ms) {
|
|
15291
|
-
return new Promise((
|
|
15336
|
+
return new Promise((resolve20, reject) => {
|
|
15292
15337
|
const timer = setTimeout(() => reject(new Error(`\u5B50\u6307\u4EE4\u8D85\u65F6\uFF08${ms}ms\uFF09`)), ms);
|
|
15293
15338
|
timer.unref?.();
|
|
15294
15339
|
p.then(
|
|
15295
15340
|
(v) => {
|
|
15296
15341
|
clearTimeout(timer);
|
|
15297
|
-
|
|
15342
|
+
resolve20(v);
|
|
15298
15343
|
},
|
|
15299
15344
|
(e) => {
|
|
15300
15345
|
clearTimeout(timer);
|
|
@@ -15645,6 +15690,11 @@ var FleetNodeBridge = class {
|
|
|
15645
15690
|
refreshInfo() {
|
|
15646
15691
|
this._publishInfo();
|
|
15647
15692
|
}
|
|
15693
|
+
/** 本地改名后把 status(含 label)与 info 立即重发,控制台不必等下一次周期上报 */
|
|
15694
|
+
republishLabel() {
|
|
15695
|
+
this._send({ kind: "status", status: this._status(this.isConnected()) });
|
|
15696
|
+
this._publishInfo();
|
|
15697
|
+
}
|
|
15648
15698
|
// ===================== 内部 =====================
|
|
15649
15699
|
_status(online) {
|
|
15650
15700
|
return {
|
|
@@ -15654,7 +15704,7 @@ var FleetNodeBridge = class {
|
|
|
15654
15704
|
label: this.opts.deps.store.loadNodeLabel() ?? void 0,
|
|
15655
15705
|
platform: process.platform,
|
|
15656
15706
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
15657
|
-
version: "0.2.
|
|
15707
|
+
version: "0.2.15",
|
|
15658
15708
|
ip: primaryIp()
|
|
15659
15709
|
};
|
|
15660
15710
|
}
|
|
@@ -15673,7 +15723,23 @@ var FleetNodeBridge = class {
|
|
|
15673
15723
|
byDay: days
|
|
15674
15724
|
};
|
|
15675
15725
|
}
|
|
15726
|
+
/**
|
|
15727
|
+
* 上报 info(项目/会话快照)。
|
|
15728
|
+
*
|
|
15729
|
+
* 失败必须留痕:这是控制台「项目列表」的唯一数据源,静默失败会表现为
|
|
15730
|
+
* 「这台节点永远没有任何项目」,且只能靠网关 detail=null 才发现。
|
|
15731
|
+
* 同时用 try 包住,避免一次读盘异常中断 `_onUp` 后续的状态通知。
|
|
15732
|
+
*/
|
|
15676
15733
|
_publishInfo() {
|
|
15734
|
+
try {
|
|
15735
|
+
this._publishInfoNow();
|
|
15736
|
+
} catch (e) {
|
|
15737
|
+
console.warn(
|
|
15738
|
+
`[fleet] \u8282\u70B9 ${this.nodeId} \u4E0A\u62A5 info \u5931\u8D25: ${e instanceof Error ? e.message : String(e)}`
|
|
15739
|
+
);
|
|
15740
|
+
}
|
|
15741
|
+
}
|
|
15742
|
+
_publishInfoNow() {
|
|
15677
15743
|
const totals = { projects: 0, sessions: 0, running: 0, waiting: 0 };
|
|
15678
15744
|
const sessions = [];
|
|
15679
15745
|
const projects = allProjectSummaries(this.opts.deps.store).map((p) => {
|
|
@@ -15700,7 +15766,15 @@ var FleetNodeBridge = class {
|
|
|
15700
15766
|
totals.sessions += p.sessionCount;
|
|
15701
15767
|
totals.running += running;
|
|
15702
15768
|
totals.waiting += waiting;
|
|
15703
|
-
return {
|
|
15769
|
+
return {
|
|
15770
|
+
id: p.id,
|
|
15771
|
+
name: p.name,
|
|
15772
|
+
sessionCount: p.sessionCount,
|
|
15773
|
+
running,
|
|
15774
|
+
waiting,
|
|
15775
|
+
// 控制台项目列表要展示工作目录(Hub 落盘快照后即可离线查看)
|
|
15776
|
+
workspaceRoot: p.workspaceRoot ?? null
|
|
15777
|
+
};
|
|
15704
15778
|
});
|
|
15705
15779
|
this._send({
|
|
15706
15780
|
kind: "info",
|
|
@@ -15709,7 +15783,7 @@ var FleetNodeBridge = class {
|
|
|
15709
15783
|
label: this.opts.deps.store.loadNodeLabel() ?? void 0,
|
|
15710
15784
|
platform: process.platform,
|
|
15711
15785
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
15712
|
-
version: "0.2.
|
|
15786
|
+
version: "0.2.15",
|
|
15713
15787
|
ip: primaryIp(),
|
|
15714
15788
|
projects,
|
|
15715
15789
|
totals,
|
|
@@ -15919,6 +15993,14 @@ function resolveFleetConfig(store) {
|
|
|
15919
15993
|
return fleetConfigFromEnv(store);
|
|
15920
15994
|
}
|
|
15921
15995
|
|
|
15996
|
+
// src/node-name.ts
|
|
15997
|
+
init_esm_shims();
|
|
15998
|
+
import * as os8 from "os";
|
|
15999
|
+
function defaultNodeLabel() {
|
|
16000
|
+
const name = os8.hostname().trim();
|
|
16001
|
+
return name || "zqagent-node";
|
|
16002
|
+
}
|
|
16003
|
+
|
|
15922
16004
|
// src/server/notify/index.ts
|
|
15923
16005
|
init_esm_shims();
|
|
15924
16006
|
|
|
@@ -17124,13 +17206,13 @@ var baseUrlResolver = null;
|
|
|
17124
17206
|
function resolveBase(baseUrl) {
|
|
17125
17207
|
return baseUrlResolver ? baseUrlResolver(baseUrl) : baseUrl;
|
|
17126
17208
|
}
|
|
17127
|
-
async function req(baseUrl, token,
|
|
17209
|
+
async function req(baseUrl, token, path37, init = {}) {
|
|
17128
17210
|
const headers = {
|
|
17129
17211
|
...init.body ? { "Content-Type": "application/json" } : {},
|
|
17130
17212
|
...init.headers ?? {}
|
|
17131
17213
|
};
|
|
17132
17214
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
17133
|
-
const res = await fetch(`${resolveBase(baseUrl).replace(/\/$/, "")}${
|
|
17215
|
+
const res = await fetch(`${resolveBase(baseUrl).replace(/\/$/, "")}${path37}`, {
|
|
17134
17216
|
...init,
|
|
17135
17217
|
headers
|
|
17136
17218
|
});
|
|
@@ -17169,6 +17251,12 @@ async function hubEnrollByAccount(baseUrl, input) {
|
|
|
17169
17251
|
});
|
|
17170
17252
|
return { hubUrl: baseUrl.replace(/\/$/, ""), ...data };
|
|
17171
17253
|
}
|
|
17254
|
+
async function hubUpdateNodeLabelSelf(baseUrl, fleetToken, input) {
|
|
17255
|
+
return await req(baseUrl, fleetToken, "/api/hub/nodes/self/label", {
|
|
17256
|
+
method: "POST",
|
|
17257
|
+
body: JSON.stringify(input)
|
|
17258
|
+
});
|
|
17259
|
+
}
|
|
17172
17260
|
|
|
17173
17261
|
// src/update/controller.ts
|
|
17174
17262
|
init_esm_shims();
|
|
@@ -17428,12 +17516,12 @@ function selfCheck(binPath, expectedVersion) {
|
|
|
17428
17516
|
// src/update/platform.ts
|
|
17429
17517
|
init_esm_shims();
|
|
17430
17518
|
import * as fs25 from "fs";
|
|
17431
|
-
import * as
|
|
17519
|
+
import * as os9 from "os";
|
|
17432
17520
|
import * as path30 from "path";
|
|
17433
17521
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
17434
17522
|
import { createRequire as createRequire3 } from "module";
|
|
17435
17523
|
function currentVersion() {
|
|
17436
|
-
const injected = "0.2.
|
|
17524
|
+
const injected = "0.2.15"?.trim();
|
|
17437
17525
|
if (injected) return injected;
|
|
17438
17526
|
try {
|
|
17439
17527
|
const req2 = createRequire3(import.meta.url);
|
|
@@ -17471,7 +17559,7 @@ function launchdPlistPath() {
|
|
|
17471
17559
|
const label2 = launchdLabel();
|
|
17472
17560
|
const uid = typeof process.getuid === "function" ? process.getuid() : -1;
|
|
17473
17561
|
if (uid === 0) return `/Library/LaunchDaemons/${label2}.plist`;
|
|
17474
|
-
return path30.join(
|
|
17562
|
+
return path30.join(os9.homedir(), "Library", "LaunchAgents", `${label2}.plist`);
|
|
17475
17563
|
}
|
|
17476
17564
|
function serviceManagerFromLaunchctl(output, pid, execPath, sea = true) {
|
|
17477
17565
|
const pidMatch = /^\s*pid = (\d+)\s*$/m.exec(output);
|
|
@@ -17960,11 +18048,11 @@ var UpdateController = class {
|
|
|
17960
18048
|
const minUptime = num("ZQAGENT_UPDATE_MIN_UPTIME_MS", 10 * 60 * 1e3);
|
|
17961
18049
|
const idleMs = num("ZQAGENT_UPDATE_IDLE_MS", 60 * 1e3);
|
|
17962
18050
|
let idleSince = null;
|
|
17963
|
-
return new Promise((
|
|
18051
|
+
return new Promise((resolve20) => {
|
|
17964
18052
|
const timer = setInterval(() => {
|
|
17965
18053
|
if (this.stopped) {
|
|
17966
18054
|
clearInterval(timer);
|
|
17967
|
-
|
|
18055
|
+
resolve20(false);
|
|
17968
18056
|
return;
|
|
17969
18057
|
}
|
|
17970
18058
|
if (Date.now() - this.startedAt < minUptime || !this.opts.isIdle()) {
|
|
@@ -17974,7 +18062,7 @@ var UpdateController = class {
|
|
|
17974
18062
|
idleSince ??= Date.now();
|
|
17975
18063
|
if (Date.now() - idleSince >= idleMs) {
|
|
17976
18064
|
clearInterval(timer);
|
|
17977
|
-
|
|
18065
|
+
resolve20(true);
|
|
17978
18066
|
}
|
|
17979
18067
|
}, 1e3);
|
|
17980
18068
|
timer.unref();
|
|
@@ -18157,7 +18245,7 @@ function exitWhenOrphaned() {
|
|
|
18157
18245
|
}
|
|
18158
18246
|
var PORT_FALLBACK_LIMIT = 20;
|
|
18159
18247
|
function listenWithPortFallback(server, startPort, host, dataDir, limit = PORT_FALLBACK_LIMIT) {
|
|
18160
|
-
return new Promise((
|
|
18248
|
+
return new Promise((resolve20, reject) => {
|
|
18161
18249
|
let attempts = 0;
|
|
18162
18250
|
const tryListen = (port) => {
|
|
18163
18251
|
server.removeAllListeners("listening");
|
|
@@ -18189,7 +18277,7 @@ function listenWithPortFallback(server, startPort, host, dataDir, limit = PORT_F
|
|
|
18189
18277
|
`);
|
|
18190
18278
|
} catch {
|
|
18191
18279
|
}
|
|
18192
|
-
|
|
18280
|
+
resolve20(actualPort);
|
|
18193
18281
|
});
|
|
18194
18282
|
};
|
|
18195
18283
|
tryListen(startPort);
|
|
@@ -18267,7 +18355,7 @@ function startServer(opts = {}) {
|
|
|
18267
18355
|
hubUrl: fleetCred?.hubUrl,
|
|
18268
18356
|
gatewayUrl: fleetCred?.gatewayUrl ?? env2("FLEET_GATEWAY_URL"),
|
|
18269
18357
|
online: fleet?.isConnected() ?? false,
|
|
18270
|
-
label: fleetCred?.label,
|
|
18358
|
+
label: fleetCred?.label ?? store.loadNodeLabel() ?? void 0,
|
|
18271
18359
|
lastError: fleet?.getLastError() ?? void 0,
|
|
18272
18360
|
reconnectCount: fleet?.getErrorCount() ?? 0
|
|
18273
18361
|
};
|
|
@@ -18276,20 +18364,53 @@ function startServer(opts = {}) {
|
|
|
18276
18364
|
status: fleetStatus,
|
|
18277
18365
|
async enroll(input) {
|
|
18278
18366
|
const nodeId = ensureNodeId(store);
|
|
18279
|
-
const
|
|
18367
|
+
const label2 = input.label?.trim() || defaultNodeLabel();
|
|
18368
|
+
const cred = input.account ? await hubEnrollByAccount(input.hubUrl, {
|
|
18369
|
+
email: input.account.email,
|
|
18370
|
+
phone: input.account.phone,
|
|
18371
|
+
password: input.account.password,
|
|
18372
|
+
code: input.account.smsCode,
|
|
18373
|
+
nodeId,
|
|
18374
|
+
label: label2
|
|
18375
|
+
}) : await hubEnrollByCode(input.hubUrl, {
|
|
18280
18376
|
code: input.code,
|
|
18281
18377
|
nodeId,
|
|
18282
|
-
label:
|
|
18378
|
+
label: label2
|
|
18283
18379
|
});
|
|
18284
18380
|
const full = {
|
|
18285
18381
|
...cred,
|
|
18286
|
-
label:
|
|
18382
|
+
label: label2,
|
|
18287
18383
|
enrolledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
18288
18384
|
};
|
|
18289
18385
|
store.saveFleetCredential(full);
|
|
18386
|
+
store.saveNodeLabel(label2);
|
|
18290
18387
|
connectFleet(full);
|
|
18291
18388
|
return fleetStatus();
|
|
18292
18389
|
},
|
|
18390
|
+
async rename(label2) {
|
|
18391
|
+
const name = label2.trim();
|
|
18392
|
+
store.saveNodeLabel(name);
|
|
18393
|
+
if (fleetCred) {
|
|
18394
|
+
fleetCred = { ...fleetCred, label: name };
|
|
18395
|
+
store.saveFleetCredential(fleetCred);
|
|
18396
|
+
}
|
|
18397
|
+
fleet?.republishLabel();
|
|
18398
|
+
let hubSynced = false;
|
|
18399
|
+
let hubError;
|
|
18400
|
+
const cred = fleetCred;
|
|
18401
|
+
if (cred?.hubUrl && cred.fleetToken) {
|
|
18402
|
+
try {
|
|
18403
|
+
await hubUpdateNodeLabelSelf(cred.hubUrl, cred.fleetToken, {
|
|
18404
|
+
nodeId: ensureNodeId(store),
|
|
18405
|
+
label: name
|
|
18406
|
+
});
|
|
18407
|
+
hubSynced = true;
|
|
18408
|
+
} catch (e) {
|
|
18409
|
+
hubError = e instanceof Error ? e.message : String(e);
|
|
18410
|
+
}
|
|
18411
|
+
}
|
|
18412
|
+
return { ...fleetStatus(), hubSynced, hubError };
|
|
18413
|
+
},
|
|
18293
18414
|
unlink() {
|
|
18294
18415
|
fleet?.close();
|
|
18295
18416
|
fleet = null;
|
|
@@ -18420,7 +18541,7 @@ function startServer(opts = {}) {
|
|
|
18420
18541
|
server.timeout = 0;
|
|
18421
18542
|
server.keepAliveTimeout = 65e3;
|
|
18422
18543
|
server.headersTimeout = 66e3;
|
|
18423
|
-
const ready = new Promise((
|
|
18544
|
+
const ready = new Promise((resolve20, reject) => {
|
|
18424
18545
|
listenWithPortFallback(server, port, host, dataDir).then((actualPort) => {
|
|
18425
18546
|
const info = {
|
|
18426
18547
|
host,
|
|
@@ -18437,7 +18558,7 @@ function startServer(opts = {}) {
|
|
|
18437
18558
|
printReady(info, qq);
|
|
18438
18559
|
}
|
|
18439
18560
|
updater?.start();
|
|
18440
|
-
|
|
18561
|
+
resolve20(info);
|
|
18441
18562
|
}, reject);
|
|
18442
18563
|
});
|
|
18443
18564
|
return {
|
|
@@ -18487,39 +18608,12 @@ function parseHubAnswer(answer, fallback) {
|
|
|
18487
18608
|
if (SKIP_ANSWERS.has(a.toLowerCase())) return null;
|
|
18488
18609
|
return (a || fallback).replace(/\/$/, "");
|
|
18489
18610
|
}
|
|
18490
|
-
function
|
|
18491
|
-
|
|
18492
|
-
}
|
|
18493
|
-
async function maybeAccountEnroll(opts = {}) {
|
|
18494
|
-
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
18495
|
-
let store;
|
|
18496
|
-
try {
|
|
18497
|
-
store = new Store(resolveDataDir(opts.dataDir));
|
|
18498
|
-
if (resolveFleetConfig(store)) return;
|
|
18499
|
-
} catch (e) {
|
|
18500
|
-
cliErr(`\u63A5\u5165\u68C0\u67E5\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
18501
|
-
return;
|
|
18502
|
-
}
|
|
18503
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
18504
|
-
try {
|
|
18505
|
-
await runWizard(rl, store, opts);
|
|
18506
|
-
} catch (e) {
|
|
18507
|
-
cliErr(`\u63A5\u5165\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
18508
|
-
cliLog(" \u53EF\u7A0D\u540E\u5728\u63A7\u5236\u53F0\u751F\u6210\u63A5\u5165\u7801\uFF0C\u518D\u6267\u884C\uFF1Azqagent link --hub <Hub\u5730\u5740> --code <\u63A5\u5165\u7801>");
|
|
18509
|
-
} finally {
|
|
18510
|
-
rl.close();
|
|
18511
|
-
}
|
|
18512
|
-
}
|
|
18513
|
-
async function runWizard(rl, store, opts) {
|
|
18514
|
-
cliLog("");
|
|
18515
|
-
cliLog("\u672C\u673A\u5C1A\u672A\u63A5\u5165 Hub\u3002\u53EF\u7528 Hub \u8D26\u53F7\u63A5\u5165\uFF08\u8282\u70B9\u9ED8\u8BA4\u8FDB\u5165\u300C\u672A\u5206\u7EC4\u300D\uFF09\uFF1B\u8F93\u5165 - \u8DF3\u8FC7\u4FDD\u6301\u7EAF\u672C\u5730\u3002");
|
|
18516
|
-
const fallback = resolveDefaultHub(opts.hubUrl);
|
|
18611
|
+
async function promptHubUrl(rl, hubUrl2) {
|
|
18612
|
+
const fallback = resolveDefaultHub(hubUrl2);
|
|
18517
18613
|
const answer = await rl.question(`Hub \u5730\u5740 [${fallback}]\uFF1A`);
|
|
18518
|
-
|
|
18519
|
-
|
|
18520
|
-
|
|
18521
|
-
return;
|
|
18522
|
-
}
|
|
18614
|
+
return parseHubAnswer(answer, fallback);
|
|
18615
|
+
}
|
|
18616
|
+
async function promptAccountLogin(rl, hubUrl2) {
|
|
18523
18617
|
cliLog("\u767B\u5F55\u65B9\u5F0F\uFF1A1) \u90AE\u7BB1 + \u5BC6\u7801 2) \u624B\u673A\u53F7 + \u5BC6\u7801 3) \u624B\u673A\u53F7 + \u77ED\u4FE1\u9A8C\u8BC1\u7801");
|
|
18524
18618
|
const mode = (await rl.question("\u8BF7\u9009\u62E9 [1]\uFF1A")).trim() || "1";
|
|
18525
18619
|
const input = {};
|
|
@@ -18528,53 +18622,107 @@ async function runWizard(rl, store, opts) {
|
|
|
18528
18622
|
input.password = await askHidden(rl, "\u5BC6\u7801\uFF1A");
|
|
18529
18623
|
if (!input.email || !input.password) {
|
|
18530
18624
|
cliErr("\u90AE\u7BB1\u4E0E\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u5DF2\u8DF3\u8FC7\u63A5\u5165\u3002");
|
|
18531
|
-
return;
|
|
18625
|
+
return null;
|
|
18532
18626
|
}
|
|
18533
18627
|
} else if (mode === "2") {
|
|
18534
18628
|
input.phone = (await rl.question("\u624B\u673A\u53F7\uFF1A")).trim();
|
|
18535
18629
|
input.password = await askHidden(rl, "\u5BC6\u7801\uFF1A");
|
|
18536
18630
|
if (!input.phone || !input.password) {
|
|
18537
18631
|
cliErr("\u624B\u673A\u53F7\u4E0E\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u5DF2\u8DF3\u8FC7\u63A5\u5165\u3002");
|
|
18538
|
-
return;
|
|
18632
|
+
return null;
|
|
18539
18633
|
}
|
|
18540
18634
|
} else if (mode === "3") {
|
|
18541
18635
|
input.phone = (await rl.question("\u624B\u673A\u53F7\uFF1A")).trim();
|
|
18542
18636
|
if (!input.phone) {
|
|
18543
18637
|
cliErr("\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u5DF2\u8DF3\u8FC7\u63A5\u5165\u3002");
|
|
18544
|
-
return;
|
|
18638
|
+
return null;
|
|
18545
18639
|
}
|
|
18546
18640
|
try {
|
|
18547
|
-
const sent = await hubSendSms(hubUrl2, {
|
|
18641
|
+
const sent = await hubSendSms(resolveDefaultHub(hubUrl2), {
|
|
18642
|
+
phone: input.phone,
|
|
18643
|
+
purpose: "login"
|
|
18644
|
+
});
|
|
18548
18645
|
if (sent.debugCode) cliLog(`\uFF08\u8C03\u8BD5\u6A21\u5F0F\u9A8C\u8BC1\u7801\uFF1A${sent.debugCode}\uFF09`);
|
|
18549
18646
|
else cliLog("\u9A8C\u8BC1\u7801\u5DF2\u53D1\u9001\uFF0C5 \u5206\u949F\u5185\u6709\u6548\u3002");
|
|
18550
18647
|
} catch (e) {
|
|
18551
18648
|
cliErr(`\u77ED\u4FE1\u9A8C\u8BC1\u7801\u53D1\u9001\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
18552
18649
|
cliLog(" \u53EF\u6539\u7528\u65B9\u5F0F 1/2\uFF08\u5BC6\u7801\u767B\u5F55\uFF09\uFF0C\u6216\u5728\u7F51\u9875\u7AEF\u751F\u6210\u63A5\u5165\u7801\u540E\u6267\u884C\uFF1A");
|
|
18553
18650
|
cliLog(" zqagent link --hub <Hub\u5730\u5740> --code <\u63A5\u5165\u7801>");
|
|
18554
|
-
return;
|
|
18651
|
+
return null;
|
|
18555
18652
|
}
|
|
18556
18653
|
input.code = (await rl.question("\u77ED\u4FE1\u9A8C\u8BC1\u7801\uFF1A")).trim();
|
|
18557
18654
|
if (!input.code) {
|
|
18558
18655
|
cliErr("\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u5DF2\u8DF3\u8FC7\u63A5\u5165\u3002");
|
|
18559
|
-
return;
|
|
18656
|
+
return null;
|
|
18560
18657
|
}
|
|
18561
18658
|
} else {
|
|
18562
18659
|
cliErr("\u672A\u77E5\u7684\u767B\u5F55\u65B9\u5F0F\uFF0C\u5DF2\u8DF3\u8FC7\u63A5\u5165\u3002");
|
|
18660
|
+
return null;
|
|
18661
|
+
}
|
|
18662
|
+
return input;
|
|
18663
|
+
}
|
|
18664
|
+
async function promptLinkAccount(rl, hubUrl2, opts = {}) {
|
|
18665
|
+
const fallback = resolveDefaultHub(hubUrl2);
|
|
18666
|
+
let resolved = fallback;
|
|
18667
|
+
if (opts.askHub !== false) {
|
|
18668
|
+
const answer = await promptHubUrl(rl, fallback);
|
|
18669
|
+
if (!answer) {
|
|
18670
|
+
cliLog("\u5DF2\u8DF3\u8FC7\u63A5\u5165\uFF1A\u8282\u70B9\u4FDD\u6301\u7EAF\u672C\u5730\u8FD0\u884C\u3002");
|
|
18671
|
+
return null;
|
|
18672
|
+
}
|
|
18673
|
+
resolved = answer;
|
|
18674
|
+
}
|
|
18675
|
+
const auth = await promptAccountLogin(rl, resolved);
|
|
18676
|
+
if (!auth) return null;
|
|
18677
|
+
return { hubUrl: resolved, auth };
|
|
18678
|
+
}
|
|
18679
|
+
function resolveDataDir(dataDir) {
|
|
18680
|
+
return path35.resolve(dataDir ?? process.env.DATA_DIR ?? DEFAULT_DATA_DIR);
|
|
18681
|
+
}
|
|
18682
|
+
async function maybeAccountEnroll(opts = {}) {
|
|
18683
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
18684
|
+
let store;
|
|
18685
|
+
try {
|
|
18686
|
+
store = new Store(resolveDataDir(opts.dataDir));
|
|
18687
|
+
if (resolveFleetConfig(store)) return;
|
|
18688
|
+
} catch (e) {
|
|
18689
|
+
cliErr(`\u63A5\u5165\u68C0\u67E5\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
18563
18690
|
return;
|
|
18564
18691
|
}
|
|
18692
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
18693
|
+
try {
|
|
18694
|
+
await runWizard(rl, store, opts);
|
|
18695
|
+
} catch (e) {
|
|
18696
|
+
cliErr(`\u63A5\u5165\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
18697
|
+
cliLog(" \u53EF\u7A0D\u540E\u5728\u63A7\u5236\u53F0\u751F\u6210\u63A5\u5165\u7801\uFF0C\u518D\u6267\u884C\uFF1Azqagent link --hub <Hub\u5730\u5740> --code <\u63A5\u5165\u7801>");
|
|
18698
|
+
} finally {
|
|
18699
|
+
rl.close();
|
|
18700
|
+
}
|
|
18701
|
+
}
|
|
18702
|
+
async function runWizard(rl, store, opts) {
|
|
18703
|
+
cliLog("");
|
|
18704
|
+
cliLog("\u672C\u673A\u5C1A\u672A\u63A5\u5165 Hub\u3002\u53EF\u7528 Hub \u8D26\u53F7\u63A5\u5165\uFF08\u8282\u70B9\u9ED8\u8BA4\u8FDB\u5165\u300C\u672A\u5206\u7EC4\u300D\uFF09\uFF1B\u8F93\u5165 - \u8DF3\u8FC7\u4FDD\u6301\u7EAF\u672C\u5730\u3002");
|
|
18705
|
+
const prompted = await promptLinkAccount(rl, opts.hubUrl);
|
|
18706
|
+
if (!prompted) return;
|
|
18565
18707
|
const nodeId = ensureNodeId(store);
|
|
18566
|
-
const
|
|
18708
|
+
const label2 = opts.label?.trim() || defaultNodeLabel();
|
|
18709
|
+
const cred = await hubEnrollByAccount(prompted.hubUrl, {
|
|
18710
|
+
...prompted.auth,
|
|
18711
|
+
nodeId,
|
|
18712
|
+
label: label2
|
|
18713
|
+
});
|
|
18567
18714
|
store.saveFleetCredential({
|
|
18568
18715
|
...cred,
|
|
18569
|
-
label:
|
|
18716
|
+
label: label2,
|
|
18570
18717
|
enrolledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
18571
18718
|
});
|
|
18719
|
+
store.saveNodeLabel(label2);
|
|
18572
18720
|
cliLog(`\u2705 \u5DF2\u63A5\u5165 Hub\uFF1A\u8282\u70B9 ${cred.nodeId}\uFF08\u7F51\u5173 ${cred.gatewayUrl ?? "\u672A\u4E0B\u53D1"}\uFF09`);
|
|
18573
18721
|
cliLog(" \u51ED\u636E\u5DF2\u4FDD\u5B58\u5230 fleet.json\uFF0C\u672C\u6B21\u542F\u52A8\u5373\u8FDE\u63A5 Hub\u3002");
|
|
18574
18722
|
}
|
|
18575
18723
|
async function askHidden(rl, prompt) {
|
|
18576
18724
|
if (!process.stdin.isTTY) return (await rl.question(prompt)).trim();
|
|
18577
|
-
return new Promise((
|
|
18725
|
+
return new Promise((resolve20) => {
|
|
18578
18726
|
const saved = process.stdin.listeners("data");
|
|
18579
18727
|
process.stdin.removeAllListeners("data");
|
|
18580
18728
|
cliWrite(prompt);
|
|
@@ -18596,13 +18744,13 @@ async function askHidden(rl, prompt) {
|
|
|
18596
18744
|
if (ch === "\r" || ch === "\n") {
|
|
18597
18745
|
cleanup();
|
|
18598
18746
|
cliWrite("\n");
|
|
18599
|
-
|
|
18747
|
+
resolve20(buf);
|
|
18600
18748
|
return;
|
|
18601
18749
|
}
|
|
18602
18750
|
if (ch === "") {
|
|
18603
18751
|
cleanup();
|
|
18604
18752
|
cliWrite("\n");
|
|
18605
|
-
|
|
18753
|
+
resolve20("");
|
|
18606
18754
|
return;
|
|
18607
18755
|
}
|
|
18608
18756
|
if (ch === "\x7F" || ch === "\b") {
|
|
@@ -18620,6 +18768,40 @@ async function askHidden(rl, prompt) {
|
|
|
18620
18768
|
});
|
|
18621
18769
|
}
|
|
18622
18770
|
|
|
18771
|
+
// src/cli/link.ts
|
|
18772
|
+
init_esm_shims();
|
|
18773
|
+
import * as readline2 from "readline";
|
|
18774
|
+
|
|
18775
|
+
// src/cli/serve-instances.ts
|
|
18776
|
+
init_esm_shims();
|
|
18777
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
18778
|
+
import * as fs30 from "fs";
|
|
18779
|
+
import * as os10 from "os";
|
|
18780
|
+
import * as path36 from "path";
|
|
18781
|
+
|
|
18782
|
+
// src/cli/link.ts
|
|
18783
|
+
function buildAccountAuth(flags, env3 = process.env) {
|
|
18784
|
+
const username = (flags.username ?? env3.ZQAGENT_HUB_USERNAME ?? "").trim();
|
|
18785
|
+
let email = (flags.email ?? "").trim();
|
|
18786
|
+
let phone = (flags.phone ?? "").trim();
|
|
18787
|
+
if (username && !email && !phone) {
|
|
18788
|
+
if (username.includes("@")) email = username;
|
|
18789
|
+
else phone = username;
|
|
18790
|
+
}
|
|
18791
|
+
if (!email && !phone) return null;
|
|
18792
|
+
const password = flags.password ?? env3.ZQAGENT_HUB_PASSWORD ?? "";
|
|
18793
|
+
const smsCode = (flags.smsCode ?? env3.ZQAGENT_HUB_SMS_CODE ?? "").trim();
|
|
18794
|
+
return {
|
|
18795
|
+
email: email ? email.toLowerCase() : void 0,
|
|
18796
|
+
phone: phone || void 0,
|
|
18797
|
+
password: password || void 0,
|
|
18798
|
+
smsCode: smsCode || void 0
|
|
18799
|
+
};
|
|
18800
|
+
}
|
|
18801
|
+
function isCompleteAccount(account2) {
|
|
18802
|
+
return Boolean(account2 && (account2.password || account2.smsCode));
|
|
18803
|
+
}
|
|
18804
|
+
|
|
18623
18805
|
// src/server/index.ts
|
|
18624
18806
|
function arg(name) {
|
|
18625
18807
|
const i = process.argv.indexOf(`--${name}`);
|
|
@@ -18628,13 +18810,22 @@ function arg(name) {
|
|
|
18628
18810
|
var hubUrl = (arg("hub") ?? process.env.HUB_URL ?? "").trim();
|
|
18629
18811
|
var enrollCode = (arg("enroll-code") ?? process.env.HUB_ENROLL_CODE ?? "").trim();
|
|
18630
18812
|
var label = arg("label")?.trim();
|
|
18631
|
-
|
|
18813
|
+
var account = buildAccountAuth({
|
|
18814
|
+
username: arg("username") ?? arg("user"),
|
|
18815
|
+
email: arg("email"),
|
|
18816
|
+
phone: arg("phone"),
|
|
18817
|
+
password: arg("password"),
|
|
18818
|
+
smsCode: arg("sms-code")
|
|
18819
|
+
});
|
|
18820
|
+
var autoEnroll = hubUrl && enrollCode ? { hubUrl, code: enrollCode, label } : hubUrl && isCompleteAccount(account) ? { hubUrl, account, label } : null;
|
|
18821
|
+
var beforeStart = autoEnroll ? Promise.resolve() : maybeAccountEnroll({ dataDir: arg("data-dir"), hubUrl: arg("hub"), label });
|
|
18822
|
+
void beforeStart.finally(() => {
|
|
18632
18823
|
startServer({
|
|
18633
18824
|
dataDir: arg("data-dir"),
|
|
18634
18825
|
port: arg("port") ? Number(arg("port")) : void 0,
|
|
18635
18826
|
host: arg("host"),
|
|
18636
|
-
//
|
|
18637
|
-
autoEnroll
|
|
18827
|
+
// 已有 fleet.json 时会在 runtime 内被忽略
|
|
18828
|
+
autoEnroll,
|
|
18638
18829
|
autoUpdate: true
|
|
18639
18830
|
});
|
|
18640
18831
|
});
|