blun-king-cli 9.1.37 → 9.1.38
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/blun.mjs +119 -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:
|
|
2
|
+
// BLUN_BUILD_INPUT_SHA256:e0036ad7d958609c5cf630953c5e1b6b6ec22fda3e8c09f26e7c97767acf846b
|
|
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);
|
|
@@ -3021,6 +3021,8 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
|
|
|
3021
3021
|
serverDecodeMs,
|
|
3022
3022
|
clientConsumeMs
|
|
3023
3023
|
});
|
|
3024
|
+
const hasToolCall = message.toolCalls.length > 0 || pendingPart !== null && pendingPart.type === "function";
|
|
3025
|
+
if (stream.finishReason === null && hasToolCall) throw new APIConnectionError("The provider stream ended before its terminal finish reason. The incomplete response was discarded and no tool call was executed.");
|
|
3024
3026
|
if (pendingPart !== null) flushPart(message, pendingPart, toolCallIndexMap);
|
|
3025
3027
|
if (message.content.length === 0 && message.toolCalls.length === 0) throw new APIEmptyResponseError("The API returned an empty response (no content, no tool calls)." + formatFinishReasonHint(stream) + ` Provider: ${provider.name}, model: ${provider.modelName}`, {
|
|
3026
3028
|
finishReason: stream.finishReason,
|
|
@@ -258792,7 +258794,116 @@ var init_read_media = __esmMin((() => {
|
|
|
258792
258794
|
//#region ../../packages/agent-core/src/tools/builtin/file/write.md?raw
|
|
258793
258795
|
var write_default;
|
|
258794
258796
|
var init_write$1 = __esmMin((() => {
|
|
258795
|
-
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 non-source content too large for one call, overwrite the first chunk, then append subsequent chunks. Never chunk Write to modify an existing file.\n";
|
|
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 non-source content too large for one call, overwrite the first chunk, then append subsequent chunks. Never chunk Write to modify an existing file.\n- Runaway generated JavaScript/TypeScript identifiers are rejected before disk I/O. Regenerate only the affected section as a smaller focused chunk.\n";
|
|
258798
|
+
}));
|
|
258799
|
+
//#endregion
|
|
258800
|
+
//#region ../../packages/agent-core/src/tools/builtin/file/generated-source-health.ts
|
|
258801
|
+
/**
|
|
258802
|
+
* Find runaway generated identifiers while ignoring comments and strings.
|
|
258803
|
+
* A 512-character identifier is already far beyond normal generated source,
|
|
258804
|
+
* while quoted assets and long comments remain valid input.
|
|
258805
|
+
*/
|
|
258806
|
+
function findDegenerateGeneratedIdentifier(path, content) {
|
|
258807
|
+
if (!JAVASCRIPT_LIKE_EXTENSIONS.has(extname$1(path).toLowerCase())) return null;
|
|
258808
|
+
let index = 0;
|
|
258809
|
+
let line = 1;
|
|
258810
|
+
while (index < content.length) {
|
|
258811
|
+
const current = content[index] ?? "";
|
|
258812
|
+
const next = content[index + 1] ?? "";
|
|
258813
|
+
if (current === "\n") {
|
|
258814
|
+
line += 1;
|
|
258815
|
+
index += 1;
|
|
258816
|
+
continue;
|
|
258817
|
+
}
|
|
258818
|
+
if (current === "/" && next === "/") {
|
|
258819
|
+
index = skipLineComment(content, index + 2);
|
|
258820
|
+
continue;
|
|
258821
|
+
}
|
|
258822
|
+
if (current === "/" && next === "*") {
|
|
258823
|
+
const skipped = skipBlockComment(content, index + 2, line);
|
|
258824
|
+
index = skipped.index;
|
|
258825
|
+
line = skipped.line;
|
|
258826
|
+
continue;
|
|
258827
|
+
}
|
|
258828
|
+
if (current === "'" || current === "\"" || current === "`") {
|
|
258829
|
+
const skipped = skipQuoted(content, index + 1, line, current);
|
|
258830
|
+
index = skipped.index;
|
|
258831
|
+
line = skipped.line;
|
|
258832
|
+
continue;
|
|
258833
|
+
}
|
|
258834
|
+
if (isIdentifierStart(current)) {
|
|
258835
|
+
const start = index;
|
|
258836
|
+
index += 1;
|
|
258837
|
+
while (index < content.length && isIdentifierPart(content[index] ?? "")) index += 1;
|
|
258838
|
+
const length = index - start;
|
|
258839
|
+
if (length > 512) return {
|
|
258840
|
+
length,
|
|
258841
|
+
line,
|
|
258842
|
+
preview: content.slice(start, start + 80)
|
|
258843
|
+
};
|
|
258844
|
+
continue;
|
|
258845
|
+
}
|
|
258846
|
+
index += 1;
|
|
258847
|
+
}
|
|
258848
|
+
return null;
|
|
258849
|
+
}
|
|
258850
|
+
function skipLineComment(content, index) {
|
|
258851
|
+
const newline = content.indexOf("\n", index);
|
|
258852
|
+
return newline < 0 ? content.length : newline;
|
|
258853
|
+
}
|
|
258854
|
+
function skipBlockComment(content, start, initialLine) {
|
|
258855
|
+
let index = start;
|
|
258856
|
+
let line = initialLine;
|
|
258857
|
+
while (index < content.length) {
|
|
258858
|
+
if (content[index] === "\n") line += 1;
|
|
258859
|
+
if (content[index] === "*" && content[index + 1] === "/") return {
|
|
258860
|
+
index: index + 2,
|
|
258861
|
+
line
|
|
258862
|
+
};
|
|
258863
|
+
index += 1;
|
|
258864
|
+
}
|
|
258865
|
+
return {
|
|
258866
|
+
index: content.length,
|
|
258867
|
+
line
|
|
258868
|
+
};
|
|
258869
|
+
}
|
|
258870
|
+
function skipQuoted(content, start, initialLine, quote) {
|
|
258871
|
+
let index = start;
|
|
258872
|
+
let line = initialLine;
|
|
258873
|
+
while (index < content.length) {
|
|
258874
|
+
const current = content[index] ?? "";
|
|
258875
|
+
if (current === "\\") {
|
|
258876
|
+
index += 2;
|
|
258877
|
+
continue;
|
|
258878
|
+
}
|
|
258879
|
+
if (current === "\n") line += 1;
|
|
258880
|
+
index += 1;
|
|
258881
|
+
if (current === quote) break;
|
|
258882
|
+
}
|
|
258883
|
+
return {
|
|
258884
|
+
index,
|
|
258885
|
+
line
|
|
258886
|
+
};
|
|
258887
|
+
}
|
|
258888
|
+
function isIdentifierStart(value) {
|
|
258889
|
+
return /[A-Za-z_$]/.test(value);
|
|
258890
|
+
}
|
|
258891
|
+
function isIdentifierPart(value) {
|
|
258892
|
+
return /[A-Za-z0-9_$]/.test(value);
|
|
258893
|
+
}
|
|
258894
|
+
var JAVASCRIPT_LIKE_EXTENSIONS;
|
|
258895
|
+
var init_generated_source_health = __esmMin((() => {
|
|
258896
|
+
init_dist$6();
|
|
258897
|
+
JAVASCRIPT_LIKE_EXTENSIONS = new Set([
|
|
258898
|
+
".cjs",
|
|
258899
|
+
".cts",
|
|
258900
|
+
".js",
|
|
258901
|
+
".jsx",
|
|
258902
|
+
".mjs",
|
|
258903
|
+
".mts",
|
|
258904
|
+
".ts",
|
|
258905
|
+
".tsx"
|
|
258906
|
+
]);
|
|
258796
258907
|
})), S_IFMT, S_IFDIR, WriteInputSchema, WriteTool;
|
|
258797
258908
|
var init_write = __esmMin((() => {
|
|
258798
258909
|
init_dist$6();
|
|
@@ -258803,6 +258914,7 @@ var init_write = __esmMin((() => {
|
|
|
258803
258914
|
init_rule_match();
|
|
258804
258915
|
init_source_file_line_limit();
|
|
258805
258916
|
init_write$1();
|
|
258917
|
+
init_generated_source_health();
|
|
258806
258918
|
init_lsp_diagnostics();
|
|
258807
258919
|
S_IFMT = 61440;
|
|
258808
258920
|
S_IFDIR = 16384;
|
|
@@ -258855,6 +258967,11 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
258855
258967
|
}
|
|
258856
258968
|
async execution(args, safePath) {
|
|
258857
258969
|
const mode = args.mode ?? "overwrite";
|
|
258970
|
+
const degenerateIdentifier = findDegenerateGeneratedIdentifier(safePath, args.content);
|
|
258971
|
+
if (degenerateIdentifier !== null) return {
|
|
258972
|
+
isError: true,
|
|
258973
|
+
output: `Refused to write ${args.path}: generated source contains a runaway ${String(degenerateIdentifier.length)}-character identifier on line ${String(degenerateIdentifier.line)} (starts with ${JSON.stringify(degenerateIdentifier.preview)}). Regenerate that section in a smaller focused chunk. No file was written.`
|
|
258974
|
+
};
|
|
258858
258975
|
let currentContent;
|
|
258859
258976
|
if (isSourceFilePath(safePath)) try {
|
|
258860
258977
|
currentContent = await this.kaos.readText(safePath);
|