@botconnector/bccli 0.4.2 → 0.4.4
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/dist/{acp-UYC6APR5.js → acp-SWBX4TT6.js} +2 -2
- package/dist/{args-NRTZWWEV.js → args-UCLW7NID.js} +2 -2
- package/dist/{chunk-TIMSYZIR.js → chunk-5BVC3Y6B.js} +2 -2
- package/dist/{chunk-266SY3MC.js → chunk-CGBSE55G.js} +1 -1
- package/dist/{chunk-R72OV7RF.js → chunk-FI7RUJRX.js} +255 -71
- package/dist/{chunk-ZEPTUKNW.js → chunk-HBQ6OLQT.js} +76 -20
- package/dist/{chunk-5YJ3ZQVR.js → chunk-MSDK4IIJ.js} +9 -7
- package/dist/{chunk-IYR5PYA3.js → chunk-OZ5GHMTN.js} +1 -1
- package/dist/{chunk-KPTML72Q.js → chunk-QQJ2VVIW.js} +8 -0
- package/dist/{chunk-H7XJDKJY.js → chunk-RZF6A43N.js} +1 -1
- package/dist/{chunk-SVD4LHJC.js → chunk-SMTBYDNO.js} +1 -1
- package/dist/{chunk-6UO5GX55.js → chunk-TGGKACSE.js} +1 -1
- package/dist/{chunk-C64KM37J.js → chunk-YCHCHOMK.js} +5 -1
- package/dist/cli.js +22 -22
- package/dist/{ghBotCli-TSLRORJJ.js → ghBotCli-ZVWU7EMG.js} +8 -8
- package/dist/{login-RYESFZG6.js → login-QPUWIC76.js} +1 -1
- package/dist/lsp.d.ts +23 -0
- package/dist/{modelsCli-OP7CDZC7.js → modelsCli-SZK4E2BY.js} +3 -3
- package/dist/{providerCli-5OZI2GQQ.js → providerCli-PKI7B2SC.js} +4 -4
- package/dist/sdk.js +341 -92
- package/dist/{serve-4J7HA4JO.js → serve-L3SAIAAI.js} +9 -9
- package/dist/{session-YQXCCKXI.js → session-ASXO6GXR.js} +3 -3
- package/dist/{setup-S4AJT6XE.js → setup-F7FZ66OS.js} +7 -7
- package/dist/tools/diagnostics.d.ts +8 -0
- package/dist/tools/sandbox.d.ts +3 -0
- package/dist/{transferCli-R2KEIWQR.js → transferCli-HKGAWZ3Q.js} +3 -3
- package/dist/{ui-36ZEK65V.js → ui-NPA52YJH.js} +45 -9
- package/dist/{update-FSS7X5WV.js → update-AFIM34US.js} +1 -1
- package/package.json +1 -1
package/dist/sdk.js
CHANGED
|
@@ -925,6 +925,14 @@ function reasoningCapability(providerId) {
|
|
|
925
925
|
case "bc-cloud":
|
|
926
926
|
return { levels: BOTCONNECTOR_LEVELS, parameter: "reasoning_effort" };
|
|
927
927
|
case "openai":
|
|
928
|
+
case "gmi":
|
|
929
|
+
case "gmicloud":
|
|
930
|
+
case "vertex-maas":
|
|
931
|
+
case "deepseek":
|
|
932
|
+
case "groq":
|
|
933
|
+
case "together":
|
|
934
|
+
case "fireworks":
|
|
935
|
+
case "mistral":
|
|
928
936
|
return { levels: OPENAI_LEVELS, parameter: "reasoning_effort" };
|
|
929
937
|
case "openrouter":
|
|
930
938
|
return { levels: ["auto", "low", "medium", "high"], parameter: "reasoning" };
|
|
@@ -1230,7 +1238,7 @@ async function readStream(res, onText, onThinking) {
|
|
|
1230
1238
|
if (!choice) return;
|
|
1231
1239
|
if (choice.finish_reason) finishReason = choice.finish_reason;
|
|
1232
1240
|
const delta = choice.delta ?? {};
|
|
1233
|
-
const reasoning = delta.reasoning_content || delta.reasoning;
|
|
1241
|
+
const reasoning = delta.reasoning_content || delta.reasoning || delta.thinking;
|
|
1234
1242
|
if (reasoning) emit({ text: "", thinking: reasoning });
|
|
1235
1243
|
if (delta.content) emit(splitter.push(delta.content));
|
|
1236
1244
|
for (const tc of delta.tool_calls ?? []) {
|
|
@@ -1261,7 +1269,7 @@ async function readStream(res, onText, onThinking) {
|
|
|
1261
1269
|
const toolCalls = calls.map((call, index) => ({ ...call, id: call.id || `call_${index}` }));
|
|
1262
1270
|
return { text, toolCalls, thinking: thinking || void 0, usage, finishReason };
|
|
1263
1271
|
}
|
|
1264
|
-
async function readJson(res) {
|
|
1272
|
+
async function readJson(res, onText, onThinking) {
|
|
1265
1273
|
const body = await res.json();
|
|
1266
1274
|
const choice = body.choices?.[0];
|
|
1267
1275
|
const toolCalls = (choice?.message?.tool_calls ?? []).map((tc, i) => ({
|
|
@@ -1270,7 +1278,9 @@ async function readJson(res) {
|
|
|
1270
1278
|
arguments: tc.function?.arguments ?? ""
|
|
1271
1279
|
}));
|
|
1272
1280
|
const split = splitThinking(choice?.message?.content ?? "");
|
|
1273
|
-
const thinking = (choice?.message?.reasoning_content || choice?.message?.reasoning || "") + split.thinking;
|
|
1281
|
+
const thinking = (choice?.message?.reasoning_content || choice?.message?.reasoning || choice?.message?.thinking || "") + split.thinking;
|
|
1282
|
+
if (thinking) onThinking?.(thinking);
|
|
1283
|
+
if (split.text) onText?.(split.text);
|
|
1274
1284
|
return { text: split.text, toolCalls, thinking: thinking || void 0, usage: toUsage(body.usage), finishReason: choice?.finish_reason };
|
|
1275
1285
|
}
|
|
1276
1286
|
function contentText(content) {
|
|
@@ -1829,7 +1839,7 @@ function createProvider(options) {
|
|
|
1829
1839
|
const isBotConnectorCloud = /^https:\/\/api\.botconnector\.id\/v1\/?$/.test(baseURL) && apiKey?.startsWith("bc_live_");
|
|
1830
1840
|
if (isBotConnectorCloud) {
|
|
1831
1841
|
headers["x-botconnector-client"] = "bccli";
|
|
1832
|
-
headers["x-botconnector-client-version"] = "0.4.
|
|
1842
|
+
headers["x-botconnector-client-version"] = "0.4.4";
|
|
1833
1843
|
}
|
|
1834
1844
|
const useNativeResponses = isBotConnectorCloud && providerId === "bc-cloud" && model === "gpt-6-luna";
|
|
1835
1845
|
const useResponsesWebSocket = useNativeResponses && Boolean(apiKey) && (fetchOverride === void 0 || responsesWebSocketFactory !== void 0);
|
|
@@ -1860,7 +1870,7 @@ function createProvider(options) {
|
|
|
1860
1870
|
baseURL: baseURL.replace(/\/+$/, ""),
|
|
1861
1871
|
defaultHeaders: {
|
|
1862
1872
|
"x-botconnector-client": "bccli",
|
|
1863
|
-
"x-botconnector-client-version": "0.4.
|
|
1873
|
+
"x-botconnector-client-version": "0.4.4"
|
|
1864
1874
|
}
|
|
1865
1875
|
});
|
|
1866
1876
|
lunaWs = responsesWebSocketFactory ? responsesWebSocketFactory(client) : new ResponsesWS(client, { reconnect: null });
|
|
@@ -2013,7 +2023,7 @@ function createProvider(options) {
|
|
|
2013
2023
|
{ model, messages, stream: true, stream_options: { include_usage: true }, ...tools?.length ? { tools } : {}, ...reasoningOverride },
|
|
2014
2024
|
signal
|
|
2015
2025
|
);
|
|
2016
|
-
if ((res.headers.get("content-type") ?? "").includes("application/json")) return readJson(res);
|
|
2026
|
+
if ((res.headers.get("content-type") ?? "").includes("application/json")) return readJson(res, onText, onThinking);
|
|
2017
2027
|
if (!res.body) throw new ProviderError(t("Empty response from the provider"));
|
|
2018
2028
|
return readStream(res, onText, onThinking);
|
|
2019
2029
|
},
|
|
@@ -2268,6 +2278,11 @@ import { join as join2 } from "path";
|
|
|
2268
2278
|
import { z } from "zod";
|
|
2269
2279
|
|
|
2270
2280
|
// src/tools/sandbox.ts
|
|
2281
|
+
function winPathToWsl(winPath) {
|
|
2282
|
+
const normalized = winPath.replace(/\\/g, "/");
|
|
2283
|
+
const m = /^([A-Za-z]):\/(.*)$/.exec(normalized);
|
|
2284
|
+
return m ? `/mnt/${m[1].toLowerCase()}/${m[2]}` : normalized;
|
|
2285
|
+
}
|
|
2271
2286
|
function darwinProfile(cwd, network) {
|
|
2272
2287
|
const writable = [cwd, "/tmp", "/private/tmp", "/dev", "/var/folders"].map((p) => `(subpath "${p}")`).join(" ");
|
|
2273
2288
|
return [
|
|
@@ -2311,6 +2326,33 @@ function sandboxArgv(command, opts) {
|
|
|
2311
2326
|
command
|
|
2312
2327
|
];
|
|
2313
2328
|
}
|
|
2329
|
+
if (opts.platform === "win32" && (opts.wslBwrap || process.env.BCCLI_WIN32_WSL_SANDBOX === "1")) {
|
|
2330
|
+
const wslCwd = winPathToWsl(opts.cwd);
|
|
2331
|
+
return [
|
|
2332
|
+
"wsl.exe",
|
|
2333
|
+
"--",
|
|
2334
|
+
"bwrap",
|
|
2335
|
+
"--ro-bind",
|
|
2336
|
+
"/",
|
|
2337
|
+
"/",
|
|
2338
|
+
"--dev-bind",
|
|
2339
|
+
"/dev",
|
|
2340
|
+
"/dev",
|
|
2341
|
+
"--proc",
|
|
2342
|
+
"/proc",
|
|
2343
|
+
"--bind",
|
|
2344
|
+
wslCwd,
|
|
2345
|
+
wslCwd,
|
|
2346
|
+
"--tmpfs",
|
|
2347
|
+
"/tmp",
|
|
2348
|
+
"--die-with-parent",
|
|
2349
|
+
...opts.network ? [] : ["--unshare-net"],
|
|
2350
|
+
"--",
|
|
2351
|
+
"/bin/bash",
|
|
2352
|
+
"-c",
|
|
2353
|
+
command
|
|
2354
|
+
];
|
|
2355
|
+
}
|
|
2314
2356
|
return void 0;
|
|
2315
2357
|
}
|
|
2316
2358
|
|
|
@@ -2393,10 +2435,14 @@ function startBackground(command, cwd, env, shell) {
|
|
|
2393
2435
|
task.status = "exited";
|
|
2394
2436
|
task.head += `${task.head ? "\n" : ""}${error.message}`;
|
|
2395
2437
|
});
|
|
2396
|
-
child.on("
|
|
2438
|
+
child.on("exit", (code) => {
|
|
2397
2439
|
task.status = "exited";
|
|
2398
2440
|
task.exitCode = code;
|
|
2399
2441
|
});
|
|
2442
|
+
child.on("close", (code) => {
|
|
2443
|
+
task.status = "exited";
|
|
2444
|
+
if (task.exitCode === null) task.exitCode = code;
|
|
2445
|
+
});
|
|
2400
2446
|
return task;
|
|
2401
2447
|
}
|
|
2402
2448
|
function backgroundStatus(task) {
|
|
@@ -2490,8 +2536,40 @@ function runCommand(command, opts) {
|
|
|
2490
2536
|
};
|
|
2491
2537
|
child.stdout.on("data", onData);
|
|
2492
2538
|
child.stderr.on("data", onData);
|
|
2539
|
+
let settled = false;
|
|
2540
|
+
let exitDrainTimer;
|
|
2541
|
+
let killDrainTimer;
|
|
2542
|
+
const finish = (exitCode, extra = "") => {
|
|
2543
|
+
if (settled) return;
|
|
2544
|
+
settled = true;
|
|
2545
|
+
active.delete(killAsAborted);
|
|
2546
|
+
clearTimeout(timer);
|
|
2547
|
+
if (exitDrainTimer) clearTimeout(exitDrainTimer);
|
|
2548
|
+
if (killDrainTimer) clearTimeout(killDrainTimer);
|
|
2549
|
+
opts.signal.removeEventListener("abort", onAbort);
|
|
2550
|
+
child.stdout.removeListener("data", onData);
|
|
2551
|
+
child.stderr.removeListener("data", onData);
|
|
2552
|
+
child.stdout.destroy();
|
|
2553
|
+
child.stderr.destroy();
|
|
2554
|
+
let spillNote = "";
|
|
2555
|
+
if (dropped && fullChunks.length) {
|
|
2556
|
+
try {
|
|
2557
|
+
const spillPath = join2(tmpdir(), `bccli-bash-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.log`);
|
|
2558
|
+
writeFileSync2(spillPath, fullChunks.join(""), "utf8");
|
|
2559
|
+
spillNote = `; full output saved to ${spillPath}`;
|
|
2560
|
+
} catch {
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
const output = dropped ? `${head}
|
|
2564
|
+
\u2026 [${dropped} characters truncated${spillNote}] \u2026
|
|
2565
|
+
${tail}` : head + tail;
|
|
2566
|
+
resolve5({ output: output + extra, exitCode, timedOut, aborted });
|
|
2567
|
+
};
|
|
2493
2568
|
const kill = () => {
|
|
2494
2569
|
if (child.pid !== void 0) killProcessTree(child.pid);
|
|
2570
|
+
if (!killDrainTimer) {
|
|
2571
|
+
killDrainTimer = setTimeout(() => finish(child.exitCode), 500);
|
|
2572
|
+
}
|
|
2495
2573
|
};
|
|
2496
2574
|
const killAsAborted = () => {
|
|
2497
2575
|
aborted = true;
|
|
@@ -2508,29 +2586,16 @@ function runCommand(command, opts) {
|
|
|
2508
2586
|
};
|
|
2509
2587
|
if (opts.signal.aborted) onAbort();
|
|
2510
2588
|
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
opts.signal.removeEventListener("abort", onAbort);
|
|
2515
|
-
let spillNote = "";
|
|
2516
|
-
if (dropped && fullChunks.length) {
|
|
2517
|
-
try {
|
|
2518
|
-
const spillPath = join2(tmpdir(), `bccli-bash-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.log`);
|
|
2519
|
-
writeFileSync2(spillPath, fullChunks.join(""), "utf8");
|
|
2520
|
-
spillNote = `; full output saved to ${spillPath}`;
|
|
2521
|
-
} catch {
|
|
2522
|
-
}
|
|
2589
|
+
child.on("exit", (code) => {
|
|
2590
|
+
if (!exitDrainTimer) {
|
|
2591
|
+
exitDrainTimer = setTimeout(() => finish(code), 200);
|
|
2523
2592
|
}
|
|
2524
|
-
|
|
2525
|
-
\u2026 [${dropped} characters truncated${spillNote}] \u2026
|
|
2526
|
-
${tail}` : head + tail;
|
|
2527
|
-
resolve5({ output: output + extra, exitCode, timedOut, aborted });
|
|
2528
|
-
};
|
|
2593
|
+
});
|
|
2529
2594
|
child.on("error", (error) => finish(null, error.message));
|
|
2530
|
-
child.on("close", (code) => finish(code));
|
|
2595
|
+
child.on("close", (code) => finish(code ?? child.exitCode));
|
|
2531
2596
|
});
|
|
2532
2597
|
}
|
|
2533
|
-
var BASH_DESCRIPTION = "Run a shell command in the project directory. No interactive input. Default timeout 2 minutes (max 10). Use for tests, builds, git, and other CLI tasks. Set background: true for long-running jobs, then poll with task_id (stop with kill: true) or use the /tasks command.";
|
|
2598
|
+
var BASH_DESCRIPTION = "Run a shell command in the project directory. No interactive input. Default timeout 2 minutes (max 10). Use for tests, builds, git, and other CLI tasks. Set background: true for long-running jobs, then poll with task_id (stop with kill: true) or use the /tasks command. Do not pipe commands that start background daemons (such as agent-browser) through | head or | tail.";
|
|
2534
2599
|
var BASH_SCHEMA = z.object({
|
|
2535
2600
|
command: z.string().optional().describe("The shell command to run (required unless task_id is set)"),
|
|
2536
2601
|
timeout_ms: z.number().int().min(1e3).max(6e5).optional().describe("Timeout in milliseconds"),
|
|
@@ -5476,14 +5541,14 @@ function createRepoMapTool() {
|
|
|
5476
5541
|
}
|
|
5477
5542
|
|
|
5478
5543
|
// src/tools/diagnostics.ts
|
|
5479
|
-
import { extname as extname3 } from "path";
|
|
5544
|
+
import { extname as extname3, relative as relative3 } from "path";
|
|
5480
5545
|
import { z as z17 } from "zod";
|
|
5481
5546
|
|
|
5482
5547
|
// src/lsp.ts
|
|
5483
5548
|
import { spawn as spawn4 } from "child_process";
|
|
5484
5549
|
import { readFileSync as readFileSync12 } from "fs";
|
|
5485
5550
|
import { extname as extname2 } from "path";
|
|
5486
|
-
import { pathToFileURL } from "url";
|
|
5551
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
5487
5552
|
var LANGUAGE_IDS = {
|
|
5488
5553
|
".ts": "typescript",
|
|
5489
5554
|
".tsx": "typescriptreact",
|
|
@@ -5551,86 +5616,253 @@ function createLspParser(onMessage) {
|
|
|
5551
5616
|
}
|
|
5552
5617
|
};
|
|
5553
5618
|
}
|
|
5554
|
-
function
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5619
|
+
function extractHoverText(contents) {
|
|
5620
|
+
if (!contents) return "";
|
|
5621
|
+
if (typeof contents === "string") return contents.trim();
|
|
5622
|
+
if (Array.isArray(contents)) return contents.map(extractHoverText).filter(Boolean).join("\n\n");
|
|
5623
|
+
if (typeof contents === "object" && "value" in contents && typeof contents.value === "string") {
|
|
5624
|
+
return contents.value.trim();
|
|
5625
|
+
}
|
|
5626
|
+
return "";
|
|
5627
|
+
}
|
|
5628
|
+
function normalizeLocations(raw) {
|
|
5629
|
+
const items = Array.isArray(raw) ? raw : raw ? [raw] : [];
|
|
5630
|
+
const out = [];
|
|
5631
|
+
for (const item of items) {
|
|
5632
|
+
if (!item || typeof item !== "object") continue;
|
|
5633
|
+
const rec = item;
|
|
5634
|
+
const uri = rec.uri ?? rec.targetUri;
|
|
5635
|
+
const start = rec.range?.start ?? rec.targetSelectionRange?.start ?? rec.targetRange?.start;
|
|
5636
|
+
if (!uri) continue;
|
|
5637
|
+
let path = uri;
|
|
5638
|
+
try {
|
|
5639
|
+
if (uri.startsWith("file:")) path = fileURLToPath(uri);
|
|
5640
|
+
} catch {
|
|
5641
|
+
}
|
|
5642
|
+
out.push({
|
|
5643
|
+
uri,
|
|
5644
|
+
path,
|
|
5645
|
+
line: start?.line ?? 0,
|
|
5646
|
+
character: start?.character ?? 0
|
|
5560
5647
|
});
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5648
|
+
}
|
|
5649
|
+
return out;
|
|
5650
|
+
}
|
|
5651
|
+
function createWarmLspClient(opts) {
|
|
5652
|
+
let child;
|
|
5653
|
+
let initPromise;
|
|
5654
|
+
let nextId = 2;
|
|
5655
|
+
const opened = /* @__PURE__ */ new Map();
|
|
5656
|
+
const pendingRpc = /* @__PURE__ */ new Map();
|
|
5657
|
+
const diagWaiters = /* @__PURE__ */ new Map();
|
|
5658
|
+
const send = (msg) => {
|
|
5659
|
+
try {
|
|
5660
|
+
child?.stdin?.write(encodeLsp(msg));
|
|
5661
|
+
} catch {
|
|
5662
|
+
}
|
|
5663
|
+
};
|
|
5664
|
+
const resetState = () => {
|
|
5665
|
+
child = void 0;
|
|
5666
|
+
initPromise = void 0;
|
|
5667
|
+
opened.clear();
|
|
5668
|
+
for (const [, resolve5] of pendingRpc) resolve5(void 0);
|
|
5669
|
+
pendingRpc.clear();
|
|
5670
|
+
for (const [, waiters] of diagWaiters) {
|
|
5671
|
+
for (const w of waiters) w([]);
|
|
5672
|
+
}
|
|
5673
|
+
diagWaiters.clear();
|
|
5674
|
+
};
|
|
5675
|
+
const ensureStarted = () => {
|
|
5676
|
+
if (initPromise && child && !child.killed) return initPromise;
|
|
5677
|
+
opened.clear();
|
|
5678
|
+
initPromise = new Promise((resolveInit) => {
|
|
5679
|
+
const proc = spawn4(opts.server.command, opts.server.args ?? [], {
|
|
5680
|
+
cwd: opts.cwd,
|
|
5681
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
5682
|
+
shell: useShellForLsp(opts.server.command)
|
|
5683
|
+
});
|
|
5684
|
+
child = proc;
|
|
5685
|
+
let initSettled = false;
|
|
5686
|
+
const settleInit = () => {
|
|
5687
|
+
if (!initSettled) {
|
|
5688
|
+
initSettled = true;
|
|
5689
|
+
resolveInit();
|
|
5581
5690
|
}
|
|
5582
|
-
}
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
5589
|
-
const timer = setTimeout(() => finish([]), opts.timeoutMs ?? 8e3);
|
|
5590
|
-
const parser = createLspParser((msg) => {
|
|
5591
|
-
if (msg.id === 1 && msg.result) {
|
|
5592
|
-
send({ jsonrpc: "2.0", method: "initialized", params: {} });
|
|
5593
|
-
let text = "";
|
|
5594
|
-
try {
|
|
5595
|
-
text = readFileSync12(opts.file, "utf8");
|
|
5596
|
-
} catch {
|
|
5691
|
+
};
|
|
5692
|
+
const parser = createLspParser((msg) => {
|
|
5693
|
+
if (msg.id === 1 && msg.result !== void 0) {
|
|
5694
|
+
send({ jsonrpc: "2.0", method: "initialized", params: {} });
|
|
5695
|
+
settleInit();
|
|
5696
|
+
return;
|
|
5597
5697
|
}
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
(msg.params.diagnostics ?? []).map((d) => ({
|
|
5698
|
+
if (msg.id !== void 0 && pendingRpc.has(msg.id)) {
|
|
5699
|
+
const fn = pendingRpc.get(msg.id);
|
|
5700
|
+
pendingRpc.delete(msg.id);
|
|
5701
|
+
fn?.(msg.result);
|
|
5702
|
+
return;
|
|
5703
|
+
}
|
|
5704
|
+
if (msg.method === "textDocument/publishDiagnostics" && msg.params?.uri) {
|
|
5705
|
+
const uri = msg.params.uri;
|
|
5706
|
+
const diags = (msg.params.diagnostics ?? []).map((d) => ({
|
|
5607
5707
|
line: d.range?.start?.line ?? 0,
|
|
5608
5708
|
character: d.range?.start?.character ?? 0,
|
|
5609
5709
|
severity: d.severity ?? 1,
|
|
5610
5710
|
message: String(d.message ?? "")
|
|
5611
|
-
}))
|
|
5612
|
-
|
|
5613
|
-
|
|
5711
|
+
}));
|
|
5712
|
+
const list2 = diagWaiters.get(uri);
|
|
5713
|
+
if (list2?.length) {
|
|
5714
|
+
diagWaiters.delete(uri);
|
|
5715
|
+
for (const w of list2) w(diags);
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5718
|
+
});
|
|
5719
|
+
proc.stdout?.on("data", (c) => parser.push(c));
|
|
5720
|
+
proc.on("error", () => {
|
|
5721
|
+
resetState();
|
|
5722
|
+
settleInit();
|
|
5723
|
+
});
|
|
5724
|
+
proc.on("close", () => {
|
|
5725
|
+
resetState();
|
|
5726
|
+
settleInit();
|
|
5727
|
+
});
|
|
5728
|
+
send({
|
|
5729
|
+
jsonrpc: "2.0",
|
|
5730
|
+
id: 1,
|
|
5731
|
+
method: "initialize",
|
|
5732
|
+
params: { processId: process.pid, capabilities: {}, rootUri: pathToFileURL(opts.cwd).href }
|
|
5733
|
+
});
|
|
5614
5734
|
});
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5735
|
+
return initPromise;
|
|
5736
|
+
};
|
|
5737
|
+
const syncDocument = (file) => {
|
|
5738
|
+
const uri = pathToFileURL(file).href;
|
|
5739
|
+
let text = "";
|
|
5740
|
+
try {
|
|
5741
|
+
text = readFileSync12(file, "utf8");
|
|
5742
|
+
} catch {
|
|
5743
|
+
}
|
|
5744
|
+
const prevVersion = opened.get(uri);
|
|
5745
|
+
if (prevVersion === void 0) {
|
|
5746
|
+
opened.set(uri, 1);
|
|
5747
|
+
send({
|
|
5748
|
+
jsonrpc: "2.0",
|
|
5749
|
+
method: "textDocument/didOpen",
|
|
5750
|
+
params: { textDocument: { uri, languageId: languageIdFor(file), version: 1, text } }
|
|
5751
|
+
});
|
|
5752
|
+
} else {
|
|
5753
|
+
const version = prevVersion + 1;
|
|
5754
|
+
opened.set(uri, version);
|
|
5755
|
+
send({
|
|
5756
|
+
jsonrpc: "2.0",
|
|
5757
|
+
method: "textDocument/didChange",
|
|
5758
|
+
params: {
|
|
5759
|
+
textDocument: { uri, version },
|
|
5760
|
+
contentChanges: [{ text }]
|
|
5761
|
+
}
|
|
5762
|
+
});
|
|
5763
|
+
}
|
|
5764
|
+
return uri;
|
|
5765
|
+
};
|
|
5766
|
+
const request = (method, params, timeoutMs = opts.timeoutMs ?? 8e3) => new Promise((resolve5) => {
|
|
5767
|
+
const id = nextId++;
|
|
5768
|
+
const timer = setTimeout(() => {
|
|
5769
|
+
pendingRpc.delete(id);
|
|
5770
|
+
resolve5(void 0);
|
|
5771
|
+
}, timeoutMs);
|
|
5772
|
+
pendingRpc.set(id, (res) => {
|
|
5773
|
+
clearTimeout(timer);
|
|
5774
|
+
resolve5(res);
|
|
5623
5775
|
});
|
|
5776
|
+
send({ jsonrpc: "2.0", id, method, params });
|
|
5624
5777
|
});
|
|
5778
|
+
return {
|
|
5779
|
+
async diagnostics(file, timeoutMs = opts.timeoutMs ?? 8e3) {
|
|
5780
|
+
await ensureStarted();
|
|
5781
|
+
if (!child) return [];
|
|
5782
|
+
const uri = pathToFileURL(file).href;
|
|
5783
|
+
return new Promise((resolve5) => {
|
|
5784
|
+
const timer = setTimeout(() => {
|
|
5785
|
+
const list3 = diagWaiters.get(uri) ?? [];
|
|
5786
|
+
diagWaiters.set(
|
|
5787
|
+
uri,
|
|
5788
|
+
list3.filter((w) => w !== onDiag)
|
|
5789
|
+
);
|
|
5790
|
+
resolve5([]);
|
|
5791
|
+
}, timeoutMs);
|
|
5792
|
+
const onDiag = (diags) => {
|
|
5793
|
+
clearTimeout(timer);
|
|
5794
|
+
resolve5(diags);
|
|
5795
|
+
};
|
|
5796
|
+
const list2 = diagWaiters.get(uri) ?? [];
|
|
5797
|
+
list2.push(onDiag);
|
|
5798
|
+
diagWaiters.set(uri, list2);
|
|
5799
|
+
syncDocument(file);
|
|
5800
|
+
});
|
|
5801
|
+
},
|
|
5802
|
+
async hover(file, line, character, timeoutMs) {
|
|
5803
|
+
await ensureStarted();
|
|
5804
|
+
if (!child) return "";
|
|
5805
|
+
const uri = syncDocument(file);
|
|
5806
|
+
const res = await request("textDocument/hover", { textDocument: { uri }, position: { line, character } }, timeoutMs);
|
|
5807
|
+
return extractHoverText(res?.contents);
|
|
5808
|
+
},
|
|
5809
|
+
async definition(file, line, character, timeoutMs) {
|
|
5810
|
+
await ensureStarted();
|
|
5811
|
+
if (!child) return [];
|
|
5812
|
+
const uri = syncDocument(file);
|
|
5813
|
+
const res = await request("textDocument/definition", { textDocument: { uri }, position: { line, character } }, timeoutMs);
|
|
5814
|
+
return normalizeLocations(res);
|
|
5815
|
+
},
|
|
5816
|
+
async references(file, line, character, timeoutMs) {
|
|
5817
|
+
await ensureStarted();
|
|
5818
|
+
if (!child) return [];
|
|
5819
|
+
const uri = syncDocument(file);
|
|
5820
|
+
const res = await request(
|
|
5821
|
+
"textDocument/references",
|
|
5822
|
+
{ textDocument: { uri }, position: { line, character }, context: { includeDeclaration: true } },
|
|
5823
|
+
timeoutMs
|
|
5824
|
+
);
|
|
5825
|
+
return normalizeLocations(res);
|
|
5826
|
+
},
|
|
5827
|
+
async close() {
|
|
5828
|
+
if (!child) return;
|
|
5829
|
+
const proc = child;
|
|
5830
|
+
send({ jsonrpc: "2.0", id: nextId++, method: "shutdown" });
|
|
5831
|
+
send({ jsonrpc: "2.0", method: "exit" });
|
|
5832
|
+
resetState();
|
|
5833
|
+
const killer = setTimeout(() => {
|
|
5834
|
+
try {
|
|
5835
|
+
proc.kill();
|
|
5836
|
+
} catch {
|
|
5837
|
+
}
|
|
5838
|
+
}, 200);
|
|
5839
|
+
killer.unref?.();
|
|
5840
|
+
}
|
|
5841
|
+
};
|
|
5625
5842
|
}
|
|
5626
5843
|
|
|
5627
5844
|
// src/tools/diagnostics.ts
|
|
5628
5845
|
var SEVERITY = { 1: "error", 2: "warning", 3: "info", 4: "hint" };
|
|
5629
|
-
var SCHEMA = z17.object({
|
|
5846
|
+
var SCHEMA = z17.object({
|
|
5847
|
+
path: z17.string().describe("File to check (absolute or relative to the working directory)"),
|
|
5848
|
+
action: z17.enum(["diagnostics", "hover", "definition", "references"]).optional().describe("LSP query action, default diagnostics"),
|
|
5849
|
+
line: z17.number().int().min(1).optional().describe("1-based line number for hover, definition, or references"),
|
|
5850
|
+
character: z17.number().int().min(1).optional().describe("1-based column number for hover, definition, or references")
|
|
5851
|
+
});
|
|
5630
5852
|
function createDiagnosticsTool(servers) {
|
|
5853
|
+
const warmPool = /* @__PURE__ */ new Map();
|
|
5854
|
+
const clientFor = (server, cwd) => {
|
|
5855
|
+
const key = `${cwd}::${server.command}::${(server.args ?? []).join("\0")}`;
|
|
5856
|
+
let client = warmPool.get(key);
|
|
5857
|
+
if (!client) {
|
|
5858
|
+
client = createWarmLspClient({ server, cwd, timeoutMs: 15e3 });
|
|
5859
|
+
warmPool.set(key, client);
|
|
5860
|
+
}
|
|
5861
|
+
return client;
|
|
5862
|
+
};
|
|
5631
5863
|
return defineTool({
|
|
5632
5864
|
name: "diagnostics",
|
|
5633
|
-
description: '
|
|
5865
|
+
description: 'Query the configured LSP server(s) on a file for diagnostics (errors/warnings), hover docs, definition, or references. Configure servers under "lsp.servers" in ~/.bccli/config.json, e.g. { "extensions": [".ts"], "command": "typescript-language-server", "args": ["--stdio"] }.',
|
|
5634
5866
|
schema: SCHEMA,
|
|
5635
5867
|
kind: "read",
|
|
5636
5868
|
target: (input) => input.path,
|
|
@@ -5641,7 +5873,24 @@ function createDiagnosticsTool(servers) {
|
|
|
5641
5873
|
if (!server) {
|
|
5642
5874
|
return { output: t("No LSP server is configured for {ext} files.", { ext: ext || "(none)" }), isError: true };
|
|
5643
5875
|
}
|
|
5644
|
-
const
|
|
5876
|
+
const client = clientFor(server, ctx.cwd);
|
|
5877
|
+
const action = input.action ?? "diagnostics";
|
|
5878
|
+
const line0 = Math.max(0, (input.line ?? 1) - 1);
|
|
5879
|
+
const char0 = Math.max(0, (input.character ?? 1) - 1);
|
|
5880
|
+
if (action === "hover") {
|
|
5881
|
+
const text = await client.hover(file, line0, char0, 15e3);
|
|
5882
|
+
return { output: text || "No hover information." };
|
|
5883
|
+
}
|
|
5884
|
+
if (action === "definition" || action === "references") {
|
|
5885
|
+
const locs = action === "definition" ? await client.definition(file, line0, char0, 15e3) : await client.references(file, line0, char0, 15e3);
|
|
5886
|
+
if (!locs.length) return { output: `No ${action} found.` };
|
|
5887
|
+
const formatted = locs.map((l) => {
|
|
5888
|
+
const rel = relative3(ctx.cwd, l.path).replace(/\\/g, "/") || input.path;
|
|
5889
|
+
return `${rel}:${l.line + 1}:${l.character + 1}`;
|
|
5890
|
+
});
|
|
5891
|
+
return { output: formatted.join("\n") };
|
|
5892
|
+
}
|
|
5893
|
+
const diags = await client.diagnostics(file, 15e3);
|
|
5645
5894
|
if (!diags.length) return { output: "No diagnostics." };
|
|
5646
5895
|
const lines = diags.map((d) => `${input.path}:${d.line + 1}:${d.character + 1} ${SEVERITY[d.severity] ?? "error"} ${d.message}`);
|
|
5647
5896
|
return { output: lines.join("\n"), isError: diags.some((d) => d.severity === 1) };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createRuntime
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FI7RUJRX.js";
|
|
5
5
|
import "./chunk-OK2USAXX.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-HBQ6OLQT.js";
|
|
7
7
|
import "./chunk-JXM6REER.js";
|
|
8
8
|
import "./chunk-PSO7R5AD.js";
|
|
9
9
|
import {
|
|
10
10
|
VERSION
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-CGBSE55G.js";
|
|
12
12
|
import {
|
|
13
13
|
LOOPBACK_BIND,
|
|
14
14
|
MAX_FRAME_BYTES,
|
|
@@ -17,19 +17,19 @@ import {
|
|
|
17
17
|
parseClientFrame,
|
|
18
18
|
randomToken,
|
|
19
19
|
trustFence
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-TGGKACSE.js";
|
|
21
21
|
import "./chunk-WFZKJY3R.js";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-RZF6A43N.js";
|
|
23
23
|
import {
|
|
24
24
|
listAllModels
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-OZ5GHMTN.js";
|
|
26
26
|
import "./chunk-HQW4BROS.js";
|
|
27
27
|
import "./chunk-3I5BW3ZT.js";
|
|
28
28
|
import {
|
|
29
29
|
Session
|
|
30
|
-
} from "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
30
|
+
} from "./chunk-SMTBYDNO.js";
|
|
31
|
+
import "./chunk-MSDK4IIJ.js";
|
|
32
|
+
import "./chunk-QQJ2VVIW.js";
|
|
33
33
|
import "./chunk-6M55UPES.js";
|
|
34
34
|
import {
|
|
35
35
|
bccliHome,
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
Session,
|
|
4
4
|
pruneSessions
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-SMTBYDNO.js";
|
|
6
|
+
import "./chunk-MSDK4IIJ.js";
|
|
7
|
+
import "./chunk-QQJ2VVIW.js";
|
|
8
8
|
import "./chunk-3WHI4LN3.js";
|
|
9
9
|
export {
|
|
10
10
|
Session,
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createRuntime,
|
|
4
4
|
lunaPtcAutoEnabled
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FI7RUJRX.js";
|
|
6
6
|
import "./chunk-OK2USAXX.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-HBQ6OLQT.js";
|
|
8
8
|
import "./chunk-JXM6REER.js";
|
|
9
9
|
import "./chunk-PSO7R5AD.js";
|
|
10
10
|
import "./chunk-WFZKJY3R.js";
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-RZF6A43N.js";
|
|
12
|
+
import "./chunk-OZ5GHMTN.js";
|
|
13
13
|
import "./chunk-HQW4BROS.js";
|
|
14
14
|
import "./chunk-3I5BW3ZT.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-SMTBYDNO.js";
|
|
16
|
+
import "./chunk-MSDK4IIJ.js";
|
|
17
|
+
import "./chunk-QQJ2VVIW.js";
|
|
18
18
|
import "./chunk-6M55UPES.js";
|
|
19
19
|
import "./chunk-RX4UQX43.js";
|
|
20
20
|
import "./chunk-3WHI4LN3.js";
|
|
@@ -2,4 +2,12 @@ import { z } from 'zod';
|
|
|
2
2
|
import { type LspServer } from '../lsp';
|
|
3
3
|
export declare function createDiagnosticsTool(servers: LspServer[]): import("./types").Tool<z.ZodObject<{
|
|
4
4
|
path: z.ZodString;
|
|
5
|
+
action: z.ZodOptional<z.ZodEnum<{
|
|
6
|
+
definition: "definition";
|
|
7
|
+
diagnostics: "diagnostics";
|
|
8
|
+
hover: "hover";
|
|
9
|
+
references: "references";
|
|
10
|
+
}>>;
|
|
11
|
+
line: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
character: z.ZodOptional<z.ZodNumber>;
|
|
5
13
|
}, z.core.$strip>>;
|