Metadata-Version: 2.4
Name: bitp
Version: 1.6.2
Summary: Manage projects made of git repositories, with BitBake/Yocto support
Author-email: Bruce Ashfield <bruce.ashfield@gmail.com>
License: GPL-2.0-only
Project-URL: Homepage, https://gitlab.com/bruce-ashfield/bitp
Project-URL: Repository, https://gitlab.com/bruce-ashfield/bitp
Project-URL: Issues, https://gitlab.com/bruce-ashfield/bitp/-/issues
Keywords: bitbake,yocto,openembedded,layers,git
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Embedded Systems
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: COPYING
Provides-Extra: completion
Requires-Dist: argcomplete>=2.0; extra == "completion"
Provides-Extra: notifications
Requires-Dist: keyring>=24.0; extra == "notifications"
Provides-Extra: tui
Requires-Dist: textual<9,>=8.2; python_version >= "3.10" and extra == "tui"
Requires-Dist: textual-tty<0.5,>=0.4; python_version >= "3.10" and extra == "tui"
Provides-Extra: dev
Requires-Dist: argcomplete>=2.0; extra == "dev"
Requires-Dist: keyring>=24.0; extra == "dev"
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: pytest-mock>=3.0; extra == "dev"
Dynamic: license-file

# bitp

Manage projects made of git repositories, locally or on build hosts over SSH,
from the command line, interactive terminal menus or a web dashboard. Any set
of git repos works; BitBake/Yocto/OpenEmbedded projects also get layers,
recipes, fragments and dependencies.

The command is `bit` for quick typing.

```bash
pip install bitp
```

Or grab the single-file standalone `bit` (see [INSTALL.md](https://gitlab.com/bruce-ashfield/bitp/-/blob/main/INSTALL.md)).

## Overview

`bit` helps developers working across several git repos, and Yocto/OpenEmbedded projects in particular, by providing tools to:

- **Update** git repos backing BitBake layers from a `bblayers.conf`
- **Explore** commits interactively with fzf-based navigation
- **Export** patches with cover letters for upstream submission
- **Move changes** between projects, locally or on other build hosts
- **Manage branches** across multiple layer repositories
- **Search** the OpenEmbedded Layer Index for layers
- **Bootstrap** new projects by cloning core repositories
- **Manage projects** - switch between multiple Yocto builds from anywhere, local or over SSH
- **Web dashboard** - the same, in a browser, with terminals and drag and drop

## Features

- **Automatic layer discovery** - finds layers by searching for `conf/layer.conf` files
- **Multi-layer repo support** - handles repos containing multiple layers (e.g., meta-openembedded)
- **Interactive fzf menus** - fast navigation with preview panes and keyboard shortcuts
- **Tab completion** - bash completion via argcomplete
- **Background refresh** - upstream status checks run in background for fast startup
- **Per-repo configuration** - custom display names, update defaults, push targets

## Quick Start

```bash
# Browse configs and create a new project (one-step)
bit setup configs

# Clone into a specific directory or remote host
bit setup configs ./my-project
bit setup configs user@host:/opt/yocto

# Or step by step
bit setup clone -b scarthgap --doit
bit setup

# Check status of all layer repos
bit repos summary

# Interactively explore repos and commits
bit explore

# Update all repos (interactive)
bit repos update

# Update all repos non-interactively (apply saved defaults)
bit repos update -y

# Search for layers in the OE Layer Index
bit layer-index security
```

## Screenshots

### Project Dashboard

Every project in one list, local builds and ones on build hosts over SSH, with each repo's local commits (↑) and upstream changes to pull (↓). Expand a project for its actions.

![Dashboard](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/dashboard.png)

### Explore Repos

Browse layer repositories with upstream status, branch info, and dirty/clean indicators. Yocto projects get extra keybindings for recipes, deps, fragments, and build info.

![Explore](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/explore.png)

Expand multi-layer repos to see individual layers:

![Explore Expanded](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/explore-expanded.png)

### Recipe Browser

Search and browse BitBake recipes across layers. Expand recipes to see dependencies inline.

![Recipes](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/recipes.png)

![Recipe Dependencies](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/recipes-deps.png)

### Commit Browser

Drill into a repo to browse its local commits and what upstream has, with a preview pane. Mark commits to export, drop or rebase, or launch git tools.

![Commits](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/commits.png)

### Web Dashboard

`bit serve` launches a web dashboard and auto-update daemon, with themes, keyboard navigation, terminals and live updates. Projects tagged with `auto-update` are periodically fetched and updated.

**Dashboard** — projects grouped by host:

![Web Dashboard](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/web-dashboard.png)

**Repos** — the project's repos with their newest commit, local and upstream counts, and actions:

![Web Repos](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/web-repos.png)

**Commits** — local commits, what upstream has, and recent history; a commit opens on the right with its diff:

![Web Commits](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/web-commits.png)

**Recipes** — recipes by layer, one open with its dependencies and variables:

![Web Recipes](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/web-recipes.png)

**Changes** — send a project's local commits to another project, here one on a build host; every repo is checked first:

![Web Changes](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/web-changes.png)

**Patches** — patch files across layers with their Upstream-Status:

![Web Patches](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/web-patches.png)

**Hosts** — each host's OS, load, memory and disks:

![Web Hosts](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/web-hosts.png)

**Settings** — themes, sizes, fonts and defaults:

![Web Settings](https://gitlab.com/bruce-ashfield/bitp/-/raw/main/docs/images/web-settings.png)

## Commands

| Command | Alias | Description |
|---------|-------|-------------|
| `explore` | `x` | Interactively explore commits in layer repos |
| `repos` | `repo` | List repos; `status` (one line each), `summary` (local commits), `update`, `config` |
| `changes` | - | A project's local commits: `list`, `send`, `fetch`, `received`, `clean`, `export`, `prep`, `summarize` |
| `branch` | `b` | List, switch and delete branches across repos |
| `info` | `i` | Show build configuration and layer status |
| `config` | `c` | bit's global settings (`get`, `set`, `export-settings`, `import-settings`) and the interactive repo config menu |
| `setup` | `init` | Show OE/Yocto build environment setup command |
| `setup shell` | - | Start shell with OE build environment pre-sourced |
| `setup clone` | - | Clone the core repos, or a `.conf.json` config or registry entry |
| `setup apply` | - | Apply layers and fragments from saved config |
| `setup configs` | - | Browse saved build configurations, pick one and clone it |
| `setup export` | - | Export current build state as `.conf.json` |
| `setup registry-copy` | - | Copy a `.conf.json` file to the user registry |
| `b4` | - | Mail-based patch management using b4 and lore.kernel.org |
| `pending` | - | Patches and pull requests that haven't landed yet |
| `patches` | - | Explore and manage patches across layers |
| `deps` | `d` | Show layer and recipe dependencies |
| `recipes` | `r` | Search and browse BitBake recipes |
| `fragments` | `f` | Browse and manage OE configuration fragments |
| `layer-index` | `layers`, `search` | Search OpenEmbedded Layer Index for layers |
| `projects` | `p` | Manage and switch between multiple project directories |
| `dashboard` | - | The project dashboard (also what `bit` alone opens) |
| `hosts` | - | SSH host entries used by remote projects (`list`, `add`, `remove`, `test`) |
| `watch` | - | Watch tracked repos for commits that match a rule |
| `notify` | - | Email notifications from the auto-update daemon |
| `serve` | `daemon` | Web dashboard and auto-update daemon |
| `help` | `h` | Browse help for every command |

**Renamed commands.** These moved under a noun; the old names still work
for now and print a warning (set `BIT_SUPPRESS_DEPRECATION=1` to silence it):

| Old | New |
|-----|-----|
| `update`, `u` | `repos update` |
| `status` | `repos summary` |
| `config <repo> …`, `config edit <layer>` | `repos config <repo> …`, `repos config edit <layer>` |
| `export`, `export prep` | `changes export`, `changes prep` |
| `summarize`, `sum` | `changes summarize` |
| `clone` | `setup configs` |
| `bootstrap` | `setup clone` |

Run `bit` with no arguments for the project dashboard (bit tui; `bit config default-tui fzf` for the fzf one), `bit help` to browse every command, or `bit <command> --help` for its options.

## Common Workflows

### Starting a New Project

There are several ways to create a new project, depending on whether you have a saved build configuration.

#### Basic clone (no config file)

Clone the three core repos (bitbake, openembedded-core, meta-yocto) and set up the build environment:

```bash
# Clone core repos at a release branch
bit setup clone -b scarthgap --doit

# Show the environment setup command
bit setup

# Or jump straight into a sourced shell
bit setup shell
```

#### Clone from a saved configuration

Build configurations (`.conf.json` files) capture repos, layers, branches, and OE fragments. The fastest way to create a project:

```bash
# One-step: browse configs, pick one, clone, apply, browse fragments
bit setup configs

# Pre-set the target directory (local or remote)
bit setup configs ./my-build
bit setup configs user@host:/opt/yocto

# Step-by-step alternative
bit setup clone --config poky.conf.json --doit
bit setup apply
```

`bit setup configs` opens a **registry browser** showing all available configs from the built-in and user registries (`~/.config/bit/registry/`). Each entry shows its type (`[Built-in]`, `[User]`) and a preview of included repos, layers, and fragments. An optional target argument pre-fills the directory prompt and shows in the header.

When you select a config and choose **Clone**, the full flow runs automatically: clone repos → apply layers → apply fragments → open fragment browser for fine-tuning. If the directory prompt receives a `user@host:/path`, the entire flow runs on the remote host via SSH.

`setup apply` creates `build/conf/` if missing, adds layers to `bblayers.conf`, and applies OE configuration fragments. For one-of fragment categories (e.g., machine, distro where only one choice makes sense), an interactive picker prompts you to choose which fragment to enable. If a different config was previously applied, a warning is shown.

#### From the dashboard

The dashboard detects empty or new directories and offers to create a project:

1. Open `bit projects`
2. Press `+` to add a directory (browse, enter a path, or use current directory)
3. If the directory is empty or doesn't exist, a **config registry picker** opens:
   - Shows all saved configs with `[Built-in]`, `[User]`, and `[Basic]` labels
   - Preview pane shows config details (repos, layers, fragments)
   - Select a config to clone its repos into the new project
   - Or choose "Basic clone" to get the three core repos (bitbake, oe-core, meta-yocto) without a config file
   - Esc skips config selection and registers an empty project
4. After cloning, `setup apply` chains automatically:
   - Creates `build/conf/` if missing (with confirmation prompt)
   - Adds layers from the config to `bblayers.conf`
   - **Fragment selection**: OE configuration fragments from the config are applied. For one-of categories (e.g., machine, distro), an interactive picker prompts you to choose which fragment to enable
   - Validates the setup and marks the config as applied
5. If apply is declined or interrupted, the project shows `⚠ setup` in the dashboard — expand it and select "setup" to resume later

If the directory already has content, it's added as an existing project (no config picker).

### Saving and Sharing Build Configurations

#### Export current build state

```bash
# Export to a .conf.json file in the current directory
bit setup export

# Export with a custom filename
bit setup export my-build.conf.json

# Export and save to the user registry for reuse
bit setup export --registry

# Export a different registered project
bit setup export --project my-other-build
```

The export captures git remotes, branches, layer paths, and enabled OE fragments.

The dashboard also supports export: expand a project and select "export" to open an inline dialog with fragment checkboxes (`[x]`/`[ ]`) to toggle which fragments are included, an optional description field, and actions to export to a file or save to the registry.

#### Manage the config registry

```bash
# Copy a config file into the registry
bit setup registry-copy poky.conf.json

# Copy with a custom name
bit setup registry-copy poky.conf.json --as my-custom-build

# Browse and manage all saved configs
bit setup configs
```

The registry browser (`bit setup configs`) provides:
- Preview pane showing config details (repos, layers, fragments)
- Actions: Clone, Apply, Fragments, Copy, Describe, Edit, Rename, Delete
- Built-in configs are read-only (Clone, Apply, Fragments, Copy only)
- User configs support all actions including inline rename and describe
- **ctrl-f** or "Browse Fragments" menu item jumps to the fragment browser (when inside a project)
- Target header shows where clones will land when a target is specified

### Build Environment Shell

```bash
# Show the source command for oe-init-build-env
bit setup

# Start a shell with the build environment pre-sourced
bit setup shell
```

`setup shell` starts a new shell with the OE build environment already sourced, so `bitbake` and related tools are immediately available.

### Daily Development

```bash
# Check what's changed upstream
bit repos summary

# Update repos (interactive)
bit repos update

# Update all repos non-interactively (apply saved defaults)
bit repos update -y

# Or update a specific repo
bit repos update OE-core
```

### Exploring Commits

```bash
# Interactive two-level browser
bit explore

# Jump directly to a repo
bit x OE-core
```

Keybindings in explore mode (repo list):
- `Enter` - explore commits in selected repo
- `→`/`←`/`\` - expand/collapse a multi-layer repo (`\` on a heading does all of them)
- `L` - switch between the repos view and the layers view
- `u` - update the repo (rebase), `m` - merge, `U` - update all repos
- `r` - refresh repo (fetch), `R` - refresh all repos
- `b` - the repo's branches, `B` - switch all repos to a branch (common branches first, partial dimmed)
- `t` - commit history browser (`T` inside it opens your git viewer)
- `v` - toggle verbose display (HEAD commit per repo/layer)
- `S` - build environment shell
- `a`/`d` - add/remove a layer in bblayers.conf
- `+`/`-` - track/hide a repo, `H` - show hidden repos, `A` - discover untracked layers
- `*` - show all layers in the repo
- `c` - open config menu
- `P` - pull patches from a remote project (browse remote commits, import)
- `l` - lore/b4 pending patches
- `w` - add a watch rule
- `X` - prune backup branches (with confirmation)
- `M` - open message log viewer (see [Status Messages](#status-messages))
- `q` - quit

Yocto-specific keybindings (explore mode, Yocto projects only):
- `i` - build info browser
- `Ctrl-R` - browse recipes (scoped to selected repo's layers, or single layer if expanded)
- `D` - layer dependencies, starting on the selected layer (or the repo's layer, when it has just one)
- `f` - browse configuration fragments

Keybindings in commit browser:
- `Enter` - actions for the commit (files, history, copy, lore, export, watch)
- `Tab` - mark commit for selection
- `Space` - select range of commits
- `?` - toggle preview pane
- `d` - toggle diff view in preview (stat ↔ full patch)
- `g` - toggle graph view in preview (git log --graph branch topology)
- `f` - switch to file/tree view (browse files, expand commit history per file)
- `c` - copy commit hash
- `e` - export selected commits
- `i` - interactive rebase (select range, then squash/reword/reorder)
- `D` - drop selected commits (a backup branch is kept)
- `S` - summarize selected commits with AI
- `t` - launch git history viewer
- `l` - browse commits grouped by layer (multi-layer repos)
- `p` - find patch source on lore.kernel.org
- `w` - watch for the commit landing upstream
- `A`/`F`/`U` - filter by author / since / until, `C` - clear filters
- `PgUp`/`PgDn` - scroll commit list
- `Alt-Up`/`Alt-Down` - scroll preview page
- `Alt-U`/`Alt-D` - scroll preview half-page
- `Shift-Up`/`Shift-Down` - scroll preview a line
- `F3`/`F4` or `Alt-←`/`Alt-→` - resize the preview
- `←`, `b`, `Esc` or `q` - back to the repo list

Keybindings in file/tree view (`f` from commit browser):
- `Enter`/`→` - expand directory or show file's commit history
- `←` - collapse directory/file or go to parent (at the top, back to the commit browser)
- `\` - toggle expand/collapse directory or file commits
- `d` - toggle diff/stat view in preview
- `a` - toggle blame view
- `f` - toggle raw file content view
- `p` - find the file or commit on lore.kernel.org
- `?` - toggle preview pane
- `b`/`Esc` - go back to commit browser
- `q` - quit

### Exporting Patches for Upstream

```bash
# Prepare commits (reorder for upstream)
bit changes prep --branch zedd/feature

# Export patches
bit changes export --target-dir ~/patches

# Export with version number
bit changes export --target-dir ~/patches -v 2
```

### Moving Changes Between Projects

A project's changes are its local commits, repo by repo. They can be sent
to another registered project, on this machine or on a build host, without
copying the project itself:

```bash
# What would be sent (default: the project you're in)
bit changes list

# Send them to another project; each repo gets an xfer/<host>/<branch> branch
bit changes send laptop-build

# Or pull them in from another project
bit changes fetch laptop-build

# Apply onto the checked-out branch instead, or just fetch the refs
bit changes send laptop-build --mode current
bit changes send laptop-build --mode fetch

# Leave repos out, or point one at a differently named repo
bit changes send laptop-build --exclude meta-virtualization
bit changes send laptop-build --map meta-mine=layers/meta-mine-v2

# See and remove what transfers left behind
bit changes received
bit changes clean
```

Every repo is checked before anything is applied: if one can't take its
changes (uncommitted work, or no matching repo in the target), nothing is
applied unless you pass `--partial`. Repos that already have the commits
are left alone. The web dashboard does the same from a project's row, or
by dragging one project's row onto another.

### Reviewing Commits

A review session is a set of commits read one after another, each in
full, with notes on each, the ones done ticked, and an AI conversation
about each commit (plus one about the series as a whole). The bit
server keeps them per project, so the web page (Reviews), bit tui
(Reviews) and the command line see the same ones.
Start one from commits marked in a repo's Commits view (📝 Review
session, `v`), from a series posted to a list (📝 Review, `R`, in Lore
or on a pending change: it's applied to a new `review/…` branch and the
review starts on its commits), or from a repo's commits that aren't
upstream:

```bash
bit review new meta-virtualization       # its commits not upstream
bit review step                          # one at a time: n / p, r ticks, e notes
bit review mail --open                   # the notes as replies, in mutt
```

Click a line of the diff to start a note on it. The notes become reply
mails: one for each commit with notes, threaded under the mail it was
posted as when the commit says where (b4's `Link:`), or one reply to the
whole series under its cover letter. A note that starts `file.c:12:`
goes under that line of the quoted diff (`file.c:-12:`, a line the
commit removes). Notes on lines can be kept in the notes box or shown
under their lines in the diff (Notes: side | inline).

For your own commits, a coding agent can do what the notes ask:
`bit review notes` prints the notes still to do as a task list (the
review's commits, then each commit's repo path, branch and commit and the
lines each note is about; `--commit N`, or the start of a sha, for one
commit's; `--brief` leaves out what to do, once the agent has it; `bit
review show --json` gives the commits as data),
and the agent ticks each off with `bit review done <review> <id> -m
"what it changed"`. A review keeps its history: when each note was made,
changed and marked done (with what was done about it), commits
rewritten, and from where (⏱ History on the page, `H` in bit tui,
`bit review history`). When a note isn't clear, the agent (or the
author) asks about it with `bit review reply <review> <id> -m "…"`: the
note stays to do, the question shows under it and in 💬 Replies (`R`),
with the review marked as waiting for your answer, and your answer is
under the note the next time the notes are read. Rewording a note keeps
its replies and done mark, and its old id still names it. Someone else
at the page (or a bit tui) on the same server says who they are: You're
Reviewer | Author and a name in the review's header (`o` and `N` in bit
tui's Replies; `--name` for `bit review reply`). As the author, every
note can be asked about. Each browser or bit tui remembers its own; it's
a label, not a sign-in.
⧉ For an agent on the page (`C` in bit tui) shows the same list to copy,
and the command an agent on another computer runs to get it from this
bit server (`bit review --server http://<address>:<port> -p <project>
notes <review>`; the first time, it asks for the token `bit serve token`
shows). When the agent amends or rebases the commits, the review finds
them again when it reads the notes, marks one done, or the review is
opened, once they're back in the checkout the review was made from. Edit commit changes the commit itself
(its message, or files as they are at it): the commits after it are
carried along, and a backup branch keeps the branch as it was.

When you're done with a review, ✓ Finish (`F`; `bit review finish`)
keeps it for reference: it moves under Finished at the bottom of the
list, with its notes, replies, history and AI conversations, and can be
reopened. Finishing offers to delete the branches the review made: Edit
commit's backups (ticked), and a series' own branch from Lore (not
ticked: its commits are only there, and once it's deleted git can prune
them; when it's checked out, the branch it was made from is checked out
first). `bit review finish --delete-branches` deletes both. A finished
review isn't looked at for rewritten commits any more.

### Searching for Layers

```bash
# Interactive search
bit layer-index

# Search with query
bit layer-index virtualization

# Get layer info for scripting
bit layer-index -i meta-virtualization

# Clone a layer directly
bit layer-index -c meta-security -b scarthgap
```

### Managing Branches

```bash
# Interactive branch management
bit branch

# Each repo's current branch, or one repo's local branches
bit branch list
bit branch list meta-oe

# Switch one repo, or all repos, to a release branch
bit branch switch meta-oe scarthgap
bit branch switch --all scarthgap

# Delete local branches (--force for unmerged ones)
bit branch delete meta-oe old-topic

# Delete the backup branches bit makes before rewriting a branch
bit branch prune-backups            # lists them and asks first
bit branch prune-backups --older-than 30 --yes
```

The older short forms still work: `bit branch meta-oe` lists,
`bit branch meta-oe scarthgap` and `bit branch --all scarthgap` switch.

Keybindings in branch management (`bit branch`):
- `→` - expand repo to show branches; on a branch, switch to it
- `Enter` - expand/collapse a repo; on a branch, switch to it
- `←` - collapse
- `B` - switch all repos to a branch (common branches first, partial dimmed)
- `D` - delete branches in the repo (pick several)
- `q` - quit

### Viewing Build Info

```bash
# Show build configuration (like BitBake summary)
bit info

# Show only layer info with branch:commit
bit info layers

# Show only key variables
bit info vars
```

Output format matches BitBake's build configuration:
```
Build Configuration:
  MACHINE = qemuarm64
  DISTRO  = poky

Layers:
  meta                = "master:01a65e8d5f73..."
  meta-selftest
  meta-poky           = "master:de4abc0a175a..."
```

The `info` entry is also available in the explore repo list menu for interactive browsing.

### Managing Multiple Projects

```bash
# Open project manager (interactive)
bit projects

# Add a project directory
bit projects add /path/to/yocto-build

# List known projects
bit projects list

# Remove a project from tracking
bit projects remove /path/to/old-project
```

Keybindings in projects menu:
- `Space` - activate selected project (all commands will operate on it); again to deactivate
- `→` - expand project; on an already-expanded project, runs the default command (default: explore)
- `Enter` - expand/collapse project
- `←` - collapse; `\` - fold project or host group
- `?`/`m` - open commands menu
- `+` - add projects: this directory, a path, browse, a remote (SSH), or sync from a remote
- `-` - remove selected project from tracking
- `n` - rename project
- `u` - update repos in project
- `x` - explore repos in project
- `t` - send or bring over changes (see [Moving Changes Between Projects](#moving-changes-between-projects))
- `r`/`R` - refresh project status
- `c` - the project's config menu (bit's own settings are under "Configure...")
- `S` - open shell in project
- `h` - SSH hosts
- `w` - start, check or stop the web server
- `v` - toggle verbose display
- `/` or `Ctrl-S` - search and filter, `Ctrl-R` - reset
- `P` - pick a pane, `Tab`/`Ctrl-P` - cycle panes
- `M` - open message log viewer (see [Status Messages](#status-messages))
- `q` - quit

Note: When no valid project context exists (no bblayers.conf found), the projects picker is automatically shown. Persona is auto-detected when adding projects (Yocto projects detected by bblayers.conf, layer.conf files, or poky directory; generic projects detected by .git directories without Yocto markers).

### Web Dashboard

```bash
# Start the server (web dashboard + auto-update daemon)
bit serve

# Custom port and host
bit serve --port 9000 --host 0.0.0.0

# Don't open browser (e.g. for remote servers)
bit serve --no-browser

# Control the server
bit serve stop          # stop the running server
bit serve restart       # restart
bit serve status        # auto-update daemon health
bit serve pause/resume  # pause/resume auto-updates
bit serve interval 30   # set update interval (minutes)
bit serve token         # the token other computers give
```

From another computer (a server started with `--host 0.0.0.0`) the
server asks for its token, which `bit serve token` shows; a browser asks
once and keeps it. On the server's own computer, at `localhost` or
`127.0.0.1`, none is needed. Web pages from other sites are always
refused.

bit tui can use a server on another computer the same way:
`bit tui --server http://build4:8123`. It asks for that server's token
the first time and keeps it (in `~/.config/bit/servers.json`, readable
only by you); its terminals then run on the server's computer, as the
web page's do. Over HTTPS, when this computer doesn't trust the
certificate authority that signed the server's certificate (the one
made on its computer when HTTPS was set up), bit offers to trust it for
that server only: it shows the authority's fingerprint and asks for the
one `bit serve token` shows on the server's computer (paste it, and bit
checks they're the same), or `y` once you've compared them. That's the
fingerprint, not the token, which it asks for after. `bit review --server` and `bit terminals --server` do
the same.

`bit terminals` lists and opens the tmux sessions the page's and bit
tui's terminals use, and ends them:

```bash
bit terminals                       # bit's sessions here (--all: every one)
bit terminals list --host build4    # a host's
bit terminals open [project]        # a project's shell (the active one by default)
bit terminals open --session work --host build4
bit terminals kill bit-poky         # asks first; -y doesn't
bit terminals killall
bit terminals --server http://build4:8123 open poky   # on that server's computer
```

`bit serve` starts a web dashboard and auto-update daemon. Projects tagged with `auto-update` are periodically fetched and updated. The server can also be launched from the TUI dashboard. `bit daemon` is an alias for `bit serve`.

The page has a project view in the centre and a pullout on the right for
details (a commit, a recipe, a host, settings). Any pullout can be promoted
to the centre.

**Views:**
- **Dashboard** — every project, grouped by host, with branch, local commits, upstream status and actions; tags, filters, and a card or list layout
- **Repos** — the project's repos and layers: commits, upstream history, branches, update, a terminal per repo
- **Recipes** — search recipes across layers; parsed and resolved variables (with `bitbake` when you ask), dependencies, and a colourized editor
- **Fragments** — enable and disable OE configuration fragments
- **Dependencies** — layer and recipe dependencies
- **Pending** — GitHub pull requests and mailing-list patches that haven't landed
- **Patches** — `.patch` files across layers, with their Upstream-Status
- **B4 / Lore** — search lore.kernel.org, then apply, diff or save a series
- **Export** — patches with cover letters for upstream
- **Layer Index** — search the OpenEmbedded Layer Index and add layers to a project
- **Configs** — browse and clone `.conf.json` build configurations, locally or on a host
- **Terminals** — tabbed tmux terminals, local or remote, shared with the TUI

**Across projects and hosts:**
- Remote projects over SSH work like local ones; bit deploys itself on the far side when needed
- Send a project's changes to another project, or copy a whole project to another host (layers, local commits and config, laid out as a current Yocto project even when the source is an older poky tree)
- Host metrics, update status and notifications for each host

**Drag and drop:**
- A project onto another sends its changes there; onto a host's heading, copies the project to that host
- Commits, Lore series and Layer Index layers onto a project
- A `.patch` or mbox file from the desktop onto a repo (`git am`), or a `.conf.json` onto Configs
- Configs onto a host, tags onto projects, terminal tabs back to their row

Keyboard navigation works throughout (`?` lists the keys), and themes,
fonts and layout are in Settings. The previous web UI is still served at
`/index.html` for now.

## Configuration

Per-repo settings are stored in `.bit.defaults` (JSON):

```json
{
  "/path/to/poky": "rebase",
  "/path/to/meta-oe": "skip",
  "__extra_repos__": ["/path/to/bitbake"],
  "__hidden_repos__": ["/path/to/unwanted-repo"],
  "__push_targets__": {
    "/path/to/oe-core": {
      "push_url": "ssh://git@push.openembedded.org/oe-core-contrib",
      "branch_prefix": "yourname/"
    }
  },
  "fzf_theme": "dark",
  "fzf_text_color": "light-gray",
  "fzf_custom_colors": {"pointer": "green"}
}
```

Configure interactively with `bit config`.

### Theme Customization

The tool supports customizable options via Settings menu (`bit config` -> Settings):

**Colors** submenu:
- **Mode** - Color source: global (`~/.config/bit/colors.json`), per-project (`.bit.defaults`), or built-in defaults
- **Theme** - Base color scheme (default, dark, light, dracula, nord, etc.)
- **Individual** - Per-element color overrides with live preview

New projects default to **global** mode — changing colors in any project updates `~/.config/bit/colors.json`, shared by all projects in global mode. Switch to **custom** for per-project overrides.

A color preview panel shows all themed elements (pointer, header, prompt, etc.) with current colors applied.

**Directory Browser** - Choose preferred file browser for project selection:
- broot (recommended)
- ranger
- nnn
- fzf (fallback)

**Git Viewer** - Choose preferred git history viewer:
- auto (detect first available: tig > lazygit > gitui > gitk)
- tig - ncurses git interface
- lazygit - terminal UI for git
- gitui - blazing fast terminal git UI (Rust)
- gitk - graphical git browser

**Preview Layout** - Configure commit browser preview pane position:
- Bottom (default) - preview below commit list
- Right (side-by-side) - preview beside commit list
- Top - preview above commit list

**Default Action** - Configure what Enter/→ does on expanded projects:
- Explore (default), Shell, Recipes, Update, Config

**Backup Prune Age** - Auto-prune old backup branches on commit browser entry:
- Always (0), 1/3/7/14/30 days, or Never (default: 7 days)
- Backup branches (`*-backup-YYYYMMDD-HHMMSS`) are created by the drop commits feature

**Editor** - Preferred text editor for config file editing:
- auto (default - uses `$EDITOR` / `$VISUAL` / vi), vim, nvim, nano, emacs, code (VS Code)

**NNN Colors** - Color scheme for the nnn file manager integration:
- Preset schemes: cyan dirs (default), green dirs, yellow dirs, magenta dirs, etc.

**Tmux Prefix** - Prefix key for remote tmux sessions:
- Ctrl-A (screen-style, default), Ctrl-B (tmux default), Ctrl-S, Ctrl-Q

**Web Autostart** - Auto-start web server when dashboard opens:
- Off (default), Localhost (127.0.0.1), All interfaces (0.0.0.0)

**Web Open Browser** - Open browser tab when web server starts:
- On or Off (default: off)

**Metrics Refresh** - Auto-refresh interval for host metrics on the dashboard:
- Off, 1 min, 2 min, 5 min, 10 min

**Graph Renderer** - Renderer for dependency graph visualization:
- Auto-detect (default - Graph::Easy if installed, else ASCII), Graph::Easy, ASCII

**Explore Load Size** - Number of commits to load per page in the commit browser:
- 50, 100, 200 (default), 500, 1000

**Terminal Colors** - Configure output colors for:
- Upstream indicator (commits to pull)
- Local commit count
- Dirty/clean status
- Repo names (configured, discovered, external)

## Visual Indicators

Repos are color-coded by source:
- **Green** - from bblayers.conf
- **Magenta** with `(?)` - discovered layers (not in bblayers.conf)
- **Cyan** with `(ext)` - external repos (git repos without conf/layer.conf)

Status indicators:
- `5 local` - commits ahead of upstream tracking ref
- `↓ 3` - commits to pull from upstream
- `→ contrib` - tracking a non-origin remote (shown when not tracking origin)
- `[clean]` / `[DIRTY]` - working tree status

### Status Messages

Actions like activating a project, refreshing repos, or running updates produce
status messages (e.g. `✓ Activated: poky`, `Refreshing OE-core... done`). These
are captured silently — they never print to the terminal — and are available in
two ways:

- **Header indicator**: The most recent message appears above the keybinding
  help for one fzf iteration, then disappears on the next redraw.
- **Message log** (`M` key): Opens a scrollable popup showing all messages from
  the current session with timestamps (newest first). Available in both the
  dashboard and explore menus.

### Remote SSH Projects

Remote projects on SSH-accessible build machines can be managed alongside local
ones:

- Add via manage menu (`+` → Remote SSH) with `user@host:/path` URI format
- Dashboard shows remote projects with `⇄ hostname` indicator
- Remote summary (branch, dirty, ahead/behind) gathered via single batched SSH call
- Actions dispatch to remote bit (auto-deployed if not installed) with fallback to raw git
- SSH connection multiplexing (`ControlMaster=auto`, `ControlPersist=600`) avoids repeated auth
- All SSH calls suppress askpass prompts (`SSH_ASKPASS_REQUIRE=never`, `BatchMode=yes`) to
  prevent password dialogs from interfering with the TUI
- Interactive SSH sessions (explore, shell) are preceded by a connection pre-check;
  if auth fails, a clean error message is shown instead of hanging
- **Pull patches** (`P` key in explore repos view): browse commits on a remote build machine and import them
  - Automatically finds matching repo on remote by basename
  - Commit browser shows provenance tags: `[build4]` (remote-only), `[upstream][build4]` (shared upstream), `[upstream][build4][local]` (shared base)
  - Mark commits with Tab/Space, press `e` to export
  - `t` launches history viewer on local repo, `g` toggles remote graph in preview
  - Import methods: apply patches (git am), fetch branch (git fetch), or save .patch files

## Requirements

- Python 3.9+
- Git
- fzf (optional, but recommended for interactive features)
- argcomplete (optional, for tab completion)
- xclip or xsel (optional, for clipboard support)

## Development

### Installation for Development

```bash
# Clone the repository
git clone https://gitlab.com/bruce-ashfield/bitp.git
cd bitp

# Create a virtual environment
python3 -m venv .venv
source .venv/bin/activate

# Install with dev dependencies
pip install -e .[dev]
```

### Running Tests

The project uses pytest with pytest-mock and pytest-cov:

```bash
# Activate virtual environment first
source .venv/bin/activate

# Run all tests
pytest tests/ -v

# Run with coverage report
pytest tests/ --cov=bitbake_project --cov-report=term-missing

# Run only unit tests
pytest tests/unit/ -v

# Run only integration tests
pytest tests/integration/ -v

# Run tests matching a pattern
pytest tests/ -k "test_colors" -v
```

### Test Structure

Unit tests are in `tests/unit/`, tests that run the `bit` command end to
end in `tests/integration/`, and shared fixtures in `tests/conftest.py`.

## Project Structure

The project is organized as a Python package with a commands subpackage:

```
bitbake_project/
├── cli.py            # Argument parsing and main()
├── core.py           # Core abstractions (Colors, GitRepo, FzfMenu)
├── daemon.py         # Auto-update daemon
├── projects_store.py # Registered projects (~/.config/bit/projects.json)
├── personas/         # Yocto and generic project behaviour
├── tui/              # fzf and Textual menus, inline dialogs
├── commands/         # One module per command
│   ├── changes.py    # changes: collect, check and apply changesets
│   ├── setup.py      # setup: clone, apply, export, configs, project copy
│   ├── query.py      # JSON queries, run on the far side for remote projects
│   ├── ssh_remote.py # SSH transport for remote projects
│   └── ...           # repos, branch, explore, b4, recipes, deps, ...
└── web/              # Browser dashboard (stdlib http.server)
    ├── server.py     # HTTP server with WebSocket upgrade
    ├── api.py        # REST API
    ├── terminal.py   # PTY-to-WebSocket bridge (tmux sessions)
    └── static/       # The page (preview.html) and the previous UI
```

Distribution options:
- **Standalone**: Single-file zipapp (`dist/bit`)
- **Pip install**: `pip install -e .` for development

## License

This project is licensed under the GNU General Public License v2.0 (GPL-2.0-only).

See [COPYING](https://gitlab.com/bruce-ashfield/bitp/-/blob/main/COPYING) for the full license text.

## See Also

- [INSTALL.md](https://gitlab.com/bruce-ashfield/bitp/-/blob/main/INSTALL.md) - Installation instructions
- [Yocto Project](https://www.yoctoproject.org/)
- [OpenEmbedded](https://www.openembedded.org/)
- [OpenEmbedded Layer Index](https://layers.openembedded.org/)
