@owloops/browserbird 1.8.5 → 1.8.7
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/README.md +4 -1
- package/dist/index.mjs +15 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -276,7 +276,10 @@ Store API keys and secrets in the web UI (Settings, Keys tab) and bind them to s
|
|
|
276
276
|
- **Encrypted at rest** with AES-256-GCM. The encryption key is auto-generated on first start and stored in `.env` as `BROWSERBIRD_VAULT_KEY`.
|
|
277
277
|
- **Redacted from output.** If the agent prints a vault key value, it appears as `[redacted]` in Slack and logs.
|
|
278
278
|
- **Bound to targets.** A key bound to channel `*` applies to all channels. A key bound to a specific bird applies only when that bird runs. Bird-level keys override channel-level keys on name conflict.
|
|
279
|
-
|
|
279
|
+
|
|
280
|
+
**Example: GitHub integration.** Store a GitHub personal access token as `GITHUB_TOKEN` in the vault and bind it to a channel or bird. The agent can then create issues, open PRs, push code, review changes, and manage repositories using the GitHub API or CLI.
|
|
281
|
+
|
|
282
|
+
**Example: authenticated browsing.** For birds that need to browse logged-in sites (X, LinkedIn, etc.), export cookies from your local browser using [Cookie-Editor](https://github.com/moustachauve/cookie-editor), store the JSON as a vault key (e.g. `X_COOKIES`), and bind it to the bird. In the bird's prompt, instruct it to read the cookies from the env var and inject them via `addCookies` before browsing. Pre-injecting cookies ensures the agent starts in a logged-in state, making scheduled tasks more reliable.
|
|
280
283
|
|
|
281
284
|
## CLI
|
|
282
285
|
|
package/dist/index.mjs
CHANGED
|
@@ -193,8 +193,8 @@ function unknownSubcommand(subcommand, command, validCommands) {
|
|
|
193
193
|
/** @fileoverview ASCII banner displayed on daemon startup and in help text. */
|
|
194
194
|
const pkg = createRequire(import.meta.url)("../package.json");
|
|
195
195
|
const buildInfo = [];
|
|
196
|
-
buildInfo.push(`commit: ${"
|
|
197
|
-
buildInfo.push(`built: 2026-03-
|
|
196
|
+
buildInfo.push(`commit: ${"637d56da365a934b93c6e1a80c98ef7bc60967bb".substring(0, 7)}`);
|
|
197
|
+
buildInfo.push(`built: 2026-03-22T22:44:02+04:00`);
|
|
198
198
|
const buildString = buildInfo.length > 0 ? ` (${buildInfo.join(", ")})` : "";
|
|
199
199
|
const VERSION = `browserbird ${pkg.version}${buildString}`;
|
|
200
200
|
const BIRD = [
|
|
@@ -4498,14 +4498,18 @@ function createHandler(client, getConfig, signal, getTeamId, getChannelNameToId)
|
|
|
4498
4498
|
const msg = err instanceof Error ? err.message : String(err);
|
|
4499
4499
|
return msg.includes("not_in_streaming_state") || msg.includes("streaming") || msg.includes("msg_too_long");
|
|
4500
4500
|
}
|
|
4501
|
+
let streamToolCount = 0;
|
|
4501
4502
|
async function resetStream() {
|
|
4502
4503
|
try {
|
|
4503
4504
|
await streamer.stop();
|
|
4504
4505
|
} catch {}
|
|
4505
4506
|
streamer = client.startStream(streamOpts);
|
|
4506
4507
|
streamedChars = 0;
|
|
4508
|
+
streamToolCount = 0;
|
|
4509
|
+
needsPlanHeader = true;
|
|
4507
4510
|
logger.debug("stream reset: started new streaming message");
|
|
4508
4511
|
}
|
|
4512
|
+
let needsPlanHeader = true;
|
|
4509
4513
|
async function safeAppend(content) {
|
|
4510
4514
|
if (streamDead) {
|
|
4511
4515
|
if (content.markdown_text) await client.postMessage(channelId, threadTs, content.markdown_text).catch(() => {});
|
|
@@ -4566,13 +4570,17 @@ function createHandler(client, getConfig, signal, getTeamId, getChannelNameToId)
|
|
|
4566
4570
|
client.setStatus?.(channelId, threadTs, lastStatus).catch(() => {});
|
|
4567
4571
|
if (event.toolCallId !== void 0) {
|
|
4568
4572
|
toolCount++;
|
|
4573
|
+
streamToolCount++;
|
|
4569
4574
|
activeTasks.set(event.toolCallId, event.toolName);
|
|
4570
4575
|
const title = toolTaskTitle(event.toolName);
|
|
4571
4576
|
const chunks = [];
|
|
4572
|
-
if (
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4577
|
+
if (needsPlanHeader) {
|
|
4578
|
+
chunks.push({
|
|
4579
|
+
type: "plan_update",
|
|
4580
|
+
title: "Working on it"
|
|
4581
|
+
});
|
|
4582
|
+
needsPlanHeader = false;
|
|
4583
|
+
}
|
|
4576
4584
|
chunks.push({
|
|
4577
4585
|
type: "task_update",
|
|
4578
4586
|
id: event.toolCallId,
|
|
@@ -4598,7 +4606,7 @@ function createHandler(client, getConfig, signal, getTeamId, getChannelNameToId)
|
|
|
4598
4606
|
...event.output ? { output: redact(event.output) } : {}
|
|
4599
4607
|
}];
|
|
4600
4608
|
if (activeTasks.size === 0) {
|
|
4601
|
-
const label = toolErrors === 0 ? `Completed (${
|
|
4609
|
+
const label = toolErrors === 0 ? `Completed (${streamToolCount} ${streamToolCount === 1 ? "step" : "steps"})` : `${toolSuccesses} passed, ${toolErrors} failed`;
|
|
4602
4610
|
chunks.push({
|
|
4603
4611
|
type: "plan_update",
|
|
4604
4612
|
title: label
|