@botconnector/bccli 0.4.16 → 0.5.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/LICENSE +203 -21
  2. package/THIRD_PARTY_NOTICES.md +9 -0
  3. package/branding.mjs +347 -0
  4. package/cli.mjs +120 -0
  5. package/core.mjs +260 -0
  6. package/credentials.mjs +52 -0
  7. package/gateway.mjs +2 -0
  8. package/model-command.mjs +61 -0
  9. package/package.json +35 -59
  10. package/provider-cli.mjs +77 -0
  11. package/providers.mjs +166 -0
  12. package/proxy.mjs +242 -0
  13. package/startup-menu.mjs +120 -0
  14. package/README.en.md +0 -253
  15. package/README.md +0 -250
  16. package/dist/abort.d.ts +0 -5
  17. package/dist/acp-JZW3XHE5.js +0 -221
  18. package/dist/acp.d.ts +0 -44
  19. package/dist/agent.d.ts +0 -147
  20. package/dist/agents.d.ts +0 -4
  21. package/dist/args-XVO7TB4C.js +0 -13
  22. package/dist/args.d.ts +0 -59
  23. package/dist/budget.d.ts +0 -26
  24. package/dist/checkpoints.d.ts +0 -35
  25. package/dist/chunk-3CYQYHPK.js +0 -202
  26. package/dist/chunk-6JK4IBGK.js +0 -1075
  27. package/dist/chunk-6SDRWEPN.js +0 -50
  28. package/dist/chunk-7GM6NN5E.js +0 -341
  29. package/dist/chunk-7XD47KN5.js +0 -71
  30. package/dist/chunk-INMSTUB2.js +0 -56
  31. package/dist/chunk-ISOKH5WB.js +0 -256
  32. package/dist/chunk-JUC3ZOCV.js +0 -50
  33. package/dist/chunk-KDVL2NP6.js +0 -861
  34. package/dist/chunk-KEKDRROL.js +0 -216
  35. package/dist/chunk-KJIXA6MP.js +0 -159
  36. package/dist/chunk-OK2USAXX.js +0 -88
  37. package/dist/chunk-PSO7R5AD.js +0 -10
  38. package/dist/chunk-Q42ZGVAQ.js +0 -91
  39. package/dist/chunk-R754XIBJ.js +0 -523
  40. package/dist/chunk-S3QEZDKB.js +0 -270
  41. package/dist/chunk-SWNRA3EW.js +0 -78
  42. package/dist/chunk-TLCL6DC7.js +0 -378
  43. package/dist/chunk-V5D6PJQN.js +0 -8
  44. package/dist/chunk-YYTFJUO2.js +0 -148
  45. package/dist/chunk-ZJRZTMJF.js +0 -2669
  46. package/dist/cli.d.ts +0 -1
  47. package/dist/cli.js +0 -233
  48. package/dist/clipboardImage.d.ts +0 -17
  49. package/dist/commands.d.ts +0 -16
  50. package/dist/completion-Q7VHOPPV.js +0 -125
  51. package/dist/completion.d.ts +0 -14
  52. package/dist/config-T7MKGJVG.js +0 -34
  53. package/dist/config-YYEAEN2C.js +0 -25
  54. package/dist/config.d.ts +0 -99
  55. package/dist/context.d.ts +0 -13
  56. package/dist/contextWindow.d.ts +0 -3
  57. package/dist/diff.d.ts +0 -7
  58. package/dist/exit.d.ts +0 -9
  59. package/dist/extensions.d.ts +0 -34
  60. package/dist/ghBotCli-7VUGI63S.js +0 -680
  61. package/dist/ghBotCli.d.ts +0 -9
  62. package/dist/ghBotDispatch.d.ts +0 -68
  63. package/dist/ghBotRunner.d.ts +0 -82
  64. package/dist/ghBotServe.d.ts +0 -21
  65. package/dist/ghBotWebhook.d.ts +0 -45
  66. package/dist/hooks.d.ts +0 -27
  67. package/dist/i18n/id.d.ts +0 -1
  68. package/dist/i18n.d.ts +0 -16
  69. package/dist/integrationCli-FBRSTF5F.js +0 -876
  70. package/dist/integrationCli.d.ts +0 -9
  71. package/dist/keybinds.d.ts +0 -22
  72. package/dist/login-BSMUGW7L.js +0 -18
  73. package/dist/login.d.ts +0 -21
  74. package/dist/lsp.d.ts +0 -73
  75. package/dist/mcp/catalog.d.ts +0 -14
  76. package/dist/mcp/config.d.ts +0 -36
  77. package/dist/mcp/manager.d.ts +0 -52
  78. package/dist/mcp/oauth.d.ts +0 -82
  79. package/dist/mcpCli-ZT7CRYMP.js +0 -113
  80. package/dist/mcpCli.d.ts +0 -3
  81. package/dist/mcpServer/serve.d.ts +0 -8
  82. package/dist/mcpServer/server.d.ts +0 -19
  83. package/dist/models.d.ts +0 -13
  84. package/dist/modelsCli-2ZRW4CC4.js +0 -36
  85. package/dist/modelsCli.d.ts +0 -15
  86. package/dist/npmRunner-LU43GM3W.js +0 -46
  87. package/dist/npmRunner.d.ts +0 -21
  88. package/dist/oauthLogin-THSM6FE7.js +0 -210
  89. package/dist/oauthLogin.d.ts +0 -47
  90. package/dist/permissions.d.ts +0 -30
  91. package/dist/pluginSpec.d.ts +0 -25
  92. package/dist/plugins.d.ts +0 -45
  93. package/dist/pluginsCli-EKQI4CJW.js +0 -288
  94. package/dist/pluginsCli.d.ts +0 -16
  95. package/dist/prCli-FMQTOBIV.js +0 -94
  96. package/dist/prCli.d.ts +0 -46
  97. package/dist/presets.d.ts +0 -8
  98. package/dist/print.d.ts +0 -17
  99. package/dist/provider.d.ts +0 -145
  100. package/dist/providerCli-3TFEKV4C.js +0 -15
  101. package/dist/providerCli.d.ts +0 -17
  102. package/dist/providers.d.ts +0 -6
  103. package/dist/reasoning.d.ts +0 -12
  104. package/dist/repomap.d.ts +0 -10
  105. package/dist/sdk.d.ts +0 -61
  106. package/dist/sdk.js +0 -6494
  107. package/dist/serve-3BODPEPR.js +0 -532
  108. package/dist/serve-V6YVZTNR.js +0 -178
  109. package/dist/serve.d.ts +0 -37
  110. package/dist/serveHeartbeat.d.ts +0 -14
  111. package/dist/serveProtocol.d.ts +0 -47
  112. package/dist/session-LX4UNPCD.js +0 -12
  113. package/dist/session.d.ts +0 -33
  114. package/dist/setup-MFG3BWEU.js +0 -24
  115. package/dist/setup.d.ts +0 -79
  116. package/dist/slash/copy.d.ts +0 -1
  117. package/dist/slash/diff.d.ts +0 -1
  118. package/dist/slash/doctor.d.ts +0 -18
  119. package/dist/slash/export.d.ts +0 -2
  120. package/dist/slash/info.d.ts +0 -46
  121. package/dist/slash/memory.d.ts +0 -10
  122. package/dist/statsCli-7MIQHLVW.js +0 -353
  123. package/dist/statsCli.d.ts +0 -62
  124. package/dist/textToolCalls.d.ts +0 -6
  125. package/dist/thinking.d.ts +0 -17
  126. package/dist/tokenBudget.d.ts +0 -22
  127. package/dist/tools/bash.d.ts +0 -54
  128. package/dist/tools/diagnostics.d.ts +0 -13
  129. package/dist/tools/edit.d.ts +0 -12
  130. package/dist/tools/fetch.d.ts +0 -41
  131. package/dist/tools/glob.d.ts +0 -5
  132. package/dist/tools/globSafety.d.ts +0 -7
  133. package/dist/tools/grep.d.ts +0 -25
  134. package/dist/tools/ignore.d.ts +0 -2
  135. package/dist/tools/index.d.ts +0 -12
  136. package/dist/tools/memory.d.ts +0 -13
  137. package/dist/tools/paths.d.ts +0 -4
  138. package/dist/tools/plan.d.ts +0 -10
  139. package/dist/tools/read.d.ts +0 -16
  140. package/dist/tools/repomap.d.ts +0 -2
  141. package/dist/tools/sandbox.d.ts +0 -15
  142. package/dist/tools/shell.d.ts +0 -18
  143. package/dist/tools/skill.d.ts +0 -3
  144. package/dist/tools/task.d.ts +0 -28
  145. package/dist/tools/todo.d.ts +0 -13
  146. package/dist/tools/types.d.ts +0 -52
  147. package/dist/tools/websearch.d.ts +0 -9
  148. package/dist/tools/write.d.ts +0 -5
  149. package/dist/transferCli-SRSYQLSJ.js +0 -73
  150. package/dist/transferCli.d.ts +0 -23
  151. package/dist/ui/App.d.ts +0 -7
  152. package/dist/ui/DiffView.d.ts +0 -3
  153. package/dist/ui/EditableText.d.ts +0 -7
  154. package/dist/ui/LinePrompt.d.ts +0 -6
  155. package/dist/ui/ListPicker.d.ts +0 -11
  156. package/dist/ui/Markdown.d.ts +0 -8
  157. package/dist/ui/McpMenu.d.ts +0 -11
  158. package/dist/ui/ModelPicker.d.ts +0 -6
  159. package/dist/ui/PermissionPrompt.d.ts +0 -5
  160. package/dist/ui/PlanApproval.d.ts +0 -5
  161. package/dist/ui/PromptInput.d.ts +0 -20
  162. package/dist/ui/ProviderMenu.d.ts +0 -10
  163. package/dist/ui/Spinner.d.ts +0 -4
  164. package/dist/ui/StatusBar.d.ts +0 -9
  165. package/dist/ui/TodoList.d.ts +0 -4
  166. package/dist/ui/ToolBlock.d.ts +0 -14
  167. package/dist/ui/complete.d.ts +0 -8
  168. package/dist/ui/index.d.ts +0 -7
  169. package/dist/ui/lineEdit.d.ts +0 -42
  170. package/dist/ui/liveCap.d.ts +0 -9
  171. package/dist/ui/replay.d.ts +0 -4
  172. package/dist/ui/stdinFilter.d.ts +0 -18
  173. package/dist/ui/table.d.ts +0 -20
  174. package/dist/ui/theme.d.ts +0 -5
  175. package/dist/ui/thinkingMouse.d.ts +0 -38
  176. package/dist/ui/transcript.d.ts +0 -55
  177. package/dist/ui/tty.d.ts +0 -11
  178. package/dist/ui/vim.d.ts +0 -26
  179. package/dist/ui-LZ4JGF2V.js +0 -2913
  180. package/dist/update-P7MU4ZM7.js +0 -145
  181. package/dist/update.d.ts +0 -30
  182. package/dist/verify.d.ts +0 -16
  183. package/dist/version.d.ts +0 -1
  184. package/dist/webBudget.d.ts +0 -25
  185. package/dist/worktree.d.ts +0 -12
@@ -1,216 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- contentText
4
- } from "./chunk-6JK4IBGK.js";
5
-
6
- // src/session.ts
7
- import { randomBytes } from "crypto";
8
- import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync } from "fs";
9
- import { basename, dirname, join } from "path";
10
- function projectDir(home, cwd) {
11
- const slug = cwd.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(-100) || "root";
12
- return join(home, "sessions", slug);
13
- }
14
- function repairTail(messages) {
15
- const out = [...messages];
16
- for (let i = out.length - 1; i >= 0; i--) {
17
- const m = out[i];
18
- if (m.role !== "assistant" || !m.tool_calls?.length) continue;
19
- const answered = new Set(out.slice(i + 1).flatMap((x) => x.role === "tool" ? [x.tool_call_id] : []));
20
- if (!m.tool_calls.every((c) => answered.has(c.id))) out.length = i;
21
- break;
22
- }
23
- return out;
24
- }
25
- var Session = class _Session {
26
- constructor(file) {
27
- this.file = file;
28
- }
29
- file;
30
- get id() {
31
- return basename(this.file, ".jsonl");
32
- }
33
- static create(home, cwd, now = /* @__PURE__ */ new Date()) {
34
- const dir = projectDir(home, cwd);
35
- const stamp = now.toISOString().replace(/[:.]/g, "-");
36
- return new _Session(join(dir, `${stamp}-${randomBytes(3).toString("hex")}.jsonl`));
37
- }
38
- static list(home, cwd) {
39
- const dir = projectDir(home, cwd);
40
- if (!existsSync(dir)) return [];
41
- return readdirSync(dir).filter((f) => f.endsWith(".jsonl")).map((f) => {
42
- const session = new _Session(join(dir, f));
43
- const first = session.loadHistory().find((m) => m.role === "user");
44
- return { session, mtime: statSync(session.file).mtime, preview: first ? contentText(first.content).slice(0, 80) : "" };
45
- }).sort((a, b) => b.mtime.getTime() - a.mtime.getTime() || b.session.file.localeCompare(a.session.file));
46
- }
47
- static latest(home, cwd) {
48
- return _Session.list(home, cwd)[0]?.session;
49
- }
50
- write(record) {
51
- mkdirSync(dirname(this.file), { recursive: true });
52
- appendFileSync(this.file, `${JSON.stringify(record)}
53
- `);
54
- }
55
- append(message) {
56
- this.write({ t: "msg", m: message });
57
- }
58
- appendUsage(usage) {
59
- this.write({ t: "usage", ...usage });
60
- }
61
- reset() {
62
- this.write({ t: "reset" });
63
- }
64
- records() {
65
- if (!existsSync(this.file)) return [];
66
- const out = [];
67
- for (const line of readFileSync(this.file, "utf8").split("\n")) {
68
- if (!line.trim()) continue;
69
- try {
70
- out.push(JSON.parse(line));
71
- } catch {
72
- }
73
- }
74
- return out;
75
- }
76
- /** What the model continues from: everything after the last reset (after a compaction that is the summary and the recent turns). */
77
- load() {
78
- let messages = [];
79
- for (const record of this.records()) {
80
- if (record.t === "reset") messages = [];
81
- else if (record.t === "msg") messages.push(record.m);
82
- }
83
- return repairTail(messages);
84
- }
85
- /** Model of the most recent turn that recorded usage — serve attach continues a session with its own model. */
86
- lastModel() {
87
- const records = this.records();
88
- for (let i = records.length - 1; i >= 0; i--) {
89
- const record = records[i];
90
- if (record.t === "usage" && record.model) return record.model;
91
- }
92
- return void 0;
93
- }
94
- /** Accumulated token usage since the last non-compaction reset. */
95
- totalUsage() {
96
- const segments = [{ msgs: [], usage: { inputTokens: 0, outputTokens: 0 } }];
97
- for (const record of this.records()) {
98
- const cur = segments[segments.length - 1];
99
- if (record.t === "reset") {
100
- segments.push({ msgs: [], usage: { inputTokens: 0, outputTokens: 0 } });
101
- } else if (record.t === "msg") {
102
- cur.msgs.push(record.m);
103
- } else if (record.t === "usage") {
104
- cur.usage.inputTokens += record.inputTokens;
105
- cur.usage.outputTokens += record.outputTokens;
106
- if (record.cachedInputTokens) cur.usage.cachedInputTokens = (cur.usage.cachedInputTokens ?? 0) + record.cachedInputTokens;
107
- if (record.cacheWriteTokens) cur.usage.cacheWriteTokens = (cur.usage.cacheWriteTokens ?? 0) + record.cacheWriteTokens;
108
- }
109
- }
110
- let total = { ...segments[0].usage };
111
- for (const seg of segments.slice(1)) {
112
- if (!isCompactionSummary(seg.msgs[0])) {
113
- total = { ...seg.usage };
114
- } else {
115
- total.inputTokens += seg.usage.inputTokens;
116
- total.outputTokens += seg.usage.outputTokens;
117
- if (seg.usage.cachedInputTokens) total.cachedInputTokens = (total.cachedInputTokens ?? 0) + seg.usage.cachedInputTokens;
118
- if (seg.usage.cacheWriteTokens) total.cacheWriteTokens = (total.cacheWriteTokens ?? 0) + seg.usage.cacheWriteTokens;
119
- }
120
- }
121
- return total;
122
- }
123
- /**
124
- * What the user sees on resume: the whole conversation. Compaction only shrinks what the model is sent, so
125
- * its reset does not hide the older turns here. A real reset (/clear, rewind) still starts over, the
126
- * synthetic summary pair is never shown, and the recent turns a compaction re-writes are not shown twice.
127
- */
128
- loadHistory() {
129
- const segments = [[]];
130
- for (const record of this.records()) {
131
- if (record.t === "reset") segments.push([]);
132
- else if (record.t === "msg") segments[segments.length - 1].push(record.m);
133
- }
134
- let shown = segments[0];
135
- let lastSummary;
136
- for (const segment of segments.slice(1)) {
137
- if (!isCompactionSummary(segment[0])) {
138
- shown = segment;
139
- lastSummary = void 0;
140
- continue;
141
- }
142
- const kept = segment.slice(2);
143
- if (lastSummary && sameMessage(segment[0], lastSummary)) {
144
- const subIdx = findContiguousSlice(shown, kept);
145
- if (subIdx !== -1) {
146
- shown = shown.slice(0, subIdx + kept.length);
147
- continue;
148
- }
149
- }
150
- lastSummary = segment[0];
151
- let at = 0;
152
- while (at <= shown.length && !endsWithPrefixOf(shown, at, kept)) at++;
153
- shown = [...shown, ...kept.slice(shown.length - at)];
154
- }
155
- return repairTail(shown.filter((m) => !isCompactionSummary(m) && !isCompactionAck(m)));
156
- }
157
- };
158
- var SUMMARY_PREFIX = "Summary of the previous conversation:";
159
- var SUMMARY_ACK = "OK, I will continue from this summary.";
160
- function isCompactionSummary(m) {
161
- return m?.role === "user" && typeof m.content === "string" && m.content.startsWith(SUMMARY_PREFIX);
162
- }
163
- function isCompactionAck(m) {
164
- return m.role === "assistant" && m.content === SUMMARY_ACK;
165
- }
166
- function sameMessage(a, b) {
167
- if (a.role !== b.role) return false;
168
- if (a.role === "tool" && b.role === "tool") return a.tool_call_id === b.tool_call_id;
169
- return JSON.stringify(a.content) === JSON.stringify(b.content) && JSON.stringify("tool_calls" in a && a.tool_calls) === JSON.stringify("tool_calls" in b && b.tool_calls);
170
- }
171
- function endsWithPrefixOf(shown, at, kept) {
172
- const n = shown.length - at;
173
- if (n > kept.length) return false;
174
- for (let j = 0; j < n; j++) if (!sameMessage(shown[at + j], kept[j])) return false;
175
- return true;
176
- }
177
- function findContiguousSlice(shown, slice) {
178
- if (slice.length === 0) return shown.length;
179
- for (let i = 0; i + slice.length <= shown.length; i++) {
180
- let ok = true;
181
- for (let j = 0; j < slice.length; j++) {
182
- if (!sameMessage(shown[i + j], slice[j])) {
183
- ok = false;
184
- break;
185
- }
186
- }
187
- if (ok) return i;
188
- }
189
- return -1;
190
- }
191
- function pruneSessions(home, now = Date.now(), maxAgeDays = 30) {
192
- const root = join(home, "sessions");
193
- if (!existsSync(root)) return 0;
194
- let removed = 0;
195
- for (const project of readdirSync(root)) {
196
- const dir = join(root, project);
197
- try {
198
- if (!statSync(dir).isDirectory()) continue;
199
- } catch {
200
- continue;
201
- }
202
- for (const file of readdirSync(dir)) {
203
- const path = join(dir, file);
204
- if (now - statSync(path).mtimeMs > maxAgeDays * 864e5) {
205
- rmSync(path);
206
- removed++;
207
- }
208
- }
209
- }
210
- return removed;
211
- }
212
-
213
- export {
214
- Session,
215
- pruneSessions
216
- };
@@ -1,159 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- defaultOpen
4
- } from "./chunk-3CYQYHPK.js";
5
- import {
6
- removeCredential,
7
- saveCredential
8
- } from "./chunk-TLCL6DC7.js";
9
- import {
10
- t
11
- } from "./chunk-R754XIBJ.js";
12
-
13
- // src/login.ts
14
- function readSecret(prompt) {
15
- return new Promise((resolve) => {
16
- process.stdout.write(prompt);
17
- const stdin = process.stdin;
18
- if (!stdin.isTTY) {
19
- let data = "";
20
- stdin.on("data", (d) => {
21
- data += d;
22
- });
23
- stdin.on("end", () => resolve(data.trim()));
24
- return;
25
- }
26
- let value = "";
27
- stdin.setRawMode(true);
28
- stdin.resume();
29
- const onData = (buffer) => {
30
- for (const ch of buffer.toString()) {
31
- if (ch === "\r" || ch === "\n") {
32
- stdin.setRawMode(false);
33
- stdin.pause();
34
- stdin.off("data", onData);
35
- process.stdout.write("\n");
36
- resolve(value.trim());
37
- return;
38
- }
39
- if (ch === "") process.exit(130);
40
- if (ch === "\x7F" || ch === "\b") value = value.slice(0, -1);
41
- else value += ch;
42
- }
43
- };
44
- stdin.on("data", onData);
45
- });
46
- }
47
- function echoFor(ch) {
48
- const code = ch.codePointAt(0) ?? 0;
49
- if (code < 32 || code === 127) return void 0;
50
- return ch;
51
- }
52
- function readLine(prompt) {
53
- return new Promise((resolve) => {
54
- process.stdout.write(prompt);
55
- const stdin = process.stdin;
56
- if (!stdin.isTTY) {
57
- let data = "";
58
- stdin.on("data", (d) => {
59
- data += d;
60
- });
61
- stdin.on("end", () => resolve(data.trim()));
62
- return;
63
- }
64
- let value = "";
65
- stdin.setRawMode(true);
66
- stdin.resume();
67
- const onData = (buffer) => {
68
- for (const ch of buffer.toString()) {
69
- const code = ch.charCodeAt(0);
70
- if (code === 13 || code === 10) {
71
- stdin.setRawMode(false);
72
- stdin.pause();
73
- stdin.off("data", onData);
74
- process.stdout.write("\n");
75
- resolve(value.trim());
76
- return;
77
- }
78
- if (code === 3) process.exit(130);
79
- if (code === 127 || code === 8) {
80
- if (value) {
81
- value = value.slice(0, -1);
82
- process.stdout.write("\b \b");
83
- }
84
- continue;
85
- }
86
- const echo = echoFor(ch);
87
- if (echo) process.stdout.write(echo);
88
- value += ch;
89
- }
90
- };
91
- stdin.on("data", onData);
92
- });
93
- }
94
- function defaultLoginDeps() {
95
- return {
96
- out: (s) => console.log(s),
97
- err: (s) => console.error(s),
98
- env: process.env,
99
- isTTY: process.stdin.isTTY ?? false,
100
- open: (url) => defaultOpen(new URL(url)),
101
- readLine,
102
- saveCredential: (id, key) => saveCredential(id, key, process.env),
103
- removeCredential: (id) => removeCredential(id, process.env),
104
- fetch: globalThis.fetch,
105
- // Wiring NYATA jalur lama: persis runLogin lama (provider add + prompt key).
106
- legacyAdd: async (providerId, targetCwd) => {
107
- const { runProviderCommand } = await import("./providerCli-3TFEKV4C.js");
108
- const { parseCliArgs: parse } = await import("./args-XVO7TB4C.js");
109
- return runProviderCommand(parse(["provider", "add", providerId]), {
110
- env: process.env,
111
- cwd: targetCwd,
112
- out: (s) => console.log(s),
113
- err: (s) => console.error(s),
114
- readSecret
115
- });
116
- }
117
- };
118
- }
119
- async function runLogin(providerId, cwd, args, deps) {
120
- if (args.key && args.logout) {
121
- deps.err(t("Use either --key or --logout, not both."));
122
- return 1;
123
- }
124
- if (args.logout) {
125
- if (providerId !== "openrouter") {
126
- deps.err(
127
- t("Logout is not supported for {id}; use bccli provider remove {id} to delete its stored key and config.", {
128
- id: providerId
129
- })
130
- );
131
- return 1;
132
- }
133
- const { runOauthLogout } = await import("./oauthLogin-THSM6FE7.js");
134
- return runOauthLogout({ out: deps.out, err: deps.err, env: deps.env, removeCredential: deps.removeCredential });
135
- }
136
- if (args.key) return deps.legacyAdd(providerId, cwd);
137
- if (providerId === "openrouter") {
138
- const { runOauthLogin } = await import("./oauthLogin-THSM6FE7.js");
139
- return runOauthLogin({
140
- out: deps.out,
141
- err: deps.err,
142
- env: deps.env,
143
- isTTY: deps.isTTY,
144
- open: deps.open,
145
- readLine: deps.readLine,
146
- saveCredential: deps.saveCredential,
147
- fetch: deps.fetch
148
- });
149
- }
150
- return deps.legacyAdd(providerId, cwd);
151
- }
152
-
153
- export {
154
- readSecret,
155
- echoFor,
156
- readLine,
157
- defaultLoginDeps,
158
- runLogin
159
- };
@@ -1,88 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/tokenBudget.ts
4
- var IMAGE_TOKEN_COST = 1e3;
5
- var estimateTokens = (text) => Math.ceil(text.length / 4);
6
- function isImageAttachmentMessage(m) {
7
- if (m.role !== "user" || !Array.isArray(m.content)) return false;
8
- const hasImage = m.content.some((p) => p.type === "image_url");
9
- const firstText = m.content.find((p) => p.type === "text");
10
- return hasImage && !!firstText && firstText.type === "text" && firstText.text.startsWith("Image read from ");
11
- }
12
- function isUserTurnBoundary(m) {
13
- return m.role === "user" && !isImageAttachmentMessage(m);
14
- }
15
- function estimateMessages(messages) {
16
- let total = 0;
17
- for (const m of messages) {
18
- if (m.role === "user" && Array.isArray(m.content)) {
19
- for (const part of m.content) {
20
- if (part.type === "image_url") total += IMAGE_TOKEN_COST;
21
- else total += estimateTokens(part.text);
22
- }
23
- total += 8;
24
- } else {
25
- total += estimateTokens(JSON.stringify(m));
26
- }
27
- }
28
- return total;
29
- }
30
- function trimToFit(messages, maxTokens) {
31
- let out = messages;
32
- while (estimateMessages(out) > maxTokens) {
33
- const boundary = out.findIndex((m, i) => i > 0 && isUserTurnBoundary(m));
34
- if (boundary === -1) return out;
35
- out = out.slice(boundary);
36
- }
37
- return out;
38
- }
39
- function splitKeepRecent(messages, keepTokens) {
40
- if (messages.length === 0) return [[], []];
41
- let start = messages.length;
42
- for (let i = messages.length - 1; i >= 0; i--) {
43
- if (i > 0 && !isUserTurnBoundary(messages[i])) continue;
44
- if (estimateMessages(messages.slice(i)) <= keepTokens) start = i;
45
- else break;
46
- }
47
- if (start === messages.length) {
48
- for (let i = messages.length - 1; i >= 0; i--) {
49
- if (isUserTurnBoundary(messages[i])) {
50
- start = i;
51
- break;
52
- }
53
- }
54
- }
55
- return [messages.slice(0, start), messages.slice(start)];
56
- }
57
- var TOOL_STUB = "[Old tool result content cleared]";
58
- var TOOL_PRUNE_KEEP_TOKENS = 4e4;
59
- var TOOL_PRUNE_MIN_TOKENS = 2e4;
60
- var isToolStub = (content) => content.startsWith(TOOL_STUB);
61
- function pruneOldToolOutputs(messages) {
62
- let kept = 0;
63
- let oldTokens = 0;
64
- const old = [];
65
- for (let i = messages.length - 1; i >= 0; i--) {
66
- const m = messages[i];
67
- if (m.role !== "tool" || isToolStub(m.content)) continue;
68
- kept += estimateTokens(m.content);
69
- if (kept > TOOL_PRUNE_KEEP_TOKENS) {
70
- old.push(i);
71
- oldTokens += estimateTokens(m.content);
72
- }
73
- }
74
- if (oldTokens <= TOOL_PRUNE_MIN_TOKENS) return false;
75
- for (const i of old) {
76
- const m = messages[i];
77
- messages[i] = { ...m, content: TOOL_STUB };
78
- }
79
- return true;
80
- }
81
-
82
- export {
83
- estimateTokens,
84
- estimateMessages,
85
- trimToFit,
86
- splitKeepRecent,
87
- pruneOldToolOutputs
88
- };
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/tools/types.ts
4
- function defineTool(tool) {
5
- return tool;
6
- }
7
-
8
- export {
9
- defineTool
10
- };
@@ -1,91 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ConfigError,
4
- writeFileAtomic
5
- } from "./chunk-TLCL6DC7.js";
6
- import {
7
- t
8
- } from "./chunk-R754XIBJ.js";
9
-
10
- // src/mcp/config.ts
11
- import { createHash } from "crypto";
12
- import { existsSync, mkdirSync, readFileSync } from "fs";
13
- import { dirname, join, resolve } from "path";
14
- var ENV_REF = /\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g;
15
- function expandEnvVars(config, env) {
16
- const expand = (value) => value.replace(ENV_REF, (match, name, fallback) => {
17
- const resolved = env[name];
18
- if (resolved !== void 0) return resolved;
19
- return fallback !== void 0 ? fallback : match;
20
- });
21
- const expandMap = (map) => Object.fromEntries(Object.entries(map).map(([k, v]) => [k, expand(v)]));
22
- if (config.type === "http") {
23
- return { ...config, url: expand(config.url), ...config.headers ? { headers: expandMap(config.headers) } : {} };
24
- }
25
- return {
26
- ...config,
27
- command: expand(config.command),
28
- ...config.args ? { args: config.args.map(expand) } : {},
29
- ...config.env ? { env: expandMap(config.env) } : {}
30
- };
31
- }
32
- var globalMcpPath = (home) => join(home, "mcp.json");
33
- var projectMcpPath = (cwd) => join(cwd, ".bccli", "mcp.json");
34
- var trustPath = (home) => join(home, "trusted-mcp.json");
35
- function readJson(path, fallback) {
36
- if (!existsSync(path)) return fallback;
37
- try {
38
- return JSON.parse(readFileSync(path, "utf8"));
39
- } catch (error) {
40
- throw new ConfigError(t("Invalid MCP file: {path} ({error})", { path, error: error.message }));
41
- }
42
- }
43
- function writePrivate(path, data) {
44
- mkdirSync(dirname(path), { recursive: true });
45
- writeFileAtomic(path, `${JSON.stringify(data, null, 2)}
46
- `, 384);
47
- }
48
- function readMcpFile(path) {
49
- return readJson(path, {}).mcpServers ?? {};
50
- }
51
- function addGlobalServer(home, name, config) {
52
- writePrivate(globalMcpPath(home), { mcpServers: { ...readMcpFile(globalMcpPath(home)), [name]: config } });
53
- }
54
- function removeGlobalServer(home, name) {
55
- const { [name]: _removed, ...rest } = readMcpFile(globalMcpPath(home));
56
- writePrivate(globalMcpPath(home), { mcpServers: rest });
57
- }
58
- var configHash = (config) => createHash("sha256").update(JSON.stringify(config)).digest("hex");
59
- function projectTrust(home, cwd, name, config) {
60
- const decision = readJson(trustPath(home), {})[resolve(cwd)]?.[name];
61
- return decision?.hash === configHash(config) ? decision.allowed : void 0;
62
- }
63
- function setProjectTrust(home, cwd, name, allowed, config) {
64
- const all = readJson(trustPath(home), {});
65
- const key = resolve(cwd);
66
- writePrivate(trustPath(home), { ...all, [key]: { ...all[key], [name]: { allowed, hash: configHash(config) } } });
67
- }
68
- function serversToStart(home, cwd) {
69
- const global = readMcpFile(globalMcpPath(home));
70
- const start = Object.entries(global).map(([name, config]) => ({ name, config, source: "global" }));
71
- const needTrust = [];
72
- for (const [name, config] of Object.entries(readMcpFile(projectMcpPath(cwd)))) {
73
- if (global[name]) continue;
74
- const trust = projectTrust(home, cwd, name, config);
75
- if (trust === true) start.push({ name, config, source: "project" });
76
- else if (trust === void 0) needTrust.push({ name, config, source: "project" });
77
- }
78
- return { start, needTrust };
79
- }
80
-
81
- export {
82
- expandEnvVars,
83
- globalMcpPath,
84
- projectMcpPath,
85
- readMcpFile,
86
- addGlobalServer,
87
- removeGlobalServer,
88
- projectTrust,
89
- setProjectTrust,
90
- serversToStart
91
- };