polygram 0.3.4 → 0.3.5

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
3
  "name": "polygram",
4
- "version": "0.3.4",
4
+ "version": "0.3.5",
5
5
  "description": "Telegram integration for Claude Code that preserves the OpenClaw per-chat session model. Migration target for OpenClaw users. Multi-bot, multi-chat, per-topic isolation; SQLite transcripts; inline-keyboard approvals. Bundles /polygram:status|logs|pair-code|approvals admin commands and a history skill.",
6
6
  "keywords": [
7
7
  "telegram",
@@ -173,14 +173,20 @@ class ProcessManager {
173
173
  entry.sessionId = event.session_id;
174
174
  if (this.onInit) this.onInit(sessionKey, event, entry);
175
175
  }
176
- if (event.type === 'assistant' && this.onStreamChunk && entry.pending) {
177
- const added = extractAssistantText(event);
178
- if (added) {
179
- entry.streamText = entry.streamText
180
- ? `${entry.streamText}\n\n${added}`
181
- : added;
182
- try { this.onStreamChunk(sessionKey, entry.streamText, entry); }
183
- catch (err) { this.logger.error(`[${entry.label}] onStreamChunk: ${err.message}`); }
176
+ if (event.type === 'assistant' && entry.pending) {
177
+ // Any assistant step (text block, tool_use, tool_result) counts as
178
+ // Claude activity — reset the idle timeout so long turns don't
179
+ // wall-clock out.
180
+ entry.pending.resetIdleTimer?.();
181
+ if (this.onStreamChunk) {
182
+ const added = extractAssistantText(event);
183
+ if (added) {
184
+ entry.streamText = entry.streamText
185
+ ? `${entry.streamText}\n\n${added}`
186
+ : added;
187
+ try { this.onStreamChunk(sessionKey, entry.streamText, entry); }
188
+ catch (err) { this.logger.error(`[${entry.label}] onStreamChunk: ${err.message}`); }
189
+ }
184
190
  }
185
191
  }
186
192
  if (event.type === 'result' && entry.pending) {
@@ -250,18 +256,27 @@ class ProcessManager {
250
256
  entry.pending = { resolve, reject };
251
257
  entry.streamText = '';
252
258
 
253
- const timer = setTimeout(() => {
259
+ // Idle timeout: counts N seconds of SILENCE from Claude, not total
260
+ // wall-clock. Long multi-tool turns that produce visible progress
261
+ // (streaming chunks, tool_use events) should not time out as long as
262
+ // they're actively working. onStreamChunk resets this below.
263
+ const arm = () => setTimeout(() => {
254
264
  if (entry.pending) {
255
265
  entry.pending = null;
256
266
  entry.inFlight = false;
257
- reject(new Error(`Timeout after ${timeoutMs / 1000}s`));
267
+ reject(new Error(`Timeout: ${timeoutMs / 1000}s idle with no Claude activity`));
258
268
  }
259
269
  }, timeoutMs);
270
+ entry.pending.timer = arm();
271
+ entry.pending.resetIdleTimer = () => {
272
+ if (entry.pending?.timer) clearTimeout(entry.pending.timer);
273
+ if (entry.pending) entry.pending.timer = arm();
274
+ };
260
275
 
261
276
  const wrappedResolve = entry.pending.resolve;
262
277
  const wrappedReject = entry.pending.reject;
263
- entry.pending.resolve = (r) => { clearTimeout(timer); wrappedResolve(r); };
264
- entry.pending.reject = (e) => { clearTimeout(timer); wrappedReject(e); };
278
+ entry.pending.resolve = (r) => { if (entry.pending?.timer) clearTimeout(entry.pending.timer); wrappedResolve(r); };
279
+ entry.pending.reject = (e) => { if (entry.pending?.timer) clearTimeout(entry.pending.timer); wrappedReject(e); };
265
280
 
266
281
  try {
267
282
  entry.proc.stdin.write(JSON.stringify({
@@ -269,9 +284,9 @@ class ProcessManager {
269
284
  message: { role: 'user', content: prompt },
270
285
  }) + '\n');
271
286
  } catch (err) {
287
+ if (entry.pending?.timer) clearTimeout(entry.pending.timer);
272
288
  entry.pending = null;
273
289
  entry.inFlight = false;
274
- clearTimeout(timer);
275
290
  reject(err);
276
291
  }
277
292
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polygram",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Telegram daemon for Claude Code that preserves the OpenClaw per-chat session model. Migration path for OpenClaw users moving to Claude Code.",
5
5
  "main": "lib/ipc-client.js",
6
6
  "bin": {