@botconnector/bccli 0.4.9 → 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.
Files changed (55) hide show
  1. package/dist/{acp-VEXFXT5P.js → acp-IPHWC6CO.js} +20 -5
  2. package/dist/acp.d.ts +17 -1
  3. package/dist/args-K5AJFDCZ.js +13 -0
  4. package/dist/args.d.ts +6 -0
  5. package/dist/budget.d.ts +4 -1
  6. package/dist/{chunk-2YG6L3YO.js → chunk-2DFY43RP.js} +2 -2
  7. package/dist/{chunk-KREGVQ63.js → chunk-6BXW7DGQ.js} +47 -18
  8. package/dist/{chunk-WSSJH765.js → chunk-6KZIOICR.js} +1 -1
  9. package/dist/{chunk-OUJRD7GG.js → chunk-6M5T7N7A.js} +8 -3
  10. package/dist/{chunk-DRJSANKH.js → chunk-C2FUGQJX.js} +9 -7
  11. package/dist/{chunk-OETLWNGS.js → chunk-F54FDJBD.js} +3 -3
  12. package/dist/{chunk-XCVYR5BK.js → chunk-G5TG43R4.js} +15 -1
  13. package/dist/{chunk-RRECJTOG.js → chunk-IHQGXDSG.js} +1 -1
  14. package/dist/{chunk-AWBEZY4D.js → chunk-JFYQCPXL.js} +7 -5
  15. package/dist/{chunk-6H6MPG7L.js → chunk-MBAMDCCV.js} +23 -9
  16. package/dist/{chunk-HCW67S5M.js → chunk-N6APAYSF.js} +1 -1
  17. package/dist/{chunk-TLCFBQ6E.js → chunk-NT2G5FSX.js} +2 -2
  18. package/dist/{chunk-CSIQDFEF.js → chunk-OAXD3X4R.js} +34 -50
  19. package/dist/{chunk-EOJNFGOP.js → chunk-OOOS5RCT.js} +98 -28
  20. package/dist/{chunk-Z2ELYJ5O.js → chunk-WSZF2CTU.js} +11 -4
  21. package/dist/{chunk-62UTSCWF.js → chunk-X24APPXO.js} +1 -1
  22. package/dist/{chunk-EAR2C6TS.js → chunk-XZ2TI5HV.js} +1 -1
  23. package/dist/{chunk-HPYI7L4W.js → chunk-Y6AZGGH7.js} +4 -4
  24. package/dist/{chunk-WFZKJY3R.js → chunk-YYTFJUO2.js} +3 -2
  25. package/dist/cli.js +40 -40
  26. package/dist/{completion-FETH4OGC.js → completion-QVDGAYUY.js} +1 -1
  27. package/dist/{config-KR5JI5RA.js → config-7TQ2KVVX.js} +3 -3
  28. package/dist/{config-RVMC23W3.js → config-RZY3XQZJ.js} +2 -2
  29. package/dist/{ghBotCli-Z6GWXCJ6.js → ghBotCli-HHJ4ANTH.js} +18 -16
  30. package/dist/{integrationCli-GPRR6J6W.js → integrationCli-LNNZDGZX.js} +40 -5
  31. package/dist/{login-DFSN77L3.js → login-MQEZGF2C.js} +6 -4
  32. package/dist/login.d.ts +2 -0
  33. package/dist/{mcpCli-64P3SVUE.js → mcpCli-CUIOYJ2A.js} +22 -7
  34. package/dist/{modelsCli-PFQY3G2Q.js → modelsCli-AAFHFI4H.js} +6 -6
  35. package/dist/{oauthLogin-NR22NWEV.js → oauthLogin-YFL2N4QA.js} +1 -1
  36. package/dist/{pluginsCli-UKRJ3AHN.js → pluginsCli-2QXXFLQA.js} +6 -2
  37. package/dist/{prCli-6FCI36AJ.js → prCli-KSA73RCS.js} +1 -1
  38. package/dist/print.d.ts +1 -0
  39. package/dist/providerCli-TXMVPSW5.js +15 -0
  40. package/dist/sdk.js +196 -87
  41. package/dist/{serve-PKUTKQQT.js → serve-EIQHEUYD.js} +3 -3
  42. package/dist/{serve-JYXPQAVY.js → serve-QYDBFTHC.js} +16 -16
  43. package/dist/session-CQCQ7KAP.js +12 -0
  44. package/dist/setup-DBSGMWHM.js +24 -0
  45. package/dist/setup.d.ts +5 -0
  46. package/dist/{statsCli-FR7GOKWO.js → statsCli-EHNJIQ2Z.js} +2 -2
  47. package/dist/tools/bash.d.ts +2 -0
  48. package/dist/{transferCli-GIE4MEJ4.js → transferCli-IXJ2O74Q.js} +4 -4
  49. package/dist/{ui-NZVOCQSU.js → ui-A2LASWDK.js} +14 -14
  50. package/dist/{update-DIYDD7LT.js → update-TR62JV3A.js} +2 -2
  51. package/package.json +1 -1
  52. package/dist/args-6XMUZDAK.js +0 -13
  53. package/dist/providerCli-PBSZECBM.js +0 -15
  54. package/dist/session-XABMBIIF.js +0 -12
  55. package/dist/setup-CLPQLTM7.js +0 -24
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/version.ts
4
- var VERSION = true ? "0.4.9" : "0.0.0-dev";
4
+ var VERSION = true ? "0.4.11" : "0.0.0-dev";
5
5
 
6
6
  export {
7
7
  VERSION
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigError
4
- } from "./chunk-DRJSANKH.js";
4
+ } from "./chunk-C2FUGQJX.js";
5
5
  import {
6
6
  t
7
- } from "./chunk-XCVYR5BK.js";
7
+ } from "./chunk-G5TG43R4.js";
8
8
 
9
9
  // src/mcp/catalog.ts
10
10
  var CATALOG = [
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-PSO7R5AD.js";
5
5
  import {
6
6
  t
7
- } from "./chunk-XCVYR5BK.js";
7
+ } from "./chunk-G5TG43R4.js";
8
8
 
9
9
  // src/tools/bash.ts
10
10
  import { spawn } from "child_process";
@@ -34,60 +34,39 @@ function darwinProfile(cwd, network) {
34
34
  network ? "(allow network*)" : "(deny network*)"
35
35
  ].join("\n");
36
36
  }
37
+ function bwrapArgv(cwd, network, command) {
38
+ return [
39
+ "bwrap",
40
+ "--ro-bind",
41
+ "/",
42
+ "/",
43
+ "--dev-bind",
44
+ "/dev",
45
+ "/dev",
46
+ "--proc",
47
+ "/proc",
48
+ "--bind",
49
+ cwd,
50
+ cwd,
51
+ "--tmpfs",
52
+ "/tmp",
53
+ "--die-with-parent",
54
+ ...network ? [] : ["--unshare-net"],
55
+ "--",
56
+ "/bin/bash",
57
+ "-c",
58
+ command
59
+ ];
60
+ }
37
61
  function sandboxArgv(command, opts) {
38
62
  if (opts.platform === "darwin") {
39
63
  return ["sandbox-exec", "-p", darwinProfile(opts.cwd, opts.network), "/bin/bash", "-c", command];
40
64
  }
41
65
  if (opts.platform === "linux") {
42
- return [
43
- "bwrap",
44
- "--ro-bind",
45
- "/",
46
- "/",
47
- "--dev-bind",
48
- "/dev",
49
- "/dev",
50
- "--proc",
51
- "/proc",
52
- "--bind",
53
- opts.cwd,
54
- opts.cwd,
55
- "--tmpfs",
56
- "/tmp",
57
- "--die-with-parent",
58
- ...opts.network ? [] : ["--unshare-net"],
59
- "--",
60
- "/bin/bash",
61
- "-c",
62
- command
63
- ];
66
+ return bwrapArgv(opts.cwd, opts.network, command);
64
67
  }
65
68
  if (opts.platform === "win32" && (opts.wslBwrap || process.env.BCCLI_WIN32_WSL_SANDBOX === "1")) {
66
- const wslCwd = winPathToWsl(opts.cwd);
67
- return [
68
- "wsl.exe",
69
- "--",
70
- "bwrap",
71
- "--ro-bind",
72
- "/",
73
- "/",
74
- "--dev-bind",
75
- "/dev",
76
- "/dev",
77
- "--proc",
78
- "/proc",
79
- "--bind",
80
- wslCwd,
81
- wslCwd,
82
- "--tmpfs",
83
- "/tmp",
84
- "--die-with-parent",
85
- ...opts.network ? [] : ["--unshare-net"],
86
- "--",
87
- "/bin/bash",
88
- "-c",
89
- command
90
- ];
69
+ return ["wsl.exe", "--", ...bwrapArgv(winPathToWsl(opts.cwd), opts.network, command)];
91
70
  }
92
71
  return void 0;
93
72
  }
@@ -156,7 +135,7 @@ function killAllCommands() {
156
135
  }
157
136
  var backgrounds = /* @__PURE__ */ new Map();
158
137
  var nextBackgroundId = 1;
159
- function startBackground(command, cwd, env, shell) {
138
+ function startBackground(command, cwd, env, shell, maxRetained) {
160
139
  const child = spawnChild(command, cwd, env, shell);
161
140
  const task = {
162
141
  id: nextBackgroundId++,
@@ -177,6 +156,10 @@ function startBackground(command, cwd, env, shell) {
177
156
  if (child.pid !== void 0) killProcessTree(child.pid);
178
157
  };
179
158
  backgrounds.set(task.id, task);
159
+ for (const [id, other] of backgrounds) {
160
+ if (backgrounds.size <= maxRetained) break;
161
+ if (id !== task.id && other.status === "exited") backgrounds.delete(id);
162
+ }
180
163
  const onData = (data) => {
181
164
  let s = data;
182
165
  if (task.head.length < HALF) {
@@ -385,6 +368,7 @@ var SHELL_NOTE = {
385
368
  function createBashTool(options = {}) {
386
369
  const offline = options.networkPolicy === "offline";
387
370
  const sandbox = options.sandbox === true;
371
+ const maxRetained = options.maxRetainedTasks ?? 50;
388
372
  const platform = options.platform ?? process.platform;
389
373
  const shell = resolveShell({ platform, env: process.env, exists: existsSync2, ...options.shellDeps });
390
374
  const childEnv = offline ? offlineEnv() : void 0;
@@ -431,7 +415,7 @@ Network access is off (networkPolicy "offline"): internet commands such as curl,
431
415
  }
432
416
  if (input.background) {
433
417
  if (!input.command) return { output: 'The "command" argument is required to start a background task.', isError: true };
434
- const task = startBackground(exec, ctx.cwd, childEnv, shell);
418
+ const task = startBackground(exec, ctx.cwd, childEnv, shell, maxRetained);
435
419
  return {
436
420
  output: `Background task #${task.id} started: ${input.command}
437
421
  Poll it with {task_id: ${task.id}}; stop it with {task_id: ${task.id}, kill: true}.`
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  reasoningPayload
4
- } from "./chunk-EAR2C6TS.js";
4
+ } from "./chunk-XZ2TI5HV.js";
5
5
  import {
6
6
  t
7
- } from "./chunk-XCVYR5BK.js";
7
+ } from "./chunk-G5TG43R4.js";
8
8
 
9
9
  // src/provider.ts
10
10
  import OpenAI from "openai";
@@ -78,6 +78,17 @@ function outputReasoningSummary(items) {
78
78
  }).map((part) => part && typeof part === "object" && "text" in part && typeof part.text === "string" ? part.text : "").filter(Boolean).join("\n");
79
79
  }
80
80
  var retryable = (status) => status === 429 || status >= 500;
81
+ function httpIdleMs() {
82
+ const raw = Number(process.env.BCCLI_HTTP_IDLE_TIMEOUT_MS);
83
+ return Number.isFinite(raw) && raw > 0 ? raw : 6e4;
84
+ }
85
+ function statusHint(status) {
86
+ if (status === 401 || status === 403) return t("The API key was rejected. Check the key for this provider (bccli login) or its API key environment variable.");
87
+ if (status === 404) return t("Model or endpoint not found. Check the model name and the provider base URL.");
88
+ if (status === 429) return t("Rate limit reached. Wait a moment, or switch model with /model.");
89
+ if (status >= 500) return t("The provider is having trouble. Try again, or switch model with /model.");
90
+ return void 0;
91
+ }
81
92
  function detectRepetition(text) {
82
93
  const tail = text.slice(-600);
83
94
  for (let len = 1; len <= 12; len++) {
@@ -120,7 +131,7 @@ var toUsage = (u) => u ? {
120
131
  ...u.prompt_tokens_details?.cached_tokens != null ? { cachedInputTokens: u.prompt_tokens_details.cached_tokens } : {},
121
132
  ...u.prompt_tokens_details?.cache_write_tokens != null ? { cacheWriteTokens: u.prompt_tokens_details.cache_write_tokens } : {}
122
133
  } : void 0;
123
- async function readStream(res, onText, onThinking) {
134
+ async function readStream(res, onText, onThinking, signal) {
124
135
  let text = "";
125
136
  let thinking = "";
126
137
  const splitter = new ThinkSplitter();
@@ -137,6 +148,7 @@ async function readStream(res, onText, onThinking) {
137
148
  };
138
149
  let usage;
139
150
  let finishReason;
151
+ let sawDone = false;
140
152
  const calls = [];
141
153
  const byIndex = /* @__PURE__ */ new Map();
142
154
  let current;
@@ -146,7 +158,11 @@ async function readStream(res, onText, onThinking) {
146
158
  const handle = (line) => {
147
159
  if (!line.startsWith("data:")) return;
148
160
  const data = line.slice(5).trim();
149
- if (!data || data === "[DONE]") return;
161
+ if (!data) return;
162
+ if (data === "[DONE]") {
163
+ sawDone = true;
164
+ return;
165
+ }
150
166
  let event;
151
167
  try {
152
168
  event = JSON.parse(data);
@@ -175,18 +191,45 @@ async function readStream(res, onText, onThinking) {
175
191
  if (tc.function?.arguments) target.arguments += tc.function.arguments;
176
192
  }
177
193
  };
178
- for await (const chunk of res.body) {
179
- buffer += decoder.decode(chunk, { stream: true });
180
- let newline = buffer.indexOf("\n");
181
- while (newline >= 0 && loopAt < 0) {
182
- handle(buffer.slice(0, newline).trim());
183
- buffer = buffer.slice(newline + 1);
184
- newline = buffer.indexOf("\n");
185
- }
186
- if (loopAt >= 0) return { text: text.slice(0, loopAt), toolCalls: [], thinking: thinking || void 0, usage, finishReason: "repetition" };
194
+ const iterator = res.body[Symbol.asyncIterator]();
195
+ const idle = httpIdleMs();
196
+ const onAbort = () => void iterator.return?.();
197
+ if (signal?.aborted) onAbort();
198
+ else signal?.addEventListener("abort", onAbort);
199
+ try {
200
+ for (; ; ) {
201
+ let timer;
202
+ const stalled = new Promise((_, reject) => {
203
+ timer = setTimeout(
204
+ () => reject(new ProviderError(t("The provider stopped sending data for {seconds}s. The answer above may be incomplete; try again.", { seconds: String(Math.round(idle / 1e3)) }))),
205
+ idle
206
+ );
207
+ });
208
+ let step;
209
+ try {
210
+ step = await Promise.race([iterator.next(), stalled]);
211
+ } finally {
212
+ if (timer) clearTimeout(timer);
213
+ }
214
+ if (step.done) break;
215
+ buffer += decoder.decode(step.value, { stream: true });
216
+ let newline = buffer.indexOf("\n");
217
+ while (newline >= 0 && loopAt < 0) {
218
+ handle(buffer.slice(0, newline).trim());
219
+ buffer = buffer.slice(newline + 1);
220
+ newline = buffer.indexOf("\n");
221
+ }
222
+ if (loopAt >= 0) return { text: text.slice(0, loopAt), toolCalls: [], thinking: thinking || void 0, usage, finishReason: "repetition" };
223
+ }
224
+ } finally {
225
+ signal?.removeEventListener("abort", onAbort);
226
+ void iterator.return?.();
187
227
  }
188
228
  handle(buffer.trim());
189
229
  emit(splitter.flush());
230
+ if (!sawDone && !finishReason) {
231
+ throw new ProviderError(t("The response ended before it finished (no finish_reason or [DONE]). The answer above is incomplete; try again."));
232
+ }
190
233
  const toolCalls = calls.map((call, index) => ({ ...call, id: call.id || `call_${index}` }));
191
234
  return { text, toolCalls, thinking: thinking || void 0, usage, finishReason };
192
235
  }
@@ -397,7 +440,7 @@ function hasPendingProgrammaticReplay(messages) {
397
440
  }
398
441
  return pending;
399
442
  }
400
- async function readResponsesStream(res, onText, onThinking) {
443
+ async function readResponsesStream(res, onText, onThinking, signal) {
401
444
  let text = "";
402
445
  let thinking = "";
403
446
  let usage;
@@ -499,17 +542,28 @@ async function readResponsesStream(res, onText, onThinking) {
499
542
  );
500
543
  }
501
544
  };
502
- for await (const chunk of res.body) {
503
- buffer += decoder.decode(chunk, { stream: true });
504
- let newline = buffer.indexOf("\n");
505
- while (newline >= 0 && loopAt < 0) {
506
- handle(buffer.slice(0, newline).trim());
507
- buffer = buffer.slice(newline + 1);
508
- newline = buffer.indexOf("\n");
509
- }
510
- if (loopAt >= 0) {
511
- return { text: text.slice(0, loopAt), toolCalls: [], usage, finishReason: "repetition" };
545
+ const iterator = res.body[Symbol.asyncIterator]();
546
+ const onAbort = () => void iterator.return?.();
547
+ if (signal?.aborted) onAbort();
548
+ else signal?.addEventListener("abort", onAbort);
549
+ try {
550
+ for (; ; ) {
551
+ const step = await iterator.next();
552
+ if (step.done) break;
553
+ buffer += decoder.decode(step.value, { stream: true });
554
+ let newline = buffer.indexOf("\n");
555
+ while (newline >= 0 && loopAt < 0) {
556
+ handle(buffer.slice(0, newline).trim());
557
+ buffer = buffer.slice(newline + 1);
558
+ newline = buffer.indexOf("\n");
559
+ }
560
+ if (loopAt >= 0) {
561
+ return { text: text.slice(0, loopAt), toolCalls: [], usage, finishReason: "repetition" };
562
+ }
512
563
  }
564
+ } finally {
565
+ signal?.removeEventListener("abort", onAbort);
566
+ void iterator.return?.();
513
567
  }
514
568
  handle(buffer.trim());
515
569
  return {
@@ -882,12 +936,26 @@ function createProvider(options) {
882
936
  await sleep(delay, signal);
883
937
  }
884
938
  let res;
939
+ const idleAbort = new AbortController();
940
+ const forwardAbort = () => idleAbort.abort(signal?.reason);
941
+ if (signal?.aborted) forwardAbort();
942
+ else signal?.addEventListener("abort", forwardAbort);
943
+ const idle = httpIdleMs();
944
+ const headerTimer = setTimeout(() => idleAbort.abort(new Error("idle-timeout")), idle);
885
945
  try {
886
- res = await doFetch(`${baseURL}${path}`, { method: "POST", headers, body: JSON.stringify(body), signal });
946
+ res = await doFetch(`${baseURL}${path}`, { method: "POST", headers, body: JSON.stringify(body), signal: idleAbort.signal });
887
947
  } catch (error) {
888
948
  if (signal?.aborted) throw error;
949
+ if (idleAbort.signal.aborted) {
950
+ throw new ProviderError(
951
+ t("The provider did not respond within {seconds}s. Check the connection, then try again.", { seconds: String(Math.round(idle / 1e3)) })
952
+ );
953
+ }
889
954
  lastError = new ProviderError(t("Cannot connect to {url}: {error}", { url: baseURL, error: error.message }));
890
955
  continue;
956
+ } finally {
957
+ clearTimeout(headerTimer);
958
+ signal?.removeEventListener("abort", forwardAbort);
891
959
  }
892
960
  if (res.ok) return res;
893
961
  const retryHeader = res.headers.get("retry-after");
@@ -896,7 +964,9 @@ function createProvider(options) {
896
964
  if (Number.isFinite(secs) && secs > 0 && secs <= 30) retryAfterWaitMs = Math.ceil(secs * 1e3);
897
965
  }
898
966
  const text = await res.text().catch(() => "");
899
- lastError = new ProviderError(t("{status} from {url}: {message}", { status: res.status, url: baseURL, message: errorMessage(text) }), res.status);
967
+ const raw = t("{status} from {url}: {message}", { status: res.status, url: baseURL, message: errorMessage(text) });
968
+ const hint = statusHint(res.status);
969
+ lastError = new ProviderError(hint ? `${hint} (${raw})` : raw, res.status);
900
970
  const deterministicQuota429 = res.status === 429 && /"code"\s*:\s*"(?:luna_monthly_quota_exhausted|plan_allowance_exhausted)"/i.test(text);
901
971
  if (!retryable(res.status) || deterministicQuota429) throw lastError;
902
972
  }
@@ -937,7 +1007,7 @@ function createProvider(options) {
937
1007
  );
938
1008
  if ((res2.headers.get("content-type") ?? "").includes("application/json")) return readResponsesJson(res2, onThinking);
939
1009
  if (!res2.body) throw new ProviderError(t("Empty response from the provider"));
940
- return readResponsesStream(res2, onText, onThinking);
1010
+ return readResponsesStream(res2, onText, onThinking, signal);
941
1011
  }
942
1012
  const res = await post(
943
1013
  "/chat/completions",
@@ -946,7 +1016,7 @@ function createProvider(options) {
946
1016
  );
947
1017
  if ((res.headers.get("content-type") ?? "").includes("application/json")) return readJson(res, onText, onThinking);
948
1018
  if (!res.body) throw new ProviderError(t("Empty response from the provider"));
949
- return readStream(res, onText, onThinking);
1019
+ return readStream(res, onText, onThinking, signal);
950
1020
  },
951
1021
  async listModels() {
952
1022
  const res = await doFetch(`${baseURL}/models`, { headers });
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  MODE_ORDER
4
- } from "./chunk-WFZKJY3R.js";
4
+ } from "./chunk-YYTFJUO2.js";
5
5
  import {
6
6
  REASONING_LEVELS,
7
7
  isReasoningLevel
8
- } from "./chunk-EAR2C6TS.js";
8
+ } from "./chunk-XZ2TI5HV.js";
9
9
  import {
10
10
  ConfigError
11
- } from "./chunk-DRJSANKH.js";
11
+ } from "./chunk-C2FUGQJX.js";
12
12
  import {
13
13
  parseLang,
14
14
  t
15
- } from "./chunk-XCVYR5BK.js";
15
+ } from "./chunk-G5TG43R4.js";
16
16
 
17
17
  // src/args.ts
18
18
  import { parseArgs } from "util";
@@ -112,6 +112,7 @@ Options:
112
112
  -r, --resume pick a session to continue
113
113
  --allow-all run all tools without asking for permission
114
114
  --allowed-tools <a,b> tools allowed without asking: bash, edit, fetch
115
+ --fail-on-tool-error with -p: exit 1 when any tool call fails (for CI)
115
116
  -w, --worktree <name> run in git worktree ../<repo>.worktrees/<name> (created, or reused if it exists)
116
117
  --output-format <fmt> text | json | stream-json for -p (machine-readable output)
117
118
  --permission-mode <mode> default | acceptEdits | plan | allowAll
@@ -137,6 +138,9 @@ function parseCliArgs(argv) {
137
138
  continue: { type: "boolean", short: "c" },
138
139
  resume: { type: "boolean", short: "r" },
139
140
  "allow-all": { type: "boolean" },
141
+ command: { type: "string" },
142
+ args: { type: "string" },
143
+ "fail-on-tool-error": { type: "boolean" },
140
144
  "allowed-tools": { type: "string" },
141
145
  worktree: { type: "string", short: "w" },
142
146
  "output-format": { type: "string" },
@@ -210,6 +214,7 @@ function parseCliArgs(argv) {
210
214
  continue: !!values.continue,
211
215
  resume: !!values.resume,
212
216
  allowAll: !!values["allow-all"],
217
+ failOnToolError: !!values["fail-on-tool-error"],
213
218
  allowedTools: (values["allowed-tools"] ?? "").split(",").map((s) => s.trim()).filter(Boolean),
214
219
  worktree: values.worktree,
215
220
  outputFormat,
@@ -221,6 +226,8 @@ function parseCliArgs(argv) {
221
226
  logout: !!values.logout,
222
227
  subArgs: ["models", "plugins", "gh-bot", "provider", "mcp", "connect", "disconnect", "integrations", "completion", "stats", "export", "import", "pr"].includes(command) ? rest : [],
223
228
  url: values.url,
229
+ stdioCommand: values.command,
230
+ stdioArgs: values.args,
224
231
  name: values.name,
225
232
  keyEnv: values["key-env"],
226
233
  values: values.value ?? [],
@@ -6,7 +6,7 @@ import {
6
6
  readJsonConfig,
7
7
  removeCredential,
8
8
  writeFileAtomic
9
- } from "./chunk-DRJSANKH.js";
9
+ } from "./chunk-C2FUGQJX.js";
10
10
 
11
11
  // src/providers.ts
12
12
  import { join } from "path";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  t
4
- } from "./chunk-XCVYR5BK.js";
4
+ } from "./chunk-G5TG43R4.js";
5
5
 
6
6
  // src/reasoning.ts
7
7
  var REASONING_LEVELS = ["auto", "off", "low", "medium", "high", "max"];
@@ -2,17 +2,17 @@
2
2
  import {
3
3
  hasKey,
4
4
  providerName
5
- } from "./chunk-62UTSCWF.js";
5
+ } from "./chunk-X24APPXO.js";
6
6
  import {
7
7
  createProvider
8
- } from "./chunk-EOJNFGOP.js";
8
+ } from "./chunk-OOOS5RCT.js";
9
9
  import {
10
10
  PRESETS,
11
11
  readCredentials
12
- } from "./chunk-DRJSANKH.js";
12
+ } from "./chunk-C2FUGQJX.js";
13
13
  import {
14
14
  t
15
- } from "./chunk-XCVYR5BK.js";
15
+ } from "./chunk-G5TG43R4.js";
16
16
 
17
17
  // src/models.ts
18
18
  function order(ids) {
@@ -94,7 +94,7 @@ var Permissions = class {
94
94
  }
95
95
  /** Rules that "[a] allow for this session" would add; undefined when it must always be asked. */
96
96
  rulesFor(req) {
97
- if (requiresSensitiveToolApproval(req) && (req.kind === "read" || process.env.BC_TOOL_POLICY_ENFORCE === "true"))
97
+ if (requiresSensitiveToolApproval(req) && (req.kind === "read" || req.kind === "edit" || process.env.BC_TOOL_POLICY_ENFORCE === "true"))
98
98
  return void 0;
99
99
  if (req.kind === "edit") return this.editInProject(req.target) ? ["edit(project)"] : void 0;
100
100
  if (req.kind === "fetch") {
@@ -116,7 +116,8 @@ var Permissions = class {
116
116
  }
117
117
  check(req) {
118
118
  if (this.mode === "plan" && req.kind !== "read") return "deny";
119
- if (req.kind === "read" && this.mode !== "allowAll" && requiresSensitiveToolApproval(req)) return "ask";
119
+ if ((req.kind === "read" || req.kind === "edit") && this.mode !== "allowAll" && requiresSensitiveToolApproval(req))
120
+ return "ask";
120
121
  if (process.env.BC_TOOL_POLICY_ENFORCE === "true" && requiresSensitiveToolApproval(req)) return "ask";
121
122
  if (req.kind === "read") return "allow";
122
123
  if (this.mode === "allowAll") return "allow";