blun-king-cli 9.1.376 → 9.1.378

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.
Files changed (2) hide show
  1. package/blun.mjs +88 -4
  2. package/package.json +1 -1
package/blun.mjs CHANGED
@@ -419329,6 +419329,8 @@ const OWNERSHIP_SETTLE_MS = 50;
419329
419329
  const OWNERSHIP_HANDOFF_WARNING_MS = 5e3;
419330
419330
  const BRIDGE_STOP_TIMEOUT_MS = 2500;
419331
419331
  const BRIDGE_FORCE_STOP_TIMEOUT_MS = 500;
419332
+ const CHANNEL_STEER_CONFIRM_TIMEOUT_MS = 15e3;
419333
+ const CHANNEL_DELIVERY_MAX_FAILURES = 3;
419332
419334
  const BLUN_NODE_FALLBACK_SUBCOMMAND = "__plugin_run_node";
419333
419335
  function isBlunNativeBinary(execPath) {
419334
419336
  return !basename(execPath).toLowerCase().startsWith("node");
@@ -516231,7 +516233,9 @@ function requestRunningUpdateAtSafeBoundary(tui) {
516231
516233
  })) {
516232
516234
  if (tui.runningUpdatePreparedNoticeVersion !== version) {
516233
516235
  tui.runningUpdatePreparedNoticeVersion = version;
516234
- tui.showStatus(runningUpdateNoticeText(version, mode), "success");
516236
+ const notice = runningUpdateNoticeText(version, mode);
516237
+ if (typeof tui.showRunningUpdateStatus === "function") tui.showRunningUpdateStatus(notice);
516238
+ else tui.showStatus(notice, "success");
516235
516239
  }
516236
516240
  return false;
516237
516241
  }
@@ -516361,6 +516365,7 @@ var BlunTUI = class {
516361
516365
  runningUpdatePreparedVersion;
516362
516366
  runningUpdatePreparedMode;
516363
516367
  runningUpdatePreparedNoticeVersion;
516368
+ runningUpdatePreparedNoticeComponent;
516364
516369
  runningUpdateMessageDispose;
516365
516370
  startupPhaseMs = {};
516366
516371
  lastActivityMode;
@@ -517296,9 +517301,16 @@ var BlunTUI = class {
517296
517301
  try {
517297
517302
  const result = await this.harness.withInteractiveAgent(item.agentId ?? "main", () => session.steerActive(input, expectedTurnId === void 0 ? {} : { expectedTurnId }));
517298
517303
  if (!result.accepted) return this.recoverRejectedActiveSteer(inFlight);
517304
+ inFlight.turnId = String(result.turnId);
517299
517305
  inFlight.accepted = true;
517300
517306
  if (result.duplicate === true) return this.commitQueuedSteer(inFlight);
517301
517307
  if (inFlight.turnEnded) return restoreHead();
517308
+ if (!inFlight.stepStarted) {
517309
+ inFlight.confirmationTimer = setTimeout(() => {
517310
+ if (this.queueSteerInFlight === inFlight && inFlight.accepted && !inFlight.stepStarted) restoreHead(new Error("channel steer confirmation timed out"));
517311
+ }, CHANNEL_STEER_CONFIRM_TIMEOUT_MS);
517312
+ inFlight.confirmationTimer.unref?.();
517313
+ }
517302
517314
  this.commitQueuedSteerIfReady(inFlight);
517303
517315
  } catch (error) {
517304
517316
  return restoreHead(error);
@@ -517341,6 +517353,7 @@ var BlunTUI = class {
517341
517353
  }
517342
517354
  commitQueuedSteer(inFlight) {
517343
517355
  if (this.queueSteerInFlight !== inFlight) return;
517356
+ if (inFlight.confirmationTimer !== void 0) clearTimeout(inFlight.confirmationTimer);
517344
517357
  this.queueSteerInFlight = void 0;
517345
517358
  inFlight.onCommit();
517346
517359
  this.updateQueueDisplay();
@@ -517357,11 +517370,64 @@ var BlunTUI = class {
517357
517370
  }
517358
517371
  return restored;
517359
517372
  }
517373
+ quarantineQueuedSteer(inFlight, error) {
517374
+ if (this.queueSteerInFlight !== inFlight) return false;
517375
+ if (inFlight.confirmationTimer !== void 0) clearTimeout(inFlight.confirmationTimer);
517376
+ this.queueSteerInFlight = void 0;
517377
+ inFlight.onRestore?.();
517378
+ const record = {
517379
+ version: 1,
517380
+ quarantinedAt: new Date().toISOString(),
517381
+ reason: String(error?.code ?? error?.name ?? "channel_delivery_failed"),
517382
+ attempts: CHANNEL_DELIVERY_MAX_FAILURES,
517383
+ items: inFlight.items.map((item) => ({
517384
+ text: item.text,
517385
+ displayText: item.displayText,
517386
+ origin: item.origin,
517387
+ mode: item.mode,
517388
+ agentId: item.agentId,
517389
+ chatId: item.channelChatId,
517390
+ queueKey: item.queueKey,
517391
+ contextOnly: item.channelContextOnly === true,
517392
+ attention: item.channelAttention === true,
517393
+ urgent: item.channelUrgent === true,
517394
+ direct: item.channelDirect === true,
517395
+ addressed: item.channelAddressed === true,
517396
+ imagePath: item.channelImagePath
517397
+ }))
517398
+ };
517399
+ try {
517400
+ appendFileSync(join(telegramStateDir(), "inbound-queue-quarantine.jsonl"), `${JSON.stringify(record)}\n`, { encoding: "utf8", mode: 384 });
517401
+ } catch (archiveError) {
517402
+ this.state.queuedMessages = [...inFlight.items.map((item) => ({
517403
+ ...item,
517404
+ channelDeliveryFailures: CHANNEL_DELIVERY_MAX_FAILURES - 1
517405
+ })), ...this.state.queuedMessages];
517406
+ this.showError(uiText("blunTui.steer.failed", { error: formatErrorMessage$2(archiveError) }));
517407
+ this.updateQueueDisplay();
517408
+ this.state.ui.requestRender();
517409
+ this.scheduleQueueDrain();
517410
+ return false;
517411
+ }
517412
+ for (const item of inFlight.items) item.channelAcknowledge?.();
517413
+ if (this.queueFlushBatchRemaining > 0) this.queueFlushBatchRemaining = Math.max(0, this.queueFlushBatchRemaining - inFlight.items.length);
517414
+ this.track("channel_queue_quarantined", { count: inFlight.items.length, attempts: CHANNEL_DELIVERY_MAX_FAILURES });
517415
+ this.updateQueueDisplay();
517416
+ this.state.ui.requestRender();
517417
+ this.scheduleQueueDrain();
517418
+ return false;
517419
+ }
517360
517420
  restoreQueuedSteer(inFlight, error) {
517361
517421
  if (this.queueSteerInFlight !== inFlight) return false;
517422
+ if (inFlight.confirmationTimer !== void 0) clearTimeout(inFlight.confirmationTimer);
517423
+ const failureCount = Math.max(0, ...inFlight.items.map((item) => Number(item.channelDeliveryFailures) || 0)) + 1;
517424
+ if (failureCount >= CHANNEL_DELIVERY_MAX_FAILURES) return this.quarantineQueuedSteer(inFlight, error);
517362
517425
  this.queueSteerInFlight = void 0;
517363
517426
  inFlight.onRestore?.();
517364
- this.state.queuedMessages = [...inFlight.items, ...this.state.queuedMessages];
517427
+ this.state.queuedMessages = [...inFlight.items.map((item) => ({
517428
+ ...item,
517429
+ channelDeliveryFailures: failureCount
517430
+ })), ...this.state.queuedMessages];
517365
517431
  if (error !== void 0) this.showError(uiText("blunTui.steer.failed", { error: formatErrorMessage$2(error) }));
517366
517432
  this.updateQueueDisplay();
517367
517433
  this.state.ui.requestRender();
@@ -517437,7 +517503,7 @@ var BlunTUI = class {
517437
517503
  for (const item of items) this.appendTranscriptEntry({
517438
517504
  id: nextTranscriptId(),
517439
517505
  kind: "user",
517440
- turnId,
517506
+ turnId: inFlight.turnId,
517441
517507
  renderMode: "plain",
517442
517508
  content: item.text.trim()
517443
517509
  });
@@ -517449,6 +517515,7 @@ var BlunTUI = class {
517449
517515
  if (this.queueSteerInFlight !== inFlight) return;
517450
517516
  if (!result.accepted) this.recoverRejectedActiveSteer(inFlight);
517451
517517
  else {
517518
+ inFlight.turnId = String(result.turnId);
517452
517519
  inFlight.accepted = true;
517453
517520
  if (inFlight.turnEnded) this.restoreQueuedSteer(inFlight);
517454
517521
  else this.commitQueuedSteerIfReady(inFlight);
@@ -517635,6 +517702,10 @@ var BlunTUI = class {
517635
517702
  this.state.ui.requestRender();
517636
517703
  return;
517637
517704
  }
517705
+ if (command.name === "loop" && activeTurn && !this.queueCommandRunning) {
517706
+ this.runTelegramRemoteCommand(item);
517707
+ return;
517708
+ }
517638
517709
  const busy = this.session === void 0 || this.state.appState.model.trim().length === 0 || this.state.queuedMessages.length > 0 || this.queueSteerInFlight !== void 0 || this.pendingChannelReplyGuard !== void 0 || this.deferUserMessages || this.streamingUI.hasActiveTurn() || this.state.appState.streamingPhase !== "idle" || this.state.appState.isCompacting;
517639
517710
  if (busy) {
517640
517711
  this.state.queuedMessages.push(item);
@@ -517671,7 +517742,8 @@ var BlunTUI = class {
517671
517742
  if (this.telegramRemoteCommandContext === context) this.telegramRemoteCommandContext = void 0;
517672
517743
  if (!context.sentModelTurn) {
517673
517744
  const response = context.responses.at(-1) ?? item.displayText ?? item.text;
517674
- if (await sendReplyFallback(item.channelChatId, response, false)) item.channelAcknowledge?.();
517745
+ if (!await sendReplyFallback(item.channelChatId, response, false)) this.track("telegram_command_reply_failed", { command: item.telegramCommandName });
517746
+ item.channelAcknowledge?.();
517675
517747
  }
517676
517748
  this.queueCommandRunning = false;
517677
517749
  if (!this.editorReplacementActive) this.preserveQueueAcrossSessionReset = false;
@@ -518875,6 +518947,18 @@ var BlunTUI = class {
518875
518947
  for (const child of toDispose) if (hasDispose(child)) child.dispose();
518876
518948
  children.splice(0, children.length, ...newChildren);
518877
518949
  }
518950
+ showRunningUpdateStatus(message) {
518951
+ const next = new StatusMessageComponent(message, "success");
518952
+ const current = this.runningUpdatePreparedNoticeComponent;
518953
+ const children = this.state.transcriptContainer.children;
518954
+ const currentIndex = current === void 0 ? -1 : children.indexOf(current);
518955
+ if (currentIndex >= 0) {
518956
+ if (hasDispose(current)) current.dispose();
518957
+ children.splice(currentIndex, 1, next);
518958
+ } else this.state.transcriptContainer.addChild(next);
518959
+ this.runningUpdatePreparedNoticeComponent = next;
518960
+ this.state.ui.requestRender();
518961
+ }
518878
518962
  showStatus(message, color) {
518879
518963
  this.telegramRemoteCommandContext?.responses.push(message);
518880
518964
  this.state.transcriptContainer.addChild(new StatusMessageComponent(message, color));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.376",
3
+ "version": "9.1.378",
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": {