KilimcininKorOglu/claude-code-mods/tree/main/plugins/error-poke
error-poke
一个 Claude Code 插件,监视 main-loop 的 turn.complete 事件;当一轮以 error 原因或用量上限结束时,最多按可配置次数提交一次 continue 提示,让模型继续完成半途工作。
关于这个 mod
error-poke 连接 main loop 的 turn.complete,只处理引擎报告为 reason error 结束的轮次,不处理 aborted 和 refused。此类结束发生后,它会在会话空闲时发送固定的 continue 提示,要求模型继续而不是重启,并采用递增退避(5 秒、15 秒、45 秒、135 秒,然后 5 分钟)。如果一轮因用量上限停止,则等到上限重置后再执行;多个上限同时用尽时以最新的重置时间为准。每次提示都会在 transcript 中记录一行,或在侧边栏打开时写入 sidebar stream,并带有彩色样式。提示通过 mod 的 markdown 命令 /error-poke:send <prompt> 派发;如果引擎拒绝,则回退到插件提示。每段连续失败默认最多 99 次提示,可通过 /error-poke limit <n> 调整(1-999,并持久保存)。命令:/error-poke(状态、on/off、上一轮原因)、/error-poke on|off、/error-poke limit <n>、/error-poke:send <prompt>。使用两个 claude plugin 命令安装,需要重启。达到 L2(驱动 Claude):读取轮次结束原因和用量上限,不执行其他操作,向你自己的会话发送一个固定提示,将设置保存到 $.store,并且不会把 transcript 或 API 文本复制进常量提示。限制:只处理 reason error,计数按会话且保存在内存中,不执行 API 级重试。
安装
请先查看作者 README 确认 marketplace 和插件名称;命令可能随仓库结构改变。
claude plugin marketplace add KilimcininKorOglu/claude-code-mods claude plugin install error-poke
原文 / README
error-poke
You leave the model working, and when you come back the session sits idle with API Error: Connection lost mid-response and the work half done. The engine gave up after its retries and nobody told the model to go on. This mod does: when an API error kills a turn, it sends one continue prompt so the model carries on, at most 99 times in a row, or as many as you set with /error-poke limit <n>.
What it does
-
It watches
turn.completeof the main loop. A subagent's turn is left alone. -
It acts on one kind of end only:
reason: "error", a turn the engine reports as dead on an API error (retries exhausted, the context limit). A turn you interrupted isabortedand a model refusal isrefusal; neither gets a prompt. -
It sends this prompt, which runs once the session is idle:
The previous turn was cut off by an API error, not by me. Continue where you stopped; do not start over. If you cannot tell how far you got, say so and stop.The interrupted turn's work is still in the transcript, so the prompt asks the model to carry on rather than repeat it.
-
The prompt waits before it goes out, longer after each failure in a row: 5 s, 15 s, 45 s, 135 s, then 5 minutes each. An overloaded API usually recovers in seconds, and an error that fails the same way on every try (the context limit) does not burn the whole limit back to back. A prompt of yours during the wait, or
/error-poke off, cancels the waiting prompt.A turn that a usage limit stopped waits for the limit instead. When a limit reads 100% or more, or the last assistant text is Claude Code's own
You've hit your ... limit, the one continue prompt goes out a minute after that limit resets (the latest reset, when several limits are full), because every prompt before that would fail the same way:error-poke: the turn hit the 5h usage limit, continuing at 14:01 (in 2 h 1 min) (1/99)Every prompt also writes one line to the transcript, so you know why the session will move by itself:
error-poke: the turn died on an API error, continuing in 5 s (1/99) -
At most 99 prompts go out for one stretch of failures, or as many as
/error-poke limit <n>says. At the limit the mod says so once and stops:error-poke: stopped after 99 continue prompts; the API keeps failing. Send a prompt to reset the count. -
A prompt of your own (from the composer, the bridge or the SDK) resets the count, so the next failure starts from 1 again.
-
With the sidebar open, these lines go into its stream instead, and the transcript stays clean. There
API errorand the usage limit's name are red, the count is faint (yellow once it is within 10% of the limit), and the stop line is red. Without the sidebar, the lines land in the transcript as above. -
The prompt runs the mod's own markdown command
/error-poke:send <prompt>, whose body is its arguments alone. The transcript shows that command line, and the model reads the prompt exactly as written, as it reads a typed slash command; a$.prompt.submittext would reach it inside aThe error-poke plugin sent a message:frame. When the engine refuses the command, one line says so and the prompt goes out as a plugin prompt, with that frame. -
A plugin prompt the engine refuses (the session is busy, a stop is pending) is reported as well, and no count is lost.
What the mod reads is the engine's own reason value, and /error-poke prints how the last turn ended. If a failure you saw got no prompt, that line tells you which value the engine reported.
Command
/error-poke on or off, the count, and how the last turn ended
/error-poke on | off on by default
/error-poke limit <n> at most n continue prompts in a row; 1 to 999, 99 by default, kept across sessions
/error-poke:send <prompt> the command a continue prompt runs; typed, it sends the prompt as written
/error-poke:send is the mod's second command, the one exception to one command per mod, because only a markdown command hands the model a prompt without the plugin frame.
Install
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install error-poke@kilimcininkoroglu-mods
Function hooks are early access. Claude Code 2.1.288 and later load them by default, so there is nothing to switch on.
After installing
- Restart Claude Code.
What it can reach
Validated with claude plugin validate on Claude Code 2.1.283:
❯ ./register.ts hooks: session.start, command.run{command=error-poke}, prompt.submit, turn.complete
❯ ./register.ts calls: $.clock.after (via afterTurn), $.clock.now (via afterTurn), $.command.register, $.command.run (via sendPoke), $.prompt.submit (via submitPoke), $.session.messages (via readLimitWait), $.session.usage (via readLimitWait), $.sidebar.set (via toPerson), $.store.get (via readLimit, readSettings), $.store.set, $.ui.log (via toPerson)
Reach L2: it drives Claude.
1. Reads: how each main-loop turn ended, and the origin of each prompt; after a turn an API error ended, the session's usage limits and the last assistant text; no file, no command
2. Runs: nothing
3. Sends: one fixed continue prompt to your own session, and one line to the transcript; nothing leaves the machine
4. Persists: in $.store, the on/off setting and the limit; the count lives in memory for one stretch of failures
5. Hostile input: the prompt text is a constant in the mod; no transcript or API text is copied into it
Limits
- The mod goes by the engine's
reason. An error the engine reports as something other thanerrorgets no prompt;/error-pokeprints the value so you can tell. - A turn that failed before any output is continued the same way. The model may answer that it cannot tell how far it got, which is what the prompt asks for.
- The count is per session and lives in memory, so a restart starts at 0.
- Nothing is retried at the API level. The mod starts a new turn, so the failed turn's tokens stay spent.
Development
make install # eslint, typescript-eslint, typescript
make lint # complexity limit 10, the build fails above it
make typecheck # needs .claude/types/ from /plugin-types
make validate
make test # claude plugin test