You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2.9 KiB
2.9 KiB
| title | status | type | priority | created_at | updated_at | blocked_by | ||
|---|---|---|---|---|---|---|---|---|
| Add 'nbd graph' CLI subcommand | completed | feature | normal | 2026-03-10T23:30:31Z | 2026-03-10T23:30:32Z |
|
Wire up the graph subcommand in src/main.rs to expose the ASCII dependency graph and JSON output.
Motivation
With src/graph.rs and the rendering functions in display.rs implemented, this ticket connects them to the CLI so users (and agents) can invoke nbd graph.
CLI interface
nbd graph # full dependency forest (all tickets)
nbd graph <id> # subtree rooted at the given ticket ID (or unique prefix)
nbd graph --json # machine-readable adjacency list (all tickets)
nbd graph <id> --json # machine-readable subtree
nbd graph --filter type=bug # forest of only bug tickets and their deps
Clap definition (add to Commands enum in main.rs)
/// Draw an ASCII dependency graph of all tickets, or a subtree rooted at a
/// specific ticket.
///
/// Without an ID, renders every ticket as a dependency forest (roots first,
/// dependencies indented below). With an ID, renders only the subtree reachable
/// from that ticket via its dependencies.
Graph {
/// Optional ticket ID or unique prefix to use as the graph root.
///
/// When omitted, the full dependency forest is rendered.
id: Option<String>,
/// Filter tickets by field before building the graph: repeatable `key=value` pairs.
///
/// Applied to the full ticket list before graph construction.
/// Keys: `status`, `type`, `priority`, `title`. Values support globs.
#[arg(long = "filter", value_name = "KEY=VALUE")]
filter: Vec<String>,
}
Handler: cmd_graph
async fn cmd_graph(id: Option<String>, filter_args: Vec<String>, json: bool) -> store::Result<()>
Steps:
find_nbd_root()andlist_tickets(&root).await?.- Apply
parse_filters(&filter_args)?to narrow the ticket list. let graph = TicketGraph::build(&tickets);- If
idisSome: a. Resolveidviaresolve_id(&root, &id).await?. b. Ifjson: printgraph.to_subtree_json_value(&id)(or similar — see graph.rs ticket for the JSON shape). c. Else:display::print_subtree(&graph, &id). - If
idisNone: a. Ifjson: printgraph.to_json_value(). b. Else:display::print_graph(&graph).
JSON output shapes
Full graph (nbd graph --json):
{
"nodes": [
{"id": "a3f9c2", "title": "Fix login bug", "status": "todo", "priority": 8, "dependencies": ["b7d41e"]},
...
],
"edges": [
{"from": "a3f9c2", "to": "b7d41e"},
...
]
}
Subtree (nbd graph <id> --json):
Same shape as full graph but only including nodes and edges reachable from <id>.
Files touched
src/main.rs—Commands::Graphvariant,cmd_graph, dispatch indispatch()
Depends on
9c9ebe— graph computation modulee14172— ASCII rendering functions