Skip to content
lettlandPublic
forked from get-bb/bb

About

The agent IDE that builds itself

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

7,019 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bb

bb

npm version Join Discord

bb is an agentic IDE that builds itself. It can control, customize, and automate itself, laying the groundwork for your own software factory.

Every surface — the desktop app, web app, CLI, and HTTP API — is a first-class way to drive bb. Work runs in threads you can follow live, steer at any point, or hand off to another agent.

Note

bb is in active development. Core architecture is stable, but workflows and surfaces are still evolving.

bb desktop app showing a code review thread, dispatch panel, and task board

Use bb

Download the desktop app

The recommended way to start using bb is the desktop app:

Download the latest desktop app

The desktop app supports macOS on Apple Silicon (arm64). The Linux x64 AppImage and the Windows x64 installer are alpha: expect problems, and please report them. Intel Mac users should run bb with npx instead. Native Windows needs Git for Windows, which bb uses for Git and for environment setup scripts. You can also run bb inside WSL2 (Windows Subsystem for Linux): install WSL2 first, then run the npx command below from your WSL2 (Linux) shell.

Early adopters can install bb Nightly alongside the stable desktop app. It has a separate application identity, yellow icon, and auto-update feed.

Or run it anywhere with npx

npx bb-app@latest

Then open http://localhost:38886.

To control bb from outside bb with the bb CLI, open Settings → General → Command line and choose Install. See The bb Command On PATH.

To run the newest automated build instead:

npx bb-app@nightly

npm 12 and later block dependency install scripts by default. bb needs those scripts to build its native add-ons. If your npm version is 12 or later, allow the scripts for the install:

npx --allow-scripts=better-sqlite3,node-pty,@parcel/watcher bb-app@latest

Or set the policy once for all global installs:

npm config set allow-scripts=better-sqlite3,node-pty,@parcel/watcher --location=user

bb uses the provider CLI you already have authenticated.

For install requirements, provider setup, configuration, and package-focused docs, start with packages/bb-app.

Telemetry

Production runs (the desktop app, npx bb-app, and pnpm start checkouts) send anonymous usage telemetry (app starts, thread creation counts, user message counts, and plugin installs) to help us understand adoption. Each event carries the app version, how bb was installed (desktop, npm, or source checkout), and the OS release, CPU architecture, and Node version. Source checkouts report whether origin points to github.com/get-bb/bb, another repository, or is unavailable. Telemetry never includes Git commit hashes or remote URLs. Identification is a random per-install id stored in your data dir — no user, host, project, workspace, or message content is ever attached. Plugin install events name only public plugins (bundled plugins and bb-community marketplace entries); installs from a local path, a private git or npm source, or a third-party marketplace report no name. Development runs (pnpm dev, pnpm start:worktree) never send. Opt out any run with BB_TELEMETRY=false. See apps/server/src/services/system/telemetry.ts.

Development

Use the development loop when working on bb itself:

pnpm dev

That starts the Vite app and proxies API and WebSocket traffic to a separate dev server. The launcher prints the actual ports at startup. Each checkout gets a data directory under ~/.bb-dev/<checkout-instance>/ and deterministic high ports derived from the checkout path. The checkout instance id is the sanitized path to the checkout, relative to your home directory, plus a short hash suffix. Separate worktrees can run alongside each other and the packaged npx bb-app@latest instance.

To test the production bundle and serving path without switching to production data or ports, use:

pnpm start:worktree

This builds the same optimized frontend and runtime artifacts as pnpm start, then serves the app from the BB server on the checkout-specific dev server port. It keeps the normal checkout-specific dev data directory and host-daemon port. There is no Vite dev server or hot reload in this mode; rerun the command after source changes. As with pnpm dev, worktree starts do not send telemetry.

For the Electron desktop shell, keep pnpm dev running and start the desktop package in a second terminal:

pnpm exec turbo run dev --filter=@bb/desktop

The desktop shell connects to this checkout's running dev app. Stop each command with Ctrl-C in its terminal.

To package a private fork beside the official Homebrew-managed desktop app, use pnpm desktop:local:package. The resulting bb Local.app has the distinct bundle identifier dev.bb.desktop.local and does not use the official update feeds. Updating it is therefore an explicit fetch/rebase/build operation, while Homebrew can continue updating the official bb.app independently.

Run pnpm desktop:local:update from Terminal or iTerm on a clean local-fork branch (--current also accepts uncommitted changes); it refuses to run inside bb because it quits bb Local itself. It first fetches upstream main and reports the upstream and patch counts, before touching bb Local. It then makes bb Local the running server (stopping the official app if it holds the port), recovers a leftover update pause, and checks the plugin collection. Only then does it pause all work through a sealed bb maintenance lease and quit bb Local. After the quit it rebases the private commit stack, installs dependencies, packages and smoke-tests the local desktop app, ad-hoc signs it, and installs it beside the official app. The new bb Local starts under the sealed lease, the script syncs the private plugins from the lettland/bb-plugins Git collection while bb Local is open but paused, waits for every host daemon that was paused to reconnect, releases the lease, and pushes the result to the fork's main with a force-with-lease. Automatic and queued work is held while paused and resumed on release; turns interrupted by the quit are retried where provider-retry applies, and turns already running on remote hosts continue. If the new app fails its health check, the previous app is restored from ~/.Trash/bb-local-backup-*.app (the failed app is moved to ~/.Trash/bb-local-failed-*.app) before the pause is released. --check only fetches and reports the upstream and patch counts. --skip-install, --skip-plugins, --skip-other-plugins, and --skip-push selectively omit those final operations; --skip-install never quits bb Local or pauses work and still starts the official app when plugin synchronization has no server.

--plugins-only syncs just the lettland/bb-plugins collection and does nothing else: no git, build, install, or push. It needs no clean worktree, and bb Local may be running. It logs the resolved bb CLI and syncs through it against whichever server answers, starting nothing. The CLI is BB_CLI when set, then bb Local's CLI, then the first bb on PATH or in an installed bb.app. It refuses to run while a desktop update is in progress or after one was interrupted, which may have left bb Local paused; if no update is running, run --recover first. It cannot be combined with other flags except --skip-other-plugins. Plugins that the collection manifest no longer lists are removed, and their settings, secrets, and schedules are dropped.

After the collection sync, --plugins-only and a full update also update the other installed plugins (git and npm plugins installed from a tracking ref or range). This pass runs last, after the update has completed and the fork push is done, so it cannot roll back a release or lengthen a pause. It runs bb plugin outdated and applies each compatible update with bb plugin update --yes, which means it auto-applies third-party full-trust plugin code without a prompt. Failures only print warnings and never change the exit code. The outdated read times out after 2 minutes and each update after 10 minutes; a timed-out update warns that the server-side update may still finish. --skip-other-plugins skips just this pass and keeps the collection sync; --skip-plugins skips both. Once the update is applied, Ctrl-C aborts the fork push if it is still running, or stops the third-party pass, and the updater then exits non-zero even though the bb update itself already finished.

The pause covers every host that was connected when it was sealed, including remote hosts such as a VPS. Release waits for a daemon with each of those host IDs to reconnect; keep those machines awake until the update finishes. A paused host that is gone for good blocks the release: the updater cannot release the pause until some daemon with that host ID reconnects, so reconnect one (or restart its daemon) and run --recover.

If the update was interrupted (a closed terminal, a crash, or a host daemon that never reconnected), the pause may still be held and the state is recorded in ~/.bb/admin/desktop-update.json. Run pnpm desktop:local:update --recover to start bb Local if needed, wait for the paused hosts, and release the pause. --recover stops the official bb.app if it is running, so run it from Terminal or from inside bb Local, never from inside the official app. If a remote host stays offline, reconnect it or restart its daemon first. If the installed app will not start, restore the backup the updater printed over /Applications/bb Local.app, then run --recover. If the state file is unreadable, or another maintenance lease is held, --recover prints the raw bb maintenance commands for the installed bb Local CLI (skip the transition when the phase is already releasing) and points to bb maintenance status and docs/linux-arm64-vps.md.

Use pnpm desktop:local:update -- --current to run the same test, package, signing, installation, activation, plugin synchronization, and health workflow against the checkout exactly as it is on disk, including uncommitted and untracked changes, which it lists before building and marks as <sha>-dirty. Current-checkout mode skips every remote fetch and the rebase. If pushing is enabled, it protects the fork with the existing remote-tracking head as a force-with-lease; fetch the fork first if that ref is missing. Pushing requires the checked-out branch to match the configured fork branch and a checkout without uncommitted changes. Pass --skip-push to use another branch or a dirty checkout and avoid all Git remote operations; dependency installation can still access package registries.

The updater identifies the two remotes by URL, not by name: whichever remote points at get-bb/bb is upstream, and the remaining one is the fork. Either remote layout therefore works, whether upstream is origin and the fork is fork, or upstream is a named remote such as _get-bb and the fork is origin. Set BB_LOCAL_UPSTREAM_REMOTE or BB_LOCAL_FORK_REMOTE to pin a name explicitly, BB_LOCAL_UPSTREAM_SLUG to track a different upstream repository, and BB_LOCAL_UPSTREAM_BRANCH or BB_LOCAL_FORK_BRANCH to use branches other than main.

The updater installs the complete lettland/bb-plugins collection. It updates plugins already installed from the collection's own GitHub repository, replaces plugins installed from another source or another GitHub repository, and removes collection-managed plugins no longer present in the manifest.

To use the dev app from another machine over Tailscale, start it with the Tailscale browser origin configured:

BB_APP_URL=https://<machine>.<tailnet>.ts.net pnpm dev

Note the printed app port, then publish the loopback Vite listener in another terminal:

tailscale serve --bg --https=443 http://127.0.0.1:<app-port>

Then open https://<machine>.<tailnet>.ts.net. Source dev binds both the Vite app and main server to loopback by default; Vite continues to proxy API and WebSocket traffic.

For direct access at http://<tailscale-ip>:<app-port> instead, run:

pnpm dev:remote

This binds the Vite app and main server to all IPv4 interfaces. The remote browser must be able to reach both the printed app and server ports for realtime updates. The server API is unauthenticated and permits command execution and file reads, so use this only behind a trusted network boundary and restrict the ports to Tailscale traffic with the host firewall when the LAN is not trusted.

To access the production-style worktree server directly from another machine, run:

pnpm start:worktree-remote

This uses the same checkout-specific data directory and ports as pnpm start:worktree, but binds its single server listener to all IPv4 interfaces. The server API is unauthenticated and permits command execution and file reads, so use it only behind a trusted network boundary and restrict the port to Tailscale traffic with the host firewall when the LAN is not trusted.

To use the component storybook from another machine, run:

pnpm storybook

Ladle binds to all interfaces and configures its HMR WebSocket to use the browser's current host instead of localhost. Do not run pnpm storybook on an untrusted network.

Development behavior is intentionally split:

  • the app hot reloads itself
  • the server does not hot reload
  • the host daemon does not hot reload

When you want the server and host daemon to pick up the latest build output, use:

pnpm dev:restart
pnpm dev:restart-server
pnpm dev:restart-host-daemon

These rebuild first, then restart only the targeted stateful services.

To run a production-mode build from a source checkout:

pnpm start

That builds only the app, server, and host-daemon runtime artifacts, then runs the launcher directly against those workspace outputs. Use the bb-app tarball smoke task when validating the published npx bb-app@latest package layout.

pnpm bb --help            # built CLI, targets the default/prod instance
pnpm reset                # clear production state

pnpm bb:dev --help        # source CLI, targets this checkout's dev instance
pnpm reset:dev            # clear this checkout's dev state

pnpm reset:all            # clear both production and dev states

These reset commands prompt for confirmation before deleting anything.

Repository Overview

See Repository overview for the monorepo package and app map.

System Overview

See System overview for runtime architecture, data model, and component boundaries.

Further Reading

Contributing

See CONTRIBUTING.md for contribution guidelines.

Troubleshooting

Could not locate the bindings file

bb uses native add-ons, for example better-sqlite3 and @parcel/watcher. npm downloads or builds those binaries in a package install script. If npm does not run install scripts, the binaries are absent. bb then stops at startup with this error:

Error: Could not locate the bindings file. Tried:
 → .../node_modules/better-sqlite3/build/better_sqlite3.node

There are two usual causes.

The first cause is npm 12 or later. Since npm 12, npm blocks dependency install scripts by default and prints npm warn install-scripts N packages had install scripts blocked. Name bb's native add-ons in --allow-scripts to let this one command run their install scripts:

npx --allow-scripts=better-sqlite3,node-pty,@parcel/watcher bb-app@latest

For a permanent install with the same setting, use:

npm install -g --allow-scripts=better-sqlite3,node-pty,@parcel/watcher bb-app
bb-app

To allow them for all global installs on this machine, run npm config set allow-scripts=better-sqlite3,node-pty,@parcel/watcher --location=user. npm 10 and 11 accept or ignore the flag, so it is safe on every supported Node.

The second cause is ignore-scripts=true in your ~/.npmrc. Set the npm_config_ignore_scripts environment variable to let this one command run its install scripts:

npm_config_ignore_scripts=false npx bb-app@latest

For a permanent install with the same setting, use:

npm_config_ignore_scripts=false npm install -g bb-app
bb-app

The environment variable applies to that one command only. Keep ignore-scripts=true in your ~/.npmrc if you want it for security.

The same error has other causes. A Node.js major-version change after the install causes it. A copy of node_modules from a different operating system, CPU architecture, or libc variant also causes it. To recover, install the package again, or run npm rebuild better-sqlite3.

Acknowledgements

CI powered by Blacksmith

About

The agent IDE that builds itself

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages