@shuyhere/bb-agent 0.0.8 → 0.0.10
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 +37 -0
- package/README.md +61 -12
- package/package.json +1 -1
- package/scripts/postinstall.js +250 -72
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,41 @@ 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.10] - 2026-04-07
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- npm install now uses a longer timeout, retries release-binary downloads, and reports real download errors instead of incorrectly saying no matching prebuilt binary exists
|
|
13
|
+
- npm install now shows progress logs during native binary download and verification so first-time installs on macOS/Linux are less confusing
|
|
14
|
+
- fullscreen `/login` provider-family status now correctly shows OpenAI OAuth state after ChatGPT login instead of incorrectly showing the API key path as not authenticated
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- README install docs now lead with `npm install -g @shuyhere/bb-agent`, move terminal/font guidance into Troubleshooting, and clearly separate npm install from building from source for development
|
|
19
|
+
|
|
20
|
+
## [0.0.9] - 2026-04-07
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- `@folder/` expansion now sends a directory tree summary to the model instead of treating folders like text files
|
|
25
|
+
- large `@file` expansions now send a structural outline first for long files instead of dumping the entire file immediately
|
|
26
|
+
- non-UTF-8 and binary `@file` references now send metadata instead of a misleading UTF-8 read error
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- fullscreen paste in iTerm2/SSH no longer corrupts the input area after paste
|
|
31
|
+
- pasted file and image paths are normalized more reliably, including quoted paths and `file://` URLs
|
|
32
|
+
- fullscreen prompt submission now expands `@file` references consistently
|
|
33
|
+
- running tool timers continue updating after `TurnEnd` while tools are still executing
|
|
34
|
+
- sub-second tool durations now display as `ms` instead of `0.0s`
|
|
35
|
+
- startup Skills/Prompts/Extensions note now only appears at startup or explicit `/reload`
|
|
36
|
+
- remote SSH clipboard copy no longer leaks Wayland/XDG clipboard helper warnings into the TUI
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- fullscreen `Ctrl+V` now falls back to clipboard text when no clipboard image is available
|
|
41
|
+
- `@` autocomplete now inserts quoted file references when paths contain spaces
|
|
42
|
+
|
|
8
43
|
## [0.0.8] - 2026-04-06
|
|
9
44
|
|
|
10
45
|
### Fixed
|
|
@@ -23,4 +58,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
23
58
|
|
|
24
59
|
- latest published package includes the post-0.0.7 startup, auth, model-default, and update-notice improvements
|
|
25
60
|
|
|
61
|
+
[0.0.10]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.10
|
|
62
|
+
[0.0.9]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.9
|
|
26
63
|
[0.0.8]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.8
|
package/README.md
CHANGED
|
@@ -1,10 +1,37 @@
|
|
|
1
1
|
# BB-Agent
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
> BB means Bridge Baby in Death Stranding. I named this project that way because while building it, I was also enjoying Death Stranding and loved the idea of connecting everyone together.
|
|
6
|
+
|
|
3
7
|
A Rust-native AI coding agent for the terminal — featuring a fullscreen TUI, multi-provider support, tool use, session persistence, branching, extensions, and skills.
|
|
4
8
|
|
|
5
9
|
## Install
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @shuyhere/bb-agent
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 1. Install with npm
|
|
16
|
+
|
|
17
|
+
npm install downloads a small wrapper package first, then fetches the matching native BB-Agent binary from the GitHub release for your platform.
|
|
18
|
+
|
|
19
|
+
What to expect:
|
|
20
|
+
- first install can take a bit because npm downloads and verifies the native binary
|
|
21
|
+
- the installer now prints progress and retry information while downloading
|
|
22
|
+
- after install, run `bb`
|
|
23
|
+
|
|
24
|
+
Current GitHub release binaries are published for:
|
|
25
|
+
- Linux x86_64
|
|
26
|
+
- macOS x86_64
|
|
27
|
+
- macOS arm64 (Apple Silicon)
|
|
28
|
+
- Windows x86_64
|
|
29
|
+
|
|
30
|
+
If no matching prebuilt binary is available, or the download fails, npm install will print source-build instructions instead.
|
|
31
|
+
|
|
32
|
+
### 2. Build from source for development
|
|
33
|
+
|
|
34
|
+
Use this if you want to develop BB-Agent itself, work on the Rust codebase, or install directly without the npm downloader.
|
|
8
35
|
|
|
9
36
|
Requires [Rust](https://rustup.rs). Install Rust first if you don't have it:
|
|
10
37
|
|
|
@@ -13,7 +40,7 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
|
13
40
|
source ~/.cargo/env
|
|
14
41
|
```
|
|
15
42
|
|
|
16
|
-
Then build and install BB-Agent:
|
|
43
|
+
Then build and install BB-Agent from source:
|
|
17
44
|
|
|
18
45
|
```bash
|
|
19
46
|
git clone https://github.com/shuyhere/bb-agent.git
|
|
@@ -23,16 +50,6 @@ cargo install --path crates/cli
|
|
|
23
50
|
|
|
24
51
|
This compiles the `bb` binary and installs it to `~/.cargo/bin/bb` (which Rust adds to your PATH).
|
|
25
52
|
|
|
26
|
-
### npm (Linux/macOS/Windows — downloads matching prebuilt binary when available)
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm install -g @shuyhere/bb-agent
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
> If no matching prebuilt binary is available for your platform, npm install will print source-build instructions instead. After install, run `bb` to start.
|
|
33
|
-
>
|
|
34
|
-
> Current GitHub release binaries are published for Linux x86_64, macOS x86_64/arm64, and Windows x86_64.
|
|
35
|
-
|
|
36
53
|
## Getting Started
|
|
37
54
|
|
|
38
55
|
### 1. Start the TUI
|
|
@@ -170,6 +187,38 @@ BB-Agent uses layered configuration:
|
|
|
170
187
|
| `bb-tui` | Terminal UI components and fullscreen experience |
|
|
171
188
|
| `bb-cli` | The `bb` command-line application |
|
|
172
189
|
|
|
190
|
+
## Troubleshooting
|
|
191
|
+
|
|
192
|
+
### Terminal & Font Compatibility
|
|
193
|
+
|
|
194
|
+
BB-Agent uses Unicode glyphs and ANSI color in the fullscreen TUI. For the best visual experience, use a modern terminal and a Unicode-capable monospace font such as:
|
|
195
|
+
|
|
196
|
+
- JetBrains Mono
|
|
197
|
+
- SF Mono / Menlo
|
|
198
|
+
- Fira Code
|
|
199
|
+
- Cascadia Mono
|
|
200
|
+
- Nerd Font variants of the above
|
|
201
|
+
|
|
202
|
+
If some symbols look broken, missing, or too narrow in your terminal:
|
|
203
|
+
|
|
204
|
+
1. switch to a Unicode-capable monospace font
|
|
205
|
+
2. make sure your terminal uses UTF-8
|
|
206
|
+
3. enable BB-Agent compatibility mode
|
|
207
|
+
|
|
208
|
+
Compatibility mode uses safer ASCII-style fallback glyphs for spinner/status/tool markers:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
BB_TUI_COMPAT=1 bb
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Or set this in `~/.bb-agent/settings.json`:
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"compatibility_mode": true
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
173
222
|
## Documentation
|
|
174
223
|
|
|
175
224
|
- [Configuration Reference](docs/configuration.md) — settings.json, AGENTS.md, templates
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -7,13 +7,15 @@ const fs = require("fs");
|
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const os = require("os");
|
|
9
9
|
const https = require("https");
|
|
10
|
+
const http = require("http");
|
|
10
11
|
|
|
11
12
|
const packageJson = require("../package.json");
|
|
12
13
|
const BINARY_RELEASE_TAG = `v${packageJson.version}`;
|
|
13
14
|
const REPO = "shuyhere/bb-agent";
|
|
14
|
-
const PACKAGE_ROOT = path.resolve(__dirname, "..");
|
|
15
15
|
const NATIVE_DIR = path.join(__dirname, "..", "native");
|
|
16
|
-
const DOWNLOAD_TIMEOUT_MS =
|
|
16
|
+
const DOWNLOAD_TIMEOUT_MS = 120_000;
|
|
17
|
+
const MAX_REDIRECTS = 8;
|
|
18
|
+
const MAX_DOWNLOAD_ATTEMPTS = 3;
|
|
17
19
|
|
|
18
20
|
function isWindows() {
|
|
19
21
|
return os.platform() === "win32";
|
|
@@ -44,34 +46,6 @@ function getTarget() {
|
|
|
44
46
|
return `${a}-${p}`;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
function downloadBinary(url, dest, timeoutMs) {
|
|
48
|
-
return new Promise((resolve, reject) => {
|
|
49
|
-
const timer = setTimeout(() => reject(new Error("Download timed out")), timeoutMs);
|
|
50
|
-
|
|
51
|
-
const follow = (url, redirects = 0) => {
|
|
52
|
-
if (redirects > 5) { clearTimeout(timer); return reject(new Error("Too many redirects")); }
|
|
53
|
-
|
|
54
|
-
const mod = url.startsWith("https") ? https : require("http");
|
|
55
|
-
const req = mod.get(url, (res) => {
|
|
56
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
57
|
-
return follow(res.headers.location, redirects + 1);
|
|
58
|
-
}
|
|
59
|
-
if (res.statusCode !== 200) {
|
|
60
|
-
clearTimeout(timer);
|
|
61
|
-
return reject(new Error(`HTTP ${res.statusCode}`));
|
|
62
|
-
}
|
|
63
|
-
const file = fs.createWriteStream(dest);
|
|
64
|
-
res.pipe(file);
|
|
65
|
-
file.on("finish", () => { clearTimeout(timer); file.close(); resolve(); });
|
|
66
|
-
file.on("error", (e) => { clearTimeout(timer); reject(e); });
|
|
67
|
-
});
|
|
68
|
-
req.on("error", (e) => { clearTimeout(timer); reject(e); });
|
|
69
|
-
req.on("timeout", () => { req.destroy(); clearTimeout(timer); reject(new Error("Request timed out")); });
|
|
70
|
-
};
|
|
71
|
-
follow(url);
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
49
|
function assetNameForTarget(target) {
|
|
76
50
|
return isWindows() ? `bb-${target}.exe` : `bb-${target}`;
|
|
77
51
|
}
|
|
@@ -87,60 +61,232 @@ function hasBundledNativeBinary() {
|
|
|
87
61
|
}
|
|
88
62
|
}
|
|
89
63
|
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
64
|
+
function makeDownloadError(kind, message, statusCode) {
|
|
65
|
+
const err = new Error(message);
|
|
66
|
+
err.kind = kind;
|
|
67
|
+
if (statusCode) err.statusCode = statusCode;
|
|
68
|
+
return err;
|
|
69
|
+
}
|
|
96
70
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
71
|
+
function formatBytes(bytes) {
|
|
72
|
+
if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
|
|
73
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
74
|
+
let value = bytes;
|
|
75
|
+
let unit = 0;
|
|
76
|
+
while (value >= 1024 && unit < units.length - 1) {
|
|
77
|
+
value /= 1024;
|
|
78
|
+
unit += 1;
|
|
79
|
+
}
|
|
80
|
+
return `${value.toFixed(value >= 10 || unit === 0 ? 0 : 1)} ${units[unit]}`;
|
|
81
|
+
}
|
|
101
82
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
fs.unlinkSync(dest);
|
|
108
|
-
return false;
|
|
83
|
+
function requestBinary(url, dest, redirects = 0) {
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
if (redirects > MAX_REDIRECTS) {
|
|
86
|
+
reject(makeDownloadError("redirect", "Too many redirects"));
|
|
87
|
+
return;
|
|
109
88
|
}
|
|
110
89
|
|
|
111
|
-
|
|
112
|
-
|
|
90
|
+
const client = url.startsWith("https:") ? https : http;
|
|
91
|
+
const req = client.get(
|
|
92
|
+
url,
|
|
93
|
+
{
|
|
94
|
+
headers: {
|
|
95
|
+
"User-Agent": `${packageJson.name}/${packageJson.version} (postinstall)`,
|
|
96
|
+
Accept: "application/octet-stream,application/octet-stream; q=0.9,*/*;q=0.1",
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
(res) => {
|
|
100
|
+
const status = res.statusCode || 0;
|
|
101
|
+
|
|
102
|
+
if (status >= 300 && status < 400 && res.headers.location) {
|
|
103
|
+
res.resume();
|
|
104
|
+
requestBinary(res.headers.location, dest, redirects + 1)
|
|
105
|
+
.then(resolve)
|
|
106
|
+
.catch(reject);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (status === 404) {
|
|
111
|
+
res.resume();
|
|
112
|
+
reject(makeDownloadError("not-found", `HTTP 404 for ${url}`, 404));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (status !== 200) {
|
|
117
|
+
res.resume();
|
|
118
|
+
reject(makeDownloadError("http", `HTTP ${status} for ${url}`, status));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const totalBytes = Number(res.headers["content-length"] || 0);
|
|
123
|
+
let downloadedBytes = 0;
|
|
124
|
+
let lastLoggedAt = Date.now();
|
|
125
|
+
if (totalBytes > 0) {
|
|
126
|
+
console.log(`Release asset size: ${formatBytes(totalBytes)}.`);
|
|
127
|
+
} else {
|
|
128
|
+
console.log("Release asset size: unknown (streaming download).");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const file = fs.createWriteStream(dest);
|
|
132
|
+
let settled = false;
|
|
133
|
+
|
|
134
|
+
const finish = (fn, value) => {
|
|
135
|
+
if (settled) return;
|
|
136
|
+
settled = true;
|
|
137
|
+
clearTimeout(timeout);
|
|
138
|
+
fn(value);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
res.on("data", (chunk) => {
|
|
142
|
+
downloadedBytes += chunk.length;
|
|
143
|
+
const now = Date.now();
|
|
144
|
+
if (now - lastLoggedAt >= 5000) {
|
|
145
|
+
lastLoggedAt = now;
|
|
146
|
+
if (totalBytes > 0) {
|
|
147
|
+
const percent = Math.min(100, Math.round((downloadedBytes / totalBytes) * 100));
|
|
148
|
+
console.log(
|
|
149
|
+
`Download progress: ${percent}% (${formatBytes(downloadedBytes)} / ${formatBytes(totalBytes)})`
|
|
150
|
+
);
|
|
151
|
+
} else {
|
|
152
|
+
console.log(`Downloaded ${formatBytes(downloadedBytes)} so far...`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
file.on("finish", () => {
|
|
158
|
+
file.close((closeErr) => {
|
|
159
|
+
if (closeErr) {
|
|
160
|
+
finish(reject, makeDownloadError("write", closeErr.message));
|
|
161
|
+
} else {
|
|
162
|
+
if (totalBytes > 0) {
|
|
163
|
+
console.log(
|
|
164
|
+
`Download complete: ${formatBytes(downloadedBytes)} / ${formatBytes(totalBytes)}.`
|
|
165
|
+
);
|
|
166
|
+
} else {
|
|
167
|
+
console.log(`Download complete: ${formatBytes(downloadedBytes)}.`);
|
|
168
|
+
}
|
|
169
|
+
finish(resolve);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
file.on("error", (err) => {
|
|
175
|
+
try { file.close(() => {}); } catch {}
|
|
176
|
+
try { fs.unlinkSync(dest); } catch {}
|
|
177
|
+
finish(reject, makeDownloadError("write", err.message));
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
res.on("error", (err) => {
|
|
181
|
+
try { file.close(() => {}); } catch {}
|
|
182
|
+
try { fs.unlinkSync(dest); } catch {}
|
|
183
|
+
finish(reject, makeDownloadError("network", err.message));
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
res.pipe(file);
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
const timeout = setTimeout(() => {
|
|
191
|
+
req.destroy(makeDownloadError("timeout", `Download timed out after ${DOWNLOAD_TIMEOUT_MS}ms`));
|
|
192
|
+
}, DOWNLOAD_TIMEOUT_MS);
|
|
193
|
+
|
|
194
|
+
req.on("error", (err) => {
|
|
195
|
+
clearTimeout(timeout);
|
|
196
|
+
reject(makeDownloadError(err.kind || "network", err.message));
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function verifyBinary(dest) {
|
|
202
|
+
try {
|
|
203
|
+
execSync(`"${dest}" --version`, { stdio: "pipe", timeout: 5000 });
|
|
204
|
+
return { ok: true };
|
|
113
205
|
} catch (err) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
206
|
+
return {
|
|
207
|
+
ok: false,
|
|
208
|
+
message: err && err.message ? err.message : "binary verification failed",
|
|
209
|
+
};
|
|
117
210
|
}
|
|
118
211
|
}
|
|
119
212
|
|
|
213
|
+
async function tryDownloadPrebuilt(target) {
|
|
214
|
+
const assetName = assetNameForTarget(target);
|
|
215
|
+
const url = `https://github.com/${REPO}/releases/download/${BINARY_RELEASE_TAG}/${assetName}`;
|
|
120
216
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
217
|
+
fs.mkdirSync(NATIVE_DIR, { recursive: true });
|
|
218
|
+
const dest = nativeBinaryPath();
|
|
125
219
|
|
|
126
|
-
|
|
220
|
+
let lastError = null;
|
|
221
|
+
for (let attempt = 1; attempt <= MAX_DOWNLOAD_ATTEMPTS; attempt += 1) {
|
|
222
|
+
try {
|
|
223
|
+
console.log(
|
|
224
|
+
`Downloading BB-Agent ${BINARY_RELEASE_TAG} for ${target} (attempt ${attempt}/${MAX_DOWNLOAD_ATTEMPTS})...`
|
|
225
|
+
);
|
|
226
|
+
console.log("This may take a little while on first install because npm downloads and verifies the native binary from the GitHub release.");
|
|
227
|
+
try { fs.unlinkSync(dest); } catch {}
|
|
228
|
+
await requestBinary(url, dest, 0);
|
|
229
|
+
fs.chmodSync(dest, 0o755);
|
|
127
230
|
|
|
128
|
-
|
|
231
|
+
const verified = verifyBinary(dest);
|
|
232
|
+
if (!verified.ok) {
|
|
233
|
+
try { fs.unlinkSync(dest); } catch {}
|
|
234
|
+
return {
|
|
235
|
+
ok: false,
|
|
236
|
+
kind: "verify",
|
|
237
|
+
message: `Downloaded binary could not run: ${verified.message}`,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
129
240
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
241
|
+
console.log("Verifying downloaded binary...");
|
|
242
|
+
console.log("✓ BB-Agent binary installed successfully.");
|
|
243
|
+
return { ok: true };
|
|
244
|
+
} catch (err) {
|
|
245
|
+
lastError = err;
|
|
246
|
+
try { fs.unlinkSync(dest); } catch {}
|
|
247
|
+
if (err.kind === "not-found") {
|
|
248
|
+
return {
|
|
249
|
+
ok: false,
|
|
250
|
+
kind: "not-found",
|
|
251
|
+
message: `No release asset named ${assetName} was found for ${BINARY_RELEASE_TAG}.`,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
if (attempt < MAX_DOWNLOAD_ATTEMPTS) {
|
|
255
|
+
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
134
258
|
}
|
|
135
259
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
260
|
+
return {
|
|
261
|
+
ok: false,
|
|
262
|
+
kind: (lastError && lastError.kind) || "download",
|
|
263
|
+
message: (lastError && lastError.message) || "unknown download failure",
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function printFallbackHelp(platform, reason) {
|
|
139
268
|
console.log("");
|
|
140
|
-
|
|
269
|
+
if (reason && reason.kind === "not-found") {
|
|
270
|
+
console.log(
|
|
271
|
+
`BB-Agent ${packageJson.version}: matching prebuilt binary is not published for ${platform}.`
|
|
272
|
+
);
|
|
273
|
+
} else if (reason) {
|
|
274
|
+
console.log(
|
|
275
|
+
`BB-Agent ${packageJson.version}: failed to download the prebuilt binary for ${platform}.`
|
|
276
|
+
);
|
|
277
|
+
console.log(`Reason: ${reason.message}`);
|
|
278
|
+
} else {
|
|
279
|
+
console.log(
|
|
280
|
+
`BB-Agent ${packageJson.version}: matching prebuilt binary not available yet for ${platform}.`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
141
283
|
console.log("");
|
|
142
284
|
console.log("╔══════════════════════════════════════════════════════════════╗");
|
|
143
|
-
console.log(
|
|
285
|
+
console.log(
|
|
286
|
+
"║ BB-Agent: npm could not install native binary for " +
|
|
287
|
+
platform.padEnd(16) +
|
|
288
|
+
" ║"
|
|
289
|
+
);
|
|
144
290
|
console.log("║ ║");
|
|
145
291
|
console.log("║ Install Rust (if needed): ║");
|
|
146
292
|
console.log("║ https://rustup.rs ║");
|
|
@@ -155,8 +301,40 @@ async function main() {
|
|
|
155
301
|
console.log("");
|
|
156
302
|
}
|
|
157
303
|
|
|
158
|
-
main()
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
304
|
+
async function main() {
|
|
305
|
+
if (process.env.BB_SKIP_POSTINSTALL) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (hasBundledNativeBinary()) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const target = getTarget();
|
|
314
|
+
const platform = `${os.platform()}-${os.arch()}`;
|
|
315
|
+
|
|
316
|
+
if (target) {
|
|
317
|
+
const result = await tryDownloadPrebuilt(target);
|
|
318
|
+
if (result.ok) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
printFallbackHelp(platform, result);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
printFallbackHelp(platform, {
|
|
326
|
+
kind: "unsupported-platform",
|
|
327
|
+
message: `Unsupported target mapping for ${platform}`,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
main()
|
|
332
|
+
.catch((err) => {
|
|
333
|
+
console.error("BB-Agent postinstall notice:", err && err.message ? err.message : String(err));
|
|
334
|
+
console.log(
|
|
335
|
+
"Install manually: git clone https://github.com/shuyhere/bb-agent.git && cd bb-agent && cargo install --path crates/cli"
|
|
336
|
+
);
|
|
337
|
+
})
|
|
338
|
+
.finally(() => {
|
|
339
|
+
process.exitCode = 0;
|
|
340
|
+
});
|