blun-king-cli 9.1.103 → 9.1.104

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/LIESMICH.txt CHANGED
@@ -91,6 +91,8 @@ Ab BLUN King 9.1.98 kann King einen abgeschlossenen Arbeitsabschnitt verdichten,
91
91
 
92
92
  Große textbasierte Werkzeugergebnisse bleiben nicht mehr vollständig im Modellkontext. Ab 12.001 Zeichen speichert BLUN King das vollständige Ergebnis in einer privaten Datei im Sitzungsordner `tool-results`. Im Modellkontext verbleiben die ersten 1.000 und die letzten 1.000 Zeichen, die genaue Zahl der ausgelassenen Zeichen und der `output_path`. Der Agent kann das vollständige Ergebnis anschließend mit `Read` seitenweise über diesen Pfad lesen. Ergebnisse bis einschließlich 12.000 Zeichen, gemischte Medienergebnisse und bereits gekürzte Ergebnisse bleiben unverändert. Auch eine spätere Mikroverdichtung bewahrt den Dateiverweis. Beispiel: Bei einem Suchergebnis mit 30.000 Zeichen sehen folgende Modellanfragen den Anfang und das abschließende Ergebnis oder den Fehler; der vollständige Text bleibt lokal verfügbar.
93
93
 
94
+ Version 9.1.104 lässt Shell-Befehle im Vordergrund auch bei sehr großen Ausgaben bis zum regulären Ende laufen. King schreibt bis zu 16 MiB fortlaufend in das private Aufgabenprotokoll, verwirft darüber hinausgehende Ausgaben und meldet den tatsächlichen Exit-Code, statt den Prozess wegen der Ausgabemenge zu beenden. Kleine Ausgaben, Hintergrundaufgaben, Zeitgrenzen und manuelle Abbrüche bleiben unverändert.
95
+
94
96
  Ab BLUN King 9.1.99 werden auch direkt aufeinanderfolgende reine Textergebnisse als Stapel betrachtet. Enthalten sie zusammen mehr als 12.000 Zeichen, obwohl kein einzelnes Ergebnis diese Grenze überschreitet, speichert King so viele der größten geeigneten Ergebnisse wie nötig in privaten Dateien. In der Modellprojektion verbleiben lesbare Verweise. Der unveränderte Sitzungsrohverlauf bleibt vollständig erhalten. Gemischte Medienergebnisse, einzelne Ergebnisse unter 3.000 Zeichen und Stapel bis einschließlich 12.000 Zeichen bleiben unverändert. Beispiel: Bei zwei Suchergebnissen mit 7.000 und 6.000 Zeichen wird das größere Ergebnis privat gespeichert; Anfang, Ende, ausgelassene Zeichenzahl und `output_path` bleiben für den Agenten sichtbar.
95
97
 
96
98
  Ab BLUN King 9.1.100 beendet eine begrenzte Grep-Inhaltssuche ripgrep, sobald der Versatz, die angeforderten Zeilen und eine zusätzliche Vorschauzeile vollständig vorliegen. Die Vorschauzeile belegt, ob eine weitere Seite existiert, ohne vorher bis zu 10 MB einzulesen. Unbegrenzte Suchen, Trefferzählungen und nach Änderungszeit sortierte Dateilisten laufen weiterhin vollständig durch.
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.100
12
+ npm install -g blun-king-cli@9.1.104
13
13
  ```
14
14
 
15
15
  ## Reproduzierbares Staging und Packen
@@ -111,6 +111,8 @@ Ab BLUN King 9.1.98 kann King einen abgeschlossenen Arbeitsabschnitt verdichten,
111
111
 
112
112
  Große textbasierte Werkzeugergebnisse bleiben nicht mehr vollständig im Modellkontext. Ab 12.001 Zeichen speichert BLUN King das vollständige Ergebnis in einer privaten Datei im Sitzungsordner `tool-results`. Im Modellkontext verbleiben die ersten 1.000 und die letzten 1.000 Zeichen, die genaue Zahl der ausgelassenen Zeichen und der `output_path`. Der Agent kann das vollständige Ergebnis anschließend mit `Read` seitenweise über diesen Pfad lesen. Ergebnisse bis einschließlich 12.000 Zeichen, gemischte Medienergebnisse und bereits gekürzte Ergebnisse bleiben unverändert. Auch eine spätere Mikroverdichtung bewahrt den Dateiverweis. Beispiel: Bei einem Suchergebnis mit 30.000 Zeichen sehen folgende Modellanfragen den Anfang und das abschließende Ergebnis oder den Fehler; der vollständige Text bleibt lokal verfügbar.
113
113
 
114
+ Version 9.1.104 lässt Shell-Befehle im Vordergrund auch bei sehr großen Ausgaben bis zum regulären Ende laufen. King schreibt bis zu 16 MiB fortlaufend in das private Aufgabenprotokoll, verwirft darüber hinausgehende Ausgaben und meldet den tatsächlichen Exit-Code, statt den Prozess wegen der Ausgabemenge zu beenden. Kleine Ausgaben, Hintergrundaufgaben, Zeitgrenzen und manuelle Abbrüche bleiben unverändert.
115
+
114
116
  Ab BLUN King 9.1.99 werden auch direkt aufeinanderfolgende reine Textergebnisse als Stapel betrachtet. Enthalten sie zusammen mehr als 12.000 Zeichen, obwohl kein einzelnes Ergebnis diese Grenze überschreitet, speichert King so viele der größten geeigneten Ergebnisse wie nötig in privaten Dateien. In der Modellprojektion verbleiben lesbare Verweise. Der unveränderte Sitzungsrohverlauf bleibt vollständig erhalten. Gemischte Medienergebnisse, einzelne Ergebnisse unter 3.000 Zeichen und Stapel bis einschließlich 12.000 Zeichen bleiben unverändert. Beispiel: Bei zwei Suchergebnissen mit 7.000 und 6.000 Zeichen wird das größere Ergebnis privat gespeichert; Anfang, Ende, ausgelassene Zeichenzahl und `output_path` bleiben für den Agenten sichtbar.
115
117
 
116
118
  Ab BLUN King 9.1.100 beendet eine begrenzte Grep-Inhaltssuche ripgrep, sobald der Versatz, die angeforderten Zeilen und eine zusätzliche Vorschauzeile vollständig vorliegen. Die Vorschauzeile belegt, ob eine weitere Seite existiert, ohne vorher bis zu 10 MB einzulesen. Unbegrenzte Suchen, Trefferzählungen und nach Änderungszeit sortierte Dateilisten laufen weiterhin vollständig durch.
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ const MAX_FOREGROUND_CAPTURE_BYTES = 16 * 1024 * 1024;
4
+
5
+ function utf8PrefixWithinBytes(text, maxBytes) {
6
+ if (maxBytes <= 0 || text.length === 0) return '';
7
+ if (Buffer.byteLength(text, 'utf8') <= maxBytes) return text;
8
+
9
+ let low = 0;
10
+ let high = text.length;
11
+ while (low < high) {
12
+ const middle = Math.ceil((low + high) / 2);
13
+ if (Buffer.byteLength(text.slice(0, middle), 'utf8') <= maxBytes) low = middle;
14
+ else high = middle - 1;
15
+ }
16
+ if (low > 0 && low < text.length) {
17
+ const last = text.charCodeAt(low - 1);
18
+ if (last >= 0xD800 && last <= 0xDBFF) low -= 1;
19
+ }
20
+ return text.slice(0, low);
21
+ }
22
+
23
+ function captureForegroundOutputChunk(text, capturedBytes, maxBytes = MAX_FOREGROUND_CAPTURE_BYTES) {
24
+ const observedBytes = Buffer.byteLength(text, 'utf8');
25
+ const remainingBytes = Math.max(0, maxBytes - Math.max(0, capturedBytes));
26
+ const capturedText = utf8PrefixWithinBytes(text, remainingBytes);
27
+ const newCapturedBytes = Buffer.byteLength(capturedText, 'utf8');
28
+ return {
29
+ capturedText,
30
+ observedBytes,
31
+ capturedBytes: newCapturedBytes,
32
+ droppedBytes: observedBytes - newCapturedBytes,
33
+ capped: newCapturedBytes < observedBytes,
34
+ };
35
+ }
36
+
37
+ module.exports = {
38
+ MAX_FOREGROUND_CAPTURE_BYTES,
39
+ captureForegroundOutputChunk,
40
+ utf8PrefixWithinBytes,
41
+ };
package/blun.mjs CHANGED
@@ -29316,9 +29316,6 @@ function isBackgroundTaskTerminal(status) {
29316
29316
  return TERMINAL_STATUSES.has(status);
29317
29317
  }
29318
29318
  /** Terminal `stopReason` recorded when a foreground command trips the output ceiling. */
29319
- function foregroundOutputLimitReason() {
29320
- return `Output limit exceeded: the command produced more than ${Math.floor(MAX_FOREGROUND_OUTPUT_BYTES / (1024 * 1024))} MiB and was terminated. Redirect large output to a file (e.g. \`command > out.txt\`) and inspect it in slices instead.`;
29321
- }
29322
29319
  /**
29323
29320
  * Generate `{prefix}-{8 base36 chars}`.
29324
29321
  *
@@ -29378,7 +29375,7 @@ function buildBackgroundTaskNotificationBody(info) {
29378
29375
  "The subagent retains its full prior context across the restart, but any in-flight tool call lost its result and may need to be redone."
29379
29376
  ].join("\n")}`;
29380
29377
  }
29381
- var MAX_OUTPUT_BYTES$2, NOTIFICATION_FALLBACK_PREVIEW_BYTES, MAX_FOREGROUND_OUTPUT_BYTES, SIGTERM_GRACE_MS$1, USER_INTERRUPT_REASON$1, _ALPHABET, BackgroundManager;
29378
+ var MAX_OUTPUT_BYTES$2, NOTIFICATION_FALLBACK_PREVIEW_BYTES, MAX_FOREGROUND_CAPTURE_BYTES, captureForegroundOutputChunk, SIGTERM_GRACE_MS$1, USER_INTERRUPT_REASON$1, _ALPHABET, BackgroundManager;
29382
29379
  var init_background = __esmMin((() => {
29383
29380
  init_dist$4();
29384
29381
  init_errors$4();
@@ -29392,7 +29389,7 @@ var init_background = __esmMin((() => {
29392
29389
  init_question_task();
29393
29390
  MAX_OUTPUT_BYTES$2 = 1024 * 1024;
29394
29391
  NOTIFICATION_FALLBACK_PREVIEW_BYTES = 3e3;
29395
- MAX_FOREGROUND_OUTPUT_BYTES = 16 * 1024 * 1024;
29392
+ ({ MAX_FOREGROUND_CAPTURE_BYTES, captureForegroundOutputChunk } = createRequire(import.meta.url)("./bin/foreground-output-capture-policy.cjs"));
29396
29393
  SIGTERM_GRACE_MS$1 = 5e3;
29397
29394
  USER_INTERRUPT_REASON$1 = "Interrupted by user";
29398
29395
  _ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
@@ -29470,7 +29467,8 @@ var init_background = __esmMin((() => {
29470
29467
  outputChunks: [],
29471
29468
  outputRingChars: 0,
29472
29469
  outputSizeBytes: 0,
29473
- outputLimitTripped: false,
29470
+ outputCapturedBytes: 0,
29471
+ outputCaptureCapped: false,
29474
29472
  status: "running",
29475
29473
  options: entryOptions,
29476
29474
  startedAt: Date.now(),
@@ -29708,27 +29706,32 @@ var init_background = __esmMin((() => {
29708
29706
  return entry.persistWriteQueue;
29709
29707
  }
29710
29708
  appendOutput(entry, chunk) {
29711
- entry.outputSizeBytes += Buffer.byteLength(chunk, "utf-8");
29712
- entry.outputChunks.push(chunk);
29713
- entry.outputRingChars += chunk.length;
29709
+ const capture = this.isDetached(entry) ? {
29710
+ capturedText: chunk,
29711
+ observedBytes: Buffer.byteLength(chunk, "utf-8"),
29712
+ capturedBytes: Buffer.byteLength(chunk, "utf-8"),
29713
+ droppedBytes: 0,
29714
+ capped: false
29715
+ } : captureForegroundOutputChunk(chunk, entry.outputCapturedBytes);
29716
+ entry.outputSizeBytes += capture.observedBytes;
29717
+ entry.outputCapturedBytes += capture.capturedBytes;
29718
+ if (capture.capped) entry.outputCaptureCapped = true;
29719
+ if (capture.capturedText.length === 0) return;
29720
+ entry.outputChunks.push(capture.capturedText);
29721
+ entry.outputRingChars += capture.capturedText.length;
29714
29722
  while (entry.outputRingChars > MAX_OUTPUT_BYTES$2 && entry.outputChunks.length > 1) {
29715
29723
  const removed = entry.outputChunks.shift();
29716
29724
  if (removed === void 0) break;
29717
29725
  entry.outputRingChars -= removed.length;
29718
29726
  }
29719
- if (!entry.outputLimitTripped && !this.isDetached(entry) && entry.outputSizeBytes > MAX_FOREGROUND_OUTPUT_BYTES) {
29720
- entry.outputLimitTripped = true;
29721
- this.stop(entry.taskId, foregroundOutputLimitReason());
29722
- }
29723
- if (entry.outputLimitTripped) return;
29724
29727
  if (this.persistence === void 0) return;
29725
29728
  if (!entry.outputPersistStarted) {
29726
- entry.pendingOutput.push(chunk);
29727
- entry.pendingOutputBytes += Buffer.byteLength(chunk, "utf-8");
29729
+ entry.pendingOutput.push(capture.capturedText);
29730
+ entry.pendingOutputBytes += capture.capturedBytes;
29728
29731
  if (entry.pendingOutputBytes > MAX_OUTPUT_BYTES$2) this.startOutputPersist(entry);
29729
29732
  return;
29730
29733
  }
29731
- this.appendTaskOutput(entry, chunk);
29734
+ this.appendTaskOutput(entry, capture.capturedText);
29732
29735
  }
29733
29736
  /** Enqueue an `output.log` append, serialized per task. No-op when detached managers omit persistence. */
29734
29737
  appendTaskOutput(entry, chunk) {
@@ -29925,6 +29928,7 @@ var init_background = __esmMin((() => {
29925
29928
  endedAt: entry.endedAt,
29926
29929
  stopReason: entry.stopReason,
29927
29930
  terminalNotificationSuppressed: entry.terminalNotificationSuppressed,
29931
+ outputCaptureCapped: entry.outputCaptureCapped,
29928
29932
  timeoutMs: entry.options.timeoutMs
29929
29933
  };
29930
29934
  return entry.task.toInfo(base);
@@ -262142,7 +262146,7 @@ var init_bash = __esmMin((() => {
262142
262146
  MAX_TIMEOUT_S,
262143
262147
  MAX_BACKGROUND_TIMEOUT_S
262144
262148
  };
262145
- bash_default = "Execute a `{{ SHELL_NAME }}` command for pipes, environment variables, processes, git, package managers, build or test runners, and other genuine shell semantics.\n\nPrefer the dedicated tools when they fit: `Read` for a known file, `Write` to create or replace a file, `Edit` for exact changes, `Glob` to locate files, and `Grep` to search contents. Their output is bounded and their permissions are clearer.\n\nStdout and stderr are combined. Long output may be truncated. A non-zero command ends with its exit code; timeouts and user interrupts are reported separately.\n\nEach call runs in a fresh shell environment. Variables, `cd`, and shell history do not carry into later calls; pass `cwd` or use absolute paths. Foreground commands default to {{ DEFAULT_TIMEOUT_S }}s and allow up to {{ MAX_TIMEOUT_S }}s through `timeout`. Do not run interactive commands or commands that may run forever in the foreground.\n\nWith `run_in_background=true`, provide a short `description`; the tool returns a task ID and notifies you on completion. Background tasks default to {{ DEFAULT_BACKGROUND_TIMEOUT_S }}s and allow up to {{ MAX_BACKGROUND_TIMEOUT_S }}s. Use `disable_timeout=true` only when no deadline is appropriate. Use `TaskOutput` for a status or output snapshot and `TaskStop` only to cancel. After launch, normally return control instead of immediately waiting.\n\nQuote paths containing spaces. Chain dependent commands with `&&`; issue independent read-only checks as parallel tool calls. Use `;`, `||`, pipes, redirects, and shell control flow when their semantics are required.\n\nStay inside the working directory unless the user explicitly requests otherwise. Avoid `..`, and never require superuser privileges without explicit instruction. Command availability depends on the host; verify unfamiliar commands before relying on them.";
262149
+ bash_default = "Execute a `{{ SHELL_NAME }}` command for pipes, environment variables, processes, git, package managers, build or test runners, and other genuine shell semantics.\n\nPrefer the dedicated tools when they fit: `Read` for a known file, `Write` to create or replace a file, `Edit` for exact changes, `Glob` to locate files, and `Grep` to search contents. Their output is bounded and their permissions are clearer.\n\nStdout and stderr are combined. Long foreground output is streamed to a private file; capture stops at a safe size while the command continues to its real exit code. A non-zero command ends with its exit code; timeouts and user interrupts are reported separately.\n\nEach call runs in a fresh shell environment. Variables, `cd`, and shell history do not carry into later calls; pass `cwd` or use absolute paths. Foreground commands default to {{ DEFAULT_TIMEOUT_S }}s and allow up to {{ MAX_TIMEOUT_S }}s through `timeout`. Do not run interactive commands or commands that may run forever in the foreground.\n\nWith `run_in_background=true`, provide a short `description`; the tool returns a task ID and notifies you on completion. Background tasks default to {{ DEFAULT_BACKGROUND_TIMEOUT_S }}s and allow up to {{ MAX_BACKGROUND_TIMEOUT_S }}s. Use `disable_timeout=true` only when no deadline is appropriate. Use `TaskOutput` for a status or output snapshot and `TaskStop` only to cancel. After launch, normally return control instead of immediately waiting.\n\nQuote paths containing spaces. Chain dependent commands with `&&`; issue independent read-only checks as parallel tool calls. Use `;`, `||`, pipes, redirects, and shell control flow when their semantics are required.\n\nStay inside the working directory unless the user explicitly requests otherwise. Avoid `..`, and never require superuser privileges without explicit instruction. Command availability depends on the host; verify unfamiliar commands before relying on them.";
262146
262150
  BashTool = class {
262147
262151
  kaos;
262148
262152
  cwd;
@@ -262308,8 +262312,10 @@ var init_bash = __esmMin((() => {
262308
262312
  if (!result.truncated) return result;
262309
262313
  const output = await this.backgroundManager.getOutputSnapshot(taskId, 0);
262310
262314
  if (!output.fullOutputAvailable || output.outputPath === void 0) return result;
262315
+ const captureCapped = this.backgroundManager.getTask(taskId)?.outputCaptureCapped === true;
262311
262316
  const taskOutputHint = this.allowBackground ? `, or TaskOutput(task_id="${taskId}", block=false)` : "";
262312
- const reference = `\n\n[Full output saved]\ntask_id: ${taskId}\noutput_path: ${output.outputPath}\noutput_size_bytes: ${String(output.outputSizeBytes)}\nnext_step: Use Read with output_path to page through the full log${taskOutputHint}.`;
262317
+ const captureNotice = captureCapped ? `\n[Capture capped at ${String(MAX_FOREGROUND_CAPTURE_BYTES)} bytes. Additional output was discarded, but the command continued to its real exit code.]` : "";
262318
+ const reference = `\n\n[Full output saved]\ntask_id: ${taskId}\noutput_path: ${output.outputPath}\noutput_size_bytes: ${String(output.outputSizeBytes)}${captureNotice}\nnext_step: Use Read with output_path to page through the full log${taskOutputHint}.`;
262313
262319
  return {
262314
262320
  ...result,
262315
262321
  output: `${result.output}${reference}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.103",
3
+ "version": "9.1.104",
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": {