# XBP
XBP (XYLEX Build Pack) is a deployment and operations CLI for single-service and multi-service projects.
It combines build/run workflows, PM2 process management, diagnostics, nginx helpers, secrets workflows, and project version synchronization in one tool.
## Features
- `monitoring`
- `docker`
- `kubernetes` [exp]
- `kafka` [exp]
- `pm2` [wip]
current version: `10.26.3`
## Repository Layout
- `crates/api`: standalone control-plane API runtime (`xbp_api`)
- `crates/athena`: Athena-backed control-plane repository layer (`xbp_athena`)
- `crates/cli`: CLI crate (`xbp_cli`) and binary entrypoint (`xbp`)
- `crates/core`: shared control-plane domain types (`xbp_core`)
- `crates/monitor`: internal monitoring crate (`xbp_monitor`)
- `crates/logs`: internal log streaming crate (`xbp_logs`)
- `apps/web`: frontend app placeholder scaffold
## TL;DR (30-Second Start)
```bash
# 1) Install
cargo install xbp
# Debian/Ubuntu (after adding XBP apt source)
sudo apt install xbp
# 2) Check project/runtime state
xbp ports
xbp services
# 3) Run and inspect
xbp service build api
xbp service start api
xbp logs api
xbp ssh --host prod.example.com --username deploy
# 4) Keep versions aligned
xbp version
xbp version patch
```
## Why XBP
- One CLI for local service workflows and server-side operations.
- Supports Rust, Node.js, Next.js, Python, Express, and mixed repos.
- Handles PM2 lifecycle, logs, snapshots, and environment inspection.
- Includes version reconciliation across common manifest files and git tags.
- Adds operational helpers for ports, nginx, diagnostics, and secrets.
## Feature Overview
- Project and service orchestration: `services`, `service`, `redeploy`, `setup`.
- Process/runtime control: `list`, `start`, `stop`, `flush`, `snapshot`, `resurrect`, `env`, `logs`, `tail`.
- Remote operator access: `ssh` for interactive SSH sessions and `cloudflared tcp` for standalone Access forwarders.
- Network and infra helpers: `ports`, `nginx`, `diag`, `curl`.
- Configuration and security: `config`, `secrets`.
- Version workflows: `version` report, bump, explicit set, git-tag view.
- Optional monitoring command family (feature-gated build).
- Optional Kubernetes helper (feature-gated): `xbp kubernetes ...` for manifest generation, apply, readiness checks, and cert-manager issuer bootstrap. Build with `--features kubernetes`.
- Optional Docker helper (feature-gated): `xbp -l` / `xbp list` shows `docker ps` snapshot when built with `--features docker`.
- Optional systemd helper (feature-gated): `xbp -l` / `xbp list` also shows configured `systemctl status` output when built with `--features systemd`.
## Installation
### Option 1: Build From Source
```bash
git clone https://github.com/xylex-group/xbp.git
cd xbp
cargo build --release
./target/release/xbp --help
```
### Option 2: Install From Cargo
```bash
cargo install xbp
```
### Option 3: Install From APT (Debian/Ubuntu)
```bash
# Recommended (signed repository)
curl -fsSL https://xylex-group.github.io/xbp/xbp-archive-keyring.asc \
| gpg --dearmor \
| sudo tee /usr/share/keyrings/xbp-archive-keyring.gpg > /dev/null
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/xbp-archive-keyring.gpg] https://xylex-group.github.io/xbp stable main" \
| sudo tee /etc/apt/sources.list.d/xbp.list > /dev/null
sudo apt update
sudo apt install xbp
```
```bash
# Fallback when repository signing is not configured yet
echo "deb [trusted=yes arch=amd64] https://xylex-group.github.io/xbp stable main" \
| sudo tee /etc/apt/sources.list.d/xbp.list > /dev/null
sudo apt update
sudo apt install xbp
```
### Windows note (Kafka feature)
- Standard install works on Windows:
```bash
cargo install xbp
```
- Kafka-enabled builds are currently Linux/WSL2-oriented because `rdkafka-sys` may require Unix tooling.
- On Windows, do not enable `kafka` during Cargo install/build.
- If you hit an `rdkafka-sys` error mentioning `cp -a` / `program not found`, rebuild without `kafka`:
```bash
cargo install xbp --no-default-features
```
or use WSL2/Linux for Kafka-enabled builds.
### Linux note (low `/tmp` quota)
If `cargo install xbp` fails with a `Disk quota exceeded` error under `/tmp`, direct Cargo's temp and target output into your home directory instead:
```bash
mkdir -p "$HOME/.cargo-tmp" "$HOME/.cargo-target"
TMPDIR="$HOME/.cargo-tmp" CARGO_TARGET_DIR="$HOME/.cargo-target" cargo install xbp
```
### Verify Installation
```bash
xbp --version
xbp --help
```
## Quick Start
```bash
# Discover project/runtime state
xbp ports
xbp services
# Build or run a service from xbp config
xbp service build api
xbp service start api
# Deploy flow shortcut
xbp redeploy api
# PM2 snapshots for recovery
xbp snapshot
xbp resurrect
# Interactive remote SSH shell
xbp ssh --host prod.example.com --username deploy
# Standalone Access forwarder
xbp cloudflared tcp --hostname bastion.example.com --listener 127.0.0.1:2222
# Persist a Hetzner dedicated-server vSwitch VLAN config
xbp network hetzner vswitch setup --ip 10.0.3.2 --vlan-id 4000 --interface enp0s31f6 --apply
# Version report across manifests and tags
xbp version
```
## Configuration
XBP resolves project config in this order:
1. `.xbp/xbp.yaml`
2. `.xbp/xbp.yml`
3. `.xbp/xbp.json`
4. `xbp.yaml`
5. `xbp.yml`
6. `xbp.json`
Both YAML and JSON are supported. If no explicit project version is set, default is `0.1.0`.
Use `xbp generate config` to generate or refresh `.xbp/xbp.yaml`, and
`xbp generate config --from-json .xbp/xbp.json` to convert legacy JSON configs.
### Minimal YAML
```yaml
project_name: my-app
version: 0.1.0
port: 3000
build_dir: /path/to/project
```
### Multi-Service Example
```yaml
project_name: my-stack
version: 0.1.0
port: 3000
build_dir: /srv/my-stack
services:
- name: api
target: rust
branch: main
port: 3000
root_directory: apps/api
url: https://api.example.com
commands:
install: cargo fetch
build: cargo build --release
start: ./target/release/api
- name: web
target: nextjs
branch: main
port: 3001
root_directory: apps/web
commands:
install: pnpm install
build: pnpm run build
start: pnpm run start
```
### Core Fields
- `project_name`: logical project name.
- `version`: semantic version string for project-level versioning.
- `port`: primary project port.
- `build_dir`: absolute path to project root.
- `services`: optional service list.
- `environment`: optional environment variables.
### Service Fields
- `name`: service identifier.
- `target`: `rust`, `nextjs`, `nodejs`, `python`, or `expressjs`.
- `branch`: deploy branch.
- `port`: service port.
- `root_directory`: optional service-specific working directory.
- `url`: optional public URL.
- `healthcheck_path`: optional health route.
- `commands`: optional `pre`, `install`, `build`, `start`, `dev` commands.
## Command Cookbook
### Project and Service Commands
- `xbp services`: list services from config.
- `xbp service build <name>`: run service build command.
- `xbp service install <name>`: run service install command.
- `xbp service start <name>`: run service start command.
- `xbp service dev <name>`: run service dev command.
- `xbp redeploy <name>`: redeploy one service.
### Runtime and Operations
- `xbp list`: PM2 process list.
- `xbp logs [project]`: view PM2 logs.
- `xbp logs --ssh-host <host> --ssh-username <user> --ssh-password <pw>`: remote logs.
- `xbp ports`: active listening ports.
- `xbp ports --kill --port 3000`: kill process(es) on a port.
- `xbp ports --nginx`: include nginx mapping view.
- `xbp ports --full`: include reconciled XBP project port data.
- `xbp diag`: run environment diagnostics.
- `xbp ports --exposure`: diagnose service bind + firewall exposure per port.
- `xbp nginx setup --domain <domain> --port <port> --email <email>`: provision HTTPS reverse proxy with Certbot.
- `xbp nginx list`: list discovered nginx sites.
- `xbp nginx show <domain>`: show nginx config.
- `xbp nginx update --domain <domain> --port <port>`: update upstream port.
- `xbp network floating-ip add --ip <IP>`: write persistent floating IP config on detected backend.
- `xbp network floating-ip add --ip <IP> --apply`: write and apply/reload network config.
- `xbp network floating-ip list`: list floating IPs from runtime + config.
- `xbp network config list`: list discovered network config files and backend detection.
- `xbp curl <url-or-domain>`: quick endpoint health/content check.
- `xbp kubernetes addons list`: show full MicroK8s addon status (enabled/disabled).
- `xbp kubernetes addons enable <name>`: enable a MicroK8s addon.
- `xbp kubernetes addons disable <name>`: disable a MicroK8s addon.
- `xbp kubernetes dashboard-token`: extract the dashboard JWT token from `describe secret`.
- `xbp kubernetes observability-creds`: print decoded Grafana admin credentials from observability secret.
- `xbp kubernetes issuer --email <email>`: create/update a cert-manager Let's Encrypt issuer (feature-gated build).
### PM2 Shortcuts
- `xbp snapshot`: save PM2 process snapshot.
- `xbp resurrect`: restore PM2 state.
- `xbp stop <target>`: stop one process or all.
- `xbp flush [target]`: flush logs globally or for a process.
- `xbp monitor check`: one-shot monitor check.
- `xbp monitor start`: monitor daemon.
- `xbp env <pm2-name-or-id>`: show PM2 env.
### Config, Setup, and Secrets
- `xbp setup`: guided local setup helpers.
- `xbp generate config`: generate `.xbp/xbp.yaml` from project detection.
- `xbp generate config --update`: refresh missing defaults in `.xbp/xbp.yaml`.
- `xbp generate config --from-json <PATH>`: convert legacy `xbp.json` to `.xbp/xbp.yaml`.
- `xbp config`: show/open global XBP config paths.
- `xbp config --project`: show current project config.
- `xbp config openrouter set-key [KEY]`: store OpenRouter API key globally.
- `xbp config openrouter show [--raw]`: inspect stored OpenRouter key.
- `xbp config openrouter delete-key`: remove stored OpenRouter key.
- `xbp config github set-key [TOKEN]`: store GitHub OAuth2 token globally.
- `xbp config github show [--raw]`: inspect stored GitHub token.
- `xbp config github delete-key`: remove stored GitHub token.
- `xbp config linear set-key [TOKEN]`: store Linear API key globally for release-note issue linking and initiative publishing.
- `xbp config linear show [--raw]`: inspect stored Linear API key.
- `xbp config linear delete-key`: remove stored Linear API key.
- `xbp config linear select-initiative`: pick a repo-scoped Linear initiative and save its ID to `.xbp/xbp.yaml`.
- `xbp secrets list`: list required/local env keys.
- `xbp secrets push --file .env.local`: push env vars into the default `xbp-dev` GitHub Actions environment.
- `xbp secrets --environment xbp-preview pull --output .env.local`: pull env vars from an opt-in environment target.
- `xbp secrets verify`: validate required env key availability.
- `xbp secrets diag`: check GitHub repo access, standard environment setup, and token scope.
## Nginx HTTPS Setup
`xbp nginx setup` now covers the full native Certbot + Nginx wiring flow for both regular and wildcard domains.
```bash
# Standard domain (HTTP-01)
xbp nginx setup --domain api.example.com --port 3000 --email ops@example.com
# Wildcard domain with manual DNS-01 prompts
xbp nginx setup \
--domain '*.example.com' \
--port 3000 \
--email ops@example.com \
--dns-mode manual \
--include-base true
# Wildcard domain with DNS plugin automation
xbp nginx setup \
--domain '*.example.com' \
--port 3000 \
--email ops@example.com \
--dns-mode plugin \
--dns-plugin cloudflare \
--dns-creds /root/.secrets/certbot/cloudflare.ini
```
Setup behavior:
- Ensures `nginx` and `certbot` are installed.
- Ensures `/etc/letsencrypt/options-ssl-nginx.conf` and `/etc/letsencrypt/ssl-dhparams.pem` exist.
- Writes a temporary HTTP ACME config for regular domains, then final HTTPS config with redirect.
- Uses DNS-01 for wildcard domains (`manual` or `plugin` mode).
- Reuses existing certificates when present.
- Validates config with `nginx -t` and restarts nginx on success.
## Floating IP Persistence
XBP can persist Floating IP configuration for Linux hosts by auto-detecting the active backend in this order:
1. Netplan
2. NetworkManager keyfiles
3. ifupdown
4. RHEL ifcfg scripts
```bash
# Hetzner-style IPv4 floating IP persistence (write-only)
xbp network floating-ip add --ip 203.0.113.10
# IPv6 floating IP with explicit CIDR and apply
xbp network floating-ip add --ip 2a01:4f9:0:2a1::2 --cidr 64 --interface eth0 --apply
# Inspect persisted + runtime addresses
xbp network floating-ip list
xbp network config list
```
### Versioning
- `xbp commit`: analyze the current git worktree, generate a Conventional Commit message, stage the current worktree, and create the git commit.
- `xbp commit --dry-run`: preview the generated message and worktree summary without staging or committing.
- `xbp commit --no-ai`: skip OpenRouter and use deterministic local heuristics only.
- `xbp commit --scope <scope>`: force the conventional commit scope.
By default `xbp commit` also pushes the new commit after it is created. Set `github.auto_push_on_commit: false` in `.xbp/xbp.yaml` to keep the commit local.
- `xbp version`: full version report (manifests + tags + registry when configured).
- `xbp version --git`: show normalized git tag versions.
- `xbp version major`: bump major in tracked files.
- `xbp version minor`: bump minor in tracked files.
- `xbp version patch`: bump patch in tracked files.
- `xbp version <x.y.z>`: set tracked files to an explicit semver.
- `xbp version <package>=<x.y.z>`: update package assignment versions in tracked TOML files.
- When run from `crates/<crate>/...`, `xbp version` scopes manifest bumps to that crate and the matching workspace `Cargo.lock` entry instead of the whole repository.
- `xbp version release`: create/push `v<version>` git tag and publish GitHub release.
- `xbp version release --version <x.y.z>`: release an explicit version.
- `xbp version release --notes-file <PATH>`: use custom Markdown release notes.
When `openapi.yaml`, `openapi.yml`, or `openapi.json` exists at the repository root or the active `crates/<name>` root, XBP uploads it as a release asset.
When `linear.release.initiative_ids` is configured, XBP also posts the release into those Linear initiatives.
When run from `crates/<crate>/...`, release tags default to `<crate-package-name>-<version>` and release notes are generated from commits that touched that crate path.
Auto-generated release notes now default the release title to `<version> - <repo>`, render grouped sections with a short summary paragraph, list markdown-linked commit SHAs, add separate GitHub PR bullets and Linear issue bullets when those references are present, and finish with a linked `Release:` footer. When an OpenRouter key is configured, XBP asks it to collapse repetitive commits into user-facing grouped bullets; otherwise it falls back to deterministic topic grouping.
`xbp commit` uses the same OpenRouter configuration path when available. It analyzes the current worktree with file-level stats, symbol extraction, and diff context, then asks the configured model for a strict Conventional Commits JSON payload. If no OpenRouter key is configured or the model response is unusable, XBP falls back to local conventional-commit heuristics.
Project config can disable the automatic push step:
```yaml
github:
auto_push_on_commit: false
```
Linear initiative publishing can be configured either per repo in `.xbp/xbp.yaml` or globally in XBP's `config.yaml`:
```yaml
linear:
release:
initiative_ids:
- "3f1f0f6f-7e1f-4a6f-9f28-8f8a52d0e9d0"
health: on_track
```
Set `enabled: false` in a repo config to opt that repo out of globally configured initiative publishing. Supported health values are `on_track`, `at_risk`, and `off_track`.
To pick a repo initiative interactively from your accessible Linear initiatives and write it into `.xbp/xbp.yaml`, run:
```bash
xbp config linear select-initiative
```
## Version Management Details
`xbp version` resolves versions from configured files, local/remote git tags, and configured package registries.
It normalizes prefixed tags (`v1.2.3`) and plain semver (`1.2.3`) into one comparison space.
### Package Assignment Updates In TOML
`xbp version <package>=<x.y.z>` updates both forms in tracked TOML files:
- `<package> = "x.y.z"`
- `<package> = { version = "x.y.z", ... }`
Example:
```bash
xbp version tokio=1.45.1
```
### Default Tracked Version Files
- `README.md`
- `openapi.yaml`
- `openapi.yml`
- `openapi.json`
- `Cargo.toml`
- `Cargo.lock`
- `package.json`
- `package-lock.json`
- `pyproject.toml`
- `xbp.yaml`
- `xbp.json`
- `.xbp/xbp.yaml`
- `.xbp/xbp.json`
The registry is synchronized into global XBP config as `versioning-files.yaml`.
Missing defaults are re-added without removing custom entries.
## PM2 Behavior
XBP uses PM2 as an execution/runtime layer for many commands.
- Deploy and start flows can (re)start services under PM2.
- `snapshot` stores recoverable process state.
- `resurrect` first tries native PM2 restore, then falls back to latest XBP snapshot.
- `env` maps PM2 names to IDs and prints effective runtime environment.
## Ports and Diagnostics
- `xbp ports` reconciles active listeners with detected project and nginx metadata.
- `xbp diag` validates common system dependencies and service expectations.
## MCP Server
XBP includes an MCP stdio server at `scripts/xbp_mcp_server.py`.
It exposes tools for all current `xbp` commands and includes `xbp_raw` for raw arg passthrough.
### Run MCP Server
```bash
python3 scripts/xbp_mcp_server.py
```
### What It Returns
Each tool call returns:
- Executed command array.
- Working directory.
- Exit code.
- Captured stdout/stderr.
### Server Tests
```bash
python3 -m unittest scripts/test_xbp_mcp_server.py
```
## Repository Layout
- `src/main.rs`: binary entrypoint.
- `src/lib.rs`: library exports.
- `src/cli/`: clap command definitions and dispatch.
- `src/commands/`: command implementations.
- `src/strategies/`: deployment strategy and project detection.
- `src/sdk/`: PM2 and nginx integrations.
- `src/utils/`: shared helpers.
- `scripts/`: support scripts including MCP server.
- `docs/`: end-user docs, operator runbooks, and phased control-plane plans.
- `architecture/`: ADRs plus Mermaid/PlantUML design diagrams.
## Development
```bash
cargo fmt
cargo test
python3 -m unittest scripts/test_xbp_mcp_server.py
```
## Troubleshooting
- If `xbp` is not found, ensure Cargo bin path is on `PATH`.
- If PM2 commands fail, verify PM2 is installed and reachable in your shell env.
- If nginx commands fail, run with elevated permissions where required.
- If `xbp version` cannot update package assignments, confirm the target file is TOML and listed in versioning registry.
- If MCP command calls fail, confirm `xbp` is installed on the same environment where `xbp_mcp_server.py` is running.
## License
MIT