polygram 0.11.0-rc.5 → 0.11.0-rc.7

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.11.0-rc.5",
4
+ "version": "0.11.0-rc.7",
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",
@@ -186,6 +186,34 @@ function resolveSessionForSpawn(db, sessionKey, resolved = {}) {
186
186
  return before[f] !== after[f];
187
187
  });
188
188
 
189
+ // 0.11.0 channels boundary (2026-05-25): SDK ↔ tmux flips remain
190
+ // non-invalidating per rc.32's reasoning. But channels mode is
191
+ // genuinely different on the claude side:
192
+ //
193
+ // - bridge MCP server is mounted (--mcp-config + --strict-mcp-config)
194
+ // - additional --append-system-prompt directive enforces the
195
+ // reply-tool contract (claude must call mcp__polygram-bridge__reply
196
+ // instead of writing inline). Sessions created without this
197
+ // directive don't have the contract baked into their context.
198
+ // - agent behavior expectations differ — same agent file, but
199
+ // conversation flow is "user msg arrives via channel, reply via
200
+ // tool" rather than "user msg arrives inline, reply inline."
201
+ //
202
+ // Live shumorobot 2026-05-25 incident: Music topic resumed a
203
+ // pre-channels session id (4837f61a-…) that had been mid-soulseek-
204
+ // curation. The user's "how are you" got interpreted as a continuation
205
+ // of THAT task; claude responded with music release info, inline,
206
+ // never calling the reply tool. Every turn timed out at 3min.
207
+ //
208
+ // Rule: any transition TO or FROM channels drops the prior session.
209
+ // XOR — flips between channels and {sdk,tmux} invalidate; sdk↔tmux
210
+ // flips remain free.
211
+ const wasChannels = before.pm_backend === 'channels';
212
+ const willBeChannels = after.pm_backend === 'channels';
213
+ if (after.pm_backend != null && wasChannels !== willBeChannels) {
214
+ drifted.push('pm_backend');
215
+ }
216
+
189
217
  if (drifted.length === 0) {
190
218
  return { existingSessionId: row.claude_session_id, drift: null };
191
219
  }
@@ -370,6 +370,14 @@ class ChannelsProcess extends Process {
370
370
  // EXISTING conversation. Lazy-respawn after bridge-disconnect must use
371
371
  // --resume so conversation history is preserved. Mirrors
372
372
  // tmux-process.js:514-518.
373
+ //
374
+ // rc.6 note: pre-channels session ids (created by sdk/tmux backends and
375
+ // persisted in polygram's DB) are NOT cross-backend compatible — claude
376
+ // indexes session files under a cwd-derived projects dir that may not
377
+ // match what channels-mode passes, leading to silent "No conversation
378
+ // found" exit. The fix lives at the data layer, not here: operator
379
+ // clears pre-channels session ids from polygram's sessions table before
380
+ // flipping a chat to channels (see ops/migrate-to-channels.sql).
373
381
  if (opts.existingSessionId) {
374
382
  claudeArgs.push('--resume', opts.existingSessionId);
375
383
  } else {
@@ -408,10 +416,40 @@ class ChannelsProcess extends Process {
408
416
  claudeArgs.push('--dangerously-skip-permissions');
409
417
  }
410
418
 
411
- // Parity audit P3: append display-hint so Claude knows it's replying
412
- // through Telegram. Prevents canned strings like "No response requested."
413
- // from leaking as user-visible messages (shumorobot 2026-05-15 incident).
414
- claudeArgs.push('--append-system-prompt', POLYGRAM_DISPLAY_HINT);
419
+ // Parity audit P3 + rc.7 (2026-05-26 shumorobot diagnosis): combined
420
+ // system-prompt suffix carrying BOTH the Telegram display rules AND the
421
+ // channels-mode reply-tool contract. Merged into a single
422
+ // --append-system-prompt block — passing two separate
423
+ // --append-system-prompt flags caused MCP server registration to fail
424
+ // (live shumorobot tmux banner: "server:polygram-bridge · no MCP server
425
+ // configured with that name"; claude received no channel messages).
426
+ // Suspected: --append-system-prompt is variadic in claude's CLI and the
427
+ // second flag was eating the subsequent --setting-sources / --mcp-config
428
+ // arguments. Single combined block sidesteps the issue.
429
+ claudeArgs.push('--append-system-prompt', [
430
+ POLYGRAM_DISPLAY_HINT,
431
+ '',
432
+ '## polygram channels mode — HARD CONTRACT',
433
+ '',
434
+ 'You are running inside polygram with the channels backend. Your stdout/TUI',
435
+ 'output is NOT seen by the user. The user is on Telegram.',
436
+ '',
437
+ 'To deliver ANY message to the user, you MUST call the MCP tool',
438
+ '`mcp__polygram-bridge__reply` with `chat_id` and `text` arguments.',
439
+ 'Pass the chat_id verbatim from the channel message you received.',
440
+ '',
441
+ 'Do NOT respond conversationally in-line. Do NOT assume any inline',
442
+ 'text will reach the user. If you have ANYTHING to say to the user —',
443
+ 'an answer, a question, a status update, an acknowledgement — it goes',
444
+ 'through `mcp__polygram-bridge__reply`. Period.',
445
+ '',
446
+ 'This applies to every turn, including the first message after',
447
+ '`/new` or `/reset`. Even a single-line "Hi" must be sent via the tool.',
448
+ '',
449
+ 'Internal tool calls (Bash, Edit, Write, Read, etc.) are fine to use',
450
+ 'as normal — only the FINAL user-visible message needs to go through',
451
+ 'the reply tool.',
452
+ ].join('\n'));
415
453
 
416
454
  // Parity audit P6: honor isolateUserConfig — mirrors tmux pattern at
417
455
  // lib/process/tmux-process.js:502-505,543-546. Channels ALWAYS uses
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polygram",
3
- "version": "0.11.0-rc.5",
3
+ "version": "0.11.0-rc.7",
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": {