polygram 0.7.4 → 0.7.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.
- package/.claude-plugin/plugin.json +1 -1
- package/lib/parse-response.js +56 -0
- package/package.json +1 -1
- package/polygram.js +14 -12
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "polygram",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.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",
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse Claude's final-turn text into one of three outbound shapes:
|
|
3
|
+
* - sticker (single emoji that maps to a sticker, OR literal
|
|
4
|
+
* `[sticker:NAME]` mimic — see below)
|
|
5
|
+
* - reaction (single emoji not mapped to a sticker)
|
|
6
|
+
* - text (everything else)
|
|
7
|
+
*
|
|
8
|
+
* Why this lives in lib/: polygram.js is a top-level script (calls main()
|
|
9
|
+
* at bottom) and can't be require()'d from a test without starting a bot.
|
|
10
|
+
* Pulling parseResponse out lets tests cover the regex edge cases.
|
|
11
|
+
*
|
|
12
|
+
* 0.7.5 (item: sticker regression):
|
|
13
|
+
* deriveOutboundText (lib/telegram.js) synthesises `[sticker:<name>]` for
|
|
14
|
+
* sendSticker calls so the messages.text column has *something* legible.
|
|
15
|
+
* On session resume Claude reads its own past assistant rows and sees
|
|
16
|
+
* `[sticker:working]` as the assistant message text — and starts mimicking
|
|
17
|
+
* the format LITERALLY, emitting the string `[sticker:working]` as plain
|
|
18
|
+
* text. parseResponse used to fall through to the chunked-text path, so
|
|
19
|
+
* the placeholder ended up rendered in the user's chat instead of an
|
|
20
|
+
* actual sticker.
|
|
21
|
+
*
|
|
22
|
+
* Match shape: optional whitespace, `[sticker:`, NAME (alnum/_/-), `]`,
|
|
23
|
+
* optional whitespace. NAME must resolve in the supplied stickerMap;
|
|
24
|
+
* unknown NAMEs fall through to the text path so a genuine
|
|
25
|
+
* "[sticker:foo]" message (e.g. someone joking, or a stale name from an
|
|
26
|
+
* older deploy) still reaches the user verbatim.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const STICKER_TAG_RE = /^\s*\[sticker:([A-Za-z0-9_-]+)\]\s*$/;
|
|
30
|
+
|
|
31
|
+
function parseResponse(text, { stickerMap = {}, emojiToSticker = {} } = {}) {
|
|
32
|
+
const trimmed = (text || '').trim();
|
|
33
|
+
|
|
34
|
+
const tagMatch = trimmed.match(STICKER_TAG_RE);
|
|
35
|
+
if (tagMatch) {
|
|
36
|
+
const name = tagMatch[1];
|
|
37
|
+
const fileId = stickerMap[name];
|
|
38
|
+
if (fileId) {
|
|
39
|
+
return { text: '', sticker: fileId, stickerLabel: name, reaction: null };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const emojiOnly = /^\p{Emoji_Presentation}$/u.test(trimmed)
|
|
44
|
+
|| /^\p{Emoji}️?$/u.test(trimmed);
|
|
45
|
+
|
|
46
|
+
if (emojiOnly && trimmed) {
|
|
47
|
+
if (emojiToSticker[trimmed]) {
|
|
48
|
+
return { text: '', sticker: emojiToSticker[trimmed], stickerLabel: trimmed, reaction: null };
|
|
49
|
+
}
|
|
50
|
+
return { text: '', sticker: null, stickerLabel: null, reaction: trimmed };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { text: trimmed, sticker: null, stickerLabel: null, reaction: null };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = { parseResponse, STICKER_TAG_RE };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polygram",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.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": {
|
package/polygram.js
CHANGED
|
@@ -961,19 +961,21 @@ const stdinLock = createAsyncLock();
|
|
|
961
961
|
// hammering sendChatAction every 4s for the full turn duration.
|
|
962
962
|
|
|
963
963
|
// ─── Response parsing (stickers, reactions) ─────────────────────────
|
|
964
|
-
|
|
964
|
+
// Implementation lives in lib/parse-response.js so tests can require it
|
|
965
|
+
// without starting a bot (polygram.js is a top-level script that calls
|
|
966
|
+
// main() at bottom). The wrapper here supplies the runtime stickerMap /
|
|
967
|
+
// emojiToSticker that the parser looks up against.
|
|
968
|
+
//
|
|
969
|
+
// 0.7.5: parser also recognises a literal `[sticker:NAME]` pattern in
|
|
970
|
+
// addition to single-emoji shortcuts. Claude reads its own past outbound
|
|
971
|
+
// rows on session resume, sees `[sticker:working]` (the placeholder
|
|
972
|
+
// deriveOutboundText synthesises for sendSticker rows), and starts
|
|
973
|
+
// mimicking the format as plain text. Without the new branch the
|
|
974
|
+
// placeholder was rendered verbatim in the chat instead of swapped for
|
|
975
|
+
// the actual sticker.
|
|
976
|
+
const { parseResponse: parseResponseImpl } = require('./lib/parse-response');
|
|
965
977
|
function parseResponse(text) {
|
|
966
|
-
|
|
967
|
-
const emojiOnly = /^\p{Emoji_Presentation}$/u.test(trimmed) || /^\p{Emoji}\uFE0F?$/u.test(trimmed);
|
|
968
|
-
|
|
969
|
-
if (emojiOnly && trimmed) {
|
|
970
|
-
if (emojiToSticker[trimmed]) {
|
|
971
|
-
return { text: '', sticker: emojiToSticker[trimmed], stickerLabel: trimmed, reaction: null };
|
|
972
|
-
}
|
|
973
|
-
return { text: '', sticker: null, stickerLabel: null, reaction: trimmed };
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
return { text: trimmed, sticker: null, stickerLabel: null, reaction: null };
|
|
978
|
+
return parseResponseImpl(text, { stickerMap, emojiToSticker });
|
|
977
979
|
}
|
|
978
980
|
|
|
979
981
|
// ─── Cron/IPC send ─────────────────────────────────────────────────
|