blun-king-cli 9.1.503 → 9.1.505

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 9.1.505 - 2026-08-30
4
+
5
+ - Preserves Telegram messages that arrive after a TUI claims channel ownership but before the delayed channel activation finishes.
6
+ - Captures the queue boundary at ownership start, keeps a valid durable checkpoint authoritative, and consumes a replaced queue from byte zero.
7
+ - Adds a regression for the measured update handoff where message 63456 arrived after ownership began and was skipped one second later as historical backlog.
8
+
9
+ ## 9.1.504 - 2026-08-30
10
+
11
+ - Starts an automatically queued Telegram message as a fresh model turn when King is idle instead of waiting forever for an already active turn.
12
+ - Preserves one-at-a-time delivery, queue ordering, deferred acknowledgement, direct-message priority, and the existing active-turn steer path.
13
+ - Adds a regression for the measured failure where an addressed group message reached the inbox and queue checkpoint but never entered the agent context.
14
+
3
15
  ## 9.1.503 - 2026-08-30
4
16
 
5
17
  - Gives the isolated TodoList maintenance message the complete provider message shape with an explicit empty `toolCalls` array.
package/LIESMICH.txt CHANGED
@@ -9,7 +9,7 @@ Installation
9
9
  ------------
10
10
  Die geprüfte Version exakt global installieren:
11
11
 
12
- npm install -g blun-king-cli@9.1.503
12
+ npm install -g blun-king-cli@9.1.505
13
13
 
14
14
  Start
15
15
  -----
@@ -65,6 +65,15 @@ geschriebenen Entwurf zu löschen. Das gilt auch bei
65
65
  Autovervollständigung, Geistervorschlägen, Bash-Eingabe und einer offenen
66
66
  Mehrzeileneingabe.
67
67
 
68
+ Version 9.1.504 startet eine automatisch eingereihte Telegram-Nachricht im
69
+ Leerlauf als neuen Modellzug. Sie wartet damit nicht mehr auf einen bereits
70
+ laufenden Zug, der im Leerlauf definitionsgemaess nie entstehen kann.
71
+
72
+ Version 9.1.505 bewahrt Telegram-Nachrichten, die waehrend der kurzen
73
+ Kanal-Uebergabe nach dem Eigentumsanspruch, aber vor der Aktivierung eintreffen.
74
+ Der Startstand der Queue wird eingefroren; nur der bereits davor vorhandene
75
+ Altbestand darf ohne gueltigen Checkpoint uebersprungen werden.
76
+
68
77
  Version 9.1.503 ergaenzt die isolierte Wartungsnachricht um das vom Anbieterpfad
69
78
  erwartete leere toolCalls-Feld. Dadurch erreicht der Wartungsschritt das Modell,
70
79
  statt in der Nachrichten-Normalisierung mit einem TypeError abzubrechen.
package/README.md CHANGED
@@ -9,7 +9,7 @@ Voraussetzung ist Node.js 24.15 oder neuer. Die geprüfte Version wird exakt
9
9
  installiert:
10
10
 
11
11
  ```powershell
12
- npm install -g blun-king-cli@9.1.503
12
+ npm install -g blun-king-cli@9.1.505
13
13
  ```
14
14
 
15
15
  ## Reproduzierbares Staging und Packen
@@ -81,6 +81,10 @@ konkurrierenden Start zurückgewiesen und bleiben an der Spitze der
81
81
  FIFO-Warteschlange. Für diesen normalen Wartestatus erscheint kein
82
82
  `turn.agent_busy`-Fehler.
83
83
 
84
+ Version 9.1.504 startet eine automatisch eingereihte Telegram-Nachricht im
85
+ Leerlauf als neuen Modellzug. Sie wartet damit nicht mehr auf einen bereits
86
+ laufenden Zug, der im Leerlauf definitionsgemäß nie entstehen kann.
87
+
84
88
  Version 9.1.503 ergänzt die isolierte Wartungsnachricht um das vom Anbieterpfad
85
89
  erwartete leere `toolCalls`-Feld. Dadurch erreicht der Wartungsschritt das Modell,
86
90
  statt in der Nachrichten-Normalisierung mit einem TypeError abzubrechen.
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ function queueFileIdentity(stats) {
4
+ if (!stats) return '';
5
+ return `${stats.dev}:${stats.ino}:${stats.birthtimeMs}`;
6
+ }
7
+
8
+ function captureTelegramQueueBaseline(stats) {
9
+ const fileId = queueFileIdentity(stats);
10
+ const offset = Number(stats?.size);
11
+ if (!fileId || !Number.isSafeInteger(offset) || offset < 0) {
12
+ return { fileId: '', offset: 0 };
13
+ }
14
+ return { fileId, offset };
15
+ }
16
+
17
+ function validCheckpoint(checkpoint, queueFileId, queueSize) {
18
+ return checkpoint?.version === 1
19
+ && checkpoint.fileId === queueFileId
20
+ && Number.isSafeInteger(checkpoint.offset)
21
+ && checkpoint.offset >= 0
22
+ && checkpoint.offset <= queueSize;
23
+ }
24
+
25
+ function resolveTelegramQueueActivationOffset(input) {
26
+ const queueFileId = String(input?.queueFileId ?? '');
27
+ const queueSize = Number(input?.queueSize);
28
+ const baseline = input?.baseline;
29
+ if (!queueFileId || !Number.isSafeInteger(queueSize) || queueSize < 0) {
30
+ return { offset: 0, reason: 'queue_unavailable' };
31
+ }
32
+ if (validCheckpoint(input?.checkpoint, queueFileId, queueSize)) {
33
+ return { offset: input.checkpoint.offset, reason: 'checkpoint' };
34
+ }
35
+ if (
36
+ baseline?.fileId === queueFileId
37
+ && Number.isSafeInteger(baseline.offset)
38
+ && baseline.offset >= 0
39
+ && baseline.offset <= queueSize
40
+ ) {
41
+ return { offset: baseline.offset, reason: 'ownership_baseline' };
42
+ }
43
+ return { offset: 0, reason: 'queue_replaced' };
44
+ }
45
+
46
+ module.exports = {
47
+ captureTelegramQueueBaseline,
48
+ resolveTelegramQueueActivationOffset,
49
+ };
package/blun.mjs CHANGED
@@ -419615,6 +419615,7 @@ var { createDirectFocusController, createDirectReplyTurnStop, enqueueTelegramDir
419615
419615
  var { enqueueTelegramAddressed } = createRequire(import.meta.url)("./bin/telegram-addressed-priority.cjs");
419616
419616
  var { enqueueTelegramBotPriority, telegramBotPriorityMessage } = createRequire(import.meta.url)("./bin/telegram-bot-priority.cjs");
419617
419617
  var { createAddressedChannelFocusStore } = createRequire(import.meta.url)("./bin/telegram-addressed-focus.cjs");
419618
+ var { captureTelegramQueueBaseline, resolveTelegramQueueActivationOffset } = createRequire(import.meta.url)("./bin/telegram-queue-handoff-policy.cjs");
419618
419619
  var { removeQueuedReloadCommands, removeQueuedSlashCommands } = createRequire(import.meta.url)("./bin/reload-queue-policy.cjs");
419619
419620
  const MAX_BUFFERED_CONTEXT_MESSAGES = 20;
419620
419621
  const MAX_BUFFERED_CONTEXT_CHARS = 24e3;
@@ -419928,6 +419929,7 @@ var TelegramChannelController = class {
419928
419929
  offset = 0;
419929
419930
  checkpointOffset = 0;
419930
419931
  queueFileId = "";
419932
+ queueClaimBaseline = { fileId: "", offset: 0 };
419931
419933
  remainder = Buffer.alloc(0);
419932
419934
  pendingQueueLines = [];
419933
419935
  started = false;
@@ -419985,6 +419987,11 @@ var TelegramChannelController = class {
419985
419987
  try {
419986
419988
  mkdirSync(this.dir, { recursive: true });
419987
419989
  } catch {}
419990
+ try {
419991
+ this.queueClaimBaseline = captureTelegramQueueBaseline(statSync(this.queueFile));
419992
+ } catch {
419993
+ this.queueClaimBaseline = { fileId: "", offset: 0 };
419994
+ }
419988
419995
  if (!this.claimOwnership()) return;
419989
419996
  this.ownershipTimer = setInterval(() => this.checkOwnership(), this.ownershipPollMs);
419990
419997
  this.ownershipTimer.unref();
@@ -420004,11 +420011,14 @@ var TelegramChannelController = class {
420004
420011
  const stats = statSync(this.queueFile);
420005
420012
  this.queueFileId = queueIdentity(stats);
420006
420013
  const checkpoint = this.readQueueCheckpoint();
420007
- if (checkpoint?.fileId === this.queueFileId && checkpoint.offset >= 0 && checkpoint.offset <= stats.size) this.offset = checkpoint.offset;
420008
- else {
420009
- this.offset = stats.size;
420010
- this.writeQueueCheckpoint(this.offset);
420011
- }
420014
+ const activation = resolveTelegramQueueActivationOffset({
420015
+ queueFileId: this.queueFileId,
420016
+ queueSize: stats.size,
420017
+ checkpoint,
420018
+ baseline: this.queueClaimBaseline
420019
+ });
420020
+ this.offset = activation.offset;
420021
+ if (activation.reason !== "checkpoint") this.writeQueueCheckpoint(this.offset);
420012
420022
  this.checkpointOffset = this.offset;
420013
420023
  } catch {
420014
420024
  this.offset = 0;
@@ -518093,8 +518103,7 @@ var BlunTUI = class {
518093
518103
  }
518094
518104
  canDeliverQueuedChannelHead() {
518095
518105
  const item = this.state.queuedMessages[0];
518096
- const hasActiveTurn = this.streamingUI.hasActiveTurn() || (this.state.appState.streamingPhase !== "idle" && this.state.appState.streamingPhase !== "shell");
518097
- if (this.isShuttingDown || this.queueCommandRunning || this.queueSteerInFlight !== void 0 || this.editorReplacementActive || this.deferUserMessages || this.session === void 0 || this.state.appState.model.trim().length === 0 || !hasActiveTurn || item?.mode !== "channel") return false;
518106
+ if (this.isShuttingDown || this.queueCommandRunning || this.queueSteerInFlight !== void 0 || this.editorReplacementActive || this.deferUserMessages || this.session === void 0 || this.state.appState.model.trim().length === 0 || item?.mode !== "channel") return false;
518098
518107
  return true;
518099
518108
  }
518100
518109
  async deliverQueuedChannelHead() {
@@ -518102,6 +518111,15 @@ var BlunTUI = class {
518102
518111
  const session = this.session;
518103
518112
  const item = this.state.queuedMessages[0];
518104
518113
  if (session === void 0 || item?.mode !== "channel") return false;
518114
+ const hasActiveTurn = this.streamingUI.hasActiveTurn() || (this.state.appState.streamingPhase !== "idle" && this.state.appState.streamingPhase !== "shell");
518115
+ if (!hasActiveTurn && item.channelContextOnly !== true) {
518116
+ this.state.queuedMessages = this.state.queuedMessages.slice(1);
518117
+ if (this.queueFlushBatchRemaining > 0) this.queueFlushBatchRemaining -= 1;
518118
+ this.updateQueueDisplay();
518119
+ this.sendChannelMessageInternal(session, item.text, item.displayText ?? item.text.trim(), item.origin, item.channelChatId, item.channelImagePath, false, item.channelTranscriptRendered === true, item.channelAcknowledge, item.channelAttention === true, item.queueKey, item.channelDirect === true, item.channelDirectResume === true, item.channelReportSources ?? [], item.channelFocusId);
518120
+ this.syncChannelQueueDeadline();
518121
+ return true;
518122
+ }
518105
518123
  const turnId = this.streamingUI.getTurnContext().turnId;
518106
518124
  if (item.channelContextOnly === true) {
518107
518125
  this.state.queuedMessages = this.state.queuedMessages.slice(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.503",
3
+ "version": "9.1.505",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {