blun-king-cli 9.1.494 → 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 +7 -0
- package/LIESMICH.txt +9 -1
- package/README.md +9 -1
- package/blun.mjs +68 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
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
|
+
|
|
3
10
|
## 9.1.494 - 2026-08-30
|
|
4
11
|
|
|
5
12
|
- Removes the conflicting Ctrl+S fallback that opened or collapsed the Todo panel when no queue item was visible.
|
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,6 +65,14 @@ 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.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
|
+
|
|
68
76
|
Version 9.1.494 trennt die Tastenkürzel wieder eindeutig: Strg+S steuert nur
|
|
69
77
|
den Queue-Rückstand, Strg+T nur die Todo-Liste. Version 9.1.493 stellt die
|
|
70
78
|
automatische Zustellung von User-Nachrichten auch
|
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,6 +81,14 @@ 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.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
|
+
|
|
84
92
|
Version 9.1.494 trennt die Tastenkürzel wieder eindeutig: Strg+S steuert nur
|
|
85
93
|
den Queue-Rückstand, Strg+T nur die Todo-Liste. Version 9.1.493 stellt die
|
|
86
94
|
automatische Zustellung von User-Nachrichten auch
|
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) {
|
|
@@ -508810,6 +508833,7 @@ var SessionEventHandler = class {
|
|
|
508810
508833
|
this.turnWatchdog.stop();
|
|
508811
508834
|
this.host.restoreQueuedSteerAtTurnEnd(event.turnId);
|
|
508812
508835
|
this.host.settleChannelPromptAtTurnEnd(event.turnId, event.reason);
|
|
508836
|
+
this.host.flushDeferredChannelAcknowledgements(event.turnId);
|
|
508813
508837
|
const sessionId = this.host.session?.id;
|
|
508814
508838
|
if (sessionId !== void 0) finishPersonalMemoryRememberIntentTurn(sessionId, event.turnId);
|
|
508815
508839
|
this.host.streamingUI.flushNow();
|
|
@@ -509074,6 +509098,7 @@ var SessionEventHandler = class {
|
|
|
509074
509098
|
});
|
|
509075
509099
|
if (matchedCall !== void 0 && matchedCall.name !== "GetMedia" && isMediaToolName(matchedCall.name) && event.isError !== true) this.host.trackChannelMediaJob(event.output);
|
|
509076
509100
|
if (matchedCall?.name === "GetMedia" && event.isError !== true) this.host.runChannelMediaFallback(event.output);
|
|
509101
|
+
this.host.settleChannelReplyToolResult(matchedCall, event.isError === true);
|
|
509077
509102
|
this.subAgentEventHandler.handleAgentSwarmToolResult(event.toolCallId, resultData, event.isError === true);
|
|
509078
509103
|
if (matchedCall !== void 0 && matchedCall.name === "TodoList" && !event.isError) {
|
|
509079
509104
|
const rawTodos = matchedCall.args.todos;
|
|
@@ -517933,6 +517958,7 @@ var BlunTUI = class {
|
|
|
517933
517958
|
queueFlushBatchRemaining = 0;
|
|
517934
517959
|
queueSteerInFlight;
|
|
517935
517960
|
channelPromptInFlight;
|
|
517961
|
+
deferredChannelAcknowledgements = /* @__PURE__ */ new Map();
|
|
517936
517962
|
editorReplacementActive = false;
|
|
517937
517963
|
editorReplacement;
|
|
517938
517964
|
editorReplacementGeneration = 0;
|
|
@@ -518013,7 +518039,11 @@ var BlunTUI = class {
|
|
|
518013
518039
|
onCommit: () => {
|
|
518014
518040
|
renderTranscripts();
|
|
518015
518041
|
for (const queued of queuedItems) queued.channelTranscriptRendered = true;
|
|
518016
|
-
|
|
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);
|
|
518017
518047
|
if (this.queueFlushBatchRemaining > 0) this.queueFlushBatchRemaining = Math.max(0, this.queueFlushBatchRemaining - items.length);
|
|
518018
518048
|
},
|
|
518019
518049
|
onRestore: () => {
|
|
@@ -518042,7 +518072,10 @@ var BlunTUI = class {
|
|
|
518042
518072
|
if (!result.accepted) return this.recoverRejectedActiveSteer(inFlight);
|
|
518043
518073
|
inFlight.turnId = String(result.turnId);
|
|
518044
518074
|
inFlight.accepted = true;
|
|
518045
|
-
if (result.duplicate === true)
|
|
518075
|
+
if (result.duplicate === true) {
|
|
518076
|
+
inFlight.duplicate = true;
|
|
518077
|
+
return this.commitQueuedSteer(inFlight);
|
|
518078
|
+
}
|
|
518046
518079
|
if (inFlight.turnEnded) return restoreHead();
|
|
518047
518080
|
if (!inFlight.stepStarted) {
|
|
518048
518081
|
inFlight.confirmationTimer = setTimeout(() => {
|
|
@@ -518071,6 +518104,18 @@ var BlunTUI = class {
|
|
|
518071
518104
|
const index = this.pendingChannelReplyGuards.indexOf(guard);
|
|
518072
518105
|
if (index >= 0) this.pendingChannelReplyGuards.splice(index, 1);
|
|
518073
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
|
+
}
|
|
518074
518119
|
pinAddressedChannelFocus(chatId, origin, text) {
|
|
518075
518120
|
return this.addressedChannelFocusStore.pin({ chatId, origin, text });
|
|
518076
518121
|
}
|
|
@@ -518115,11 +518160,24 @@ var BlunTUI = class {
|
|
|
518115
518160
|
if (inFlight.stepStarted || inFlight.userCancelled === true) this.commitQueuedSteer(inFlight);
|
|
518116
518161
|
else if (inFlight.accepted) this.restoreQueuedSteer(inFlight);
|
|
518117
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
|
+
}
|
|
518118
518176
|
commitChannelPromptAtStepStart(turnId) {
|
|
518119
518177
|
const inFlight = this.channelPromptInFlight;
|
|
518120
518178
|
if (inFlight === void 0 || inFlight.turnId !== String(turnId)) return;
|
|
518121
518179
|
this.channelPromptInFlight = void 0;
|
|
518122
|
-
inFlight.acknowledge
|
|
518180
|
+
this.deferChannelAcknowledgement(inFlight.turnId, inFlight.acknowledge);
|
|
518123
518181
|
}
|
|
518124
518182
|
settleChannelPromptAtTurnEnd(turnId, reason) {
|
|
518125
518183
|
const inFlight = this.channelPromptInFlight;
|