@lih-x-x/kmr 1.0.43 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +3 -3
- package/dist/index.js +97 -27
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6,9 +6,9 @@ async function checkUpdate() {
|
|
|
6
6
|
try {
|
|
7
7
|
const res = await fetch(`https://registry.npmjs.org/${"@lih-x-x/kmr"}/latest`, { signal: AbortSignal.timeout(3e3) });
|
|
8
8
|
const data = await res.json();
|
|
9
|
-
if (data.version && data.version !== "1.0.
|
|
9
|
+
if (data.version && data.version !== "1.0.45") {
|
|
10
10
|
console.log(`
|
|
11
|
-
\u2B06\uFE0F \u65B0\u7248\u672C\u53EF\u7528: ${"1.0.
|
|
11
|
+
\u2B06\uFE0F \u65B0\u7248\u672C\u53EF\u7528: ${"1.0.45"} \u2192 ${data.version}`);
|
|
12
12
|
console.log(` \u8FD0\u884C npm install -g ${"@lih-x-x/kmr"} \u66F4\u65B0
|
|
13
13
|
`);
|
|
14
14
|
}
|
|
@@ -56,7 +56,7 @@ KMR\uFF08Key Meetings Record\uFF09\u2014 \u4F1A\u8BAE\u6316\u6398\u673A
|
|
|
56
56
|
kmr --help \u663E\u793A\u5E2E\u52A9
|
|
57
57
|
`);
|
|
58
58
|
} else if (command === "--version" || command === "-v") {
|
|
59
|
-
console.log("1.0.
|
|
59
|
+
console.log("1.0.45");
|
|
60
60
|
} else if (command === "list") {
|
|
61
61
|
const { loadConfig } = await import("./config-L2SVVMAR.js");
|
|
62
62
|
const { JsonStore } = await import("./jsonStore-AL73KEUG.js");
|
package/dist/index.js
CHANGED
|
@@ -620,6 +620,7 @@ var SessionManager = class {
|
|
|
620
620
|
}
|
|
621
621
|
timeout;
|
|
622
622
|
activeSessions = /* @__PURE__ */ new Map();
|
|
623
|
+
ownedPids = /* @__PURE__ */ new Set();
|
|
623
624
|
sessionDir;
|
|
624
625
|
async handleMessage(userId, text) {
|
|
625
626
|
const sessionName = await this.ensureSession(userId);
|
|
@@ -632,6 +633,28 @@ var SessionManager = class {
|
|
|
632
633
|
const provider = getAgentProvider();
|
|
633
634
|
return provider === "codex" ? "codex" : provider;
|
|
634
635
|
}
|
|
636
|
+
/**
|
|
637
|
+
* 获取当前所有 claude-agent-acp 进程的 PID
|
|
638
|
+
*/
|
|
639
|
+
async getAgentPids() {
|
|
640
|
+
try {
|
|
641
|
+
const { stdout } = await execFileAsync("pgrep", ["-f", "claude-agent-acp"], { timeout: 5e3 });
|
|
642
|
+
return new Set(stdout.trim().split("\n").filter(Boolean).map(Number));
|
|
643
|
+
} catch {
|
|
644
|
+
return /* @__PURE__ */ new Set();
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* 记录操作前后新增的 PID
|
|
649
|
+
*/
|
|
650
|
+
async trackNewPids(before) {
|
|
651
|
+
const after = await this.getAgentPids();
|
|
652
|
+
for (const pid of after) {
|
|
653
|
+
if (!before.has(pid)) {
|
|
654
|
+
this.ownedPids.add(pid);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
635
658
|
async ensureSession(userId) {
|
|
636
659
|
const existing = this.activeSessions.get(userId);
|
|
637
660
|
if (existing) {
|
|
@@ -640,26 +663,46 @@ var SessionManager = class {
|
|
|
640
663
|
const sessionName = `kmr-${userId}`;
|
|
641
664
|
const userDir = path2.join(this.sessionDir, userId);
|
|
642
665
|
fs2.mkdirSync(userDir, { recursive: true });
|
|
643
|
-
console.log(`[session] \u521B\u5EFA\u65B0 session: ${sessionName}`);
|
|
644
666
|
const agentCmd = this.getAgentCmd();
|
|
667
|
+
let sessionExists = false;
|
|
645
668
|
try {
|
|
646
|
-
await execFileAsync("acpx", [agentCmd, "sessions", "
|
|
647
|
-
timeout:
|
|
669
|
+
const { stdout } = await execFileAsync("acpx", [agentCmd, "sessions", "list"], {
|
|
670
|
+
timeout: 1e4,
|
|
648
671
|
maxBuffer: 1024 * 1024,
|
|
649
672
|
env: getExecEnv()
|
|
650
673
|
});
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
throw new Error(`\u521B\u5EFA\u4F1A\u8BDD\u5931\u8D25: ${err.message}`);
|
|
654
|
-
}
|
|
655
|
-
try {
|
|
656
|
-
await execFileAsync(
|
|
657
|
-
"acpx",
|
|
658
|
-
["--approve-all", agentCmd, "-s", sessionName, SESSION_SKILL],
|
|
659
|
-
{ timeout: this.timeout, maxBuffer: 1024 * 1024, env: getExecEnv() }
|
|
674
|
+
sessionExists = stdout.split("\n").some(
|
|
675
|
+
(line) => !line.includes("[closed]") && line.split(" ")[1]?.trim() === sessionName
|
|
660
676
|
);
|
|
661
|
-
} catch
|
|
662
|
-
|
|
677
|
+
} catch {
|
|
678
|
+
}
|
|
679
|
+
if (sessionExists) {
|
|
680
|
+
console.log(`[session] \u590D\u7528\u5DF2\u6709 acpx session: ${sessionName}`);
|
|
681
|
+
} else {
|
|
682
|
+
console.log(`[session] \u521B\u5EFA\u65B0 session: ${sessionName}`);
|
|
683
|
+
const pidsBefore = await this.getAgentPids();
|
|
684
|
+
try {
|
|
685
|
+
await execFileAsync("acpx", [agentCmd, "sessions", "ensure", "--name", sessionName], {
|
|
686
|
+
timeout: this.timeout,
|
|
687
|
+
maxBuffer: 1024 * 1024,
|
|
688
|
+
env: getExecEnv()
|
|
689
|
+
});
|
|
690
|
+
} catch (err) {
|
|
691
|
+
console.error(`[session] \u521B\u5EFA session \u5931\u8D25:`, err.message);
|
|
692
|
+
throw new Error(`\u521B\u5EFA\u4F1A\u8BDD\u5931\u8D25: ${err.message}`);
|
|
693
|
+
}
|
|
694
|
+
await this.trackNewPids(pidsBefore);
|
|
695
|
+
const pidsBefore2 = await this.getAgentPids();
|
|
696
|
+
try {
|
|
697
|
+
await execFileAsync(
|
|
698
|
+
"acpx",
|
|
699
|
+
["--approve-all", agentCmd, "-s", sessionName, SESSION_SKILL],
|
|
700
|
+
{ timeout: this.timeout, maxBuffer: 1024 * 1024, env: getExecEnv() }
|
|
701
|
+
);
|
|
702
|
+
} catch (err) {
|
|
703
|
+
console.error(`[session] \u89D2\u8272\u8BBE\u5B9A\u5931\u8D25:`, err.message);
|
|
704
|
+
}
|
|
705
|
+
await this.trackNewPids(pidsBefore2);
|
|
663
706
|
}
|
|
664
707
|
this.activeSessions.set(userId, {
|
|
665
708
|
name: sessionName,
|
|
@@ -669,14 +712,17 @@ var SessionManager = class {
|
|
|
669
712
|
}
|
|
670
713
|
async sendToSession(sessionName, text) {
|
|
671
714
|
const agentCmd = this.getAgentCmd();
|
|
715
|
+
const pidsBefore = await this.getAgentPids();
|
|
672
716
|
try {
|
|
673
717
|
const { stdout } = await execFileAsync(
|
|
674
718
|
"acpx",
|
|
675
719
|
["--approve-all", agentCmd, "-s", sessionName, text],
|
|
676
720
|
{ timeout: this.timeout, maxBuffer: 1024 * 1024, env: getExecEnv() }
|
|
677
721
|
);
|
|
722
|
+
await this.trackNewPids(pidsBefore);
|
|
678
723
|
return this.extractReply(stdout);
|
|
679
724
|
} catch (err) {
|
|
725
|
+
await this.trackNewPids(pidsBefore);
|
|
680
726
|
if (err.killed) {
|
|
681
727
|
throw new Error(`AI \u56DE\u590D\u8D85\u65F6 (${this.timeout}ms)`);
|
|
682
728
|
}
|
|
@@ -737,6 +783,26 @@ var SessionManager = class {
|
|
|
737
783
|
}
|
|
738
784
|
this.activeSessions.delete(userId);
|
|
739
785
|
}
|
|
786
|
+
/**
|
|
787
|
+
* 关闭所有活跃 session 并杀掉自己启动的进程,服务退出时调用
|
|
788
|
+
*/
|
|
789
|
+
async closeAll() {
|
|
790
|
+
const userIds = [...this.activeSessions.keys()];
|
|
791
|
+
if (userIds.length > 0) {
|
|
792
|
+
console.log(`[session] \u6B63\u5728\u5173\u95ED ${userIds.length} \u4E2A\u6D3B\u8DC3 session...`);
|
|
793
|
+
await Promise.all(userIds.map((uid) => this.closeSession(uid)));
|
|
794
|
+
}
|
|
795
|
+
if (this.ownedPids.size > 0) {
|
|
796
|
+
console.log(`[session] \u6B63\u5728\u6E05\u7406 ${this.ownedPids.size} \u4E2A agent \u8FDB\u7A0B...`);
|
|
797
|
+
for (const pid of this.ownedPids) {
|
|
798
|
+
try {
|
|
799
|
+
process.kill(pid, "SIGTERM");
|
|
800
|
+
} catch {
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
this.ownedPids.clear();
|
|
804
|
+
}
|
|
805
|
+
}
|
|
740
806
|
};
|
|
741
807
|
|
|
742
808
|
// src/index.ts
|
|
@@ -1043,22 +1109,26 @@ async function main() {
|
|
|
1043
1109
|
}
|
|
1044
1110
|
}, 6e4);
|
|
1045
1111
|
}
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1112
|
+
let exiting = false;
|
|
1113
|
+
const onExit = async (signal) => {
|
|
1114
|
+
if (exiting) return;
|
|
1115
|
+
exiting = true;
|
|
1116
|
+
console.log(`[exit] \u6536\u5230 ${signal}\uFF0C\u6B63\u5728\u9000\u51FA...`);
|
|
1117
|
+
try {
|
|
1118
|
+
await sessionManager.closeAll();
|
|
1119
|
+
} catch (err) {
|
|
1120
|
+
console.error("[exit] \u5173\u95ED session \u5931\u8D25:", err.message);
|
|
1121
|
+
}
|
|
1122
|
+
if (config.lark.adminOpenId) {
|
|
1053
1123
|
try {
|
|
1054
|
-
await messenger.sendToUser(
|
|
1124
|
+
await messenger.sendToUser(config.lark.adminOpenId, `\u26D4 KMR \u670D\u52A1\u5DF2\u505C\u6B62\uFF08${signal}\uFF09`);
|
|
1055
1125
|
} catch (err) {
|
|
1056
1126
|
console.error("[notify] \u63A8\u9001\u505C\u6B62\u901A\u77E5\u5931\u8D25:", err.message);
|
|
1057
1127
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1128
|
+
}
|
|
1129
|
+
process.exit(0);
|
|
1130
|
+
};
|
|
1131
|
+
process.on("SIGINT", () => onExit("SIGINT"));
|
|
1132
|
+
process.on("SIGTERM", () => onExit("SIGTERM"));
|
|
1063
1133
|
}
|
|
1064
1134
|
main().catch(console.error);
|