@zqagent/core 0.2.12 → 0.2.14
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 +441 -184
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +441 -184
- package/dist/cli/index.js.map +1 -1
- package/dist/server/index.cjs +105 -16
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js +105 -16
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -554,7 +554,7 @@ init_esm_shims();
|
|
|
554
554
|
import "dotenv/config";
|
|
555
555
|
import * as fs34 from "fs";
|
|
556
556
|
import * as readline3 from "readline";
|
|
557
|
-
import * as
|
|
557
|
+
import * as path44 from "path";
|
|
558
558
|
import { exec } from "child_process";
|
|
559
559
|
import { promisify } from "util";
|
|
560
560
|
|
|
@@ -1360,12 +1360,12 @@ var MUTATING_TOOLS = /* @__PURE__ */ new Set([
|
|
|
1360
1360
|
]);
|
|
1361
1361
|
function parseReadFileSpan(content) {
|
|
1362
1362
|
const body = content.replace(/^\[tool output truncated:[^\n]*\]\n\n/, "");
|
|
1363
|
-
let
|
|
1363
|
+
let path45;
|
|
1364
1364
|
let start;
|
|
1365
1365
|
let end;
|
|
1366
1366
|
try {
|
|
1367
1367
|
const obj = JSON.parse(body);
|
|
1368
|
-
|
|
1368
|
+
path45 = obj.path;
|
|
1369
1369
|
start = obj.start_line;
|
|
1370
1370
|
end = obj.end_line;
|
|
1371
1371
|
} catch {
|
|
@@ -1374,14 +1374,14 @@ function parseReadFileSpan(content) {
|
|
|
1374
1374
|
const m = new RegExp(`"${key}"\\s*:\\s*(\\d+)`).exec(body);
|
|
1375
1375
|
return m ? Number(m[1]) : void 0;
|
|
1376
1376
|
};
|
|
1377
|
-
|
|
1377
|
+
path45 = str2("path");
|
|
1378
1378
|
start = num2("start_line");
|
|
1379
1379
|
end = num2("end_line");
|
|
1380
1380
|
}
|
|
1381
|
-
if (typeof
|
|
1381
|
+
if (typeof path45 !== "string" || !path45) return null;
|
|
1382
1382
|
if (typeof start !== "number" || typeof end !== "number") return null;
|
|
1383
1383
|
if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
|
|
1384
|
-
return { path:
|
|
1384
|
+
return { path: path45, start, end };
|
|
1385
1385
|
}
|
|
1386
1386
|
function addSpan(spans, start, end) {
|
|
1387
1387
|
spans.push([start, end]);
|
|
@@ -3020,9 +3020,9 @@ var TurnEngine = class _TurnEngine {
|
|
|
3020
3020
|
return;
|
|
3021
3021
|
}
|
|
3022
3022
|
if (result && typeof result === "object") {
|
|
3023
|
-
const
|
|
3024
|
-
if (
|
|
3025
|
-
this._producedFiles.push(
|
|
3023
|
+
const path45 = result.path;
|
|
3024
|
+
if (path45) {
|
|
3025
|
+
this._producedFiles.push(path45);
|
|
3026
3026
|
return;
|
|
3027
3027
|
}
|
|
3028
3028
|
const changed = result.changed_files;
|
|
@@ -3724,10 +3724,10 @@ var OpenAIProvider = class {
|
|
|
3724
3724
|
let timer;
|
|
3725
3725
|
try {
|
|
3726
3726
|
for (; ; ) {
|
|
3727
|
-
const idle = new Promise((
|
|
3727
|
+
const idle = new Promise((resolve25) => {
|
|
3728
3728
|
timer = setTimeout(() => {
|
|
3729
3729
|
onIdle();
|
|
3730
|
-
|
|
3730
|
+
resolve25({ timedOut: true });
|
|
3731
3731
|
}, idleMs);
|
|
3732
3732
|
});
|
|
3733
3733
|
const next = iter.next();
|
|
@@ -6048,12 +6048,12 @@ function makeSink(maxBuffer) {
|
|
|
6048
6048
|
};
|
|
6049
6049
|
}
|
|
6050
6050
|
function execAsync(file, argv, opts = {}) {
|
|
6051
|
-
return new Promise((
|
|
6051
|
+
return new Promise((resolve25) => {
|
|
6052
6052
|
const maxBuffer = opts.maxBuffer ?? DEFAULT_MAX_BUFFER;
|
|
6053
6053
|
const out = makeSink(maxBuffer);
|
|
6054
6054
|
const err = makeSink(maxBuffer);
|
|
6055
6055
|
if (opts.signal?.aborted) {
|
|
6056
|
-
|
|
6056
|
+
resolve25({
|
|
6057
6057
|
status: null,
|
|
6058
6058
|
stdout: Buffer.alloc(0),
|
|
6059
6059
|
stderr: Buffer.alloc(0),
|
|
@@ -6074,7 +6074,7 @@ function execAsync(file, argv, opts = {}) {
|
|
|
6074
6074
|
windowsHide: true
|
|
6075
6075
|
});
|
|
6076
6076
|
} catch (e) {
|
|
6077
|
-
|
|
6077
|
+
resolve25({
|
|
6078
6078
|
status: null,
|
|
6079
6079
|
stdout: Buffer.alloc(0),
|
|
6080
6080
|
stderr: Buffer.alloc(0),
|
|
@@ -6111,7 +6111,7 @@ function execAsync(file, argv, opts = {}) {
|
|
|
6111
6111
|
};
|
|
6112
6112
|
if (aborted) result.aborted = true;
|
|
6113
6113
|
if (spawnError) result.error = spawnError;
|
|
6114
|
-
|
|
6114
|
+
resolve25(result);
|
|
6115
6115
|
};
|
|
6116
6116
|
const killAndSettle = () => {
|
|
6117
6117
|
killTree(child.pid);
|
|
@@ -8006,18 +8006,18 @@ function makeApplyPatch(workspace) {
|
|
|
8006
8006
|
return { changed_files: changedFiles, added_files: addedFiles, deleted_files: deletedFiles, file_count: fileCount };
|
|
8007
8007
|
};
|
|
8008
8008
|
}
|
|
8009
|
-
function applyPatchHunks(oldLines, chunks,
|
|
8009
|
+
function applyPatchHunks(oldLines, chunks, path45) {
|
|
8010
8010
|
let newLines = [...oldLines];
|
|
8011
8011
|
let cursor = 0;
|
|
8012
8012
|
for (const chunk of chunks) {
|
|
8013
8013
|
const oldBlock = chunk.filter((l) => l[0] === " " || l[0] === "-").map((l) => l.slice(1));
|
|
8014
8014
|
const newBlock = chunk.filter((l) => l[0] === " " || l[0] === "+").map((l) => l.slice(1));
|
|
8015
8015
|
if (!oldBlock.length) {
|
|
8016
|
-
throw new Error(`\u8865\u4E01 hunk \u5FC5\u987B\u5305\u542B\u4E0A\u4E0B\u6587\u6216\u5220\u9664\u884C: ${
|
|
8016
|
+
throw new Error(`\u8865\u4E01 hunk \u5FC5\u987B\u5305\u542B\u4E0A\u4E0B\u6587\u6216\u5220\u9664\u884C: ${path45}`);
|
|
8017
8017
|
}
|
|
8018
8018
|
const matchStart = findBlockMatch(newLines, oldBlock, cursor);
|
|
8019
8019
|
if (matchStart === -1) {
|
|
8020
|
-
throw new Error(`\u8865\u4E01\u4E0A\u4E0B\u6587\u4E0D\u5339\u914D: ${
|
|
8020
|
+
throw new Error(`\u8865\u4E01\u4E0A\u4E0B\u6587\u4E0D\u5339\u914D: ${path45}`);
|
|
8021
8021
|
}
|
|
8022
8022
|
const matchEnd = matchStart + oldBlock.length;
|
|
8023
8023
|
newLines.splice(matchStart, oldBlock.length, ...newBlock);
|
|
@@ -10233,8 +10233,8 @@ var InputRouter = class {
|
|
|
10233
10233
|
}
|
|
10234
10234
|
/** 询问一行:显示 prompt,返回该行内容 */
|
|
10235
10235
|
ask(prompt) {
|
|
10236
|
-
return new Promise((
|
|
10237
|
-
this.pendingAsks.push({ prompt, resolve:
|
|
10236
|
+
return new Promise((resolve25) => {
|
|
10237
|
+
this.pendingAsks.push({ prompt, resolve: resolve25 });
|
|
10238
10238
|
this.pumpAsks();
|
|
10239
10239
|
});
|
|
10240
10240
|
}
|
|
@@ -10859,13 +10859,13 @@ var baseUrlResolver = null;
|
|
|
10859
10859
|
function resolveBase(baseUrl) {
|
|
10860
10860
|
return baseUrlResolver ? baseUrlResolver(baseUrl) : baseUrl;
|
|
10861
10861
|
}
|
|
10862
|
-
async function req(baseUrl, token,
|
|
10862
|
+
async function req(baseUrl, token, path45, init = {}) {
|
|
10863
10863
|
const headers = {
|
|
10864
10864
|
...init.body ? { "Content-Type": "application/json" } : {},
|
|
10865
10865
|
...init.headers ?? {}
|
|
10866
10866
|
};
|
|
10867
10867
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
10868
|
-
const res = await fetch(`${resolveBase(baseUrl).replace(/\/$/, "")}${
|
|
10868
|
+
const res = await fetch(`${resolveBase(baseUrl).replace(/\/$/, "")}${path45}`, {
|
|
10869
10869
|
...init,
|
|
10870
10870
|
headers
|
|
10871
10871
|
});
|
|
@@ -10904,6 +10904,20 @@ async function hubEnrollByAccount(baseUrl, input) {
|
|
|
10904
10904
|
});
|
|
10905
10905
|
return { hubUrl: baseUrl.replace(/\/$/, ""), ...data };
|
|
10906
10906
|
}
|
|
10907
|
+
async function hubUpdateNodeLabelSelf(baseUrl, fleetToken, input) {
|
|
10908
|
+
return await req(baseUrl, fleetToken, "/api/hub/nodes/self/label", {
|
|
10909
|
+
method: "POST",
|
|
10910
|
+
body: JSON.stringify(input)
|
|
10911
|
+
});
|
|
10912
|
+
}
|
|
10913
|
+
|
|
10914
|
+
// src/node-name.ts
|
|
10915
|
+
init_esm_shims();
|
|
10916
|
+
import * as os4 from "os";
|
|
10917
|
+
function defaultNodeLabel() {
|
|
10918
|
+
const name = os4.hostname().trim();
|
|
10919
|
+
return name || "zqagent-node";
|
|
10920
|
+
}
|
|
10907
10921
|
|
|
10908
10922
|
// src/cli/account-enroll.ts
|
|
10909
10923
|
init_esm_shims();
|
|
@@ -11747,11 +11761,11 @@ function isAffirmative(answer) {
|
|
|
11747
11761
|
return /^(yes|approve|同意|批准|允许|确定|可以|好的|确认)/.test(a);
|
|
11748
11762
|
}
|
|
11749
11763
|
function defer() {
|
|
11750
|
-
let
|
|
11764
|
+
let resolve25;
|
|
11751
11765
|
const promise = new Promise((r) => {
|
|
11752
|
-
|
|
11766
|
+
resolve25 = r;
|
|
11753
11767
|
});
|
|
11754
|
-
return { promise, resolve:
|
|
11768
|
+
return { promise, resolve: resolve25 };
|
|
11755
11769
|
}
|
|
11756
11770
|
var SessionManager = class {
|
|
11757
11771
|
constructor(store, approvalTimeoutMs = APPROVAL_TIMEOUT_MS, opts = {}) {
|
|
@@ -12323,11 +12337,11 @@ data: ${JSON.stringify({ sessionId, seq: entry.seq, ts: entry.ts, data: entry.da
|
|
|
12323
12337
|
status: "pending",
|
|
12324
12338
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12325
12339
|
};
|
|
12326
|
-
const { promise, resolve:
|
|
12340
|
+
const { promise, resolve: resolve25 } = defer();
|
|
12327
12341
|
const timer = setTimeout(() => {
|
|
12328
12342
|
this._recycleApproval(rt, id);
|
|
12329
12343
|
}, this.approvalTimeoutMs);
|
|
12330
|
-
rt.pendingApprovals.set(id, { promise, resolve:
|
|
12344
|
+
rt.pendingApprovals.set(id, { promise, resolve: resolve25, record, timer });
|
|
12331
12345
|
rt.approvals.set(id, record);
|
|
12332
12346
|
this._setStatus(rt, "waiting_approval");
|
|
12333
12347
|
this._persist(rt);
|
|
@@ -12405,11 +12419,11 @@ data: ${JSON.stringify({ sessionId, seq: entry.seq, ts: entry.ts, data: entry.da
|
|
|
12405
12419
|
status: "pending",
|
|
12406
12420
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12407
12421
|
};
|
|
12408
|
-
const { promise, resolve:
|
|
12422
|
+
const { promise, resolve: resolve25 } = defer();
|
|
12409
12423
|
const timer = setTimeout(() => {
|
|
12410
12424
|
this._recycleQuestion(rt, qid);
|
|
12411
12425
|
}, this.approvalTimeoutMs);
|
|
12412
|
-
rt.pendingQuestions.set(qid, { promise, resolve:
|
|
12426
|
+
rt.pendingQuestions.set(qid, { promise, resolve: resolve25, record, timer });
|
|
12413
12427
|
rt.questions.set(qid, record);
|
|
12414
12428
|
this._setStatus(rt, "waiting_question");
|
|
12415
12429
|
this._persist(rt);
|
|
@@ -12718,7 +12732,7 @@ data: ${JSON.stringify(entry.data)}
|
|
|
12718
12732
|
if (rt.mcpReady) {
|
|
12719
12733
|
await Promise.race([
|
|
12720
12734
|
rt.mcpReady,
|
|
12721
|
-
new Promise((
|
|
12735
|
+
new Promise((resolve25) => setTimeout(resolve25, 15e3))
|
|
12722
12736
|
]).catch(() => void 0);
|
|
12723
12737
|
}
|
|
12724
12738
|
for await (const event of gen) {
|
|
@@ -13296,7 +13310,7 @@ function buildNodeInfo(store, opts) {
|
|
|
13296
13310
|
nodeId: opts.nodeId ?? ensureNodeId(store),
|
|
13297
13311
|
platform: process.platform,
|
|
13298
13312
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
13299
|
-
version: "0.2.
|
|
13313
|
+
version: "0.2.14",
|
|
13300
13314
|
admin: opts.admin,
|
|
13301
13315
|
projects: opts.projects
|
|
13302
13316
|
};
|
|
@@ -13434,22 +13448,24 @@ async function runWizard(rl2, store, opts) {
|
|
|
13434
13448
|
const prompted = await promptLinkAccount(rl2, opts.hubUrl);
|
|
13435
13449
|
if (!prompted) return;
|
|
13436
13450
|
const nodeId = ensureNodeId(store);
|
|
13451
|
+
const label = opts.label?.trim() || defaultNodeLabel();
|
|
13437
13452
|
const cred = await hubEnrollByAccount(prompted.hubUrl, {
|
|
13438
13453
|
...prompted.auth,
|
|
13439
13454
|
nodeId,
|
|
13440
|
-
label
|
|
13455
|
+
label
|
|
13441
13456
|
});
|
|
13442
13457
|
store.saveFleetCredential({
|
|
13443
13458
|
...cred,
|
|
13444
|
-
label
|
|
13459
|
+
label,
|
|
13445
13460
|
enrolledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13446
13461
|
});
|
|
13462
|
+
store.saveNodeLabel(label);
|
|
13447
13463
|
cliLog(`\u2705 \u5DF2\u63A5\u5165 Hub\uFF1A\u8282\u70B9 ${cred.nodeId}\uFF08\u7F51\u5173 ${cred.gatewayUrl ?? "\u672A\u4E0B\u53D1"}\uFF09`);
|
|
13448
13464
|
cliLog(" \u51ED\u636E\u5DF2\u4FDD\u5B58\u5230 fleet.json\uFF0C\u672C\u6B21\u542F\u52A8\u5373\u8FDE\u63A5 Hub\u3002");
|
|
13449
13465
|
}
|
|
13450
13466
|
async function askHidden(rl2, prompt) {
|
|
13451
13467
|
if (!process.stdin.isTTY) return (await rl2.question(prompt)).trim();
|
|
13452
|
-
return new Promise((
|
|
13468
|
+
return new Promise((resolve25) => {
|
|
13453
13469
|
const saved = process.stdin.listeners("data");
|
|
13454
13470
|
process.stdin.removeAllListeners("data");
|
|
13455
13471
|
cliWrite(prompt);
|
|
@@ -13471,13 +13487,13 @@ async function askHidden(rl2, prompt) {
|
|
|
13471
13487
|
if (ch === "\r" || ch === "\n") {
|
|
13472
13488
|
cleanup();
|
|
13473
13489
|
cliWrite("\n");
|
|
13474
|
-
|
|
13490
|
+
resolve25(buf);
|
|
13475
13491
|
return;
|
|
13476
13492
|
}
|
|
13477
13493
|
if (ch === "") {
|
|
13478
13494
|
cleanup();
|
|
13479
13495
|
cliWrite("\n");
|
|
13480
|
-
|
|
13496
|
+
resolve25("");
|
|
13481
13497
|
return;
|
|
13482
13498
|
}
|
|
13483
13499
|
if (ch === "\x7F" || ch === "\b") {
|
|
@@ -13499,18 +13515,18 @@ async function askHidden(rl2, prompt) {
|
|
|
13499
13515
|
init_esm_shims();
|
|
13500
13516
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
13501
13517
|
import * as fs21 from "fs";
|
|
13502
|
-
import * as
|
|
13518
|
+
import * as os6 from "os";
|
|
13503
13519
|
import * as path27 from "path";
|
|
13504
13520
|
|
|
13505
13521
|
// src/update/platform.ts
|
|
13506
13522
|
init_esm_shims();
|
|
13507
13523
|
import * as fs20 from "fs";
|
|
13508
|
-
import * as
|
|
13524
|
+
import * as os5 from "os";
|
|
13509
13525
|
import * as path26 from "path";
|
|
13510
13526
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
13511
13527
|
import { createRequire as createRequire3 } from "module";
|
|
13512
13528
|
function currentVersion() {
|
|
13513
|
-
const injected = "0.2.
|
|
13529
|
+
const injected = "0.2.14"?.trim();
|
|
13514
13530
|
if (injected) return injected;
|
|
13515
13531
|
try {
|
|
13516
13532
|
const req2 = createRequire3(import.meta.url);
|
|
@@ -13548,7 +13564,7 @@ function launchdPlistPath() {
|
|
|
13548
13564
|
const label = launchdLabel();
|
|
13549
13565
|
const uid = typeof process.getuid === "function" ? process.getuid() : -1;
|
|
13550
13566
|
if (uid === 0) return `/Library/LaunchDaemons/${label}.plist`;
|
|
13551
|
-
return path26.join(
|
|
13567
|
+
return path26.join(os5.homedir(), "Library", "LaunchAgents", `${label}.plist`);
|
|
13552
13568
|
}
|
|
13553
13569
|
function serviceManagerFromLaunchctl(output, pid, execPath, sea = true) {
|
|
13554
13570
|
const pidMatch = /^\s*pid = (\d+)\s*$/m.exec(output);
|
|
@@ -13856,7 +13872,7 @@ function launchdServiceInstances() {
|
|
|
13856
13872
|
const label = process.env.ZQAGENT_SERVICE_LABEL?.trim() || DEFAULT_SERVICE_LABEL2;
|
|
13857
13873
|
const plists = [
|
|
13858
13874
|
`/Library/LaunchDaemons/${label}.plist`,
|
|
13859
|
-
path27.join(
|
|
13875
|
+
path27.join(os6.homedir(), "Library", "LaunchAgents", `${label}.plist`)
|
|
13860
13876
|
];
|
|
13861
13877
|
const out = [];
|
|
13862
13878
|
for (const plist of plists) {
|
|
@@ -13901,7 +13917,7 @@ function parseSystemdUnit(text) {
|
|
|
13901
13917
|
function systemdServiceInstances() {
|
|
13902
13918
|
if (process.platform !== "linux") return [];
|
|
13903
13919
|
const unit = process.env.ZQAGENT_SERVICE_NAME?.trim() || DEFAULT_SERVICE_NAME2;
|
|
13904
|
-
const configHome = process.env.XDG_CONFIG_HOME?.trim() || path27.join(
|
|
13920
|
+
const configHome = process.env.XDG_CONFIG_HOME?.trim() || path27.join(os6.homedir(), ".config");
|
|
13905
13921
|
const units = [
|
|
13906
13922
|
`/etc/systemd/system/${unit}.service`,
|
|
13907
13923
|
path27.join(configHome, "systemd", "user", `${unit}.service`)
|
|
@@ -14136,6 +14152,7 @@ async function linkNode(opts) {
|
|
|
14136
14152
|
const targetedService = !explicitDataDir && Boolean(managedDir) && dataDir === managedDir;
|
|
14137
14153
|
const store = new Store(dataDir);
|
|
14138
14154
|
const nodeId = ensureNodeId2(store);
|
|
14155
|
+
const label = opts.label?.trim() || defaultNodeLabel();
|
|
14139
14156
|
const account = opts.account;
|
|
14140
14157
|
const cred = account && isCompleteAccount(account) ? await hubEnrollByAccount(hubUrl, {
|
|
14141
14158
|
email: account.email,
|
|
@@ -14143,18 +14160,19 @@ async function linkNode(opts) {
|
|
|
14143
14160
|
password: account.password,
|
|
14144
14161
|
code: account.smsCode,
|
|
14145
14162
|
nodeId,
|
|
14146
|
-
label
|
|
14163
|
+
label
|
|
14147
14164
|
}) : await hubEnrollByCode(hubUrl, {
|
|
14148
14165
|
code: opts.code,
|
|
14149
14166
|
nodeId,
|
|
14150
|
-
label
|
|
14167
|
+
label
|
|
14151
14168
|
});
|
|
14152
14169
|
try {
|
|
14153
14170
|
store.saveFleetCredential({
|
|
14154
14171
|
...cred,
|
|
14155
|
-
label
|
|
14172
|
+
label,
|
|
14156
14173
|
enrolledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
14157
14174
|
});
|
|
14175
|
+
store.saveNodeLabel(label);
|
|
14158
14176
|
} catch (e) {
|
|
14159
14177
|
const err = e;
|
|
14160
14178
|
if (err.code === "EACCES" || err.code === "EPERM") {
|
|
@@ -14216,7 +14234,7 @@ async function runLinkCommand(argv, ctx = {}) {
|
|
|
14216
14234
|
return false;
|
|
14217
14235
|
}
|
|
14218
14236
|
const asPrompter = (rl2) => ({
|
|
14219
|
-
question: (q) => new Promise((
|
|
14237
|
+
question: (q) => new Promise((resolve25) => rl2.question(q, resolve25)),
|
|
14220
14238
|
pause: () => rl2.pause(),
|
|
14221
14239
|
resume: () => rl2.resume()
|
|
14222
14240
|
});
|
|
@@ -14311,18 +14329,178 @@ async function runLinkCommand(argv, ctx = {}) {
|
|
|
14311
14329
|
}
|
|
14312
14330
|
}
|
|
14313
14331
|
|
|
14332
|
+
// src/cli/rename.ts
|
|
14333
|
+
init_esm_shims();
|
|
14334
|
+
import * as path29 from "path";
|
|
14335
|
+
function parseArgs(argv) {
|
|
14336
|
+
const out = {};
|
|
14337
|
+
for (let i = 0; i < argv.length; i++) {
|
|
14338
|
+
const a = argv[i];
|
|
14339
|
+
if (a === "--data-dir") {
|
|
14340
|
+
out.dataDir = argv[++i];
|
|
14341
|
+
} else if (a === "--host") {
|
|
14342
|
+
out.host = argv[++i];
|
|
14343
|
+
} else if (a === "--port") {
|
|
14344
|
+
out.port = Number(argv[++i]);
|
|
14345
|
+
} else if (a === "-h" || a === "--help") {
|
|
14346
|
+
out.help = true;
|
|
14347
|
+
} else if (!a.startsWith("-") && out.label === void 0) {
|
|
14348
|
+
out.label = a;
|
|
14349
|
+
}
|
|
14350
|
+
}
|
|
14351
|
+
return out;
|
|
14352
|
+
}
|
|
14353
|
+
function printRenameHelp() {
|
|
14354
|
+
cliLog("\u7528\u6CD5: zqagent rename <\u540D\u79F0> [--data-dir <dir>]");
|
|
14355
|
+
cliLog(" \u4FEE\u6539\u672C\u673A\u8282\u70B9\u5728 Hub \u663E\u793A\u7684\u540D\u79F0\u3002\u672C\u673A\u6709 server \u5728\u8DD1\u65F6\u70ED\u751F\u6548\uFF08\u514D\u91CD\u542F\uFF09\uFF0C");
|
|
14356
|
+
cliLog(" \u5426\u5219\u5199\u5165\u6570\u636E\u76EE\u5F55\uFF0C\u4E0B\u6B21\u542F\u52A8\u751F\u6548\uFF1B\u5DF2\u63A5\u5165 Hub \u65F6\u540C\u65F6\u66F4\u65B0 Hub \u7684\u8282\u70B9\u8BB0\u5F55\u3002");
|
|
14357
|
+
cliLog(" \u63A5\u5165\u65F6\u672A\u6307\u5B9A\u540D\u79F0\u7684\u8282\u70B9\u9ED8\u8BA4\u7528\u4E3B\u673A\u540D\uFF0C\u4E5F\u53EF\u5728 Hub \u754C\u9762\u76F4\u63A5\u6539\u540D\u3002");
|
|
14358
|
+
cliLog(" \u793A\u4F8B: zqagent rename ten004-dev");
|
|
14359
|
+
}
|
|
14360
|
+
async function probeServer2(host, port, adminKey) {
|
|
14361
|
+
const ctrl = new AbortController();
|
|
14362
|
+
const timer = setTimeout(() => ctrl.abort(), 1500);
|
|
14363
|
+
try {
|
|
14364
|
+
const res = await fetch(`http://${host}:${port}/api/v1/fleet/status`, {
|
|
14365
|
+
headers: { Authorization: `Bearer ${adminKey}` },
|
|
14366
|
+
signal: ctrl.signal
|
|
14367
|
+
});
|
|
14368
|
+
return res.ok;
|
|
14369
|
+
} catch {
|
|
14370
|
+
return false;
|
|
14371
|
+
} finally {
|
|
14372
|
+
clearTimeout(timer);
|
|
14373
|
+
}
|
|
14374
|
+
}
|
|
14375
|
+
async function renameViaServer(host, port, adminKey, label) {
|
|
14376
|
+
const res = await fetch(`http://${host}:${port}/api/v1/fleet/label`, {
|
|
14377
|
+
method: "POST",
|
|
14378
|
+
headers: {
|
|
14379
|
+
"Content-Type": "application/json",
|
|
14380
|
+
Authorization: `Bearer ${adminKey}`
|
|
14381
|
+
},
|
|
14382
|
+
body: JSON.stringify({ label })
|
|
14383
|
+
});
|
|
14384
|
+
const text = await res.text();
|
|
14385
|
+
let payload = null;
|
|
14386
|
+
try {
|
|
14387
|
+
payload = text ? JSON.parse(text) : null;
|
|
14388
|
+
} catch {
|
|
14389
|
+
}
|
|
14390
|
+
if (!res.ok) {
|
|
14391
|
+
throw new Error(payload?.error?.message ?? `HTTP ${res.status}`);
|
|
14392
|
+
}
|
|
14393
|
+
const data = payload?.data;
|
|
14394
|
+
return { hubSynced: Boolean(data?.hubSynced), hubError: data?.hubError };
|
|
14395
|
+
}
|
|
14396
|
+
async function runRenameCommand(argv) {
|
|
14397
|
+
const args = parseArgs(argv);
|
|
14398
|
+
if (args.help) {
|
|
14399
|
+
printRenameHelp();
|
|
14400
|
+
return true;
|
|
14401
|
+
}
|
|
14402
|
+
const label = (args.label ?? "").trim();
|
|
14403
|
+
if (!label) {
|
|
14404
|
+
cliErr("\u7F3A\u5C11\u65B0\u7684\u8282\u70B9\u540D\u79F0\u3002");
|
|
14405
|
+
printRenameHelp();
|
|
14406
|
+
return false;
|
|
14407
|
+
}
|
|
14408
|
+
const host = args.host?.trim() || process.env.HOST?.trim() || DEFAULT_SERVE_HOST;
|
|
14409
|
+
const port = args.port ?? Number(process.env.PORT ?? DEFAULT_SERVE_PORT);
|
|
14410
|
+
const explicitDataDir = args.dataDir?.trim() ? expandHome(args.dataDir.trim()) : void 0;
|
|
14411
|
+
const running = discoverRunningServeInstances();
|
|
14412
|
+
const candidates = explicitDataDir ? [
|
|
14413
|
+
running.find((r) => path29.resolve(r.dataDir) === path29.resolve(explicitDataDir)) ?? {
|
|
14414
|
+
dataDir: path29.resolve(explicitDataDir),
|
|
14415
|
+
host,
|
|
14416
|
+
port
|
|
14417
|
+
}
|
|
14418
|
+
] : buildHotCandidates(void 0, running, { host, port });
|
|
14419
|
+
for (const inst of candidates) {
|
|
14420
|
+
const store2 = new Store(inst.dataDir);
|
|
14421
|
+
const adminKey = process.env.ADMIN_API_KEY ?? store2.loadAdminKey();
|
|
14422
|
+
if (!adminKey) continue;
|
|
14423
|
+
if (!await probeServer2(inst.host, inst.port, adminKey)) continue;
|
|
14424
|
+
try {
|
|
14425
|
+
const r = await renameViaServer(inst.host, inst.port, adminKey, label);
|
|
14426
|
+
cliLog(`\u2705 \u8282\u70B9\u540D\u79F0\u5DF2\u66F4\u65B0\u4E3A\u300C${label}\u300D\uFF08\u5DF2\u70ED\u751F\u6548\uFF0C\u65E0\u9700\u91CD\u542F\uFF09`);
|
|
14427
|
+
cliLog(` \u6570\u636E\u76EE\u5F55: ${inst.dataDir}`);
|
|
14428
|
+
if (r.hubSynced) {
|
|
14429
|
+
cliLog(" Hub \u8BB0\u5F55\u5DF2\u540C\u6B65\uFF0C\u5237\u65B0\u63A7\u5236\u53F0\u5373\u53EF\u770B\u5230\u65B0\u540D\u79F0\u3002");
|
|
14430
|
+
} else if (r.hubError) {
|
|
14431
|
+
cliLog(`\u26A0\uFE0F \u672C\u5730\u5DF2\u66F4\u65B0\uFF0C\u4F46\u540C\u6B65 Hub \u5931\u8D25\uFF1A${r.hubError}`);
|
|
14432
|
+
cliLog(" \u53EF\u7A0D\u540E\u91CD\u8BD5\u540C\u4E00\u547D\u4EE4\uFF0C\u6216\u76F4\u63A5\u5728 Hub \u754C\u9762\u6539\u540D\u3002");
|
|
14433
|
+
} else {
|
|
14434
|
+
cliLog(" \u672C\u673A\u672A\u63A5\u5165 Hub\uFF0CHub \u754C\u9762\u4E0D\u4F1A\u663E\u793A\u8BE5\u540D\u79F0\u3002");
|
|
14435
|
+
}
|
|
14436
|
+
return true;
|
|
14437
|
+
} catch (e) {
|
|
14438
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
14439
|
+
if (/未知路由|HTTP 404/.test(msg)) {
|
|
14440
|
+
cliLog("\u26A0\uFE0F \u8FD0\u884C\u4E2D\u7684\u8282\u70B9\u670D\u52A1\u7248\u672C\u8F83\u65E7\uFF0C\u6539\u540D\u6539\u4E3A\u76F4\u63A5\u5199\u5165\u6570\u636E\u76EE\u5F55\uFF0C\u91CD\u542F\u540E\u751F\u6548\u3002");
|
|
14441
|
+
break;
|
|
14442
|
+
}
|
|
14443
|
+
cliErr(`\u6539\u540D\u5931\u8D25: ${msg}`);
|
|
14444
|
+
return false;
|
|
14445
|
+
}
|
|
14446
|
+
}
|
|
14447
|
+
const dataDir = path29.resolve(
|
|
14448
|
+
explicitDataDir ?? running.find((r) => r.managed)?.dataDir ?? DEFAULT_DATA_DIR
|
|
14449
|
+
);
|
|
14450
|
+
const store = new Store(dataDir);
|
|
14451
|
+
try {
|
|
14452
|
+
store.saveNodeLabel(label);
|
|
14453
|
+
} catch (e) {
|
|
14454
|
+
const err = e;
|
|
14455
|
+
cliErr(
|
|
14456
|
+
`\u65E0\u6CD5\u5199\u5165\u6570\u636E\u76EE\u5F55 ${dataDir}\uFF08${err.code ?? "EACCES"}\uFF09\u3002\u82E5\u8282\u70B9\u7531\u7CFB\u7EDF\u670D\u52A1\u6258\u7BA1\uFF0C\u8BF7\u7528 sudo \u6267\u884C\uFF0C\u6216\u7528 --data-dir \u6307\u5B9A\u76EE\u5F55\u3002`
|
|
14457
|
+
);
|
|
14458
|
+
return false;
|
|
14459
|
+
}
|
|
14460
|
+
const cred = store.loadFleetCredential();
|
|
14461
|
+
if (!cred) {
|
|
14462
|
+
cliLog(`\u2705 \u8282\u70B9\u540D\u79F0\u5DF2\u4FDD\u5B58\u4E3A\u300C${label}\u300D\uFF08${dataDir}\uFF09`);
|
|
14463
|
+
cliLog(" \u672C\u673A\u672A\u63A5\u5165 Hub\uFF0C\u4E0B\u6B21\u542F\u52A8 serve \u540E\u751F\u6548\u3002");
|
|
14464
|
+
return true;
|
|
14465
|
+
}
|
|
14466
|
+
store.saveFleetCredential({ ...cred, label });
|
|
14467
|
+
let hubSynced = false;
|
|
14468
|
+
let hubError;
|
|
14469
|
+
if (cred.hubUrl && cred.fleetToken) {
|
|
14470
|
+
try {
|
|
14471
|
+
await hubUpdateNodeLabelSelf(cred.hubUrl, cred.fleetToken, {
|
|
14472
|
+
nodeId: cred.nodeId,
|
|
14473
|
+
label
|
|
14474
|
+
});
|
|
14475
|
+
hubSynced = true;
|
|
14476
|
+
} catch (e) {
|
|
14477
|
+
hubError = e instanceof Error ? e.message : String(e);
|
|
14478
|
+
}
|
|
14479
|
+
}
|
|
14480
|
+
cliLog(`\u2705 \u8282\u70B9\u540D\u79F0\u5DF2\u4FDD\u5B58\u4E3A\u300C${label}\u300D\uFF08${dataDir}\uFF0C\u4E0B\u6B21\u542F\u52A8 serve \u751F\u6548\uFF09`);
|
|
14481
|
+
if (hubSynced) {
|
|
14482
|
+
cliLog(" Hub \u8BB0\u5F55\u5DF2\u540C\u6B65\uFF0C\u5237\u65B0\u63A7\u5236\u53F0\u5373\u53EF\u770B\u5230\u65B0\u540D\u79F0\u3002");
|
|
14483
|
+
} else if (hubError) {
|
|
14484
|
+
cliLog(`\u26A0\uFE0F \u672C\u5730\u5DF2\u4FDD\u5B58\uFF0C\u4F46\u540C\u6B65 Hub \u5931\u8D25\uFF1A${hubError}`);
|
|
14485
|
+
cliLog(" \u53EF\u7A0D\u540E\u91CD\u8BD5\u540C\u4E00\u547D\u4EE4\uFF0C\u6216\u76F4\u63A5\u5728 Hub \u754C\u9762\u6539\u540D\u3002");
|
|
14486
|
+
} else {
|
|
14487
|
+
cliLog(" \u8282\u70B9\u51ED\u636E\u4E0D\u5B8C\u6574\uFF08\u7F3A\u5C11 Hub \u5730\u5740\u6216\u4EE4\u724C\uFF09\uFF0CHub \u8BB0\u5F55\u672A\u66F4\u65B0\u3002");
|
|
14488
|
+
}
|
|
14489
|
+
return true;
|
|
14490
|
+
}
|
|
14491
|
+
|
|
14314
14492
|
// src/cli/serve.ts
|
|
14315
14493
|
init_esm_shims();
|
|
14316
14494
|
|
|
14317
14495
|
// src/server/runtime.ts
|
|
14318
14496
|
init_esm_shims();
|
|
14319
14497
|
import * as fs31 from "fs";
|
|
14320
|
-
import * as
|
|
14498
|
+
import * as path40 from "path";
|
|
14321
14499
|
|
|
14322
14500
|
// src/server/routes.ts
|
|
14323
14501
|
init_esm_shims();
|
|
14324
14502
|
import { createServer } from "http";
|
|
14325
|
-
import * as
|
|
14503
|
+
import * as path33 from "path";
|
|
14326
14504
|
|
|
14327
14505
|
// src/server/auth.ts
|
|
14328
14506
|
init_esm_shims();
|
|
@@ -14402,8 +14580,8 @@ function hubProxyEnabled(host) {
|
|
|
14402
14580
|
const h = (host ?? "127.0.0.1").trim();
|
|
14403
14581
|
return h === "127.0.0.1" || h === "localhost" || h === "::1";
|
|
14404
14582
|
}
|
|
14405
|
-
function isHubProxyPath(
|
|
14406
|
-
return
|
|
14583
|
+
function isHubProxyPath(path45) {
|
|
14584
|
+
return path45.startsWith(HUB_PROXY_PREFIX);
|
|
14407
14585
|
}
|
|
14408
14586
|
function decodeTarget(enc) {
|
|
14409
14587
|
try {
|
|
@@ -14498,14 +14676,14 @@ async function handleHubProxy(req2, res) {
|
|
|
14498
14676
|
// src/server/fsBrowser.ts
|
|
14499
14677
|
init_esm_shims();
|
|
14500
14678
|
import * as fs22 from "fs";
|
|
14501
|
-
import * as
|
|
14502
|
-
import * as
|
|
14679
|
+
import * as os7 from "os";
|
|
14680
|
+
import * as path30 from "path";
|
|
14503
14681
|
var MAX_ENTRIES = 2e3;
|
|
14504
14682
|
var DEFAULT_SEARCH_LIMIT = 200;
|
|
14505
14683
|
var MAX_SEARCH_LIMIT = 1e3;
|
|
14506
14684
|
function listDirs(input) {
|
|
14507
|
-
const base = (input ?? "").trim() ||
|
|
14508
|
-
const target =
|
|
14685
|
+
const base = (input ?? "").trim() || os7.homedir();
|
|
14686
|
+
const target = path30.resolve(base);
|
|
14509
14687
|
let st;
|
|
14510
14688
|
try {
|
|
14511
14689
|
st = fs22.statSync(target);
|
|
@@ -14520,7 +14698,7 @@ function listDirs(input) {
|
|
|
14520
14698
|
throw new Error(`\u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\uFF08\u6743\u9650\u4E0D\u8DB3\uFF1F\uFF09: ${target}`);
|
|
14521
14699
|
}
|
|
14522
14700
|
const entries = dirents.map((d) => {
|
|
14523
|
-
const full =
|
|
14701
|
+
const full = path30.join(target, d.name);
|
|
14524
14702
|
let isDir = d.isDirectory();
|
|
14525
14703
|
if (d.isSymbolicLink()) {
|
|
14526
14704
|
try {
|
|
@@ -14533,7 +14711,7 @@ function listDirs(input) {
|
|
|
14533
14711
|
entries.sort(
|
|
14534
14712
|
(a, b) => a.type === b.type ? a.name.localeCompare(b.name) : a.type === "dir" ? -1 : 1
|
|
14535
14713
|
);
|
|
14536
|
-
const parentDir =
|
|
14714
|
+
const parentDir = path30.dirname(target);
|
|
14537
14715
|
return {
|
|
14538
14716
|
path: target,
|
|
14539
14717
|
parent: parentDir !== target ? parentDir : null,
|
|
@@ -14564,7 +14742,7 @@ var NAME_CACHE_MAX_DIRS = 4;
|
|
|
14564
14742
|
var NAME_CACHE_MAX_ENTRIES = 5e4;
|
|
14565
14743
|
var nameCache = /* @__PURE__ */ new Map();
|
|
14566
14744
|
function invalidateDirNames(target) {
|
|
14567
|
-
nameCache.delete(
|
|
14745
|
+
nameCache.delete(path30.resolve(target));
|
|
14568
14746
|
}
|
|
14569
14747
|
async function loadDirNames(target) {
|
|
14570
14748
|
const now = Date.now();
|
|
@@ -14599,7 +14777,7 @@ async function loadDirNames(target) {
|
|
|
14599
14777
|
return entries;
|
|
14600
14778
|
}
|
|
14601
14779
|
async function toDirEntry(dir, e) {
|
|
14602
|
-
const full =
|
|
14780
|
+
const full = path30.join(dir, e.name);
|
|
14603
14781
|
let isDir = e.isDir;
|
|
14604
14782
|
if (e.isLink) {
|
|
14605
14783
|
try {
|
|
@@ -14610,8 +14788,8 @@ async function toDirEntry(dir, e) {
|
|
|
14610
14788
|
return { name: e.name, path: full, type: isDir ? "dir" : "file" };
|
|
14611
14789
|
}
|
|
14612
14790
|
async function searchDirs(input, query, limit) {
|
|
14613
|
-
const base = (input ?? "").trim() ||
|
|
14614
|
-
const target =
|
|
14791
|
+
const base = (input ?? "").trim() || os7.homedir();
|
|
14792
|
+
const target = path30.resolve(base);
|
|
14615
14793
|
let st;
|
|
14616
14794
|
try {
|
|
14617
14795
|
st = await fs22.promises.stat(target);
|
|
@@ -14644,7 +14822,7 @@ async function searchDirs(input, query, limit) {
|
|
|
14644
14822
|
);
|
|
14645
14823
|
const hit = scored.slice(0, max);
|
|
14646
14824
|
const entries = await Promise.all(hit.map(({ entry }) => toDirEntry(target, entry)));
|
|
14647
|
-
const parentDir =
|
|
14825
|
+
const parentDir = path30.dirname(target);
|
|
14648
14826
|
return {
|
|
14649
14827
|
path: target,
|
|
14650
14828
|
parent: parentDir !== target ? parentDir : null,
|
|
@@ -14655,13 +14833,13 @@ async function searchDirs(input, query, limit) {
|
|
|
14655
14833
|
};
|
|
14656
14834
|
}
|
|
14657
14835
|
function makeDirIn(parentInput, name) {
|
|
14658
|
-
const parent =
|
|
14836
|
+
const parent = path30.resolve((parentInput ?? "").trim() || os7.homedir());
|
|
14659
14837
|
const clean = (name ?? "").trim();
|
|
14660
14838
|
if (!clean) throw new Error("\u76EE\u5F55\u540D\u4E0D\u80FD\u4E3A\u7A7A");
|
|
14661
14839
|
if (clean === "." || clean === "..") throw new Error("\u76EE\u5F55\u540D\u975E\u6CD5");
|
|
14662
|
-
const target =
|
|
14663
|
-
const rel =
|
|
14664
|
-
if (!rel || rel.startsWith("..") ||
|
|
14840
|
+
const target = path30.resolve(parent, clean);
|
|
14841
|
+
const rel = path30.relative(parent, target);
|
|
14842
|
+
if (!rel || rel.startsWith("..") || path30.isAbsolute(rel)) {
|
|
14665
14843
|
throw new Error("\u76EE\u5F55\u540D\u4E0D\u80FD\u8D8A\u51FA\u5F53\u524D\u76EE\u5F55");
|
|
14666
14844
|
}
|
|
14667
14845
|
let st = null;
|
|
@@ -14677,25 +14855,25 @@ function makeDirIn(parentInput, name) {
|
|
|
14677
14855
|
throw new Error(`\u521B\u5EFA\u76EE\u5F55\u5931\u8D25: ${e instanceof Error ? e.message : String(e)}`);
|
|
14678
14856
|
}
|
|
14679
14857
|
invalidateDirNames(parent);
|
|
14680
|
-
return { name:
|
|
14858
|
+
return { name: path30.basename(target), path: target, type: "dir" };
|
|
14681
14859
|
}
|
|
14682
14860
|
|
|
14683
14861
|
// src/server/projectFiles.ts
|
|
14684
14862
|
init_esm_shims();
|
|
14685
14863
|
import * as fs23 from "fs";
|
|
14686
|
-
import * as
|
|
14864
|
+
import * as path31 from "path";
|
|
14687
14865
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
14688
14866
|
var MAX_DOWNLOAD_BYTES = 16 * 1024 * 1024;
|
|
14689
14867
|
var MAX_ENTRIES2 = 2e3;
|
|
14690
14868
|
function toPosix(p) {
|
|
14691
|
-
return p.split(
|
|
14869
|
+
return p.split(path31.sep).join("/");
|
|
14692
14870
|
}
|
|
14693
14871
|
function projectRoot(workspaceRoot) {
|
|
14694
14872
|
const r = (workspaceRoot ?? "").trim();
|
|
14695
14873
|
if (!r) {
|
|
14696
14874
|
throw new Error("\u9879\u76EE\u672A\u8BBE\u7F6E\u5DE5\u4F5C\u533A\u76EE\u5F55\uFF08workspaceRoot\uFF09\uFF0C\u65E0\u6CD5\u6D4F\u89C8\u6587\u4EF6");
|
|
14697
14875
|
}
|
|
14698
|
-
const abs =
|
|
14876
|
+
const abs = path31.resolve(r);
|
|
14699
14877
|
if (!fs23.existsSync(abs)) {
|
|
14700
14878
|
throw new Error(`\u5DE5\u4F5C\u533A\u76EE\u5F55\u4E0D\u5B58\u5728: ${abs}`);
|
|
14701
14879
|
}
|
|
@@ -14720,7 +14898,7 @@ function listProjectFiles(workspaceRoot, relPath) {
|
|
|
14720
14898
|
try {
|
|
14721
14899
|
st = fs23.statSync(dir);
|
|
14722
14900
|
} catch {
|
|
14723
|
-
throw new Error(`\u76EE\u5F55\u4E0D\u5B58\u5728: ${toPosix(
|
|
14901
|
+
throw new Error(`\u76EE\u5F55\u4E0D\u5B58\u5728: ${toPosix(path31.relative(base, dir)) || "/"}`);
|
|
14724
14902
|
}
|
|
14725
14903
|
if (!st.isDirectory()) throw new Error("\u76EE\u6807\u4E0D\u662F\u76EE\u5F55");
|
|
14726
14904
|
let dirents;
|
|
@@ -14730,7 +14908,7 @@ function listProjectFiles(workspaceRoot, relPath) {
|
|
|
14730
14908
|
throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\uFF08\u6743\u9650\u4E0D\u8DB3\uFF1F\uFF09");
|
|
14731
14909
|
}
|
|
14732
14910
|
const entries = dirents.map((d) => {
|
|
14733
|
-
const full =
|
|
14911
|
+
const full = path31.join(dir, d.name);
|
|
14734
14912
|
let isDir = d.isDirectory();
|
|
14735
14913
|
if (d.isSymbolicLink()) {
|
|
14736
14914
|
try {
|
|
@@ -14748,7 +14926,7 @@ function listProjectFiles(workspaceRoot, relPath) {
|
|
|
14748
14926
|
}
|
|
14749
14927
|
return {
|
|
14750
14928
|
name: d.name,
|
|
14751
|
-
path: toPosix(
|
|
14929
|
+
path: toPosix(path31.relative(base, full)),
|
|
14752
14930
|
type: isDir ? "dir" : "file",
|
|
14753
14931
|
size,
|
|
14754
14932
|
mtime
|
|
@@ -14757,12 +14935,12 @@ function listProjectFiles(workspaceRoot, relPath) {
|
|
|
14757
14935
|
entries.sort(
|
|
14758
14936
|
(a, b) => a.type === b.type ? a.name.localeCompare(b.name) : a.type === "dir" ? -1 : 1
|
|
14759
14937
|
);
|
|
14760
|
-
const relDir = toPosix(
|
|
14761
|
-
const parentAbs =
|
|
14938
|
+
const relDir = toPosix(path31.relative(base, dir));
|
|
14939
|
+
const parentAbs = path31.dirname(dir);
|
|
14762
14940
|
return {
|
|
14763
14941
|
root: base,
|
|
14764
14942
|
path: relDir,
|
|
14765
|
-
parent: isWithinRoot(base, parentAbs) ? toPosix(
|
|
14943
|
+
parent: isWithinRoot(base, parentAbs) ? toPosix(path31.relative(base, parentAbs)) : null,
|
|
14766
14944
|
entries: entries.slice(0, MAX_ENTRIES2)
|
|
14767
14945
|
};
|
|
14768
14946
|
}
|
|
@@ -14781,7 +14959,7 @@ function readProjectFile(workspaceRoot, relPath) {
|
|
|
14781
14959
|
const truncated = buf.length > MAX_FILE_BYTES;
|
|
14782
14960
|
const slice = truncated ? buf.subarray(0, MAX_FILE_BYTES) : buf;
|
|
14783
14961
|
return {
|
|
14784
|
-
path: toPosix(
|
|
14962
|
+
path: toPosix(path31.relative(base, file)),
|
|
14785
14963
|
size: st.size,
|
|
14786
14964
|
binary,
|
|
14787
14965
|
truncated,
|
|
@@ -14803,8 +14981,8 @@ function downloadProjectFile(workspaceRoot, relPath) {
|
|
|
14803
14981
|
}
|
|
14804
14982
|
const buf = fs23.readFileSync(file);
|
|
14805
14983
|
return {
|
|
14806
|
-
path: toPosix(
|
|
14807
|
-
name:
|
|
14984
|
+
path: toPosix(path31.relative(base, file)),
|
|
14985
|
+
name: path31.basename(file),
|
|
14808
14986
|
size: buf.length,
|
|
14809
14987
|
base64: buf.toString("base64")
|
|
14810
14988
|
};
|
|
@@ -14826,12 +15004,12 @@ function writeProjectFile(workspaceRoot, relPath, content) {
|
|
|
14826
15004
|
throw new Error("\u5185\u5BB9\u8D85\u8FC7 2MB \u4E0A\u9650\uFF0C\u65E0\u6CD5\u4FDD\u5B58");
|
|
14827
15005
|
}
|
|
14828
15006
|
try {
|
|
14829
|
-
fs23.mkdirSync(
|
|
15007
|
+
fs23.mkdirSync(path31.dirname(file), { recursive: true });
|
|
14830
15008
|
fs23.writeFileSync(file, buf);
|
|
14831
15009
|
} catch (e) {
|
|
14832
15010
|
throw new Error(`\u5199\u5165\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
14833
15011
|
}
|
|
14834
|
-
return { path: toPosix(
|
|
15012
|
+
return { path: toPosix(path31.relative(base, file)), size: buf.length };
|
|
14835
15013
|
}
|
|
14836
15014
|
function createProjectDir(workspaceRoot, relPath) {
|
|
14837
15015
|
const base = projectRoot(workspaceRoot);
|
|
@@ -14843,7 +15021,7 @@ function createProjectDir(workspaceRoot, relPath) {
|
|
|
14843
15021
|
} catch (e) {
|
|
14844
15022
|
throw new Error(`\u521B\u5EFA\u76EE\u5F55\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
14845
15023
|
}
|
|
14846
|
-
return { path: toPosix(
|
|
15024
|
+
return { path: toPosix(path31.relative(base, dir)) };
|
|
14847
15025
|
}
|
|
14848
15026
|
function createProjectFile(workspaceRoot, relPath, content = "") {
|
|
14849
15027
|
const base = projectRoot(workspaceRoot);
|
|
@@ -14853,12 +15031,12 @@ function createProjectFile(workspaceRoot, relPath, content = "") {
|
|
|
14853
15031
|
if (fs23.existsSync(file)) throw new Error("\u6587\u4EF6\u5DF2\u5B58\u5728");
|
|
14854
15032
|
const buf = Buffer.from(String(content ?? ""), "utf-8");
|
|
14855
15033
|
try {
|
|
14856
|
-
fs23.mkdirSync(
|
|
15034
|
+
fs23.mkdirSync(path31.dirname(file), { recursive: true });
|
|
14857
15035
|
fs23.writeFileSync(file, buf);
|
|
14858
15036
|
} catch (e) {
|
|
14859
15037
|
throw new Error(`\u521B\u5EFA\u6587\u4EF6\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
14860
15038
|
}
|
|
14861
|
-
return { path: toPosix(
|
|
15039
|
+
return { path: toPosix(path31.relative(base, file)), size: buf.length };
|
|
14862
15040
|
}
|
|
14863
15041
|
function searchProjectFiles(workspaceRoot, query) {
|
|
14864
15042
|
const base = projectRoot(workspaceRoot);
|
|
@@ -14892,7 +15070,7 @@ function searchProjectFiles(workspaceRoot, query) {
|
|
|
14892
15070
|
let isDir = d.isDirectory();
|
|
14893
15071
|
if (d.isSymbolicLink()) {
|
|
14894
15072
|
try {
|
|
14895
|
-
isDir = fs23.statSync(
|
|
15073
|
+
isDir = fs23.statSync(path31.join(dir, d.name)).isDirectory();
|
|
14896
15074
|
} catch {
|
|
14897
15075
|
isDir = false;
|
|
14898
15076
|
}
|
|
@@ -14900,7 +15078,7 @@ function searchProjectFiles(workspaceRoot, query) {
|
|
|
14900
15078
|
if (d.name.toLowerCase().includes(q)) {
|
|
14901
15079
|
out.push({ path: rel, type: isDir ? "dir" : "file" });
|
|
14902
15080
|
}
|
|
14903
|
-
if (isDir) walk(
|
|
15081
|
+
if (isDir) walk(path31.join(dir, d.name), rel);
|
|
14904
15082
|
}
|
|
14905
15083
|
};
|
|
14906
15084
|
walk(base, "");
|
|
@@ -14909,8 +15087,8 @@ function searchProjectFiles(workspaceRoot, query) {
|
|
|
14909
15087
|
|
|
14910
15088
|
// src/server/projectOps.ts
|
|
14911
15089
|
init_esm_shims();
|
|
14912
|
-
import * as
|
|
14913
|
-
import * as
|
|
15090
|
+
import * as os8 from "os";
|
|
15091
|
+
import * as path32 from "path";
|
|
14914
15092
|
var MAX_STDOUT2 = 2e4;
|
|
14915
15093
|
var MAX_STDERR2 = 1e4;
|
|
14916
15094
|
var MAX_BUFFER3 = 1024 * 1024 * 5;
|
|
@@ -14924,7 +15102,7 @@ function resolveInvocation2(spec, prepared) {
|
|
|
14924
15102
|
}
|
|
14925
15103
|
function workRoot(workspaceRoot) {
|
|
14926
15104
|
const r = (workspaceRoot ?? "").trim();
|
|
14927
|
-
return r ?
|
|
15105
|
+
return r ? path32.resolve(r) : os8.homedir();
|
|
14928
15106
|
}
|
|
14929
15107
|
async function runProjectCommand(workspaceRoot, command, timeoutSeconds) {
|
|
14930
15108
|
const cmd = String(command ?? "");
|
|
@@ -15236,7 +15414,7 @@ function projectStats(manager, tenantId) {
|
|
|
15236
15414
|
// src/server/nodeHost.ts
|
|
15237
15415
|
init_esm_shims();
|
|
15238
15416
|
import * as fs24 from "fs";
|
|
15239
|
-
import * as
|
|
15417
|
+
import * as os9 from "os";
|
|
15240
15418
|
function diskInfo(pathStr) {
|
|
15241
15419
|
try {
|
|
15242
15420
|
const st = fs24.statfsSync(pathStr);
|
|
@@ -15251,7 +15429,7 @@ function diskInfo(pathStr) {
|
|
|
15251
15429
|
}
|
|
15252
15430
|
function networkInfo() {
|
|
15253
15431
|
const out = [];
|
|
15254
|
-
const ifaces =
|
|
15432
|
+
const ifaces = os9.networkInterfaces();
|
|
15255
15433
|
for (const [name, list] of Object.entries(ifaces)) {
|
|
15256
15434
|
for (const info of list ?? []) {
|
|
15257
15435
|
out.push({
|
|
@@ -15302,23 +15480,23 @@ function overview(store, manager) {
|
|
|
15302
15480
|
return { projects, sessions: { total, running, waiting, items }, usage: { tokensIn, tokensOut } };
|
|
15303
15481
|
}
|
|
15304
15482
|
function buildNodeHost(store, manager, diskPath) {
|
|
15305
|
-
const cpus2 =
|
|
15483
|
+
const cpus2 = os9.cpus();
|
|
15306
15484
|
const ov = overview(store, manager);
|
|
15307
15485
|
return {
|
|
15308
15486
|
nodeId: store.loadNodeId() ?? "",
|
|
15309
|
-
hostname:
|
|
15487
|
+
hostname: os9.hostname(),
|
|
15310
15488
|
platform: process.platform,
|
|
15311
15489
|
arch: process.arch,
|
|
15312
|
-
release:
|
|
15313
|
-
uptimeSec: Math.round(
|
|
15314
|
-
version: "0.2.
|
|
15490
|
+
release: os9.release(),
|
|
15491
|
+
uptimeSec: Math.round(os9.uptime()),
|
|
15492
|
+
version: "0.2.14",
|
|
15315
15493
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
15316
15494
|
cpu: {
|
|
15317
15495
|
count: cpus2.length,
|
|
15318
15496
|
model: cpus2[0]?.model ?? "",
|
|
15319
|
-
loadAvg:
|
|
15497
|
+
loadAvg: os9.loadavg().map((n) => Math.round(n * 100) / 100)
|
|
15320
15498
|
},
|
|
15321
|
-
memory: { total:
|
|
15499
|
+
memory: { total: os9.totalmem(), free: os9.freemem() },
|
|
15322
15500
|
network: networkInfo(),
|
|
15323
15501
|
disk: diskInfo(diskPath || process.cwd()),
|
|
15324
15502
|
...ov
|
|
@@ -15355,7 +15533,7 @@ function saveNotifications(tenant, secretBox, notifications) {
|
|
|
15355
15533
|
var API_PREFIX = "/api/v1";
|
|
15356
15534
|
var MAX_BODY_BYTES = 10 * 1024 * 1024;
|
|
15357
15535
|
function readBody(req2) {
|
|
15358
|
-
return new Promise((
|
|
15536
|
+
return new Promise((resolve25, reject) => {
|
|
15359
15537
|
const chunks = [];
|
|
15360
15538
|
let size = 0;
|
|
15361
15539
|
req2.on("data", (c) => {
|
|
@@ -15368,9 +15546,9 @@ function readBody(req2) {
|
|
|
15368
15546
|
chunks.push(c);
|
|
15369
15547
|
});
|
|
15370
15548
|
req2.on("end", () => {
|
|
15371
|
-
if (chunks.length === 0) return
|
|
15549
|
+
if (chunks.length === 0) return resolve25(void 0);
|
|
15372
15550
|
try {
|
|
15373
|
-
|
|
15551
|
+
resolve25(JSON.parse(Buffer.concat(chunks).toString("utf-8")));
|
|
15374
15552
|
} catch {
|
|
15375
15553
|
reject(new ApiError(400, "bad_request", "\u8BF7\u6C42\u4F53\u4E0D\u662F\u5408\u6CD5 JSON"));
|
|
15376
15554
|
}
|
|
@@ -15681,6 +15859,24 @@ function createApp(store, manager, opts = {}) {
|
|
|
15681
15859
|
ok(res, opts.fleet.status());
|
|
15682
15860
|
}
|
|
15683
15861
|
},
|
|
15862
|
+
// 修改本机节点显示名:写本地配置并立即上报;已接入 Hub 时同步 Hub 记录。
|
|
15863
|
+
// `zqagent rename` 在有 server 在跑时走这里(热生效,免重启)。
|
|
15864
|
+
{
|
|
15865
|
+
method: "POST",
|
|
15866
|
+
pattern: ["fleet", "label"],
|
|
15867
|
+
adminOnly: true,
|
|
15868
|
+
fn: async (_req, res, { body }) => {
|
|
15869
|
+
if (!opts.fleet) {
|
|
15870
|
+
throw new ApiError(503, "fleet_disabled", "\u8282\u70B9\u7BA1\u7406\u63A7\u5236\u5668\u672A\u542F\u7528");
|
|
15871
|
+
}
|
|
15872
|
+
const raw = body ?? {};
|
|
15873
|
+
const label = typeof raw.label === "string" ? raw.label.trim() : "";
|
|
15874
|
+
if (!label) {
|
|
15875
|
+
throw new ApiError(400, "bad_request", "label \u4E0D\u80FD\u4E3A\u7A7A");
|
|
15876
|
+
}
|
|
15877
|
+
ok(res, await opts.fleet.rename(label));
|
|
15878
|
+
}
|
|
15879
|
+
},
|
|
15684
15880
|
// 运行时热接入:凭一次性注册码或 Hub 账号接入(落盘 fleet.json + 立即连接,免重启)
|
|
15685
15881
|
{
|
|
15686
15882
|
method: "POST",
|
|
@@ -15913,7 +16109,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
15913
16109
|
applyProvidersPatch(tenant, raw);
|
|
15914
16110
|
if (typeof raw.workspaceRoot === "string") {
|
|
15915
16111
|
const ws = raw.workspaceRoot.trim();
|
|
15916
|
-
const next = ws ?
|
|
16112
|
+
const next = ws ? path33.resolve(ws) : void 0;
|
|
15917
16113
|
if (tenant.workspaceRoot) {
|
|
15918
16114
|
if (next !== tenant.workspaceRoot) {
|
|
15919
16115
|
throw new ApiError(
|
|
@@ -16874,10 +17070,10 @@ function createApp(store, manager, opts = {}) {
|
|
|
16874
17070
|
function handle(req2, res) {
|
|
16875
17071
|
const startedAt2 = Date.now();
|
|
16876
17072
|
const url = new URL(req2.url ?? "/", "http://localhost");
|
|
16877
|
-
const
|
|
17073
|
+
const path45 = url.pathname;
|
|
16878
17074
|
const method = req2.method ?? "GET";
|
|
16879
17075
|
console.log(
|
|
16880
|
-
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} \u2192 ${method} ${
|
|
17076
|
+
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} \u2192 ${method} ${path45}${url.search}`
|
|
16881
17077
|
);
|
|
16882
17078
|
let tenantId = null;
|
|
16883
17079
|
let logged = false;
|
|
@@ -16885,7 +17081,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
16885
17081
|
if (logged) return;
|
|
16886
17082
|
logged = true;
|
|
16887
17083
|
console.log(
|
|
16888
|
-
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} \u2190 ${method} ${
|
|
17084
|
+
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} \u2190 ${method} ${path45} ${extra} (${Date.now() - startedAt2}ms) tenant=${tenantId ?? "-"}`
|
|
16889
17085
|
);
|
|
16890
17086
|
};
|
|
16891
17087
|
res.on("finish", () => logDone(`HTTP ${res.statusCode}`));
|
|
@@ -16896,16 +17092,16 @@ function createApp(store, manager, opts = {}) {
|
|
|
16896
17092
|
res.end();
|
|
16897
17093
|
return;
|
|
16898
17094
|
}
|
|
16899
|
-
if (req2.method === "GET" &&
|
|
17095
|
+
if (req2.method === "GET" && path45 === "/healthz") {
|
|
16900
17096
|
json(res, 200, {
|
|
16901
17097
|
status: "ok",
|
|
16902
17098
|
// 版本让运维/探针能确认线上跑的是哪个构建(更新与回滚据此判断)
|
|
16903
|
-
version: "0.2.
|
|
17099
|
+
version: "0.2.14",
|
|
16904
17100
|
features: { mcp: hasServerMcpConfig() }
|
|
16905
17101
|
});
|
|
16906
17102
|
return;
|
|
16907
17103
|
}
|
|
16908
|
-
if (hubProxyEnabled(opts.host) && isHubProxyPath(
|
|
17104
|
+
if (hubProxyEnabled(opts.host) && isHubProxyPath(path45)) {
|
|
16909
17105
|
void handleHubProxy(req2, res).catch(() => {
|
|
16910
17106
|
if (!res.headersSent) {
|
|
16911
17107
|
res.writeHead(502, { "Content-Type": "application/json; charset=utf-8" });
|
|
@@ -16916,11 +17112,11 @@ function createApp(store, manager, opts = {}) {
|
|
|
16916
17112
|
});
|
|
16917
17113
|
return;
|
|
16918
17114
|
}
|
|
16919
|
-
if (!
|
|
17115
|
+
if (!path45.startsWith(API_PREFIX)) {
|
|
16920
17116
|
json(res, 404, { error: { code: "not_found", message: "\u672A\u77E5\u8DEF\u5F84" } });
|
|
16921
17117
|
return;
|
|
16922
17118
|
}
|
|
16923
|
-
const segs =
|
|
17119
|
+
const segs = path45.slice(API_PREFIX.length).split("/").filter(Boolean);
|
|
16924
17120
|
const apiKey = extractApiKey(req2);
|
|
16925
17121
|
if (!apiKey) {
|
|
16926
17122
|
json(res, 401, {
|
|
@@ -16985,7 +17181,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
16985
17181
|
).catch((err) => {
|
|
16986
17182
|
const msg = err instanceof Error ? err.message : String(err);
|
|
16987
17183
|
console.log(
|
|
16988
|
-
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} ! ${method} ${
|
|
17184
|
+
`[api] ${(/* @__PURE__ */ new Date()).toISOString()} ! ${method} ${path45} ERROR: ${msg}`
|
|
16989
17185
|
);
|
|
16990
17186
|
error(res, err);
|
|
16991
17187
|
});
|
|
@@ -16995,7 +17191,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
16995
17191
|
|
|
16996
17192
|
// src/server/fleet/FleetNodeBridge.ts
|
|
16997
17193
|
init_esm_shims();
|
|
16998
|
-
import * as
|
|
17194
|
+
import * as os10 from "os";
|
|
16999
17195
|
import { monitorEventLoopDelay } from "perf_hooks";
|
|
17000
17196
|
|
|
17001
17197
|
// src/server/fleet/FleetCommands.ts
|
|
@@ -17016,8 +17212,8 @@ async function cachedFetchModels(baseURL, apiKey) {
|
|
|
17016
17212
|
try {
|
|
17017
17213
|
result = await Promise.race([
|
|
17018
17214
|
fetchModels(baseURL, apiKey),
|
|
17019
|
-
new Promise((
|
|
17020
|
-
const t = setTimeout(() =>
|
|
17215
|
+
new Promise((resolve25) => {
|
|
17216
|
+
const t = setTimeout(() => resolve25(null), MODEL_FETCH_TIMEOUT_MS);
|
|
17021
17217
|
t.unref?.();
|
|
17022
17218
|
})
|
|
17023
17219
|
]);
|
|
@@ -17042,8 +17238,8 @@ async function cachedFetchModelsEnriched(baseURL, apiKey, preferred) {
|
|
|
17042
17238
|
if (!target) return r;
|
|
17043
17239
|
const ctx = await Promise.race([
|
|
17044
17240
|
fetchModelContext(baseURL, apiKey, target),
|
|
17045
|
-
new Promise((
|
|
17046
|
-
const t = setTimeout(() =>
|
|
17241
|
+
new Promise((resolve25) => {
|
|
17242
|
+
const t = setTimeout(() => resolve25(void 0), MODEL_FETCH_TIMEOUT_MS);
|
|
17047
17243
|
t.unref?.();
|
|
17048
17244
|
})
|
|
17049
17245
|
]);
|
|
@@ -18172,13 +18368,13 @@ var EVENT_FLUSH_MAX_EVENTS = 60;
|
|
|
18172
18368
|
var EVENT_FLUSH_MAX_BYTES = 200 * 1024;
|
|
18173
18369
|
var LOOP_LAG_WARN_MS = 2e3;
|
|
18174
18370
|
function withTimeout(p, ms) {
|
|
18175
|
-
return new Promise((
|
|
18371
|
+
return new Promise((resolve25, reject) => {
|
|
18176
18372
|
const timer = setTimeout(() => reject(new Error(`\u5B50\u6307\u4EE4\u8D85\u65F6\uFF08${ms}ms\uFF09`)), ms);
|
|
18177
18373
|
timer.unref?.();
|
|
18178
18374
|
p.then(
|
|
18179
18375
|
(v) => {
|
|
18180
18376
|
clearTimeout(timer);
|
|
18181
|
-
|
|
18377
|
+
resolve25(v);
|
|
18182
18378
|
},
|
|
18183
18379
|
(e) => {
|
|
18184
18380
|
clearTimeout(timer);
|
|
@@ -18189,7 +18385,7 @@ function withTimeout(p, ms) {
|
|
|
18189
18385
|
}
|
|
18190
18386
|
function primaryIp() {
|
|
18191
18387
|
let v6;
|
|
18192
|
-
for (const infos of Object.values(
|
|
18388
|
+
for (const infos of Object.values(os10.networkInterfaces())) {
|
|
18193
18389
|
for (const info of infos ?? []) {
|
|
18194
18390
|
if (info.internal) continue;
|
|
18195
18391
|
if (info.family === "IPv4") return info.address;
|
|
@@ -18529,6 +18725,11 @@ var FleetNodeBridge = class {
|
|
|
18529
18725
|
refreshInfo() {
|
|
18530
18726
|
this._publishInfo();
|
|
18531
18727
|
}
|
|
18728
|
+
/** 本地改名后把 status(含 label)与 info 立即重发,控制台不必等下一次周期上报 */
|
|
18729
|
+
republishLabel() {
|
|
18730
|
+
this._send({ kind: "status", status: this._status(this.isConnected()) });
|
|
18731
|
+
this._publishInfo();
|
|
18732
|
+
}
|
|
18532
18733
|
// ===================== 内部 =====================
|
|
18533
18734
|
_status(online) {
|
|
18534
18735
|
return {
|
|
@@ -18538,7 +18739,7 @@ var FleetNodeBridge = class {
|
|
|
18538
18739
|
label: this.opts.deps.store.loadNodeLabel() ?? void 0,
|
|
18539
18740
|
platform: process.platform,
|
|
18540
18741
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
18541
|
-
version: "0.2.
|
|
18742
|
+
version: "0.2.14",
|
|
18542
18743
|
ip: primaryIp()
|
|
18543
18744
|
};
|
|
18544
18745
|
}
|
|
@@ -18557,7 +18758,23 @@ var FleetNodeBridge = class {
|
|
|
18557
18758
|
byDay: days
|
|
18558
18759
|
};
|
|
18559
18760
|
}
|
|
18761
|
+
/**
|
|
18762
|
+
* 上报 info(项目/会话快照)。
|
|
18763
|
+
*
|
|
18764
|
+
* 失败必须留痕:这是控制台「项目列表」的唯一数据源,静默失败会表现为
|
|
18765
|
+
* 「这台节点永远没有任何项目」,且只能靠网关 detail=null 才发现。
|
|
18766
|
+
* 同时用 try 包住,避免一次读盘异常中断 `_onUp` 后续的状态通知。
|
|
18767
|
+
*/
|
|
18560
18768
|
_publishInfo() {
|
|
18769
|
+
try {
|
|
18770
|
+
this._publishInfoNow();
|
|
18771
|
+
} catch (e) {
|
|
18772
|
+
console.warn(
|
|
18773
|
+
`[fleet] \u8282\u70B9 ${this.nodeId} \u4E0A\u62A5 info \u5931\u8D25: ${e instanceof Error ? e.message : String(e)}`
|
|
18774
|
+
);
|
|
18775
|
+
}
|
|
18776
|
+
}
|
|
18777
|
+
_publishInfoNow() {
|
|
18561
18778
|
const totals = { projects: 0, sessions: 0, running: 0, waiting: 0 };
|
|
18562
18779
|
const sessions = [];
|
|
18563
18780
|
const projects = allProjectSummaries(this.opts.deps.store).map((p) => {
|
|
@@ -18584,7 +18801,15 @@ var FleetNodeBridge = class {
|
|
|
18584
18801
|
totals.sessions += p.sessionCount;
|
|
18585
18802
|
totals.running += running;
|
|
18586
18803
|
totals.waiting += waiting;
|
|
18587
|
-
return {
|
|
18804
|
+
return {
|
|
18805
|
+
id: p.id,
|
|
18806
|
+
name: p.name,
|
|
18807
|
+
sessionCount: p.sessionCount,
|
|
18808
|
+
running,
|
|
18809
|
+
waiting,
|
|
18810
|
+
// 控制台项目列表要展示工作目录(Hub 落盘快照后即可离线查看)
|
|
18811
|
+
workspaceRoot: p.workspaceRoot ?? null
|
|
18812
|
+
};
|
|
18588
18813
|
});
|
|
18589
18814
|
this._send({
|
|
18590
18815
|
kind: "info",
|
|
@@ -18593,7 +18818,7 @@ var FleetNodeBridge = class {
|
|
|
18593
18818
|
label: this.opts.deps.store.loadNodeLabel() ?? void 0,
|
|
18594
18819
|
platform: process.platform,
|
|
18595
18820
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
18596
|
-
version: "0.2.
|
|
18821
|
+
version: "0.2.14",
|
|
18597
18822
|
ip: primaryIp(),
|
|
18598
18823
|
projects,
|
|
18599
18824
|
totals,
|
|
@@ -19341,7 +19566,7 @@ init_esm_shims();
|
|
|
19341
19566
|
// src/server/qq/bindings.ts
|
|
19342
19567
|
init_esm_shims();
|
|
19343
19568
|
import * as fs25 from "fs";
|
|
19344
|
-
import * as
|
|
19569
|
+
import * as path34 from "path";
|
|
19345
19570
|
function conversationKey(target) {
|
|
19346
19571
|
switch (target.kind) {
|
|
19347
19572
|
case "c2c":
|
|
@@ -19380,7 +19605,7 @@ var QqBindingsStore = class _QqBindingsStore {
|
|
|
19380
19605
|
cache = null;
|
|
19381
19606
|
/** 基于 DATA_DIR 构造 */
|
|
19382
19607
|
static in(dataDir) {
|
|
19383
|
-
return new _QqBindingsStore(
|
|
19608
|
+
return new _QqBindingsStore(path34.join(dataDir, "qq", "bindings.json"));
|
|
19384
19609
|
}
|
|
19385
19610
|
load() {
|
|
19386
19611
|
if (this.cache) return this.cache;
|
|
@@ -19417,7 +19642,7 @@ var QqBindingsStore = class _QqBindingsStore {
|
|
|
19417
19642
|
return null;
|
|
19418
19643
|
}
|
|
19419
19644
|
persist() {
|
|
19420
|
-
fs25.mkdirSync(
|
|
19645
|
+
fs25.mkdirSync(path34.dirname(this.file), { recursive: true });
|
|
19421
19646
|
fs25.writeFileSync(this.file, JSON.stringify(this.cache, null, 2), "utf-8");
|
|
19422
19647
|
}
|
|
19423
19648
|
};
|
|
@@ -19831,7 +20056,7 @@ ${lines.join("\n")}`, msgId);
|
|
|
19831
20056
|
// src/server/qq/QqManager.ts
|
|
19832
20057
|
init_esm_shims();
|
|
19833
20058
|
import * as fs26 from "fs";
|
|
19834
|
-
import * as
|
|
20059
|
+
import * as path35 from "path";
|
|
19835
20060
|
var QqManager = class {
|
|
19836
20061
|
constructor(opts) {
|
|
19837
20062
|
this.opts = opts;
|
|
@@ -19840,7 +20065,7 @@ var QqManager = class {
|
|
|
19840
20065
|
adapter = null;
|
|
19841
20066
|
config = null;
|
|
19842
20067
|
get configFile() {
|
|
19843
|
-
return
|
|
20068
|
+
return path35.join(this.opts.dataDir, "qq", "config.json");
|
|
19844
20069
|
}
|
|
19845
20070
|
/** 启动:读配置(env 优先,其次文件),有则建连接 */
|
|
19846
20071
|
start() {
|
|
@@ -19933,7 +20158,7 @@ var QqManager = class {
|
|
|
19933
20158
|
return null;
|
|
19934
20159
|
}
|
|
19935
20160
|
_persistConfig(cfg) {
|
|
19936
|
-
fs26.mkdirSync(
|
|
20161
|
+
fs26.mkdirSync(path35.dirname(this.configFile), { recursive: true });
|
|
19937
20162
|
fs26.writeFileSync(this.configFile, JSON.stringify(cfg, null, 2), "utf-8");
|
|
19938
20163
|
}
|
|
19939
20164
|
};
|
|
@@ -19983,7 +20208,7 @@ var PairingCodeStore = class {
|
|
|
19983
20208
|
// src/update/controller.ts
|
|
19984
20209
|
init_esm_shims();
|
|
19985
20210
|
import * as fs30 from "fs";
|
|
19986
|
-
import * as
|
|
20211
|
+
import * as path39 from "path";
|
|
19987
20212
|
|
|
19988
20213
|
// src/update/downloader.ts
|
|
19989
20214
|
init_esm_shims();
|
|
@@ -19992,7 +20217,7 @@ import * as fs27 from "fs";
|
|
|
19992
20217
|
import { Readable as Readable2 } from "stream";
|
|
19993
20218
|
import { pipeline as pipeline2 } from "stream/promises";
|
|
19994
20219
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
19995
|
-
import * as
|
|
20220
|
+
import * as path36 from "path";
|
|
19996
20221
|
|
|
19997
20222
|
// src/update/manifest.ts
|
|
19998
20223
|
init_esm_shims();
|
|
@@ -20169,7 +20394,7 @@ async function fetchManifest(url, publicKey, opts = {}) {
|
|
|
20169
20394
|
async function downloadBinary(bin, destPath, log = () => {
|
|
20170
20395
|
}) {
|
|
20171
20396
|
const partPath = `${destPath}.part`;
|
|
20172
|
-
fs27.mkdirSync(
|
|
20397
|
+
fs27.mkdirSync(path36.dirname(destPath), { recursive: true });
|
|
20173
20398
|
fs27.rmSync(partPath, { force: true });
|
|
20174
20399
|
let res;
|
|
20175
20400
|
try {
|
|
@@ -20213,7 +20438,7 @@ async function downloadBinary(bin, destPath, log = () => {
|
|
|
20213
20438
|
fs27.rmSync(destPath, { force: true });
|
|
20214
20439
|
fs27.renameSync(partPath, destPath);
|
|
20215
20440
|
fs27.chmodSync(destPath, 493);
|
|
20216
|
-
log(`\u5DF2\u4E0B\u8F7D ${
|
|
20441
|
+
log(`\u5DF2\u4E0B\u8F7D ${path36.basename(destPath)}\uFF08${Math.round(bytes / 1024 / 1024)}MB\uFF0C\u6821\u9A8C\u901A\u8FC7\uFF09`);
|
|
20217
20442
|
return { bytes };
|
|
20218
20443
|
}
|
|
20219
20444
|
function selfCheck(binPath, expectedVersion) {
|
|
@@ -20238,17 +20463,17 @@ function selfCheck(binPath, expectedVersion) {
|
|
|
20238
20463
|
// src/update/installer.ts
|
|
20239
20464
|
init_esm_shims();
|
|
20240
20465
|
import * as fs29 from "fs";
|
|
20241
|
-
import * as
|
|
20466
|
+
import * as path38 from "path";
|
|
20242
20467
|
|
|
20243
20468
|
// src/update/state.ts
|
|
20244
20469
|
init_esm_shims();
|
|
20245
20470
|
import * as fs28 from "fs";
|
|
20246
|
-
import * as
|
|
20471
|
+
import * as path37 from "path";
|
|
20247
20472
|
function updatesDir(dataDir) {
|
|
20248
|
-
return
|
|
20473
|
+
return path37.join(dataDir, "updates");
|
|
20249
20474
|
}
|
|
20250
20475
|
function statePath(dataDir) {
|
|
20251
|
-
return
|
|
20476
|
+
return path37.join(updatesDir(dataDir), "state.json");
|
|
20252
20477
|
}
|
|
20253
20478
|
function loadState(dataDir) {
|
|
20254
20479
|
try {
|
|
@@ -20275,12 +20500,12 @@ function patchState(dataDir, patch) {
|
|
|
20275
20500
|
|
|
20276
20501
|
// src/update/installer.ts
|
|
20277
20502
|
function backupDir(dataDir) {
|
|
20278
|
-
return
|
|
20503
|
+
return path38.join(updatesDir(dataDir), "backup");
|
|
20279
20504
|
}
|
|
20280
20505
|
function backupCurrent(dataDir, execPath, version) {
|
|
20281
20506
|
const dir = backupDir(dataDir);
|
|
20282
20507
|
fs29.mkdirSync(dir, { recursive: true });
|
|
20283
|
-
const target =
|
|
20508
|
+
const target = path38.join(dir, `zqagent-${version}${process.platform === "win32" ? ".exe" : ""}`);
|
|
20284
20509
|
fs29.copyFileSync(execPath, target);
|
|
20285
20510
|
fs29.chmodSync(target, 493);
|
|
20286
20511
|
return target;
|
|
@@ -20312,7 +20537,7 @@ function installStaged(opts) {
|
|
|
20312
20537
|
const from = currentVersion();
|
|
20313
20538
|
log(`\u6B63\u5728\u5B89\u88C5 v${opts.version}\uFF08\u5F53\u524D v${from}\uFF09`);
|
|
20314
20539
|
const backupPath = backupCurrent(opts.dataDir, opts.execPath, from);
|
|
20315
|
-
log(`\u5DF2\u5907\u4EFD\u5F53\u524D\u7248\u672C\u5230 ${
|
|
20540
|
+
log(`\u5DF2\u5907\u4EFD\u5F53\u524D\u7248\u672C\u5230 ${path38.basename(backupPath)}`);
|
|
20316
20541
|
replaceExecutable(opts.execPath, opts.stagedPath);
|
|
20317
20542
|
return patchState(opts.dataDir, {
|
|
20318
20543
|
stagedVersion: void 0,
|
|
@@ -20356,7 +20581,7 @@ function rollback(dataDir, execPath, log = () => {
|
|
|
20356
20581
|
}
|
|
20357
20582
|
function readRollbackTarget(dataDir) {
|
|
20358
20583
|
try {
|
|
20359
|
-
const raw = fs29.readFileSync(
|
|
20584
|
+
const raw = fs29.readFileSync(path38.join(updatesDir(dataDir), "state.json"), "utf-8");
|
|
20360
20585
|
const s = JSON.parse(raw);
|
|
20361
20586
|
if (s.backupPath && s.backupVersion) return s;
|
|
20362
20587
|
} catch {
|
|
@@ -20533,7 +20758,7 @@ var UpdateController = class {
|
|
|
20533
20758
|
if (!bin) return `\u6E05\u5355\u6CA1\u6709\u5F53\u524D\u5E73\u53F0\uFF08${platformKey()}\uFF09\u7684\u4EA7\u7269`;
|
|
20534
20759
|
let stagedPath = state.stagedPath;
|
|
20535
20760
|
if (!(state.stagedVersion === manifest.version && stagedPath && fs30.existsSync(stagedPath))) {
|
|
20536
|
-
stagedPath =
|
|
20761
|
+
stagedPath = path39.join(
|
|
20537
20762
|
updatesDir(this.opts.dataDir),
|
|
20538
20763
|
"staged",
|
|
20539
20764
|
`zqagent-${manifest.version}${process.platform === "win32" ? ".exe" : ""}`
|
|
@@ -20600,11 +20825,11 @@ var UpdateController = class {
|
|
|
20600
20825
|
const minUptime = num("ZQAGENT_UPDATE_MIN_UPTIME_MS", 10 * 60 * 1e3);
|
|
20601
20826
|
const idleMs = num("ZQAGENT_UPDATE_IDLE_MS", 60 * 1e3);
|
|
20602
20827
|
let idleSince = null;
|
|
20603
|
-
return new Promise((
|
|
20828
|
+
return new Promise((resolve25) => {
|
|
20604
20829
|
const timer = setInterval(() => {
|
|
20605
20830
|
if (this.stopped) {
|
|
20606
20831
|
clearInterval(timer);
|
|
20607
|
-
|
|
20832
|
+
resolve25(false);
|
|
20608
20833
|
return;
|
|
20609
20834
|
}
|
|
20610
20835
|
if (Date.now() - this.startedAt < minUptime || !this.opts.isIdle()) {
|
|
@@ -20614,7 +20839,7 @@ var UpdateController = class {
|
|
|
20614
20839
|
idleSince ??= Date.now();
|
|
20615
20840
|
if (Date.now() - idleSince >= idleMs) {
|
|
20616
20841
|
clearInterval(timer);
|
|
20617
|
-
|
|
20842
|
+
resolve25(true);
|
|
20618
20843
|
}
|
|
20619
20844
|
}, 1e3);
|
|
20620
20845
|
timer.unref();
|
|
@@ -20708,7 +20933,7 @@ function seedDemoTenant(store) {
|
|
|
20708
20933
|
apiKey: env2("OPENAI_API_KEY"),
|
|
20709
20934
|
baseURL: env2("OPENAI_BASE_URL")
|
|
20710
20935
|
},
|
|
20711
|
-
workspaceRoot: workspace ?
|
|
20936
|
+
workspaceRoot: workspace ? path40.resolve(workspace) : void 0,
|
|
20712
20937
|
allowedCommands: []
|
|
20713
20938
|
};
|
|
20714
20939
|
store.saveTenant(demo);
|
|
@@ -20762,9 +20987,9 @@ function syncTenantModels(store) {
|
|
|
20762
20987
|
tenant.model = model;
|
|
20763
20988
|
changed = true;
|
|
20764
20989
|
}
|
|
20765
|
-
if (workspace && tenant.workspaceRoot !==
|
|
20766
|
-
console.log(`[sync] \u79DF\u6237 ${id} workspaceRoot \u5DF2\u540C\u6B65: ${tenant.workspaceRoot ?? "(\u6C99\u7BB1)"} \u2192 ${
|
|
20767
|
-
tenant.workspaceRoot =
|
|
20990
|
+
if (workspace && tenant.workspaceRoot !== path40.resolve(workspace)) {
|
|
20991
|
+
console.log(`[sync] \u79DF\u6237 ${id} workspaceRoot \u5DF2\u540C\u6B65: ${tenant.workspaceRoot ?? "(\u6C99\u7BB1)"} \u2192 ${path40.resolve(workspace)}`);
|
|
20992
|
+
tenant.workspaceRoot = path40.resolve(workspace);
|
|
20768
20993
|
changed = true;
|
|
20769
20994
|
}
|
|
20770
20995
|
if (apiKey && tenant.provider.apiKey !== apiKey) {
|
|
@@ -20797,7 +21022,7 @@ function exitWhenOrphaned() {
|
|
|
20797
21022
|
}
|
|
20798
21023
|
var PORT_FALLBACK_LIMIT = 20;
|
|
20799
21024
|
function listenWithPortFallback(server, startPort, host, dataDir, limit = PORT_FALLBACK_LIMIT) {
|
|
20800
|
-
return new Promise((
|
|
21025
|
+
return new Promise((resolve25, reject) => {
|
|
20801
21026
|
let attempts = 0;
|
|
20802
21027
|
const tryListen = (port) => {
|
|
20803
21028
|
server.removeAllListeners("listening");
|
|
@@ -20825,18 +21050,18 @@ function listenWithPortFallback(server, startPort, host, dataDir, limit = PORT_F
|
|
|
20825
21050
|
}
|
|
20826
21051
|
try {
|
|
20827
21052
|
fs31.mkdirSync(dataDir, { recursive: true });
|
|
20828
|
-
fs31.writeFileSync(
|
|
21053
|
+
fs31.writeFileSync(path40.join(dataDir, "server-port"), `${actualPort}
|
|
20829
21054
|
`);
|
|
20830
21055
|
} catch {
|
|
20831
21056
|
}
|
|
20832
|
-
|
|
21057
|
+
resolve25(actualPort);
|
|
20833
21058
|
});
|
|
20834
21059
|
};
|
|
20835
21060
|
tryListen(startPort);
|
|
20836
21061
|
});
|
|
20837
21062
|
}
|
|
20838
21063
|
function startServer(opts = {}) {
|
|
20839
|
-
const dataDir =
|
|
21064
|
+
const dataDir = path40.resolve(opts.dataDir ?? env2("DATA_DIR") ?? DEFAULT_DATA_DIR);
|
|
20840
21065
|
const port = opts.port ?? Number(env2("PORT") ?? 8787);
|
|
20841
21066
|
const host = opts.host ?? env2("HOST") ?? "127.0.0.1";
|
|
20842
21067
|
exitWhenOrphaned();
|
|
@@ -20866,7 +21091,7 @@ function startServer(opts = {}) {
|
|
|
20866
21091
|
}
|
|
20867
21092
|
const adminKey = ensureAdminKey();
|
|
20868
21093
|
const secretKey = env2("SECRET_KEY");
|
|
20869
|
-
const secretBox = secretKey ? SecretBox.fromHex(secretKey) : SecretBox.fromFile(
|
|
21094
|
+
const secretBox = secretKey ? SecretBox.fromHex(secretKey) : SecretBox.fromFile(path40.join(dataDir, "secret.key"));
|
|
20870
21095
|
if (secretKey && !secretBox) {
|
|
20871
21096
|
console.warn("[crypto] SECRET_KEY \u975E\u6CD5\uFF08\u9700 64 \u4F4D hex\uFF09\uFF0C\u901A\u77E5\u51ED\u636E\u5C06\u9000\u5316\u4E3A\u660E\u6587");
|
|
20872
21097
|
}
|
|
@@ -20907,7 +21132,7 @@ function startServer(opts = {}) {
|
|
|
20907
21132
|
hubUrl: fleetCred?.hubUrl,
|
|
20908
21133
|
gatewayUrl: fleetCred?.gatewayUrl ?? env2("FLEET_GATEWAY_URL"),
|
|
20909
21134
|
online: fleet?.isConnected() ?? false,
|
|
20910
|
-
label: fleetCred?.label,
|
|
21135
|
+
label: fleetCred?.label ?? store.loadNodeLabel() ?? void 0,
|
|
20911
21136
|
lastError: fleet?.getLastError() ?? void 0,
|
|
20912
21137
|
reconnectCount: fleet?.getErrorCount() ?? 0
|
|
20913
21138
|
};
|
|
@@ -20916,27 +21141,53 @@ function startServer(opts = {}) {
|
|
|
20916
21141
|
status: fleetStatus,
|
|
20917
21142
|
async enroll(input) {
|
|
20918
21143
|
const nodeId = ensureNodeId(store);
|
|
21144
|
+
const label = input.label?.trim() || defaultNodeLabel();
|
|
20919
21145
|
const cred = input.account ? await hubEnrollByAccount(input.hubUrl, {
|
|
20920
21146
|
email: input.account.email,
|
|
20921
21147
|
phone: input.account.phone,
|
|
20922
21148
|
password: input.account.password,
|
|
20923
21149
|
code: input.account.smsCode,
|
|
20924
21150
|
nodeId,
|
|
20925
|
-
label
|
|
21151
|
+
label
|
|
20926
21152
|
}) : await hubEnrollByCode(input.hubUrl, {
|
|
20927
21153
|
code: input.code,
|
|
20928
21154
|
nodeId,
|
|
20929
|
-
label
|
|
21155
|
+
label
|
|
20930
21156
|
});
|
|
20931
21157
|
const full = {
|
|
20932
21158
|
...cred,
|
|
20933
|
-
label
|
|
21159
|
+
label,
|
|
20934
21160
|
enrolledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
20935
21161
|
};
|
|
20936
21162
|
store.saveFleetCredential(full);
|
|
21163
|
+
store.saveNodeLabel(label);
|
|
20937
21164
|
connectFleet(full);
|
|
20938
21165
|
return fleetStatus();
|
|
20939
21166
|
},
|
|
21167
|
+
async rename(label) {
|
|
21168
|
+
const name = label.trim();
|
|
21169
|
+
store.saveNodeLabel(name);
|
|
21170
|
+
if (fleetCred) {
|
|
21171
|
+
fleetCred = { ...fleetCred, label: name };
|
|
21172
|
+
store.saveFleetCredential(fleetCred);
|
|
21173
|
+
}
|
|
21174
|
+
fleet?.republishLabel();
|
|
21175
|
+
let hubSynced = false;
|
|
21176
|
+
let hubError;
|
|
21177
|
+
const cred = fleetCred;
|
|
21178
|
+
if (cred?.hubUrl && cred.fleetToken) {
|
|
21179
|
+
try {
|
|
21180
|
+
await hubUpdateNodeLabelSelf(cred.hubUrl, cred.fleetToken, {
|
|
21181
|
+
nodeId: ensureNodeId(store),
|
|
21182
|
+
label: name
|
|
21183
|
+
});
|
|
21184
|
+
hubSynced = true;
|
|
21185
|
+
} catch (e) {
|
|
21186
|
+
hubError = e instanceof Error ? e.message : String(e);
|
|
21187
|
+
}
|
|
21188
|
+
}
|
|
21189
|
+
return { ...fleetStatus(), hubSynced, hubError };
|
|
21190
|
+
},
|
|
20940
21191
|
unlink() {
|
|
20941
21192
|
fleet?.close();
|
|
20942
21193
|
fleet = null;
|
|
@@ -21067,7 +21318,7 @@ function startServer(opts = {}) {
|
|
|
21067
21318
|
server.timeout = 0;
|
|
21068
21319
|
server.keepAliveTimeout = 65e3;
|
|
21069
21320
|
server.headersTimeout = 66e3;
|
|
21070
|
-
const ready = new Promise((
|
|
21321
|
+
const ready = new Promise((resolve25, reject) => {
|
|
21071
21322
|
listenWithPortFallback(server, port, host, dataDir).then((actualPort) => {
|
|
21072
21323
|
const info = {
|
|
21073
21324
|
host,
|
|
@@ -21084,7 +21335,7 @@ function startServer(opts = {}) {
|
|
|
21084
21335
|
printReady(info, qq);
|
|
21085
21336
|
}
|
|
21086
21337
|
updater?.start();
|
|
21087
|
-
|
|
21338
|
+
resolve25(info);
|
|
21088
21339
|
}, reject);
|
|
21089
21340
|
});
|
|
21090
21341
|
return {
|
|
@@ -21102,7 +21353,7 @@ function printReady(info, qq) {
|
|
|
21102
21353
|
`zqagent server \u76D1\u542C http://${info.host}:${info.port}`,
|
|
21103
21354
|
`\u6570\u636E\u76EE\u5F55: ${info.dataDir}`,
|
|
21104
21355
|
`\u5BA1\u6279\u6302\u8D77\u8D85\u65F6: ${env2("APPROVAL_TIMEOUT_SECONDS") ?? 900}s\uFF08\u8D85\u65F6\u540E\u56DE\u6536\u5185\u5B58\u4EFB\u52A1\uFF0C\u53EF\u7ECF resume \u6062\u590D\uFF09`,
|
|
21105
|
-
env2("ZQAGENT_LOG_ADMIN_KEY") === "0" ? `\u7BA1\u7406\u5458\u5BC6\u94A5: ${maskKey(info.adminKey)}\uFF08\u5DF2\u8131\u654F\uFF0C\u5B8C\u6574\u503C\u89C1 ${
|
|
21356
|
+
env2("ZQAGENT_LOG_ADMIN_KEY") === "0" ? `\u7BA1\u7406\u5458\u5BC6\u94A5: ${maskKey(info.adminKey)}\uFF08\u5DF2\u8131\u654F\uFF0C\u5B8C\u6574\u503C\u89C1 ${path40.join(info.dataDir, "admin.json")}\uFF09` : `\u7BA1\u7406\u5458\u5BC6\u94A5: ${info.adminKey}\uFF08\u63A7\u5236\u53F0\u591A\u9879\u76EE\u5165\u53E3\uFF1A/api/v1/projects\uFF1B\u9879\u76EE\u7EA7\u63A5\u53E3\u52A0 X-Project-Id \u5934\uFF09`
|
|
21106
21357
|
];
|
|
21107
21358
|
if (info.fleetNodeId) {
|
|
21108
21359
|
lines.push(
|
|
@@ -21235,7 +21486,7 @@ async function runServeCommand(argv) {
|
|
|
21235
21486
|
|
|
21236
21487
|
// src/cli/update.ts
|
|
21237
21488
|
init_esm_shims();
|
|
21238
|
-
import * as
|
|
21489
|
+
import * as path41 from "path";
|
|
21239
21490
|
function parse3(argv) {
|
|
21240
21491
|
const out = { status: false, check: false, now: false, rollback: false };
|
|
21241
21492
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -21264,7 +21515,7 @@ function restartHint() {
|
|
|
21264
21515
|
}
|
|
21265
21516
|
async function runUpdateCommand(argv) {
|
|
21266
21517
|
const args = parse3(argv);
|
|
21267
|
-
const dataDir =
|
|
21518
|
+
const dataDir = path41.resolve(args.dataDir ?? process.env.DATA_DIR ?? DEFAULT_DATA_DIR);
|
|
21268
21519
|
const controller = new UpdateController({ dataDir, isIdle: () => true });
|
|
21269
21520
|
if (args.rollback) {
|
|
21270
21521
|
const restored = controller.rollbackNow();
|
|
@@ -21313,9 +21564,9 @@ async function runUpdateCommand(argv) {
|
|
|
21313
21564
|
// src/cli/sessionMeta.ts
|
|
21314
21565
|
init_esm_shims();
|
|
21315
21566
|
import * as fs32 from "fs";
|
|
21316
|
-
import * as
|
|
21567
|
+
import * as path42 from "path";
|
|
21317
21568
|
function updateSessionMetaFile(stateDir2, sessionId, patch) {
|
|
21318
|
-
const file =
|
|
21569
|
+
const file = path42.join(stateDir2, `${sessionId}_state.json`);
|
|
21319
21570
|
try {
|
|
21320
21571
|
const raw = fs32.readFileSync(file, "utf8");
|
|
21321
21572
|
const state = JSON.parse(raw);
|
|
@@ -21332,8 +21583,8 @@ function updateSessionMetaFile(stateDir2, sessionId, patch) {
|
|
|
21332
21583
|
// src/cli/debug.ts
|
|
21333
21584
|
init_esm_shims();
|
|
21334
21585
|
import * as fs33 from "fs";
|
|
21335
|
-
import * as
|
|
21336
|
-
import * as
|
|
21586
|
+
import * as os11 from "os";
|
|
21587
|
+
import * as path43 from "path";
|
|
21337
21588
|
var LOG_NAME = "zqagent-debug.log";
|
|
21338
21589
|
var TRUTHY = /^(1|true|yes|on)$/i;
|
|
21339
21590
|
function bootRef() {
|
|
@@ -21344,9 +21595,9 @@ var logFile = null;
|
|
|
21344
21595
|
var startedAt = Date.now();
|
|
21345
21596
|
function resolveLogFile() {
|
|
21346
21597
|
const explicit = process.env.ZQAGENT_DEBUG_LOG;
|
|
21347
|
-
if (explicit) return
|
|
21598
|
+
if (explicit) return path43.resolve(explicit);
|
|
21348
21599
|
const dir = process.env.ZQAGENT_DEBUG_DIR;
|
|
21349
|
-
return
|
|
21600
|
+
return path43.join(dir ? path43.resolve(dir) : os11.tmpdir(), LOG_NAME);
|
|
21350
21601
|
}
|
|
21351
21602
|
function enableDebug(argv = process.argv) {
|
|
21352
21603
|
if (enabled) return true;
|
|
@@ -21362,7 +21613,7 @@ function enableDebug(argv = process.argv) {
|
|
|
21362
21613
|
enabled = true;
|
|
21363
21614
|
logFile = resolveLogFile();
|
|
21364
21615
|
try {
|
|
21365
|
-
fs33.mkdirSync(
|
|
21616
|
+
fs33.mkdirSync(path43.dirname(logFile), { recursive: true });
|
|
21366
21617
|
fs33.writeFileSync(logFile, "");
|
|
21367
21618
|
} catch {
|
|
21368
21619
|
logFile = null;
|
|
@@ -21540,7 +21791,7 @@ if (enableDebug(process.argv)) {
|
|
|
21540
21791
|
logEnvironment();
|
|
21541
21792
|
}
|
|
21542
21793
|
var MODEL = process.env.OPENAI_MODEL ?? "gpt-4o";
|
|
21543
|
-
var WORKSPACE =
|
|
21794
|
+
var WORKSPACE = path44.resolve(process.env.WORKSPACE ?? ".");
|
|
21544
21795
|
var MAX_ITERATIONS = parseMaxIterations(process.env.MAX_ITERATIONS, 300);
|
|
21545
21796
|
var STATE_DIR = stateDir();
|
|
21546
21797
|
function listSessions() {
|
|
@@ -21551,7 +21802,7 @@ function listSessions() {
|
|
|
21551
21802
|
if (!f.endsWith("_state.json")) continue;
|
|
21552
21803
|
try {
|
|
21553
21804
|
const parsed = JSON.parse(
|
|
21554
|
-
fs34.readFileSync(
|
|
21805
|
+
fs34.readFileSync(path44.join(STATE_DIR, f), "utf8")
|
|
21555
21806
|
);
|
|
21556
21807
|
if (parsed && typeof parsed.sessionId === "string") {
|
|
21557
21808
|
sessions.push(parsed);
|
|
@@ -21585,7 +21836,7 @@ function printLastAssistantMessage(messages) {
|
|
|
21585
21836
|
out += renderer.flush();
|
|
21586
21837
|
cliWrite(out + "\n");
|
|
21587
21838
|
}
|
|
21588
|
-
var AGENTS_FILE =
|
|
21839
|
+
var AGENTS_FILE = path44.join(WORKSPACE, ".agent", "agents.json");
|
|
21589
21840
|
function loadAgentsFromFile() {
|
|
21590
21841
|
try {
|
|
21591
21842
|
if (!fs34.existsSync(AGENTS_FILE)) return [];
|
|
@@ -21601,7 +21852,7 @@ function loadAgentsFromFile() {
|
|
|
21601
21852
|
}
|
|
21602
21853
|
function saveAgentsToFile(defs) {
|
|
21603
21854
|
try {
|
|
21604
|
-
fs34.mkdirSync(
|
|
21855
|
+
fs34.mkdirSync(path44.dirname(AGENTS_FILE), { recursive: true });
|
|
21605
21856
|
fs34.writeFileSync(AGENTS_FILE, JSON.stringify(defs, null, 2) + "\n", "utf8");
|
|
21606
21857
|
} catch (err) {
|
|
21607
21858
|
cliErr(`\u26A0\uFE0F \u4FDD\u5B58 agents \u914D\u7F6E\u5931\u8D25: ${err}`);
|
|
@@ -21611,8 +21862,8 @@ var agentRegistry = new AgentRegistry([
|
|
|
21611
21862
|
...BUILTIN_AGENTS,
|
|
21612
21863
|
...loadAgentsFromFile()
|
|
21613
21864
|
]);
|
|
21614
|
-
var MCP_FILE =
|
|
21615
|
-
var COMMAND_TOOLS_FILE =
|
|
21865
|
+
var MCP_FILE = path44.join(WORKSPACE, ".agent", "mcp.json");
|
|
21866
|
+
var COMMAND_TOOLS_FILE = path44.join(WORKSPACE, ".agent", "tools.json");
|
|
21616
21867
|
function loadJsonArray(file, validate) {
|
|
21617
21868
|
try {
|
|
21618
21869
|
if (!fs34.existsSync(file)) return [];
|
|
@@ -21626,7 +21877,7 @@ function loadJsonArray(file, validate) {
|
|
|
21626
21877
|
}
|
|
21627
21878
|
function saveJsonFile(file, data) {
|
|
21628
21879
|
try {
|
|
21629
|
-
fs34.mkdirSync(
|
|
21880
|
+
fs34.mkdirSync(path44.dirname(file), { recursive: true });
|
|
21630
21881
|
fs34.writeFileSync(file, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
21631
21882
|
} catch (err) {
|
|
21632
21883
|
cliErr(`\u26A0\uFE0F \u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${err}`);
|
|
@@ -21699,7 +21950,7 @@ ${stderr}` : ""
|
|
|
21699
21950
|
}
|
|
21700
21951
|
}
|
|
21701
21952
|
var mcpManager = null;
|
|
21702
|
-
function
|
|
21953
|
+
function parseArgs2(argv) {
|
|
21703
21954
|
const result = {};
|
|
21704
21955
|
for (let i = 0; i < argv.length; i++) {
|
|
21705
21956
|
if (argv[i] === "--resume" || argv[i] === "--r") {
|
|
@@ -21728,13 +21979,13 @@ function pruneEmptySessions(keepSessionId) {
|
|
|
21728
21979
|
if (!isEmptySession(s) || s.sessionId === keepSessionId) continue;
|
|
21729
21980
|
for (const suffix of ["_state.json", ".jsonl"]) {
|
|
21730
21981
|
try {
|
|
21731
|
-
fs34.unlinkSync(
|
|
21982
|
+
fs34.unlinkSync(path44.join(STATE_DIR, `${s.sessionId}${suffix}`));
|
|
21732
21983
|
} catch {
|
|
21733
21984
|
}
|
|
21734
21985
|
}
|
|
21735
21986
|
}
|
|
21736
21987
|
}
|
|
21737
|
-
var cliArgs =
|
|
21988
|
+
var cliArgs = parseArgs2(process.argv.slice(2));
|
|
21738
21989
|
var resumeId = cliArgs["resume"];
|
|
21739
21990
|
var SESSION_ID = resolveInitialSessionId(resumeId);
|
|
21740
21991
|
if (!resumeId) pruneEmptySessions(SESSION_ID);
|
|
@@ -21791,7 +22042,7 @@ function question(prompt) {
|
|
|
21791
22042
|
}
|
|
21792
22043
|
function readPassword(prompt) {
|
|
21793
22044
|
if (!process.stdin.isTTY) return question(prompt);
|
|
21794
|
-
return new Promise((
|
|
22045
|
+
return new Promise((resolve25) => {
|
|
21795
22046
|
const savedDataListeners = process.stdin.listeners("data");
|
|
21796
22047
|
process.stdin.removeAllListeners("data");
|
|
21797
22048
|
cliWrite(prompt);
|
|
@@ -21807,13 +22058,13 @@ function readPassword(prompt) {
|
|
|
21807
22058
|
if (ch === "\r" || ch === "\n") {
|
|
21808
22059
|
cleanup();
|
|
21809
22060
|
cliWrite("\n");
|
|
21810
|
-
|
|
22061
|
+
resolve25(buf);
|
|
21811
22062
|
return;
|
|
21812
22063
|
}
|
|
21813
22064
|
if (ch === "") {
|
|
21814
22065
|
cleanup();
|
|
21815
22066
|
cliWrite("\n");
|
|
21816
|
-
|
|
22067
|
+
resolve25("");
|
|
21817
22068
|
return;
|
|
21818
22069
|
}
|
|
21819
22070
|
if (ch === "\x7F" || ch === "\b") {
|
|
@@ -22246,9 +22497,9 @@ async function offerTerminalSetup(engine, canUseAgent) {
|
|
|
22246
22497
|
cliLog("");
|
|
22247
22498
|
}
|
|
22248
22499
|
}
|
|
22249
|
-
var KNOWN_SUBCOMMANDS = /* @__PURE__ */ new Set(["link", "serve", "update"]);
|
|
22500
|
+
var KNOWN_SUBCOMMANDS = /* @__PURE__ */ new Set(["link", "serve", "update", "rename"]);
|
|
22250
22501
|
function cliVersion() {
|
|
22251
|
-
const env3 = "0.2.
|
|
22502
|
+
const env3 = "0.2.14"?.trim();
|
|
22252
22503
|
if (env3) return env3;
|
|
22253
22504
|
try {
|
|
22254
22505
|
const req2 = createRequire4(import.meta.url);
|
|
@@ -22269,6 +22520,7 @@ function printCliUsage() {
|
|
|
22269
22520
|
cliLog(" zqagent link [--hub <url>] [--username <\u90AE\u7BB1/\u624B\u673A\u53F7> --password <\u5BC6\u7801>]");
|
|
22270
22521
|
cliLog(" [--code <\u63A5\u5165\u7801>] [--label \u540D\u79F0]");
|
|
22271
22522
|
cliLog(" \u628A\u672C\u673A\u8282\u70B9\u63A5\u5165 Hub\uFF08\u8D26\u53F7\u76F4\u8FDE\u6216\u63A5\u5165\u7801\uFF1B\u672C\u673A\u6709 server \u65F6\u70ED\u63A5\u5165\uFF09");
|
|
22523
|
+
cliLog(" zqagent rename <\u540D\u79F0> \u4FEE\u6539\u8282\u70B9\u5728 Hub \u663E\u793A\u7684\u540D\u79F0\uFF08\u672C\u673A\u4E0E Hub \u8BB0\u5F55\u4E00\u8D77\u66F4\u65B0\uFF09");
|
|
22272
22524
|
cliLog("");
|
|
22273
22525
|
cliLog("serve \u9009\u9879\uFF1A--port <n> --host <addr> --data-dir <dir>");
|
|
22274
22526
|
cliLog(" --hub <url> --enroll-code <\u7801> --label <\u540D\u79F0> \uFF08\u542F\u52A8\u5373\u63A5\u5165\uFF09");
|
|
@@ -22296,6 +22548,11 @@ async function main() {
|
|
|
22296
22548
|
rl.close();
|
|
22297
22549
|
process.exit(ok2 ? 0 : 1);
|
|
22298
22550
|
}
|
|
22551
|
+
if (subcommand === "rename") {
|
|
22552
|
+
const ok2 = await runRenameCommand(process.argv.slice(3));
|
|
22553
|
+
rl.close();
|
|
22554
|
+
process.exit(ok2 ? 0 : 1);
|
|
22555
|
+
}
|
|
22299
22556
|
if (subcommand === "serve") {
|
|
22300
22557
|
rl.close();
|
|
22301
22558
|
await runServeCommand(process.argv.slice(3));
|
|
@@ -22457,7 +22714,7 @@ async function main() {
|
|
|
22457
22714
|
}
|
|
22458
22715
|
});
|
|
22459
22716
|
const savedState = resumeId ? FileLogHook.loadState(resumeId, STATE_DIR) : null;
|
|
22460
|
-
const metaStateFile =
|
|
22717
|
+
const metaStateFile = path44.join(STATE_DIR, `${SESSION_ID}_state.json`);
|
|
22461
22718
|
const stateForMeta = savedState ?? (fs34.existsSync(metaStateFile) ? FileLogHook.loadState(SESSION_ID, STATE_DIR) : null);
|
|
22462
22719
|
sessionMeta = {
|
|
22463
22720
|
sessionId: SESSION_ID,
|