Tickets can now be stored in four formats, selected with --ftype: json (.json) — pretty-printed JSON, default, unchanged md (.md) — Markdown body with TOML frontmatter toml (.toml) — full TOML jsonb (.jsonb) — CBOR binary via ciborium Changes: - store.rs: FileFormat enum, detect_format(), find_ticket_path(), per-format serialize/deserialize helpers; read_ticket/list_tickets/ resolve_id/migrate_tickets all scan all known extensions - main.rs: --ftype on create (default "json") and update (optional, converts format and removes old file); archive/update preserve existing format when --ftype is absent - tests.rs: update write_ticket/ticket_path call sites; add TOML, Markdown, and CBOR roundtrip unit tests - integration.rs: 8 new format tests covering create, list, update conversion, format preservation, body roundtrip, unknown-ftype error Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
3 months ago | |
|---|---|---|
| .. | ||
| .claude | 3 months ago | |
| .nbd/tickets | 3 months ago | |
| docs | 3 months ago | |
| src | 3 months ago | |
| tests | 3 months ago | |
| CLAUDE.md | 3 months ago | |
| Cargo.lock | 3 months ago | |
| Cargo.toml | 3 months ago | |
| PLAN.md | 3 months ago | |
| README.md | 3 months ago | |
| triage-example.md | 3 months ago | |
README.md
nbd
A CLI tool for managing work tickets, primarily targeted at agent workflows.
Tickets are stored as JSON files in .nbd/tickets/ inside the nearest ancestor
directory that contains a .nbd/ folder, discovered by traversing upward from
the current working directory — just like git finds .git/.
How it works
Each ticket is a JSON file named {id}.json, where id is a unique
6-character lowercase hex string (e.g. a3f9c2). Tickets carry:
| Field | Type | Default |
|---|---|---|
id |
6-char hex string | auto-generated |
title |
string | (required) |
body |
string | "" |
priority |
integer 0–10 | 5 |
status |
todo | in_progress | done | closed |
todo |
ticket_type |
project | feature | task | bug |
task |
dependencies |
list of ticket IDs | [] |
Tickets can be stored in multiple formats, selected at creation time with
--ftype:
| Format | Extension | Description |
|---|---|---|
json |
.json |
Pretty-printed JSON (default) |
md |
.md |
Markdown body with TOML frontmatter |
toml |
.toml |
TOML |
jsonb |
.jsonb |
CBOR binary |
All commands accept --json for machine-readable output.
Usage
Initialise
Create the ticket store in your project root:
nbd init
Analogous to git init — safe to run multiple times.
Create a ticket
nbd create --title "Fix login bug" --priority 8 --type bug
nbd create --title "Add rate limiting" --body "Protect public endpoints" --deps a3f9c2
nbd create --title "Long-form spec" --body "# Section\n\nDetails..." --ftype md
nbd create --title "Config ticket" --ftype toml
Read a ticket
nbd read a3f9c2
nbd read a3f9c2 --json
List all tickets
By default, done and closed tickets are excluded.
nbd list # todo + in_progress only (done + closed excluded)
nbd list --all # all tickets including done and closed
nbd list --filter status=* # all tickets (alias for --all via filter)
nbd list --filter status=done # only completed tickets
nbd list --filter status=closed # only archived tickets
nbd list --filter type=bug # non-done, non-closed bug tickets
nbd list --json
Archive a ticket
Soft-delete a ticket by setting its status to closed. The file is preserved
on disk but hidden from normal listings.
nbd archive a3f9c2
nbd archive a3f9c2 --json
nbd archive is shorthand for nbd update <id> --status closed. Archived
tickets still count as resolved for dependency purposes — any ticket that
depends on an archived ticket becomes unblocked.
Update a ticket
Only the flags you supply are changed; all other fields retain their current
values. Use --ftype to convert to a different storage format (the old file
is removed automatically).
nbd update a3f9c2 --status in_progress
nbd update a3f9c2 --priority 9 --type bug
nbd update a3f9c2 --ftype md # convert to markdown format
Find the next ticket to work on
Returns the single highest-priority ticket that is ready to work on — not done and with all dependencies completed:
nbd next
nbd next --json
nbd next --filter type=bug # highest-priority ready bug
nbd next --filter priority=9 # highest-priority ready ticket at priority 9
Exits 0 even when no ready ticket exists ({"next": null} in JSON mode).
Find all actionable tickets
List all tickets that are ready to work on — not done and with all dependencies completed:
nbd ready
nbd ready --json
Print a CLAUDE.md snippet
Print a ready-to-paste section for adopting nbd in any project's CLAUDE.md:
nbd claude-md # raw markdown, suitable for redirect
nbd claude-md >> CLAUDE.md # append to your project's CLAUDE.md
nbd claude-md --json # machine-readable {"snippet": "..."}
The snippet is embedded in the binary at compile time, so it is always in sync
with the installed version of nbd.
Migrate ticket files
Re-serialise all ticket files through the current schema. Use this after
upgrading nbd to remove stale fields, add new fields with defaults, and
normalise formatting.
nbd migrate
nbd migrate --dry-run # preview changes without writing
nbd migrate --json # machine-readable summary
Running
# From the nbd/ directory
cargo run -- init
cargo run -- create --title "Test ticket" --priority 7 --type bug
cargo run -- list
cargo run -- list --all
cargo run -- ready
cargo run -- read <id>
cargo run -- update <id> --status in_progress
cargo run -- archive <id>
cargo run -- list --json
cargo run -- claude-md
cargo run -- claude-md --json
Testing
cargo test
Unit tests live in src/tests.rs. Integration tests (full command flows against
a temporary directory) live in tests/integration.rs.
Development
Run these commands in order before committing:
cargo fmt
cargo check
cargo clippy
cargo test
License
Dual-licensed under Apache License, Version 2.0 and
MIT License, consistent with the rest of the vibed mono-repo.
This software was written with Claude Code using the claude-sonnet-4-6 model.