polygram 0.38.9 → 0.39.0

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.38.9",
4
+ "version": "0.39.0",
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",
@@ -111,6 +111,7 @@ const MIME_ALLOW = [
111
111
  /^text\/csv$/,
112
112
  // rc.68: archives + markup formats Claude reads natively.
113
113
  /^application\/zip$/, /^application\/x-zip-compressed$/,
114
+ /^application\/gzip$/, /^application\/x-gzip$/, /^application\/x-tar$/,
114
115
  /^text\/markdown$/,
115
116
  /^text\/html$/,
116
117
  /^text\/yaml$/, /^application\/yaml$/, /^application\/x-yaml$/,
@@ -122,8 +123,10 @@ const MIME_ALLOW = [
122
123
  // the fallback is "trust the filename when MIME is unhelpful" — not "any
123
124
  // extension goes." A file named foo.exe with empty MIME stays rejected.
124
125
  const EXTENSION_ALLOW = new Set([
125
- // archives
126
- 'zip',
126
+ // archives — extensionOf() only sees the last dot segment, so
127
+ // "foo.tar.gz" resolves to 'gz' (not 'tar.gz'); listing 'gz'/'tgz'/'tar'
128
+ // separately covers the common compound and short forms.
129
+ 'zip', 'gz', 'tgz', 'tar',
127
130
  // text / structured data
128
131
  'txt', 'md', 'csv', 'json', 'yaml', 'yml', 'xml', 'html',
129
132
  // documents
@@ -220,7 +220,7 @@ function resolveDisplayRichText(chatConfig, topicConfig, effectiveRichText) {
220
220
  // polygram passes the alias (opus / sonnet / haiku) and lets claude
221
221
  // resolve. Bump on Claude release.
222
222
  const MODEL_VERSIONS_DESC = {
223
- opus: 'claude-opus-5',
223
+ opus: 'claude-opus-5-5',
224
224
  sonnet: 'claude-sonnet-4-6',
225
225
  haiku: 'claude-haiku-4-5',
226
226
  };
@@ -17,8 +17,8 @@
17
17
  'use strict';
18
18
 
19
19
  // Per-million-token rates ($ USD). Cache-read and cache-creation
20
- // follow Anthropic's prompt-caching pricing — read is ~10% of normal
21
- // input; 1-hour creation is ~125% of normal input.
20
+ // follow Anthropic's prompt-caching pricing — read is usually ~10% of
21
+ // normal input (Opus 5.5: 5%); 5-minute creation is 125% of normal input.
22
22
  const MODEL_COSTS = {
23
23
  // Claude Sonnet 4.6
24
24
  'claude-sonnet-4-6': { input: 3, output: 15, cacheRead: 0.30, cacheCreation: 3.75 },
@@ -31,8 +31,11 @@ const MODEL_COSTS = {
31
31
  // Claude Opus 4.8 — kept for turns recorded before the CLI pin moved to
32
32
  // 2.1.220; without an entry those fall back to the Sonnet `default`.
33
33
  'claude-opus-4-8': { input: 15, output: 75, cacheRead: 1.50, cacheCreation: 18.75 },
34
- // Claude Opus 5 — what `--model opus` resolves to on the pinned CLI.
34
+ // Claude Opus 5 — kept for turns recorded before the CLI pin moved to
35
+ // 2.1.283; without an entry those fall back to the Sonnet `default`.
35
36
  'claude-opus-5': { input: 5, output: 25, cacheRead: 0.50, cacheCreation: 6.25 },
37
+ // Claude Opus 5.5 — what `--model opus` resolves to on the pinned CLI.
38
+ 'claude-opus-5-5': { input: 4, output: 20, cacheRead: 0.20, cacheCreation: 5 },
36
39
  // Default fallback — Sonnet rates (safest mid-tier estimate).
37
40
  default: { input: 3, output: 15, cacheRead: 0.30, cacheCreation: 3.75 },
38
41
  };
@@ -36,6 +36,19 @@ const CHILD_ENV_ALLOWLIST = new Set([
36
36
  ]);
37
37
  const CHILD_ENV_PREFIXES = ['LC_', 'NODE_', 'CLAUDE_', 'ANTHROPIC_'];
38
38
 
39
+ // Claude Code records a conversation's system prompt once and replays that
40
+ // record on every resume until compaction. The appended display hint depends
41
+ // on richText and changes between releases, so opt out of the recording to
42
+ // let changes reach resumed sessions. Bare string / string[] prompts can only
43
+ // opt out in the custom-object form.
44
+ function withoutPromptSnapshot(systemPrompt) {
45
+ if (systemPrompt == null) return systemPrompt;
46
+ if (typeof systemPrompt === 'string' || Array.isArray(systemPrompt)) {
47
+ return { type: 'custom', prompt: systemPrompt, snapshot: false };
48
+ }
49
+ return { ...systemPrompt, snapshot: false };
50
+ }
51
+
39
52
  function filterEnv(src) {
40
53
  const out = {};
41
54
  for (const [k, v] of Object.entries(src)) {
@@ -173,13 +186,13 @@ function createBuildSdkOptions({
173
186
  // inlineMedia: replies on this path are delivered by the streamer, which
174
187
  // resolves and uploads local media into the rich payload. The reply-tool
175
188
  // path cannot, so it asks for the hint without those paragraphs.
176
- composed.systemPrompt = appendDisplayHint(
189
+ composed.systemPrompt = withoutPromptSnapshot(appendDisplayHint(
177
190
  composed.systemPrompt,
178
191
  buildPolygramDisplayHint(
179
192
  resolveRichTextEnabled(config, chatId, threadId),
180
193
  { inlineMedia: true },
181
194
  ),
182
- );
195
+ ));
183
196
  return composed;
184
197
  };
185
198
  }
@@ -189,6 +202,7 @@ module.exports = {
189
202
  // Exposed for tests + adjacent extractions that need the same env
190
203
  // discipline (e.g. lib/sdk/callbacks.js when it ships).
191
204
  filterEnv,
205
+ withoutPromptSnapshot,
192
206
  CHILD_ENV_ALLOWLIST,
193
207
  CHILD_ENV_PREFIXES,
194
208
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polygram",
3
- "version": "0.38.9",
3
+ "version": "0.39.0",
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": {
@@ -66,9 +66,9 @@
66
66
  "homepage": "https://github.com/shumkov/polygram#readme",
67
67
  "type": "commonjs",
68
68
  "dependencies": {
69
- "@anthropic-ai/claude-agent-sdk": "0.2.123",
69
+ "@anthropic-ai/claude-agent-sdk": "0.3.283",
70
70
  "@modelcontextprotocol/sdk": "^1.29.0",
71
- "@shumkov/orchestra": "0.10.21",
71
+ "@shumkov/orchestra": "0.11.0",
72
72
  "acorn": "8.18.0",
73
73
  "better-sqlite3": "^12.9.0",
74
74
  "grammy": "^1.42.0",
package/polygram.js CHANGED
@@ -4184,6 +4184,11 @@ async function main() {
4184
4184
  + `${binCheck.vendored ? ' (vendored)' : ''}`,
4185
4185
  );
4186
4186
  pinnedClaudeBin = binCheck.path;
4187
+ // CliProcess checks `claude --help` before passing newer flags; the
4188
+ // probe is synchronous and takes up to a few seconds, so run it here
4189
+ // while boot already blocks instead of on the first chat's spawn.
4190
+ const { supportsClaudeFlag } = require('@shumkov/orchestra').claudeBin;
4191
+ supportsClaudeFlag(pinnedClaudeBin, '--system-prompt-snapshot', { logger: console });
4187
4192
  } else {
4188
4193
  console.warn(`[polygram] WARNING: ${binCheck.reason}`);
4189
4194
  }