@botconnector/bccli 0.4.10 → 0.4.12
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-L4WGVJTY.js → acp-JZW3XHE5.js} +20 -5
- package/dist/acp.d.ts +17 -1
- package/dist/args-XVO7TB4C.js +13 -0
- package/dist/budget.d.ts +4 -1
- package/dist/{chunk-67REFMSY.js → chunk-3CYQYHPK.js} +1 -1
- package/dist/{chunk-VXRW5SYP.js → chunk-6JK4IBGK.js} +25 -14
- package/dist/{chunk-MPYSYTSO.js → chunk-6SDRWEPN.js} +1 -1
- package/dist/{chunk-4WI5ON64.js → chunk-7GM6NN5E.js} +1 -1
- package/dist/{chunk-6RVAPAE5.js → chunk-7XD47KN5.js} +1 -1
- package/dist/{chunk-SXRQ2Q7A.js → chunk-INMSTUB2.js} +4 -4
- package/dist/{chunk-CIEPLTGS.js → chunk-ISOKH5WB.js} +5 -5
- package/dist/{chunk-6N2BBLIT.js → chunk-JUC3ZOCV.js} +2 -2
- package/dist/{chunk-3PUWH62K.js → chunk-KDVL2NP6.js} +34 -50
- package/dist/{chunk-24KDXQZT.js → chunk-KEKDRROL.js} +3 -3
- package/dist/{chunk-ZWXKBFKW.js → chunk-KJIXA6MP.js} +23 -9
- package/dist/{chunk-CBD52BYV.js → chunk-OFMZ6CE6.js} +1 -1
- package/dist/{chunk-7HDBPDAD.js → chunk-Q42ZGVAQ.js} +2 -2
- package/dist/{chunk-ED5TTYQU.js → chunk-R754XIBJ.js} +11 -3
- package/dist/{chunk-3K66L37W.js → chunk-S3QEZDKB.js} +3 -3
- package/dist/{chunk-PGDYPOQW.js → chunk-SWNRA3EW.js} +4 -4
- package/dist/{chunk-USFXL5BS.js → chunk-TLCL6DC7.js} +6 -6
- package/dist/{chunk-WFZKJY3R.js → chunk-YYTFJUO2.js} +3 -2
- package/dist/{chunk-5QCCV2JM.js → chunk-ZJRZTMJF.js} +47 -18
- package/dist/cli.js +39 -39
- package/dist/{completion-GEFRIQWV.js → completion-Q7VHOPPV.js} +1 -1
- package/dist/{config-JKMYKNAT.js → config-T7MKGJVG.js} +2 -2
- package/dist/{config-JLOH5M6B.js → config-YYEAEN2C.js} +3 -3
- package/dist/{ghBotCli-WEVS6S6O.js → ghBotCli-7VUGI63S.js} +18 -16
- package/dist/{integrationCli-PKMICTHC.js → integrationCli-TO42MBZB.js} +192 -12
- package/dist/{login-2TZRODUL.js → login-BSMUGW7L.js} +6 -4
- package/dist/login.d.ts +2 -0
- package/dist/{mcpCli-TAPKYGHO.js → mcpCli-ZT7CRYMP.js} +6 -6
- package/dist/{modelsCli-6PK7V2QZ.js → modelsCli-2ZRW4CC4.js} +6 -6
- package/dist/{oauthLogin-UI34LQZU.js → oauthLogin-THSM6FE7.js} +1 -1
- package/dist/{pluginsCli-RCF33U5J.js → pluginsCli-EKQI4CJW.js} +2 -2
- package/dist/{prCli-24PMW7NS.js → prCli-FMQTOBIV.js} +1 -1
- package/dist/providerCli-3TFEKV4C.js +15 -0
- package/dist/sdk.js +111 -75
- package/dist/{serve-7BFCIEPJ.js → serve-DC6YICSK.js} +16 -16
- package/dist/{serve-XNJI67DU.js → serve-V6YVZTNR.js} +3 -3
- package/dist/session-LX4UNPCD.js +12 -0
- package/dist/setup-MFG3BWEU.js +24 -0
- package/dist/setup.d.ts +5 -0
- package/dist/{statsCli-QDHE4TKB.js → statsCli-7MIQHLVW.js} +2 -2
- package/dist/tools/bash.d.ts +2 -0
- package/dist/{transferCli-7OKKYGG2.js → transferCli-SRSYQLSJ.js} +4 -4
- package/dist/{ui-SZAIIJC5.js → ui-IMCUSB6Q.js} +14 -14
- package/dist/{update-JSNVVXPS.js → update-POT5W6MC.js} +2 -2
- package/package.json +1 -1
- package/dist/args-EW7XJVQN.js +0 -13
- package/dist/providerCli-XA4LTWRD.js +0 -15
- package/dist/session-VAPIHHUG.js +0 -12
- package/dist/setup-GPIMZOWE.js +0 -24
package/dist/sdk.js
CHANGED
|
@@ -168,7 +168,7 @@ Usage:
|
|
|
168
168
|
bccli import <file> import a session JSONL into the current project
|
|
169
169
|
bccli pr <number> [--repo owner/name] [task] check out a GitHub PR and run a task on it
|
|
170
170
|
bccli integrations show the status of external agent integrations
|
|
171
|
-
bccli connect <agent> opencode, aider, cline, dsh, codex, claude-code, cursor, openai-cli, openai-sdk, openai-compatible
|
|
171
|
+
bccli connect <agent> opencode, aider, cline, dsh, codex, claude-code, openclaw, hermes, crush, kilo, cursor, openai-cli, openai-sdk, openai-compatible
|
|
172
172
|
bccli disconnect <agent> remove an integration and restore the previous config
|
|
173
173
|
|
|
174
174
|
Options:
|
|
@@ -199,7 +199,7 @@ Pemakaian:
|
|
|
199
199
|
bccli provider list|add <id>|remove <id> kelola provider (custom: --url <url> [--name N] [--key-env ENV])
|
|
200
200
|
bccli mcp list|add <nama>|remove <nama>|auth <nama>|logout <nama>|serve [--base-url <url>] kelola server MCP, atau layani tools akun ini lewat stdio
|
|
201
201
|
bccli integrations lihat status integrasi agent eksternal
|
|
202
|
-
bccli connect <agent> opencode, aider, cline, dsh, codex, claude-code, cursor, openai-cli, openai-sdk, openai-compatible
|
|
202
|
+
bccli connect <agent> opencode, aider, cline, dsh, codex, claude-code, openclaw, hermes, crush, kilo, cursor, openai-cli, openai-sdk, openai-compatible
|
|
203
203
|
bccli disconnect <agent> lepas integrasi dan pulihkan config sebelumnya
|
|
204
204
|
|
|
205
205
|
Opsi:
|
|
@@ -227,6 +227,7 @@ Opsi:
|
|
|
227
227
|
"usageCap.usd must be a number greater than 0.": "usageCap.usd harus angka lebih dari 0.",
|
|
228
228
|
"usageCap.usd requires usageCap.prices (USD per 1M tokens).": "usageCap.usd memerlukan usageCap.prices (USD per 1 juta token).",
|
|
229
229
|
'usageCap.prices["{key}"] must have numeric input and output (USD per 1M tokens).': 'usageCap.prices["{key}"] harus punya input dan output numerik (USD per 1 juta token).',
|
|
230
|
+
'usageCap.prices["{key}"].cachedInput must be a number >= 0 (USD per 1M tokens).': 'usageCap.prices["{key}"].cachedInput harus angka >= 0 (USD per 1 juta token).',
|
|
230
231
|
"usageCap needs at least one of: tokens, usd.": "usageCap memerlukan setidaknya salah satu dari: tokens, usd.",
|
|
231
232
|
'updateCheck must be "on" or "off".': 'updateCheck harus "on" atau "off".',
|
|
232
233
|
"repoMap must be true or false.": "repoMap harus true atau false.",
|
|
@@ -376,7 +377,12 @@ Opsi:
|
|
|
376
377
|
'-p mode needs a task, e.g. bccli -p "explain this repo"': 'Mode -p butuh tugas, contoh: bccli -p "jelaskan repo ini"',
|
|
377
378
|
'Project MCP server "{name}" skipped (not approved yet; run interactive bccli once to approve it).': 'Server MCP project "{name}" dilewati (belum diizinkan; jalankan bccli interaktif sekali untuk menyetujuinya).',
|
|
378
379
|
'Interactive mode needs a terminal. For scripts/CI use: bccli -p "task"': 'Mode interaktif butuh terminal. Untuk skrip/CI pakai: bccli -p "tugas"',
|
|
379
|
-
"Agent must be one of: opencode, aider, cline, deepseek-harness (dsh), cursor, openai-cli, openai-sdk, openai-compatible, codex, claude-code, openclaw, hermes": "Agent harus salah satu dari: opencode, aider, cline, deepseek-harness (dsh), cursor, openai-cli, openai-sdk, openai-compatible, codex, claude-code, openclaw, hermes",
|
|
380
|
+
"Agent must be one of: opencode, aider, cline, deepseek-harness (dsh), cursor, openai-cli, openai-sdk, openai-compatible, codex, claude-code, openclaw, hermes, crush, kilo": "Agent harus salah satu dari: opencode, aider, cline, deepseek-harness (dsh), cursor, openai-cli, openai-sdk, openai-compatible, codex, claude-code, openclaw, hermes, crush, kilo",
|
|
381
|
+
"Crush already has a botconnector provider outside the BCCLI block: {path}": "Crush sudah memiliki provider botconnector di luar blok BCCLI: {path}",
|
|
382
|
+
"Crush is connected to BotConnector ({n} models available; large model {model}).": "Crush terhubung ke BotConnector ({n} model tersedia; model large {model}).",
|
|
383
|
+
"The Kilo global kilo.json is not valid JSON: {path}": "kilo.json global Kilo tidak valid JSON: {path}",
|
|
384
|
+
'Kilo already has a provider "{id}" with a different endpoint.': 'Kilo sudah memiliki provider "{id}" dengan endpoint lain.',
|
|
385
|
+
"Kilo Code is connected to BotConnector ({n} models available; suggested model {model}).": "Kilo Code terhubung ke BotConnector ({n} model tersedia; model yang disarankan {model}).",
|
|
380
386
|
"Cannot determine the home directory.": "Home directory tidak dapat ditentukan.",
|
|
381
387
|
"No BotConnector API key yet. Run bccli login bc-cloud first.": "API key BotConnector belum tersedia. Jalankan bccli login bc-cloud terlebih dahulu.",
|
|
382
388
|
"Could not load the BotConnector model catalog (HTTP {status}).": "Katalog model BotConnector gagal dimuat (HTTP {status}).",
|
|
@@ -412,6 +418,8 @@ Opsi:
|
|
|
412
418
|
"API key: env {env} only (via key_env; a plaintext key in config.yaml is never written).": "API key: hanya env {env} (melalui key_env; key plaintext tidak pernah ditulis ke config.yaml).",
|
|
413
419
|
"{target}: not managed by BCCLI yet.": "{target}: belum dikelola oleh BCCLI.",
|
|
414
420
|
"{target}: the BotConnector integration was removed and the config restored.": "{target}: integrasi BotConnector dilepas dan config dipulihkan.",
|
|
421
|
+
'{target}: {path} changed after BCCLI connected it, so the old backup was not copied over it. Remove the BCCLI part (provider "botconnector" or the marked block) from that file by hand.': '{target}: {path} berubah setelah BCCLI menyambungkannya, jadi backup lama tidak ditimpa ke file itu. Hapus bagian BCCLI (provider "botconnector" atau blok bertanda) dari file tersebut secara manual.',
|
|
422
|
+
"{target}: the BotConnector integration was removed. {n} file(s) were left untouched (see above); delete the BCCLI entries in them by hand for a clean removal.": "{target}: integrasi BotConnector dilepas. {n} file tidak disentuh (lihat di atas); hapus entri BCCLI di dalamnya secara manual agar bersih.",
|
|
415
423
|
"Custom commands:": "Perintah custom:",
|
|
416
424
|
"Skills:": "Skill:",
|
|
417
425
|
"shift+tab switch permission mode esc cancel the turn": "shift+tab ganti mode izin esc batalkan giliran",
|
|
@@ -617,6 +625,9 @@ function resolvedUsageCap(global) {
|
|
|
617
625
|
if (!price || !nonNegative(price.input) || !nonNegative(price.output)) {
|
|
618
626
|
throw new ConfigError(t('usageCap.prices["{key}"] must have numeric input and output (USD per 1M tokens).', { key }));
|
|
619
627
|
}
|
|
628
|
+
if (price.cachedInput !== void 0 && !nonNegative(price.cachedInput)) {
|
|
629
|
+
throw new ConfigError(t('usageCap.prices["{key}"].cachedInput must be a number >= 0 (USD per 1M tokens).', { key }));
|
|
630
|
+
}
|
|
620
631
|
}
|
|
621
632
|
}
|
|
622
633
|
if (tokens2 === void 0 && usd === void 0) throw new ConfigError(t("usageCap needs at least one of: tokens, usd."));
|
|
@@ -704,7 +715,7 @@ function loadConfig(cwd, env = process.env) {
|
|
|
704
715
|
const project = readJsonConfig(join(cwd, ".bccli", "config.json"));
|
|
705
716
|
const known = { ...DEFAULT_CONFIG.providers, ...global.providers };
|
|
706
717
|
const fromProject = untrustedProviders(project, known);
|
|
707
|
-
const rawFallbacks =
|
|
718
|
+
const rawFallbacks = global.fallbackModels;
|
|
708
719
|
const fallbackModels = Array.isArray(rawFallbacks) ? rawFallbacks.filter((m) => typeof m === "string" && m.includes("/")) : void 0;
|
|
709
720
|
return {
|
|
710
721
|
model: project.model ?? global.model ?? DEFAULT_CONFIG.model,
|
|
@@ -884,7 +895,7 @@ var Permissions = class {
|
|
|
884
895
|
}
|
|
885
896
|
/** Rules that "[a] allow for this session" would add; undefined when it must always be asked. */
|
|
886
897
|
rulesFor(req) {
|
|
887
|
-
if (requiresSensitiveToolApproval(req) && (req.kind === "read" || process.env.BC_TOOL_POLICY_ENFORCE === "true"))
|
|
898
|
+
if (requiresSensitiveToolApproval(req) && (req.kind === "read" || req.kind === "edit" || process.env.BC_TOOL_POLICY_ENFORCE === "true"))
|
|
888
899
|
return void 0;
|
|
889
900
|
if (req.kind === "edit") return this.editInProject(req.target) ? ["edit(project)"] : void 0;
|
|
890
901
|
if (req.kind === "fetch") {
|
|
@@ -906,7 +917,8 @@ var Permissions = class {
|
|
|
906
917
|
}
|
|
907
918
|
check(req) {
|
|
908
919
|
if (this.mode === "plan" && req.kind !== "read") return "deny";
|
|
909
|
-
if (req.kind === "read" && this.mode !== "allowAll" && requiresSensitiveToolApproval(req))
|
|
920
|
+
if ((req.kind === "read" || req.kind === "edit") && this.mode !== "allowAll" && requiresSensitiveToolApproval(req))
|
|
921
|
+
return "ask";
|
|
910
922
|
if (process.env.BC_TOOL_POLICY_ENFORCE === "true" && requiresSensitiveToolApproval(req)) return "ask";
|
|
911
923
|
if (req.kind === "read") return "allow";
|
|
912
924
|
if (this.mode === "allowAll") return "allow";
|
|
@@ -1541,7 +1553,7 @@ function hasPendingProgrammaticReplay(messages) {
|
|
|
1541
1553
|
}
|
|
1542
1554
|
return pending;
|
|
1543
1555
|
}
|
|
1544
|
-
async function readResponsesStream(res, onText, onThinking) {
|
|
1556
|
+
async function readResponsesStream(res, onText, onThinking, signal) {
|
|
1545
1557
|
let text = "";
|
|
1546
1558
|
let thinking = "";
|
|
1547
1559
|
let usage;
|
|
@@ -1643,17 +1655,28 @@ async function readResponsesStream(res, onText, onThinking) {
|
|
|
1643
1655
|
);
|
|
1644
1656
|
}
|
|
1645
1657
|
};
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1658
|
+
const iterator = res.body[Symbol.asyncIterator]();
|
|
1659
|
+
const onAbort = () => void iterator.return?.();
|
|
1660
|
+
if (signal?.aborted) onAbort();
|
|
1661
|
+
else signal?.addEventListener("abort", onAbort);
|
|
1662
|
+
try {
|
|
1663
|
+
for (; ; ) {
|
|
1664
|
+
const step = await iterator.next();
|
|
1665
|
+
if (step.done) break;
|
|
1666
|
+
buffer += decoder.decode(step.value, { stream: true });
|
|
1667
|
+
let newline = buffer.indexOf("\n");
|
|
1668
|
+
while (newline >= 0 && loopAt < 0) {
|
|
1669
|
+
handle(buffer.slice(0, newline).trim());
|
|
1670
|
+
buffer = buffer.slice(newline + 1);
|
|
1671
|
+
newline = buffer.indexOf("\n");
|
|
1672
|
+
}
|
|
1673
|
+
if (loopAt >= 0) {
|
|
1674
|
+
return { text: text.slice(0, loopAt), toolCalls: [], usage, finishReason: "repetition" };
|
|
1675
|
+
}
|
|
1656
1676
|
}
|
|
1677
|
+
} finally {
|
|
1678
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1679
|
+
void iterator.return?.();
|
|
1657
1680
|
}
|
|
1658
1681
|
handle(buffer.trim());
|
|
1659
1682
|
return {
|
|
@@ -2097,7 +2120,7 @@ function createProvider(options) {
|
|
|
2097
2120
|
);
|
|
2098
2121
|
if ((res2.headers.get("content-type") ?? "").includes("application/json")) return readResponsesJson(res2, onThinking);
|
|
2099
2122
|
if (!res2.body) throw new ProviderError(t("Empty response from the provider"));
|
|
2100
|
-
return readResponsesStream(res2, onText, onThinking);
|
|
2123
|
+
return readResponsesStream(res2, onText, onThinking, signal);
|
|
2101
2124
|
}
|
|
2102
2125
|
const res = await post(
|
|
2103
2126
|
"/chat/completions",
|
|
@@ -2379,60 +2402,39 @@ function darwinProfile(cwd, network) {
|
|
|
2379
2402
|
network ? "(allow network*)" : "(deny network*)"
|
|
2380
2403
|
].join("\n");
|
|
2381
2404
|
}
|
|
2405
|
+
function bwrapArgv(cwd, network, command) {
|
|
2406
|
+
return [
|
|
2407
|
+
"bwrap",
|
|
2408
|
+
"--ro-bind",
|
|
2409
|
+
"/",
|
|
2410
|
+
"/",
|
|
2411
|
+
"--dev-bind",
|
|
2412
|
+
"/dev",
|
|
2413
|
+
"/dev",
|
|
2414
|
+
"--proc",
|
|
2415
|
+
"/proc",
|
|
2416
|
+
"--bind",
|
|
2417
|
+
cwd,
|
|
2418
|
+
cwd,
|
|
2419
|
+
"--tmpfs",
|
|
2420
|
+
"/tmp",
|
|
2421
|
+
"--die-with-parent",
|
|
2422
|
+
...network ? [] : ["--unshare-net"],
|
|
2423
|
+
"--",
|
|
2424
|
+
"/bin/bash",
|
|
2425
|
+
"-c",
|
|
2426
|
+
command
|
|
2427
|
+
];
|
|
2428
|
+
}
|
|
2382
2429
|
function sandboxArgv(command, opts) {
|
|
2383
2430
|
if (opts.platform === "darwin") {
|
|
2384
2431
|
return ["sandbox-exec", "-p", darwinProfile(opts.cwd, opts.network), "/bin/bash", "-c", command];
|
|
2385
2432
|
}
|
|
2386
2433
|
if (opts.platform === "linux") {
|
|
2387
|
-
return
|
|
2388
|
-
"bwrap",
|
|
2389
|
-
"--ro-bind",
|
|
2390
|
-
"/",
|
|
2391
|
-
"/",
|
|
2392
|
-
"--dev-bind",
|
|
2393
|
-
"/dev",
|
|
2394
|
-
"/dev",
|
|
2395
|
-
"--proc",
|
|
2396
|
-
"/proc",
|
|
2397
|
-
"--bind",
|
|
2398
|
-
opts.cwd,
|
|
2399
|
-
opts.cwd,
|
|
2400
|
-
"--tmpfs",
|
|
2401
|
-
"/tmp",
|
|
2402
|
-
"--die-with-parent",
|
|
2403
|
-
...opts.network ? [] : ["--unshare-net"],
|
|
2404
|
-
"--",
|
|
2405
|
-
"/bin/bash",
|
|
2406
|
-
"-c",
|
|
2407
|
-
command
|
|
2408
|
-
];
|
|
2434
|
+
return bwrapArgv(opts.cwd, opts.network, command);
|
|
2409
2435
|
}
|
|
2410
2436
|
if (opts.platform === "win32" && (opts.wslBwrap || process.env.BCCLI_WIN32_WSL_SANDBOX === "1")) {
|
|
2411
|
-
|
|
2412
|
-
return [
|
|
2413
|
-
"wsl.exe",
|
|
2414
|
-
"--",
|
|
2415
|
-
"bwrap",
|
|
2416
|
-
"--ro-bind",
|
|
2417
|
-
"/",
|
|
2418
|
-
"/",
|
|
2419
|
-
"--dev-bind",
|
|
2420
|
-
"/dev",
|
|
2421
|
-
"/dev",
|
|
2422
|
-
"--proc",
|
|
2423
|
-
"/proc",
|
|
2424
|
-
"--bind",
|
|
2425
|
-
wslCwd,
|
|
2426
|
-
wslCwd,
|
|
2427
|
-
"--tmpfs",
|
|
2428
|
-
"/tmp",
|
|
2429
|
-
"--die-with-parent",
|
|
2430
|
-
...opts.network ? [] : ["--unshare-net"],
|
|
2431
|
-
"--",
|
|
2432
|
-
"/bin/bash",
|
|
2433
|
-
"-c",
|
|
2434
|
-
command
|
|
2435
|
-
];
|
|
2437
|
+
return ["wsl.exe", "--", ...bwrapArgv(winPathToWsl(opts.cwd), opts.network, command)];
|
|
2436
2438
|
}
|
|
2437
2439
|
return void 0;
|
|
2438
2440
|
}
|
|
@@ -2472,7 +2474,7 @@ function killAllCommands() {
|
|
|
2472
2474
|
}
|
|
2473
2475
|
var backgrounds = /* @__PURE__ */ new Map();
|
|
2474
2476
|
var nextBackgroundId = 1;
|
|
2475
|
-
function startBackground(command, cwd, env, shell) {
|
|
2477
|
+
function startBackground(command, cwd, env, shell, maxRetained) {
|
|
2476
2478
|
const child = spawnChild(command, cwd, env, shell);
|
|
2477
2479
|
const task = {
|
|
2478
2480
|
id: nextBackgroundId++,
|
|
@@ -2493,6 +2495,10 @@ function startBackground(command, cwd, env, shell) {
|
|
|
2493
2495
|
if (child.pid !== void 0) killProcessTree(child.pid);
|
|
2494
2496
|
};
|
|
2495
2497
|
backgrounds.set(task.id, task);
|
|
2498
|
+
for (const [id, other] of backgrounds) {
|
|
2499
|
+
if (backgrounds.size <= maxRetained) break;
|
|
2500
|
+
if (id !== task.id && other.status === "exited") backgrounds.delete(id);
|
|
2501
|
+
}
|
|
2496
2502
|
const onData = (data) => {
|
|
2497
2503
|
let s = data;
|
|
2498
2504
|
if (task.head.length < HALF) {
|
|
@@ -2691,6 +2697,7 @@ var SHELL_NOTE = {
|
|
|
2691
2697
|
function createBashTool(options = {}) {
|
|
2692
2698
|
const offline = options.networkPolicy === "offline";
|
|
2693
2699
|
const sandbox = options.sandbox === true;
|
|
2700
|
+
const maxRetained = options.maxRetainedTasks ?? 50;
|
|
2694
2701
|
const platform = options.platform ?? process.platform;
|
|
2695
2702
|
const shell = resolveShell({ platform, env: process.env, exists: existsSync3, ...options.shellDeps });
|
|
2696
2703
|
const childEnv = offline ? offlineEnv() : void 0;
|
|
@@ -2737,7 +2744,7 @@ Network access is off (networkPolicy "offline"): internet commands such as curl,
|
|
|
2737
2744
|
}
|
|
2738
2745
|
if (input.background) {
|
|
2739
2746
|
if (!input.command) return { output: 'The "command" argument is required to start a background task.', isError: true };
|
|
2740
|
-
const task = startBackground(exec, ctx.cwd, childEnv, shell);
|
|
2747
|
+
const task = startBackground(exec, ctx.cwd, childEnv, shell, maxRetained);
|
|
2741
2748
|
return {
|
|
2742
2749
|
output: `Background task #${task.id} started: ${input.command}
|
|
2743
2750
|
Poll it with {task_id: ${task.id}}; stop it with {task_id: ${task.id}, kill: true}.`
|
|
@@ -3607,6 +3614,12 @@ async function readTextResult(input, buffer) {
|
|
|
3607
3614
|
const lines = buffer.toString("utf8").split(/\r?\n/);
|
|
3608
3615
|
const start = (input.offset ?? 1) - 1;
|
|
3609
3616
|
const limit = input.limit ?? 2e3;
|
|
3617
|
+
if (start >= lines.length) {
|
|
3618
|
+
return {
|
|
3619
|
+
output: `offset ${input.offset} is past the end of ${input.path} (${lines.length} line(s)); start at 1.`,
|
|
3620
|
+
isError: true
|
|
3621
|
+
};
|
|
3622
|
+
}
|
|
3610
3623
|
const requested = lines.slice(start, start + limit);
|
|
3611
3624
|
const shown = [];
|
|
3612
3625
|
let size = 0;
|
|
@@ -3688,7 +3701,9 @@ var writeTool = defineTool({
|
|
|
3688
3701
|
target: (input) => input.path,
|
|
3689
3702
|
async validate(input, ctx) {
|
|
3690
3703
|
const abs = resolvePath(ctx.cwd, input.path);
|
|
3691
|
-
|
|
3704
|
+
if (existsSync4(abs) && !ctx.readFiles.has(abs)) return `${input.path} already exists. Read it with read before overwriting it.`;
|
|
3705
|
+
if (isFileModifiedSinceRead(ctx.readFiles, abs)) return `${input.path} has been modified since it was last read. Read it again before overwriting it.`;
|
|
3706
|
+
return void 0;
|
|
3692
3707
|
},
|
|
3693
3708
|
async preview(input, ctx) {
|
|
3694
3709
|
const abs = resolvePath(ctx.cwd, input.path);
|
|
@@ -3700,6 +3715,9 @@ var writeTool = defineTool({
|
|
|
3700
3715
|
if (existsSync4(abs) && !ctx.readFiles.has(abs)) {
|
|
3701
3716
|
return { output: `${input.path} already exists. Read it with read before overwriting it.`, isError: true };
|
|
3702
3717
|
}
|
|
3718
|
+
if (isFileModifiedSinceRead(ctx.readFiles, abs)) {
|
|
3719
|
+
return { output: `${input.path} has been modified since it was last read. Read it again before overwriting it.`, isError: true };
|
|
3720
|
+
}
|
|
3703
3721
|
try {
|
|
3704
3722
|
await ctx.checkpoint?.(abs);
|
|
3705
3723
|
await mkdir(dirname4(abs), { recursive: true });
|
|
@@ -3809,7 +3827,9 @@ function budgetStatus(usage, cap, model) {
|
|
|
3809
3827
|
if (cap.usd !== void 0) {
|
|
3810
3828
|
const price = priceFor(cap, model);
|
|
3811
3829
|
if (price) {
|
|
3812
|
-
const
|
|
3830
|
+
const cached = Math.max(0, Math.min(usage.cachedInputTokens ?? 0, usage.inputTokens));
|
|
3831
|
+
const cachedRate = price.cachedInput ?? price.input;
|
|
3832
|
+
const usd = ((usage.inputTokens - cached) * price.input + cached * cachedRate + usage.outputTokens * price.output) / 1e6;
|
|
3813
3833
|
if (usd >= cap.usd) return { kind: "usd", used: usd, limit: cap.usd };
|
|
3814
3834
|
}
|
|
3815
3835
|
}
|
|
@@ -4999,7 +5019,7 @@ async function addProviderKey(providerId, key, deps) {
|
|
|
4999
5019
|
// src/session.ts
|
|
5000
5020
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
5001
5021
|
import { appendFileSync, existsSync as existsSync10, mkdirSync as mkdirSync4, readdirSync as readdirSync3, readFileSync as readFileSync7, rmSync as rmSync2, statSync as statSync7 } from "fs";
|
|
5002
|
-
import { basename as basename3, join as join10 } from "path";
|
|
5022
|
+
import { basename as basename3, dirname as dirname8, join as join10 } from "path";
|
|
5003
5023
|
function projectDir(home, cwd) {
|
|
5004
5024
|
const slug = cwd.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(-100) || "root";
|
|
5005
5025
|
return join10(home, "sessions", slug);
|
|
@@ -5025,7 +5045,6 @@ var Session = class _Session {
|
|
|
5025
5045
|
}
|
|
5026
5046
|
static create(home, cwd, now = /* @__PURE__ */ new Date()) {
|
|
5027
5047
|
const dir = projectDir(home, cwd);
|
|
5028
|
-
mkdirSync4(dir, { recursive: true });
|
|
5029
5048
|
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
5030
5049
|
return new _Session(join10(dir, `${stamp}-${randomBytes2(3).toString("hex")}.jsonl`));
|
|
5031
5050
|
}
|
|
@@ -5042,6 +5061,7 @@ var Session = class _Session {
|
|
|
5042
5061
|
return _Session.list(home, cwd)[0]?.session;
|
|
5043
5062
|
}
|
|
5044
5063
|
write(record) {
|
|
5064
|
+
mkdirSync4(dirname8(this.file), { recursive: true });
|
|
5045
5065
|
appendFileSync(this.file, `${JSON.stringify(record)}
|
|
5046
5066
|
`);
|
|
5047
5067
|
}
|
|
@@ -6074,6 +6094,15 @@ function loadPlugins(specs, opts) {
|
|
|
6074
6094
|
|
|
6075
6095
|
// src/setup.ts
|
|
6076
6096
|
var TOOL_RULES = { bash: "bash", edit: "edit", write: "edit", fetch: "fetch" };
|
|
6097
|
+
var pluginCache = /* @__PURE__ */ new Map();
|
|
6098
|
+
function loadPluginsOnce(specs, opts) {
|
|
6099
|
+
const key = JSON.stringify({ specs, home: opts.home, cwd: opts.cwd });
|
|
6100
|
+
const cached = pluginCache.get(key);
|
|
6101
|
+
if (cached) return cached;
|
|
6102
|
+
const loaded = loadPlugins(specs, opts);
|
|
6103
|
+
pluginCache.set(key, loaded);
|
|
6104
|
+
return loaded;
|
|
6105
|
+
}
|
|
6077
6106
|
function lunaPtcAutoEnabled(env) {
|
|
6078
6107
|
const value = String(env.BCCLI_LUNA_PTC ?? "").trim().toLowerCase();
|
|
6079
6108
|
return !["0", "false", "off", "no"].includes(value);
|
|
@@ -6081,6 +6110,7 @@ function lunaPtcAutoEnabled(env) {
|
|
|
6081
6110
|
function createRuntime(opts) {
|
|
6082
6111
|
const env = opts.env ?? process.env;
|
|
6083
6112
|
const home = bccliHome(env);
|
|
6113
|
+
const persistSession = opts.persistSession !== false;
|
|
6084
6114
|
let config = loadConfig(opts.cwd, env);
|
|
6085
6115
|
let modelRef = opts.args.model ?? config.model;
|
|
6086
6116
|
let reasoning = opts.args.reasoning ?? config.reasoning;
|
|
@@ -6169,7 +6199,7 @@ function createRuntime(opts) {
|
|
|
6169
6199
|
createRepoMapTool()
|
|
6170
6200
|
];
|
|
6171
6201
|
if (config.lsp?.servers.length) baseTools.push(createDiagnosticsTool(config.lsp.servers));
|
|
6172
|
-
const plugins =
|
|
6202
|
+
const plugins = loadPluginsOnce(config.plugins ?? [], {
|
|
6173
6203
|
home,
|
|
6174
6204
|
cwd: opts.cwd,
|
|
6175
6205
|
env,
|
|
@@ -6207,9 +6237,15 @@ function createRuntime(opts) {
|
|
|
6207
6237
|
usageCap: config.usageCap,
|
|
6208
6238
|
budgetModel: modelRef,
|
|
6209
6239
|
contextWindow: contextWindowFor(modelRef, env),
|
|
6210
|
-
onMessage: (m) =>
|
|
6211
|
-
|
|
6212
|
-
|
|
6240
|
+
onMessage: (m) => {
|
|
6241
|
+
if (persistSession) session.append(m);
|
|
6242
|
+
},
|
|
6243
|
+
onUsage: (u) => {
|
|
6244
|
+
if (persistSession) session.appendUsage({ ...u, model: modelRef });
|
|
6245
|
+
},
|
|
6246
|
+
onReset: () => {
|
|
6247
|
+
if (persistSession) session.reset();
|
|
6248
|
+
},
|
|
6213
6249
|
onTurnStart: () => {
|
|
6214
6250
|
for (let i = turnMarks.length - 1; i >= 0 && turnMarks[i] > agent.messages.length; i--) {
|
|
6215
6251
|
turnMarks.splice(i, 1);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createRuntime
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZJRZTMJF.js";
|
|
5
5
|
import "./chunk-OK2USAXX.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-KDVL2NP6.js";
|
|
7
|
+
import "./chunk-7GM6NN5E.js";
|
|
8
8
|
import "./chunk-PSO7R5AD.js";
|
|
9
9
|
import {
|
|
10
10
|
VERSION
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-OFMZ6CE6.js";
|
|
12
12
|
import {
|
|
13
13
|
LOOPBACK_BIND,
|
|
14
14
|
MAX_FRAME_BYTES,
|
|
@@ -17,25 +17,25 @@ import {
|
|
|
17
17
|
parseClientFrame,
|
|
18
18
|
randomToken,
|
|
19
19
|
trustFence
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
20
|
+
} from "./chunk-ISOKH5WB.js";
|
|
21
|
+
import "./chunk-YYTFJUO2.js";
|
|
22
|
+
import "./chunk-SWNRA3EW.js";
|
|
23
23
|
import {
|
|
24
24
|
listAllModels
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-INMSTUB2.js";
|
|
26
|
+
import "./chunk-6SDRWEPN.js";
|
|
27
|
+
import "./chunk-3CYQYHPK.js";
|
|
28
28
|
import {
|
|
29
29
|
Session
|
|
30
|
-
} from "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
-
import "./chunk-
|
|
30
|
+
} from "./chunk-KEKDRROL.js";
|
|
31
|
+
import "./chunk-6JK4IBGK.js";
|
|
32
|
+
import "./chunk-7XD47KN5.js";
|
|
33
|
+
import "./chunk-Q42ZGVAQ.js";
|
|
34
34
|
import {
|
|
35
35
|
bccliHome,
|
|
36
36
|
loadConfig
|
|
37
|
-
} from "./chunk-
|
|
38
|
-
import "./chunk-
|
|
37
|
+
} from "./chunk-TLCL6DC7.js";
|
|
38
|
+
import "./chunk-R754XIBJ.js";
|
|
39
39
|
|
|
40
40
|
// src/serve.ts
|
|
41
41
|
import { randomBytes } from "crypto";
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
createFetchTool,
|
|
4
4
|
createWebSearchTool,
|
|
5
5
|
isPrivateHost
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7GM6NN5E.js";
|
|
7
7
|
import "./chunk-PSO7R5AD.js";
|
|
8
8
|
import {
|
|
9
9
|
loadConfig,
|
|
10
10
|
readCredentials
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-TLCL6DC7.js";
|
|
12
12
|
import {
|
|
13
13
|
t
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-R754XIBJ.js";
|
|
15
15
|
|
|
16
16
|
// src/mcpServer/serve.ts
|
|
17
17
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createRuntime,
|
|
4
|
+
lunaPtcAutoEnabled
|
|
5
|
+
} from "./chunk-ZJRZTMJF.js";
|
|
6
|
+
import "./chunk-OK2USAXX.js";
|
|
7
|
+
import "./chunk-KDVL2NP6.js";
|
|
8
|
+
import "./chunk-7GM6NN5E.js";
|
|
9
|
+
import "./chunk-PSO7R5AD.js";
|
|
10
|
+
import "./chunk-YYTFJUO2.js";
|
|
11
|
+
import "./chunk-SWNRA3EW.js";
|
|
12
|
+
import "./chunk-INMSTUB2.js";
|
|
13
|
+
import "./chunk-6SDRWEPN.js";
|
|
14
|
+
import "./chunk-3CYQYHPK.js";
|
|
15
|
+
import "./chunk-KEKDRROL.js";
|
|
16
|
+
import "./chunk-6JK4IBGK.js";
|
|
17
|
+
import "./chunk-7XD47KN5.js";
|
|
18
|
+
import "./chunk-Q42ZGVAQ.js";
|
|
19
|
+
import "./chunk-TLCL6DC7.js";
|
|
20
|
+
import "./chunk-R754XIBJ.js";
|
|
21
|
+
export {
|
|
22
|
+
createRuntime,
|
|
23
|
+
lunaPtcAutoEnabled
|
|
24
|
+
};
|
package/dist/setup.d.ts
CHANGED
|
@@ -71,4 +71,9 @@ export declare function createRuntime(opts: {
|
|
|
71
71
|
userHome?: string;
|
|
72
72
|
/** Override langkah agent (mis. githubBot.stepLimit) — menang atas config.maxSteps. */
|
|
73
73
|
maxSteps?: number | null;
|
|
74
|
+
/**
|
|
75
|
+
* Write the conversation to ~/.bccli/sessions (default true). One-shot hosts such as
|
|
76
|
+
* `gh-bot` turn it off: a session log per webhook comment is never resumed.
|
|
77
|
+
*/
|
|
78
|
+
persistSession?: boolean;
|
|
74
79
|
}): Runtime;
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-OK2USAXX.js";
|
|
5
5
|
import {
|
|
6
6
|
t
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R754XIBJ.js";
|
|
8
8
|
|
|
9
9
|
// src/statsCli.ts
|
|
10
10
|
import { existsSync, readdirSync, readFileSync, statSync } from "fs";
|
|
@@ -124,7 +124,7 @@ function aggregateSessions(home, opts) {
|
|
|
124
124
|
row.usageOutputTokens += usageOut;
|
|
125
125
|
row.cachedInputTokens += cachedIn;
|
|
126
126
|
row.cacheWriteTokens += cacheWrite;
|
|
127
|
-
row.sessionTotals.push(usageIn + usageOut
|
|
127
|
+
row.sessionTotals.push(usageIn + usageOut);
|
|
128
128
|
} else {
|
|
129
129
|
row.inputTokens += estIn;
|
|
130
130
|
row.outputTokens += estOut;
|
package/dist/tools/bash.d.ts
CHANGED
|
@@ -34,6 +34,8 @@ export interface BashToolOptions {
|
|
|
34
34
|
platform?: NodeJS.Platform;
|
|
35
35
|
/** Test hook: fake environment / file lookup used to pick the Windows shell. */
|
|
36
36
|
shellDeps?: Partial<ShellDeps>;
|
|
37
|
+
/** How many finished background tasks are kept for polling (default 50). */
|
|
38
|
+
maxRetainedTasks?: number;
|
|
37
39
|
}
|
|
38
40
|
export declare function createBashTool(options?: BashToolOptions): import("./types").Tool<z.ZodObject<{
|
|
39
41
|
command: z.ZodOptional<z.ZodString>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
Session
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-KEKDRROL.js";
|
|
5
|
+
import "./chunk-6JK4IBGK.js";
|
|
6
|
+
import "./chunk-7XD47KN5.js";
|
|
7
7
|
import {
|
|
8
8
|
t
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-R754XIBJ.js";
|
|
10
10
|
|
|
11
11
|
// src/transferCli.ts
|
|
12
12
|
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CATALOG,
|
|
4
4
|
fillTemplate
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-JUC3ZOCV.js";
|
|
6
6
|
import {
|
|
7
7
|
MAX_VERIFY_ROUNDS,
|
|
8
8
|
runVerify,
|
|
9
9
|
toolLabel,
|
|
10
10
|
verifyFollowup,
|
|
11
11
|
worktreeListText
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-S3QEZDKB.js";
|
|
13
13
|
import {
|
|
14
14
|
BUILTIN_AGENTS,
|
|
15
15
|
appendMemory,
|
|
@@ -24,49 +24,49 @@ import {
|
|
|
24
24
|
runCommand,
|
|
25
25
|
runHooks,
|
|
26
26
|
validateGlobPattern
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-KDVL2NP6.js";
|
|
28
28
|
import "./chunk-PSO7R5AD.js";
|
|
29
29
|
import {
|
|
30
30
|
nextMode,
|
|
31
31
|
requiresSensitiveToolApproval
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-YYTFJUO2.js";
|
|
33
33
|
import {
|
|
34
34
|
hasKey,
|
|
35
35
|
providerName,
|
|
36
36
|
writeGlobalConfig
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-6SDRWEPN.js";
|
|
38
38
|
import {
|
|
39
39
|
Session
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-KEKDRROL.js";
|
|
41
41
|
import {
|
|
42
42
|
contentText
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-6JK4IBGK.js";
|
|
44
44
|
import {
|
|
45
45
|
REASONING_LEVELS,
|
|
46
46
|
assertReasoningSupported,
|
|
47
47
|
parseReasoningLevel,
|
|
48
48
|
supportedReasoningLevels
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-7XD47KN5.js";
|
|
50
50
|
import {
|
|
51
51
|
addGlobalServer,
|
|
52
52
|
globalMcpPath,
|
|
53
53
|
readMcpFile,
|
|
54
54
|
removeGlobalServer
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-Q42ZGVAQ.js";
|
|
56
56
|
import {
|
|
57
57
|
ACCENT,
|
|
58
58
|
PRESETS,
|
|
59
59
|
color,
|
|
60
60
|
matchKeybind,
|
|
61
61
|
removeCredential
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-TLCL6DC7.js";
|
|
63
63
|
import {
|
|
64
64
|
getLanguage,
|
|
65
65
|
locale,
|
|
66
66
|
parseLang,
|
|
67
67
|
setLanguage,
|
|
68
68
|
t
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-R754XIBJ.js";
|
|
70
70
|
|
|
71
71
|
// src/ui/index.tsx
|
|
72
72
|
import { render } from "ink";
|
|
@@ -2805,7 +2805,7 @@ ${allLines.slice(-maxLiveLines).join("\n")}` : text;
|
|
|
2805
2805
|
const activeSpinnerSummary = activeToolEntry ? `${toolLabel(activeToolEntry.tool)}${activeTarget ? ` ${activeTarget.length > 20 ? `${activeTarget.slice(0, 20)}\u2026` : activeTarget}` : ""}` : "";
|
|
2806
2806
|
const activeToolSummary = activeToolEntry ? `${toolLabel(activeToolEntry.tool)}${activeTarget ? ` ${activeTarget.length > 68 ? `${activeTarget.slice(0, 68)}\u2026` : activeTarget}` : ""}` : "";
|
|
2807
2807
|
return /* @__PURE__ */ jsxs12(Box13, { ref: liveRootRef, flexDirection: "column", children: [
|
|
2808
|
-
/* @__PURE__ */ jsx16(Static, { items: staticDone, children: renderEntry }, staticKey),
|
|
2808
|
+
/* @__PURE__ */ jsx16(Static, { items: staticDone, children: renderEntry }, `static-${staticKey}`),
|
|
2809
2809
|
activeTurnDone.map(renderEntry),
|
|
2810
2810
|
transcript.live.map(renderEntry),
|
|
2811
2811
|
busy && !pending && !planAsk ? /* @__PURE__ */ jsxs12(
|
|
@@ -2887,7 +2887,7 @@ ${allLines.slice(-maxLiveLines).join("\n")}` : text;
|
|
|
2887
2887
|
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
2888
2888
|
async function startInteractive(rt, opts) {
|
|
2889
2889
|
if (opts.resume) {
|
|
2890
|
-
const { Session: Session2 } = await import("./session-
|
|
2890
|
+
const { Session: Session2 } = await import("./session-LX4UNPCD.js");
|
|
2891
2891
|
const list = Session2.list(rt.home, rt.cwd).slice(0, 20);
|
|
2892
2892
|
if (!list.length) console.log(t("No sessions in this folder yet; starting a new one."));
|
|
2893
2893
|
else {
|
|
@@ -2903,7 +2903,7 @@ async function startInteractive(rt, opts) {
|
|
|
2903
2903
|
if (chosen) rt.resume(chosen.session);
|
|
2904
2904
|
}
|
|
2905
2905
|
}
|
|
2906
|
-
const { serversToStart, setProjectTrust } = await import("./config-
|
|
2906
|
+
const { serversToStart, setProjectTrust } = await import("./config-YYEAEN2C.js");
|
|
2907
2907
|
const plan = serversToStart(rt.home, rt.cwd);
|
|
2908
2908
|
if (plan.needTrust.length) {
|
|
2909
2909
|
const { createInterface } = await import("readline/promises");
|