@shuyhere/bb-agent 0.0.11 → 0.0.14
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 +60 -0
- package/README.md +18 -1
- package/package.json +1 -1
- package/scripts/test-pi-token-parity.mjs +141 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,18 +5,75 @@ 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.14] - 2026-04-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- fullscreen now supports extension-driven workflows and structured slash-command outcomes, including menus, hidden dispatches, and richer command result handling
|
|
13
|
+
- `/settings` in fullscreen now exposes compaction controls for `Auto-compact`, `Reserve tokens`, and `Keep recent tokens`
|
|
14
|
+
- skills can now be listed, disabled, and re-enabled from the CLI without deleting their installed files
|
|
15
|
+
- startup model selection now prefers configured provider/model defaults more consistently, with better OpenAI startup fallback behavior
|
|
16
|
+
- added a parity test script against installed pi compaction logic to keep BB token accounting aligned with upstream behavior
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- session resume now restores the prior model and thinking level instead of starting with mismatched runtime defaults
|
|
21
|
+
- fullscreen/TUI terminal rendering now sanitizes terminal control text more reliably and avoids ANSI leakage into the UI
|
|
22
|
+
- auto-compaction token estimation now matches pi more closely by using the last successful assistant usage plus trailing estimates, using ceil-based token heuristics, computing `tokens_before` from rebuilt context instead of raw payload size, and ignoring assistant usage from before the latest compaction boundary
|
|
23
|
+
- fullscreen compaction behavior and status reporting are more consistent after auto-compaction and manual compaction events, and local fullscreen actions now show an animated elapsed-time status while they run
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- fullscreen extension workflows and session compaction support are now merged into the main interaction path on `master`
|
|
28
|
+
|
|
29
|
+
## [0.0.13] - 2026-04-09
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- fullscreen screenshot and image clipboard paste now works on the normal paste path, with macOS clipboard fallbacks and Codex image preservation so pasted images reach image-capable models correctly
|
|
34
|
+
- model registry metadata now tracks image input capability, making `/models` truthful about image support and allowing runtime warnings when users attach images to text-only models
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- fullscreen clipboard image attach no longer leaks helper `true` / `false` output or stray follow-up paste text into the input block
|
|
39
|
+
- attached image chips can now be removed with `Backspace`, image-only prompts can be submitted, and optimistic user messages keep attachment chip previews in the transcript
|
|
40
|
+
- rebuilt fullscreen session transcripts now preserve user image attachment markers instead of silently dropping image blocks
|
|
41
|
+
- managed `bb-clipboard-*.png` temp files are now cleaned up after removal or ingestion instead of lingering in `/tmp`
|
|
42
|
+
- the fullscreen input block now hides raw `@file` tokens when the corresponding attachment chip is already shown, preventing duplicated `@file` text in the editor
|
|
43
|
+
- fullscreen tool-header regression tests now match the intended live bash-header rendering and running-dot animation behavior
|
|
44
|
+
|
|
45
|
+
## [0.0.12] - 2026-04-06
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- direct `@image` references in print mode and fullscreen now attach real image inputs instead of falling back to UTF-8 read warnings
|
|
50
|
+
- `@path with spaces` parsing now correctly keeps the full file path before trailing prompt text, including whole-message forms
|
|
51
|
+
- image tool results are now preserved through provider conversion so models can actually see images returned by tools instead of responding as if no image was provided
|
|
52
|
+
- fullscreen `@` folder navigation now keeps the completion menu open when you select a directory and immediately shows the next level, including directories with spaces
|
|
53
|
+
- the fullscreen input block now shows attached files as `[name, sizeKB]`, keeps those chips visible, and places the cursor below them so typing starts after the attachments
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- binary office/document inputs (`pdf`, `docx`, `pptx`, `xlsx`) now degrade to format-aware metadata notes instead of misleading invalid-UTF-8 errors
|
|
58
|
+
|
|
8
59
|
## [0.0.11] - 2026-04-07
|
|
9
60
|
|
|
10
61
|
### Added
|
|
11
62
|
|
|
12
63
|
- startup update notices in the fullscreen transcript are now highlighted so available updates stand out clearly during startup
|
|
13
64
|
- 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
|
|
65
|
+
- fullscreen footer and `/session` info now show the active execution posture so safety vs yolo is visible during a run
|
|
14
66
|
|
|
15
67
|
### Improved
|
|
16
68
|
|
|
17
69
|
- npm install now caches verified native binaries by version/platform and reuses them on reinstall instead of re-downloading every time
|
|
18
70
|
- npm install now shows more frequent download progress with transfer rate information to make slow installs easier to understand
|
|
19
71
|
- npm install now avoids unnecessary re-verification on cache hits, making repeat installs faster
|
|
72
|
+
- safety mode now restricts built-in `write` and `edit` to the active workspace, while `yolo` keeps unrestricted file mutation behavior
|
|
73
|
+
|
|
74
|
+
### Migration
|
|
75
|
+
|
|
76
|
+
- `execution_mode` now defaults to `safety`; set `"execution_mode": "yolo"` if your workflow intentionally edits files outside the current workspace
|
|
20
77
|
|
|
21
78
|
## [0.0.10] - 2026-04-07
|
|
22
79
|
|
|
@@ -71,6 +128,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
71
128
|
|
|
72
129
|
- latest published package includes the post-0.0.7 startup, auth, model-default, and update-notice improvements
|
|
73
130
|
|
|
131
|
+
[0.0.14]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.14
|
|
132
|
+
[0.0.13]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.13
|
|
133
|
+
[0.0.12]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.12
|
|
74
134
|
[0.0.11]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.11
|
|
75
135
|
[0.0.10]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.10
|
|
76
136
|
[0.0.9]: https://github.com/shuyhere/bb-agent/releases/tag/v0.0.9
|
package/README.md
CHANGED
|
@@ -101,6 +101,7 @@ bb --list-models # List all available models
|
|
|
101
101
|
- **Fullscreen TUI** — rich terminal interface with streaming output, markdown rendering, syntax highlighting
|
|
102
102
|
- **Multi-provider** — Anthropic (Claude), OpenAI, Google (Gemini), Groq, xAI, OpenRouter, and custom OpenAI-compatible endpoints
|
|
103
103
|
- **Built-in tools** — `read`, `write`, `edit`, `bash`, `find`, `grep`, `ls`, `web_search`, `web_fetch`, `browser_fetch`
|
|
104
|
+
- **Safety and yolo execution modes** — default safety posture restricts built-in `write` and `edit` to the active workspace; yolo removes that guard
|
|
104
105
|
- **Session persistence** — SQLite-backed sessions with branching, forking, and tree navigation
|
|
105
106
|
- **Extensions** — JS/TS plugin system for custom tools, commands, and hooks
|
|
106
107
|
- **Skills** — markdown-based instruction files that auto-load contextual knowledge
|
|
@@ -144,9 +145,11 @@ BB-Agent uses layered configuration:
|
|
|
144
145
|
|
|
145
146
|
```json
|
|
146
147
|
{
|
|
148
|
+
"execution_mode": "safety",
|
|
147
149
|
"default_model": "claude-sonnet-4-20250514",
|
|
148
150
|
"default_provider": "anthropic",
|
|
149
151
|
"default_thinking": "medium",
|
|
152
|
+
"execution_mode": "safety",
|
|
150
153
|
"models": [
|
|
151
154
|
{
|
|
152
155
|
"id": "my-local-model",
|
|
@@ -160,6 +163,21 @@ BB-Agent uses layered configuration:
|
|
|
160
163
|
}
|
|
161
164
|
```
|
|
162
165
|
|
|
166
|
+
### Execution Modes
|
|
167
|
+
|
|
168
|
+
BB-Agent exposes the active permission posture in fullscreen and `/session`.
|
|
169
|
+
|
|
170
|
+
- `safety` is the default. Built-in `write` and `edit` stay inside the current workspace, and bash commands use the safer approval/sandboxed posture.
|
|
171
|
+
- `yolo` is the opt-in less-restrictive mode.
|
|
172
|
+
|
|
173
|
+
Example:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"execution_mode": "yolo"
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
163
181
|
## Keyboard Shortcuts
|
|
164
182
|
|
|
165
183
|
| Key | Action |
|
|
@@ -228,7 +246,6 @@ Or set this in `~/.bb-agent/settings.json`:
|
|
|
228
246
|
- [Development Guide](docs/development.md) — build from source, dev workflow, project structure, debugging
|
|
229
247
|
- [Contributing](CONTRIBUTING.md) — code style, PR process
|
|
230
248
|
- [Changelog](CHANGELOG.md) — release history
|
|
231
|
-
- [Security](SECURITY.md) — vulnerability reporting, security model
|
|
232
249
|
|
|
233
250
|
## Development
|
|
234
251
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import * as pi from '/home/shuyhere/projects/tako/node_modules/@mariozechner/pi-coding-agent/dist/core/compaction/compaction.js';
|
|
4
|
+
|
|
5
|
+
const settings = { enabled: true, reserveTokens: 16384, keepRecentTokens: 20000 };
|
|
6
|
+
|
|
7
|
+
function bbEstimateContextTokens(messages) {
|
|
8
|
+
function calc(usage) {
|
|
9
|
+
return usage.total_tokens > 0
|
|
10
|
+
? usage.total_tokens
|
|
11
|
+
: usage.input + usage.output + usage.cache_read + usage.cache_write;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function estimateText(text) {
|
|
15
|
+
return Math.ceil(text.length / 4);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function estimateMessage(message) {
|
|
19
|
+
switch (message.role) {
|
|
20
|
+
case 'user':
|
|
21
|
+
return message.content.reduce((sum, block) => sum + (block.type === 'text' ? estimateText(block.text) : 1200), 0);
|
|
22
|
+
case 'assistant':
|
|
23
|
+
return message.content.reduce((sum, block) => {
|
|
24
|
+
if (block.type === 'text') return sum + estimateText(block.text);
|
|
25
|
+
if (block.type === 'thinking') return sum + estimateText(block.thinking);
|
|
26
|
+
if (block.type === 'toolCall') return sum + estimateText(block.name) + estimateText(JSON.stringify(block.arguments ?? {}));
|
|
27
|
+
return sum;
|
|
28
|
+
}, 0);
|
|
29
|
+
case 'toolResult':
|
|
30
|
+
case 'custom':
|
|
31
|
+
return message.content.reduce((sum, block) => sum + (block.type === 'text' ? estimateText(block.text) : 1200), 0);
|
|
32
|
+
case 'bashExecution':
|
|
33
|
+
return estimateText(message.command) + estimateText(message.output);
|
|
34
|
+
case 'branchSummary':
|
|
35
|
+
case 'compactionSummary':
|
|
36
|
+
return estimateText(message.summary);
|
|
37
|
+
default:
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const lastUsageIndex = [...messages.keys()].reverse().find((i) => {
|
|
43
|
+
const m = messages[i];
|
|
44
|
+
return m.role === 'assistant' && m.stopReason !== 'aborted' && m.stopReason !== 'error' && calc(m.usage) > 0;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (lastUsageIndex == null) {
|
|
48
|
+
const trailingTokens = messages.reduce((sum, m) => sum + estimateMessage(m), 0);
|
|
49
|
+
return { tokens: trailingTokens, usageTokens: 0, trailingTokens, lastUsageIndex: null };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const usageTokens = calc(messages[lastUsageIndex].usage);
|
|
53
|
+
const trailingTokens = messages.slice(lastUsageIndex + 1).reduce((sum, m) => sum + estimateMessage(m), 0);
|
|
54
|
+
return { tokens: usageTokens + trailingTokens, usageTokens, trailingTokens, lastUsageIndex };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
test('bb estimator matches installed pi on shared fixtures', () => {
|
|
58
|
+
const fixtures = [
|
|
59
|
+
[
|
|
60
|
+
{
|
|
61
|
+
role: 'assistant',
|
|
62
|
+
content: [{ type: 'text', text: 'done' }],
|
|
63
|
+
provider: 'test',
|
|
64
|
+
model: 'test',
|
|
65
|
+
usage: { input: 100, output: 20, cacheRead: 10, cacheWrite: 5, totalTokens: 0 },
|
|
66
|
+
stopReason: 'stop',
|
|
67
|
+
timestamp: Date.now(),
|
|
68
|
+
},
|
|
69
|
+
{ role: 'user', content: [{ type: 'text', text: '12345678' }], timestamp: Date.now() },
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
{
|
|
73
|
+
role: 'assistant',
|
|
74
|
+
content: [{ type: 'text', text: 'aborted' }],
|
|
75
|
+
provider: 'test',
|
|
76
|
+
model: 'test',
|
|
77
|
+
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 500 },
|
|
78
|
+
stopReason: 'aborted',
|
|
79
|
+
timestamp: Date.now(),
|
|
80
|
+
},
|
|
81
|
+
{ role: 'user', content: [{ type: 'text', text: '12345678' }], timestamp: Date.now() },
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
{
|
|
85
|
+
role: 'assistant',
|
|
86
|
+
content: [
|
|
87
|
+
{ type: 'text', text: 'hello' },
|
|
88
|
+
{ type: 'thinking', thinking: 'reasoning text' },
|
|
89
|
+
{ type: 'toolCall', id: '1', name: 'read', arguments: { path: 'src/main.rs' } },
|
|
90
|
+
],
|
|
91
|
+
provider: 'test',
|
|
92
|
+
model: 'test',
|
|
93
|
+
usage: { input: 300, output: 40, cacheRead: 50, cacheWrite: 0, totalTokens: 0 },
|
|
94
|
+
stopReason: 'stop',
|
|
95
|
+
timestamp: Date.now(),
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
role: 'toolResult',
|
|
99
|
+
toolCallId: '1',
|
|
100
|
+
toolName: 'read',
|
|
101
|
+
content: [{ type: 'text', text: 'fn main() {}' }],
|
|
102
|
+
isError: false,
|
|
103
|
+
timestamp: Date.now(),
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
role: 'bashExecution',
|
|
107
|
+
command: 'ls -la',
|
|
108
|
+
output: 'file1\nfile2\n',
|
|
109
|
+
cancelled: false,
|
|
110
|
+
truncated: false,
|
|
111
|
+
timestamp: Date.now(),
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
for (const messages of fixtures) {
|
|
117
|
+
const piEstimate = pi.estimateContextTokens(messages);
|
|
118
|
+
const bbEstimate = bbEstimateContextTokens(
|
|
119
|
+
JSON.parse(
|
|
120
|
+
JSON.stringify(messages)
|
|
121
|
+
.replace(/cacheRead/g, 'cache_read')
|
|
122
|
+
.replace(/cacheWrite/g, 'cache_write')
|
|
123
|
+
.replace(/totalTokens/g, 'total_tokens')
|
|
124
|
+
.replace(/stopReason/g, 'stopReason')
|
|
125
|
+
)
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
assert.deepEqual(bbEstimate, {
|
|
129
|
+
tokens: piEstimate.tokens,
|
|
130
|
+
usageTokens: piEstimate.usageTokens,
|
|
131
|
+
trailingTokens: piEstimate.trailingTokens,
|
|
132
|
+
lastUsageIndex: piEstimate.lastUsageIndex,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const contextWindow = 128000;
|
|
136
|
+
assert.equal(
|
|
137
|
+
bbEstimate.tokens > contextWindow - settings.reserveTokens,
|
|
138
|
+
pi.shouldCompact(piEstimate.tokens, contextWindow, settings)
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
});
|