Command Registry¶
blq maintains a registry of named commands that can be executed with blq run. This provides consistent command execution across your project.
commands - List Registered Commands¶
Show all registered commands.
Options¶
| Option | Short | Description |
|---|---|---|
--json |
-j |
Output as JSON |
Output¶
Name Command Capture Description
--------------------------------------------------------------------------------
build make -j8 yes Build project
test pytest yes Run tests
lint ruff check . yes Check code style
format black . no Format code
register - Register a Command¶
Add a new command to the registry.
blq register build "make -j8"
blq register test pytest --description "Run unit tests"
blq register format "black ." --no-capture
Arguments¶
| Argument | Description |
|---|---|
name |
Command name (e.g., 'build', 'test') |
cmd |
Command to run (can be multiple words) |
Options¶
| Option | Short | Description |
|---|---|---|
--description TEXT |
-d |
Command description |
--timeout SECONDS |
-t |
Timeout in seconds (default: 300) |
--format FORMAT |
-f |
Log format hint for parsing |
--no-capture |
-N |
Don't capture logs by default |
--sandbox PRESET |
-S |
Sandbox preset (test, build, readonly, none) |
--force |
Overwrite existing command |
Examples¶
Basic registration:
With description:
With format hint:
No capture mode:
Update existing:
Capture Mode¶
By default, commands capture and parse output. Use --no-capture for commands where:
- Output parsing isn't useful (formatters, cleaners)
- Speed is critical
- You just want to run the command
At runtime, you can override with:
unregister - Remove a Command¶
Remove a command from the registry.
Example¶
Parameterized Commands¶
Instead of registering multiple variations of a command, use templates with {param} placeholders:
# Instead of:
blq register test-unit "pytest tests/unit/"
blq register test-integration "pytest tests/integration/"
blq register test-all "pytest tests/"
# Use a parameterized template:
# (edit .bird/commands.toml directly - see Storage below)
Template Syntax¶
In .bird/commands.toml, use tpl instead of cmd with {param} placeholders:
[commands.test]
tpl = "pytest {path} {flags}"
defaults = { path = "tests/", flags = "-v" }
description = "Run tests"
[commands.test-file]
tpl = "pytest {file} -v --tb=short"
description = "Test a single file"
# No defaults = 'file' is required
Running Parameterized Commands¶
# Use defaults
blq run test
# → pytest tests/ -v
# Override path
blq run test path=tests/unit/
# → pytest tests/unit/ -v
# Override both
blq run test path=tests/unit/ flags="-vvs -x"
# → pytest tests/unit/ -vvs -x
# Required parameter
blq run test-file file=tests/test_core.py
# → pytest tests/test_core.py -v --tb=short
# Extra args after ::
blq run test :: --capture=no
# → pytest tests/ -v --capture=no
Missing required parameters will show an error with valid parameter names.
Storage¶
Commands are stored in .bird/commands.toml:
[commands.build]
cmd = "make -j8"
description = "Build project"
timeout = 300
[commands.test]
tpl = "pytest {path} {flags}"
defaults = { path = "tests/", flags = "-v" }
description = "Run tests"
format = "pytest"
[commands.format]
cmd = "black ."
description = "Format code"
capture = false
Command Locks¶
Commands can share a named lock to prevent concurrent execution:
[commands.build]
cmd = "make -j8"
lock = "build"
[commands.test]
cmd = "pytest"
lock = "build" # Shares lock — can't run while build is running
[commands.lint]
cmd = "ruff check"
# No lock — runs concurrently with anything
When a lock is held, blq run fails immediately with a clear error. Use --no-lock to bypass or --wait-lock SECONDS to wait:
Stale locks (from crashed processes) are automatically reclaimed.
Sandbox Profiling¶
Discover what resources a command actually uses to inform sandbox spec creation:
This wraps the command in strace (2-10x overhead) and reports:
- Files read and written
- Network connections attempted
- Subprocesses spawned
- Suggested sandbox spec based on observed patterns
Use the output to create a data-driven sandbox spec:
blq sandbox profile test # discover access patterns
blq sandbox suggest test # combine with resource metrics
Requires strace to be installed (sudo apt install strace).
You can edit this file directly for bulk changes or to add parameterized commands.
Auto-Detection¶
Use blq init --detect to auto-register commands based on your project's build files:
blq init --detect --yes # Auto-confirm all detected commands
blq init --detect # Interactive confirmation
See init command for detection modes and supported build systems.
Use Cases¶
Project Setup¶
# Initialize with auto-detected commands
blq init --detect --yes
# Add project-specific commands
blq register integration-test "pytest tests/integration" -d "Integration tests"
blq register deploy "./scripts/deploy.sh" --no-capture
Team Standardization¶
Share .bird/commands.toml in version control:
# Team member clones repo
git clone https://github.com/team/project
cd project
blq init # Commands already configured
# Everyone uses the same commands
blq run build
blq run test
CI Integration¶
# .github/workflows/ci.yml
jobs:
build:
steps:
- uses: actions/checkout@v4
- run: pip install blq-cli
- run: blq init
- run: blq run build
- run: blq run test
Multiple Build Configurations¶
Using separate commands:
blq register build-debug "make DEBUG=1"
blq register build-release "make RELEASE=1"
blq register build-sanitize "make SANITIZE=1"
blq run build-debug
blq run build-release
Or using a parameterized template (in .bird/commands.toml):
[commands.build]
tpl = "make {flags}"
defaults = { flags = "" }
description = "Build with optional flags"
Best Practices¶
- Descriptive names: Use clear, action-oriented names
- Add descriptions: Help team members understand each command
- Set appropriate timeouts: Increase for long builds
- Use format hints: When auto-detection struggles
- Skip capture for speed: Use
--no-capturefor formatters and cleaners - Version control: Commit
.bird/commands.tomlfor team consistency - Use templates: Avoid duplicate commands - use
tplwith{param}placeholders