polygram 0.10.0-rc.31 → 0.10.0-rc.32
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/db/sessions.js +28 -11
- package/lib/process/tmux-process.js +6 -3
- package/package.json +1 -1
- package/polygram.js +11 -8
|
@@ -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.32",
|
|
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",
|
package/lib/db/sessions.js
CHANGED
|
@@ -98,16 +98,33 @@ function getClaudeSessionId(db, sessionKey) {
|
|
|
98
98
|
// ─── S2: session-config drift ────────────────────────────────────────
|
|
99
99
|
//
|
|
100
100
|
// A stored `sessions` row records the config the claude session was
|
|
101
|
-
// SPAWNED under
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
101
|
+
// SPAWNED under. Two of the recorded fields are spawn-identity:
|
|
102
|
+
// - agent — `--agent <name>` is baked into the spawned process;
|
|
103
|
+
// resuming a session spawned under agent X under agent Y forces
|
|
104
|
+
// claude to use Y's system prompt + tool whitelist against
|
|
105
|
+
// conversation history built under X's. Incoherent.
|
|
106
|
+
// - cwd — `--cwd <path>` (SDK) / tmux session cwd; claude resolves
|
|
107
|
+
// project-local config (.claude/settings.json, agent files,
|
|
108
|
+
// plugins) relative to it. Mid-conversation cwd drift means
|
|
109
|
+
// half the messages are answered with one project's allowlist
|
|
110
|
+
// and the other half with another's.
|
|
111
|
+
//
|
|
112
|
+
// pm_backend was REMOVED from spawn-identity (rc.32, 2026-05-21).
|
|
113
|
+
// Both backends spawn the same pinned claude binary and write the
|
|
114
|
+
// same on-disk JSONL (~/.claude/projects/<cwd-enc>/<sid>.jsonl) —
|
|
115
|
+
// claude itself doesn't know or care which Node-side wrapper invoked
|
|
116
|
+
// it. Treating a backend flip as drift was destructively dropping
|
|
117
|
+
// context across the SDK→tmux migration window, costing every chat
|
|
118
|
+
// its conversation history on its first turn under the new backend.
|
|
119
|
+
// shumorobot 2026-05-20 18:51 incident: the Music topic flipped
|
|
120
|
+
// tmux→sdk→tmux during runtime and lost its agent's prior context
|
|
121
|
+
// at each flip. The orphan-tmux problem that the flip ALSO triggered
|
|
122
|
+
// is solved by rc.31's spawn-time reconcile (TmuxProcess.start) —
|
|
123
|
+
// independently, so a backend flip is now a no-op for session-state.
|
|
124
|
+
//
|
|
125
|
+
// shumorobot 2026-05-17 22:03, topic :3 (the original drift incident)
|
|
126
|
+
// remains correctly handled: that row had agent+cwd drift in
|
|
127
|
+
// addition to backend, so the agent+cwd drift alone still drops it.
|
|
111
128
|
//
|
|
112
129
|
// model + effort are deliberately EXCLUDED from the invalidating set.
|
|
113
130
|
// They are NOT spawn-identity: a live `/model` or `/effort` change is
|
|
@@ -118,7 +135,7 @@ function getClaudeSessionId(db, sessionKey) {
|
|
|
118
135
|
// every model switch, double-handling what the live-apply path
|
|
119
136
|
// already covers cleanly. The stored model/effort columns are
|
|
120
137
|
// informational, not identity.
|
|
121
|
-
const SPAWN_IDENTITY_FIELDS = ['agent', 'cwd'
|
|
138
|
+
const SPAWN_IDENTITY_FIELDS = ['agent', 'cwd'];
|
|
122
139
|
|
|
123
140
|
/**
|
|
124
141
|
* Decide whether a stored session can be resumed for the next spawn,
|
|
@@ -499,9 +499,12 @@ class TmuxProcess extends Process {
|
|
|
499
499
|
// Spawn-time reconcile (shumorobot 2026-05-20 18:51 incident).
|
|
500
500
|
// A tmux session with our name may already exist on the host
|
|
501
501
|
// BEFORE we spawn — sources:
|
|
502
|
-
// - pm_backend
|
|
503
|
-
// polygram dropped its in-memory handle
|
|
504
|
-
// daemon's tmux session is still
|
|
502
|
+
// - pm_backend flip: chat config flipped tmux → sdk → tmux;
|
|
503
|
+
// polygram dropped its in-memory handle on the flip away
|
|
504
|
+
// from tmux but the previous daemon's tmux session is still
|
|
505
|
+
// running headless. (rc.32 makes the flip context-preserving
|
|
506
|
+
// on the session-id side; this reconcile keeps the
|
|
507
|
+
// tmux-pane side safe.)
|
|
505
508
|
// - Boot-sweep raced a concurrent operator (already noted in
|
|
506
509
|
// lib/tmux/orphan-sweep.js header).
|
|
507
510
|
// - Crash mid-spawn: the spawn() call landed but the sessionCreated
|
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.32",
|
|
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
|
@@ -400,18 +400,21 @@ function buildSpawnContext(sessionKey) {
|
|
|
400
400
|
const threadId = sessionKey.includes(':') ? sessionKey.split(':')[1] : null;
|
|
401
401
|
|
|
402
402
|
// S2: a stored session is valid ONLY for the config it was spawned
|
|
403
|
-
// under. agent / cwd
|
|
404
|
-
//
|
|
405
|
-
//
|
|
406
|
-
//
|
|
407
|
-
//
|
|
403
|
+
// under. agent / cwd are spawn-identity — baked into the process at
|
|
404
|
+
// spawn time, never mutable on a live session. Resolve them the
|
|
405
|
+
// same way the backends do (topic override merged over chat-level)
|
|
406
|
+
// and compare to the stored `sessions` row. On drift,
|
|
407
|
+
// resolveSessionForSpawn drops the stale row and returns
|
|
408
408
|
// existingSessionId:null → the spawn starts fresh under the correct
|
|
409
409
|
// config instead of `--resume`-ing a stale one. This self-heals the
|
|
410
410
|
// pre-per-topic-config rows (e.g. shumorobot's Music topic :3,
|
|
411
|
-
// stored agent=shumabit / cwd=$HOME
|
|
412
|
-
// music-curation:music-curator / .../Music/rekordbox
|
|
411
|
+
// stored agent=shumabit / cwd=$HOME vs the current
|
|
412
|
+
// music-curation:music-curator / .../Music/rekordbox).
|
|
413
413
|
// model/effort are NOT compared — they apply live via setModel /
|
|
414
|
-
// applyFlagSettings with no respawn.
|
|
414
|
+
// applyFlagSettings with no respawn. pm_backend is also NOT
|
|
415
|
+
// compared (rc.32): both backends spawn the same pinned claude
|
|
416
|
+
// binary against the same on-disk JSONL, so a backend flip
|
|
417
|
+
// preserves context. See lib/db/sessions.js for full reasoning.
|
|
415
418
|
//
|
|
416
419
|
// The drift check runs only at COLD spawn (no warm process). A warm
|
|
417
420
|
// process already runs under its spawn-time config; getOrSpawn
|