@botconnector/bccli 0.4.10 → 0.4.11
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-IPHWC6CO.js} +20 -5
- package/dist/acp.d.ts +17 -1
- package/dist/args-K5AJFDCZ.js +13 -0
- package/dist/budget.d.ts +4 -1
- package/dist/{chunk-7HDBPDAD.js → chunk-2DFY43RP.js} +2 -2
- package/dist/{chunk-5QCCV2JM.js → chunk-6BXW7DGQ.js} +47 -18
- package/dist/{chunk-4WI5ON64.js → chunk-6KZIOICR.js} +1 -1
- package/dist/{chunk-3K66L37W.js → chunk-6M5T7N7A.js} +3 -3
- package/dist/{chunk-USFXL5BS.js → chunk-C2FUGQJX.js} +6 -6
- package/dist/{chunk-24KDXQZT.js → chunk-F54FDJBD.js} +3 -3
- package/dist/{chunk-ED5TTYQU.js → chunk-G5TG43R4.js} +3 -0
- package/dist/{chunk-67REFMSY.js → chunk-IHQGXDSG.js} +1 -1
- package/dist/{chunk-PGDYPOQW.js → chunk-JFYQCPXL.js} +4 -4
- package/dist/{chunk-ZWXKBFKW.js → chunk-MBAMDCCV.js} +23 -9
- package/dist/{chunk-CBD52BYV.js → chunk-N6APAYSF.js} +1 -1
- package/dist/{chunk-6N2BBLIT.js → chunk-NT2G5FSX.js} +2 -2
- package/dist/{chunk-3PUWH62K.js → chunk-OAXD3X4R.js} +34 -50
- package/dist/{chunk-VXRW5SYP.js → chunk-OOOS5RCT.js} +25 -14
- package/dist/{chunk-CIEPLTGS.js → chunk-WSZF2CTU.js} +4 -4
- package/dist/{chunk-MPYSYTSO.js → chunk-X24APPXO.js} +1 -1
- package/dist/{chunk-6RVAPAE5.js → chunk-XZ2TI5HV.js} +1 -1
- package/dist/{chunk-SXRQ2Q7A.js → chunk-Y6AZGGH7.js} +4 -4
- package/dist/{chunk-WFZKJY3R.js → chunk-YYTFJUO2.js} +3 -2
- package/dist/cli.js +39 -39
- package/dist/{completion-GEFRIQWV.js → completion-QVDGAYUY.js} +1 -1
- package/dist/{config-JLOH5M6B.js → config-7TQ2KVVX.js} +3 -3
- package/dist/{config-JKMYKNAT.js → config-RZY3XQZJ.js} +2 -2
- package/dist/{ghBotCli-WEVS6S6O.js → ghBotCli-HHJ4ANTH.js} +18 -16
- package/dist/{integrationCli-PKMICTHC.js → integrationCli-LNNZDGZX.js} +40 -5
- package/dist/{login-2TZRODUL.js → login-MQEZGF2C.js} +6 -4
- package/dist/login.d.ts +2 -0
- package/dist/{mcpCli-TAPKYGHO.js → mcpCli-CUIOYJ2A.js} +6 -6
- package/dist/{modelsCli-6PK7V2QZ.js → modelsCli-AAFHFI4H.js} +6 -6
- package/dist/{oauthLogin-UI34LQZU.js → oauthLogin-YFL2N4QA.js} +1 -1
- package/dist/{pluginsCli-RCF33U5J.js → pluginsCli-2QXXFLQA.js} +2 -2
- package/dist/{prCli-24PMW7NS.js → prCli-KSA73RCS.js} +1 -1
- package/dist/providerCli-TXMVPSW5.js +15 -0
- package/dist/sdk.js +103 -72
- package/dist/{serve-XNJI67DU.js → serve-EIQHEUYD.js} +3 -3
- package/dist/{serve-7BFCIEPJ.js → serve-QYDBFTHC.js} +16 -16
- package/dist/session-CQCQ7KAP.js +12 -0
- package/dist/setup-DBSGMWHM.js +24 -0
- package/dist/setup.d.ts +5 -0
- package/dist/{statsCli-QDHE4TKB.js → statsCli-EHNJIQ2Z.js} +2 -2
- package/dist/tools/bash.d.ts +2 -0
- package/dist/{transferCli-7OKKYGG2.js → transferCli-IXJ2O74Q.js} +4 -4
- package/dist/{ui-SZAIIJC5.js → ui-A2LASWDK.js} +14 -14
- package/dist/{update-JSNVVXPS.js → update-TR62JV3A.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
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
defaultLoginDeps,
|
|
4
|
+
echoFor,
|
|
4
5
|
readLine,
|
|
5
6
|
readSecret,
|
|
6
7
|
runLogin
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-MBAMDCCV.js";
|
|
9
|
+
import "./chunk-IHQGXDSG.js";
|
|
10
|
+
import "./chunk-C2FUGQJX.js";
|
|
11
|
+
import "./chunk-G5TG43R4.js";
|
|
11
12
|
export {
|
|
12
13
|
defaultLoginDeps,
|
|
14
|
+
echoFor,
|
|
13
15
|
readLine,
|
|
14
16
|
readSecret,
|
|
15
17
|
runLogin
|
package/dist/login.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export declare function readSecret(prompt: string): Promise<string>;
|
|
2
|
+
/** What readLine writes back to the terminal: printable input is visible, control keys are not. */
|
|
3
|
+
export declare function echoFor(ch: string): string | undefined;
|
|
2
4
|
/** Prompt TANPA masking (kode otorisasi harus terlihat saat di-paste). Ctrl+C -> exit 130. */
|
|
3
5
|
export declare function readLine(prompt: string): Promise<string>;
|
|
4
6
|
import type { CliArgs } from './args';
|
|
@@ -2,30 +2,30 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CATALOG,
|
|
4
4
|
fillTemplate
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-NT2G5FSX.js";
|
|
6
6
|
import {
|
|
7
7
|
authorizeMcpServer,
|
|
8
8
|
clearTokens
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IHQGXDSG.js";
|
|
10
10
|
import {
|
|
11
11
|
addGlobalServer,
|
|
12
12
|
globalMcpPath,
|
|
13
13
|
readMcpFile,
|
|
14
14
|
removeGlobalServer
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-2DFY43RP.js";
|
|
16
16
|
import {
|
|
17
17
|
bccliHome
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-C2FUGQJX.js";
|
|
19
19
|
import {
|
|
20
20
|
t
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-G5TG43R4.js";
|
|
22
22
|
|
|
23
23
|
// src/mcpCli.ts
|
|
24
24
|
async function runMcpCommand(args, deps) {
|
|
25
25
|
const home = bccliHome(deps.env);
|
|
26
26
|
const [action = "list", name] = args.subArgs;
|
|
27
27
|
if (action === "serve") {
|
|
28
|
-
const { runMcpServe } = await import("./serve-
|
|
28
|
+
const { runMcpServe } = await import("./serve-EIQHEUYD.js");
|
|
29
29
|
return runMcpServe(args, deps);
|
|
30
30
|
}
|
|
31
31
|
const installed = readMcpFile(globalMcpPath(home));
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
listAllModels
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-Y6AZGGH7.js";
|
|
5
|
+
import "./chunk-X24APPXO.js";
|
|
6
|
+
import "./chunk-OOOS5RCT.js";
|
|
7
|
+
import "./chunk-XZ2TI5HV.js";
|
|
8
8
|
import {
|
|
9
9
|
loadConfig,
|
|
10
10
|
resolveModel
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-C2FUGQJX.js";
|
|
12
12
|
import {
|
|
13
13
|
t
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-G5TG43R4.js";
|
|
15
15
|
|
|
16
16
|
// src/modelsCli.ts
|
|
17
17
|
async function runModelsCommand(args, deps) {
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
bccliHome,
|
|
4
4
|
globalConfigPath
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-C2FUGQJX.js";
|
|
6
6
|
import {
|
|
7
7
|
t
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-G5TG43R4.js";
|
|
9
9
|
|
|
10
10
|
// src/pluginsCli.ts
|
|
11
11
|
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
addProviderKey,
|
|
4
|
+
runProviderCommand
|
|
5
|
+
} from "./chunk-JFYQCPXL.js";
|
|
6
|
+
import "./chunk-Y6AZGGH7.js";
|
|
7
|
+
import "./chunk-X24APPXO.js";
|
|
8
|
+
import "./chunk-OOOS5RCT.js";
|
|
9
|
+
import "./chunk-XZ2TI5HV.js";
|
|
10
|
+
import "./chunk-C2FUGQJX.js";
|
|
11
|
+
import "./chunk-G5TG43R4.js";
|
|
12
|
+
export {
|
|
13
|
+
addProviderKey,
|
|
14
|
+
runProviderCommand
|
|
15
|
+
};
|
package/dist/sdk.js
CHANGED
|
@@ -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.",
|
|
@@ -412,6 +413,8 @@ Opsi:
|
|
|
412
413
|
"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
414
|
"{target}: not managed by BCCLI yet.": "{target}: belum dikelola oleh BCCLI.",
|
|
414
415
|
"{target}: the BotConnector integration was removed and the config restored.": "{target}: integrasi BotConnector dilepas dan config dipulihkan.",
|
|
416
|
+
'{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.',
|
|
417
|
+
"{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
418
|
"Custom commands:": "Perintah custom:",
|
|
416
419
|
"Skills:": "Skill:",
|
|
417
420
|
"shift+tab switch permission mode esc cancel the turn": "shift+tab ganti mode izin esc batalkan giliran",
|
|
@@ -617,6 +620,9 @@ function resolvedUsageCap(global) {
|
|
|
617
620
|
if (!price || !nonNegative(price.input) || !nonNegative(price.output)) {
|
|
618
621
|
throw new ConfigError(t('usageCap.prices["{key}"] must have numeric input and output (USD per 1M tokens).', { key }));
|
|
619
622
|
}
|
|
623
|
+
if (price.cachedInput !== void 0 && !nonNegative(price.cachedInput)) {
|
|
624
|
+
throw new ConfigError(t('usageCap.prices["{key}"].cachedInput must be a number >= 0 (USD per 1M tokens).', { key }));
|
|
625
|
+
}
|
|
620
626
|
}
|
|
621
627
|
}
|
|
622
628
|
if (tokens2 === void 0 && usd === void 0) throw new ConfigError(t("usageCap needs at least one of: tokens, usd."));
|
|
@@ -704,7 +710,7 @@ function loadConfig(cwd, env = process.env) {
|
|
|
704
710
|
const project = readJsonConfig(join(cwd, ".bccli", "config.json"));
|
|
705
711
|
const known = { ...DEFAULT_CONFIG.providers, ...global.providers };
|
|
706
712
|
const fromProject = untrustedProviders(project, known);
|
|
707
|
-
const rawFallbacks =
|
|
713
|
+
const rawFallbacks = global.fallbackModels;
|
|
708
714
|
const fallbackModels = Array.isArray(rawFallbacks) ? rawFallbacks.filter((m) => typeof m === "string" && m.includes("/")) : void 0;
|
|
709
715
|
return {
|
|
710
716
|
model: project.model ?? global.model ?? DEFAULT_CONFIG.model,
|
|
@@ -884,7 +890,7 @@ var Permissions = class {
|
|
|
884
890
|
}
|
|
885
891
|
/** Rules that "[a] allow for this session" would add; undefined when it must always be asked. */
|
|
886
892
|
rulesFor(req) {
|
|
887
|
-
if (requiresSensitiveToolApproval(req) && (req.kind === "read" || process.env.BC_TOOL_POLICY_ENFORCE === "true"))
|
|
893
|
+
if (requiresSensitiveToolApproval(req) && (req.kind === "read" || req.kind === "edit" || process.env.BC_TOOL_POLICY_ENFORCE === "true"))
|
|
888
894
|
return void 0;
|
|
889
895
|
if (req.kind === "edit") return this.editInProject(req.target) ? ["edit(project)"] : void 0;
|
|
890
896
|
if (req.kind === "fetch") {
|
|
@@ -906,7 +912,8 @@ var Permissions = class {
|
|
|
906
912
|
}
|
|
907
913
|
check(req) {
|
|
908
914
|
if (this.mode === "plan" && req.kind !== "read") return "deny";
|
|
909
|
-
if (req.kind === "read" && this.mode !== "allowAll" && requiresSensitiveToolApproval(req))
|
|
915
|
+
if ((req.kind === "read" || req.kind === "edit") && this.mode !== "allowAll" && requiresSensitiveToolApproval(req))
|
|
916
|
+
return "ask";
|
|
910
917
|
if (process.env.BC_TOOL_POLICY_ENFORCE === "true" && requiresSensitiveToolApproval(req)) return "ask";
|
|
911
918
|
if (req.kind === "read") return "allow";
|
|
912
919
|
if (this.mode === "allowAll") return "allow";
|
|
@@ -1541,7 +1548,7 @@ function hasPendingProgrammaticReplay(messages) {
|
|
|
1541
1548
|
}
|
|
1542
1549
|
return pending;
|
|
1543
1550
|
}
|
|
1544
|
-
async function readResponsesStream(res, onText, onThinking) {
|
|
1551
|
+
async function readResponsesStream(res, onText, onThinking, signal) {
|
|
1545
1552
|
let text = "";
|
|
1546
1553
|
let thinking = "";
|
|
1547
1554
|
let usage;
|
|
@@ -1643,17 +1650,28 @@ async function readResponsesStream(res, onText, onThinking) {
|
|
|
1643
1650
|
);
|
|
1644
1651
|
}
|
|
1645
1652
|
};
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1653
|
+
const iterator = res.body[Symbol.asyncIterator]();
|
|
1654
|
+
const onAbort = () => void iterator.return?.();
|
|
1655
|
+
if (signal?.aborted) onAbort();
|
|
1656
|
+
else signal?.addEventListener("abort", onAbort);
|
|
1657
|
+
try {
|
|
1658
|
+
for (; ; ) {
|
|
1659
|
+
const step = await iterator.next();
|
|
1660
|
+
if (step.done) break;
|
|
1661
|
+
buffer += decoder.decode(step.value, { stream: true });
|
|
1662
|
+
let newline = buffer.indexOf("\n");
|
|
1663
|
+
while (newline >= 0 && loopAt < 0) {
|
|
1664
|
+
handle(buffer.slice(0, newline).trim());
|
|
1665
|
+
buffer = buffer.slice(newline + 1);
|
|
1666
|
+
newline = buffer.indexOf("\n");
|
|
1667
|
+
}
|
|
1668
|
+
if (loopAt >= 0) {
|
|
1669
|
+
return { text: text.slice(0, loopAt), toolCalls: [], usage, finishReason: "repetition" };
|
|
1670
|
+
}
|
|
1656
1671
|
}
|
|
1672
|
+
} finally {
|
|
1673
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1674
|
+
void iterator.return?.();
|
|
1657
1675
|
}
|
|
1658
1676
|
handle(buffer.trim());
|
|
1659
1677
|
return {
|
|
@@ -2097,7 +2115,7 @@ function createProvider(options) {
|
|
|
2097
2115
|
);
|
|
2098
2116
|
if ((res2.headers.get("content-type") ?? "").includes("application/json")) return readResponsesJson(res2, onThinking);
|
|
2099
2117
|
if (!res2.body) throw new ProviderError(t("Empty response from the provider"));
|
|
2100
|
-
return readResponsesStream(res2, onText, onThinking);
|
|
2118
|
+
return readResponsesStream(res2, onText, onThinking, signal);
|
|
2101
2119
|
}
|
|
2102
2120
|
const res = await post(
|
|
2103
2121
|
"/chat/completions",
|
|
@@ -2379,60 +2397,39 @@ function darwinProfile(cwd, network) {
|
|
|
2379
2397
|
network ? "(allow network*)" : "(deny network*)"
|
|
2380
2398
|
].join("\n");
|
|
2381
2399
|
}
|
|
2400
|
+
function bwrapArgv(cwd, network, command) {
|
|
2401
|
+
return [
|
|
2402
|
+
"bwrap",
|
|
2403
|
+
"--ro-bind",
|
|
2404
|
+
"/",
|
|
2405
|
+
"/",
|
|
2406
|
+
"--dev-bind",
|
|
2407
|
+
"/dev",
|
|
2408
|
+
"/dev",
|
|
2409
|
+
"--proc",
|
|
2410
|
+
"/proc",
|
|
2411
|
+
"--bind",
|
|
2412
|
+
cwd,
|
|
2413
|
+
cwd,
|
|
2414
|
+
"--tmpfs",
|
|
2415
|
+
"/tmp",
|
|
2416
|
+
"--die-with-parent",
|
|
2417
|
+
...network ? [] : ["--unshare-net"],
|
|
2418
|
+
"--",
|
|
2419
|
+
"/bin/bash",
|
|
2420
|
+
"-c",
|
|
2421
|
+
command
|
|
2422
|
+
];
|
|
2423
|
+
}
|
|
2382
2424
|
function sandboxArgv(command, opts) {
|
|
2383
2425
|
if (opts.platform === "darwin") {
|
|
2384
2426
|
return ["sandbox-exec", "-p", darwinProfile(opts.cwd, opts.network), "/bin/bash", "-c", command];
|
|
2385
2427
|
}
|
|
2386
2428
|
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
|
-
];
|
|
2429
|
+
return bwrapArgv(opts.cwd, opts.network, command);
|
|
2409
2430
|
}
|
|
2410
2431
|
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
|
-
];
|
|
2432
|
+
return ["wsl.exe", "--", ...bwrapArgv(winPathToWsl(opts.cwd), opts.network, command)];
|
|
2436
2433
|
}
|
|
2437
2434
|
return void 0;
|
|
2438
2435
|
}
|
|
@@ -2472,7 +2469,7 @@ function killAllCommands() {
|
|
|
2472
2469
|
}
|
|
2473
2470
|
var backgrounds = /* @__PURE__ */ new Map();
|
|
2474
2471
|
var nextBackgroundId = 1;
|
|
2475
|
-
function startBackground(command, cwd, env, shell) {
|
|
2472
|
+
function startBackground(command, cwd, env, shell, maxRetained) {
|
|
2476
2473
|
const child = spawnChild(command, cwd, env, shell);
|
|
2477
2474
|
const task = {
|
|
2478
2475
|
id: nextBackgroundId++,
|
|
@@ -2493,6 +2490,10 @@ function startBackground(command, cwd, env, shell) {
|
|
|
2493
2490
|
if (child.pid !== void 0) killProcessTree(child.pid);
|
|
2494
2491
|
};
|
|
2495
2492
|
backgrounds.set(task.id, task);
|
|
2493
|
+
for (const [id, other] of backgrounds) {
|
|
2494
|
+
if (backgrounds.size <= maxRetained) break;
|
|
2495
|
+
if (id !== task.id && other.status === "exited") backgrounds.delete(id);
|
|
2496
|
+
}
|
|
2496
2497
|
const onData = (data) => {
|
|
2497
2498
|
let s = data;
|
|
2498
2499
|
if (task.head.length < HALF) {
|
|
@@ -2691,6 +2692,7 @@ var SHELL_NOTE = {
|
|
|
2691
2692
|
function createBashTool(options = {}) {
|
|
2692
2693
|
const offline = options.networkPolicy === "offline";
|
|
2693
2694
|
const sandbox = options.sandbox === true;
|
|
2695
|
+
const maxRetained = options.maxRetainedTasks ?? 50;
|
|
2694
2696
|
const platform = options.platform ?? process.platform;
|
|
2695
2697
|
const shell = resolveShell({ platform, env: process.env, exists: existsSync3, ...options.shellDeps });
|
|
2696
2698
|
const childEnv = offline ? offlineEnv() : void 0;
|
|
@@ -2737,7 +2739,7 @@ Network access is off (networkPolicy "offline"): internet commands such as curl,
|
|
|
2737
2739
|
}
|
|
2738
2740
|
if (input.background) {
|
|
2739
2741
|
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);
|
|
2742
|
+
const task = startBackground(exec, ctx.cwd, childEnv, shell, maxRetained);
|
|
2741
2743
|
return {
|
|
2742
2744
|
output: `Background task #${task.id} started: ${input.command}
|
|
2743
2745
|
Poll it with {task_id: ${task.id}}; stop it with {task_id: ${task.id}, kill: true}.`
|
|
@@ -3607,6 +3609,12 @@ async function readTextResult(input, buffer) {
|
|
|
3607
3609
|
const lines = buffer.toString("utf8").split(/\r?\n/);
|
|
3608
3610
|
const start = (input.offset ?? 1) - 1;
|
|
3609
3611
|
const limit = input.limit ?? 2e3;
|
|
3612
|
+
if (start >= lines.length) {
|
|
3613
|
+
return {
|
|
3614
|
+
output: `offset ${input.offset} is past the end of ${input.path} (${lines.length} line(s)); start at 1.`,
|
|
3615
|
+
isError: true
|
|
3616
|
+
};
|
|
3617
|
+
}
|
|
3610
3618
|
const requested = lines.slice(start, start + limit);
|
|
3611
3619
|
const shown = [];
|
|
3612
3620
|
let size = 0;
|
|
@@ -3688,7 +3696,9 @@ var writeTool = defineTool({
|
|
|
3688
3696
|
target: (input) => input.path,
|
|
3689
3697
|
async validate(input, ctx) {
|
|
3690
3698
|
const abs = resolvePath(ctx.cwd, input.path);
|
|
3691
|
-
|
|
3699
|
+
if (existsSync4(abs) && !ctx.readFiles.has(abs)) return `${input.path} already exists. Read it with read before overwriting it.`;
|
|
3700
|
+
if (isFileModifiedSinceRead(ctx.readFiles, abs)) return `${input.path} has been modified since it was last read. Read it again before overwriting it.`;
|
|
3701
|
+
return void 0;
|
|
3692
3702
|
},
|
|
3693
3703
|
async preview(input, ctx) {
|
|
3694
3704
|
const abs = resolvePath(ctx.cwd, input.path);
|
|
@@ -3700,6 +3710,9 @@ var writeTool = defineTool({
|
|
|
3700
3710
|
if (existsSync4(abs) && !ctx.readFiles.has(abs)) {
|
|
3701
3711
|
return { output: `${input.path} already exists. Read it with read before overwriting it.`, isError: true };
|
|
3702
3712
|
}
|
|
3713
|
+
if (isFileModifiedSinceRead(ctx.readFiles, abs)) {
|
|
3714
|
+
return { output: `${input.path} has been modified since it was last read. Read it again before overwriting it.`, isError: true };
|
|
3715
|
+
}
|
|
3703
3716
|
try {
|
|
3704
3717
|
await ctx.checkpoint?.(abs);
|
|
3705
3718
|
await mkdir(dirname4(abs), { recursive: true });
|
|
@@ -3809,7 +3822,9 @@ function budgetStatus(usage, cap, model) {
|
|
|
3809
3822
|
if (cap.usd !== void 0) {
|
|
3810
3823
|
const price = priceFor(cap, model);
|
|
3811
3824
|
if (price) {
|
|
3812
|
-
const
|
|
3825
|
+
const cached = Math.max(0, Math.min(usage.cachedInputTokens ?? 0, usage.inputTokens));
|
|
3826
|
+
const cachedRate = price.cachedInput ?? price.input;
|
|
3827
|
+
const usd = ((usage.inputTokens - cached) * price.input + cached * cachedRate + usage.outputTokens * price.output) / 1e6;
|
|
3813
3828
|
if (usd >= cap.usd) return { kind: "usd", used: usd, limit: cap.usd };
|
|
3814
3829
|
}
|
|
3815
3830
|
}
|
|
@@ -4999,7 +5014,7 @@ async function addProviderKey(providerId, key, deps) {
|
|
|
4999
5014
|
// src/session.ts
|
|
5000
5015
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
5001
5016
|
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";
|
|
5017
|
+
import { basename as basename3, dirname as dirname8, join as join10 } from "path";
|
|
5003
5018
|
function projectDir(home, cwd) {
|
|
5004
5019
|
const slug = cwd.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(-100) || "root";
|
|
5005
5020
|
return join10(home, "sessions", slug);
|
|
@@ -5025,7 +5040,6 @@ var Session = class _Session {
|
|
|
5025
5040
|
}
|
|
5026
5041
|
static create(home, cwd, now = /* @__PURE__ */ new Date()) {
|
|
5027
5042
|
const dir = projectDir(home, cwd);
|
|
5028
|
-
mkdirSync4(dir, { recursive: true });
|
|
5029
5043
|
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
5030
5044
|
return new _Session(join10(dir, `${stamp}-${randomBytes2(3).toString("hex")}.jsonl`));
|
|
5031
5045
|
}
|
|
@@ -5042,6 +5056,7 @@ var Session = class _Session {
|
|
|
5042
5056
|
return _Session.list(home, cwd)[0]?.session;
|
|
5043
5057
|
}
|
|
5044
5058
|
write(record) {
|
|
5059
|
+
mkdirSync4(dirname8(this.file), { recursive: true });
|
|
5045
5060
|
appendFileSync(this.file, `${JSON.stringify(record)}
|
|
5046
5061
|
`);
|
|
5047
5062
|
}
|
|
@@ -6074,6 +6089,15 @@ function loadPlugins(specs, opts) {
|
|
|
6074
6089
|
|
|
6075
6090
|
// src/setup.ts
|
|
6076
6091
|
var TOOL_RULES = { bash: "bash", edit: "edit", write: "edit", fetch: "fetch" };
|
|
6092
|
+
var pluginCache = /* @__PURE__ */ new Map();
|
|
6093
|
+
function loadPluginsOnce(specs, opts) {
|
|
6094
|
+
const key = JSON.stringify({ specs, home: opts.home, cwd: opts.cwd });
|
|
6095
|
+
const cached = pluginCache.get(key);
|
|
6096
|
+
if (cached) return cached;
|
|
6097
|
+
const loaded = loadPlugins(specs, opts);
|
|
6098
|
+
pluginCache.set(key, loaded);
|
|
6099
|
+
return loaded;
|
|
6100
|
+
}
|
|
6077
6101
|
function lunaPtcAutoEnabled(env) {
|
|
6078
6102
|
const value = String(env.BCCLI_LUNA_PTC ?? "").trim().toLowerCase();
|
|
6079
6103
|
return !["0", "false", "off", "no"].includes(value);
|
|
@@ -6081,6 +6105,7 @@ function lunaPtcAutoEnabled(env) {
|
|
|
6081
6105
|
function createRuntime(opts) {
|
|
6082
6106
|
const env = opts.env ?? process.env;
|
|
6083
6107
|
const home = bccliHome(env);
|
|
6108
|
+
const persistSession = opts.persistSession !== false;
|
|
6084
6109
|
let config = loadConfig(opts.cwd, env);
|
|
6085
6110
|
let modelRef = opts.args.model ?? config.model;
|
|
6086
6111
|
let reasoning = opts.args.reasoning ?? config.reasoning;
|
|
@@ -6169,7 +6194,7 @@ function createRuntime(opts) {
|
|
|
6169
6194
|
createRepoMapTool()
|
|
6170
6195
|
];
|
|
6171
6196
|
if (config.lsp?.servers.length) baseTools.push(createDiagnosticsTool(config.lsp.servers));
|
|
6172
|
-
const plugins =
|
|
6197
|
+
const plugins = loadPluginsOnce(config.plugins ?? [], {
|
|
6173
6198
|
home,
|
|
6174
6199
|
cwd: opts.cwd,
|
|
6175
6200
|
env,
|
|
@@ -6207,9 +6232,15 @@ function createRuntime(opts) {
|
|
|
6207
6232
|
usageCap: config.usageCap,
|
|
6208
6233
|
budgetModel: modelRef,
|
|
6209
6234
|
contextWindow: contextWindowFor(modelRef, env),
|
|
6210
|
-
onMessage: (m) =>
|
|
6211
|
-
|
|
6212
|
-
|
|
6235
|
+
onMessage: (m) => {
|
|
6236
|
+
if (persistSession) session.append(m);
|
|
6237
|
+
},
|
|
6238
|
+
onUsage: (u) => {
|
|
6239
|
+
if (persistSession) session.appendUsage({ ...u, model: modelRef });
|
|
6240
|
+
},
|
|
6241
|
+
onReset: () => {
|
|
6242
|
+
if (persistSession) session.reset();
|
|
6243
|
+
},
|
|
6213
6244
|
onTurnStart: () => {
|
|
6214
6245
|
for (let i = turnMarks.length - 1; i >= 0 && turnMarks[i] > agent.messages.length; i--) {
|
|
6215
6246
|
turnMarks.splice(i, 1);
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
createFetchTool,
|
|
4
4
|
createWebSearchTool,
|
|
5
5
|
isPrivateHost
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-6KZIOICR.js";
|
|
7
7
|
import "./chunk-PSO7R5AD.js";
|
|
8
8
|
import {
|
|
9
9
|
loadConfig,
|
|
10
10
|
readCredentials
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-C2FUGQJX.js";
|
|
12
12
|
import {
|
|
13
13
|
t
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-G5TG43R4.js";
|
|
15
15
|
|
|
16
16
|
// src/mcpServer/serve.ts
|
|
17
17
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createRuntime
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6BXW7DGQ.js";
|
|
5
5
|
import "./chunk-OK2USAXX.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-OAXD3X4R.js";
|
|
7
|
+
import "./chunk-6KZIOICR.js";
|
|
8
8
|
import "./chunk-PSO7R5AD.js";
|
|
9
9
|
import {
|
|
10
10
|
VERSION
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-N6APAYSF.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-WSZF2CTU.js";
|
|
21
|
+
import "./chunk-YYTFJUO2.js";
|
|
22
|
+
import "./chunk-JFYQCPXL.js";
|
|
23
23
|
import {
|
|
24
24
|
listAllModels
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-Y6AZGGH7.js";
|
|
26
|
+
import "./chunk-X24APPXO.js";
|
|
27
|
+
import "./chunk-IHQGXDSG.js";
|
|
28
28
|
import {
|
|
29
29
|
Session
|
|
30
|
-
} from "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
-
import "./chunk-
|
|
30
|
+
} from "./chunk-F54FDJBD.js";
|
|
31
|
+
import "./chunk-OOOS5RCT.js";
|
|
32
|
+
import "./chunk-XZ2TI5HV.js";
|
|
33
|
+
import "./chunk-2DFY43RP.js";
|
|
34
34
|
import {
|
|
35
35
|
bccliHome,
|
|
36
36
|
loadConfig
|
|
37
|
-
} from "./chunk-
|
|
38
|
-
import "./chunk-
|
|
37
|
+
} from "./chunk-C2FUGQJX.js";
|
|
38
|
+
import "./chunk-G5TG43R4.js";
|
|
39
39
|
|
|
40
40
|
// src/serve.ts
|
|
41
41
|
import { randomBytes } from "crypto";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createRuntime,
|
|
4
|
+
lunaPtcAutoEnabled
|
|
5
|
+
} from "./chunk-6BXW7DGQ.js";
|
|
6
|
+
import "./chunk-OK2USAXX.js";
|
|
7
|
+
import "./chunk-OAXD3X4R.js";
|
|
8
|
+
import "./chunk-6KZIOICR.js";
|
|
9
|
+
import "./chunk-PSO7R5AD.js";
|
|
10
|
+
import "./chunk-YYTFJUO2.js";
|
|
11
|
+
import "./chunk-JFYQCPXL.js";
|
|
12
|
+
import "./chunk-Y6AZGGH7.js";
|
|
13
|
+
import "./chunk-X24APPXO.js";
|
|
14
|
+
import "./chunk-IHQGXDSG.js";
|
|
15
|
+
import "./chunk-F54FDJBD.js";
|
|
16
|
+
import "./chunk-OOOS5RCT.js";
|
|
17
|
+
import "./chunk-XZ2TI5HV.js";
|
|
18
|
+
import "./chunk-2DFY43RP.js";
|
|
19
|
+
import "./chunk-C2FUGQJX.js";
|
|
20
|
+
import "./chunk-G5TG43R4.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-G5TG43R4.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>;
|