@shuyhere/bb-agent 0.0.16 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.0.18] - 2026-04-18
11
+
12
+ ### Added
13
+
14
+ - added `/exit` as a shared TUI slash-command alias for `/quit`, including help/menu/autocomplete coverage
15
+
16
+ ### Changed
17
+
18
+ - cache metrics now explicitly follow auth mode: API-key sessions report `official` cache-hit provenance while OAuth sessions report `estimate`
19
+ - provider-side cache-affinity shaping is now restored for OpenAI and Anthropic baseline requests, improving cache-monitor consistency and estimate-vs-official comparisons
20
+ - the TUI cache monitor now renders on the footer/path line and labels cache source directly as `cache hit (official|estimate|mixed|unknown)`
21
+
22
+ ### Fixed
23
+
24
+ - OAuth estimated cache-hit normalization no longer pegs changed prompts to misleading `100.0%` latest-hit readings
25
+ - switching models or auth sources now resets latest-request cache state so the monitor starts cold instead of reusing stale latest-hit/source data from the previous cache domain
26
+ - clean `bb-tui` test builds no longer fail on the stale `wrap_visual_line` test-only re-export visibility issue
27
+
28
+ ### Improved
29
+
30
+ - cache-monitor wording, placement, and reset behavior are now more trustworthy for manual validation across provider/auth combinations
31
+
32
+ ## [0.0.17] - 2026-04-17
33
+
34
+ ### Added
35
+
36
+ - added the reusable `bb-monitor` backend crate and wired request metrics, session usage summaries, and cache provenance tracking through it
37
+ - added a dedicated under-input TUI cache monitor that shows cache source plus average and latest request hit rate
38
+ - added a profile-aware auth store with saved timestamps, active-profile tracking, and richer provider auth summaries in `/model`
39
+
40
+ ### Changed
41
+
42
+ - `/model` now supports choosing auth source/profile as part of model selection when a provider has multiple usable auth options
43
+ - `/login` now exposes concrete auth-option choosers instead of only coarse method picks, including switching among saved/env-backed auth and starting new provider logins from the same flow
44
+ - providers that support it can now keep multiple saved OAuth profiles and multiple saved API-key profiles side-by-side for the same provider, with safe labels to distinguish saved keys
45
+
46
+ ### Fixed
47
+
48
+ - OpenAI GPT-5 API-key requests now use the Responses API when tools/reasoning are involved instead of failing against chat completions with `reasoning_effort` errors
49
+ - `/session` now reports the live session auth override when auth was explicitly selected in-session instead of falling back to default provider resolution
50
+ - auth/profile menus now disambiguate saved API-key profiles even when labels would otherwise look too similar
51
+
52
+ ### Improved
53
+
54
+ - footer, `/session`, `/login`, and `/model` now present provider auth state more consistently, including explicit auth method/source/account details and safer saved-profile switching flows
55
+ - cache monitor visibility and provider-metric provenance are clearer across session summaries, request tracking, and the TUI monitor line
56
+
10
57
  ## [0.0.16] - 2026-04-15
11
58
 
12
59
  ### Added
@@ -174,6 +221,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
174
221
 
175
222
  - latest published package includes the post-0.0.7 startup, auth, model-default, and update-notice improvements
176
223
 
224
+ [0.0.18]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.18
225
+ [0.0.17]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.17
177
226
  [0.0.16]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.16
178
227
  [0.0.15]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.15
179
228
  [0.0.14]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuyhere/bb-agent",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "BB-Agent — a Rust-native AI coding agent for the terminal",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,6 +9,7 @@ const os = require("os");
9
9
  const https = require("https");
10
10
  const http = require("http");
11
11
  const zlib = require("zlib");
12
+ const { pipeline } = require("stream/promises");
12
13
 
13
14
  const packageJson = require("../package.json");
14
15
  const BINARY_RELEASE_TAG = `v${packageJson.version}`;
@@ -204,8 +205,14 @@ function copyBinary(src, dest) {
204
205
  function installFromVerifiedCache(target) {
205
206
  const cached = cacheBinaryPath(target);
206
207
  const meta = loadCacheMetadata(target);
207
- if (!fs.existsSync(cached) || !meta) return false;
208
- if (meta.version !== packageJson.version || meta.target !== target) return false;
208
+ if (!fs.existsSync(cached) || !meta) {
209
+ logLine(`No verified cached BB-Agent binary found for ${target} yet.`);
210
+ return false;
211
+ }
212
+ if (meta.version !== packageJson.version || meta.target !== target) {
213
+ logLine(`Ignoring stale cache metadata for ${target}; expected ${packageJson.version}.`);
214
+ return false;
215
+ }
209
216
 
210
217
  let stat;
211
218
  try {
@@ -214,9 +221,13 @@ function installFromVerifiedCache(target) {
214
221
  return false;
215
222
  }
216
223
  if (!stat.isFile() || stat.size <= 0) return false;
217
- if (meta.size && stat.size !== meta.size) return false;
224
+ if (meta.size && stat.size !== meta.size) {
225
+ logLine(`Cached BB-Agent binary for ${target} changed size; re-validating it.`);
226
+ return false;
227
+ }
218
228
 
219
229
  logLine(`Using cached BB-Agent binary for ${target} (${formatBytes(stat.size)}).`);
230
+ logLine(`Installing cached binary to ${nativeBinaryPath()}.`);
220
231
  copyBinary(cached, nativeBinaryPath());
221
232
  return true;
222
233
  }
@@ -245,8 +256,9 @@ function maybeRepairCache(target) {
245
256
  }
246
257
  }
247
258
 
248
- logLine(`Checking cached BB-Agent binary for ${target}...`);
259
+ logLine(`Checking cached BB-Agent binary for ${target} at ${cached}...`);
249
260
  if (!binaryMatchesCurrentVersion(cached)) {
261
+ logLine(`Cached binary for ${target} is stale or invalid; removing cached copy.`);
250
262
  removeIfExists(cached);
251
263
  removeIfExists(cacheMetadataPath(target));
252
264
  return false;
@@ -385,7 +397,7 @@ function requestBinary(url, dest, redirects = 0) {
385
397
  }
386
398
 
387
399
  function verifyBinary(binaryPath) {
388
- logLine("Verifying downloaded binary...");
400
+ logLine(`Verifying downloaded binary at ${binaryPath}...`);
389
401
  const version = binaryVersion(binaryPath);
390
402
  if (!version) {
391
403
  return {
@@ -402,12 +414,19 @@ function verifyBinary(binaryPath) {
402
414
  return { ok: true, version };
403
415
  }
404
416
 
405
- function expandCompressedBinary(src, dest) {
406
- logLine("Decompressing downloaded BB-Agent binary...");
417
+ async function expandCompressedBinary(src, dest) {
418
+ logLine(`Decompressing downloaded BB-Agent binary from ${path.basename(src)}...`);
407
419
  ensureParentDir(dest);
408
- const expanded = zlib.gunzipSync(fs.readFileSync(src));
409
- fs.writeFileSync(dest, expanded);
410
- removeIfExists(src);
420
+ try {
421
+ await pipeline(fs.createReadStream(src), zlib.createGunzip(), fs.createWriteStream(dest));
422
+ const stat = fs.statSync(dest);
423
+ logLine(`Expanded compressed asset to ${formatBytes(stat.size)}.`);
424
+ } catch (err) {
425
+ removeIfExists(dest);
426
+ throw makeDownloadError("decompress", `Failed to decompress ${path.basename(src)}: ${err.message}`);
427
+ } finally {
428
+ removeIfExists(src);
429
+ }
411
430
  }
412
431
 
413
432
  async function tryDownloadPrebuilt(target) {
@@ -416,6 +435,10 @@ async function tryDownloadPrebuilt(target) {
416
435
  fs.mkdirSync(NATIVE_DIR, { recursive: true });
417
436
  const dest = nativeBinaryPath();
418
437
  const tmpDest = `${dest}.tmp`;
438
+ const cachePath = cacheBinaryPath(target);
439
+
440
+ logLine(`Native binary destination: ${dest}`);
441
+ logLine(`Binary cache path: ${cachePath}`);
419
442
 
420
443
  if (installFromVerifiedCache(target)) {
421
444
  logLine("✓ BB-Agent binary installed successfully from cache.");
@@ -446,10 +469,12 @@ async function tryDownloadPrebuilt(target) {
446
469
  try {
447
470
  if (asset.compressed) {
448
471
  logLine(`Trying compressed release asset ${asset.assetName} first for a faster download.`);
472
+ } else {
473
+ logLine(`Trying uncompressed release asset ${asset.assetName}.`);
449
474
  }
450
475
  await requestBinary(url, downloadDest, 0);
451
476
  if (asset.compressed) {
452
- expandCompressedBinary(downloadDest, tmpDest);
477
+ await expandCompressedBinary(downloadDest, tmpDest);
453
478
  }
454
479
  if (!isWindows()) {
455
480
  fs.chmodSync(tmpDest, 0o755);
@@ -466,8 +491,9 @@ async function tryDownloadPrebuilt(target) {
466
491
  }
467
492
 
468
493
  fs.renameSync(tmpDest, dest);
494
+ logLine(`Installed BB-Agent binary to ${dest}.`);
469
495
  refreshCacheFromExistingBinary(target, dest);
470
- logLine("Cached verified BB-Agent binary for future installs.");
496
+ logLine(`Cached verified BB-Agent binary for future installs at ${cachePath}.`);
471
497
  logLine("✓ BB-Agent binary installed successfully.");
472
498
  return { ok: true, source: "download" };
473
499
  } catch (err) {
@@ -553,7 +579,9 @@ async function main() {
553
579
  const target = getTarget();
554
580
  const platform = `${os.platform()}-${os.arch()}`;
555
581
 
582
+ logLine(`Resolved install platform: ${platform}.`);
556
583
  if (target) {
584
+ logLine(`Resolved native target: ${target}.`);
557
585
  const result = await tryDownloadPrebuilt(target);
558
586
  if (result.ok) {
559
587
  return;