@shuyhere/bb-agent 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/scripts/postinstall.js +256 -68
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@ All notable changes to BB-Agent will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.0.11] - 2026-04-07
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- startup update notices in the fullscreen transcript are now highlighted so available updates stand out clearly during startup
|
|
13
|
+
- read-tool line ranges in fullscreen tool activity now highlight the requested span, so values like `2148-2267/5006` stand out while the model is using tools
|
|
14
|
+
|
|
15
|
+
### Improved
|
|
16
|
+
|
|
17
|
+
- npm install now caches verified native binaries by version/platform and reuses them on reinstall instead of re-downloading every time
|
|
18
|
+
- npm install now shows more frequent download progress with transfer rate information to make slow installs easier to understand
|
|
19
|
+
- npm install now avoids unnecessary re-verification on cache hits, making repeat installs faster
|
|
20
|
+
|
|
8
21
|
## [0.0.10] - 2026-04-07
|
|
9
22
|
|
|
10
23
|
### Fixed
|
|
@@ -58,6 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
58
71
|
|
|
59
72
|
- latest published package includes the post-0.0.7 startup, auth, model-default, and update-notice improvements
|
|
60
73
|
|
|
74
|
+
[0.0.11]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.11
|
|
61
75
|
[0.0.10]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.10
|
|
62
76
|
[0.0.9]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.9
|
|
63
77
|
[0.0.8]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.8
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const {
|
|
5
|
+
const { execFileSync } = require("child_process");
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const os = require("os");
|
|
@@ -14,6 +14,7 @@ const BINARY_RELEASE_TAG = `v${packageJson.version}`;
|
|
|
14
14
|
const REPO = "shuyhere/bb-agent";
|
|
15
15
|
const NATIVE_DIR = path.join(__dirname, "..", "native");
|
|
16
16
|
const DOWNLOAD_TIMEOUT_MS = 120_000;
|
|
17
|
+
const DOWNLOAD_PROGRESS_INTERVAL_MS = 1_000;
|
|
17
18
|
const MAX_REDIRECTS = 8;
|
|
18
19
|
const MAX_DOWNLOAD_ATTEMPTS = 3;
|
|
19
20
|
|
|
@@ -50,15 +51,10 @@ function assetNameForTarget(target) {
|
|
|
50
51
|
return isWindows() ? `bb-${target}.exe` : `bb-${target}`;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
function
|
|
54
|
-
const dest = nativeBinaryPath();
|
|
55
|
-
if (!fs.existsSync(dest)) return false;
|
|
54
|
+
function logLine(message = "") {
|
|
56
55
|
try {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
} catch {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
56
|
+
process.stderr.write(`${message}\n`);
|
|
57
|
+
} catch (_) {}
|
|
62
58
|
}
|
|
63
59
|
|
|
64
60
|
function makeDownloadError(kind, message, statusCode) {
|
|
@@ -80,6 +76,172 @@ function formatBytes(bytes) {
|
|
|
80
76
|
return `${value.toFixed(value >= 10 || unit === 0 ? 0 : 1)} ${units[unit]}`;
|
|
81
77
|
}
|
|
82
78
|
|
|
79
|
+
function formatRate(bytesPerSecond) {
|
|
80
|
+
if (!Number.isFinite(bytesPerSecond) || bytesPerSecond <= 0) return "0 B/s";
|
|
81
|
+
return `${formatBytes(bytesPerSecond)}/s`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function ensureParentDir(filePath) {
|
|
85
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function removeIfExists(filePath) {
|
|
89
|
+
try {
|
|
90
|
+
fs.unlinkSync(filePath);
|
|
91
|
+
} catch (_) {}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function binaryVersion(binaryPath) {
|
|
95
|
+
try {
|
|
96
|
+
const out = execFileSync(binaryPath, ["--version"], {
|
|
97
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
98
|
+
timeout: 2500,
|
|
99
|
+
encoding: "utf8",
|
|
100
|
+
});
|
|
101
|
+
return (out || "").trim();
|
|
102
|
+
} catch (err) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function binaryMatchesCurrentVersion(binaryPath) {
|
|
108
|
+
const version = binaryVersion(binaryPath);
|
|
109
|
+
if (!version) return false;
|
|
110
|
+
return version.includes(packageJson.version);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function hasBundledNativeBinary() {
|
|
114
|
+
const dest = nativeBinaryPath();
|
|
115
|
+
if (!fs.existsSync(dest)) return false;
|
|
116
|
+
if (!binaryMatchesCurrentVersion(dest)) return false;
|
|
117
|
+
try {
|
|
118
|
+
fs.accessSync(dest, fs.constants.X_OK);
|
|
119
|
+
return true;
|
|
120
|
+
} catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function cacheRootDir() {
|
|
126
|
+
if (process.env.BB_INSTALL_CACHE_DIR && process.env.BB_INSTALL_CACHE_DIR.trim()) {
|
|
127
|
+
return process.env.BB_INSTALL_CACHE_DIR;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const home = os.homedir();
|
|
131
|
+
if (isWindows()) {
|
|
132
|
+
return path.join(
|
|
133
|
+
process.env.LOCALAPPDATA || process.env.APPDATA || path.join(home, "AppData", "Local"),
|
|
134
|
+
"bb-agent"
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (os.platform() === "darwin") {
|
|
138
|
+
return path.join(home, "Library", "Caches", "bb-agent");
|
|
139
|
+
}
|
|
140
|
+
return path.join(process.env.XDG_CACHE_HOME || path.join(home, ".cache"), "bb-agent");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function cacheBinaryPath(target) {
|
|
144
|
+
return path.join(cacheRootDir(), "prebuilt", packageJson.version, assetNameForTarget(target));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function cacheMetadataPath(target) {
|
|
148
|
+
return `${cacheBinaryPath(target)}.json`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function loadCacheMetadata(target) {
|
|
152
|
+
try {
|
|
153
|
+
return JSON.parse(fs.readFileSync(cacheMetadataPath(target), "utf8"));
|
|
154
|
+
} catch (_) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function storeCacheMetadata(target, binaryPath) {
|
|
160
|
+
try {
|
|
161
|
+
const stat = fs.statSync(binaryPath);
|
|
162
|
+
ensureParentDir(cacheMetadataPath(target));
|
|
163
|
+
fs.writeFileSync(
|
|
164
|
+
cacheMetadataPath(target),
|
|
165
|
+
JSON.stringify(
|
|
166
|
+
{
|
|
167
|
+
version: packageJson.version,
|
|
168
|
+
target,
|
|
169
|
+
assetName: assetNameForTarget(target),
|
|
170
|
+
binaryName: nativeBinaryName(),
|
|
171
|
+
size: stat.size,
|
|
172
|
+
verifiedAt: new Date().toISOString(),
|
|
173
|
+
},
|
|
174
|
+
null,
|
|
175
|
+
2
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
} catch (_) {}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function copyBinary(src, dest) {
|
|
182
|
+
ensureParentDir(dest);
|
|
183
|
+
fs.copyFileSync(src, dest);
|
|
184
|
+
if (!isWindows()) {
|
|
185
|
+
fs.chmodSync(dest, 0o755);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function installFromVerifiedCache(target) {
|
|
190
|
+
const cached = cacheBinaryPath(target);
|
|
191
|
+
const meta = loadCacheMetadata(target);
|
|
192
|
+
if (!fs.existsSync(cached) || !meta) return false;
|
|
193
|
+
if (meta.version !== packageJson.version || meta.target !== target) return false;
|
|
194
|
+
|
|
195
|
+
let stat;
|
|
196
|
+
try {
|
|
197
|
+
stat = fs.statSync(cached);
|
|
198
|
+
} catch (_) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
if (!stat.isFile() || stat.size <= 0) return false;
|
|
202
|
+
if (meta.size && stat.size !== meta.size) return false;
|
|
203
|
+
|
|
204
|
+
logLine(`Using cached BB-Agent binary for ${target} (${formatBytes(stat.size)}).`);
|
|
205
|
+
copyBinary(cached, nativeBinaryPath());
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function refreshCacheFromExistingBinary(target, sourcePath) {
|
|
210
|
+
if (!binaryMatchesCurrentVersion(sourcePath)) return false;
|
|
211
|
+
const cached = cacheBinaryPath(target);
|
|
212
|
+
copyBinary(sourcePath, cached);
|
|
213
|
+
storeCacheMetadata(target, cached);
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function maybeRepairCache(target) {
|
|
218
|
+
const cached = cacheBinaryPath(target);
|
|
219
|
+
if (!fs.existsSync(cached)) return false;
|
|
220
|
+
|
|
221
|
+
const meta = loadCacheMetadata(target);
|
|
222
|
+
if (meta && meta.version === packageJson.version && meta.target === target && meta.size) {
|
|
223
|
+
try {
|
|
224
|
+
const stat = fs.statSync(cached);
|
|
225
|
+
if (stat.isFile() && stat.size === meta.size) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
} catch (_) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
logLine(`Checking cached BB-Agent binary for ${target}...`);
|
|
234
|
+
if (!binaryMatchesCurrentVersion(cached)) {
|
|
235
|
+
removeIfExists(cached);
|
|
236
|
+
removeIfExists(cacheMetadataPath(target));
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
storeCacheMetadata(target, cached);
|
|
241
|
+
logLine("Verified cached BB-Agent binary for reuse.");
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
|
|
83
245
|
function requestBinary(url, dest, redirects = 0) {
|
|
84
246
|
return new Promise((resolve, reject) => {
|
|
85
247
|
if (redirects > MAX_REDIRECTS) {
|
|
@@ -120,14 +282,17 @@ function requestBinary(url, dest, redirects = 0) {
|
|
|
120
282
|
}
|
|
121
283
|
|
|
122
284
|
const totalBytes = Number(res.headers["content-length"] || 0);
|
|
285
|
+
const startedAt = Date.now();
|
|
123
286
|
let downloadedBytes = 0;
|
|
124
|
-
let lastLoggedAt =
|
|
287
|
+
let lastLoggedAt = 0;
|
|
288
|
+
|
|
125
289
|
if (totalBytes > 0) {
|
|
126
|
-
|
|
290
|
+
logLine(`Release asset size: ${formatBytes(totalBytes)}.`);
|
|
127
291
|
} else {
|
|
128
|
-
|
|
292
|
+
logLine("Release asset size: unknown (streaming download).");
|
|
129
293
|
}
|
|
130
294
|
|
|
295
|
+
ensureParentDir(dest);
|
|
131
296
|
const file = fs.createWriteStream(dest);
|
|
132
297
|
let settled = false;
|
|
133
298
|
|
|
@@ -141,15 +306,17 @@ function requestBinary(url, dest, redirects = 0) {
|
|
|
141
306
|
res.on("data", (chunk) => {
|
|
142
307
|
downloadedBytes += chunk.length;
|
|
143
308
|
const now = Date.now();
|
|
144
|
-
if (now - lastLoggedAt >=
|
|
309
|
+
if (now - lastLoggedAt >= DOWNLOAD_PROGRESS_INTERVAL_MS) {
|
|
145
310
|
lastLoggedAt = now;
|
|
311
|
+
const elapsedSeconds = Math.max((now - startedAt) / 1000, 0.001);
|
|
312
|
+
const rate = downloadedBytes / elapsedSeconds;
|
|
146
313
|
if (totalBytes > 0) {
|
|
147
314
|
const percent = Math.min(100, Math.round((downloadedBytes / totalBytes) * 100));
|
|
148
|
-
|
|
149
|
-
`Download progress: ${percent}% (${formatBytes(downloadedBytes)} / ${formatBytes(totalBytes)})`
|
|
315
|
+
logLine(
|
|
316
|
+
`Download progress: ${percent}% (${formatBytes(downloadedBytes)} / ${formatBytes(totalBytes)}, ${formatRate(rate)})`
|
|
150
317
|
);
|
|
151
318
|
} else {
|
|
152
|
-
|
|
319
|
+
logLine(`Downloaded ${formatBytes(downloadedBytes)} so far (${formatRate(rate)})...`);
|
|
153
320
|
}
|
|
154
321
|
}
|
|
155
322
|
});
|
|
@@ -159,12 +326,16 @@ function requestBinary(url, dest, redirects = 0) {
|
|
|
159
326
|
if (closeErr) {
|
|
160
327
|
finish(reject, makeDownloadError("write", closeErr.message));
|
|
161
328
|
} else {
|
|
329
|
+
const elapsedSeconds = Math.max((Date.now() - startedAt) / 1000, 0.001);
|
|
330
|
+
const rate = downloadedBytes / elapsedSeconds;
|
|
162
331
|
if (totalBytes > 0) {
|
|
163
|
-
|
|
164
|
-
`Download complete: ${formatBytes(downloadedBytes)} / ${formatBytes(totalBytes)}.`
|
|
332
|
+
logLine(
|
|
333
|
+
`Download complete: ${formatBytes(downloadedBytes)} / ${formatBytes(totalBytes)} in ${elapsedSeconds.toFixed(1)}s (${formatRate(rate)}).`
|
|
165
334
|
);
|
|
166
335
|
} else {
|
|
167
|
-
|
|
336
|
+
logLine(
|
|
337
|
+
`Download complete: ${formatBytes(downloadedBytes)} in ${elapsedSeconds.toFixed(1)}s (${formatRate(rate)}).`
|
|
338
|
+
);
|
|
168
339
|
}
|
|
169
340
|
finish(resolve);
|
|
170
341
|
}
|
|
@@ -172,14 +343,14 @@ function requestBinary(url, dest, redirects = 0) {
|
|
|
172
343
|
});
|
|
173
344
|
|
|
174
345
|
file.on("error", (err) => {
|
|
175
|
-
try { file.close(() => {}); } catch {}
|
|
176
|
-
|
|
346
|
+
try { file.close(() => {}); } catch (_) {}
|
|
347
|
+
removeIfExists(dest);
|
|
177
348
|
finish(reject, makeDownloadError("write", err.message));
|
|
178
349
|
});
|
|
179
350
|
|
|
180
351
|
res.on("error", (err) => {
|
|
181
|
-
try { file.close(() => {}); } catch {}
|
|
182
|
-
|
|
352
|
+
try { file.close(() => {}); } catch (_) {}
|
|
353
|
+
removeIfExists(dest);
|
|
183
354
|
finish(reject, makeDownloadError("network", err.message));
|
|
184
355
|
});
|
|
185
356
|
|
|
@@ -198,16 +369,22 @@ function requestBinary(url, dest, redirects = 0) {
|
|
|
198
369
|
});
|
|
199
370
|
}
|
|
200
371
|
|
|
201
|
-
function verifyBinary(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
372
|
+
function verifyBinary(binaryPath) {
|
|
373
|
+
logLine("Verifying downloaded binary...");
|
|
374
|
+
const version = binaryVersion(binaryPath);
|
|
375
|
+
if (!version) {
|
|
376
|
+
return {
|
|
377
|
+
ok: false,
|
|
378
|
+
message: "binary verification failed",
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
if (!version.includes(packageJson.version)) {
|
|
206
382
|
return {
|
|
207
383
|
ok: false,
|
|
208
|
-
message:
|
|
384
|
+
message: `expected version ${packageJson.version}, got '${version}'`,
|
|
209
385
|
};
|
|
210
386
|
}
|
|
387
|
+
return { ok: true, version };
|
|
211
388
|
}
|
|
212
389
|
|
|
213
390
|
async function tryDownloadPrebuilt(target) {
|
|
@@ -216,21 +393,34 @@ async function tryDownloadPrebuilt(target) {
|
|
|
216
393
|
|
|
217
394
|
fs.mkdirSync(NATIVE_DIR, { recursive: true });
|
|
218
395
|
const dest = nativeBinaryPath();
|
|
396
|
+
const tmpDest = `${dest}.tmp`;
|
|
397
|
+
|
|
398
|
+
if (installFromVerifiedCache(target)) {
|
|
399
|
+
logLine("✓ BB-Agent binary installed successfully from cache.");
|
|
400
|
+
return { ok: true, source: "cache" };
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (maybeRepairCache(target) && installFromVerifiedCache(target)) {
|
|
404
|
+
logLine("✓ BB-Agent binary installed successfully from cache.");
|
|
405
|
+
return { ok: true, source: "cache" };
|
|
406
|
+
}
|
|
219
407
|
|
|
220
408
|
let lastError = null;
|
|
221
409
|
for (let attempt = 1; attempt <= MAX_DOWNLOAD_ATTEMPTS; attempt += 1) {
|
|
222
410
|
try {
|
|
223
|
-
|
|
411
|
+
logLine(
|
|
224
412
|
`Downloading BB-Agent ${BINARY_RELEASE_TAG} for ${target} (attempt ${attempt}/${MAX_DOWNLOAD_ATTEMPTS})...`
|
|
225
413
|
);
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
await requestBinary(url,
|
|
229
|
-
|
|
414
|
+
logLine("This may take a little while on first install because npm downloads the native binary from the GitHub release.");
|
|
415
|
+
removeIfExists(tmpDest);
|
|
416
|
+
await requestBinary(url, tmpDest, 0);
|
|
417
|
+
if (!isWindows()) {
|
|
418
|
+
fs.chmodSync(tmpDest, 0o755);
|
|
419
|
+
}
|
|
230
420
|
|
|
231
|
-
const verified = verifyBinary(
|
|
421
|
+
const verified = verifyBinary(tmpDest);
|
|
232
422
|
if (!verified.ok) {
|
|
233
|
-
|
|
423
|
+
removeIfExists(tmpDest);
|
|
234
424
|
return {
|
|
235
425
|
ok: false,
|
|
236
426
|
kind: "verify",
|
|
@@ -238,12 +428,14 @@ async function tryDownloadPrebuilt(target) {
|
|
|
238
428
|
};
|
|
239
429
|
}
|
|
240
430
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
431
|
+
fs.renameSync(tmpDest, dest);
|
|
432
|
+
refreshCacheFromExistingBinary(target, dest);
|
|
433
|
+
logLine("Cached verified BB-Agent binary for future installs.");
|
|
434
|
+
logLine("✓ BB-Agent binary installed successfully.");
|
|
435
|
+
return { ok: true, source: "download" };
|
|
244
436
|
} catch (err) {
|
|
245
437
|
lastError = err;
|
|
246
|
-
|
|
438
|
+
removeIfExists(tmpDest);
|
|
247
439
|
if (err.kind === "not-found") {
|
|
248
440
|
return {
|
|
249
441
|
ok: false,
|
|
@@ -252,6 +444,7 @@ async function tryDownloadPrebuilt(target) {
|
|
|
252
444
|
};
|
|
253
445
|
}
|
|
254
446
|
if (attempt < MAX_DOWNLOAD_ATTEMPTS) {
|
|
447
|
+
logLine(`Download failed (${err.message}). Retrying...`);
|
|
255
448
|
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
|
|
256
449
|
}
|
|
257
450
|
}
|
|
@@ -265,40 +458,34 @@ async function tryDownloadPrebuilt(target) {
|
|
|
265
458
|
}
|
|
266
459
|
|
|
267
460
|
function printFallbackHelp(platform, reason) {
|
|
268
|
-
|
|
461
|
+
logLine("");
|
|
269
462
|
if (reason && reason.kind === "not-found") {
|
|
270
|
-
|
|
271
|
-
`BB-Agent ${packageJson.version}: matching prebuilt binary is not published for ${platform}.`
|
|
272
|
-
);
|
|
463
|
+
logLine(`BB-Agent ${packageJson.version}: matching prebuilt binary is not published for ${platform}.`);
|
|
273
464
|
} else if (reason) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
);
|
|
277
|
-
console.log(`Reason: ${reason.message}`);
|
|
465
|
+
logLine(`BB-Agent ${packageJson.version}: failed to download the prebuilt binary for ${platform}.`);
|
|
466
|
+
logLine(`Reason: ${reason.message}`);
|
|
278
467
|
} else {
|
|
279
|
-
|
|
280
|
-
`BB-Agent ${packageJson.version}: matching prebuilt binary not available yet for ${platform}.`
|
|
281
|
-
);
|
|
468
|
+
logLine(`BB-Agent ${packageJson.version}: matching prebuilt binary not available yet for ${platform}.`);
|
|
282
469
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
470
|
+
logLine("");
|
|
471
|
+
logLine("╔══════════════════════════════════════════════════════════════╗");
|
|
472
|
+
logLine(
|
|
286
473
|
"║ BB-Agent: npm could not install native binary for " +
|
|
287
474
|
platform.padEnd(16) +
|
|
288
475
|
" ║"
|
|
289
476
|
);
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
477
|
+
logLine("║ ║");
|
|
478
|
+
logLine("║ Install Rust (if needed): ║");
|
|
479
|
+
logLine("║ https://rustup.rs ║");
|
|
480
|
+
logLine("║ Then install with rustup for your platform ║");
|
|
481
|
+
logLine("║ ║");
|
|
482
|
+
logLine("║ Then build BB-Agent: ║");
|
|
483
|
+
logLine("║ git clone https://github.com/shuyhere/bb-agent.git ║");
|
|
484
|
+
logLine("║ cd bb-agent && cargo install --path crates/cli ║");
|
|
485
|
+
logLine("║ ║");
|
|
486
|
+
logLine("║ Then run: bb ║");
|
|
487
|
+
logLine("╚══════════════════════════════════════════════════════════════╝");
|
|
488
|
+
logLine("");
|
|
302
489
|
}
|
|
303
490
|
|
|
304
491
|
async function main() {
|
|
@@ -307,6 +494,7 @@ async function main() {
|
|
|
307
494
|
}
|
|
308
495
|
|
|
309
496
|
if (hasBundledNativeBinary()) {
|
|
497
|
+
logLine(`BB-Agent ${packageJson.version} native binary already present; skipping download.`);
|
|
310
498
|
return;
|
|
311
499
|
}
|
|
312
500
|
|
|
@@ -330,8 +518,8 @@ async function main() {
|
|
|
330
518
|
|
|
331
519
|
main()
|
|
332
520
|
.catch((err) => {
|
|
333
|
-
|
|
334
|
-
|
|
521
|
+
logLine(`BB-Agent postinstall notice: ${err && err.message ? err.message : String(err)}`);
|
|
522
|
+
logLine(
|
|
335
523
|
"Install manually: git clone https://github.com/shuyhere/bb-agent.git && cd bb-agent && cargo install --path crates/cli"
|
|
336
524
|
);
|
|
337
525
|
})
|