polygram 0.6.7 → 0.6.8
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/package.json +1 -1
- package/polygram.js +33 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polygram",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.8",
|
|
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
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* → sends to persistent claude process via stdin (stream-json)
|
|
12
12
|
* → reads response from stdout (stream-json)
|
|
13
13
|
* → sends reply to Telegram
|
|
14
|
-
* → writes every in/out message to
|
|
14
|
+
* → writes every in/out message to per-bot SQLite (source of truth)
|
|
15
15
|
*
|
|
16
16
|
* Chat commands: /model <model>, /effort <level>, /config
|
|
17
17
|
*/
|
|
@@ -191,7 +191,7 @@ async function readSessionContext(sessionKey, cwd) {
|
|
|
191
191
|
} catch { return ''; }
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
// ─── DB writes (
|
|
194
|
+
// ─── DB writes (best-effort wrapper, never throws) ──────────────────
|
|
195
195
|
|
|
196
196
|
function dbWrite(fn, context) {
|
|
197
197
|
if (!db) return;
|
|
@@ -238,11 +238,15 @@ function recordInbound(msg) {
|
|
|
238
238
|
const messageId = db.getInboundMessageId({ chat_id: chatId, msg_id: msg.message_id });
|
|
239
239
|
if (!messageId) return;
|
|
240
240
|
// Edit-safe insert: Telegram edited_message events re-fire
|
|
241
|
-
// recordInbound with the same (chat_id, msg_id).
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
//
|
|
245
|
-
//
|
|
241
|
+
// recordInbound with the same (chat_id, msg_id). polygram doesn't
|
|
242
|
+
// currently handle media-edit cases (Bot API does support
|
|
243
|
+
// editMessageMedia, but we don't process it specially — the typical
|
|
244
|
+
// edit is text/caption). If rows already exist for this message_id
|
|
245
|
+
// they're correct as-is — re-inserting would (a) duplicate them,
|
|
246
|
+
// (b) reset download_status back to 'pending' and lose the
|
|
247
|
+
// local_path we already fetched. If we add media-edit support
|
|
248
|
+
// later, this guard needs to compare file_unique_id and replace
|
|
249
|
+
// selectively rather than skipping wholesale.
|
|
246
250
|
if (db.getAttachmentsByMessage(messageId).length > 0) return;
|
|
247
251
|
for (const att of attachments) {
|
|
248
252
|
db.insertAttachment({
|
|
@@ -1250,13 +1254,18 @@ function startApprovalSweeper(intervalMs = 30_000) {
|
|
|
1250
1254
|
id: row.id, bot: BOT_NAME, tool: row.tool_name,
|
|
1251
1255
|
}), 'log approval-timeout');
|
|
1252
1256
|
resolveApprovalWaiter(row.id, 'timeout', 'swept');
|
|
1253
|
-
// Best-effort: edit the card to show the timeout.
|
|
1257
|
+
// Best-effort: edit the card to show the timeout. Routed through
|
|
1258
|
+
// tg() so the edit gets the same plain-text formatting policy as
|
|
1259
|
+
// the original card post (no parse_mode injection from tool input)
|
|
1260
|
+
// AND lands in the transcript like every other outbound. Pre-0.6.8
|
|
1261
|
+
// this called bot.api.editMessageText directly and bypassed both.
|
|
1254
1262
|
if (bot && row.approver_msg_id) {
|
|
1255
|
-
bot
|
|
1256
|
-
row.approver_chat_id,
|
|
1257
|
-
row.approver_msg_id,
|
|
1258
|
-
approvalCardText(approvals.getById(row.id), { resolvedBy: '⏰ Timed out' }),
|
|
1259
|
-
|
|
1263
|
+
tg(bot, 'editMessageText', {
|
|
1264
|
+
chat_id: row.approver_chat_id,
|
|
1265
|
+
message_id: row.approver_msg_id,
|
|
1266
|
+
text: approvalCardText(approvals.getById(row.id), { resolvedBy: '⏰ Timed out' }),
|
|
1267
|
+
}, { source: 'approval-card-timeout', botName: BOT_NAME, plainText: true })
|
|
1268
|
+
.catch((err) => console.error(`[${BOT_NAME}] approval-card-timeout edit: ${err.message}`));
|
|
1260
1269
|
}
|
|
1261
1270
|
}
|
|
1262
1271
|
}, intervalMs);
|
|
@@ -1812,7 +1821,17 @@ function createBot(token) {
|
|
|
1812
1821
|
async function onboardPairedChat(ctx, code) {
|
|
1813
1822
|
const chatId = ctx.chat.id.toString();
|
|
1814
1823
|
const userId = ctx.message.from?.id;
|
|
1815
|
-
|
|
1824
|
+
// Route through tg() so onboarding replies (success notice + error
|
|
1825
|
+
// messages) get the standard write-before-send DB row, log on
|
|
1826
|
+
// failure, and the same formatting policy as every other outbound.
|
|
1827
|
+
// Pre-0.6.8 this was bot.api.sendMessage(...).catch(() => {}) which
|
|
1828
|
+
// silently dropped failures: the user typed /pair, the code was
|
|
1829
|
+
// claimed (DB mutated), but if the "Paired" reply failed to send
|
|
1830
|
+
// they'd assume it didn't work and try the now-invalid code again.
|
|
1831
|
+
const send = (text) => tg(bot, 'sendMessage', {
|
|
1832
|
+
chat_id: chatId, text,
|
|
1833
|
+
}, { source: 'pair-onboarding', botName: BOT_NAME }).catch((err) =>
|
|
1834
|
+
console.error(`[${BOT_NAME}] pair-onboarding reply: ${err.message}`));
|
|
1816
1835
|
|
|
1817
1836
|
if (!userId) {
|
|
1818
1837
|
await send('No user id on request.');
|