@gonzih/cc-discord 0.2.43 → 0.2.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.
@@ -223,52 +223,55 @@ function wireStdoutToRedis(proc, ns, wire) {
223
223
  result: resultText,
224
224
  is_error: parsed.is_error ?? false,
225
225
  };
226
- if (resultText && !parsed.is_error) {
227
- const msg = {
226
+ if (parsed.is_error && resultText) {
227
+ // Error case: assistant event may not carry the error message — publish it directly
228
+ const errMsg = {
228
229
  id: crypto.randomUUID(),
229
230
  source: "claude",
230
231
  role: "assistant",
231
- content: resultText,
232
+ content: `⚠️ Error: ${resultText}`,
232
233
  timestamp: new Date().toISOString(),
233
234
  chatId: 0,
234
235
  };
235
- // Publish text first (logs to chat history), then signal done for immediate finalization
236
- wire.discord.publishOutgoing(ns, msg).then(() => {
237
- rawRedis.publish(discordChatOutgoing(ns), JSON.stringify({
238
- id: crypto.randomUUID(), source: "claude", role: "assistant",
239
- content: "", event: "done", timestamp: new Date().toISOString(), chatId: 0,
240
- })).catch(() => { });
241
- }).catch((err) => {
242
- console.warn(`[meta-agent-manager] publishOutgoing (result) failed (ns=${ns}):`, err.message);
243
- // Still signal done even if text publish failed
244
- rawRedis.publish(discordChatOutgoing(ns), JSON.stringify({
245
- id: crypto.randomUUID(), source: "claude", role: "assistant",
246
- content: "", event: "done", timestamp: new Date().toISOString(), chatId: 0,
247
- })).catch(() => { });
248
- });
236
+ wire.discord.publishOutgoing(ns, errMsg).catch(() => { });
249
237
  }
250
- else if (parsed.is_error) {
251
- // Error result: publish error text and signal done
252
- const errMsg = {
238
+ // Signal turn completion — text was already published via the assistant event above.
239
+ // Do NOT re-publish resultText here: that would double-deliver the same content.
240
+ rawRedis.publish(discordChatOutgoing(ns), JSON.stringify({
241
+ id: crypto.randomUUID(), source: "claude", role: "assistant",
242
+ content: "", event: "done", timestamp: new Date().toISOString(), chatId: 0,
243
+ })).catch(() => { });
244
+ }
245
+ else if (type === "rate_limit_event") {
246
+ const rl = parsed.rate_limit_info;
247
+ structuredEvent = parsed;
248
+ // Throttled: five-hour window exhausted and no overage credits.
249
+ // Claude will hang on API calls until the window resets — notify Discord immediately
250
+ // and signal done so the live message finalizes, rather than silently timing out.
251
+ if (rl?.overageStatus === "rejected") {
252
+ const resetsAt = rl.resetsAt ? new Date(rl.resetsAt * 1000).toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", timeZoneName: "short" }) : "soon";
253
+ const alertMsg = {
253
254
  id: crypto.randomUUID(),
254
255
  source: "claude",
255
256
  role: "assistant",
256
- content: `⚠️ Error: ${resultText || "unknown error"}`,
257
+ content: `⏳ Rate limited — five-hour window exhausted. Resets at **${resetsAt}**. Session paused; send any message after reset to resume.`,
257
258
  timestamp: new Date().toISOString(),
258
259
  chatId: 0,
259
260
  };
260
- wire.discord.publishOutgoing(ns, errMsg).catch(() => { });
261
- rawRedis.publish(discordChatOutgoing(ns), JSON.stringify({
262
- id: crypto.randomUUID(), source: "claude", role: "assistant",
263
- content: "", event: "done", timestamp: new Date().toISOString(), chatId: 0,
264
- })).catch(() => { });
265
- }
266
- else {
267
- // Empty result — just signal done
261
+ wire.discord.publishOutgoing(ns, alertMsg).catch(() => { });
262
+ // Fire done so notifier finalizes the live message
268
263
  rawRedis.publish(discordChatOutgoing(ns), JSON.stringify({
269
264
  id: crypto.randomUUID(), source: "claude", role: "assistant",
270
265
  content: "", event: "done", timestamp: new Date().toISOString(), chatId: 0,
271
266
  })).catch(() => { });
267
+ // Kill the process — API calls will hang until reset anyway
268
+ setTimeout(() => {
269
+ try {
270
+ proc.stdin.end();
271
+ proc.kill("SIGTERM");
272
+ }
273
+ catch { /* ignore */ }
274
+ }, 500);
272
275
  }
273
276
  }
274
277
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gonzih/cc-discord",
3
- "version": "0.2.43",
3
+ "version": "0.2.45",
4
4
  "description": "Claude Code Discord bot — chat with Claude Code via Discord",
5
5
  "type": "module",
6
6
  "bin": {