bmo

bmo is a local-first command-line issue tracker backed by a single SQLite file, designed for use by both human developers and AI agents operating in a terminal. It requires no server, no network dependency, and no external services. Issues are identified by BMO-N IDs.
Attribution
bmo was inspired by and adapted from docket, an issue tracker for AI agents written by ALT-F4-LLC. The design, data model, and command structure of BMO all owe a direct debt to that project, and all credit for the underlying ideas belongs there.
In addition, the code in this repository was written by Claude Code, Anthropic's AI coding assistant. The repo owner directed this work.
Installation
From crates.io (recommended):
From source:
Pre-built binaries:
Download the latest binary for your platform from GitHub Releases.
Quickstart
Commands
Global Flags
These flags are accepted by every command.
| Flag | Type | Default | Description |
|---|---|---|---|
--json |
bool | false | Output results as JSON |
--db <PATH> |
string | auto | Override database path (also reads BMO_DB env var) |
Issue Management
bmo issue create
Create a new issue.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--title |
-t |
string | required | Issue title |
--description |
-d |
string | "" |
Issue description |
--status |
-s |
string | backlog |
Initial status |
--priority |
-p |
string | medium |
Priority level |
--kind |
-T |
string | task |
Issue kind |
--assignee |
-a |
string | none | Assignee name |
--parent |
string | none | Parent issue ID | |
--label |
-l |
string | none | Label name (repeatable) |
--file |
-f |
string | none | File path to attach (repeatable) |
bmo issue list
List issues with optional filters.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--status |
-s |
string | none | Filter by status (repeatable) |
--priority |
-p |
string | none | Filter by priority (repeatable) |
--kind |
-T |
string | none | Filter by kind (repeatable) |
--assignee |
-a |
string | none | Filter by assignee |
--label |
-l |
string | none | Filter by label, AND semantics (repeatable) |
--parent |
string | none | Filter by parent ID | |
--search |
string | none | Search in title and description | |
--limit |
integer | 50 |
Maximum number of results | |
--sort |
string | none | Sort field | |
--all |
bool | false | Include done issues |
bmo issue show
Show full detail for a single issue.
bmo issue edit
Edit issue fields. Only supplied flags are updated.
| Flag | Short | Type | Description |
|---|---|---|---|
--title |
-t |
string | New title |
--description |
-d |
string | New description |
--status |
-s |
string | New status |
--priority |
-p |
string | New priority |
--kind |
-T |
string | New kind |
--assignee |
-a |
string | New assignee |
--parent |
string | New parent issue ID |
bmo issue move
Change the status of an issue.
| Flag | Short | Type | Description |
|---|---|---|---|
--status |
-s |
string | New status value |
bmo issue close
Close an issue by setting its status to done.
bmo issue reopen
Reopen a closed issue.
bmo issue delete
Delete an issue permanently.
| Flag | Type | Description |
|---|---|---|
--yes |
bool | Skip confirmation prompt |
bmo issue comment add
Add a comment to an issue.
| Flag | Short | Type | Description |
|---|---|---|---|
--body |
-b |
string | Comment text |
--author |
-a |
string | Comment author name |
bmo issue comment list
List all comments on an issue.
bmo issue label add
Add a label to an issue. Creates the label if it does not exist.
| Flag | Type | Description |
|---|---|---|
--color |
string | Label color as a hex string (e.g. #ff0000) |
bmo issue label rm
Remove a label from an issue. Accepts rm or remove.
bmo issue label list
List all labels attached to an issue.
bmo issue label delete
Delete a label globally, removing it from all issues.
bmo issue link add
Add a directional relation between two issues.
Valid relation values: blocks, blocked-by, depends-on, dependency-of, relates-to, duplicates, duplicate-of.
bmo issue link remove
Remove a relation by its numeric relation ID.
bmo issue link list
List all relations for an issue.
bmo issue file add
Attach a file path to an issue.
bmo issue file rm
Remove a file attachment from an issue. Accepts rm or remove.
bmo issue file list
List all file attachments for an issue.
bmo issue log
Show the activity log for an issue.
| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
integer | 10 |
Maximum number of log entries to show |
bmo issue graph
Show the dependency graph for an issue.
Issue IDs accept both 42 and BMO-42 everywhere.
Board and Planning
bmo board
Show a Kanban board of all issues grouped by status.
| Flag | Short | Type | Description |
|---|---|---|---|
--label |
-l |
string | Filter by label (repeatable) |
--priority |
-p |
string | Filter by priority (repeatable) |
--assignee |
-a |
string | Filter by assignee |
bmo next
Show the next work-ready issues. An issue is work-ready when it has no unresolved blocking dependencies.
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--assignee |
-a |
string | none | Filter by assignee |
--limit |
integer | 10 |
Maximum number of results |
bmo plan
Show a phased execution plan ordered by dependency relationships.
| Flag | Short | Type | Description |
|---|---|---|---|
--assignee |
-a |
string | Filter by assignee |
Statistics and Export
bmo stats
Show issue counts grouped by status, priority, and kind.
bmo export
Export all issues, comments, labels, relations, activity, and file attachments as a JSON bundle.
bmo export [--output <file>]
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--output |
-o |
string | stdout | Output file path |
bmo import
Import a JSON export bundle. Use --from-docket when importing from a docket export.
bmo import <file> [--from-docket]
| Flag | Type | Description |
|---|---|---|
--from-docket |
bool | Remap DKT- IDs to BMO- IDs during import |
Web Interface
bmo web
bmo web starts a local HTTP server at http://127.0.0.1:7777 by default and opens a browser window automatically. The web interface provides a read-friendly view of all issues, their statuses, comments, labels, and relationships.
To start without opening a browser:
To bind to a different port:
The bmo server will use server-sent-events to update the web view.
BMO Basics
bmo init
Initialize a new bmo project in the current directory. Creates .bmo/issues.db and .bmo/config.toml. Safe to run on an existing project; it is idempotent.
| Flag | Type | Description |
|---|---|---|
--name |
string | Project name written to config |
bmo config
Project-level settings will be stored in the file .bmo/config.toml:
= "my-project"
= "me"
= 7777
= "127.0.0.1"
Read and write these values with the command bmo config:
With no flags, bmo config prints all current values.
Valid keys are: project_name, default_assignee, web_port, web_host.
| Flag | Type | Description |
|---|---|---|
--get <key> |
string | Print the value of a single key |
--set <key>=<value> |
string | Set a key to a value |
bmo version
Print the current bmo version.
JSON Output
Every command accepts --json and returns a consistent envelope.
Success:
Error:
Error codes and exit statuses:
| Code | Exit | Meaning |
|---|---|---|
general |
1 | Unclassified error |
not-found |
2 | Requested resource does not exist |
validation |
3 | Invalid input |
conflict |
4 | State conflict (e.g. duplicate relation) |
The --json flag is designed for programmatic consumption by AI agents and other tools. All structured data in the data field is stable across patch releases within a major version.
Enumerations
Valid string values for enumerated fields. All values are case-insensitive. Agents should use these exact strings to construct valid commands without trial and error.
Status: backlog, todo, in-progress, review, done
in-progress also accepts in_progress and inprogress as aliases.
Priority: none, low, medium, high, critical
Kind: bug, feature, task, epic, chore
Relation kinds: blocks, blocked-by, depends-on, dependency-of, relates-to, duplicates, duplicate-of
For AI Agents
bmo is built for agent-driven workflows. This section documents the recommended integration pattern.
Session initialization. At the start of a session, run:
Finding work. Use bmo next --json to retrieve the issues an agent should act on next. Issues returned by bmo next have no unresolved blocking dependencies and are not yet done.
Creating issues. Use -d to provide a rich description so that any agent or human reading the issue later has full context:
Tracking progress. Move issues through the workflow as work proceeds:
# or equivalently:
Adding context. Comment on issues to record findings, decisions, and discoveries:
Attaching files. Record which files are relevant to an issue for traceability and collision detection:
Reading machine-readable output. Always pass --json when the output will be consumed by code:
Data Storage
All data is stored in .bmo/issues.db in the directory where bmo init was run. bmo walks up the directory tree from the current working directory to find the nearest .bmo/ directory, so you can run bmo commands from any subdirectory of your project.
To use a database at an explicit path, set the BMO_DB environment variable or pass --db <path>:
BMO_DB=/path/to/issues.db
Migration from docket
See docs/migration-from-docket.md for the full migration guide.
Quick start:
&& &&
Development
We use just to run common recipes for this project:
License
MIT License. See LICENSE file.
bmo was inspired by docket by ALT-F4-LLC. Please credit that project for the ideas in this project.