migate nbd tickets, triage example for skill maybe later

quotesdb
Elijah Voigt 3 months ago
parent ba0efeb622
commit c95ebc9057

@ -1,5 +1,4 @@
{
"id": "460caf",
"title": "Multiple file format support (md, toml, jsonb)",
"body": "Add `--ftype` flag to `create` and `update` to write tickets in markdown, TOML, or binary JSON (CBOR) in addition to the existing JSON format. Format is detected from file extension on read.\n\n## Motivation\n\nMarkdown format lets agents write long-form ticket bodies with full markdown syntax, and makes tickets human-readable in a file browser. TOML is a natural config format. CBOR offers compact binary storage.\n\n## Approach\n\n### New crate dependencies (Cargo.toml)\nEvaluate and add:\n- `toml` — TOML serialisation (likely `toml = \"0.8\"`)\n- `serde_yml` or `serde_yaml` — YAML frontmatter (for `.md` files)\n- `ciborium` — CBOR binary JSON (`.jsonb`)\n\n### ticket.rs\nNo changes needed — `Ticket` already derives `Serialize`/`Deserialize`.\n\n### store.rs\nNew enum `FileFormat { Json, Markdown, Toml, Jsonb }`.\n\nNew function `detect_format(path: &Path) -> FileFormat`:\n- `.json` → `Json`\n- `.md` → `Markdown`\n- `.toml` → `Toml`\n- `.jsonb` → `Jsonb`\n- Unknown → `Json` (fallback)\n\nUpdate `ticket_path(root, id, format)` to use the format-appropriate extension. This is a breaking change to the function signature — update all callers.\n\nUpdate `read_ticket(root, id)`:\n1. Try each known extension in order until a file is found.\n2. Read the file and dispatch to the format-appropriate deserialiser.\n\nSerialisation helpers (private):\n- `serialize_json(ticket) -> String`\n- `serialize_toml(ticket) -> String`\n- `serialize_markdown(ticket) -> String` — TOML frontmatter (`+++` delimiters) with body as file content\n- `serialize_jsonb(ticket) -> Vec<u8>`\n\nDeserialization helpers (private):\n- `deserialize_markdown(bytes) -> Result<Ticket>` — parse frontmatter + body\n\nUpdate `list_tickets` to scan for `*.json`, `*.md`, `*.toml`, `*.jsonb` files.\n\nUpdate `write_ticket` to accept `format: FileFormat` and write in the appropriate format.\n\n### main.rs\nAdd `--ftype [json|md|toml|jsonb]` option (default `json`) to `create` and `update`.\nConversion on `update --ftype`: read old file, write new format, delete old file (if extension changed).\n\n## Markdown format (TOML frontmatter)\n```\n+++\nid = \"a3f9c2\"\ntitle = \"Fix login bug\"\npriority = 8\nstatus = \"in_progress\"\nticket_type = \"bug\"\ndependencies = [\"b7d41e\"]\n+++\n\nLong-form body text goes here. Supports full markdown.\n```\n\n## Tests\n- Unit tests: roundtrip each format (JSON already tested).\n- Integration tests: `nbd create --ftype md` creates a `.md` file; `nbd read` finds and parses it.\n- Integration test: `nbd update <id> --ftype toml` converts format and removes old file.\n\n## Files touched\n- `Cargo.toml` — new dependencies\n- `src/store.rs` — format detection, multi-format read/write, updated `list_tickets`\n- `src/main.rs` — `--ftype` flags\n- `src/tests.rs` — format roundtrip tests\n- `tests/integration.rs` — format integration tests\n- `README.md` — document `--ftype`\n- `docs/ARCHITECTURE.md` — update storage layout section",
"priority": 5,

@ -1,5 +1,4 @@
{
"id": "5f1495",
"title": "nbd update diff output",
"body": "Show a git-diff-style +/- summary of what changed when `nbd update` is run without `--json`.\n\n## Motivation\n\nCurrently `nbd update` prints the full ticket after the change, making it hard to see at a glance what actually changed. A diff view — showing only changed fields — is more informative.\n\n## Approach\n\n### display.rs\nAdd `format_diff(old: &Ticket, new: &Ticket) -> String`:\n- Compare each field between `old` and `new`.\n- For each field that changed, emit two lines:\n ```\n - status: todo\n + status: in_progress\n ```\n- If no fields changed, emit `(no changes)`.\n- Fields compared: `title`, `body`, `priority`, `status`, `ticket_type`, `dependencies`.\n- `id` is never shown (it cannot change).\n- Label width matches `format_ticket` (LABEL_WIDTH).\n\nAdd `print_diff(old: &Ticket, new: &Ticket)` that calls `println!(\"{}\" format_diff(...))`.\n\n### main.rs\nIn `cmd_update`:\n- Before applying changes: `let old = ticket.clone();`\n- After `write_ticket`:\n - If `json`: current behaviour (print new ticket as JSON).\n - Else: `display::print_diff(&old, &ticket)`.\n\n## Tests\n\nUnit tests in `src/tests.rs`:\n- `format_diff` shows changed fields only.\n- `format_diff` with identical tickets outputs `(no changes)`.\n- Changed dependencies are shown as comma-separated lists on each line.\n\nIntegration test:\n- `nbd update <id> --status in_progress` (no `--json`) prints `- status:` and `+ status:` lines.\n- `nbd update <id> --json` still prints full JSON (no diff).\n\n## Files touched\n- `src/display.rs` — `format_diff`, `print_diff`\n- `src/main.rs` — `cmd_update` uses `print_diff`\n- `src/tests.rs` — unit tests for `format_diff`\n- `tests/integration.rs` — integration tests",
"priority": 5,

@ -1,5 +1,4 @@
{
"id": "6e4239",
"title": "Nix flake for nbd",
"body": "Add `nbd/flake.nix` so that `nbd` can be consumed as a Nix package and used as a CLI tool in other projects in the mono-repo.\n\n## Motivation\n\nOther `vibed` services and external projects should be able to include `nbd` as a dev dependency via Nix, getting a pinned, reproducible binary without needing Cargo installed.\n\n## Approach\n\n### nbd/flake.nix\n\nFollow the pattern from the repo root `flake.nix`. The service flake should:\n1. Inherit the base flake's inputs (nixpkgs, rust-overlay, etc.) or declare its own.\n2. Define a `packages.default` attribute that builds the `nbd` crate with `rustPlatform.buildRustPackage`.\n3. Define a `devShells.default` that includes the `nbd` binary and standard Rust tooling (rustfmt, clippy, cargo).\n4. Optionally expose an `apps.default` for `nix run .#nbd`.\n\n### Cargo.lock\nEnsure `Cargo.lock` is committed (it already is) — required for reproducible Nix builds.\n\n### cargoHash / cargoSha256\nThe `buildRustPackage` derivation requires a `cargoHash` (or `cargoSha256`). Use the correct fetcher approach (vendored deps or `fetchCargoTarball`).\n\n## Steps\n1. Read the root `flake.nix` to understand the base structure.\n2. Write `nbd/flake.nix` following the same conventions.\n3. Run `nix build .#nbd` from the `nbd/` directory to verify it builds.\n4. Run `nix run .#nbd -- --help` to verify the binary works.\n\n## Files touched\n- `nbd/flake.nix` — new file\n- `README.md` — add `nix run` usage section",
"priority": 4,

@ -1,5 +1,4 @@
{
"id": "833807",
"title": "SQLite cache for list performance",
"body": "Add an optional SQLite cache in `.nbd/cache.db` to accelerate `nbd list` and `nbd ready` for large ticket stores.\n\n## Motivation\n\n`list_tickets` currently does O(n) file reads on every call. For stores with hundreds of tickets this is measurably slow. A SQLite cache avoids re-reading unchanged files by comparing file modification times (mtimes).\n\n## Approach\n\n### Crate dependency\nAdd `sqlx` with the `sqlite` and `runtime-async-std` features to `Cargo.toml`.\n\n### store.rs additions\nNew async function `open_cache(root: &Path) -> Result<sqlx::SqlitePool>`:\n- Opens (or creates) `.nbd/cache.db`.\n- Runs a migration: `CREATE TABLE IF NOT EXISTS tickets (id TEXT PRIMARY KEY, json TEXT NOT NULL, mtime INTEGER NOT NULL)`.\n\nNew function `list_tickets_cached(root: &Path) -> Result<Vec<Ticket>>`:\n1. Open cache.\n2. Read directory listing to get file names and mtimes.\n3. For each file: if the DB has a row with matching mtime, use cached JSON; otherwise read file, parse, insert/update row.\n4. Delete DB rows for IDs no longer on disk.\n5. Return deserialized tickets sorted by priority desc.\n\nKeep existing `list_tickets` as the non-cached fallback. Consider making `cmd_list` and `cmd_ready` use `list_tickets_cached` when available.\n\n### Migration strategy\n- The cache is always optional. If `cache.db` can't be opened, fall back to `list_tickets` (log a warning to stderr).\n- The cache is never the source of truth — the JSON files are. The cache is always reconstructable by deleting `.nbd/cache.db`.\n\n## Decision point\nDecide whether to enable the cache unconditionally or gate it behind a flag (`--cache` / `NBD_CACHE=1`). Recommendation: enable by default once the feature is stable.\n\n## Tests\n- Unit test: cache hit returns same data as direct file read.\n- Unit test: cache miss (mtime changed) re-reads the file.\n- Unit test: deleted ticket is evicted from cache.\n- Performance test (optional): benchmark 1000-ticket list with and without cache.\n\n## Files touched\n- `Cargo.toml` — add `sqlx`\n- `src/store.rs` — `open_cache`, `list_tickets_cached`\n- `src/tests.rs` — cache unit tests\n- `docs/ARCHITECTURE.md` — document the cache layer",
"priority": 3,

File diff suppressed because one or more lines are too long

@ -0,0 +1,23 @@
Add the following tickets:
Read @docs @src @tests @PLAN.md @README.md and @CLAUDE.md for context.
* Add a `--filter` flag to `list`, `ready`, and `migrate` commands.
* This should accept `key=value` pairs for all metadata.
* Keys include: priority, type, status, title.
* Users can pass multiple key=value pairs.
* When passing different keys this is a logical AND reducing the results.
* When passing the same key with different values, this results in a logical OR expanding the results.
* Values should support globs,
* Example: `status=*` matches all status values
* Example: `--title=*command*` matches all tickets with 'command' in the title
* By default do not include `done` tasks in `nbd list`. Require `--filter status=*` or `--filter status=done`
* Add a new `next` subcommand which chooses the highest priority ticket which is ready to be worked on.
* This should support the `--filter` flag.
Deeply understand each item before planning.
Create `nbd` tickets for each item including your plan, breaking the problem down into smaller tickets where it makes sense.
Include relevant source files, documentation, and context about each ticket so the work has the higest probability of success without additional context being required.
Do not implement any tickets.
Loading…
Cancel
Save