@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,353 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- estimateTokens
4
- } from "./chunk-OK2USAXX.js";
5
- import {
6
- t
7
- } from "./chunk-R754XIBJ.js";
8
-
9
- // src/statsCli.ts
10
- import { existsSync, readdirSync, readFileSync, statSync } from "fs";
11
- import { join } from "path";
12
- function isUsageRecord(value) {
13
- if (!value || typeof value !== "object") return false;
14
- const v = value;
15
- return v.t === "usage" && typeof v.inputTokens === "number" && typeof v.outputTokens === "number";
16
- }
17
- function isMsgRecord(value) {
18
- if (!value || typeof value !== "object") return false;
19
- const v = value;
20
- return v.t === "msg" && !!v.m;
21
- }
22
- function emptyRow(project) {
23
- return {
24
- project,
25
- sessions: 0,
26
- messages: 0,
27
- inputTokens: 0,
28
- outputTokens: 0,
29
- usageInputTokens: 0,
30
- usageOutputTokens: 0,
31
- cachedInputTokens: 0,
32
- cacheWriteTokens: 0,
33
- toolCalls: {},
34
- sessionTotals: [],
35
- modelUsage: {}
36
- };
37
- }
38
- function aggregateSessions(home, opts) {
39
- const now = opts.now ?? Date.now();
40
- const cutoff = now - opts.days * 864e5;
41
- const root = join(home, "sessions");
42
- if (!existsSync(root)) return [];
43
- const byProject = /* @__PURE__ */ new Map();
44
- for (const project of readdirSync(root)) {
45
- const dir = join(root, project);
46
- let st;
47
- try {
48
- st = statSync(dir);
49
- } catch {
50
- continue;
51
- }
52
- if (!st.isDirectory()) continue;
53
- for (const file of readdirSync(dir)) {
54
- if (!file.endsWith(".jsonl")) continue;
55
- const path = join(dir, file);
56
- let fst;
57
- try {
58
- fst = statSync(path);
59
- } catch {
60
- continue;
61
- }
62
- if (fst.mtimeMs < cutoff) continue;
63
- let row = byProject.get(project);
64
- if (!row) {
65
- row = emptyRow(project);
66
- byProject.set(project, row);
67
- }
68
- row.sessions++;
69
- let usageIn = 0;
70
- let usageOut = 0;
71
- let cachedIn = 0;
72
- let cacheWrite = 0;
73
- let usageCount = 0;
74
- let estIn = 0;
75
- let estOut = 0;
76
- let messages = 0;
77
- const tools = {};
78
- for (const line of readFileSync(path, "utf8").split("\n")) {
79
- if (!line.trim()) continue;
80
- let record;
81
- try {
82
- record = JSON.parse(line);
83
- } catch {
84
- continue;
85
- }
86
- if (isUsageRecord(record)) {
87
- usageIn += record.inputTokens;
88
- usageOut += record.outputTokens;
89
- cachedIn += record.cachedInputTokens ?? 0;
90
- cacheWrite += record.cacheWriteTokens ?? 0;
91
- usageCount++;
92
- if (record.model) {
93
- let mt = row.modelUsage[record.model];
94
- if (!mt) {
95
- mt = { turns: 0, inputTokens: 0, outputTokens: 0, cachedInputTokens: 0, cacheWriteTokens: 0 };
96
- row.modelUsage[record.model] = mt;
97
- }
98
- mt.turns++;
99
- mt.inputTokens += record.inputTokens;
100
- mt.outputTokens += record.outputTokens;
101
- mt.cachedInputTokens += record.cachedInputTokens ?? 0;
102
- mt.cacheWriteTokens += record.cacheWriteTokens ?? 0;
103
- }
104
- continue;
105
- }
106
- if (!isMsgRecord(record)) continue;
107
- messages++;
108
- if (record.m.role === "user" || record.m.role === "assistant") {
109
- const text = typeof record.m.content === "string" ? record.m.content : JSON.stringify(record.m.content ?? "");
110
- const tokens = estimateTokens(text);
111
- if (record.m.role === "user") estIn += tokens;
112
- else estOut += tokens;
113
- }
114
- if (record.m.role === "assistant") {
115
- for (const call of record.m.tool_calls ?? []) {
116
- const name = call?.function?.name;
117
- if (typeof name === "string" && name) tools[name] = (tools[name] ?? 0) + 1;
118
- }
119
- }
120
- }
121
- row.messages += messages;
122
- if (usageCount > 0) {
123
- row.usageInputTokens += usageIn;
124
- row.usageOutputTokens += usageOut;
125
- row.cachedInputTokens += cachedIn;
126
- row.cacheWriteTokens += cacheWrite;
127
- row.sessionTotals.push(usageIn + usageOut);
128
- } else {
129
- row.inputTokens += estIn;
130
- row.outputTokens += estOut;
131
- row.sessionTotals.push(estIn + estOut);
132
- }
133
- for (const [name, count] of Object.entries(tools)) row.toolCalls[name] = (row.toolCalls[name] ?? 0) + count;
134
- }
135
- }
136
- return [...byProject.values()].sort((a, b) => b.messages - a.messages || a.project.localeCompare(b.project));
137
- }
138
- function fmtCompact(n) {
139
- if (n < 1e3) return String(Math.round(n));
140
- const units = [
141
- [1e9, "B"],
142
- [1e6, "M"],
143
- [1e3, "K"]
144
- ];
145
- for (const [size, suffix] of units) {
146
- if (n >= size) return `${(n / size).toFixed(1)}${suffix}`;
147
- }
148
- return String(Math.round(n));
149
- }
150
- function fmtCount(n) {
151
- return n.toLocaleString("en-US");
152
- }
153
- function median(values) {
154
- if (!values.length) return 0;
155
- const sorted = [...values].sort((a, b) => a - b);
156
- const mid = sorted.length >> 1;
157
- return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
158
- }
159
- var BOX_INNER = 46;
160
- function border(left, right) {
161
- return `${left}${"\u2500".repeat(BOX_INNER + 2)}${right}`;
162
- }
163
- function center(text) {
164
- const pad = Math.max(0, BOX_INNER - text.length);
165
- const left = Math.floor(pad / 2);
166
- return `\u2502${" ".repeat(left)}${text}${" ".repeat(pad - left)}\u2502`;
167
- }
168
- function contentLine(content) {
169
- return `\u2502${content}${" ".repeat(Math.max(1, BOX_INNER + 1 - content.length))}\u2502`;
170
- }
171
- function valueLine(label, value) {
172
- return contentLine(` ${label}${" ".repeat(Math.max(1, BOX_INNER - 1 - label.length - value.length))}${value}`);
173
- }
174
- function box(title, rows) {
175
- return [border("\u250C", "\u2510"), center(title), border("\u251C", "\u2524"), ...rows.map(([l, v]) => valueLine(l, v)), border("\u2514", "\u2518")];
176
- }
177
- function truncateName(name) {
178
- return name.length > 18 ? `${name.slice(0, 16)}..` : name;
179
- }
180
- function toolBox(tools) {
181
- const total = tools.reduce((sum, [, n]) => sum + n, 0);
182
- const max = tools[0]?.[1] ?? 1;
183
- const lines = tools.map(([name, count]) => {
184
- const blocks = Math.max(1, Math.round(count / max * 20));
185
- const pct = (count / total * 100).toFixed(1).padStart(5);
186
- return contentLine(` ${truncateName(name).padEnd(16)} ${"\u2588".repeat(blocks).padEnd(20)} ${count} (${pct}%)`);
187
- });
188
- return [border("\u250C", "\u2510"), center("TOOL USAGE"), border("\u251C", "\u2524"), ...lines, border("\u2514", "\u2518")];
189
- }
190
- function modelBox(models) {
191
- const lines = [];
192
- for (let i = 0; i < models.length; i++) {
193
- const [name, m] = models[i];
194
- if (i > 0) lines.push(border("\u251C", "\u2524"));
195
- lines.push(contentLine(` ${truncateName(name)}`));
196
- lines.push(valueLine(" Turns", fmtCount(m.turns)));
197
- lines.push(valueLine(" Input Tokens", fmtCompact(m.inputTokens)));
198
- lines.push(valueLine(" Output Tokens", fmtCompact(m.outputTokens)));
199
- lines.push(valueLine(" Cache Read", fmtCompact(m.cachedInputTokens)));
200
- lines.push(valueLine(" Cache Write", fmtCompact(m.cacheWriteTokens)));
201
- }
202
- return [border("\u250C", "\u2510"), center("MODEL USAGE"), border("\u251C", "\u2524"), ...lines, border("\u2514", "\u2518")];
203
- }
204
- function projectSlug(cwd) {
205
- return cwd.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(-100) || "root";
206
- }
207
- function runStatsCommand(args, deps) {
208
- let days = args.days ?? 7;
209
- let toolsCap = args.tools;
210
- let modelsFlag = args.models;
211
- let projectFilter = args.project;
212
- const rest = args.subArgs;
213
- for (let i = 0; i < rest.length; i++) {
214
- const a = rest[i];
215
- if (a === "--days" || a === "--tools" || a === "--models" || a === "--project") {
216
- const raw = rest[++i] ?? "";
217
- if (a === "--days") {
218
- const n = Number(raw);
219
- if (!Number.isInteger(n) || n < 1) {
220
- deps.err?.(t("--days must be a positive integer"));
221
- return 1;
222
- }
223
- days = n;
224
- } else if (a === "--tools") {
225
- const n = Number(raw);
226
- if (!Number.isInteger(n) || n < 1) {
227
- deps.err?.(t("--tools must be a positive integer"));
228
- return 1;
229
- }
230
- toolsCap = n;
231
- } else if (a === "--models") {
232
- if (raw === "" || raw === "all" || raw.startsWith("-")) {
233
- modelsFlag = "all";
234
- if (raw.startsWith("-")) i--;
235
- } else {
236
- const n = Number(raw);
237
- if (!Number.isInteger(n) || n < 1) {
238
- deps.err?.(t('--models must be a positive integer or "all"'));
239
- return 1;
240
- }
241
- modelsFlag = raw;
242
- }
243
- } else {
244
- projectFilter = raw;
245
- }
246
- } else if (a.startsWith("--days=")) {
247
- const n = Number(a.slice("--days=".length));
248
- if (!Number.isInteger(n) || n < 1) {
249
- deps.err?.(t("--days must be a positive integer"));
250
- return 1;
251
- }
252
- days = n;
253
- } else if (a.startsWith("--tools=")) {
254
- const n = Number(a.slice("--tools=".length));
255
- if (!Number.isInteger(n) || n < 1) {
256
- deps.err?.(t("--tools must be a positive integer"));
257
- return 1;
258
- }
259
- toolsCap = n;
260
- } else if (a.startsWith("--models=")) {
261
- const raw = a.slice("--models=".length);
262
- if (raw === "" || raw === "all") {
263
- modelsFlag = "all";
264
- } else {
265
- const n = Number(raw);
266
- if (!Number.isInteger(n) || n < 1) {
267
- deps.err?.(t('--models must be a positive integer or "all"'));
268
- return 1;
269
- }
270
- modelsFlag = raw;
271
- }
272
- } else if (a.startsWith("--project=")) {
273
- projectFilter = a.slice("--project=".length);
274
- }
275
- }
276
- let rows = aggregateSessions(args.home, { days, now: args.now });
277
- if (projectFilter !== void 0) {
278
- const needle = projectFilter === "" ? projectSlug(args.cwd ?? "") : projectFilter;
279
- rows = rows.filter((r) => r.project.includes(needle));
280
- }
281
- if (!rows.length) {
282
- deps.out(t("no sessions in the last {days} day(s)", { days: String(days) }));
283
- return 0;
284
- }
285
- const sessions = rows.reduce((s, r) => s + r.sessions, 0);
286
- const messages = rows.reduce((s, r) => s + r.messages, 0);
287
- const input = rows.reduce((s, r) => s + r.inputTokens + r.usageInputTokens, 0);
288
- const output = rows.reduce((s, r) => s + r.outputTokens + r.usageOutputTokens, 0);
289
- const cachedIn = rows.reduce((s, r) => s + r.cachedInputTokens, 0);
290
- const cacheWrite = rows.reduce((s, r) => s + r.cacheWriteTokens, 0);
291
- const totals = rows.flatMap((r) => r.sessionTotals);
292
- const avg = totals.length ? totals.reduce((s, n) => s + n, 0) / totals.length : 0;
293
- const tools = {};
294
- for (const r of rows) for (const [name, count] of Object.entries(r.toolCalls)) tools[name] = (tools[name] ?? 0) + count;
295
- const modelUsage = {};
296
- for (const r of rows) {
297
- for (const [name, m] of Object.entries(r.modelUsage)) {
298
- let mt = modelUsage[name];
299
- if (!mt) {
300
- mt = { turns: 0, inputTokens: 0, outputTokens: 0, cachedInputTokens: 0, cacheWriteTokens: 0 };
301
- modelUsage[name] = mt;
302
- }
303
- mt.turns += m.turns;
304
- mt.inputTokens += m.inputTokens;
305
- mt.outputTokens += m.outputTokens;
306
- mt.cachedInputTokens += m.cachedInputTokens;
307
- mt.cacheWriteTokens += m.cacheWriteTokens;
308
- }
309
- }
310
- for (const line of box("OVERVIEW", [
311
- ["Sessions", fmtCount(sessions)],
312
- ["Messages", fmtCount(messages)],
313
- ["Days", String(days)]
314
- ])) deps.out(line);
315
- deps.out("");
316
- for (const line of box("TOKENS", [
317
- ["Input", fmtCompact(input)],
318
- ["Output", fmtCompact(output)],
319
- ["Cache Read", fmtCompact(cachedIn)],
320
- ["Cache Write", fmtCompact(cacheWrite)],
321
- ["Avg Tokens/Session", fmtCompact(avg)],
322
- ["Median Tokens/Session", fmtCompact(median(totals))]
323
- ])) deps.out(line);
324
- if (modelsFlag !== void 0) {
325
- let modelEntries = Object.entries(modelUsage).sort(
326
- (a, b) => b[1].inputTokens + b[1].outputTokens - (a[1].inputTokens + a[1].outputTokens) || a[0].localeCompare(b[0])
327
- );
328
- if (modelsFlag !== "all") modelEntries = modelEntries.slice(0, Number(modelsFlag));
329
- if (modelEntries.length) {
330
- deps.out("");
331
- for (const line of modelBox(modelEntries)) deps.out(line);
332
- }
333
- }
334
- let toolEntries = Object.entries(tools).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
335
- if (toolsCap !== void 0) toolEntries = toolEntries.slice(0, toolsCap);
336
- if (toolEntries.length) {
337
- deps.out("");
338
- for (const line of toolBox(toolEntries)) deps.out(line);
339
- }
340
- deps.out("");
341
- deps.out(t("sessions (last {days} day(s)):", { days: String(days) }));
342
- for (const r of rows) {
343
- const inputTotal = r.inputTokens + r.usageInputTokens;
344
- const outputTotal = r.outputTokens + r.usageOutputTokens;
345
- deps.out(`${r.project} ${r.sessions} ${t("session(s)")} ${r.messages} ${t("message(s)")} ${fmtCompact(inputTotal)}in/${fmtCompact(outputTotal)}out`);
346
- }
347
- return 0;
348
- }
349
- export {
350
- aggregateSessions,
351
- fmtCompact,
352
- runStatsCommand
353
- };
@@ -1,62 +0,0 @@
1
- export interface StatsRow {
2
- project: string;
3
- sessions: number;
4
- messages: number;
5
- /** Estimated tokens (messages without recorded usage only). */
6
- inputTokens: number;
7
- outputTokens: number;
8
- /** Tokens from persisted `t:usage` records. */
9
- usageInputTokens: number;
10
- usageOutputTokens: number;
11
- cachedInputTokens: number;
12
- cacheWriteTokens: number;
13
- toolCalls: Record<string, number>;
14
- /** Total tokens per session (recorded basis when present, estimate otherwise). */
15
- sessionTotals: number[];
16
- /** Per-model token totals from `t:usage` records that carry a model ref. */
17
- modelUsage: Record<string, ModelTotals>;
18
- }
19
- export interface ModelTotals {
20
- turns: number;
21
- inputTokens: number;
22
- outputTokens: number;
23
- cachedInputTokens: number;
24
- cacheWriteTokens: number;
25
- }
26
- export interface AggregateOptions {
27
- days: number;
28
- now?: number;
29
- }
30
- /**
31
- * Walk home/sessions/<project>/*.jsonl, keep files with mtime within `days`,
32
- * and aggregate per project. Token basis switches per session: sessions with
33
- * recorded usage records use them (incl. cache counters); older sessions fall
34
- * back to ~4 chars/token estimates from message content.
35
- */
36
- export declare function aggregateSessions(home: string, opts: AggregateOptions): StatsRow[];
37
- /** Compact token formatting like the opencode stats boxes: 291.6K / 41.0M / 627.4M. */
38
- export declare function fmtCompact(n: number): string;
39
- export interface StatsCliArgs {
40
- subArgs: string[];
41
- home: string;
42
- cwd?: string;
43
- now?: number;
44
- /** Already-parsed `--days` from parseCliArgs (subArgs never contains it). */
45
- days?: number;
46
- /** Already-parsed `--tools` top-N cap. */
47
- tools?: number;
48
- /** Already-parsed `--models` ("all" or a number as string). */
49
- models?: string;
50
- /** Already-parsed `--project` filter (empty string = current project). */
51
- project?: string;
52
- }
53
- export interface StatsDeps {
54
- out(line: string): void;
55
- err?(line: string): void;
56
- }
57
- /**
58
- * `bccli stats [--days N] [--tools N] [--models [N|all]] [--project slug]` —
59
- * token usage and tool-call stats from local session files, rendered as
60
- * opencode-style overview/tokens/model/tool boxes.
61
- */
62
- export declare function runStatsCommand(args: StatsCliArgs, deps: StatsDeps): number;
@@ -1,6 +0,0 @@
1
- import type { ToolCall } from './provider';
2
- import type { ToolDefinition } from './tools/index';
3
- export declare function recoverTextToolCalls(text: string, tools: ToolDefinition[]): {
4
- text: string;
5
- toolCalls: ToolCall[];
6
- } | null;
@@ -1,17 +0,0 @@
1
- export declare class ThinkSplitter {
2
- private inside;
3
- private held;
4
- push(delta: string): {
5
- text: string;
6
- thinking: string;
7
- };
8
- /** Whatever was held back as a possible tag start is plain text after all. */
9
- flush(): {
10
- text: string;
11
- thinking: string;
12
- };
13
- }
14
- export declare function splitThinking(text: string): {
15
- text: string;
16
- thinking: string;
17
- };
@@ -1,22 +0,0 @@
1
- import type { ChatMessage } from './provider';
2
- /** ~4 chars per token, the same conservative estimate the usage fallback uses. */
3
- export declare const estimateTokens: (text: string) => number;
4
- export declare function estimateMessages(messages: ChatMessage[]): number;
5
- /**
6
- * Drops whole oldest turns (everything up to the next user message) until the history fits the
7
- * budget. Cutting only at turn boundaries keeps assistant tool_calls paired with their tool
8
- * replies, so the trimmed history is always valid for a provider request.
9
- */
10
- export declare function trimToFit(messages: ChatMessage[], maxTokens: number): ChatMessage[];
11
- /**
12
- * Splits history into [old, keep]: the newest whole turns that fit `keepTokens` (at least the
13
- * last user turn) stay verbatim; everything older goes to `old` for summarization. Cutting at
14
- * user boundaries keeps tool_calls paired with their replies.
15
- */
16
- export declare function splitKeepRecent(messages: ChatMessage[], keepTokens: number): [ChatMessage[], ChatMessage[]];
17
- export declare const isToolStub: (content: string) => boolean;
18
- /**
19
- * Replaces old tool results with a one-line stub once they add up past PRUNE_MIN_TOKENS, so the
20
- * prompt prefix (and its cache) changes rarely. The newest KEEP_TOKENS worth stay intact.
21
- */
22
- export declare function pruneOldToolOutputs(messages: ChatMessage[]): boolean;
@@ -1,54 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- import { z } from 'zod';
3
- import { type ShellDeps, type ShellSpec } from './shell';
4
- type Spawn = typeof spawn;
5
- /** Kill a command and everything it started. Never throws (e.g. taskkill missing on Windows). */
6
- export declare function killProcessTree(pid: number, platform?: NodeJS.Platform, spawnFn?: Spawn): void;
7
- export declare function killAllCommands(): void;
8
- /** Human-readable list for the /tasks slash command. */
9
- export declare function renderBackgroundTasks(): string;
10
- /** Test/exit helper: stop every background task and forget them. */
11
- export declare function resetBackgroundTasks(): void;
12
- export interface CommandResult {
13
- output: string;
14
- exitCode: number | null;
15
- timedOut: boolean;
16
- aborted: boolean;
17
- }
18
- export declare function needsNetwork(command: string): boolean;
19
- /** Proxy env pointing at a dead local port: tools that honour proxy vars fail fast offline. */
20
- export declare function offlineEnv(env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
21
- export declare function runCommand(command: string | string[], opts: {
22
- cwd: string;
23
- timeoutMs: number;
24
- signal: AbortSignal;
25
- env?: NodeJS.ProcessEnv;
26
- shell?: ShellSpec;
27
- }): Promise<CommandResult>;
28
- export interface BashToolOptions {
29
- /** "offline" blocks known network commands and points proxy env at a dead local port. */
30
- networkPolicy?: 'allow' | 'offline';
31
- /** Run every command inside the OS sandbox (sandbox-exec on macOS, bwrap on Linux). */
32
- sandbox?: boolean;
33
- /** Test hook: pretend to be another platform. */
34
- platform?: NodeJS.Platform;
35
- /** Test hook: fake environment / file lookup used to pick the Windows shell. */
36
- shellDeps?: Partial<ShellDeps>;
37
- /** How many finished background tasks are kept for polling (default 50). */
38
- maxRetainedTasks?: number;
39
- }
40
- export declare function createBashTool(options?: BashToolOptions): import("./types").Tool<z.ZodObject<{
41
- command: z.ZodOptional<z.ZodString>;
42
- timeout_ms: z.ZodOptional<z.ZodNumber>;
43
- background: z.ZodOptional<z.ZodBoolean>;
44
- task_id: z.ZodOptional<z.ZodNumber>;
45
- kill: z.ZodOptional<z.ZodBoolean>;
46
- }, z.core.$strip>>;
47
- export declare const bashTool: import("./types").Tool<z.ZodObject<{
48
- command: z.ZodOptional<z.ZodString>;
49
- timeout_ms: z.ZodOptional<z.ZodNumber>;
50
- background: z.ZodOptional<z.ZodBoolean>;
51
- task_id: z.ZodOptional<z.ZodNumber>;
52
- kill: z.ZodOptional<z.ZodBoolean>;
53
- }, z.core.$strip>>;
54
- export {};
@@ -1,13 +0,0 @@
1
- import { z } from 'zod';
2
- import { type LspServer } from '../lsp';
3
- export declare function createDiagnosticsTool(servers: LspServer[]): import("./types").Tool<z.ZodObject<{
4
- path: z.ZodString;
5
- action: z.ZodOptional<z.ZodEnum<{
6
- definition: "definition";
7
- diagnostics: "diagnostics";
8
- hover: "hover";
9
- references: "references";
10
- }>>;
11
- line: z.ZodOptional<z.ZodNumber>;
12
- character: z.ZodOptional<z.ZodNumber>;
13
- }, z.core.$strip>>;
@@ -1,12 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const editTool: import("./types").Tool<z.ZodObject<{
3
- path: z.ZodString;
4
- old_string: z.ZodOptional<z.ZodString>;
5
- new_string: z.ZodOptional<z.ZodString>;
6
- replace_all: z.ZodOptional<z.ZodBoolean>;
7
- edits: z.ZodOptional<z.ZodArray<z.ZodObject<{
8
- old_string: z.ZodString;
9
- new_string: z.ZodString;
10
- replace_all: z.ZodOptional<z.ZodBoolean>;
11
- }, z.core.$strip>>>;
12
- }, z.core.$strip>>;
@@ -1,41 +0,0 @@
1
- import { z } from 'zod';
2
- export declare function htmlToText(html: string): string;
3
- export declare function isPrivateHost(host: string): boolean;
4
- export interface PinnedAddress {
5
- address: string;
6
- family: number;
7
- }
8
- type LookupCallback = (err: NodeJS.ErrnoException | null, address: string | PinnedAddress[], family?: number) => void;
9
- /**
10
- * A DNS lookup that answers with the address the rebinding guard already validated,
11
- * so the socket connects to exactly the IP that was checked (closes the
12
- * resolve-then-fetch gap). An empty pin falls back to the real resolver; a family
13
- * mismatch refuses instead of re-resolving, and unknown hostnames use real DNS.
14
- */
15
- export declare function pinLookup(pinned: PinnedAddress[]): (hostname: string, options: unknown, callback: LookupCallback) => void;
16
- /** Best BM25 chunks for `query`, in page order; null when no chunk shares a word with it. */
17
- export declare function pickRelevant(text: string, query: string, count?: number, size?: number): string | null;
18
- export declare const clearFetchCache: () => void;
19
- export interface FetchToolOptions {
20
- /** Keenable fetch endpoint used when `prompt` is given; null disables it. */
21
- keenableURL?: string | null;
22
- isPrivate?: (host: string) => boolean;
23
- /** DNS resolver for the rebinding guard; injectable for tests. */
24
- lookup?: (hostname: string) => Promise<Array<{
25
- address: string;
26
- family: number;
27
- }>>;
28
- /** Page fetch override for tests; receives the same init (including `dispatcher`). */
29
- fetchPage?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
30
- }
31
- export declare function createFetchTool(opts?: FetchToolOptions): import("./types").Tool<z.ZodObject<{
32
- url: z.ZodString;
33
- prompt: z.ZodOptional<z.ZodString>;
34
- offset: z.ZodOptional<z.ZodNumber>;
35
- }, z.core.$strip>>;
36
- export declare const fetchTool: import("./types").Tool<z.ZodObject<{
37
- url: z.ZodString;
38
- prompt: z.ZodOptional<z.ZodString>;
39
- offset: z.ZodOptional<z.ZodNumber>;
40
- }, z.core.$strip>>;
41
- export {};
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const globTool: import("./types").Tool<z.ZodObject<{
3
- pattern: z.ZodString;
4
- path: z.ZodOptional<z.ZodString>;
5
- }, z.core.$strip>>;
@@ -1,7 +0,0 @@
1
- /**
2
- * Reject glob inputs that can trigger pathological brace expansion before they
3
- * reach the glob engine. Backslash-escaped braces are literals.
4
- */
5
- export declare function validateGlobPattern(pattern: string): string | undefined;
6
- /** Keep tool/UI path output stable across Windows and POSIX. */
7
- export declare function normalizeGlobPath(path: string): string;
@@ -1,25 +0,0 @@
1
- import { z } from 'zod';
2
- export interface GrepOptions {
3
- root: string;
4
- projectRoot?: string;
5
- glob?: string;
6
- ignoreCase?: boolean;
7
- literal?: boolean;
8
- context?: number;
9
- outputMode?: 'content' | 'files_with_matches' | 'count';
10
- signal?: AbortSignal;
11
- }
12
- export declare function grepJs(pattern: string, opts: GrepOptions): Promise<string[]>;
13
- export declare const grepTool: import("./types").Tool<z.ZodObject<{
14
- pattern: z.ZodString;
15
- path: z.ZodOptional<z.ZodString>;
16
- glob: z.ZodOptional<z.ZodString>;
17
- ignore_case: z.ZodOptional<z.ZodBoolean>;
18
- literal: z.ZodOptional<z.ZodBoolean>;
19
- context: z.ZodOptional<z.ZodNumber>;
20
- output_mode: z.ZodOptional<z.ZodEnum<{
21
- content: "content";
22
- count: "count";
23
- files_with_matches: "files_with_matches";
24
- }>>;
25
- }, z.core.$strip>>;
@@ -1,2 +0,0 @@
1
- /** Native glob exclude patterns: node_modules, .git, and .gitignore entries up to projectRoot. */
2
- export declare function ignorePatterns(root: string, projectRoot?: string): string[];
@@ -1,12 +0,0 @@
1
- import type { Tool } from './types';
2
- export interface ToolDefinition {
3
- type: 'function';
4
- function: {
5
- name: string;
6
- description: string;
7
- parameters: Record<string, unknown>;
8
- output_schema?: Record<string, unknown>;
9
- };
10
- }
11
- export declare const ALL_TOOLS: Tool[];
12
- export declare function toolDefinitions(tools: Tool[]): ToolDefinition[];
@@ -1,13 +0,0 @@
1
- import { defineTool } from './types';
2
- export interface SaveMemoryOptions {
3
- /** Global store lives at <home>/BCCLI.md; project store at <cwd>/AGENTS.md. */
4
- home: string;
5
- /** Called after the instruction files changed so the system prompt can be rebuilt. */
6
- onSaved?: () => void;
7
- }
8
- /**
9
- * Lets the model persist durable facts itself (same store as /memory): project rules
10
- * go to AGENTS.md, cross-project preferences to the global BCCLI.md. Duplicate lines
11
- * are not written again.
12
- */
13
- export declare function createSaveMemoryTool(opts: SaveMemoryOptions): ReturnType<typeof defineTool>;
@@ -1,4 +0,0 @@
1
- export declare function resolvePath(cwd: string, path: string): string;
2
- export declare function errorCode(error: unknown): string;
3
- export declare function recordFileMtime(readFiles: Set<string>, abs: string): void;
4
- export declare function isFileModifiedSinceRead(readFiles: Set<string>, abs: string): boolean;