blun-king-cli 9.1.493 → 9.1.495
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 +12 -0
- package/LIESMICH.txt +12 -2
- package/README.md +12 -2
- package/blun.mjs +71 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.1.495 - 2026-08-30
|
|
4
|
+
|
|
5
|
+
- Starts every new or replaced goal with a fresh visible TodoList and requires a truthful refresh after at most eight work batches.
|
|
6
|
+
- Retires answered Telegram group focus immediately after a successful reply or edit instead of waiting for a long-running turn to end.
|
|
7
|
+
- Defers normal inbound checkpoint acknowledgement until turn end, so restart replay cannot lose a message accepted during an early model step.
|
|
8
|
+
- Adds real control-key decoding coverage for Ctrl+S and Ctrl+T, including Kitty keyboard sequences with Caps Lock active.
|
|
9
|
+
|
|
10
|
+
## 9.1.494 - 2026-08-30
|
|
11
|
+
|
|
12
|
+
- Removes the conflicting Ctrl+S fallback that opened or collapsed the Todo panel when no queue item was visible.
|
|
13
|
+
- Keeps Todo expansion exclusively on Ctrl+T and queue-backlog release exclusively on Ctrl+S.
|
|
14
|
+
|
|
3
15
|
## 9.1.493 - 2026-08-30
|
|
4
16
|
|
|
5
17
|
- Automatically authorizes every new Telegram user message for delivery at the next safe handoff, including messages from groups, instead of requiring Ctrl+S or Escape first.
|
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.
|
|
12
|
+
npm install -g blun-king-cli@9.1.495
|
|
13
13
|
|
|
14
14
|
Start
|
|
15
15
|
-----
|
|
@@ -65,7 +65,17 @@ 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.
|
|
68
|
+
Version 9.1.495 startet jedes neue Ziel mit einer frischen sichtbaren Todo-Liste,
|
|
69
|
+
erzwingt regelmäßige wahrheitsgemäße Fortschrittsstände und quittiert normale
|
|
70
|
+
Telegram-Nachrichten erst am Zugende. Dadurch bleiben sie nach einem Neustart
|
|
71
|
+
wiederholbar, bis ihre Verarbeitung wirklich abgeschlossen ist. Erfolgreich
|
|
72
|
+
beantwortete Gruppenmeldungen verschwinden sofort aus der sichtbaren Queue.
|
|
73
|
+
Zusätzliche Regressionstests prüfen Strg+S und Strg+T als echte Terminalsequenzen,
|
|
74
|
+
auch bei aktiver Feststelltaste.
|
|
75
|
+
|
|
76
|
+
Version 9.1.494 trennt die Tastenkürzel wieder eindeutig: Strg+S steuert nur
|
|
77
|
+
den Queue-Rückstand, Strg+T nur die Todo-Liste. Version 9.1.493 stellt die
|
|
78
|
+
automatische Zustellung von User-Nachrichten auch
|
|
69
79
|
für Telegram-Gruppen wieder her. Version 9.1.492 schützt Veröffentlichungen
|
|
70
80
|
zusätzlich mit einer verpflichtenden
|
|
71
81
|
Metadatenprüfung. Packen und Veröffentlichen brechen ab, wenn Paketversion,
|
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.
|
|
12
|
+
npm install -g blun-king-cli@9.1.495
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Reproduzierbares Staging und Packen
|
|
@@ -81,7 +81,17 @@ 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.
|
|
84
|
+
Version 9.1.495 startet jedes neue Ziel mit einer frischen sichtbaren Todo-Liste,
|
|
85
|
+
erzwingt regelmäßige wahrheitsgemäße Fortschrittsstände und quittiert normale
|
|
86
|
+
Telegram-Nachrichten erst am Zugende. Dadurch bleiben sie nach einem Neustart
|
|
87
|
+
wiederholbar, bis ihre Verarbeitung wirklich abgeschlossen ist. Erfolgreich
|
|
88
|
+
beantwortete Gruppenmeldungen verschwinden sofort aus der sichtbaren Queue.
|
|
89
|
+
Zusätzliche Regressionstests prüfen Strg+S und Strg+T als echte Terminalsequenzen,
|
|
90
|
+
auch bei aktiver Feststelltaste.
|
|
91
|
+
|
|
92
|
+
Version 9.1.494 trennt die Tastenkürzel wieder eindeutig: Strg+S steuert nur
|
|
93
|
+
den Queue-Rückstand, Strg+T nur die Todo-Liste. Version 9.1.493 stellt die
|
|
94
|
+
automatische Zustellung von User-Nachrichten auch
|
|
85
95
|
für Telegram-Gruppen wieder her. Version 9.1.492 schützt Veröffentlichungen
|
|
86
96
|
zusätzlich mit einer verpflichtenden
|
|
87
97
|
Metadatenprüfung. Packen und Veröffentlichen brechen ab, wenn Paketversion,
|
package/blun.mjs
CHANGED
|
@@ -230323,6 +230323,7 @@ var init_goal$1 = __esmMin((() => {
|
|
|
230323
230323
|
});
|
|
230324
230324
|
}
|
|
230325
230325
|
this.persistState(state);
|
|
230326
|
+
this.agent.tools.updateStore(TODO_STORE_KEY, []);
|
|
230326
230327
|
this.agent.records.logRecord({
|
|
230327
230328
|
type: "goal.create",
|
|
230328
230329
|
goalId: state.goalId,
|
|
@@ -423204,6 +423205,10 @@ function validInitialIdeaPlan(value) {
|
|
|
423204
423205
|
function enforceGoalTodoPolicy(agent, context) {
|
|
423205
423206
|
if (isIdeaGoal(agent) || agent.goal.getActiveGoal() === null) return;
|
|
423206
423207
|
const todos = ideaTodos(agent);
|
|
423208
|
+
const progress = agent.goalTodoPolicyState ??= {
|
|
423209
|
+
workCallsSinceRefresh: 0,
|
|
423210
|
+
refreshRequired: false
|
|
423211
|
+
};
|
|
423207
423212
|
if (todos.length === 0) {
|
|
423208
423213
|
const firstCall = context.toolCalls[0];
|
|
423209
423214
|
if (context.toolCall.id !== firstCall?.id || context.toolCall.name !== "TodoList") return {
|
|
@@ -423214,16 +423219,34 @@ function enforceGoalTodoPolicy(agent, context) {
|
|
|
423214
423219
|
block: true,
|
|
423215
423220
|
reason: "The first goal TodoList must contain at least one item, exactly one in_progress item, and only pending items otherwise."
|
|
423216
423221
|
};
|
|
423222
|
+
progress.workCallsSinceRefresh = 0;
|
|
423223
|
+
progress.refreshRequired = false;
|
|
423217
423224
|
return;
|
|
423218
423225
|
}
|
|
423219
|
-
if (context.toolCall.name
|
|
423220
|
-
|
|
423221
|
-
|
|
423222
|
-
|
|
423223
|
-
}
|
|
423224
|
-
if (context.
|
|
423226
|
+
if (context.toolCall.name === "TodoList") {
|
|
423227
|
+
progress.workCallsSinceRefresh = 0;
|
|
423228
|
+
progress.refreshRequired = false;
|
|
423229
|
+
return;
|
|
423230
|
+
}
|
|
423231
|
+
if (context.toolCall.name === "UpdateGoal" && (context.args?.status === "complete" || context.args?.status === "blocked")) {
|
|
423232
|
+
if (todos.some((todo) => !IDEA_TERMINAL_TODO_STATUSES.includes(todo.status))) return {
|
|
423233
|
+
block: true,
|
|
423234
|
+
reason: "The goal cannot finish while a visible TodoList item has no truthful terminal status. Reconcile the list first."
|
|
423235
|
+
};
|
|
423236
|
+
if (context.args.status === "complete" && todos.some((todo) => todo.status !== "done")) return {
|
|
423237
|
+
block: true,
|
|
423238
|
+
reason: "The goal can complete only when every visible TodoList item is done. Use blocked when an item is blocked, waiting_approval, or aborted."
|
|
423239
|
+
};
|
|
423240
|
+
return;
|
|
423241
|
+
}
|
|
423242
|
+
if (context.toolCall.id === context.toolCalls[0]?.id) {
|
|
423243
|
+
progress.workCallsSinceRefresh += 1;
|
|
423244
|
+
if (progress.workCallsSinceRefresh > 8) progress.refreshRequired = true;
|
|
423245
|
+
}
|
|
423246
|
+
if (!progress.refreshRequired) return;
|
|
423247
|
+
return {
|
|
423225
423248
|
block: true,
|
|
423226
|
-
reason: "
|
|
423249
|
+
reason: "Refresh TodoList before more work. Mark only evidenced steps done, keep the actual current step in_progress, and leave later steps pending."
|
|
423227
423250
|
};
|
|
423228
423251
|
}
|
|
423229
423252
|
function ideaOutboundChannel(toolName, args) {
|
|
@@ -504008,8 +504031,9 @@ const CHANNEL_QUEUE_RETRY_MS = 5e3;
|
|
|
504008
504031
|
//#endregion
|
|
504009
504032
|
//#region src/tui/controllers/channel-queue-deadline.ts
|
|
504010
504033
|
/**
|
|
504011
|
-
* Delivers channel work
|
|
504012
|
-
*
|
|
504034
|
+
* Delivers authorized channel work during the active turn. User messages
|
|
504035
|
+
* authorize themselves on arrival; Ctrl+S and Escape remain explicit controls.
|
|
504036
|
+
* A busy runtime is retried without cancelling the turn or crossing FIFO.
|
|
504013
504037
|
*/
|
|
504014
504038
|
var ChannelQueueDeadlineController = class {
|
|
504015
504039
|
host;
|
|
@@ -505593,12 +505617,6 @@ var EditorKeyboardController = class {
|
|
|
505593
505617
|
return true;
|
|
505594
505618
|
};
|
|
505595
505619
|
editor.onCtrlS = () => {
|
|
505596
|
-
if (editor.getText().trim().length === 0 && host.state.queuedMessages.length === 0 && host.state.todoPanel.hasOverflow()) {
|
|
505597
|
-
this.clearPendingExit();
|
|
505598
|
-
host.track("shortcut_todo_expand");
|
|
505599
|
-
host.toggleTodoPanelExpansion();
|
|
505600
|
-
return;
|
|
505601
|
-
}
|
|
505602
505620
|
if (!host.streamingUI.hasActiveTurn() && host.state.appState.streamingPhase === "idle") return;
|
|
505603
505621
|
host.flushQueuedMessages(editor.getText().trim(), editor.inputMode);
|
|
505604
505622
|
host.updateQueueDisplay();
|
|
@@ -508815,6 +508833,7 @@ var SessionEventHandler = class {
|
|
|
508815
508833
|
this.turnWatchdog.stop();
|
|
508816
508834
|
this.host.restoreQueuedSteerAtTurnEnd(event.turnId);
|
|
508817
508835
|
this.host.settleChannelPromptAtTurnEnd(event.turnId, event.reason);
|
|
508836
|
+
this.host.flushDeferredChannelAcknowledgements(event.turnId);
|
|
508818
508837
|
const sessionId = this.host.session?.id;
|
|
508819
508838
|
if (sessionId !== void 0) finishPersonalMemoryRememberIntentTurn(sessionId, event.turnId);
|
|
508820
508839
|
this.host.streamingUI.flushNow();
|
|
@@ -509079,6 +509098,7 @@ var SessionEventHandler = class {
|
|
|
509079
509098
|
});
|
|
509080
509099
|
if (matchedCall !== void 0 && matchedCall.name !== "GetMedia" && isMediaToolName(matchedCall.name) && event.isError !== true) this.host.trackChannelMediaJob(event.output);
|
|
509081
509100
|
if (matchedCall?.name === "GetMedia" && event.isError !== true) this.host.runChannelMediaFallback(event.output);
|
|
509101
|
+
this.host.settleChannelReplyToolResult(matchedCall, event.isError === true);
|
|
509082
509102
|
this.subAgentEventHandler.handleAgentSwarmToolResult(event.toolCallId, resultData, event.isError === true);
|
|
509083
509103
|
if (matchedCall !== void 0 && matchedCall.name === "TodoList" && !event.isError) {
|
|
509084
509104
|
const rawTodos = matchedCall.args.todos;
|
|
@@ -517938,6 +517958,7 @@ var BlunTUI = class {
|
|
|
517938
517958
|
queueFlushBatchRemaining = 0;
|
|
517939
517959
|
queueSteerInFlight;
|
|
517940
517960
|
channelPromptInFlight;
|
|
517961
|
+
deferredChannelAcknowledgements = /* @__PURE__ */ new Map();
|
|
517941
517962
|
editorReplacementActive = false;
|
|
517942
517963
|
editorReplacement;
|
|
517943
517964
|
editorReplacementGeneration = 0;
|
|
@@ -518018,7 +518039,11 @@ var BlunTUI = class {
|
|
|
518018
518039
|
onCommit: () => {
|
|
518019
518040
|
renderTranscripts();
|
|
518020
518041
|
for (const queued of queuedItems) queued.channelTranscriptRendered = true;
|
|
518021
|
-
|
|
518042
|
+
const acknowledge = () => {
|
|
518043
|
+
for (const queued of items) queued.channelAcknowledge?.();
|
|
518044
|
+
};
|
|
518045
|
+
if (inFlight.duplicate === true) acknowledge();
|
|
518046
|
+
else this.deferChannelAcknowledgement(inFlight.turnId, acknowledge);
|
|
518022
518047
|
if (this.queueFlushBatchRemaining > 0) this.queueFlushBatchRemaining = Math.max(0, this.queueFlushBatchRemaining - items.length);
|
|
518023
518048
|
},
|
|
518024
518049
|
onRestore: () => {
|
|
@@ -518047,7 +518072,10 @@ var BlunTUI = class {
|
|
|
518047
518072
|
if (!result.accepted) return this.recoverRejectedActiveSteer(inFlight);
|
|
518048
518073
|
inFlight.turnId = String(result.turnId);
|
|
518049
518074
|
inFlight.accepted = true;
|
|
518050
|
-
if (result.duplicate === true)
|
|
518075
|
+
if (result.duplicate === true) {
|
|
518076
|
+
inFlight.duplicate = true;
|
|
518077
|
+
return this.commitQueuedSteer(inFlight);
|
|
518078
|
+
}
|
|
518051
518079
|
if (inFlight.turnEnded) return restoreHead();
|
|
518052
518080
|
if (!inFlight.stepStarted) {
|
|
518053
518081
|
inFlight.confirmationTimer = setTimeout(() => {
|
|
@@ -518076,6 +518104,18 @@ var BlunTUI = class {
|
|
|
518076
518104
|
const index = this.pendingChannelReplyGuards.indexOf(guard);
|
|
518077
518105
|
if (index >= 0) this.pendingChannelReplyGuards.splice(index, 1);
|
|
518078
518106
|
}
|
|
518107
|
+
settleChannelReplyToolResult(matchedCall, isError) {
|
|
518108
|
+
if (matchedCall === void 0 || isError) return;
|
|
518109
|
+
if (!/(?:^|__|:)(?:reply|edit_message)$/i.test(matchedCall.name ?? "")) return;
|
|
518110
|
+
const chatId = String(matchedCall.args?.["chat_id"] ?? matchedCall.args?.["chatId"] ?? "");
|
|
518111
|
+
if (chatId.length === 0) return;
|
|
518112
|
+
const delivered = this.pendingChannelReplyGuards.filter((guard) => guard.chatId === chatId);
|
|
518113
|
+
if (delivered.length === 0) return;
|
|
518114
|
+
this.pendingChannelReplyGuards = this.pendingChannelReplyGuards.filter((guard) => guard.chatId !== chatId);
|
|
518115
|
+
this.clearAddressedChannelFocus(chatId);
|
|
518116
|
+
for (const guard of delivered) if (guard.directFocus === true) this.directFocusController.noteReplyDelivered(chatId);
|
|
518117
|
+
this.updateAddressedChannelFocus();
|
|
518118
|
+
}
|
|
518079
518119
|
pinAddressedChannelFocus(chatId, origin, text) {
|
|
518080
518120
|
return this.addressedChannelFocusStore.pin({ chatId, origin, text });
|
|
518081
518121
|
}
|
|
@@ -518120,11 +518160,24 @@ var BlunTUI = class {
|
|
|
518120
518160
|
if (inFlight.stepStarted || inFlight.userCancelled === true) this.commitQueuedSteer(inFlight);
|
|
518121
518161
|
else if (inFlight.accepted) this.restoreQueuedSteer(inFlight);
|
|
518122
518162
|
}
|
|
518163
|
+
deferChannelAcknowledgement(turnId, acknowledge) {
|
|
518164
|
+
const key = String(turnId);
|
|
518165
|
+
const pending = this.deferredChannelAcknowledgements.get(key) ?? [];
|
|
518166
|
+
pending.push(acknowledge);
|
|
518167
|
+
this.deferredChannelAcknowledgements.set(key, pending);
|
|
518168
|
+
}
|
|
518169
|
+
flushDeferredChannelAcknowledgements(turnId) {
|
|
518170
|
+
const key = String(turnId);
|
|
518171
|
+
const pending = this.deferredChannelAcknowledgements.get(key);
|
|
518172
|
+
if (pending === void 0) return;
|
|
518173
|
+
this.deferredChannelAcknowledgements.delete(key);
|
|
518174
|
+
for (const acknowledge of pending) acknowledge();
|
|
518175
|
+
}
|
|
518123
518176
|
commitChannelPromptAtStepStart(turnId) {
|
|
518124
518177
|
const inFlight = this.channelPromptInFlight;
|
|
518125
518178
|
if (inFlight === void 0 || inFlight.turnId !== String(turnId)) return;
|
|
518126
518179
|
this.channelPromptInFlight = void 0;
|
|
518127
|
-
inFlight.acknowledge
|
|
518180
|
+
this.deferChannelAcknowledgement(inFlight.turnId, inFlight.acknowledge);
|
|
518128
518181
|
}
|
|
518129
518182
|
settleChannelPromptAtTurnEnd(turnId, reason) {
|
|
518130
518183
|
const inFlight = this.channelPromptInFlight;
|