@botconnector/bccli 0.4.0 → 0.4.1

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 (162) hide show
  1. package/README.en.md +13 -2
  2. package/README.md +13 -2
  3. package/dist/abort.d.ts +5 -0
  4. package/dist/{acp-ATIL4JOZ.js → acp-3PHBAI64.js} +2 -2
  5. package/dist/acp.d.ts +27 -0
  6. package/dist/agent.d.ts +143 -0
  7. package/dist/agents.d.ts +4 -0
  8. package/dist/{args-J5ONVGIF.js → args-W6BNKY7K.js} +3 -3
  9. package/dist/args.d.ts +51 -0
  10. package/dist/budget.d.ts +23 -0
  11. package/dist/checkpoints.d.ts +34 -0
  12. package/dist/{chunk-L7QI6JN2.js → chunk-24JN75FZ.js} +6 -6
  13. package/dist/{chunk-XBO5GACQ.js → chunk-75BECX4F.js} +3 -3
  14. package/dist/{chunk-QDQU6VY2.js → chunk-BC7UXFE4.js} +10 -1
  15. package/dist/{chunk-M7CALSP3.js → chunk-BGXNR74O.js} +1 -1
  16. package/dist/{chunk-6M5X2KZE.js → chunk-BKGFA2PT.js} +1 -1
  17. package/dist/{chunk-BNA74HPN.js → chunk-BXQQCUAC.js} +4 -4
  18. package/dist/{chunk-LACUWBWS.js → chunk-FLQPE4S5.js} +21 -9
  19. package/dist/{chunk-JL5ZCSP2.js → chunk-GN4W3T6E.js} +3 -3
  20. package/dist/{chunk-SPRNLS7K.js → chunk-JHPGOAXU.js} +1 -1
  21. package/dist/{chunk-7F3IWBPQ.js → chunk-MFHCQQEN.js} +18 -8
  22. package/dist/{chunk-O7M3TGIW.js → chunk-MHIYLXJC.js} +35 -0
  23. package/dist/{chunk-TVALKHFB.js → chunk-PZRKU4UM.js} +10 -10
  24. package/dist/{chunk-TLPFQIS2.js → chunk-R5RE46CW.js} +2 -2
  25. package/dist/{chunk-BQ2IGPBR.js → chunk-WI22M2ID.js} +1 -1
  26. package/dist/{chunk-PUN4HMAG.js → chunk-WNACAUDK.js} +9 -3
  27. package/dist/{chunk-KEMYIGCP.js → chunk-XV7ZVL4J.js} +2 -2
  28. package/dist/cli.d.ts +1 -0
  29. package/dist/cli.js +34 -35
  30. package/dist/clipboardImage.d.ts +17 -0
  31. package/dist/commands.d.ts +16 -0
  32. package/dist/completion.d.ts +14 -0
  33. package/dist/{config-COPNMMV6.js → config-DIDLDONU.js} +2 -2
  34. package/dist/{config-RZ5JONMX.js → config-IU76CPK2.js} +7 -3
  35. package/dist/config.d.ts +97 -0
  36. package/dist/context.d.ts +13 -0
  37. package/dist/contextWindow.d.ts +3 -0
  38. package/dist/diff.d.ts +7 -0
  39. package/dist/exit.d.ts +9 -0
  40. package/dist/extensions.d.ts +34 -0
  41. package/dist/{ghBotCli-IBCZIWT5.js → ghBotCli-E3VPHNZY.js} +12 -12
  42. package/dist/ghBotCli.d.ts +9 -0
  43. package/dist/ghBotDispatch.d.ts +68 -0
  44. package/dist/ghBotRunner.d.ts +82 -0
  45. package/dist/ghBotServe.d.ts +21 -0
  46. package/dist/ghBotWebhook.d.ts +45 -0
  47. package/dist/hooks.d.ts +27 -0
  48. package/dist/i18n/id.d.ts +1 -0
  49. package/dist/i18n.d.ts +16 -0
  50. package/dist/{integrationCli-P75R2VSC.js → integrationCli-Q2YPDTPG.js} +1 -1
  51. package/dist/integrationCli.d.ts +9 -0
  52. package/dist/keybinds.d.ts +22 -0
  53. package/dist/{login-SYIQP46J.js → login-FP3BB44A.js} +3 -3
  54. package/dist/login.d.ts +19 -0
  55. package/dist/lsp.d.ts +47 -0
  56. package/dist/mcp/catalog.d.ts +14 -0
  57. package/dist/mcp/config.d.ts +36 -0
  58. package/dist/mcp/manager.d.ts +34 -0
  59. package/dist/mcp/oauth.d.ts +82 -0
  60. package/dist/{mcpCli-QUV5SD64.js → mcpCli-SNBDUWJN.js} +5 -5
  61. package/dist/mcpCli.d.ts +3 -0
  62. package/dist/mcpServer/serve.d.ts +8 -0
  63. package/dist/mcpServer/server.d.ts +19 -0
  64. package/dist/models.d.ts +13 -0
  65. package/dist/{modelsCli-TRRB5LX4.js → modelsCli-CZ2HNGKR.js} +4 -4
  66. package/dist/modelsCli.d.ts +15 -0
  67. package/dist/npmRunner.d.ts +21 -0
  68. package/dist/oauthLogin.d.ts +47 -0
  69. package/dist/permissions.d.ts +30 -0
  70. package/dist/pluginSpec.d.ts +25 -0
  71. package/dist/plugins.d.ts +45 -0
  72. package/dist/{pluginsCli-GNW4TPVV.js → pluginsCli-LPIUUDWB.js} +1 -1
  73. package/dist/pluginsCli.d.ts +16 -0
  74. package/dist/prCli.d.ts +33 -0
  75. package/dist/presets.d.ts +8 -0
  76. package/dist/print.d.ts +14 -0
  77. package/dist/provider.d.ts +140 -0
  78. package/dist/{providerCli-FAOZHOKW.js → providerCli-NMUFXAAS.js} +5 -5
  79. package/dist/providerCli.d.ts +17 -0
  80. package/dist/providers.d.ts +6 -0
  81. package/dist/reasoning.d.ts +12 -0
  82. package/dist/repomap.d.ts +10 -0
  83. package/dist/sdk.d.ts +57 -0
  84. package/dist/sdk.js +99 -18
  85. package/dist/{serve-6QLBJUYW.js → serve-KWOECK5W.js} +1 -1
  86. package/dist/{serve-JG7RLIUD.js → serve-X2ZV4S5U.js} +20 -14
  87. package/dist/serve.d.ts +37 -0
  88. package/dist/serveHeartbeat.d.ts +14 -0
  89. package/dist/serveProtocol.d.ts +47 -0
  90. package/dist/{session-KBAQ4BZ5.js → session-GKEXDJKZ.js} +2 -2
  91. package/dist/session.d.ts +30 -0
  92. package/dist/setup-OV3NWQN5.js +24 -0
  93. package/dist/setup.d.ts +74 -0
  94. package/dist/slash/copy.d.ts +1 -0
  95. package/dist/slash/diff.d.ts +1 -0
  96. package/dist/slash/doctor.d.ts +18 -0
  97. package/dist/slash/export.d.ts +2 -0
  98. package/dist/slash/info.d.ts +45 -0
  99. package/dist/slash/memory.d.ts +10 -0
  100. package/dist/statsCli.d.ts +62 -0
  101. package/dist/textToolCalls.d.ts +6 -0
  102. package/dist/thinking.d.ts +17 -0
  103. package/dist/tokenBudget.d.ts +22 -0
  104. package/dist/tools/bash.d.ts +52 -0
  105. package/dist/tools/diagnostics.d.ts +5 -0
  106. package/dist/tools/edit.d.ts +7 -0
  107. package/dist/tools/fetch.d.ts +41 -0
  108. package/dist/tools/glob.d.ts +5 -0
  109. package/dist/tools/globSafety.d.ts +7 -0
  110. package/dist/tools/grep.d.ts +13 -0
  111. package/dist/tools/ignore.d.ts +2 -0
  112. package/dist/tools/index.d.ts +12 -0
  113. package/dist/tools/memory.d.ts +13 -0
  114. package/dist/tools/paths.d.ts +2 -0
  115. package/dist/tools/plan.d.ts +10 -0
  116. package/dist/tools/read.d.ts +16 -0
  117. package/dist/tools/repomap.d.ts +2 -0
  118. package/dist/tools/sandbox.d.ts +12 -0
  119. package/dist/tools/shell.d.ts +18 -0
  120. package/dist/tools/skill.d.ts +3 -0
  121. package/dist/tools/task.d.ts +28 -0
  122. package/dist/tools/todo.d.ts +13 -0
  123. package/dist/tools/types.d.ts +52 -0
  124. package/dist/tools/websearch.d.ts +9 -0
  125. package/dist/tools/write.d.ts +5 -0
  126. package/dist/{transferCli-TK2GSVRK.js → transferCli-YUFPI6AH.js} +3 -3
  127. package/dist/transferCli.d.ts +23 -0
  128. package/dist/ui/App.d.ts +7 -0
  129. package/dist/ui/DiffView.d.ts +3 -0
  130. package/dist/ui/EditableText.d.ts +7 -0
  131. package/dist/ui/LinePrompt.d.ts +6 -0
  132. package/dist/ui/ListPicker.d.ts +11 -0
  133. package/dist/ui/Markdown.d.ts +8 -0
  134. package/dist/ui/McpMenu.d.ts +11 -0
  135. package/dist/ui/ModelPicker.d.ts +6 -0
  136. package/dist/ui/PermissionPrompt.d.ts +5 -0
  137. package/dist/ui/PlanApproval.d.ts +5 -0
  138. package/dist/ui/PromptInput.d.ts +18 -0
  139. package/dist/ui/ProviderMenu.d.ts +10 -0
  140. package/dist/ui/Spinner.d.ts +4 -0
  141. package/dist/ui/StatusBar.d.ts +9 -0
  142. package/dist/ui/TodoList.d.ts +4 -0
  143. package/dist/ui/ToolBlock.d.ts +14 -0
  144. package/dist/ui/complete.d.ts +1 -0
  145. package/dist/ui/focusReport.d.ts +1 -0
  146. package/dist/ui/index.d.ts +7 -0
  147. package/dist/ui/lineEdit.d.ts +42 -0
  148. package/dist/ui/replay.d.ts +4 -0
  149. package/dist/ui/table.d.ts +20 -0
  150. package/dist/ui/theme.d.ts +5 -0
  151. package/dist/ui/thinkingMouse.d.ts +33 -0
  152. package/dist/ui/transcript.d.ts +55 -0
  153. package/dist/ui/vim.d.ts +26 -0
  154. package/dist/{ui-B3CJ6TGE.js → ui-IVIFNUCC.js} +13 -11
  155. package/dist/{update-K5IQ2MYR.js → update-TZ2G6KQ3.js} +1 -1
  156. package/dist/update.d.ts +30 -0
  157. package/dist/verify.d.ts +16 -0
  158. package/dist/version.d.ts +1 -0
  159. package/dist/webBudget.d.ts +25 -0
  160. package/dist/worktree.d.ts +12 -0
  161. package/package.json +26 -13
  162. package/dist/setup-FJAWDWV4.js +0 -24
@@ -1,8 +1,12 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ quarantineCorruptFile,
4
+ writeFileAtomic
5
+ } from "./chunk-FLQPE4S5.js";
2
6
 
3
7
  // src/mcp/oauth.ts
4
8
  import { spawn } from "child_process";
5
- import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
9
+ import { existsSync, mkdirSync, readFileSync } from "fs";
6
10
  import { createServer } from "http";
7
11
  import { dirname, join } from "path";
8
12
  import { auth } from "@modelcontextprotocol/sdk/client/auth.js";
@@ -12,16 +16,16 @@ function readStore(home) {
12
16
  if (!existsSync(path)) return {};
13
17
  try {
14
18
  return JSON.parse(readFileSync(path, "utf8"));
15
- } catch {
19
+ } catch (error) {
20
+ quarantineCorruptFile(path, error);
16
21
  return {};
17
22
  }
18
23
  }
19
24
  function writeStore(home, store) {
20
25
  const path = oauthStorePath(home);
21
26
  mkdirSync(dirname(path), { recursive: true });
22
- writeFileSync(path, `${JSON.stringify(store, null, 2)}
23
- `, { mode: 384 });
24
- chmodSync(path, 384);
27
+ writeFileAtomic(path, `${JSON.stringify(store, null, 2)}
28
+ `, 384);
25
29
  }
26
30
  function hasStoredTokens(home, serverUrl) {
27
31
  return Boolean(readStore(home)[serverUrl]?.tokens);
@@ -34,9 +38,15 @@ function clearTokens(home, serverUrl) {
34
38
  writeStore(home, store);
35
39
  return true;
36
40
  }
37
- function defaultOpen(url) {
38
- const target = url.href;
39
- const child = process.platform === "win32" ? spawn("cmd", ["/c", "start", "", target], { detached: true, stdio: "ignore" }) : spawn(process.platform === "darwin" ? "open" : "xdg-open", [target], { detached: true, stdio: "ignore" });
41
+ function openCommand(url, platform) {
42
+ if (url.protocol !== "http:" && url.protocol !== "https:") return void 0;
43
+ if (platform === "win32") return { command: "rundll32.exe", args: ["url.dll,FileProtocolHandler", url.href] };
44
+ return { command: platform === "darwin" ? "open" : "xdg-open", args: [url.href] };
45
+ }
46
+ function defaultOpen(url, deps = {}) {
47
+ const plan = openCommand(url, deps.platform ?? process.platform);
48
+ if (!plan) return;
49
+ const child = (deps.spawn ?? spawn)(plan.command, plan.args, { detached: true, stdio: "ignore" });
40
50
  child.unref();
41
51
  child.on("error", () => {
42
52
  });
@@ -20,8 +20,43 @@ function isAlwaysAsk(segment) {
20
20
  }
21
21
  return false;
22
22
  }
23
+ var RUNNER_COMMANDS = /* @__PURE__ */ new Set([
24
+ "npm",
25
+ "npx",
26
+ "pnpm",
27
+ "pnpx",
28
+ "yarn",
29
+ "bun",
30
+ "bunx",
31
+ "deno",
32
+ "node",
33
+ "tsx",
34
+ "ts-node",
35
+ "python",
36
+ "python3",
37
+ "py",
38
+ "uv",
39
+ "uvx",
40
+ "pip",
41
+ "pip3",
42
+ "pipx",
43
+ "pytest",
44
+ "make",
45
+ "cargo",
46
+ "go",
47
+ "dotnet",
48
+ "java",
49
+ "ruby",
50
+ "bundle",
51
+ "rake",
52
+ "gradle",
53
+ "mvn",
54
+ "php",
55
+ "composer"
56
+ ]);
23
57
  function commandKey(segment) {
24
58
  const words = segment.trim().split(/\s+/);
59
+ if (RUNNER_COMMANDS.has(words[0] ?? "") && words[2] && !words[2].startsWith("-")) return words.slice(0, 3).join(" ");
25
60
  return words[1] ? `${words[0]} ${words[1]}` : words[0];
26
61
  }
27
62
  function requiresSensitiveToolApproval(req) {
@@ -20,7 +20,7 @@ import {
20
20
  parseFrontmatter,
21
21
  runHooks,
22
22
  validateGlobPattern
23
- } from "./chunk-M7CALSP3.js";
23
+ } from "./chunk-BGXNR74O.js";
24
24
  import {
25
25
  createWebSearchTool,
26
26
  fetchTool
@@ -30,38 +30,38 @@ import {
30
30
  } from "./chunk-PSO7R5AD.js";
31
31
  import {
32
32
  Permissions
33
- } from "./chunk-O7M3TGIW.js";
33
+ } from "./chunk-MHIYLXJC.js";
34
34
  import {
35
35
  addProviderKey
36
- } from "./chunk-JL5ZCSP2.js";
36
+ } from "./chunk-GN4W3T6E.js";
37
37
  import {
38
38
  listAllModels
39
- } from "./chunk-XBO5GACQ.js";
39
+ } from "./chunk-75BECX4F.js";
40
40
  import {
41
41
  providerName
42
- } from "./chunk-SPRNLS7K.js";
42
+ } from "./chunk-JHPGOAXU.js";
43
43
  import {
44
44
  FileOAuthProvider,
45
45
  hasStoredTokens
46
- } from "./chunk-7F3IWBPQ.js";
46
+ } from "./chunk-MFHCQQEN.js";
47
47
  import {
48
48
  Session
49
- } from "./chunk-QDQU6VY2.js";
49
+ } from "./chunk-BC7UXFE4.js";
50
50
  import {
51
51
  completionAssistantMessage,
52
52
  createProvider,
53
53
  hasPendingProgrammaticReplay,
54
54
  imageUserMessage
55
- } from "./chunk-PUN4HMAG.js";
55
+ } from "./chunk-WNACAUDK.js";
56
56
  import {
57
57
  expandEnvVars
58
- } from "./chunk-L7QI6JN2.js";
58
+ } from "./chunk-24JN75FZ.js";
59
59
  import {
60
60
  ConfigError,
61
61
  bccliHome,
62
62
  loadConfig,
63
63
  resolveModel
64
- } from "./chunk-LACUWBWS.js";
64
+ } from "./chunk-FLQPE4S5.js";
65
65
  import {
66
66
  t
67
67
  } from "./chunk-UZWJQF67.js";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runCommand,
4
4
  runHooks
5
- } from "./chunk-M7CALSP3.js";
5
+ } from "./chunk-BGXNR74O.js";
6
6
  import {
7
7
  ConfigError
8
- } from "./chunk-LACUWBWS.js";
8
+ } from "./chunk-FLQPE4S5.js";
9
9
  import {
10
10
  t
11
11
  } from "./chunk-UZWJQF67.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigError
4
- } from "./chunk-LACUWBWS.js";
4
+ } from "./chunk-FLQPE4S5.js";
5
5
  import {
6
6
  t
7
7
  } from "./chunk-UZWJQF67.js";
@@ -749,7 +749,7 @@ function createProvider(options) {
749
749
  const isBotConnectorCloud = /^https:\/\/api\.botconnector\.id\/v1\/?$/.test(baseURL) && apiKey?.startsWith("bc_live_");
750
750
  if (isBotConnectorCloud) {
751
751
  headers["x-botconnector-client"] = "bccli";
752
- headers["x-botconnector-client-version"] = "0.4.0";
752
+ headers["x-botconnector-client-version"] = "0.4.1";
753
753
  }
754
754
  const useNativeResponses = isBotConnectorCloud && providerId === "bc-cloud" && model === "gpt-6-luna";
755
755
  const useResponsesWebSocket = useNativeResponses && Boolean(apiKey) && (fetchOverride === void 0 || responsesWebSocketFactory !== void 0);
@@ -780,7 +780,7 @@ function createProvider(options) {
780
780
  baseURL: baseURL.replace(/\/+$/, ""),
781
781
  defaultHeaders: {
782
782
  "x-botconnector-client": "bccli",
783
- "x-botconnector-client-version": "0.4.0"
783
+ "x-botconnector-client-version": "0.4.1"
784
784
  }
785
785
  });
786
786
  lunaWs = responsesWebSocketFactory ? responsesWebSocketFactory(client) : new ResponsesWS(client, { reconnect: null });
@@ -843,8 +843,13 @@ function createProvider(options) {
843
843
  } catch (error) {
844
844
  const err = error instanceof ProviderError ? error : new ProviderError(error.message);
845
845
  const lostPrevious = err.code === "previous_response_not_found";
846
+ const handshakeStatus = /unexpected server response:\s*(\d{3})\b/i.exec(err.message);
847
+ const handshakeRejected = Boolean(handshakeStatus && Number(handshakeStatus[1]) >= 400);
846
848
  const connectionLost = /websocket|connection closed|socket|network/i.test(err.message) || err.code === "websocket_connection_limit_reached";
847
849
  resetLunaWebSocket();
850
+ if (!emittedText && !signal?.aborted && handshakeRejected) {
851
+ throw new ProviderError(err.message, Number(handshakeStatus?.[1]), "bc_ws_http_fallback");
852
+ }
848
853
  if (attempt === 0 && !emittedText && !signal?.aborted && (plan.incremental || lostPrevious || connectionLost)) {
849
854
  continue;
850
855
  }
@@ -871,7 +876,8 @@ function createProvider(options) {
871
876
  if (res.ok) return res;
872
877
  const text = await res.text().catch(() => "");
873
878
  lastError = new ProviderError(t("{status} from {url}: {message}", { status: res.status, url: baseURL, message: errorMessage(text) }), res.status);
874
- if (!retryable(res.status)) throw lastError;
879
+ const deterministicQuota429 = res.status === 429 && /"code"\s*:\s*"(?:luna_monthly_quota_exhausted|plan_allowance_exhausted)"/i.test(text);
880
+ if (!retryable(res.status) || deterministicQuota429) throw lastError;
875
881
  }
876
882
  throw lastError ?? new ProviderError(t("Request failed"));
877
883
  }
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  MODE_ORDER
4
- } from "./chunk-O7M3TGIW.js";
4
+ } from "./chunk-MHIYLXJC.js";
5
5
  import {
6
6
  REASONING_LEVELS,
7
7
  isReasoningLevel
8
8
  } from "./chunk-BLOYFIAD.js";
9
9
  import {
10
10
  ConfigError
11
- } from "./chunk-LACUWBWS.js";
11
+ } from "./chunk-FLQPE4S5.js";
12
12
  import {
13
13
  parseLang,
14
14
  t
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/cli.js CHANGED
@@ -2,42 +2,42 @@
2
2
  import {
3
3
  resolveWorktree,
4
4
  runPrint
5
- } from "./chunk-TLPFQIS2.js";
5
+ } from "./chunk-R5RE46CW.js";
6
6
  import {
7
7
  createRuntime
8
- } from "./chunk-TVALKHFB.js";
8
+ } from "./chunk-PZRKU4UM.js";
9
9
  import "./chunk-QZKLZELZ.js";
10
- import "./chunk-M7CALSP3.js";
10
+ import "./chunk-BGXNR74O.js";
11
11
  import "./chunk-45SDLMTV.js";
12
12
  import "./chunk-PSO7R5AD.js";
13
13
  import {
14
14
  VERSION
15
- } from "./chunk-6M5X2KZE.js";
15
+ } from "./chunk-BKGFA2PT.js";
16
16
  import {
17
17
  helpText,
18
18
  parseCliArgs
19
- } from "./chunk-KEMYIGCP.js";
20
- import "./chunk-O7M3TGIW.js";
21
- import "./chunk-JL5ZCSP2.js";
22
- import "./chunk-XBO5GACQ.js";
19
+ } from "./chunk-XV7ZVL4J.js";
20
+ import "./chunk-MHIYLXJC.js";
21
+ import "./chunk-GN4W3T6E.js";
22
+ import "./chunk-75BECX4F.js";
23
23
  import {
24
24
  readGlobalConfigFile
25
- } from "./chunk-SPRNLS7K.js";
25
+ } from "./chunk-JHPGOAXU.js";
26
26
  import {
27
27
  defaultLoginDeps,
28
28
  runLogin
29
- } from "./chunk-BNA74HPN.js";
30
- import "./chunk-7F3IWBPQ.js";
29
+ } from "./chunk-BXQQCUAC.js";
30
+ import "./chunk-MFHCQQEN.js";
31
31
  import {
32
32
  pruneSessions
33
- } from "./chunk-QDQU6VY2.js";
34
- import "./chunk-PUN4HMAG.js";
33
+ } from "./chunk-BC7UXFE4.js";
34
+ import "./chunk-WNACAUDK.js";
35
35
  import "./chunk-BLOYFIAD.js";
36
- import "./chunk-L7QI6JN2.js";
36
+ import "./chunk-24JN75FZ.js";
37
37
  import {
38
38
  ConfigError,
39
39
  setTheme
40
- } from "./chunk-LACUWBWS.js";
40
+ } from "./chunk-FLQPE4S5.js";
41
41
  import {
42
42
  resolveLanguage,
43
43
  setLanguage,
@@ -84,17 +84,17 @@ async function main() {
84
84
  if (args.worktree) cwd = (await resolveWorktree(cwd, args.worktree)).path;
85
85
  if (args.command === "login") return runLogin(args.loginProvider ?? "bc-cloud", cwd, args, defaultLoginDeps());
86
86
  if (args.command === "mcp") {
87
- const { runMcpCommand } = await import("./mcpCli-QUV5SD64.js");
88
- const { readSecret } = await import("./login-SYIQP46J.js");
87
+ const { runMcpCommand } = await import("./mcpCli-SNBDUWJN.js");
88
+ const { readSecret } = await import("./login-FP3BB44A.js");
89
89
  return runMcpCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
90
90
  }
91
91
  if (args.command === "provider") {
92
- const { runProviderCommand } = await import("./providerCli-FAOZHOKW.js");
93
- const { readSecret } = await import("./login-SYIQP46J.js");
92
+ const { runProviderCommand } = await import("./providerCli-NMUFXAAS.js");
93
+ const { readSecret } = await import("./login-FP3BB44A.js");
94
94
  return runProviderCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
95
95
  }
96
96
  if (args.command === "connect" || args.command === "disconnect" || args.command === "integrations") {
97
- const { runIntegrationCommand } = await import("./integrationCli-P75R2VSC.js");
97
+ const { runIntegrationCommand } = await import("./integrationCli-Q2YPDTPG.js");
98
98
  return runIntegrationCommand(args, {
99
99
  env: process.env,
100
100
  cwd,
@@ -104,23 +104,22 @@ async function main() {
104
104
  });
105
105
  }
106
106
  if (args.command === "models") {
107
- const { runModelsCommand } = await import("./modelsCli-TRRB5LX4.js");
107
+ const { runModelsCommand } = await import("./modelsCli-CZ2HNGKR.js");
108
108
  return runModelsCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), fetch: globalThis.fetch });
109
109
  }
110
110
  if (args.command === "update") {
111
- const { runUpdateCommand } = await import("./update-K5IQ2MYR.js");
111
+ const { runUpdateCommand } = await import("./update-TZ2G6KQ3.js");
112
112
  return runUpdateCommand({ env: process.env });
113
113
  }
114
114
  if (args.command === "acp") {
115
- const { runtimeAgent, runAcp } = await import("./acp-ATIL4JOZ.js");
115
+ const { runtimeAgent, runAcp } = await import("./acp-3PHBAI64.js");
116
116
  await runAcp(process.stdin, process.stdout, { cwd, newAgent: (c) => runtimeAgent(c, args.allowAll) });
117
117
  return 0;
118
118
  }
119
119
  if (args.command === "serve") {
120
- const { startServe } = await import("./serve-JG7RLIUD.js");
120
+ const { serveBanner, startServe } = await import("./serve-X2ZV4S5U.js");
121
121
  const handle = await startServe({ port: args.port, host: args.host, token: args.token, cwd, env: process.env });
122
- process.stderr.write(`bccli serve ${handle.url} \u2014 Authorization: Bearer ${handle.token}
123
- `);
122
+ process.stderr.write(serveBanner(handle, { token: args.token }));
124
123
  await new Promise((resolve) => {
125
124
  const stop = () => {
126
125
  void handle.close().finally(resolve);
@@ -131,8 +130,8 @@ async function main() {
131
130
  return 0;
132
131
  }
133
132
  if (args.command === "plugins") {
134
- const { runPluginsCommand } = await import("./pluginsCli-GNW4TPVV.js");
135
- const { readGlobalPlugins, updateGlobalConfig } = await import("./config-RZ5JONMX.js");
133
+ const { runPluginsCommand } = await import("./pluginsCli-LPIUUDWB.js");
134
+ const { readGlobalPlugins, updateGlobalConfig } = await import("./config-IU76CPK2.js");
136
135
  const { runNpmSync } = await import("./npmRunner-LU43GM3W.js");
137
136
  return runPluginsCommand(args, {
138
137
  out: (s) => console.log(s),
@@ -146,7 +145,7 @@ async function main() {
146
145
  });
147
146
  }
148
147
  if (args.command === "gh-bot") {
149
- const { runGhBotCommand } = await import("./ghBotCli-IBCZIWT5.js");
148
+ const { runGhBotCommand } = await import("./ghBotCli-E3VPHNZY.js");
150
149
  return runGhBotCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s) });
151
150
  }
152
151
  if (args.command === "completion") {
@@ -155,15 +154,15 @@ async function main() {
155
154
  }
156
155
  if (args.command === "stats") {
157
156
  const { runStatsCommand } = await import("./statsCli-CF3R7ATL.js");
158
- const { bccliHome } = await import("./config-RZ5JONMX.js");
157
+ const { bccliHome } = await import("./config-IU76CPK2.js");
159
158
  return runStatsCommand(
160
159
  { subArgs: args.subArgs, home: bccliHome(process.env), cwd, days: args.days, tools: args.tools, models: args.models, project: args.project },
161
160
  { out: (s) => console.log(s), err: (s) => console.error(s) }
162
161
  );
163
162
  }
164
163
  if (args.command === "export" || args.command === "import") {
165
- const { runExportCommand, runImportCommand } = await import("./transferCli-TK2GSVRK.js");
166
- const { bccliHome } = await import("./config-RZ5JONMX.js");
164
+ const { runExportCommand, runImportCommand } = await import("./transferCli-YUFPI6AH.js");
165
+ const { bccliHome } = await import("./config-IU76CPK2.js");
167
166
  const deps = { subArgs: args.subArgs, home: bccliHome(process.env), cwd };
168
167
  const io = { out: (s) => console.log(s), err: (s) => console.error(s) };
169
168
  return args.command === "export" ? runExportCommand(deps, io) : runImportCommand(deps, io);
@@ -183,7 +182,7 @@ async function main() {
183
182
  }
184
183
  if (args.print) {
185
184
  if (!args.prompt) throw new ConfigError(t('-p mode needs a task, e.g. bccli -p "explain this repo"'));
186
- const { serversToStart } = await import("./config-COPNMMV6.js");
185
+ const { serversToStart } = await import("./config-DIDLDONU.js");
187
186
  const plan = serversToStart(rt.home, cwd);
188
187
  for (const s of plan.needTrust) {
189
188
  console.error(t('Project MCP server "{name}" skipped (not approved yet; run interactive bccli once to approve it).', { name: s.name }));
@@ -199,13 +198,13 @@ async function main() {
199
198
  let updateMessage;
200
199
  if (rt.config.updateCheck !== "off" && !process.env.BCCLI_NO_UPDATE_CHECK) {
201
200
  try {
202
- const { checkForUpdate } = await import("./update-K5IQ2MYR.js");
201
+ const { checkForUpdate } = await import("./update-TZ2G6KQ3.js");
203
202
  const update = await checkForUpdate({ home: rt.home, fetch: globalThis.fetch, now: /* @__PURE__ */ new Date() });
204
203
  updateMessage = update;
205
204
  } catch {
206
205
  }
207
206
  }
208
- const { startInteractive } = await import("./ui-B3CJ6TGE.js");
207
+ const { startInteractive } = await import("./ui-IVIFNUCC.js");
209
208
  return startInteractive(rt, { initialPrompt: args.prompt, resume: args.resume, version: VERSION, updateMessage });
210
209
  }
211
210
  main().then(
@@ -0,0 +1,17 @@
1
+ export interface GrabDeps {
2
+ platform: NodeJS.Platform;
3
+ tmpdir: string;
4
+ now: Date;
5
+ run?(cmd: string, args: string[]): Promise<{
6
+ code: number;
7
+ output: string;
8
+ }>;
9
+ }
10
+ export declare function clipboardTarget(tmpdir: string, now: Date): string;
11
+ /** Terminals cannot transmit images, so each platform's clipboard tool saves a PNG we can point the model at. */
12
+ export declare function clipboardCommand(platform: NodeJS.Platform, target: string): {
13
+ cmd: string;
14
+ args: string[];
15
+ } | undefined;
16
+ /** Returns the saved PNG path, or undefined when the clipboard holds no image / the platform is unsupported. */
17
+ export declare function grabClipboardImage(deps: GrabDeps): Promise<string | undefined>;
@@ -0,0 +1,16 @@
1
+ import type { CommandDef } from './extensions';
2
+ /** Descriptions are English keys; wrap them in t() when showing them. */
3
+ export declare const SLASH_COMMANDS: {
4
+ name: string;
5
+ description: string;
6
+ }[];
7
+ export declare function parseSlash(text: string): {
8
+ name: string;
9
+ args: string;
10
+ } | undefined;
11
+ export declare function expandCommand(def: CommandDef, args: string): string;
12
+ /**
13
+ * /pr: the model runs gh itself (installed on PATH), so this is a prompt, not a fetch.
14
+ * Empty selector = the PR of the current branch, falling back to a branch diff.
15
+ */
16
+ export declare function prReviewPrompt(selector: string): string;
@@ -0,0 +1,14 @@
1
+ import type { CliArgs } from './args';
2
+ export declare const SHELLS: readonly ['bash', 'zsh', 'fish', 'powershell'];
3
+ export type CompletionShell = (typeof SHELLS)[number];
4
+ export declare function isCompletionShell(value: string): value is CompletionShell;
5
+ /** Completion script for a supported shell (bash, zsh, fish, powershell). */
6
+ export declare function completionScript(shell: CompletionShell): string;
7
+ export interface CompletionDeps {
8
+ out(line: string): void;
9
+ err?(line: string): void;
10
+ }
11
+ /**
12
+ * `bccli completion <bash|zsh|fish|powershell>` — print a completion script to stdout.
13
+ */
14
+ export declare function runCompletionCommand(args: Pick<CliArgs, 'subArgs'>, deps: CompletionDeps): number;
@@ -9,8 +9,8 @@ import {
9
9
  removeGlobalServer,
10
10
  serversToStart,
11
11
  setProjectTrust
12
- } from "./chunk-L7QI6JN2.js";
13
- import "./chunk-LACUWBWS.js";
12
+ } from "./chunk-24JN75FZ.js";
13
+ import "./chunk-FLQPE4S5.js";
14
14
  import "./chunk-UZWJQF67.js";
15
15
  export {
16
16
  addGlobalServer,
@@ -5,14 +5,16 @@ import {
5
5
  bccliHome,
6
6
  globalConfigPath,
7
7
  loadConfig,
8
+ quarantineCorruptFile,
8
9
  readCredentials,
9
10
  readGlobalPlugins,
10
11
  readJsonConfig,
11
12
  removeCredential,
12
13
  resolveModel,
13
14
  saveCredential,
14
- updateGlobalConfig
15
- } from "./chunk-LACUWBWS.js";
15
+ updateGlobalConfig,
16
+ writeFileAtomic
17
+ } from "./chunk-FLQPE4S5.js";
16
18
  import "./chunk-UZWJQF67.js";
17
19
  export {
18
20
  ConfigError,
@@ -20,11 +22,13 @@ export {
20
22
  bccliHome,
21
23
  globalConfigPath,
22
24
  loadConfig,
25
+ quarantineCorruptFile,
23
26
  readCredentials,
24
27
  readGlobalPlugins,
25
28
  readJsonConfig,
26
29
  removeCredential,
27
30
  resolveModel,
28
31
  saveCredential,
29
- updateGlobalConfig
32
+ updateGlobalConfig,
33
+ writeFileAtomic
30
34
  };
@@ -0,0 +1,97 @@
1
+ import type { ReasoningLevel } from './reasoning';
2
+ import type { HooksConfig } from './hooks';
3
+ import { type Keybind, type KeybindAction } from './keybinds';
4
+ import type { LspServer } from './lsp';
5
+ import type { UsageCap } from './budget';
6
+ import type { Lang } from './i18n';
7
+ export type PermissionMode = 'default' | 'acceptEdits' | 'plan' | 'allowAll';
8
+ export interface ProviderConfig {
9
+ baseURL: string;
10
+ apiKeyEnv?: string;
11
+ name?: string;
12
+ }
13
+ export interface Config {
14
+ model: string;
15
+ permissionMode: PermissionMode;
16
+ reasoning: ReasoningLevel;
17
+ /** Show provider-supplied reasoning summaries in the TUI. Global setting only. */
18
+ thinkingVisible?: boolean;
19
+ /** Delete saved sessions older than this many days at startup. Omitted, null or 0 keeps them until you delete them (the default). Global setting only. */
20
+ sessionRetentionDays?: number | null;
21
+ /** Click the Thinking block to expand/collapse it. Off by default: it needs terminal mouse reporting, which blocks drag-to-copy. Global setting only; ctrl+t works either way. */
22
+ thinkingClickCollapse?: boolean;
23
+ /** Tool-call step cap per turn. Omitted, null or 0 means unlimited (the default); a positive number opts into a cap. */
24
+ maxSteps?: number | null;
25
+ /** Interface language; only the global config is read for it. */
26
+ language?: Lang;
27
+ /** Tool/session hooks; only the global config is read — the project file is untrusted and must never execute code. */
28
+ hooks?: HooksConfig;
29
+ /** Attach images read from disk as vision parts. Only the global config is read; default true. */
30
+ vision?: boolean;
31
+ /** Bash network gate: "offline" blocks known internet commands. Only the global config is read. */
32
+ networkPolicy?: 'allow' | 'offline';
33
+ /** JS plugin specs, loaded at boot. Only the global config is read — the project file must never execute code. */
34
+ plugins?: string[];
35
+ /** Resolved TUI key bindings; only the global config is read (a cloned project must not rebind your keys). */
36
+ keybinds: Record<KeybindAction, Keybind>;
37
+ /** Commands run after a turn that edited files (aider --test-cmd style). Only the global config is read. */
38
+ verifyCommands: string[];
39
+ /** Per-session token/USD budget; the agent stops calling the model once it is exceeded. Only the global config is read. */
40
+ usageCap?: UsageCap;
41
+ /** Daily npm registry check with a notice when a newer bccli exists. Only the global config is read; default "on". */
42
+ updateCheck?: 'on' | 'off';
43
+ /** Include a repo map (files + top-level symbols) in the system prompt. Only the global config is read; default false. */
44
+ repoMap: boolean;
45
+ /** Color theme name. Only the global config is read; default "default". */
46
+ theme: string;
47
+ /** Prompt editing style. Only the global config is read; default "emacs". */
48
+ editor: 'emacs' | 'vim';
49
+ /** Run bash commands inside the OS sandbox (macOS sandbox-exec / Linux bwrap). Only the global config is read; default "off". */
50
+ sandbox: 'off' | 'on';
51
+ /** LSP servers used by the diagnostics tool. Only the global config is read (it spawns commands). */
52
+ lsp?: {
53
+ servers: LspServer[];
54
+ };
55
+ providers: Record<string, ProviderConfig>;
56
+ allow: string[];
57
+ /** Provider ids that came from the (untrusted) project config. */
58
+ projectProviders?: string[];
59
+ }
60
+ export interface ResolvedModel {
61
+ providerId: string;
62
+ model: string;
63
+ baseURL: string;
64
+ apiKey?: string;
65
+ }
66
+ export declare class ConfigError extends Error {
67
+ }
68
+ /**
69
+ * Default cap on tool-call steps per turn for the main agent: none, like Claude Code, Codex and
70
+ * OpenCode (its `steps` is unset = unlimited). The turn runs until the model stops or the user
71
+ * presses Esc. Set maxSteps in the global config to a positive number to opt into a safety cap
72
+ * (the "type continue" notice then appears when it is reached).
73
+ */
74
+ export declare const DEFAULT_MAX_STEPS: number | null;
75
+ export declare function bccliHome(env?: NodeJS.ProcessEnv): string;
76
+ export declare function readJsonConfig(path: string): Partial<Config>;
77
+ export declare function loadConfig(cwd: string, env?: NodeJS.ProcessEnv): Config;
78
+ export declare function globalConfigPath(env?: NodeJS.ProcessEnv): string;
79
+ export declare function readGlobalPlugins(env?: NodeJS.ProcessEnv): string[];
80
+ export declare function writeFileAtomic(path: string, data: string, mode?: number): void;
81
+ /**
82
+ * A corrupt JSON file must never be silently treated as empty: the next write would
83
+ * wipe whatever the user had. Move it aside in place (timestamped, same folder) so
84
+ * the data stays recoverable, and warn on stderr. Returns the backup path.
85
+ */
86
+ export declare function quarantineCorruptFile(path: string, error: unknown): string | undefined;
87
+ /**
88
+ * Read-modify-write of the global config.json. `mutate` throwing aborts before
89
+ * any write; the write itself is atomic (tmp + rename in the same directory),
90
+ * so a failed run never leaves a truncated or half-updated config.
91
+ */
92
+ export declare function updateGlobalConfig(env: NodeJS.ProcessEnv, mutate: (cfg: Record<string, unknown>) => void): void;
93
+ export declare function readCredentials(env?: NodeJS.ProcessEnv): Record<string, string>;
94
+ export declare function saveCredential(providerId: string, key: string, env?: NodeJS.ProcessEnv): void;
95
+ export declare function resolveModel(config: Config, modelRef: string, env?: NodeJS.ProcessEnv): ResolvedModel;
96
+ /** Returns false when there was no stored key to remove. */
97
+ export declare function removeCredential(providerId: string, env?: NodeJS.ProcessEnv): boolean;
@@ -0,0 +1,13 @@
1
+ import type { SkillDef } from './extensions';
2
+ /** Instruction files in load order: global BCCLI.md, then AGENTS.md/BCCLI.md from the filesystem root down to cwd. */
3
+ export declare function instructionPaths(cwd: string, home: string): string[];
4
+ export declare function loadInstructions(cwd: string, home: string): string;
5
+ export declare function buildSystemPrompt(opts: {
6
+ cwd: string;
7
+ home: string;
8
+ model: string;
9
+ date?: string;
10
+ platform?: string;
11
+ skills?: SkillDef[];
12
+ repoMap?: string;
13
+ }): string;
@@ -0,0 +1,3 @@
1
+ export declare const DEFAULT_CONTEXT_WINDOW = 128000;
2
+ /** Resolves the context window for a `provider/model` ref; `BCCLI_CONTEXT_WINDOW` overrides everything. */
3
+ export declare function contextWindowFor(modelRef: string, env?: NodeJS.ProcessEnv): number;
package/dist/diff.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export interface DiffLine {
2
+ kind: 'add' | 'del' | 'ctx';
3
+ line: number;
4
+ text: string;
5
+ }
6
+ export declare function diffLines(oldText: string, newText: string): DiffLine[];
7
+ export declare function formatDiff(lines: DiffLine[]): string;
package/dist/exit.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export declare const EXIT_GRACE_MS = 1000;
2
+ export interface ExitDeps {
3
+ setExitCode: (code: number) => void;
4
+ exit: (code: number) => void;
5
+ setTimer: (fn: () => void, ms: number) => {
6
+ unref: () => void;
7
+ };
8
+ }
9
+ export declare function settleExit(code: number, deps?: Partial<ExitDeps>): void;