polygram 0.10.0-rc.42 → 0.10.0-rc.43
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.10.0-rc.
|
|
4
|
+
"version": "0.10.0-rc.43",
|
|
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 plus history (transcript queries) and polygram-send (out-of-turn IPC sends with file-upload validation) skills.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"telegram",
|
|
@@ -225,6 +225,32 @@ const DEFAULT_STOP_GRACE_MS = 2_000; // 2 s
|
|
|
225
225
|
// block, but `_waitForReady` runs only at startup before any turn).
|
|
226
226
|
const DEFAULT_READY_DEBUG_QUIET_MS = 1000;
|
|
227
227
|
|
|
228
|
+
// rc.43 (shumorobot Music topic, 2026-05-22 21:11): claude TUI on
|
|
229
|
+
// `--resume` of a session that has crossed an age/token threshold
|
|
230
|
+
// (~8h / ~120k tokens observed) renders an INTERACTIVE menu instead
|
|
231
|
+
// of the chat input:
|
|
232
|
+
//
|
|
233
|
+
// This session is 8h 38m old and 117.6k tokens.
|
|
234
|
+
// Resuming the full session will consume a substantial portion of
|
|
235
|
+
// your usage limits. We recommend resuming from a summary.
|
|
236
|
+
// ❯ 1. Resume from summary (recommended)
|
|
237
|
+
// 2. Resume full session as-is
|
|
238
|
+
// 3. Don't ask me again
|
|
239
|
+
// Enter to confirm · Esc to cancel
|
|
240
|
+
//
|
|
241
|
+
// `_waitForReady` doesn't recognise this menu — there's no
|
|
242
|
+
// `? for shortcuts` / `accept edits on` / `bypass permissions on`
|
|
243
|
+
// hint visible. It times out at `readyTimeoutMs` (120 s) and polygram
|
|
244
|
+
// fails the user's message with a generic "TUI did not signal ready"
|
|
245
|
+
// error. Detection in the pane and pressing Enter dismisses the menu
|
|
246
|
+
// (selects option 1 = resume from summary, the safe default).
|
|
247
|
+
//
|
|
248
|
+
// The detection regex matches a distinctive substring from the menu
|
|
249
|
+
// header that doesn't appear during normal turns or other startup
|
|
250
|
+
// banners — looking for the literal "Resume from summary" option
|
|
251
|
+
// combined with the "Resuming the full session" rationale.
|
|
252
|
+
const SESSION_AGE_PROMPT_RE = /Resuming the full session.*Resume from summary/s;
|
|
253
|
+
|
|
228
254
|
// R7: sentinel returned by _awaitTurnComplete when its poll loop is
|
|
229
255
|
// stopped by the caller's absolute-deadline abort (rather than by a
|
|
230
256
|
// real READY quiescence or its own internal timeout). _runTurn maps
|
|
@@ -2591,6 +2617,10 @@ class TmuxProcess extends Process {
|
|
|
2591
2617
|
// next polls, which is what resets the clock.
|
|
2592
2618
|
let prevDebugSize = null;
|
|
2593
2619
|
let lastGrowthAt = null;
|
|
2620
|
+
// rc.43: track whether we've already dismissed the session-age
|
|
2621
|
+
// prompt this wait, so we don't fire Enter every poll if claude
|
|
2622
|
+
// is slow to re-render after dismissing it.
|
|
2623
|
+
let sessionAgePromptDismissed = false;
|
|
2594
2624
|
if (this.pollScheduler) this.pollScheduler.acquire();
|
|
2595
2625
|
try {
|
|
2596
2626
|
while (this._now() < deadline) {
|
|
@@ -2598,6 +2628,41 @@ class TmuxProcess extends Process {
|
|
|
2598
2628
|
// pane. Polling 1000 lines each tick is wasteful — cap at 80
|
|
2599
2629
|
// for a ~12× cheaper tmux subprocess.
|
|
2600
2630
|
lastBuf = await this.runner.captureWide(this.tmuxName, { lines: 80 });
|
|
2631
|
+
// rc.43: if claude rendered the session-age "resume from
|
|
2632
|
+
// summary" prompt (only happens on `--resume` of an aged
|
|
2633
|
+
// session, see SESSION_AGE_PROMPT_RE comment), press Enter
|
|
2634
|
+
// once to confirm the default selection (option 1 — resume
|
|
2635
|
+
// from summary) and emit a `session-age-prompt-dismissed`
|
|
2636
|
+
// event for forensics. The TUI then proceeds to load the
|
|
2637
|
+
// summary and the ready hint appears normally; subsequent
|
|
2638
|
+
// polls take the standard B6/B8 path.
|
|
2639
|
+
if (!sessionAgePromptDismissed
|
|
2640
|
+
&& SESSION_AGE_PROMPT_RE.test(lastBuf)) {
|
|
2641
|
+
this.logger.warn?.(
|
|
2642
|
+
`[${this.label}] claude TUI showed session-age resume prompt; `
|
|
2643
|
+
+ `auto-dismissing with Enter (select option 1 — resume from summary)`,
|
|
2644
|
+
);
|
|
2645
|
+
this.emit('session-age-prompt-dismissed', {
|
|
2646
|
+
sessionId: this.claudeSessionId,
|
|
2647
|
+
backend: 'tmux',
|
|
2648
|
+
});
|
|
2649
|
+
try {
|
|
2650
|
+
await this.runner.sendControl(this.tmuxName, 'Enter');
|
|
2651
|
+
} catch (err) {
|
|
2652
|
+
this.logger.warn?.(
|
|
2653
|
+
`[${this.label}] sendControl(Enter) for session-age dismissal failed: `
|
|
2654
|
+
+ `${err.message}`,
|
|
2655
|
+
);
|
|
2656
|
+
}
|
|
2657
|
+
sessionAgePromptDismissed = true;
|
|
2658
|
+
// Reset readiness clock + prev-pane so the menu's content
|
|
2659
|
+
// doesn't satisfy the byte-stability check while claude is
|
|
2660
|
+
// reloading from the summary.
|
|
2661
|
+
readySinceAt = null;
|
|
2662
|
+
prevBuf = null;
|
|
2663
|
+
await this._waitForNextTick();
|
|
2664
|
+
continue;
|
|
2665
|
+
}
|
|
2601
2666
|
// Ready ⇔ the hint is on the pane AND the pane is identical to
|
|
2602
2667
|
// the previous poll (the MCP-loading repaint storm has
|
|
2603
2668
|
// stopped). The first poll has no previous buffer to compare,
|
|
@@ -3225,4 +3290,6 @@ class TmuxProcess extends Process {
|
|
|
3225
3290
|
module.exports = {
|
|
3226
3291
|
TmuxProcess,
|
|
3227
3292
|
CLAUDE_CLI_PINNED_VERSION,
|
|
3293
|
+
// rc.43 — exported for unit-test coverage of the menu pattern.
|
|
3294
|
+
SESSION_AGE_PROMPT_RE,
|
|
3228
3295
|
};
|
package/lib/process-manager.js
CHANGED
|
@@ -119,6 +119,10 @@ const CALLBACK_TO_EVENT = {
|
|
|
119
119
|
// the event lets the soak count how often H4 actually fires its
|
|
120
120
|
// rescue contract.
|
|
121
121
|
onStopHookResolved: 'stop-hook-resolved',
|
|
122
|
+
// 0.10.0 rc.43: claude TUI's "This session is N old…" interactive
|
|
123
|
+
// menu auto-dismissed by `_waitForReady`. Surfacing the event so
|
|
124
|
+
// soak can count how often aged-session resumes hit this path.
|
|
125
|
+
onSessionAgePromptDismissed: 'session-age-prompt-dismissed',
|
|
122
126
|
};
|
|
123
127
|
|
|
124
128
|
class ProcessManager {
|
package/lib/sdk/callbacks.js
CHANGED
|
@@ -520,6 +520,23 @@ function createSdkCallbacks({
|
|
|
520
520
|
}
|
|
521
521
|
},
|
|
522
522
|
|
|
523
|
+
// 0.10.0 rc.43: claude TUI session-age resume prompt was
|
|
524
|
+
// auto-dismissed by `_waitForReady`. Counting these helps decide
|
|
525
|
+
// whether to push the "Don't ask me again" option globally vs
|
|
526
|
+
// keep the auto-dismiss as a safety net.
|
|
527
|
+
onSessionAgePromptDismissed: (sessionKey, payload /* , entry */) => {
|
|
528
|
+
try {
|
|
529
|
+
logEvent('session-age-prompt-dismissed', {
|
|
530
|
+
chat_id: getChatIdFromKey(sessionKey),
|
|
531
|
+
session_key: sessionKey,
|
|
532
|
+
backend: 'tmux',
|
|
533
|
+
claude_session_id: payload?.sessionId ?? null,
|
|
534
|
+
});
|
|
535
|
+
} catch (err) {
|
|
536
|
+
logger.error?.(`[${botName}] session-age-prompt-dismissed handler: ${err.message}`);
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
|
|
523
540
|
onInjectFail: (sessionKey, payload /* , entry */) => {
|
|
524
541
|
try {
|
|
525
542
|
const msgId = payload?.msgId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polygram",
|
|
3
|
-
"version": "0.10.0-rc.
|
|
3
|
+
"version": "0.10.0-rc.43",
|
|
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": {
|