hvip-mcp-server 0.4.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -165
- package/dist/hub-server.js +1433 -115
- package/dist/hub-worker.js +97 -22
- package/dist/index.js +495 -62
- package/package.json +76 -68
package/dist/hub-worker.js
CHANGED
|
@@ -3717,6 +3717,56 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
|
3717
3717
|
|
|
3718
3718
|
// src/hub-worker.ts
|
|
3719
3719
|
var import_node_child_process = require("node:child_process");
|
|
3720
|
+
|
|
3721
|
+
// src/utils/logger.ts
|
|
3722
|
+
var LEVEL_EMOJI = {
|
|
3723
|
+
[0 /* DEBUG */]: "\u{1F50D}",
|
|
3724
|
+
[1 /* INFO */]: "\u2139\uFE0F",
|
|
3725
|
+
[2 /* WARN */]: "\u26A0\uFE0F",
|
|
3726
|
+
[3 /* ERROR */]: "\u274C",
|
|
3727
|
+
[4 /* SILENT */]: ""
|
|
3728
|
+
};
|
|
3729
|
+
function resolveLevel() {
|
|
3730
|
+
const raw = (process.env.LOG_LEVEL || "").toUpperCase();
|
|
3731
|
+
if (raw === "DEBUG") return 0 /* DEBUG */;
|
|
3732
|
+
if (raw === "WARN" || raw === "WARNING") return 2 /* WARN */;
|
|
3733
|
+
if (raw === "ERROR") return 3 /* ERROR */;
|
|
3734
|
+
if (raw === "SILENT" || raw === "OFF") return 4 /* SILENT */;
|
|
3735
|
+
return 1 /* INFO */;
|
|
3736
|
+
}
|
|
3737
|
+
var currentLevel = resolveLevel();
|
|
3738
|
+
var LoggerImpl = class {
|
|
3739
|
+
constructor(tag) {
|
|
3740
|
+
this.tag = tag;
|
|
3741
|
+
}
|
|
3742
|
+
tag;
|
|
3743
|
+
debug(msg) {
|
|
3744
|
+
this.write(0 /* DEBUG */, msg);
|
|
3745
|
+
}
|
|
3746
|
+
info(msg) {
|
|
3747
|
+
this.write(1 /* INFO */, msg);
|
|
3748
|
+
}
|
|
3749
|
+
warn(msg) {
|
|
3750
|
+
this.write(2 /* WARN */, msg);
|
|
3751
|
+
}
|
|
3752
|
+
error(msg) {
|
|
3753
|
+
this.write(3 /* ERROR */, msg);
|
|
3754
|
+
}
|
|
3755
|
+
write(level, msg) {
|
|
3756
|
+
if (level < currentLevel) return;
|
|
3757
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
3758
|
+
const emoji = LEVEL_EMOJI[level];
|
|
3759
|
+
const tag = this.tag ? `[${this.tag}]` : "";
|
|
3760
|
+
const prefix = emoji ? `${emoji} ${tag}` : tag;
|
|
3761
|
+
process.stderr.write(`${ts} ${prefix} ${msg}
|
|
3762
|
+
`);
|
|
3763
|
+
}
|
|
3764
|
+
};
|
|
3765
|
+
function logger(tag) {
|
|
3766
|
+
return new LoggerImpl(tag);
|
|
3767
|
+
}
|
|
3768
|
+
|
|
3769
|
+
// src/hub-worker.ts
|
|
3720
3770
|
var argv = process.argv.slice(2);
|
|
3721
3771
|
function flag(name) {
|
|
3722
3772
|
const i = argv.indexOf("--" + name);
|
|
@@ -3732,8 +3782,12 @@ var AGENT_ID = `worker-${TASK_ID}-${Date.now()}`;
|
|
|
3732
3782
|
var AGENT_NAME = `Worker\xB7${TASK_ID}`;
|
|
3733
3783
|
var CLAUDE_CLI = process.env.CLAUDE_CLI || "claude";
|
|
3734
3784
|
var WORKER_TIMEOUT_MS = parseInt(process.env.HUB_WORKER_TIMEOUT || "600000", 10);
|
|
3785
|
+
var log = logger(`Worker-${TASK_ID}`);
|
|
3735
3786
|
var ws;
|
|
3736
3787
|
var taskReceived = false;
|
|
3788
|
+
var heartbeatTimer;
|
|
3789
|
+
var taskDoneSent = false;
|
|
3790
|
+
var taskTitle = "";
|
|
3737
3791
|
function connect() {
|
|
3738
3792
|
ws = new import_websocket.default(HUB_URL);
|
|
3739
3793
|
ws.on("open", () => {
|
|
@@ -3746,6 +3800,11 @@ function connect() {
|
|
|
3746
3800
|
version: "0.3.0",
|
|
3747
3801
|
capabilities: [TASK_ID]
|
|
3748
3802
|
}));
|
|
3803
|
+
heartbeatTimer = setInterval(() => {
|
|
3804
|
+
if (ws.readyState === import_websocket.default.OPEN) {
|
|
3805
|
+
ws.send(JSON.stringify({ type: "agent:status" }));
|
|
3806
|
+
}
|
|
3807
|
+
}, 3e4);
|
|
3749
3808
|
});
|
|
3750
3809
|
ws.on("message", (raw) => {
|
|
3751
3810
|
try {
|
|
@@ -3757,6 +3816,7 @@ function connect() {
|
|
|
3757
3816
|
}
|
|
3758
3817
|
});
|
|
3759
3818
|
ws.on("close", () => {
|
|
3819
|
+
clearInterval(heartbeatTimer);
|
|
3760
3820
|
if (!taskReceived) {
|
|
3761
3821
|
process.stderr.write("[Worker] \u8FDE\u63A5\u65AD\u5F00\uFF0C5s \u540E\u91CD\u8FDE...\n");
|
|
3762
3822
|
setTimeout(connect, 5e3);
|
|
@@ -3767,6 +3827,19 @@ function connect() {
|
|
|
3767
3827
|
`);
|
|
3768
3828
|
});
|
|
3769
3829
|
}
|
|
3830
|
+
function sendTaskDone(taskId, result) {
|
|
3831
|
+
if (taskDoneSent) return;
|
|
3832
|
+
taskDoneSent = true;
|
|
3833
|
+
try {
|
|
3834
|
+
ws.send(JSON.stringify({
|
|
3835
|
+
type: "task:done",
|
|
3836
|
+
taskId,
|
|
3837
|
+
agentId: AGENT_ID,
|
|
3838
|
+
result
|
|
3839
|
+
}));
|
|
3840
|
+
} catch {
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3770
3843
|
function handleMessage(msg) {
|
|
3771
3844
|
switch (msg.type) {
|
|
3772
3845
|
case "agent:registered":
|
|
@@ -3804,8 +3877,8 @@ function detectTaskType(title) {
|
|
|
3804
3877
|
return "code";
|
|
3805
3878
|
}
|
|
3806
3879
|
function doTask(taskId, title, url, promptB64) {
|
|
3807
|
-
|
|
3808
|
-
`);
|
|
3880
|
+
taskTitle = title;
|
|
3881
|
+
log.info(`\u{1F680} \u5F00\u59CB\u6267\u884C: ${title}`);
|
|
3809
3882
|
ws.send(JSON.stringify({ type: "task:claim", taskId, agentId: AGENT_ID }));
|
|
3810
3883
|
let prompt;
|
|
3811
3884
|
let mode = "code";
|
|
@@ -3822,7 +3895,7 @@ function doTask(taskId, title, url, promptB64) {
|
|
|
3822
3895
|
}
|
|
3823
3896
|
try {
|
|
3824
3897
|
const memUrl = `http://127.0.0.1:${WEB_PORT}/api/memory/for-task?q=${encodeURIComponent(title)}`;
|
|
3825
|
-
const kbRaw = (0, import_node_child_process.execSync)(`curl -s "${memUrl}"`, { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] });
|
|
3898
|
+
const kbRaw = (0, import_node_child_process.execSync)(`curl -s "${memUrl}"`, { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"], windowsHide: true });
|
|
3826
3899
|
if (kbRaw && kbRaw.length > 0) {
|
|
3827
3900
|
const kb = JSON.parse(kbRaw.toString());
|
|
3828
3901
|
if (kb.hit > 0) {
|
|
@@ -3845,7 +3918,8 @@ Worker \u5DF2\u542F\u52A8\uFF0CClaude Code \u6B63\u5728\u521D\u59CB\u5316...`
|
|
|
3845
3918
|
const child = (0, import_node_child_process.spawn)(CLAUDE_CLI, ["-p", prompt], {
|
|
3846
3919
|
cwd: REPO_PATH,
|
|
3847
3920
|
stdio: ["pipe", "pipe", "pipe"],
|
|
3848
|
-
env: { ...process.env, NO_COLOR: "1" }
|
|
3921
|
+
env: { ...process.env, NO_COLOR: "1" },
|
|
3922
|
+
windowsHide: true
|
|
3849
3923
|
});
|
|
3850
3924
|
child.stdin.end();
|
|
3851
3925
|
let output = "";
|
|
@@ -3864,6 +3938,14 @@ ${text}`
|
|
|
3864
3938
|
const timeoutTimer = setTimeout(() => {
|
|
3865
3939
|
process.stderr.write(`[Worker] \u23F0 \u8D85\u65F6 (${WORKER_TIMEOUT_MS / 1e3}s)\uFF0C\u5F3A\u5236\u7EC8\u6B62
|
|
3866
3940
|
`);
|
|
3941
|
+
sendTaskDone(taskId, `\u274C (\u8D85\u65F6 ${WORKER_TIMEOUT_MS / 1e3}s) ${title}
|
|
3942
|
+
${output.slice(-3e3)}`);
|
|
3943
|
+
ws.send(JSON.stringify({
|
|
3944
|
+
type: "room:message",
|
|
3945
|
+
roomId: "#review",
|
|
3946
|
+
text: `\u274C ${taskId} \u8D85\u65F6 ${WORKER_TIMEOUT_MS / 1e3}s\uFF0C\u5DF2\u7EC8\u6B62\u3002\u8F93\u51FA:
|
|
3947
|
+
${output.slice(-1e3)}`
|
|
3948
|
+
}));
|
|
3867
3949
|
try {
|
|
3868
3950
|
child.kill("SIGKILL");
|
|
3869
3951
|
} catch {
|
|
@@ -3879,8 +3961,7 @@ ${text}`
|
|
|
3879
3961
|
clearInterval(progressTimer);
|
|
3880
3962
|
clearTimeout(timeoutTimer);
|
|
3881
3963
|
if (code === 0) {
|
|
3882
|
-
|
|
3883
|
-
`);
|
|
3964
|
+
log.info(`\u2705 Claude Code \u5B8C\u6210 (exit ${code})`);
|
|
3884
3965
|
if (mode === "market" || mode === "research" || mode === "template") {
|
|
3885
3966
|
ws.send(JSON.stringify({
|
|
3886
3967
|
type: "room:message",
|
|
@@ -3889,12 +3970,7 @@ ${text}`
|
|
|
3889
3970
|
|
|
3890
3971
|
${output.slice(-3e3)}`
|
|
3891
3972
|
}));
|
|
3892
|
-
|
|
3893
|
-
type: "task:done",
|
|
3894
|
-
taskId,
|
|
3895
|
-
agentId: AGENT_ID,
|
|
3896
|
-
result: output.slice(-5e3) || `${title} \u2014 \u65E0\u8F93\u51FA`
|
|
3897
|
-
}));
|
|
3973
|
+
sendTaskDone(taskId, output.slice(-5e3) || `${title} \u2014 \u65E0\u8F93\u51FA`);
|
|
3898
3974
|
try {
|
|
3899
3975
|
tagAndSave(title, output);
|
|
3900
3976
|
} catch {
|
|
@@ -3902,27 +3978,23 @@ ${output.slice(-3e3)}`
|
|
|
3902
3978
|
} else {
|
|
3903
3979
|
const branchMatch = output.match(/push.*?(task\/\S+|feat\/\S+|fix\/\S+)/i);
|
|
3904
3980
|
const branch = branchMatch ? branchMatch[1] : `worker/${AGENT_ID}`;
|
|
3905
|
-
|
|
3906
|
-
type: "task:done",
|
|
3907
|
-
taskId,
|
|
3908
|
-
agentId: AGENT_ID,
|
|
3909
|
-
branch,
|
|
3910
|
-
result: `${title} \u2014
|
|
3981
|
+
sendTaskDone(taskId, `${title} \u2014
|
|
3911
3982
|
|
|
3912
|
-
${output.slice(-5e3)}`
|
|
3913
|
-
}));
|
|
3983
|
+
${output.slice(-5e3)}`);
|
|
3914
3984
|
}
|
|
3915
3985
|
} else {
|
|
3916
|
-
|
|
3917
|
-
`);
|
|
3986
|
+
log.error(`\u274C Claude Code \u5931\u8D25 (exit ${code})`);
|
|
3918
3987
|
ws.send(JSON.stringify({
|
|
3919
3988
|
type: "room:message",
|
|
3920
3989
|
roomId: "#review",
|
|
3921
3990
|
text: `\u274C ${taskId} \u6267\u884C\u5931\u8D25 (exit ${code})\u3002\u8F93\u51FA:
|
|
3922
3991
|
${output.slice(-1e3)}`
|
|
3923
3992
|
}));
|
|
3993
|
+
sendTaskDone(taskId, `\u274C (\u5931\u8D25 exit ${code}) ${title}
|
|
3994
|
+
${output.slice(-3e3)}`);
|
|
3924
3995
|
}
|
|
3925
3996
|
setTimeout(() => {
|
|
3997
|
+
clearInterval(heartbeatTimer);
|
|
3926
3998
|
ws.close();
|
|
3927
3999
|
process.exit(code === 0 ? 0 : 1);
|
|
3928
4000
|
}, 3e4);
|
|
@@ -3930,8 +4002,10 @@ ${output.slice(-1e3)}`
|
|
|
3930
4002
|
child.on("error", (err) => {
|
|
3931
4003
|
clearInterval(progressTimer);
|
|
3932
4004
|
clearTimeout(timeoutTimer);
|
|
4005
|
+
clearInterval(heartbeatTimer);
|
|
3933
4006
|
process.stderr.write(`[Worker] Claude Code \u542F\u52A8\u5931\u8D25: ${err.message}
|
|
3934
4007
|
`);
|
|
4008
|
+
sendTaskDone(taskId, `\u274C (\u542F\u52A8\u5931\u8D25) ${title}: ${err.message}`);
|
|
3935
4009
|
ws.send(JSON.stringify({
|
|
3936
4010
|
type: "room:message",
|
|
3937
4011
|
roomId: "#review",
|
|
@@ -4033,6 +4107,7 @@ connect();
|
|
|
4033
4107
|
setTimeout(() => {
|
|
4034
4108
|
if (!taskReceived) {
|
|
4035
4109
|
process.stderr.write("[Worker] \u8D85\u65F6\u672A\u6536\u5230\u4EFB\u52A1\uFF0C\u9000\u51FA\n");
|
|
4110
|
+
clearInterval(heartbeatTimer);
|
|
4036
4111
|
ws.close();
|
|
4037
4112
|
process.exit(1);
|
|
4038
4113
|
}
|