diff --git a/PROJECTS.md b/PROJECTS.md index 0f569ca..51e38dd 100644 --- a/PROJECTS.md +++ b/PROJECTS.md @@ -13,6 +13,7 @@ - [ ] Local-first app development ## Interactive Learning and Education +- [ ] Git worktrees, how do use please - [ ] How to structure a co-op profit sharing worker owned business - [ ] Hands-on: Markov Chains - [ ] Hands-on: Vector Databases diff --git a/nbd/.claude/skills/work/SKILL.md b/nbd/.claude/skills/work/SKILL.md index 3be2355..1ee2e5c 100644 --- a/nbd/.claude/skills/work/SKILL.md +++ b/nbd/.claude/skills/work/SKILL.md @@ -3,7 +3,8 @@ name: work description: work on the highest priority thing --- -* Use nbd to choose the highest priority issue with no outstanding dependencies. +* If a ticket ID or description of a ticket is provided, look for that ticket. +* If no ticket/description is provided, use nbd next to choose the ticket to work on. * Thoroughly investigate the relevant parts of the codebase to ensure you understand the problem and how to implement the solution as describe in the ticket. * Implement the plan in the selected ticket. * Once complete validate changes with cargo fmt, cargo check, cargo clippy, and cargo test. diff --git a/nbd/.nbd/tickets/4036aa.md b/nbd/.nbd/tickets/4036aa.md new file mode 100644 index 0000000..b4c9844 --- /dev/null +++ b/nbd/.nbd/tickets/4036aa.md @@ -0,0 +1,97 @@ ++++ +title = "Print tickets in markdown format instead of key-value table" +priority = 5 +status = "todo" +ticket_type = "feature" +dependencies = [] ++++ +## Goal + +When a ticket is printed to stdout (e.g. by `nbd read`, `nbd create`, `nbd archive`, `nbd next`, `nbd update` without `--json`), it should be rendered as markdown with TOML frontmatter — the same format used by `--ftype md` files on disk — rather than the current key-value table. + +`--json` output is unaffected. + +## Current output (`nbd read `) + +``` +ID: a3f9c2 +Title: Fix login bug +Body: Users cannot log in with email + +Priority: 8 +Status: in_progress +Type: bug +Dependencies: b7d41e, c9e823 +``` + +## Target output + +``` ++++ +title = "Fix login bug" +priority = 8 +status = "in_progress" +ticket_type = "bug" +dependencies = ["b7d41e", "c9e823"] ++++ +Users cannot log in with email + +``` + +The `id` field is not in the frontmatter on disk (filename is the source of truth), but for display purposes it should appear as a comment or additional line. Recommended approach: add `id = "a3f9c2"` as the **first key** in the frontmatter so it's immediately visible: + +``` ++++ +id = "a3f9c2" +title = "Fix login bug" +priority = 8 +status = "in_progress" +ticket_type = "bug" +dependencies = ["b7d41e", "c9e823"] ++++ +Users cannot log in with email + +``` + +## Files to change + +### `src/display.rs` + +Replace `format_ticket` with a markdown-rendering implementation. The simplest approach reuses `serialize_markdown` from `src/store.rs`, adding `id` to the frontmatter output. + +Option A (preferred): expose `serialize_markdown` from `store.rs` as `pub(crate)` and call it from `display.rs`, prepending the `id` line to the TOML frontmatter block. + +Option B: duplicate the logic in `display.rs` as a display-specific formatter that includes `id`. + +The `print_ticket` function should call the new formatter. + +### `src/tests.rs` + +Update any unit tests for `format_ticket` that check the old key-value table format. They should now expect TOML frontmatter. + +### `tests/integration.rs` + +Update any integration tests that check the plain-text output of `nbd read`, `nbd create`, etc. + +## Commands affected + +Any command that calls `display::print_ticket`: +- `nbd create` (non-JSON path) +- `nbd read` (non-JSON path) +- `nbd archive` (non-JSON path) +- `nbd next` (non-JSON path, single ticket) +- `nbd update` currently calls `print_diff`, so it is **not** affected + +## Validation + +```sh +cargo fmt && cargo check && cargo clippy && cargo test +cargo run -- create --title "Test ticket" --body "Some body text" --priority 7 --type bug +# Output should be: +# +++ +# id = "" +# title = "Test ticket" +# priority = 7 +# status = "todo" +# ticket_type = "bug" +# dependencies = [] +# +++ +# Some body text +``` \ No newline at end of file diff --git a/nbd/.nbd/tickets/8b4041.md b/nbd/.nbd/tickets/8b4041.md new file mode 100644 index 0000000..5c52f97 --- /dev/null +++ b/nbd/.nbd/tickets/8b4041.md @@ -0,0 +1,58 @@ ++++ +title = "Change graph cycle marker from [cycle] to *" +priority = 3 +status = "todo" +ticket_type = "task" +dependencies = [] ++++ +## Goal + +When `nbd graph` renders a node that has already been visited (a node appearing in multiple branches of the tree), it currently labels the repeat occurrence as `[cycle]`. This label is misleading — the node isn't truly in a cycle, it's simply appearing twice in the tree because it's depended on from multiple places. Change the marker to `*` to indicate "this ticket appears elsewhere in the tree". + +## Current output + +``` +a3f9c2 [todo] Fix login bug +├── b7d41e [in_progress] Add rate limiting +│ └── c9e823 [todo] Write tests +└── c9e823 [cycle] +``` + +## Target output + +``` +a3f9c2 [todo] Fix login bug +├── b7d41e [in_progress] Add rate limiting +│ └── c9e823 [todo] Write tests +└── c9e823 * +``` + +## Files to change + +### `src/display.rs` + +In the `render_node` function (around line 409), change the cycle rendering line from: + +```rust +append_line(out, &format!("{prefix}{connector}{id} [cycle]")); +``` + +to: + +```rust +append_line(out, &format!("{prefix}{connector}{id} *")); +``` + +### README.md + +Update the `nbd graph` section example to replace `[cycle]` with `*` in the documentation. + +## Validation + +```sh +cargo fmt && cargo check && cargo clippy && cargo test +# Create two tickets that share a dependency, then graph them +cargo run -- graph +``` + +Any test that checks for `[cycle]` in graph output needs updating to expect `*` instead. \ No newline at end of file diff --git a/nbd/.nbd/tickets/9344a5.md b/nbd/.nbd/tickets/9344a5.md new file mode 100644 index 0000000..b1108e8 --- /dev/null +++ b/nbd/.nbd/tickets/9344a5.md @@ -0,0 +1,51 @@ ++++ +title = "Update claude-md snippet to show --json on all commands" +priority = 4 +status = "todo" +ticket_type = "task" +dependencies = [] ++++ +## Goal + +The `nbd claude-md` command emits `src/claude_md_snippet.md` verbatim. The current snippet shows core commands without `--json`, contradicting the guideline at the bottom that says to always pass it. + +## What to change + +In `src/claude_md_snippet.md`, update the **Core commands** section so every example includes `--json`: + +```sh +# Create a new ticket (use --ftype md for a human-readable body) +nbd create --title "Add OAuth login" --type feature --priority 7 --ftype md --json + +# List all open tickets (sorted by priority) +nbd list --json + +# Read a specific ticket +nbd read --json + +# Update a ticket +nbd update --status in_progress --json +nbd update --status done --json +``` + +Also update the **Workflow** numbered list to use `--json` in every command: + +``` +1. **Before starting** — create a ticket: `nbd create --title "..." --ftype md --json` +2. **When starting** — mark it in progress: `nbd update --status in_progress --json` +3. **When done** — mark it complete: `nbd update --status done --json` +``` + +The `nbd ready` and `nbd next` sections should also include `--json`. + +## Files + +- `src/claude_md_snippet.md` — the only file that needs changing + +## Validation + +```sh +cargo run -- claude-md | grep -c '\-\-json' +``` + +The count should go up after the change. All existing tests should still pass. \ No newline at end of file diff --git a/nbd/.nbd/tickets/feb901.md b/nbd/.nbd/tickets/feb901.md new file mode 100644 index 0000000..efb3619 --- /dev/null +++ b/nbd/.nbd/tickets/feb901.md @@ -0,0 +1,88 @@ ++++ +title = "Split archive/closed: archive=done, closed=cancelled" +priority = 6 +status = "todo" +ticket_type = "bug" +dependencies = [] ++++ +## Problem + +Currently `nbd archive` sets a ticket's status to `closed`. This conflates two distinct intents: + +- A ticket that **was completed** and is being retired from the active list +- A ticket that **will not be completed** (e.g. cancelled, superseded, won't-fix) + +## Desired semantics + +| Status | Meaning | Resolved (unblocks deps)? | Visible in `nbd list` by default? | +|---|---|---|---| +| `archived` | Completed and soft-deleted from view | Yes | No | +| `closed` | Won't be completed (cancelled/won't-fix) | Yes (avoids deadlock) | No | + +Both statuses resolve dependencies, so a ticket depending on an `archived` or `closed` ticket becomes unblocked. This matches current behaviour for `closed`. + +## Changes required + +### `src/ticket.rs` + +Add `Archived` variant to `Status`: + +```rust +pub enum Status { + #[default] + Todo, + InProgress, + Done, + Closed, + Archived, // new +} +``` + +Serialises as `"archived"`. + +### `src/main.rs` + +- `parse_status`: add `"archived" => Ok(Status::Archived)` arm and update error message +- `cmd_archive`: change `ticket.status = Status::Closed` → `ticket.status = Status::Archived` +- `cmd_list`: exclude `Status::Archived` alongside `Done` and `Closed` in the default filter path +- `cmd_ready` / `cmd_next`: treat `Status::Archived` as resolved (count it in `done_ids`) +- Update the `Archive` command docstring to say it sets status to `archived` not `closed` + +### `src/display.rs` + +- `status_str`: add `Status::Archived => "archived"` arm + +### `src/graph.rs` + +- `status_str` (internal helper): add `Status::Archived => "archived"` arm + +### README.md + +- Update the Status table to show `archived` as a valid status +- Update `nbd archive` description to say it sets status to `archived` +- Update the note about `archived` vs `closed` semantics + +### CLAUDE.md + +- Update CLI Interface block to include `archived` in valid status values +- Update `nbd archive` description + +### `src/tests.rs` / `tests/integration.rs` + +- Update any test that checks `status == "closed"` after `nbd archive` → expect `"archived"` instead +- Add test: `nbd archive ` produces `"archived"` status +- Add test: a ticket with `status=closed` (manually set) is also excluded from list by default and treated as resolved + +## Migration concern + +Existing tickets on disk that have `status: "closed"` set by previous `nbd archive` calls will retain `closed` status. This is acceptable — `closed` remains a valid status. Users who want to distinguish can `nbd update --status archived` on historical tickets, or run `nbd migrate` once the schema is updated. + +## Validation + +```sh +cargo fmt && cargo check && cargo clippy && cargo test +cargo run -- create --title "Test archive" --json | jq -r '.id' | xargs -I{} cargo run -- archive {} --json +# → status should be "archived" +cargo run -- create --title "Cancelled ticket" --json | jq -r '.id' | xargs -I{} cargo run -- update {} --status closed --json +# → status should be "closed" +``` \ No newline at end of file diff --git a/nbd/TODO.md b/nbd/TODO.md index baa42f5..86970a8 100644 --- a/nbd/TODO.md +++ b/nbd/TODO.md @@ -2,6 +2,10 @@ --- +`nbd claude-md` should advise using `--json` for all commands. + +--- + Add a new `backlog` state to tickets. The goal of this is tickets which are created but should not be worked on yet. Tickets with this status do not show up by default in `nbd list`, `nbd ready`, and `nbd next`. diff --git a/nbd/flake.lock b/nbd/flake.lock new file mode 100644 index 0000000..244e7d5 --- /dev/null +++ b/nbd/flake.lock @@ -0,0 +1,48 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1771369470, + "narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0182a361324364ae3f436a63005877674cf45efb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1771816254, + "narHash": "sha256-vkp3iTF6QmHMvL+34DI93IiMPjS2lqcMlA1fl7nXVsQ=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "085bdbf5dde5477538e4c87d1684b6c6df56c0ad", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +}