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/README.en.md
CHANGED
|
@@ -85,6 +85,7 @@ Send these from WeChat to control routing:
|
|
|
85
85
|
| `/runs` | List running `/run` task sessions |
|
|
86
86
|
| `/stop <name>` | Kill a `/run` task session (names start with `wc-`) |
|
|
87
87
|
| `/close <number\|name\|pid>` | Close a Claude session remotely — terminates its Claude process (and MCP server) and removes it from the list. Unsaved work in that session is lost. If a name matches several sessions it lists them instead of guessing; `/close <name> all` closes all matches, `/close idle` cleans up every unmonitored session idle for 2+ hours. Every close reply ends with a remaining-session summary |
|
|
88
|
+
| `/usage` | Check whether Claude's usage limit is what's blocking replies. Runs one tiny headless probe (Haiku by default — see below) |
|
|
88
89
|
| `/help` | Show command help |
|
|
89
90
|
| *(no prefix)* | Send to the most recently active **monitoring** session (falls back to most recently active overall) |
|
|
90
91
|
|
|
@@ -92,6 +93,47 @@ Delivery feedback: if a message lands in a session that isn't monitoring its
|
|
|
92
93
|
inbox, the daemon warns you immediately; if a delivered message is still
|
|
93
94
|
unread after 2 minutes, it sends a reminder.
|
|
94
95
|
|
|
96
|
+
### Usage limits (when every session goes quiet)
|
|
97
|
+
|
|
98
|
+
When the Claude account hits its usage limit, **every** session goes silent at
|
|
99
|
+
once: model calls are rejected, so nothing is read and nothing is answered —
|
|
100
|
+
from WeChat that is indistinguishable from a dead daemon. So the daemon works
|
|
101
|
+
it out itself:
|
|
102
|
+
|
|
103
|
+
1. A delivered message with no reply for 90 seconds, **and** a target session
|
|
104
|
+
whose *own* transcript (`~/.claude/projects/….jsonl` — the MCP server records
|
|
105
|
+
the exact path, so a busy neighbour sharing the directory can't mask it)
|
|
106
|
+
hasn't been written for 60 seconds — i.e. it isn't busy, it is stuck —
|
|
107
|
+
triggers one headless probe (`claude -p ok`, with no MCP servers loaded).
|
|
108
|
+
2. If the probe confirms a usage limit, the daemon says so on WeChat with the
|
|
109
|
+
expected reset time, and suppresses the misleading "that session may not be
|
|
110
|
+
monitoring" reminder. Messages you send meanwhile are still delivered, with
|
|
111
|
+
a note attached.
|
|
112
|
+
3. When the limit lifts, the daemon sends a recovery message and gets the
|
|
113
|
+
unanswered work moving: messages still in an inbox only need their watcher
|
|
114
|
+
poked (the original announcement is long gone and never repeats); messages
|
|
115
|
+
Claude *read* but never got to answer are put back in the inbox first, since
|
|
116
|
+
there is nothing left to announce. Only deliveries with no reply are
|
|
117
|
+
replayed, so nothing is handled twice.
|
|
118
|
+
|
|
119
|
+
Probes cost a little quota, so: only one runs at a time; at most one every 5
|
|
120
|
+
minutes while things look healthy; once a limit is confirmed probes are free
|
|
121
|
+
(the request is rejected outright), and a known reset time is waited out.
|
|
122
|
+
|
|
123
|
+
Optional config (`~/.claude/wechat/config.json`):
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{ "probeModel": "claude-haiku-4-5-20251001", "claudeBin": "~/.local/bin/claude" }
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- `probeModel` — model used for the probe. Haiku by default: cheap, and
|
|
130
|
+
subscription limits are account-wide, so it is rejected by the same limit.
|
|
131
|
+
Set `"default"` to probe with your own default model — needed if the limit you
|
|
132
|
+
care about is an Opus-only weekly cap.
|
|
133
|
+
- `claudeBin` — path to the `claude` executable, only needed when launchd's
|
|
134
|
+
minimal PATH can't find it (`~/.local/bin`, `~/.claude/local`, Homebrew and
|
|
135
|
+
`/usr/local/bin` are tried).
|
|
136
|
+
|
|
95
137
|
Incoming images are downloaded and decrypted automatically to
|
|
96
138
|
`~/.claude/wechat/media/` (cleaned up after 7 days); the routed message text
|
|
97
139
|
contains the local path (`[图片: /path/to/file.png]`) so the receiving Claude
|
|
@@ -151,6 +193,11 @@ Use `wechat_set_session_name` to set a custom name.
|
|
|
151
193
|
├── daemon.log # daemon output
|
|
152
194
|
├── cursor.txt # message polling cursor
|
|
153
195
|
├── expired.flag # present when the WeChat login has expired
|
|
196
|
+
├── usage-limit.json # known Claude usage-limit state (incl. notified users)
|
|
197
|
+
├── replies/ # last time each session replied to each WeChat user
|
|
198
|
+
│ └── <pid>--<userId>
|
|
199
|
+
├── nudge/ # signal to re-announce a backlog (after a limit lifts)
|
|
200
|
+
│ └── <pid>
|
|
154
201
|
├── sessions/ # registered Claude Code sessions
|
|
155
202
|
│ └── <pid>.json
|
|
156
203
|
├── inbox/ # per-session message queues
|
|
@@ -204,6 +251,9 @@ server's pid.
|
|
|
204
251
|
4. **MCP Server** reads from its inbox when Claude calls `wechat_get_messages`
|
|
205
252
|
5. Claude processes the message and replies via `wechat_send_text`
|
|
206
253
|
6. The MCP server clears the typing indicator file; the daemon detects this and stops typing
|
|
254
|
+
7. If a message goes unread *and* unanswered for too long, the daemon checks
|
|
255
|
+
whether Claude's usage limit is the cause and explains it on WeChat (see
|
|
256
|
+
[Usage limits](#usage-limits-when-every-session-goes-quiet))
|
|
207
257
|
|
|
208
258
|
## Language
|
|
209
259
|
|
package/README.md
CHANGED
|
@@ -78,12 +78,42 @@ wechat-claude daemon # 前台运行 / 交给你自己的进程管理
|
|
|
78
78
|
| `/runs` | 列出运行中的 `/run` 任务 session |
|
|
79
79
|
| `/stop <名字>` | 终止一个 `/run` 任务 session(名字以 `wc-` 开头) |
|
|
80
80
|
| `/close <编号\|名字\|pid>` | 远程关闭一个 Claude session —— 终结它的 Claude 进程(以及 MCP server)并从列表移除。该 session 里未保存的工作会丢失。如果一个名字匹配到多个,会列出来而不是瞎猜;`/close <名字> all` 关闭全部匹配项,`/close idle` 清理所有闲置 2 小时以上且未被监控的 session。每次关闭的回复末尾都会附上剩余 session 概览 |
|
|
81
|
+
| `/usage` | 查询 Claude 用量是否已达上限(session 集体不回复时用)。会跑一次极小的 headless 探测(默认用 Haiku,见下) |
|
|
81
82
|
| `/help` | 显示命令帮助 |
|
|
82
83
|
| *(无前缀)* | 发给最近活跃的**监控中** session(没有的话退回到最近活跃的那个) |
|
|
83
84
|
|
|
84
85
|
**投递反馈**:如果消息落到了一个没在监控 inbox 的 session,daemon 会立刻警告你;如果一条
|
|
85
86
|
已投递的消息 2 分钟后仍未被读取,它会再发一条提醒。
|
|
86
87
|
|
|
88
|
+
### 用量上限(session 集体不回复)
|
|
89
|
+
|
|
90
|
+
Claude 账号一旦触达用量上限,**所有** session 会同时哑掉:模型调用被拒绝,消息既没人读、
|
|
91
|
+
也没人回,从微信看和 daemon 挂了一模一样。为此 daemon 会自己判断:
|
|
92
|
+
|
|
93
|
+
1. 一条已投递的消息 90 秒没有得到回复,**并且**目标 session 自己的 transcript
|
|
94
|
+
(`~/.claude/projects/…jsonl`,由 MCP server 记下确切路径,不会被同目录下别的 session
|
|
95
|
+
干扰)也 60 秒没有任何写入 —— 即它不是在忙,而是真的停住了 —— daemon 会跑一次 headless
|
|
96
|
+
探测(`claude -p ok`,不加载任何 MCP server)。
|
|
97
|
+
2. 探测确认是用量上限,daemon 会主动在微信里说明情况,附上预计恢复时间,并且不再发那条
|
|
98
|
+
容易误导人的"session 可能没在监控"提醒。期间新发的消息照常投递,但会附一条提示。
|
|
99
|
+
3. 上限解除后,daemon 会再发一条"已恢复",并把没被回答的消息重新推起来:还留在 inbox 里的,
|
|
100
|
+
戳一下让 watcher 重新播报(否则那条播报早过去了);已经被读走、但还没来得及回复的(inbox
|
|
101
|
+
已经被清空,没东西可播报),会先塞回 inbox 再播报。只有确实没得到回复的才会重来,不会重复处理。
|
|
102
|
+
|
|
103
|
+
探测本身要花一点点额度,所以:同一时间只跑一个;正常状态下最多 5 分钟一次;确认受限之后
|
|
104
|
+
探测是免费的(请求被直接拒绝),有明确恢复时间时会等到那个时间点再查。
|
|
105
|
+
|
|
106
|
+
可选配置(`~/.claude/wechat/config.json`):
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{ "probeModel": "claude-haiku-4-5-20251001", "claudeBin": "~/.local/bin/claude" }
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- `probeModel` —— 探测用的模型,默认 Haiku(便宜,且订阅的用量上限是账号级的,拒绝同样会
|
|
113
|
+
发生)。设成 `"default"` 用你自己的默认模型 —— 如果你想抓的是 Opus 专属的周上限,就得这么设。
|
|
114
|
+
- `claudeBin` —— `claude` 可执行文件路径,launchd 环境下 PATH 很干净时才需要(默认会依次
|
|
115
|
+
找 `~/.local/bin`、`~/.claude/local`、Homebrew、`/usr/local/bin`)。
|
|
116
|
+
|
|
87
117
|
**图片**会被自动下载解密到 `~/.claude/wechat/media/`(保留 7 天);路由后的消息文本里带
|
|
88
118
|
本地路径(`[图片: /path/to/file.png]`),接收方的 Claude session 可以直接打开该文件。
|
|
89
119
|
|
|
@@ -138,6 +168,11 @@ Session 会根据工作目录自动命名:
|
|
|
138
168
|
├── daemon.log # daemon 输出
|
|
139
169
|
├── cursor.txt # 消息轮询游标
|
|
140
170
|
├── expired.flag # 微信登录过期时存在
|
|
171
|
+
├── usage-limit.json # 已知的 Claude 用量上限状态(含已通知的用户)
|
|
172
|
+
├── replies/ # 各 session 最近一次回复各微信用户的时间戳
|
|
173
|
+
│ └── <pid>--<userId>
|
|
174
|
+
├── nudge/ # 让 watcher 重播积压 inbox 的信号(上限解除后)
|
|
175
|
+
│ └── <pid>
|
|
141
176
|
├── sessions/ # 已注册的 Claude Code session
|
|
142
177
|
│ └── <pid>.json
|
|
143
178
|
├── inbox/ # 各 session 的消息队列
|
|
@@ -189,6 +224,8 @@ wechat-claude daemon restart
|
|
|
189
224
|
4. **MCP Server** 在 Claude 调用 `wechat_get_messages` 时读取自己的 inbox
|
|
190
225
|
5. Claude 处理消息并通过 `wechat_send_text` 回复
|
|
191
226
|
6. MCP server 清除输入状态文件,daemon 检测到后停止"正在输入"
|
|
227
|
+
7. 如果长时间既没被读也没被回,daemon 会检查是不是撞上了 Claude 用量上限,并在微信里说明
|
|
228
|
+
(见[用量上限](#用量上限session-集体不回复))
|
|
192
229
|
|
|
193
230
|
## 语言
|
|
194
231
|
|
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,7 @@ import { fileURLToPath } from "node:url";
|
|
|
13
13
|
import { ILinkClient } from "./ilink.js";
|
|
14
14
|
import { pkgFile } from "./pkg-root.js";
|
|
15
15
|
import { DAEMON_PID_FILE, ensureDirs, WECHAT_DIR } from "./paths.js";
|
|
16
|
+
import { classifyMcpRegistration } from "./utils.js";
|
|
16
17
|
import * as launchd from "./launchd.js";
|
|
17
18
|
const DAEMON_JS = fileURLToPath(new URL("./daemon.js", import.meta.url));
|
|
18
19
|
const SERVER_JS = fileURLToPath(new URL("./server.js", import.meta.url));
|
|
@@ -26,18 +27,18 @@ function mcpAdd() {
|
|
|
26
27
|
stdio: ["ignore", "pipe", "pipe"],
|
|
27
28
|
}).status === 0);
|
|
28
29
|
}
|
|
29
|
-
// What the registration currently points at
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
|
|
30
|
+
// What the registration currently points at. `claude mcp get` prints a
|
|
31
|
+
// human-readable block; classifyMcpRegistration looks for this install's
|
|
32
|
+
// exact path in it (robust to spaces in the path) and treats any successful
|
|
33
|
+
// output that lacks it as an existing registration to replace — a get that
|
|
34
|
+
// succeeds must never be read as "no registration", or the stale entry
|
|
35
|
+
// survives and `claude mcp add` keeps no-opping against it.
|
|
36
|
+
function mcpRegistration() {
|
|
33
37
|
const r = spawnSync("claude", ["mcp", "get", MCP_NAME], {
|
|
34
38
|
stdio: ["ignore", "pipe", "ignore"],
|
|
35
39
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const text = r.stdout.toString();
|
|
39
|
-
const match = text.match(/\S*dist[/\\]server\.js/);
|
|
40
|
-
return match?.[0];
|
|
40
|
+
const stdout = r.status === 0 && r.stdout ? r.stdout.toString() : undefined;
|
|
41
|
+
return classifyMcpRegistration(stdout, SERVER_JS);
|
|
41
42
|
}
|
|
42
43
|
function registerMcpServer() {
|
|
43
44
|
out(`→ Registering MCP server (claude mcp add ${MCP_NAME})…`);
|
|
@@ -46,24 +47,24 @@ function registerMcpServer() {
|
|
|
46
47
|
// install, which breaks as soon as that copy is gone. So replace an existing
|
|
47
48
|
// registration rather than trusting the exit code.
|
|
48
49
|
mcpAdd();
|
|
49
|
-
let registered =
|
|
50
|
-
if (registered
|
|
51
|
-
out(` • replacing a registration that points at ${registered}`);
|
|
50
|
+
let registered = mcpRegistration();
|
|
51
|
+
if (registered.kind === "other") {
|
|
52
|
+
out(` • replacing a registration that points at ${registered.target ?? "another install"}`);
|
|
52
53
|
spawnSync("claude", ["mcp", "remove", "--scope", "user", MCP_NAME], {
|
|
53
54
|
stdio: ["ignore", "pipe", "pipe"],
|
|
54
55
|
});
|
|
55
56
|
mcpAdd();
|
|
56
|
-
registered =
|
|
57
|
+
registered = mcpRegistration();
|
|
57
58
|
}
|
|
58
|
-
if (registered ===
|
|
59
|
+
if (registered.kind === "current") {
|
|
59
60
|
out(" ✓ registered");
|
|
60
61
|
}
|
|
61
|
-
else if (registered ===
|
|
62
|
+
else if (registered.kind === "none") {
|
|
62
63
|
out(" ! failed — is the `claude` CLI on your PATH?");
|
|
63
64
|
out(` Register it manually: claude mcp add --scope user ${MCP_NAME} node ${SERVER_JS}`);
|
|
64
65
|
}
|
|
65
66
|
else {
|
|
66
|
-
out(` ! still registered to ${registered}, not this install`);
|
|
67
|
+
out(` ! still registered to ${registered.target ?? "another install"}, not this install`);
|
|
67
68
|
out(` Fix it with: claude mcp remove --scope user ${MCP_NAME}`);
|
|
68
69
|
}
|
|
69
70
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.js
CHANGED
|
@@ -6,10 +6,14 @@ import { spawnSync } from "node:child_process";
|
|
|
6
6
|
import { ILinkClient } from "./ilink.js";
|
|
7
7
|
import { clearBinding, clearBindingsToSession, getBinding, setBinding, } from "./bindings.js";
|
|
8
8
|
import { clearHeartbeat, isMonitoring } from "./monitoring.js";
|
|
9
|
+
import { nudgeSession } from "./nudge.js";
|
|
10
|
+
import { lastReplyAt, pruneReplies } from "./replies.js";
|
|
11
|
+
import { looksStalled } from "./transcripts.js";
|
|
12
|
+
import { probeUsageLimit, readUsageState, resetHint, shouldProbe, writeUsageState, } from "./usage.js";
|
|
9
13
|
import { CONFIG_FILE, CURSOR_FILE, DAEMON_PID_FILE, EXPIRED_FLAG_FILE, INBOX_DIR, MEDIA_DIR, SESSIONS_DIR, TYPING_DIR, WECHAT_DIR, ensureDirs as ensureWechatDirs, isProcessAlive, } from "./paths.js";
|
|
10
14
|
import { assignSessionNumbers } from "./session-numbers.js";
|
|
11
15
|
import { findSession, getDefaultTarget, listSessions, matchSessions, sessionLabel, sortedSessions, } from "./sessions.js";
|
|
12
|
-
import { writeToInbox } from "./inbox.js";
|
|
16
|
+
import { peekInbox, writeToInbox } from "./inbox.js";
|
|
13
17
|
import { CLAUDE_CONFIG_FILE, ensureBypassAccepted } from "./claude-config.js";
|
|
14
18
|
import { formatAgo, getLang, marker, t } from "./i18n.js";
|
|
15
19
|
import { hasTmux, isSafeSessionName, killTmuxSession, listTmuxSessions, newTmuxSession, sanitizeForSessionName, tmuxSessionExists, } from "./tmux.js";
|
|
@@ -21,6 +25,12 @@ const MEDIA_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
|
21
25
|
const UNREAD_WARN_AFTER_MS = 120_000;
|
|
22
26
|
const DELIVERY_EXPIRE_MS = 600_000;
|
|
23
27
|
const IDLE_MS = 2 * 60 * 60 * 1000;
|
|
28
|
+
// A delivery with no answer for this long is a candidate for a usage-limit
|
|
29
|
+
// check — but only if the session also looks stalled (see sessionStalled).
|
|
30
|
+
const SILENT_PROBE_AFTER_MS = 90_000;
|
|
31
|
+
// A session that is genuinely working writes to its transcript constantly; one
|
|
32
|
+
// whose model calls are being rejected writes nothing at all.
|
|
33
|
+
const TRANSCRIPT_IDLE_MS = 60_000;
|
|
24
34
|
function cleanOldMedia() {
|
|
25
35
|
try {
|
|
26
36
|
const now = Date.now();
|
|
@@ -141,42 +151,234 @@ function isTypingActive(userId) {
|
|
|
141
151
|
}
|
|
142
152
|
const extractText = sharedExtractText;
|
|
143
153
|
const deliveries = [];
|
|
144
|
-
function trackDelivery(
|
|
154
|
+
function trackDelivery(msg, sessionId, targetName) {
|
|
145
155
|
deliveries.push({
|
|
146
|
-
|
|
156
|
+
msg,
|
|
147
157
|
sessionId,
|
|
148
158
|
targetName,
|
|
149
|
-
fromUserId,
|
|
150
159
|
deliveredAt: Date.now(),
|
|
151
160
|
warned: false,
|
|
161
|
+
probed: false,
|
|
152
162
|
});
|
|
153
163
|
if (deliveries.length > 200)
|
|
154
164
|
deliveries.shift();
|
|
155
165
|
}
|
|
166
|
+
function inboxHas(sessionId, msgId) {
|
|
167
|
+
try {
|
|
168
|
+
const inbox = JSON.parse(fs.readFileSync(path.join(INBOX_DIR, `${sessionId}.json`), "utf-8"));
|
|
169
|
+
return inbox.some((m) => m.id === msgId);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Has the session gone quiet, or is it just busy? Claude Code appends to its
|
|
176
|
+
// transcript on every step, so a still-working session is never "stalled" —
|
|
177
|
+
// which keeps long tasks from triggering (and paying for) usage probes.
|
|
178
|
+
function sessionStalled(sessionId) {
|
|
179
|
+
const session = listSessions().find((s) => s.id === sessionId);
|
|
180
|
+
if (!session)
|
|
181
|
+
return false;
|
|
182
|
+
return looksStalled(session, TRANSCRIPT_IDLE_MS);
|
|
183
|
+
}
|
|
184
|
+
// Deliveries this user is still waiting on an answer for.
|
|
185
|
+
function pendingFor(userId) {
|
|
186
|
+
return deliveries.filter((d) => d.msg.fromUserId === userId);
|
|
187
|
+
}
|
|
156
188
|
function startDeliveryWatcher(client) {
|
|
157
189
|
setInterval(() => {
|
|
158
190
|
const now = Date.now();
|
|
159
191
|
for (let i = deliveries.length - 1; i >= 0; i--) {
|
|
160
192
|
const d = deliveries[i];
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
193
|
+
// That session answered this user after the delivery — done watching.
|
|
194
|
+
if (lastReplyAt(d.sessionId, d.msg.fromUserId) > d.deliveredAt) {
|
|
195
|
+
deliveries.splice(i, 1);
|
|
196
|
+
continue;
|
|
165
197
|
}
|
|
166
|
-
|
|
167
|
-
if (!stillPending || now - d.deliveredAt > DELIVERY_EXPIRE_MS) {
|
|
198
|
+
if (now - d.deliveredAt > DELIVERY_EXPIRE_MS) {
|
|
168
199
|
deliveries.splice(i, 1);
|
|
169
200
|
continue;
|
|
170
201
|
}
|
|
171
|
-
|
|
202
|
+
const stillPending = inboxHas(d.sessionId, d.msg.id);
|
|
203
|
+
// Silence can mean "unread" (never picked up) or "read but no reply"
|
|
204
|
+
// (the model call was rejected mid-turn). Both look like a usage limit,
|
|
205
|
+
// so check it before blaming the session.
|
|
206
|
+
if (!d.probed &&
|
|
207
|
+
now - d.deliveredAt > SILENT_PROBE_AFTER_MS &&
|
|
208
|
+
sessionStalled(d.sessionId)) {
|
|
209
|
+
d.probed = true;
|
|
210
|
+
void checkUsage(client);
|
|
211
|
+
}
|
|
212
|
+
if (!d.warned && stillPending && now - d.deliveredAt > UNREAD_WARN_AFTER_MS) {
|
|
172
213
|
d.warned = true;
|
|
214
|
+
// A confirmed usage limit already explains the silence, and does it
|
|
215
|
+
// better than "that session may not be monitoring".
|
|
216
|
+
if (isLimitedNow())
|
|
217
|
+
continue;
|
|
173
218
|
client
|
|
174
|
-
.sendText(d.fromUserId, t().unreadWarn(d.targetName))
|
|
219
|
+
.sendText(d.msg.fromUserId, t().unreadWarn(d.targetName))
|
|
175
220
|
.catch((err) => log(`Unread warning failed: ${err}`));
|
|
176
221
|
}
|
|
177
222
|
}
|
|
178
223
|
}, 20_000);
|
|
179
224
|
}
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
// Claude usage limit
|
|
227
|
+
//
|
|
228
|
+
// When the account's limit is reached every session stops answering at once,
|
|
229
|
+
// which from WeChat is indistinguishable from a dead daemon. The daemon probes
|
|
230
|
+
// for it, says so, and follows up when the limit lifts.
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
let usageState = readUsageState();
|
|
233
|
+
function saveUsageState() {
|
|
234
|
+
writeUsageState(usageState);
|
|
235
|
+
}
|
|
236
|
+
// Limited, as far as we know right now. Once the reported reset time has
|
|
237
|
+
// passed the state is stale — the watcher re-probes rather than keep claiming
|
|
238
|
+
// a limit that may already be over.
|
|
239
|
+
function isLimitedNow(now = Date.now()) {
|
|
240
|
+
if (!usageState.limited)
|
|
241
|
+
return false;
|
|
242
|
+
return usageState.resetAt === undefined || now < usageState.resetAt;
|
|
243
|
+
}
|
|
244
|
+
function hintFor(now = Date.now()) {
|
|
245
|
+
return resetHint(usageState, now) ?? t().usageResetUnknown;
|
|
246
|
+
}
|
|
247
|
+
function waitingSummary(userId) {
|
|
248
|
+
const pending = pendingFor(userId);
|
|
249
|
+
if (pending.length === 0)
|
|
250
|
+
return "";
|
|
251
|
+
const body = pending
|
|
252
|
+
.map((d) => `• ${d.targetName}: ${d.msg.text.replace(/\s+/g, " ").slice(0, 40)}`)
|
|
253
|
+
.join("\n");
|
|
254
|
+
return t().usageWaitingList(body);
|
|
255
|
+
}
|
|
256
|
+
function notifyLimited(client, userId) {
|
|
257
|
+
if (usageState.notified.includes(userId))
|
|
258
|
+
return;
|
|
259
|
+
usageState.notified.push(userId);
|
|
260
|
+
saveUsageState();
|
|
261
|
+
client
|
|
262
|
+
.sendText(userId, t().usageLimited(hintFor(), waitingSummary(userId)))
|
|
263
|
+
.catch((err) => log(`Usage-limit notice failed: ${err}`));
|
|
264
|
+
}
|
|
265
|
+
// Tell everyone who is currently waiting on a session, not just the user whose
|
|
266
|
+
// message triggered the probe.
|
|
267
|
+
function announceLimited(client) {
|
|
268
|
+
for (const userId of new Set(deliveries.map((d) => d.msg.fromUserId))) {
|
|
269
|
+
notifyLimited(client, userId);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Get unanswered work moving again after a limit lifts.
|
|
273
|
+
//
|
|
274
|
+
// Two shapes to repair. A message still in the inbox only needs its watcher
|
|
275
|
+
// poked: the announcement it made while Claude could not react never repeats on
|
|
276
|
+
// its own. A message Claude *read* and then failed to answer is worse — the
|
|
277
|
+
// inbox was already drained, so there is nothing left to announce and nothing
|
|
278
|
+
// to poke; it has to go back in the inbox first. Only deliveries with no reply
|
|
279
|
+
// are requeued, so nothing is handled twice.
|
|
280
|
+
//
|
|
281
|
+
// Deliveries are in-memory, so a daemon restart during a limit loses the
|
|
282
|
+
// read-but-unanswered ones; the still-in-inbox case survives on disk.
|
|
283
|
+
function resumePendingDeliveries() {
|
|
284
|
+
const live = new Set(listSessions().map((s) => s.id));
|
|
285
|
+
let requeued = 0;
|
|
286
|
+
for (const d of deliveries) {
|
|
287
|
+
if (!live.has(d.sessionId))
|
|
288
|
+
continue;
|
|
289
|
+
if (inboxHas(d.sessionId, d.msg.id))
|
|
290
|
+
continue;
|
|
291
|
+
writeToInbox(d.sessionId, d.msg);
|
|
292
|
+
requeued += 1;
|
|
293
|
+
}
|
|
294
|
+
let nudged = 0;
|
|
295
|
+
for (const session of listSessions()) {
|
|
296
|
+
if (peekInbox(session.id) === 0)
|
|
297
|
+
continue;
|
|
298
|
+
nudgeSession(session.id);
|
|
299
|
+
nudged += 1;
|
|
300
|
+
}
|
|
301
|
+
return { nudged, requeued };
|
|
302
|
+
}
|
|
303
|
+
function applyProbe(client, probe) {
|
|
304
|
+
const now = Date.now();
|
|
305
|
+
if (probe.state === "limited") {
|
|
306
|
+
if (!usageState.limited) {
|
|
307
|
+
log(`Claude usage limit detected: ${probe.detail}`);
|
|
308
|
+
usageState = {
|
|
309
|
+
limited: true,
|
|
310
|
+
since: now,
|
|
311
|
+
resetAt: probe.resetAt,
|
|
312
|
+
resetText: probe.resetText,
|
|
313
|
+
lastProbeAt: now,
|
|
314
|
+
notified: [],
|
|
315
|
+
};
|
|
316
|
+
notifyMacOS(t().usageMacNotice(hintFor(now)));
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
usageState.lastProbeAt = now;
|
|
320
|
+
usageState.resetAt = probe.resetAt ?? usageState.resetAt;
|
|
321
|
+
usageState.resetText = probe.resetText ?? usageState.resetText;
|
|
322
|
+
}
|
|
323
|
+
saveUsageState();
|
|
324
|
+
announceLimited(client);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (probe.state === "unknown") {
|
|
328
|
+
// Some other failure (CLI missing, network, timeout). Don't invent a limit
|
|
329
|
+
// — just record the attempt so probes stay throttled.
|
|
330
|
+
log(`Usage probe inconclusive: ${probe.detail}`);
|
|
331
|
+
usageState.lastProbeAt = now;
|
|
332
|
+
saveUsageState();
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
if (!usageState.limited) {
|
|
336
|
+
usageState.lastProbeAt = now;
|
|
337
|
+
saveUsageState();
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const mins = Math.round((now - (usageState.since ?? now)) / 60_000);
|
|
341
|
+
const audience = new Set([
|
|
342
|
+
...usageState.notified,
|
|
343
|
+
...deliveries.map((d) => d.msg.fromUserId),
|
|
344
|
+
]);
|
|
345
|
+
usageState = { limited: false, lastProbeAt: now, notified: [] };
|
|
346
|
+
saveUsageState();
|
|
347
|
+
const { nudged, requeued } = resumePendingDeliveries();
|
|
348
|
+
log(`Claude usage limit lifted after ${mins}m; requeued ${requeued} message(s), nudged ${nudged} session(s)`);
|
|
349
|
+
const tail = nudged > 0 ? t().usagePendingNudged(nudged) : t().usagePendingNone;
|
|
350
|
+
for (const userId of audience) {
|
|
351
|
+
client
|
|
352
|
+
.sendText(userId, t().usageRecovered(mins, tail))
|
|
353
|
+
.catch((err) => log(`Usage-recovery notice failed: ${err}`));
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// One probe at a time, throttled unless forced (the /usage command).
|
|
357
|
+
let probeInFlight;
|
|
358
|
+
async function checkUsage(client, force = false) {
|
|
359
|
+
if (probeInFlight)
|
|
360
|
+
return probeInFlight;
|
|
361
|
+
if (!force && !shouldProbe(usageState, Date.now()))
|
|
362
|
+
return undefined;
|
|
363
|
+
probeInFlight = probeUsageLimit();
|
|
364
|
+
try {
|
|
365
|
+
const probe = await probeInFlight;
|
|
366
|
+
applyProbe(client, probe);
|
|
367
|
+
return probe;
|
|
368
|
+
}
|
|
369
|
+
finally {
|
|
370
|
+
probeInFlight = undefined;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// While limited, keep checking so recovery is announced without the user
|
|
374
|
+
// having to poke it — rejected probes are instant and cost nothing.
|
|
375
|
+
function startUsageWatcher(client) {
|
|
376
|
+
setInterval(() => {
|
|
377
|
+
if (!usageState.limited)
|
|
378
|
+
return;
|
|
379
|
+
void checkUsage(client);
|
|
380
|
+
}, 30_000);
|
|
381
|
+
}
|
|
180
382
|
function notifyMacOS(message) {
|
|
181
383
|
if (process.platform !== "darwin")
|
|
182
384
|
return;
|
|
@@ -422,6 +624,18 @@ function handleRunCommand(client, msg, args) {
|
|
|
422
624
|
log(`Started tmux session "${sessionName}" in ${cwd}: ${task}`);
|
|
423
625
|
sendReply(m.runStarted(path.basename(cwd), task, auto ? m.permSkip : m.permSafe, sessionName) + (bypass === "accepted" ? `\n\n${m.bypassAutoAccepted}` : ""));
|
|
424
626
|
}
|
|
627
|
+
// A message delivered during a known limit episode would otherwise vanish into
|
|
628
|
+
// silence, so say so immediately instead of waiting for the watchdog.
|
|
629
|
+
function noteUsageLimit(client, userId) {
|
|
630
|
+
if (!isLimitedNow())
|
|
631
|
+
return;
|
|
632
|
+
if (!usageState.notified.includes(userId))
|
|
633
|
+
usageState.notified.push(userId);
|
|
634
|
+
saveUsageState();
|
|
635
|
+
client
|
|
636
|
+
.sendText(userId, t().usageNoteOnSend(hintFor()))
|
|
637
|
+
.catch((err) => log(`Usage-limit note failed: ${err}`));
|
|
638
|
+
}
|
|
425
639
|
function routeMessage(client, msg) {
|
|
426
640
|
const text = msg.text.trim();
|
|
427
641
|
const lang = getLang();
|
|
@@ -431,6 +645,28 @@ function routeMessage(client, msg) {
|
|
|
431
645
|
log(`Reply failed: ${err}`);
|
|
432
646
|
});
|
|
433
647
|
};
|
|
648
|
+
if (text === "/usage" || text === "/limit" || text === "/用量") {
|
|
649
|
+
sendReply(m.usageChecking);
|
|
650
|
+
void (async () => {
|
|
651
|
+
const probe = await checkUsage(client, true);
|
|
652
|
+
if (!probe)
|
|
653
|
+
return;
|
|
654
|
+
if (probe.state === "limited") {
|
|
655
|
+
const now = Date.now();
|
|
656
|
+
const mins = Math.round((now - (usageState.since ?? now)) / 60_000);
|
|
657
|
+
// Answering here counts as telling this user about the episode, so the
|
|
658
|
+
// watcher does not send them the same news a second time.
|
|
659
|
+
if (!usageState.notified.includes(msg.fromUserId)) {
|
|
660
|
+
usageState.notified.push(msg.fromUserId);
|
|
661
|
+
saveUsageState();
|
|
662
|
+
}
|
|
663
|
+
sendReply(m.usageStatusLimited(hintFor(now), mins));
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
sendReply(probe.state === "ok" ? m.usageOk : m.usageUnknown(probe.detail));
|
|
667
|
+
})();
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
434
670
|
const runMatch = text.match(/^\/run(?:\s+([\s\S]*))?$/);
|
|
435
671
|
if (runMatch) {
|
|
436
672
|
handleRunCommand(client, msg, runMatch[1] ?? "");
|
|
@@ -627,11 +863,13 @@ function routeMessage(client, msg) {
|
|
|
627
863
|
sendReply(m.notFound(selector));
|
|
628
864
|
return;
|
|
629
865
|
}
|
|
630
|
-
|
|
631
|
-
|
|
866
|
+
const routed = { ...msg, text: message };
|
|
867
|
+
writeToInbox(target.id, routed);
|
|
868
|
+
trackDelivery(routed, target.id, target.name);
|
|
632
869
|
if (!isMonitoring(target.id)) {
|
|
633
870
|
sendReply(m.deliveredUnmonitored(target.name));
|
|
634
871
|
}
|
|
872
|
+
noteUsageLimit(client, msg.fromUserId);
|
|
635
873
|
markTyping(msg.fromUserId);
|
|
636
874
|
client.startTypingKeepAlive(msg.fromUserId, () => isTypingActive(msg.fromUserId));
|
|
637
875
|
log(`Routed to ${target.name} (${target.id})`);
|
|
@@ -654,10 +892,11 @@ function routeMessage(client, msg) {
|
|
|
654
892
|
return;
|
|
655
893
|
}
|
|
656
894
|
writeToInbox(target.id, msg);
|
|
657
|
-
trackDelivery(msg
|
|
895
|
+
trackDelivery(msg, target.id, target.name);
|
|
658
896
|
if (!isMonitoring(target.id)) {
|
|
659
897
|
sendReply(m.deliveredNoneMonitored(target.name));
|
|
660
898
|
}
|
|
899
|
+
noteUsageLimit(client, msg.fromUserId);
|
|
661
900
|
markTyping(msg.fromUserId);
|
|
662
901
|
client.startTypingKeepAlive(msg.fromUserId);
|
|
663
902
|
log(`Routed to ${target.name} (${target.id})`);
|
|
@@ -714,6 +953,9 @@ async function main() {
|
|
|
714
953
|
startTypingWatcher(client);
|
|
715
954
|
startDeliveryWatcher(client);
|
|
716
955
|
startRunWatcher(client);
|
|
956
|
+
startUsageWatcher(client);
|
|
957
|
+
pruneReplies(listSessions().map((s) => s.id));
|
|
958
|
+
setInterval(() => pruneReplies(listSessions().map((s) => s.id)), 30 * 60_000);
|
|
717
959
|
log(`Daemon started (pid ${process.pid}). Polling WeChat...`);
|
|
718
960
|
let clearedExpiredFlag = false;
|
|
719
961
|
while (true) {
|
|
@@ -756,8 +998,17 @@ async function main() {
|
|
|
756
998
|
fs.writeFileSync(EXPIRED_FLAG_FILE, String(Date.now()));
|
|
757
999
|
}
|
|
758
1000
|
catch { }
|
|
1001
|
+
// The cursor belongs to the dead login session; a fresh login must
|
|
1002
|
+
// start from a fresh cursor or getupdates may keep rejecting it.
|
|
1003
|
+
try {
|
|
1004
|
+
fs.unlinkSync(CURSOR_FILE);
|
|
1005
|
+
}
|
|
1006
|
+
catch { }
|
|
759
1007
|
notifyMacOS(t().loginExpired);
|
|
760
|
-
|
|
1008
|
+
// The watcher setIntervals keep the event loop alive, so breaking out
|
|
1009
|
+
// of the loop is not enough — without an explicit exit the process
|
|
1010
|
+
// lingers, holds the pid file, and blocks launchd from restarting.
|
|
1011
|
+
process.exit(1);
|
|
761
1012
|
}
|
|
762
1013
|
log(`Poll error: ${errMsg}`);
|
|
763
1014
|
await new Promise((r) => setTimeout(r, 5000));
|