blun-king-cli 9.1.232 → 9.1.233

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.
@@ -15,6 +15,41 @@ function resolveWriteContinuationContract({ continuation, current, mode }) {
15
15
  };
16
16
  }
17
17
 
18
+ function resolvePlainWriteContract({
19
+ contentBytes,
20
+ maxContinuationChunkBytes,
21
+ continuationRequired = false,
22
+ }) {
23
+ if (!Number.isSafeInteger(contentBytes) || contentBytes < 0) {
24
+ throw new TypeError('contentBytes must be a non-negative safe integer');
25
+ }
26
+ if (!Number.isSafeInteger(maxContinuationChunkBytes) || maxContinuationChunkBytes < 1) {
27
+ throw new TypeError('maxContinuationChunkBytes must be a positive safe integer');
28
+ }
29
+
30
+ const directWriteLimit = Math.max(4_096, maxContinuationChunkBytes);
31
+ if (continuationRequired) {
32
+ return {
33
+ allowed: false,
34
+ directWriteLimit,
35
+ reason: 'continuation_required',
36
+ };
37
+ }
38
+ if (contentBytes > directWriteLimit) {
39
+ return {
40
+ allowed: false,
41
+ directWriteLimit,
42
+ reason: 'too_large',
43
+ };
44
+ }
45
+ return {
46
+ allowed: true,
47
+ directWriteLimit,
48
+ reason: 'direct',
49
+ };
50
+ }
51
+
18
52
  module.exports = {
53
+ resolvePlainWriteContract,
19
54
  resolveWriteContinuationContract,
20
55
  };
package/blun.mjs CHANGED
@@ -259580,8 +259580,8 @@ var init_write$1 = __esmMin((() => {
259580
259580
  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";
259581
259581
  }));
259582
259582
  //#endregion
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`. 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.";
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\nWrite complete files up to 4,096 UTF-8 bytes atomically. For a larger new or completely replaced file, 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. After an oversized plain Write is refused, that path accepts only continuation calls until the sequence completes. 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\nWrite complete files up to 4,096 UTF-8 bytes atomically. For a larger new or completely replaced file, 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. After an oversized plain Write is refused, that path accepts only continuation calls until the sequence completes. 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, resolveWriteContinuationContract;
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, resolvePlainWriteContract;
259708
259708
  var init_write = __esmMin((() => {
259709
259709
  init_dist$6();
259710
259710
  init_zod$1();
@@ -259716,7 +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
+ ({ resolveWriteContinuationContract, resolvePlainWriteContract } = createRequire(import.meta.url)("./bin/write-continuation-policy.cjs"));
259720
259720
  S_IFMT = 61440;
259721
259721
  S_IFDIR = 16384;
259722
259722
  DEFAULT_CONTINUATION_CHUNK_BYTES = 2048;
@@ -259751,6 +259751,7 @@ bytesWritten: number$1().int().nonnegative() });
259751
259751
  description = write_default;
259752
259752
  parameters = toInputJsonSchema(WriteInputSchema);
259753
259753
  pendingContinuations = /* @__PURE__ */ new Map();
259754
+ continuationRequiredPaths = /* @__PURE__ */ new Set();
259754
259755
  constructor(kaos, workspace, history, lsp, maxContinuationChunkBytes = resolveWriteContinuationChunkBytes()) {
259755
259756
  this.kaos = kaos;
259756
259757
  this.workspace = workspace;
@@ -259872,6 +259873,7 @@ bytesWritten: number$1().int().nonnegative() });
259872
259873
  ...percent === void 0 ? {} : { percent }
259873
259874
  });
259874
259875
  if (!final) {
259876
+ this.continuationRequiredPaths.delete(safePath);
259875
259877
  this.pendingContinuations.set(safePath, staged);
259876
259878
  const progress = expectedLines === void 0 ? `${String(completedLines)} lines staged; final count not predeclared` : `${String(completedLines)} of ${String(expectedLines)} lines (${String(percent)}%)`;
259877
259879
  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.` };
@@ -259904,6 +259906,7 @@ bytesWritten: number$1().int().nonnegative() });
259904
259906
  output: `Write continuation integrity failure for ${args.path}: staged SHA-256 ${actualSha256}, persisted SHA-256 ${persistedSha256}. The target may be incomplete; inspect it before continuing.`
259905
259907
  };
259906
259908
  this.pendingContinuations.delete(safePath);
259909
+ this.continuationRequiredPaths.delete(safePath);
259907
259910
  const writeOutput = typeof result.output === "string" ? result.output : "Write completed.";
259908
259911
  return {
259909
259912
  ...result,
@@ -259937,10 +259940,19 @@ bytesWritten: number$1().int().nonnegative() });
259937
259940
  output: lineLimit.error
259938
259941
  };
259939
259942
  const contentBytes = Buffer.byteLength(args.content, "utf8");
259940
- if (!allowLargeContent && contentBytes > this.maxContinuationChunkBytes) return {
259941
- isError: true,
259942
- 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.`
259943
- };
259943
+ const plainWrite = resolvePlainWriteContract({
259944
+ contentBytes,
259945
+ maxContinuationChunkBytes: this.maxContinuationChunkBytes,
259946
+ continuationRequired: this.continuationRequiredPaths.has(safePath)
259947
+ });
259948
+ if (!allowLargeContent && !plainWrite.allowed) {
259949
+ if (plainWrite.reason === "too_large") this.continuationRequiredPaths.add(safePath);
259950
+ const reason = plainWrite.reason === "continuation_required" ? "an earlier oversized Write locked this path to the continuation protocol" : `the content is ${String(contentBytes)} UTF-8 bytes, above the ${String(plainWrite.directWriteLimit)}-byte direct-write limit`;
259951
+ return {
259952
+ isError: true,
259953
+ output: `Refused to write ${args.path}: ${reason}. Start or resume continuation with {\"path\":${JSON.stringify(args.path)},\"content\":\"<complete-line chunk ending in \\\\n>\",\"continuation\":{}}. Each chunk may contain at most ${this.maxContinuationChunkBytes.toLocaleString("en-US")} UTF-8 bytes. No file was written.`
259954
+ };
259955
+ }
259944
259956
  const parentError = await this.ensureParentDirectory(safePath);
259945
259957
  if (parentError !== void 0) return {
259946
259958
  isError: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.232",
3
+ "version": "9.1.233",
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": {