blun-king-cli 9.1.228 → 9.1.230

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.
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ function normalizePath(value) {
4
+ return String(value || '').trim().replaceAll('\\', '/').replace(/\/+$/u, '').toLowerCase();
5
+ }
6
+
7
+ function windowsBashPath(value) {
8
+ const normalized = normalizePath(value);
9
+ const match = normalized.match(/^([a-z]):(\/.*)$/u);
10
+ return match ? `/${match[1]}${match[2]}` : normalized;
11
+ }
12
+
13
+ function escapeRegExp(value) {
14
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
15
+ }
16
+
17
+ function findTargetsWholeHome(command, homeDir, isWindowsBash) {
18
+ const normalizedHome = normalizePath(homeDir);
19
+ if (!normalizedHome) return false;
20
+ const homes = new Set([normalizedHome, '~', '$home']);
21
+ if (isWindowsBash) homes.add(windowsBashPath(normalizedHome));
22
+ return [...homes].some((home) => {
23
+ const target = escapeRegExp(home);
24
+ return new RegExp(`(?:^|[;&|]\\s*)find\\s+(?:["']?)${target}(?=["'\\s;|&]|$)`, 'iu').test(command);
25
+ });
26
+ }
27
+
28
+ function recursiveGrepTargetsDot(command) {
29
+ const segments = String(command || '').split(/(?:&&|\|\||[;\n])/u);
30
+ return segments.some((segment) => {
31
+ const match = segment.match(/^\s*grep\s+(.+)$/iu);
32
+ if (!match) return false;
33
+ const args = match[1];
34
+ if (!/(?:^|\s)-[^\s]*[rR][^\s]*(?=\s|$)/u.test(args)) return false;
35
+ return /(?:^|\s)["']?\.["']?(?=\s|$)/u.test(args);
36
+ });
37
+ }
38
+
39
+ function broadRecursiveSearchRefusal({ command, homeDir, isWindowsBash = false }) {
40
+ if (findTargetsWholeHome(String(command || ''), homeDir, isWindowsBash)) {
41
+ return 'Refused broad recursive search over the whole user home before execution. Use Glob with an anchored filename pattern, or narrow Bash find to a known project directory.';
42
+ }
43
+ if (recursiveGrepTargetsDot(command)) {
44
+ return 'Refused broad recursive grep against dot before execution. Use Grep with a path/glob filter, or narrow Bash grep to explicit project subdirectories.';
45
+ }
46
+ return undefined;
47
+ }
48
+
49
+ module.exports = { broadRecursiveSearchRefusal };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ function resolveWriteContinuationContract({ continuation, current, mode }) {
4
+ const expectedPart = current === undefined ? 1 : current.chunks.length + 1;
5
+ const expectedStartLine = (current?.completedLines ?? 0) + 1;
6
+
7
+ return {
8
+ expectedPart,
9
+ expectedStartLine,
10
+ part: continuation.part ?? expectedPart,
11
+ startLine: continuation.start_line ?? expectedStartLine,
12
+ mode: mode ?? (expectedPart === 1 ? 'overwrite' : 'append'),
13
+ final: continuation.final === true,
14
+ expectedLines: continuation.expected_lines ?? current?.expectedLines,
15
+ };
16
+ }
17
+
18
+ module.exports = {
19
+ resolveWriteContinuationContract,
20
+ };
package/blun.mjs CHANGED
@@ -259581,7 +259581,7 @@ var init_write$1 = __esmMin((() => {
259581
259581
  }));
259582
259582
  //#endregion
259583
259583
  write_default = "Create, append to, or completely replace a file. Missing parent directories are created automatically. Overwrite is the default; append adds content at EOF without adding a newline.\n\nUse Write for a new file or a complete replacement. For every incremental change to an existing file, Use Edit instead, even when it is small. Read before overwriting an existing file. Do not create unsolicited documentation, README, summary, or report files unless the user or project instructions require them.\n\nContent is written literally. Never include Read/Edit line prefixes. Supplied LF and CRLF endings are preserved. Source files may contain at most 500 lines; split larger implementations into focused files. Set `single_file_override=true` only when the latest direct user message explicitly requires one source file.\n\nFor a new or completely replaced file too large for one call, use `continuation`. Keep each chunk within the configured UTF-8 bytes limit and end it on a complete line with `\\n`. Set exact `expected_lines` and, when available, `expected_sha256`. Part 1 uses overwrite, `part=1`, and `start_line=1`; every later part uses append, the next consecutive part, and the exact `next_start_line` returned by Write. Set `final=true` only on the complete final part. The Target file remains unchanged until final line-count and optional SHA-256 checks pass. Restart an unfinished sequence only with part 1, overwrite, `start_line=1`, and `reset=true`. Never use continuation for incremental edits.\n\nRunaway generated JavaScript or TypeScript identifiers are rejected before disk I/O; regenerate only the affected section as a smaller chunk.";
259584
- write_default = "Create, append to, or replace a whole file. Missing parent directories are created automatically. Overwrite is default; append adds content at EOF without a newline.\n\nUse Write only for new files or complete replacements. Use Edit for every incremental change, even a small one. Read before overwriting an existing file. Do not create unsolicited documentation unless the user or project instructions require it.\n\nContent is literal. Never include line prefixes. Supplied LF and CRLF endings are preserved. Source files may contain at most 500 lines; split larger implementations into focused files. Set `single_file_override=true` only when the latest direct user message explicitly requires one source file.\n\nFor a new or completely replaced file too large for one call, use `continuation`. Keep each chunk within the configured UTF-8 bytes limit and end it on a complete line with `\\n`. Set exact `expected_lines` and, when available, `expected_sha256`. Part 1 uses overwrite, `part=1`, and `start_line=1`; every later part uses append, the next consecutive part, and the exact `next_start_line` returned by Write. Set `final=true` only on the complete final part. The Target file remains unchanged until final line-count and optional SHA-256 checks pass. Restart an unfinished sequence only with part 1, overwrite, `start_line=1`, and `reset=true`. Never use continuation for incremental edits.\n\nRunaway generated JavaScript or TypeScript identifiers are rejected before disk I/O; regenerate only the affected section as a smaller chunk.";
259584
+ write_default = "Create, append to, or replace a whole file. Missing parent directories are created automatically. Overwrite is default; append adds content at EOF without a newline.\n\nUse Write only for new files or complete replacements. Use Edit for every incremental change, even a small one. Read before overwriting an existing file. Do not create unsolicited documentation unless the user or project instructions require it.\n\nContent is literal. Never include line prefixes. Supplied LF and CRLF endings are preserved. Source files may contain at most 500 lines; split larger implementations into focused files. Set `single_file_override=true` only when the latest direct user message explicitly requires one source file.\n\nFor a new or completely replaced file too large for one call, use `continuation`. Keep each chunk within the configured UTF-8 bytes limit and end it on a complete line with `\\n`. Optionally set exact `expected_lines` and, when available, `expected_sha256`. Part number, start line, and mode are derived from actually staged content when omitted. Set `final=true` only on the complete final part. The Target file remains unchanged until final line-count and optional SHA-256 checks pass. Restart an unfinished sequence with `reset=true`. Never use continuation for incremental edits.\n\nRunaway generated JavaScript or TypeScript identifiers are rejected before disk I/O; regenerate only the affected section as a smaller chunk.";
259585
259585
  //#region ../../packages/agent-core/src/tools/builtin/file/generated-source-health.ts
259586
259586
  /**
259587
259587
  * Find runaway generated identifiers while ignoring comments and strings.
@@ -259704,7 +259704,7 @@ function countCompletedLines(content) {
259704
259704
  for (const character of content) if (character === "\n") count += 1;
259705
259705
  return count;
259706
259706
  }
259707
- var S_IFMT, S_IFDIR, DEFAULT_CONTINUATION_CHUNK_BYTES, MIN_CONTINUATION_CHUNK_BYTES, MAX_CONTINUATION_CHUNK_BYTES, CONTINUATION_CHUNK_BYTES_ENV, WriteContinuationSchema, WriteInputSchema, WriteTool;
259707
+ var S_IFMT, S_IFDIR, DEFAULT_CONTINUATION_CHUNK_BYTES, MIN_CONTINUATION_CHUNK_BYTES, MAX_CONTINUATION_CHUNK_BYTES, CONTINUATION_CHUNK_BYTES_ENV, WriteContinuationSchema, WriteInputSchema, WriteTool, resolveWriteContinuationContract;
259708
259708
  var init_write = __esmMin((() => {
259709
259709
  init_dist$6();
259710
259710
  init_zod$1();
@@ -259716,6 +259716,7 @@ var init_write = __esmMin((() => {
259716
259716
  init_write$1();
259717
259717
  init_generated_source_health();
259718
259718
  init_lsp_diagnostics();
259719
+ ({ resolveWriteContinuationContract } = createRequire(import.meta.url)("./bin/write-continuation-policy.cjs"));
259719
259720
  S_IFMT = 61440;
259720
259721
  S_IFDIR = 16384;
259721
259722
  DEFAULT_CONTINUATION_CHUNK_BYTES = 2048;
@@ -259723,17 +259724,17 @@ var init_write = __esmMin((() => {
259723
259724
  MAX_CONTINUATION_CHUNK_BYTES = 16384;
259724
259725
  CONTINUATION_CHUNK_BYTES_ENV = "BLUN_WRITE_CONTINUATION_MAX_BYTES";
259725
259726
  WriteContinuationSchema = object({
259726
- part: number$1().int().positive().describe("One-based chunk number. Start with 1 and increment by exactly one."),
259727
- 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."),
259728
- expected_lines: number$1().int().positive().describe("Exact completed-line count expected in the final file."),
259729
- final: boolean$1().describe("Set true only for the last chunk, when the complete file is present."),
259727
+ part: number$1().int().positive().optional().describe("Optional one-based chunk number. When omitted, the runtime derives the next part from actually staged content."),
259728
+ start_line: number$1().int().positive().optional().describe("Optional one-based start line. When omitted, the runtime derives it from actually staged content."),
259729
+ expected_lines: number$1().int().positive().optional().describe("Optional exact completed-line count for final verification. It may first be supplied on the final part."),
259730
+ final: boolean$1().optional().describe("Set true only for the last chunk, when the complete file is present. Omitted means false."),
259730
259731
  expected_sha256: string().regex(/^[0-9a-f]{64}$/i).optional().describe("Optional SHA-256 of the complete expected file for byte-for-byte verification."),
259731
259732
  reset: boolean$1().optional().describe("Set true only with part 1 and overwrite to discard an unfinished staged write.")
259732
259733
  });
259733
259734
  WriteInputSchema = object({
259734
259735
  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."),
259735
259736
  content: string().describe("Raw full file content to write exactly as provided. This does not use the Read/Edit text view."),
259736
- 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."),
259737
+ mode: _enum(["overwrite", "append"]).optional().describe("Write mode. Outside continuation it defaults to overwrite; continuation derives overwrite for part 1 and append for later parts when omitted."),
259737
259738
  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."),
259738
259739
  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.")
259739
259740
  });
@@ -259792,89 +259793,94 @@ bytesWritten: number$1().int().nonnegative() });
259792
259793
  async continueWrite(args, safePath, ctx) {
259793
259794
  const continuation = args.continuation;
259794
259795
  if (continuation === void 0) throw new Error("continuation is required");
259795
- const mode = args.mode ?? "overwrite";
259796
+ const initialPart = continuation.part ?? (this.pendingContinuations.get(safePath)?.chunks.length ?? 0) + 1;
259796
259797
  const chunkBytes = Buffer.byteLength(args.content, "utf8");
259797
259798
  if (chunkBytes > this.maxContinuationChunkBytes) return {
259798
259799
  isError: true,
259799
- 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.`
259800
+ output: `Refused continuation part ${String(initialPart)} 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.`
259800
259801
  };
259801
259802
  if (args.content.length === 0 || !args.content.endsWith("\n")) return {
259802
259803
  isError: true,
259803
- 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.`
259804
+ output: `Refused continuation part ${String(initialPart)} for ${args.path}: every chunk must end on a complete line with a newline. No content was staged and no file was written.`
259804
259805
  };
259805
- if (continuation.reset === true && (continuation.part !== 1 || mode !== "overwrite")) return {
259806
+ if (continuation.reset === true && (continuation.part !== void 0 && continuation.part !== 1 || args.mode !== void 0 && args.mode !== "overwrite")) return {
259806
259807
  isError: true,
259807
259808
  output: `Refused continuation reset for ${args.path}: reset requires part 1 with mode=overwrite. No content was staged and no file was written.`
259808
259809
  };
259809
259810
  if (continuation.reset === true) this.pendingContinuations.delete(safePath);
259810
259811
  const current = this.pendingContinuations.get(safePath);
259811
- const expectedPart = current === void 0 ? 1 : current.chunks.length + 1;
259812
- if (continuation.part !== expectedPart) return {
259812
+ const contract = resolveWriteContinuationContract({
259813
+ continuation,
259814
+ current,
259815
+ mode: args.mode
259816
+ });
259817
+ const { expectedPart, expectedStartLine, part, startLine, mode, final, expectedLines } = contract;
259818
+ if (part !== expectedPart) return {
259813
259819
  isError: true,
259814
- output: `Refused continuation part ${String(continuation.part)} for ${args.path}: expected part ${String(expectedPart)}. No content was staged and no file was written.`
259820
+ output: `Refused continuation part ${String(part)} for ${args.path}: expected part ${String(expectedPart)}. No content was staged and no file was written.`
259815
259821
  };
259816
- const expectedStartLine = (current?.completedLines ?? 0) + 1;
259817
- if (continuation.start_line !== expectedStartLine) return {
259822
+ if (startLine !== expectedStartLine) return {
259818
259823
  isError: true,
259819
- 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.`
259824
+ output: `Refused continuation part ${String(part)} for ${args.path}: expected start_line ${String(expectedStartLine)} from the actually staged content, received ${String(startLine)}. No content was staged and no file was written.`
259820
259825
  };
259821
- if (continuation.part === 1 && mode !== "overwrite" || continuation.part > 1 && mode !== "append") return {
259826
+ if (part === 1 && mode !== "overwrite" || part > 1 && mode !== "append") return {
259822
259827
  isError: true,
259823
- 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.`
259828
+ output: `Refused continuation part ${String(part)} for ${args.path}: part 1 must use overwrite and later parts must use append. No content was staged and no file was written.`
259824
259829
  };
259825
- if (current !== void 0 && continuation.expected_lines !== current.expectedLines) return {
259830
+ if (current?.expectedLines !== void 0 && continuation.expected_lines !== void 0 && continuation.expected_lines !== current.expectedLines) return {
259826
259831
  isError: true,
259827
- output: `Refused continuation part ${String(continuation.part)} for ${args.path}: expected_lines changed from ${String(current.expectedLines)} to ${String(continuation.expected_lines)}. No content was staged and no file was written.`
259832
+ output: `Refused continuation part ${String(part)} for ${args.path}: expected_lines changed from ${String(current.expectedLines)} to ${String(continuation.expected_lines)}. No content was staged and no file was written.`
259828
259833
  };
259829
259834
  const expectedSha256 = continuation.expected_sha256?.toLowerCase();
259830
259835
  if (current?.expectedSha256 !== void 0 && expectedSha256 !== void 0 && expectedSha256 !== current.expectedSha256) return {
259831
259836
  isError: true,
259832
- output: `Refused continuation part ${String(continuation.part)} for ${args.path}: expected_sha256 changed between parts. No content was staged and no file was written.`
259837
+ output: `Refused continuation part ${String(part)} for ${args.path}: expected_sha256 changed between parts. No content was staged and no file was written.`
259833
259838
  };
259834
259839
  const chunkLines = countCompletedLines(args.content);
259835
259840
  const completedBefore = current?.completedLines ?? 0;
259836
259841
  const completedLines = completedBefore + chunkLines;
259837
- if (completedLines > continuation.expected_lines) return {
259842
+ if (expectedLines !== void 0 && completedLines > expectedLines) return {
259838
259843
  isError: true,
259839
- output: `Refused continuation part ${String(continuation.part)} for ${args.path}: it would stage ${String(completedLines)} lines, exceeding the expected ${String(continuation.expected_lines)}. No content was staged and no file was written.`
259844
+ output: `Refused continuation part ${String(part)} for ${args.path}: it would stage ${String(completedLines)} lines, exceeding the expected ${String(expectedLines)}. No content was staged and no file was written.`
259840
259845
  };
259841
- if (!continuation.final && completedLines === continuation.expected_lines) return {
259846
+ if (!final && expectedLines !== void 0 && completedLines === expectedLines) return {
259842
259847
  isError: true,
259843
- output: `Refused continuation part ${String(continuation.part)} for ${args.path}: all ${String(completedLines)} expected lines are present but final is false. Retry this part with final=true. No content was staged and no file was written.`
259848
+ output: `Refused continuation part ${String(part)} for ${args.path}: all ${String(completedLines)} expected lines are present but final is false. Retry this part with final=true. No content was staged and no file was written.`
259844
259849
  };
259845
- if (continuation.final && completedLines !== continuation.expected_lines) return {
259850
+ if (final && expectedLines !== void 0 && completedLines !== expectedLines) return {
259846
259851
  isError: true,
259847
- output: `Refused final continuation part ${String(continuation.part)} for ${args.path}: expected ${String(continuation.expected_lines)} lines but would have ${String(completedLines)}. No content was staged and no file was written.`
259852
+ output: `Refused final continuation part ${String(part)} for ${args.path}: expected ${String(expectedLines)} lines but would have ${String(completedLines)}. No content was staged and no file was written.`
259848
259853
  };
259849
- const startLine = completedBefore + 1;
259850
- const boundary = `${String(startLine)}-${String(completedLines)}`;
259854
+ const actualStartLine = completedBefore + 1;
259855
+ const boundary = `${String(actualStartLine)}-${String(completedLines)}`;
259851
259856
  const chunks = [...current?.chunks ?? [], args.content];
259852
259857
  const boundaries = [...current?.boundaries ?? [], boundary];
259853
259858
  const totalBytes = (current?.bytes ?? 0) + chunkBytes;
259854
259859
  const stableExpectedSha256 = current?.expectedSha256 ?? expectedSha256;
259855
259860
  const staged = {
259856
- expectedLines: continuation.expected_lines,
259861
+ expectedLines,
259857
259862
  expectedSha256: stableExpectedSha256,
259858
259863
  chunks,
259859
259864
  boundaries,
259860
259865
  completedLines,
259861
259866
  bytes: totalBytes
259862
259867
  };
259863
- const percent = Math.floor(completedLines / continuation.expected_lines * 100);
259868
+ const percent = expectedLines === void 0 ? void 0 : Math.floor(completedLines / expectedLines * 100);
259864
259869
  ctx?.onUpdate?.({
259865
259870
  kind: "progress",
259866
- text: `Write continuation ${String(continuation.part)}: lines ${boundary}`,
259867
- percent
259871
+ text: `Write continuation ${String(part)}: lines ${boundary}`,
259872
+ ...percent === void 0 ? {} : { percent }
259868
259873
  });
259869
- if (!continuation.final) {
259874
+ if (!final) {
259870
259875
  this.pendingContinuations.set(safePath, staged);
259871
- 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)}.` };
259876
+ const progress = expectedLines === void 0 ? `${String(completedLines)} lines staged; final count not predeclared` : `${String(completedLines)} of ${String(expectedLines)} lines (${String(percent)}%)`;
259877
+ return { output: `Write continuation part ${String(part)} staged lines ${boundary} (${progress}, ${String(chunkBytes)} bytes). Target unchanged. Continue with the next chunk; mode=append, part=${String(part + 1)}, and start_line=${String(completedLines + 1)} are inferred when omitted.` };
259872
259878
  }
259873
259879
  const content = chunks.join("");
259874
259880
  const actualSha256 = createHash("sha256").update(content).digest("hex");
259875
259881
  if (stableExpectedSha256 !== void 0 && actualSha256 !== stableExpectedSha256) return {
259876
259882
  isError: true,
259877
- output: `Refused final continuation part ${String(continuation.part)} for ${args.path}: SHA-256 mismatch (expected ${stableExpectedSha256}, got ${actualSha256}). No file was written; the first ${String(current?.completedLines ?? 0)} staged lines remain available for retry.`
259883
+ output: `Refused final continuation part ${String(part)} for ${args.path}: SHA-256 mismatch (expected ${stableExpectedSha256}, got ${actualSha256}). No file was written; the first ${String(current?.completedLines ?? 0)} staged lines remain available for retry.`
259878
259884
  };
259879
259885
  const result = await this.writeContent({
259880
259886
  ...args,
@@ -262713,7 +262719,7 @@ function windowsPathToPosixPath(path) {
262713
262719
  function rewriteWindowsNullRedirect(command) {
262714
262720
  return command.replace(WINDOWS_NUL_REDIRECT, "$1/dev/null");
262715
262721
  }
262716
- var MS_PER_SECOND, DEFAULT_TIMEOUT_S, MAX_TIMEOUT_S, DEFAULT_BACKGROUND_TIMEOUT_S, MAX_BACKGROUND_TIMEOUT_S, USER_INTERRUPT_REASON, BashInputSchema, SHELL_TIMEOUT_VARS, BashTool, WINDOWS_NUL_REDIRECT;
262722
+ var MS_PER_SECOND, DEFAULT_TIMEOUT_S, MAX_TIMEOUT_S, DEFAULT_BACKGROUND_TIMEOUT_S, MAX_BACKGROUND_TIMEOUT_S, USER_INTERRUPT_REASON, BashInputSchema, SHELL_TIMEOUT_VARS, BashTool, WINDOWS_NUL_REDIRECT, broadRecursiveSearchRefusal;
262717
262723
  var init_bash = __esmMin((() => {
262718
262724
  init_zod$1();
262719
262725
  init_background();
@@ -262722,6 +262728,7 @@ var init_bash = __esmMin((() => {
262722
262728
  init_rule_match();
262723
262729
  init_result_builder();
262724
262730
  init_bash$1();
262731
+ ({ broadRecursiveSearchRefusal } = createRequire(import.meta.url)("./bin/bash-search-scope-policy.cjs"));
262725
262732
  MS_PER_SECOND = 1e3;
262726
262733
  DEFAULT_TIMEOUT_S = 60;
262727
262734
  MAX_TIMEOUT_S = 300;
@@ -262758,7 +262765,7 @@ var init_bash = __esmMin((() => {
262758
262765
  MAX_TIMEOUT_S,
262759
262766
  MAX_BACKGROUND_TIMEOUT_S
262760
262767
  };
262761
- 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.";
262768
+ bash_default = "Execute a `{{ SHELL_NAME }}` command for pipes, environment variables, processes, git, package managers, builds, tests, and other shell semantics.\n\nPrefer dedicated tools: `Read` for a known file, `Write` to create or replace it, `Edit` for exact changes, `Glob` to locate files, and `Grep` to search contents. Whole-home `find` and recursive `grep` against `.` are refused; narrow the path or use those search tools.\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.";
262762
262769
  BashTool = class {
262763
262770
  kaos;
262764
262771
  cwd;
@@ -262891,6 +262898,16 @@ var init_bash = __esmMin((() => {
262891
262898
  isError: true,
262892
262899
  output: "Command cannot be empty."
262893
262900
  };
262901
+ const searchRefusal = broadRecursiveSearchRefusal({
262902
+ command: args.command,
262903
+ cwd: args.cwd ?? this.cwd,
262904
+ homeDir: process.env["USERPROFILE"] ?? process.env["HOME"],
262905
+ isWindowsBash: this.isWindowsBash
262906
+ });
262907
+ if (searchRefusal !== void 0) return {
262908
+ isError: true,
262909
+ output: searchRefusal
262910
+ };
262894
262911
  if (args.run_in_background !== true) return void 0;
262895
262912
  if (!this.allowBackground) return {
262896
262913
  isError: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.228",
3
+ "version": "9.1.230",
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": {