wechat-claude-sessions 1.0.1-dev → 1.0.1-dev.usage-limit-detection.4.76a0129
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.en.md +50 -0
- package/README.md +37 -0
- package/dist/cli.js +17 -16
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +267 -16
- package/dist/daemon.js.map +1 -1
- package/dist/i18n.d.ts +12 -0
- package/dist/i18n.js +30 -0
- package/dist/i18n.js.map +1 -1
- package/dist/ilink.js +8 -1
- package/dist/ilink.js.map +1 -1
- package/dist/nudge.d.ts +2 -0
- package/dist/nudge.js +29 -0
- package/dist/nudge.js.map +1 -0
- package/dist/paths.d.ts +3 -0
- package/dist/paths.js +16 -1
- package/dist/paths.js.map +1 -1
- package/dist/replies.d.ts +3 -0
- package/dist/replies.js +51 -0
- package/dist/replies.js.map +1 -0
- package/dist/routing.js +1 -1
- package/dist/routing.js.map +1 -1
- package/dist/server.js +20 -0
- package/dist/server.js.map +1 -1
- package/dist/sessions.d.ts +1 -0
- package/dist/sessions.js.map +1 -1
- package/dist/transcripts.d.ts +9 -0
- package/dist/transcripts.js +71 -0
- package/dist/transcripts.js.map +1 -0
- package/dist/types.d.ts +6 -4
- package/dist/usage.d.ts +33 -0
- package/dist/usage.js +260 -0
- package/dist/usage.js.map +1 -0
- package/dist/utils.d.ts +9 -0
- package/dist/utils.js +9 -0
- package/dist/utils.js.map +1 -1
- package/dist/watch-inbox.js +18 -1
- package/dist/watch-inbox.js.map +1 -1
- package/package.json +1 -1
- package/templates/wechat.md +1 -1
- package/dist/router.d.ts +0 -31
- package/dist/router.js +0 -339
- package/dist/router.js.map +0 -1
package/dist/watch-inbox.js
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
import fs from "node:fs";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { clearHeartbeat, touchHeartbeat } from "./monitoring.js";
|
|
12
|
-
import {
|
|
12
|
+
import { consumeNudge } from "./nudge.js";
|
|
13
|
+
import { INBOX_DIR, NUDGE_DIR, SESSIONS_DIR } from "./paths.js";
|
|
13
14
|
function resolveSessionByCwd() {
|
|
14
15
|
let best;
|
|
15
16
|
try {
|
|
@@ -61,6 +62,14 @@ function checkInbox() {
|
|
|
61
62
|
.join(" | ");
|
|
62
63
|
process.stdout.write(`WECHAT: ${msgs.length} msg(s) - ${preview}\n`);
|
|
63
64
|
}
|
|
65
|
+
// Re-announce the pending inbox when the daemon nudges us (e.g. after a Claude
|
|
66
|
+
// usage limit lifted and the original announcement went unanswered).
|
|
67
|
+
function checkNudge() {
|
|
68
|
+
if (!consumeNudge(sessionId))
|
|
69
|
+
return;
|
|
70
|
+
lastSig = "";
|
|
71
|
+
checkInbox();
|
|
72
|
+
}
|
|
64
73
|
function cleanup() {
|
|
65
74
|
clearHeartbeat(sessionId);
|
|
66
75
|
}
|
|
@@ -80,6 +89,13 @@ try {
|
|
|
80
89
|
catch {
|
|
81
90
|
// fall back to the interval below
|
|
82
91
|
}
|
|
92
|
+
try {
|
|
93
|
+
fs.mkdirSync(NUDGE_DIR, { recursive: true, mode: 0o700 });
|
|
94
|
+
fs.watch(NUDGE_DIR, () => checkNudge());
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// fall back to the interval below
|
|
98
|
+
}
|
|
83
99
|
function sessionAlive() {
|
|
84
100
|
try {
|
|
85
101
|
const info = JSON.parse(fs.readFileSync(sessionFile, "utf-8"));
|
|
@@ -97,6 +113,7 @@ setInterval(() => {
|
|
|
97
113
|
process.exit(0);
|
|
98
114
|
}
|
|
99
115
|
touchHeartbeat(sessionId);
|
|
116
|
+
checkNudge();
|
|
100
117
|
checkInbox();
|
|
101
118
|
}, 10_000);
|
|
102
119
|
//# sourceMappingURL=watch-inbox.js.map
|
package/dist/watch-inbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch-inbox.js","sourceRoot":"","sources":["../src/watch-inbox.ts"],"names":[],"mappings":";AACA,wDAAwD;AACxD,EAAE;AACF,8CAA8C;AAC9C,EAAE;AACF,4EAA4E;AAC5E,qEAAqE;AACrE,qEAAqE;AACrE,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"watch-inbox.js","sourceRoot":"","sources":["../src/watch-inbox.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/templates/wechat.md
CHANGED
|
@@ -15,6 +15,6 @@ Start WeChat message monitoring for this session.
|
|
|
15
15
|
- Call `wechat_get_messages` to read and clear the inbox
|
|
16
16
|
- Process the message content (answer questions, execute tasks, etc.)
|
|
17
17
|
- Reply via `wechat_send_text` with the result; use `wechat_send_image` for images
|
|
18
|
-
7. Confirm to the user that WeChat monitoring is active. Check the `Routing` / `Binding` lines in the `wechat_status` output: if a binding routes plain messages to a **different** session (or the default target is another session), tell the user explicitly —
|
|
18
|
+
7. Confirm to the user that WeChat monitoring is active. Check the `Routing` / `Binding` lines in the `wechat_status` output: if a binding routes plain messages to a **different** session (or the default target is another session), tell the user explicitly — to receive plain messages here they should send `/use <n>` in WeChat to bind this session (see `/ls` for numbers). `/use off` only removes an existing binding; messages then go to the default target (the most recently active monitored session), which is not necessarily this one.
|
|
19
19
|
|
|
20
20
|
Fallback: if the Monitor tool is unavailable, use ScheduleWakeup with a 60-second interval and call `wechat_get_messages` on each wakeup (note: without the watcher heartbeat, this session will not show as `[monitoring]`, but messages explicitly routed here with `/s` still arrive).
|
package/dist/router.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { PendingMessage } from "./types.js";
|
|
2
|
-
export type SessionInfo = {
|
|
3
|
-
id: string;
|
|
4
|
-
name: string;
|
|
5
|
-
cwd: string;
|
|
6
|
-
pid: number;
|
|
7
|
-
lastActive: number;
|
|
8
|
-
};
|
|
9
|
-
export declare class WechatRouter {
|
|
10
|
-
private sessionId;
|
|
11
|
-
private sessionName;
|
|
12
|
-
private isLeader;
|
|
13
|
-
constructor(name?: string);
|
|
14
|
-
get id(): string;
|
|
15
|
-
get name(): string;
|
|
16
|
-
setName(name: string): void;
|
|
17
|
-
private register;
|
|
18
|
-
touchActive(): void;
|
|
19
|
-
private cleanup;
|
|
20
|
-
tryBecomePollLeader(): boolean;
|
|
21
|
-
get isPollLeader(): boolean;
|
|
22
|
-
getCursor(): string;
|
|
23
|
-
setCursor(cursor: string): void;
|
|
24
|
-
listSessions(): SessionInfo[];
|
|
25
|
-
private findSession;
|
|
26
|
-
private getDefaultTarget;
|
|
27
|
-
routeMessage(msg: PendingMessage, sendReply: (text: string) => Promise<void>): boolean;
|
|
28
|
-
private writeToInbox;
|
|
29
|
-
peekInbox(): number;
|
|
30
|
-
readInbox(): PendingMessage[];
|
|
31
|
-
}
|
package/dist/router.js
DELETED
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import { isMonitoring } from "./monitoring.js";
|
|
5
|
-
import { assignSessionNumbers } from "./session-numbers.js";
|
|
6
|
-
import { formatAgo } from "./utils.js";
|
|
7
|
-
const WECHAT_DIR = path.join(os.homedir(), ".claude", "wechat");
|
|
8
|
-
const SESSIONS_DIR = path.join(WECHAT_DIR, "sessions");
|
|
9
|
-
const INBOX_DIR = path.join(WECHAT_DIR, "inbox");
|
|
10
|
-
const LOCK_FILE = path.join(WECHAT_DIR, "poll.lock");
|
|
11
|
-
const CURSOR_FILE = path.join(WECHAT_DIR, "cursor.txt");
|
|
12
|
-
function detectSessionName() {
|
|
13
|
-
const cwd = process.cwd();
|
|
14
|
-
const worktreeMatch = cwd.match(/\.claude[/\\]worktrees[/\\]([^/\\]+)/);
|
|
15
|
-
if (worktreeMatch) {
|
|
16
|
-
const repoPath = cwd.split(/\.claude[/\\]worktrees[/\\]/)[0].replace(/[/\\]$/, "");
|
|
17
|
-
const repoName = path.basename(repoPath);
|
|
18
|
-
return `${repoName}/${worktreeMatch[1]}`;
|
|
19
|
-
}
|
|
20
|
-
const repoName = path.basename(cwd);
|
|
21
|
-
try {
|
|
22
|
-
let gitDir = path.join(cwd, ".git");
|
|
23
|
-
const gitStat = fs.statSync(gitDir);
|
|
24
|
-
if (!gitStat.isDirectory()) {
|
|
25
|
-
const content = fs.readFileSync(gitDir, "utf-8").trim();
|
|
26
|
-
const m = content.match(/gitdir:\s*(.+)/);
|
|
27
|
-
if (m)
|
|
28
|
-
gitDir = path.resolve(cwd, m[1]);
|
|
29
|
-
}
|
|
30
|
-
const head = fs.readFileSync(path.join(gitDir, "HEAD"), "utf-8").trim();
|
|
31
|
-
const branchMatch = head.match(/ref:\s*refs\/heads\/(.+)/);
|
|
32
|
-
if (branchMatch) {
|
|
33
|
-
return `${repoName}:${branchMatch[1]}`;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
catch { }
|
|
37
|
-
return repoName || `session-${process.pid}`;
|
|
38
|
-
}
|
|
39
|
-
function ensureDirs() {
|
|
40
|
-
for (const dir of [WECHAT_DIR, SESSIONS_DIR, INBOX_DIR]) {
|
|
41
|
-
if (!fs.existsSync(dir))
|
|
42
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function isProcessAlive(pid) {
|
|
46
|
-
try {
|
|
47
|
-
process.kill(pid, 0);
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
export class WechatRouter {
|
|
55
|
-
sessionId;
|
|
56
|
-
sessionName;
|
|
57
|
-
isLeader = false;
|
|
58
|
-
constructor(name) {
|
|
59
|
-
ensureDirs();
|
|
60
|
-
this.sessionId = String(process.pid);
|
|
61
|
-
this.sessionName = name ?? detectSessionName();
|
|
62
|
-
this.register();
|
|
63
|
-
process.on("exit", () => this.cleanup());
|
|
64
|
-
}
|
|
65
|
-
get id() {
|
|
66
|
-
return this.sessionId;
|
|
67
|
-
}
|
|
68
|
-
get name() {
|
|
69
|
-
return this.sessionName;
|
|
70
|
-
}
|
|
71
|
-
setName(name) {
|
|
72
|
-
this.sessionName = name;
|
|
73
|
-
this.register();
|
|
74
|
-
}
|
|
75
|
-
register() {
|
|
76
|
-
const info = {
|
|
77
|
-
id: this.sessionId,
|
|
78
|
-
name: this.sessionName,
|
|
79
|
-
cwd: process.cwd(),
|
|
80
|
-
pid: process.pid,
|
|
81
|
-
lastActive: Date.now(),
|
|
82
|
-
};
|
|
83
|
-
fs.writeFileSync(path.join(SESSIONS_DIR, `${this.sessionId}.json`), JSON.stringify(info));
|
|
84
|
-
}
|
|
85
|
-
touchActive() {
|
|
86
|
-
try {
|
|
87
|
-
const file = path.join(SESSIONS_DIR, `${this.sessionId}.json`);
|
|
88
|
-
const info = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
89
|
-
info.lastActive = Date.now();
|
|
90
|
-
info.name = this.sessionName;
|
|
91
|
-
fs.writeFileSync(file, JSON.stringify(info));
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
this.register();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
cleanup() {
|
|
98
|
-
try {
|
|
99
|
-
fs.unlinkSync(path.join(SESSIONS_DIR, `${this.sessionId}.json`));
|
|
100
|
-
}
|
|
101
|
-
catch { }
|
|
102
|
-
try {
|
|
103
|
-
fs.unlinkSync(path.join(INBOX_DIR, `${this.sessionId}.json`));
|
|
104
|
-
}
|
|
105
|
-
catch { }
|
|
106
|
-
if (this.isLeader) {
|
|
107
|
-
try {
|
|
108
|
-
fs.unlinkSync(LOCK_FILE);
|
|
109
|
-
}
|
|
110
|
-
catch { }
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
tryBecomePollLeader() {
|
|
114
|
-
try {
|
|
115
|
-
const lockPid = parseInt(fs.readFileSync(LOCK_FILE, "utf-8").trim(), 10);
|
|
116
|
-
if (isProcessAlive(lockPid)) {
|
|
117
|
-
this.isLeader = false;
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
fs.unlinkSync(LOCK_FILE);
|
|
121
|
-
}
|
|
122
|
-
catch {
|
|
123
|
-
// no lock file
|
|
124
|
-
}
|
|
125
|
-
try {
|
|
126
|
-
fs.writeFileSync(LOCK_FILE, String(process.pid), { flag: "wx" });
|
|
127
|
-
this.isLeader = true;
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
this.isLeader = false;
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
get isPollLeader() {
|
|
136
|
-
return this.isLeader;
|
|
137
|
-
}
|
|
138
|
-
getCursor() {
|
|
139
|
-
try {
|
|
140
|
-
return fs.readFileSync(CURSOR_FILE, "utf-8").trim();
|
|
141
|
-
}
|
|
142
|
-
catch {
|
|
143
|
-
return "";
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
setCursor(cursor) {
|
|
147
|
-
fs.writeFileSync(CURSOR_FILE, cursor);
|
|
148
|
-
}
|
|
149
|
-
listSessions() {
|
|
150
|
-
const sessions = [];
|
|
151
|
-
try {
|
|
152
|
-
for (const file of fs.readdirSync(SESSIONS_DIR)) {
|
|
153
|
-
if (!file.endsWith(".json"))
|
|
154
|
-
continue;
|
|
155
|
-
try {
|
|
156
|
-
const info = JSON.parse(fs.readFileSync(path.join(SESSIONS_DIR, file), "utf-8"));
|
|
157
|
-
if (isProcessAlive(info.pid)) {
|
|
158
|
-
sessions.push(info);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
fs.unlinkSync(path.join(SESSIONS_DIR, file));
|
|
162
|
-
try {
|
|
163
|
-
fs.unlinkSync(path.join(INBOX_DIR, file));
|
|
164
|
-
}
|
|
165
|
-
catch { }
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
catch { }
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
catch { }
|
|
172
|
-
// Monitored sessions first, stable pid order within each group; listing
|
|
173
|
-
// numbers and "/s <number>" both follow this order.
|
|
174
|
-
return sessions.sort((a, b) => {
|
|
175
|
-
const ma = isMonitoring(a.id) ? 1 : 0;
|
|
176
|
-
const mb = isMonitoring(b.id) ? 1 : 0;
|
|
177
|
-
if (ma !== mb)
|
|
178
|
-
return mb - ma;
|
|
179
|
-
return a.pid - b.pid;
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
findSession(selector) {
|
|
183
|
-
const sessions = this.listSessions();
|
|
184
|
-
const num = parseInt(selector, 10);
|
|
185
|
-
if (!isNaN(num) && String(num) === selector) {
|
|
186
|
-
const numbers = assignSessionNumbers(sessions.map((s) => s.id));
|
|
187
|
-
const byNum = sessions.find((s) => numbers[s.id] === num);
|
|
188
|
-
if (byNum)
|
|
189
|
-
return byNum;
|
|
190
|
-
}
|
|
191
|
-
const byPid = sessions.find((s) => String(s.pid) === selector);
|
|
192
|
-
if (byPid)
|
|
193
|
-
return byPid;
|
|
194
|
-
const lower = selector.toLowerCase();
|
|
195
|
-
const exact = sessions.filter((s) => s.name.toLowerCase() === lower);
|
|
196
|
-
const pool = exact.length > 0
|
|
197
|
-
? exact
|
|
198
|
-
: sessions.filter((s) => s.name.toLowerCase().includes(lower));
|
|
199
|
-
if (pool.length === 0)
|
|
200
|
-
return undefined;
|
|
201
|
-
if (pool.length === 1)
|
|
202
|
-
return pool[0];
|
|
203
|
-
// Ambiguous name: prefer monitored sessions, then the most recently active.
|
|
204
|
-
const monitored = pool.filter((s) => isMonitoring(s.id));
|
|
205
|
-
const finalPool = monitored.length > 0 ? monitored : pool;
|
|
206
|
-
return finalPool.reduce((a, b) => (a.lastActive > b.lastActive ? a : b));
|
|
207
|
-
}
|
|
208
|
-
// Prefer sessions that are actively monitoring their inbox; among those,
|
|
209
|
-
// pick the most recently active one.
|
|
210
|
-
getDefaultTarget() {
|
|
211
|
-
const sessions = this.listSessions();
|
|
212
|
-
const monitored = sessions.filter((s) => isMonitoring(s.id));
|
|
213
|
-
const pool = monitored.length > 0 ? monitored : sessions;
|
|
214
|
-
if (pool.length === 0)
|
|
215
|
-
return undefined;
|
|
216
|
-
return pool.reduce((a, b) => (a.lastActive > b.lastActive ? a : b));
|
|
217
|
-
}
|
|
218
|
-
routeMessage(msg, sendReply) {
|
|
219
|
-
const text = msg.text.trim();
|
|
220
|
-
if (text === "/help" || text === "/h") {
|
|
221
|
-
sendReply([
|
|
222
|
-
"wechat-claude 命令:",
|
|
223
|
-
"",
|
|
224
|
-
"/sessions 或 /ls — 列出活跃的 Claude session",
|
|
225
|
-
"/s <编号|名字> <消息> — 发送消息到指定 session",
|
|
226
|
-
"/help — 显示本帮助",
|
|
227
|
-
"",
|
|
228
|
-
"不带命令的消息会发送到最近活跃且在监控中的 session。",
|
|
229
|
-
].join("\n"));
|
|
230
|
-
return true;
|
|
231
|
-
}
|
|
232
|
-
const listMatch = text.match(/^\/(?:sessions|ls)(?:\s+(all|全部))?$/);
|
|
233
|
-
if (listMatch) {
|
|
234
|
-
const showAll = listMatch[1] !== undefined;
|
|
235
|
-
const sessions = this.listSessions();
|
|
236
|
-
if (sessions.length === 0) {
|
|
237
|
-
sendReply("当前没有活跃的 Claude session。");
|
|
238
|
-
return true;
|
|
239
|
-
}
|
|
240
|
-
const defaultTarget = this.getDefaultTarget();
|
|
241
|
-
const now = Date.now();
|
|
242
|
-
const IDLE_MS = 2 * 60 * 60 * 1000;
|
|
243
|
-
const isIdle = (s) => !showAll &&
|
|
244
|
-
!isMonitoring(s.id) &&
|
|
245
|
-
s.id !== defaultTarget?.id &&
|
|
246
|
-
now - s.lastActive >= IDLE_MS;
|
|
247
|
-
const labelOf = (s) => {
|
|
248
|
-
const dup = sessions.filter((o) => o.name === s.name).length > 1;
|
|
249
|
-
return dup ? `${s.name}#${s.pid}` : s.name;
|
|
250
|
-
};
|
|
251
|
-
const numbers = assignSessionNumbers(sessions.map((s) => s.id));
|
|
252
|
-
const entries = sessions.map((s) => ({ s, num: numbers[s.id] }));
|
|
253
|
-
const mainLines = entries
|
|
254
|
-
.filter(({ s }) => !isIdle(s))
|
|
255
|
-
.map(({ s, num }) => {
|
|
256
|
-
const active = now - s.lastActive < 120_000 ? "●" : "○";
|
|
257
|
-
const monitoring = isMonitoring(s.id) ? " [监控中]" : "";
|
|
258
|
-
const isDefault = s.id === defaultTarget?.id ? " ← 默认接收" : "";
|
|
259
|
-
const cwd = path.basename(s.cwd);
|
|
260
|
-
return `${active} ${num}. ${labelOf(s)}${monitoring}${isDefault}\n 目录: ${cwd} · ${formatAgo(now - s.lastActive)}活跃`;
|
|
261
|
-
});
|
|
262
|
-
const idleLines = entries
|
|
263
|
-
.filter(({ s }) => isIdle(s))
|
|
264
|
-
.map(({ s, num }) => `○ ${num}. ${labelOf(s)} · ${formatAgo(now - s.lastActive)}`);
|
|
265
|
-
const sections = [
|
|
266
|
-
`活跃 sessions (${sessions.length}):`,
|
|
267
|
-
mainLines.join("\n\n"),
|
|
268
|
-
idleLines.length > 0
|
|
269
|
-
? `闲置(未监控、2 小时以上未活跃):\n${idleLines.join("\n")}\n可发 /close idle 一键清理`
|
|
270
|
-
: "",
|
|
271
|
-
[
|
|
272
|
-
"[监控中] = 正在读取消息 · ← 默认接收 = 不带命令的消息会发到这里",
|
|
273
|
-
"用 /s <编号|名字|pid> <消息> 发送到指定 session,例: /s 1 你好",
|
|
274
|
-
].join("\n"),
|
|
275
|
-
].filter(Boolean);
|
|
276
|
-
sendReply(sections.join("\n\n"));
|
|
277
|
-
return true;
|
|
278
|
-
}
|
|
279
|
-
const bareRoute = text.match(/^\/s(?:\s+(\S+))?\s*$/);
|
|
280
|
-
if (bareRoute) {
|
|
281
|
-
sendReply("用法: /s <编号|名字> <消息>\n例: /s 1 你好\n发送 /sessions 查看可用列表。");
|
|
282
|
-
return true;
|
|
283
|
-
}
|
|
284
|
-
const routeMatch = text.match(/^\/s\s+(\S+)\s+([\s\S]+)$/);
|
|
285
|
-
if (routeMatch) {
|
|
286
|
-
const selector = routeMatch[1];
|
|
287
|
-
const message = routeMatch[2];
|
|
288
|
-
const target = this.findSession(selector);
|
|
289
|
-
if (!target) {
|
|
290
|
-
sendReply(`找不到 "${selector}"。发送 /sessions 查看列表,可用编号或名字。`);
|
|
291
|
-
return true;
|
|
292
|
-
}
|
|
293
|
-
this.writeToInbox(target.id, { ...msg, text: message });
|
|
294
|
-
return false;
|
|
295
|
-
}
|
|
296
|
-
const target = this.getDefaultTarget();
|
|
297
|
-
if (!target) {
|
|
298
|
-
sendReply("当前没有活跃的 Claude session,消息无法投递。");
|
|
299
|
-
return true;
|
|
300
|
-
}
|
|
301
|
-
this.writeToInbox(target.id, msg);
|
|
302
|
-
return false;
|
|
303
|
-
}
|
|
304
|
-
writeToInbox(sessionId, msg) {
|
|
305
|
-
const file = path.join(INBOX_DIR, `${sessionId}.json`);
|
|
306
|
-
let inbox = [];
|
|
307
|
-
try {
|
|
308
|
-
inbox = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
309
|
-
}
|
|
310
|
-
catch { }
|
|
311
|
-
inbox.push(msg);
|
|
312
|
-
fs.writeFileSync(file, JSON.stringify(inbox));
|
|
313
|
-
}
|
|
314
|
-
peekInbox() {
|
|
315
|
-
const file = path.join(INBOX_DIR, `${this.sessionId}.json`);
|
|
316
|
-
try {
|
|
317
|
-
const msgs = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
318
|
-
return msgs.length;
|
|
319
|
-
}
|
|
320
|
-
catch {
|
|
321
|
-
return 0;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
readInbox() {
|
|
325
|
-
const file = path.join(INBOX_DIR, `${this.sessionId}.json`);
|
|
326
|
-
try {
|
|
327
|
-
const raw = fs.readFileSync(file, "utf-8");
|
|
328
|
-
const msgs = JSON.parse(raw);
|
|
329
|
-
if (msgs.length > 0) {
|
|
330
|
-
fs.writeFileSync(file, "[]");
|
|
331
|
-
}
|
|
332
|
-
return msgs;
|
|
333
|
-
}
|
|
334
|
-
catch {
|
|
335
|
-
return [];
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
//# sourceMappingURL=router.js.map
|
package/dist/router.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
|