blun-king-cli 9.1.39 → 9.1.41

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 +90 -79
  2. package/package.json +1 -1
package/blun.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // BLUN_BUILD_INPUT_SHA256:100000256c8742e28ac1b44fd85c258bacd68037bbbe180b9d79717e466d1d89
2
+ // BLUN_BUILD_INPUT_SHA256:6009b58ca14a14c742deab1a33fcd60086908033898c436965fbdad7c20c9073
3
3
  import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
4
4
  import { dirname as __cjsShimDirname } from 'node:path';
5
5
  const __filename = __cjsShimFileURLToPath(import.meta.url);
@@ -1765,6 +1765,18 @@ function createFetchHttpClient(options) {
1765
1765
  files: { create: (params, requestOptions) => transport.uploadFile(params, requestOptions) }
1766
1766
  };
1767
1767
  }
1768
+ function exactBodyBytes(body) {
1769
+ if (typeof body === "string") return Buffer.byteLength(body, "utf8");
1770
+ if (body instanceof URLSearchParams) return Buffer.byteLength(body.toString(), "utf8");
1771
+ if (body instanceof Blob) return body.size;
1772
+ if (body instanceof ArrayBuffer) return body.byteLength;
1773
+ if (ArrayBuffer.isView(body)) return body.byteLength;
1774
+ }
1775
+ function notifyTransportAttempt(callback, stats) {
1776
+ try {
1777
+ callback?.(stats);
1778
+ } catch {}
1779
+ }
1768
1780
  function normalizeMaxRetries(value) {
1769
1781
  if (value === void 0) return DEFAULT_MAX_RETRIES$1;
1770
1782
  if (!Number.isSafeInteger(value) || value < 0) throw new ChatProviderError("transportMaxRetries must be a non-negative integer.");
@@ -1950,7 +1962,7 @@ var init_fetch_http_client = __esmMin((() => {
1950
1962
  headers,
1951
1963
  body: JSON.stringify(params),
1952
1964
  signal: options?.signal
1953
- }, options?.maxRetries);
1965
+ }, options);
1954
1966
  if (isStream) return parseServerSentJson(response);
1955
1967
  return readJson$1(response);
1956
1968
  }
@@ -1965,7 +1977,7 @@ var init_fetch_http_client = __esmMin((() => {
1965
1977
  headers,
1966
1978
  body: form,
1967
1979
  signal: options?.signal
1968
- }, options?.maxRetries));
1980
+ }, options));
1969
1981
  if (typeof uploaded.id !== "string" || uploaded.id.length === 0) throw new ChatProviderError("File upload response did not include a file id.");
1970
1982
  return { id: uploaded.id };
1971
1983
  }
@@ -1974,28 +1986,49 @@ var init_fetch_http_client = __esmMin((() => {
1974
1986
  if (!headers.has("authorization")) headers.set("authorization", `Bearer ${this.apiKey}`);
1975
1987
  return headers;
1976
1988
  }
1977
- async fetchWithRetries(pathname, init, configuredMaxRetries) {
1978
- const maxRetries = normalizeMaxRetries(configuredMaxRetries);
1989
+ async fetchWithRetries(pathname, init, requestOptions) {
1990
+ const maxRetries = normalizeMaxRetries(requestOptions?.maxRetries);
1991
+ const requestBytes = exactBodyBytes(init.body);
1979
1992
  let attempt = 0;
1980
- while (true) try {
1981
- const response = await this.fetch(`${this.baseUrl}${pathname}`, init);
1982
- if (response.ok) return response;
1983
- if (attempt < maxRetries && shouldRetryResponse(response)) {
1984
- const delayMs = retryDelayMs(response.headers, attempt);
1985
- await response.body?.cancel();
1986
- await waitForRetry(delayMs, init.signal);
1987
- attempt += 1;
1988
- continue;
1989
- }
1990
- throw await responseError(response);
1991
- } catch (error) {
1992
- if (error instanceof ChatProviderError) throw error;
1993
- if (attempt < maxRetries && init.signal?.aborted !== true && isRetryableTransportFailure(error)) {
1994
- await waitForRetry(retryDelayMs(void 0, attempt), init.signal);
1995
- attempt += 1;
1996
- continue;
1993
+ while (true) {
1994
+ const startedAt = performance.now();
1995
+ try {
1996
+ const response = await this.fetch(`${this.baseUrl}${pathname}`, init);
1997
+ const willRetry = attempt < maxRetries && shouldRetryResponse(response);
1998
+ notifyTransportAttempt(requestOptions?.onTransportAttempt, {
1999
+ transportAttempt: attempt + 1,
2000
+ ...requestBytes === void 0 ? {} : { requestBytes },
2001
+ elapsedMs: performance.now() - startedAt,
2002
+ statusCode: response.status,
2003
+ outcome: "response",
2004
+ willRetry
2005
+ });
2006
+ if (response.ok) return response;
2007
+ if (willRetry) {
2008
+ const delayMs = retryDelayMs(response.headers, attempt);
2009
+ await response.body?.cancel();
2010
+ await waitForRetry(delayMs, init.signal);
2011
+ attempt += 1;
2012
+ continue;
2013
+ }
2014
+ throw await responseError(response);
2015
+ } catch (error) {
2016
+ if (error instanceof ChatProviderError) throw error;
2017
+ const willRetry = attempt < maxRetries && init.signal?.aborted !== true && isRetryableTransportFailure(error);
2018
+ notifyTransportAttempt(requestOptions?.onTransportAttempt, {
2019
+ transportAttempt: attempt + 1,
2020
+ ...requestBytes === void 0 ? {} : { requestBytes },
2021
+ elapsedMs: performance.now() - startedAt,
2022
+ outcome: "transport_error",
2023
+ willRetry
2024
+ });
2025
+ if (willRetry) {
2026
+ await waitForRetry(retryDelayMs(void 0, attempt), init.signal);
2027
+ attempt += 1;
2028
+ continue;
2029
+ }
2030
+ throw normalizeFetchHttpError(error);
1997
2031
  }
1998
- throw normalizeFetchHttpError(error);
1999
2032
  }
2000
2033
  }
2001
2034
  };
@@ -2800,9 +2833,10 @@ var init_blun = __esmMin((() => {
2800
2833
  if (this._stream) createParams["stream_options"] = { include_usage: true };
2801
2834
  try {
2802
2835
  const client = this._createClient(options?.auth);
2803
- const requestOptions = options?.signal !== void 0 || options?.transportMaxRetries !== void 0 ? {
2836
+ const requestOptions = options?.signal !== void 0 || options?.transportMaxRetries !== void 0 || options?.onTransportAttempt !== void 0 ? {
2804
2837
  ...options.signal !== void 0 ? { signal: options.signal } : {},
2805
- ...options.transportMaxRetries !== void 0 ? { maxRetries: options.transportMaxRetries } : {}
2838
+ ...options.transportMaxRetries !== void 0 ? { maxRetries: options.transportMaxRetries } : {},
2839
+ ...options.onTransportAttempt !== void 0 ? { onTransportAttempt: options.onTransportAttempt } : {}
2806
2840
  } : void 0;
2807
2841
  options?.onRequestSent?.();
2808
2842
  return new BlunStreamedMessage(await client.chat.completions.create(createParams, requestOptions), this._stream, reasoningRequested);
@@ -258794,7 +258828,7 @@ var init_read_media = __esmMin((() => {
258794
258828
  //#region ../../packages/agent-core/src/tools/builtin/file/write.md?raw
258795
258829
  var write_default;
258796
258830
  var init_write$1 = __esmMin((() => {
258797
- write_default = "Create, append to, or replace a file entirely.\n\n- Missing parent directories are created automatically (like `mkdir(parents=True, exist_ok=True)`).\n- Mode defaults to overwrite; append adds content at EOF without adding a newline.\n- Write is NOT ALLOWED for incremental changes to existing files, including trivial, one-line, quick, or cosmetic edits. Use Edit instead.\n- Use Write only when the file does not exist, you intend a complete replacement, or the new contents have little continuity with the old contents.\n- Do not create unsolicited documentation files (`*.md` write-ups, `README`s, summaries) just because a task finished — write one only when the user asks for it, or when a task or project instruction requires it (e.g. the plan-mode plan file, created with Write when plan mode directs you to, or a changeset the repo mandates).\n- Read before overwriting an existing file.\n- Write ignores the Read/Edit line-number view. NEVER include line prefixes.\n- Write outputs content literally, including supplied line endings: \\n stays LF, \\r\\n stays CRLF.\n- Source files may contain at most 500 lines. Split larger implementations into focused files; append cannot bypass the limit.\n- Set `single_file_override=true` only when the latest direct user message explicitly requires one single file. The accepted override is reported visibly.\n- For any new or completely replaced file with content too large for one call, use `continuation`. Keep each chunk at or below the configured limit. The default is 2,048 UTF-8 bytes, a conservative safety margin for unstable model output rather than a measured hard model limit; operators can set `BLUN_WRITE_CONTINUATION_MAX_BYTES` from 512 through 16,384. End every chunk on a complete line with `\\n`. Set the exact final `expected_lines`; include `expected_sha256` when a source hash is available. Use overwrite and `start_line=1` for the first chunk, then use append for every later chunk and copy the exact `next_start_line` returned by the previous Write result; never continue from a planned boundary. Use consecutive part numbers. The target file remains unchanged until the final line-count and optional SHA-256 checks pass. To discard an unfinished sequence, restart with part 1, overwrite, `start_line=1`, and `reset=true`.\n- Never use continuation to modify an existing file incrementally. Use Edit for incremental changes.\n- Runaway generated JavaScript/TypeScript identifiers are rejected before disk I/O. Regenerate only the affected section as a smaller focused chunk.\n";
258831
+ write_default = "Create, append to, or replace a file entirely.\n\n- Missing parent directories are created automatically (like `mkdir(parents=True, exist_ok=True)`).\n- Mode defaults to overwrite; append adds content at EOF without adding a newline.\n- Write is NOT ALLOWED for incremental changes to existing files, including trivial, one-line, quick, or cosmetic edits. Use Edit instead.\n- Use Write only when the file does not exist, you intend a complete replacement, or the new contents have little continuity with the old contents.\n- Do not create unsolicited documentation files (`*.md` write-ups, `README`s, summaries) just because a task finished — write one only when the user asks for it, or when a task or project instruction requires it (e.g. the plan-mode plan file, created with Write when plan mode directs you to, or a changeset the repo mandates).\n- Read before overwriting an existing file.\n- Write ignores the Read/Edit line-number view. NEVER include line prefixes.\n- Write outputs content literally, including supplied line endings: \\n stays LF, \\r\\n stays CRLF.\n- Source files may contain at most 500 lines. Split larger implementations into focused files; append cannot bypass the limit.\n- Set `single_file_override=true` only when the latest direct user message explicitly requires one single file. The accepted override is reported visibly.\n- For any new or completely replaced file with content too large for one call, use `continuation`. Keep every chunk at or below 2,048 UTF-8 bytes and end every chunk on a complete line with `\\n`. Set the exact final `expected_lines`; include `expected_sha256` when a source hash is available. Use overwrite for the first chunk, then append for every later chunk, with consecutive part numbers. The target file remains unchanged until the final line-count and optional SHA-256 checks pass.\n- Never use continuation to modify an existing file incrementally. Use Edit for incremental changes.\n- Runaway generated JavaScript/TypeScript identifiers are rejected before disk I/O. Regenerate only the affected section as a smaller focused chunk.\n";
258798
258832
  }));
258799
258833
  //#endregion
258800
258834
  //#region ../../packages/agent-core/src/tools/builtin/file/generated-source-health.ts
@@ -258907,19 +258941,12 @@ var init_generated_source_health = __esmMin((() => {
258907
258941
  }));
258908
258942
  //#endregion
258909
258943
  //#region ../../packages/agent-core/src/tools/builtin/file/write.ts
258910
- function resolveWriteContinuationChunkBytes(env = process.env) {
258911
- const raw = env[CONTINUATION_CHUNK_BYTES_ENV]?.trim();
258912
- if (raw === void 0 || raw === "") return DEFAULT_CONTINUATION_CHUNK_BYTES;
258913
- const parsed = Number(raw);
258914
- if (!Number.isSafeInteger(parsed) || parsed < MIN_CONTINUATION_CHUNK_BYTES || parsed > MAX_CONTINUATION_CHUNK_BYTES) throw new Error(`${CONTINUATION_CHUNK_BYTES_ENV} must be an integer between ${String(MIN_CONTINUATION_CHUNK_BYTES)} and ${String(MAX_CONTINUATION_CHUNK_BYTES)} bytes; received ${JSON.stringify(raw)}.`);
258915
- return parsed;
258916
- }
258917
258944
  function countCompletedLines(content) {
258918
258945
  let count = 0;
258919
258946
  for (const character of content) if (character === "\n") count += 1;
258920
258947
  return count;
258921
258948
  }
258922
- var S_IFMT, S_IFDIR, DEFAULT_CONTINUATION_CHUNK_BYTES, MIN_CONTINUATION_CHUNK_BYTES, MAX_CONTINUATION_CHUNK_BYTES, CONTINUATION_CHUNK_BYTES_ENV, WriteContinuationSchema, WriteInputSchema, WriteTool;
258949
+ var S_IFMT, S_IFDIR, MAX_CONTINUATION_CHUNK_BYTES, WriteContinuationSchema, WriteInputSchema, WriteTool;
258923
258950
  var init_write = __esmMin((() => {
258924
258951
  init_dist$6();
258925
258952
  init_zod$1();
@@ -258933,24 +258960,19 @@ var init_write = __esmMin((() => {
258933
258960
  init_lsp_diagnostics();
258934
258961
  S_IFMT = 61440;
258935
258962
  S_IFDIR = 16384;
258936
- DEFAULT_CONTINUATION_CHUNK_BYTES = 2048;
258937
- MIN_CONTINUATION_CHUNK_BYTES = 512;
258938
- MAX_CONTINUATION_CHUNK_BYTES = 16384;
258939
- CONTINUATION_CHUNK_BYTES_ENV = "BLUN_WRITE_CONTINUATION_MAX_BYTES";
258963
+ MAX_CONTINUATION_CHUNK_BYTES = 2048;
258940
258964
  WriteContinuationSchema = object({
258941
258965
  part: number$1().int().positive().describe("One-based chunk number. Start with 1 and increment by exactly one."),
258942
- start_line: number$1().int().positive().describe("One-based line where this chunk starts. Use 1 for part 1; for every later part, copy next_start_line from the preceding tool result instead of using a planned boundary."),
258943
258966
  expected_lines: number$1().int().positive().describe("Exact completed-line count expected in the final file."),
258944
258967
  final: boolean$1().describe("Set true only for the last chunk, when the complete file is present."),
258945
- expected_sha256: string().regex(/^[0-9a-f]{64}$/i).optional().describe("Optional SHA-256 of the complete expected file for byte-for-byte verification."),
258946
- reset: boolean$1().optional().describe("Set true only with part 1 and overwrite to discard an unfinished staged write.")
258968
+ expected_sha256: string().regex(/^[0-9a-f]{64}$/i).optional().describe("Optional SHA-256 of the complete expected file for byte-for-byte verification.")
258947
258969
  });
258948
258970
  WriteInputSchema = object({
258949
258971
  path: string().describe("Path to the file to create, append to, or completely overwrite. Relative paths resolve against the working directory; a path outside the working directory must be absolute. Missing parent directories are created automatically."),
258950
258972
  content: string().describe("Raw full file content to write exactly as provided. This does not use the Read/Edit text view."),
258951
258973
  mode: _enum(["overwrite", "append"]).optional().describe("Write mode. Defaults to overwrite. append adds content to the end exactly as provided and does not add a newline."),
258952
258974
  single_file_override: boolean$1().optional().describe("Set true only when the latest direct user message explicitly requires one single source file. The tool verifies that request and reports the override visibly."),
258953
- continuation: WriteContinuationSchema.optional().describe("Safe long-write protocol. Split generated files into complete-line chunks within the configured limit (2,048 UTF-8 bytes by default; operator override BLUN_WRITE_CONTINUATION_MAX_BYTES). Part 1 uses overwrite and start_line=1; later parts use append and the exact next_start_line returned by the previous call. The target file is changed only after the final line-count and optional SHA-256 checks pass.")
258975
+ continuation: WriteContinuationSchema.optional().describe("Safe long-write protocol. Split generated files into complete-line chunks of at most 2,048 UTF-8 bytes. Part 1 uses overwrite; later parts use append. The target file is changed only after the final line-count and optional SHA-256 checks pass.")
258954
258976
  });
258955
258977
  object({
258956
258978
  /** Number of UTF-8 bytes written to disk by this call. */
@@ -258960,17 +258982,15 @@ bytesWritten: number$1().int().nonnegative() });
258960
258982
  workspace;
258961
258983
  history;
258962
258984
  lsp;
258963
- maxContinuationChunkBytes;
258964
258985
  name = "Write";
258965
258986
  description = write_default;
258966
258987
  parameters = toInputJsonSchema(WriteInputSchema);
258967
258988
  pendingContinuations = /* @__PURE__ */ new Map();
258968
- constructor(kaos, workspace, history, lsp, maxContinuationChunkBytes = resolveWriteContinuationChunkBytes()) {
258989
+ constructor(kaos, workspace, history, lsp) {
258969
258990
  this.kaos = kaos;
258970
258991
  this.workspace = workspace;
258971
258992
  this.history = history;
258972
258993
  this.lsp = lsp;
258973
- this.maxContinuationChunkBytes = maxContinuationChunkBytes;
258974
258994
  }
258975
258995
  resolveExecution(args) {
258976
258996
  const path = resolvePathAccessPath(args.path, {
@@ -259009,30 +259029,20 @@ bytesWritten: number$1().int().nonnegative() });
259009
259029
  if (continuation === void 0) throw new Error("continuation is required");
259010
259030
  const mode = args.mode ?? "overwrite";
259011
259031
  const chunkBytes = Buffer.byteLength(args.content, "utf8");
259012
- if (chunkBytes > this.maxContinuationChunkBytes) return {
259032
+ if (chunkBytes > MAX_CONTINUATION_CHUNK_BYTES) return {
259013
259033
  isError: true,
259014
- output: `Refused continuation part ${String(continuation.part)} for ${args.path}: chunks may contain at most ${this.maxContinuationChunkBytes.toLocaleString("en-US")} UTF-8 bytes (${String(chunkBytes)} received). No content was staged and no file was written.`
259034
+ output: `Refused continuation part ${String(continuation.part)} for ${args.path}: chunks may contain at most ${MAX_CONTINUATION_CHUNK_BYTES.toLocaleString("en-US")} UTF-8 bytes (${String(chunkBytes)} received). No content was staged and no file was written.`
259015
259035
  };
259016
259036
  if (args.content.length === 0 || !args.content.endsWith("\n")) return {
259017
259037
  isError: true,
259018
259038
  output: `Refused continuation part ${String(continuation.part)} for ${args.path}: every chunk must end on a complete line with a newline. No content was staged and no file was written.`
259019
259039
  };
259020
- if (continuation.reset === true && (continuation.part !== 1 || mode !== "overwrite")) return {
259021
- isError: true,
259022
- output: `Refused continuation reset for ${args.path}: reset requires part 1 with mode=overwrite. No content was staged and no file was written.`
259023
- };
259024
- if (continuation.reset === true) this.pendingContinuations.delete(safePath);
259025
259040
  const current = this.pendingContinuations.get(safePath);
259026
259041
  const expectedPart = current === void 0 ? 1 : current.chunks.length + 1;
259027
259042
  if (continuation.part !== expectedPart) return {
259028
259043
  isError: true,
259029
259044
  output: `Refused continuation part ${String(continuation.part)} for ${args.path}: expected part ${String(expectedPart)}. No content was staged and no file was written.`
259030
259045
  };
259031
- const expectedStartLine = (current?.completedLines ?? 0) + 1;
259032
- if (continuation.start_line !== expectedStartLine) return {
259033
- isError: true,
259034
- output: `Refused continuation part ${String(continuation.part)} for ${args.path}: expected start_line ${String(expectedStartLine)} from the actually staged content, received ${String(continuation.start_line)}. No content was staged and no file was written.`
259035
- };
259036
259046
  if (continuation.part === 1 && mode !== "overwrite" || continuation.part > 1 && mode !== "append") return {
259037
259047
  isError: true,
259038
259048
  output: `Refused continuation part ${String(continuation.part)} for ${args.path}: part 1 must use overwrite and later parts must use append. No content was staged and no file was written.`
@@ -259083,7 +259093,7 @@ bytesWritten: number$1().int().nonnegative() });
259083
259093
  });
259084
259094
  if (!continuation.final) {
259085
259095
  this.pendingContinuations.set(safePath, staged);
259086
- return { output: `Write continuation part ${String(continuation.part)} staged lines ${boundary} of ${String(continuation.expected_lines)} (${String(percent)}%, ${String(chunkBytes)} bytes). Target unchanged. Continue with mode=append, part=${String(continuation.part + 1)}, next_start_line=${String(completedLines + 1)}.` };
259096
+ return { output: `Write continuation part ${String(continuation.part)} staged lines ${boundary} of ${String(continuation.expected_lines)} (${String(percent)}%, ${String(chunkBytes)} bytes). Target unchanged. Continue with mode=append, part=${String(continuation.part + 1)}.` };
259087
259097
  }
259088
259098
  const content = chunks.join("");
259089
259099
  const actualSha256 = createHash("sha256").update(content).digest("hex");
@@ -259132,9 +259142,9 @@ bytesWritten: number$1().int().nonnegative() });
259132
259142
  output: lineLimit.error
259133
259143
  };
259134
259144
  const contentBytes = Buffer.byteLength(args.content, "utf8");
259135
- if (!allowLargeContent && contentBytes > this.maxContinuationChunkBytes) return {
259145
+ if (!allowLargeContent && contentBytes > MAX_CONTINUATION_CHUNK_BYTES) return {
259136
259146
  isError: true,
259137
- output: `Refused to write ${args.path}: the content is ${String(contentBytes)} UTF-8 bytes. Long generated writes must use the continuation protocol with complete-line chunks of at most ${this.maxContinuationChunkBytes.toLocaleString("en-US")} bytes. No file was written.`
259147
+ output: `Refused to write ${args.path}: the content is ${String(contentBytes)} UTF-8 bytes. Long generated writes must use the continuation protocol with complete-line chunks of at most ${MAX_CONTINUATION_CHUNK_BYTES.toLocaleString("en-US")} bytes. No file was written.`
259138
259148
  };
259139
259149
  const parentError = await this.ensureParentDirectory(safePath);
259140
259150
  if (parentError !== void 0) return {
@@ -262960,6 +262970,12 @@ var init_llm_request_logger = __esmMin((() => {
262960
262970
  if (partialMessageCount > 0) requestFields.partialMessageCount = partialMessageCount;
262961
262971
  this.log.info("llm request", requestFields);
262962
262972
  }
262973
+ logTransportAttempt(stats, fields) {
262974
+ this.log.info("llm transport attempt", {
262975
+ ...fields,
262976
+ ...stats
262977
+ });
262978
+ }
262963
262979
  };
262964
262980
  }));
262965
262981
  //#endregion
@@ -263129,9 +263145,14 @@ var init_agent = __esmMin((() => {
263129
263145
  generateForModel(modelAlias) {
263130
263146
  return async (provider, systemPrompt, tools, history, callbacks, options) => {
263131
263147
  const { requestLogFields, generateOptions } = splitGenerateOptions(options);
263148
+ const callerTransportAttempt = generateOptions?.onTransportAttempt;
263132
263149
  const ownedGenerateOptions = {
263133
263150
  ...generateOptions,
263134
- transportMaxRetries: 0
263151
+ transportMaxRetries: 0,
263152
+ onTransportAttempt: (stats) => {
263153
+ callerTransportAttempt?.(stats);
263154
+ this.llmRequestLogger.logTransportAttempt(stats, requestLogFields);
263155
+ }
263135
263156
  };
263136
263157
  const run = (requestOptions) => {
263137
263158
  this.llmRequestLogger.logRequest({
@@ -370228,7 +370249,7 @@ var require_constants$2 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370228
370249
  };
370229
370250
  }));
370230
370251
  //#endregion
370231
- //#region ../../../node_modules/node-gyp-build/node-gyp-build.js
370252
+ //#region ../../../../node_modules/node-gyp-build/node-gyp-build.js
370232
370253
  var require_node_gyp_build$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370233
370254
  var fs$3 = __require("fs");
370234
370255
  var path$5 = __require("path");
@@ -370384,14 +370405,14 @@ var require_node_gyp_build$1 = /* @__PURE__ */ __commonJSMin(((exports, module)
370384
370405
  load.compareTuples = compareTuples;
370385
370406
  }));
370386
370407
  //#endregion
370387
- //#region ../../../node_modules/node-gyp-build/index.js
370408
+ //#region ../../../../node_modules/node-gyp-build/index.js
370388
370409
  var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370389
370410
  const runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
370390
370411
  if (typeof runtimeRequire.addon === "function") module.exports = runtimeRequire.addon.bind(runtimeRequire);
370391
370412
  else module.exports = require_node_gyp_build$1();
370392
370413
  }));
370393
370414
  //#endregion
370394
- //#region ../../../node_modules/bufferutil/fallback.js
370415
+ //#region ../../../../node_modules/bufferutil/fallback.js
370395
370416
  var require_fallback$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370396
370417
  /**
370397
370418
  * Masks a buffer using the given mask.
@@ -370423,7 +370444,7 @@ var require_fallback$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370423
370444
  };
370424
370445
  }));
370425
370446
  //#endregion
370426
- //#region ../../../node_modules/bufferutil/index.js
370447
+ //#region ../../../../node_modules/bufferutil/index.js
370427
370448
  var require_bufferutil = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370428
370449
  try {
370429
370450
  module.exports = require_node_gyp_build()(__dirname);
@@ -370916,7 +370937,7 @@ var require_permessage_deflate = /* @__PURE__ */ __commonJSMin(((exports, module
370916
370937
  }
370917
370938
  }));
370918
370939
  //#endregion
370919
- //#region ../../../node_modules/utf-8-validate/fallback.js
370940
+ //#region ../../../../node_modules/utf-8-validate/fallback.js
370920
370941
  var require_fallback = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370921
370942
  /**
370922
370943
  * Checks if a given buffer contains only correct UTF-8.
@@ -370946,7 +370967,7 @@ var require_fallback = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370946
370967
  module.exports = isValidUTF8;
370947
370968
  }));
370948
370969
  //#endregion
370949
- //#region ../../../node_modules/utf-8-validate/index.js
370970
+ //#region ../../../../node_modules/utf-8-validate/index.js
370950
370971
  var require_utf_8_validate = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370951
370972
  try {
370952
370973
  module.exports = require_node_gyp_build()(__dirname);
@@ -420000,15 +420021,6 @@ function isBusy(host) {
420000
420021
  //#endregion
420001
420022
  //#region src/tui/commands/loop.ts
420002
420023
  const LOOP_ARGUMENT_HINT = "/loop [interval] [prompt]";
420003
- const LOOP_CREATE_FILLERS = new Set([
420004
- "mit",
420005
- "alle",
420006
- "jede",
420007
- "jeden",
420008
- "every",
420009
- "each"
420010
- ]);
420011
- const LOOP_INTERVAL_TOKEN = /^\d+(?:m|h|d)$/i;
420012
420024
  function parseLoopCommand(rawArgs) {
420013
420025
  const args = rawArgs.trim();
420014
420026
  if (args.length === 0 || args.toLowerCase() === "status") return { kind: "status" };
@@ -420019,11 +420031,10 @@ function parseLoopCommand(rawArgs) {
420019
420031
  if (action === "resume") return { kind: "resume" };
420020
420032
  if (action === "stop") return { kind: "stop" };
420021
420033
  }
420022
- let startIndex = action === "start" ? 1 : 0;
420023
- if (LOOP_CREATE_FILLERS.has(tokens[startIndex]?.toLowerCase() ?? "")) startIndex += 1;
420034
+ const startIndex = action === "start" ? 1 : 0;
420024
420035
  const interval = tokens[startIndex];
420025
420036
  const prompt = tokens.slice(startIndex + 1).join(" ").trim();
420026
- if (interval === void 0 || !LOOP_INTERVAL_TOKEN.test(interval) || prompt.length === 0) return { kind: "error" };
420037
+ if (interval === void 0 || prompt.length === 0) return { kind: "error" };
420027
420038
  return {
420028
420039
  kind: "create",
420029
420040
  interval,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.39",
3
+ "version": "9.1.41",
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": {