You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+10Lines changed: 10 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
8
8
## [Unreleased]
9
9
10
+
## v0.6.0 - 2026-07-19
11
+
12
+
### Added
13
+
-**Update notifications across CLI, TUI, and web** — nibs checks GitHub for a newer release (cached ~24 h in the user cache directory; silently skipped for dev builds, in CI, or when `NIBS_NO_UPDATE_CHECK` is set) and surfaces it unobtrusively: a trailing line on stderr after an interactive CLI command (never for `--json`, pipes, or `serve`/`graphql`/`query`), a footer hint in the TUI, and a dismissible banner in the web UI — backed by a new best-effort `updateStatus` GraphQL query and remembered per version. Version comparison only: no telemetry and no automatic action. (Refs: nibs-jlzy, nibs-ipmj, nibs-imib, nibs-25od.)
14
+
-**`nibs upgrade`** — downloads, checksum-verifies, and replaces the running binary with the latest release (or a specific `--version <tag>`), rolling back automatically on failure. `--check` reports whether an update is available without changing anything; pre-releases are skipped by default. When nibs was installed by a package manager (Homebrew, Nix, Scoop, Chocolatey, WinGet, or `go install`), `upgrade` defers to that manager with guidance instead of replacing the binary itself. (Refs: nibs-hkub.)
15
+
16
+
### Changed
17
+
-**BREAKING:**`deferred` is now a nib *status* (parked; non-terminal; excluded from `--ready`) instead of a priority. The priority axis is now `critical / high / normal / low`, and `--priority deferred` is no longer accepted. Existing nibs with `priority: deferred` are normalized to `priority: low` on load — its lowest-rank equivalent — and the normalization is persisted immediately so on-disk and in-memory values agree. (Refs: nibs-0m5d.)
18
+
- Release archives are now named `{project}_{os}_{arch}` (the version is no longer embedded in the asset name) and their checksums are published as a single `checksums.txt`, so `nibs upgrade` can match the asset for the running platform; `install.sh` and `install.ps1` resolve the new names. (Refs: nibs-hkub.)
19
+
10
20
### Fixed
11
21
- Keyword search (web keyword box, `nibs list -S`, GraphQL `search:`) now matches nib IDs and ID fragments directly: a substring of the short ID (very short fragments excluded), a prefix of the full ID, or an exact full ID, case-insensitive, surrounding whitespace trimmed. In queries without an explicit sort (e.g. `nibs query`), ID matches come first (sorted by ID, capped at the search limit), followed by full-text hits in relevance order; sorted surfaces (`nibs list`, the web view) interleave them per their sort. A nib matching both appears once. Previously an ID query returned nothing because the index stores `id` as an unanalyzed keyword field. (Refs: nibs-sn96.)
Copy file name to clipboardExpand all lines: CLAUDE.md
+13-6Lines changed: 13 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,8 @@ Nibs is a file-based issue tracker for AI-first workflows. Issues ("nibs") are s
11
11
All commands use [Task](https://taskfile.dev/) (`go-task/task`) as the task runner. Tool version pinning (Go, golangci-lint, Task itself) is handled by [mise](https://mise.jdx.dev/) via `mise.toml`, so the only thing contributors need to install manually is mise.
12
12
13
13
-`task build` - Build the `./nibs` executable (runs codegen first)
14
-
-`task test` - Run all tests: Go + web (runs codegen and web:build first)
14
+
-`task test` - Run all tests: Go + web (runs codegen and web:build first); includes the `-race` gate on `internal/nibcore` + `internal/graph`
15
+
-`task test:race` - Run the `-race` detector on the concurrency-critical packages (`internal/nibcore` + `internal/graph`) only
-`task nibs` - Build and run the CLI in one step (`go run .`)
17
18
-`go test ./internal/nib/` - Run tests for a specific package
@@ -21,6 +22,8 @@ All commands use [Task](https://taskfile.dev/) (`go-task/task`) as the task runn
21
22
-`task screenshots` - Capture web UI screenshots to `web/screenshots/output/` for visual verification
22
23
-`task --list` - List all available tasks
23
24
25
+
`go build ./...` fails in a fresh git worktree — `embed.go` embeds `web/dist`, which is gitignored, so it looks like a broken checkout (`pattern all:web/dist: no matching files found`). Build the web assets there first, or scope to what you need (`go test ./internal/...`).
26
+
24
27
## GraphQL Schema Changes
25
28
26
29
When modifying the GraphQL schema (`internal/graph/schema.graphqls`):
@@ -52,7 +55,7 @@ The GraphQL engine runs in-process for CLI commands (`cmd/graphql.go` executes q
52
55
-**`internal/nib/`** - Core `Nib` struct, Markdown+YAML parsing/rendering, ID generation, sorting
53
56
-**`internal/nibcore/`** - `Core` type: thread-safe in-memory nib store with filesystem persistence, file watching (fsnotify), search (Bleve), and archive management
54
57
-**`internal/graph/`** - gqlgen GraphQL layer. `schema.graphqls` is the schema, `schema.resolvers.go` has resolver implementations, `resolver.go` has shared validation logic (parent hierarchy, cycle detection, etag validation)
-**`internal/tui/`** - Bubbletea TUI app. Uses the GraphQL resolver internally for all mutations
57
60
-**`internal/search/`** - Bleve full-text search index (lazy-initialized, in-memory)
58
61
-**`internal/ui/`** - Shared UI utilities (styles, tree rendering)
@@ -77,22 +80,23 @@ The GraphQL engine runs in-process for CLI commands (`cmd/graphql.go` executes q
77
80
-**Event delegation**: TreeTable uses delegated event handlers on the scroll container (not per-row callbacks). TreeTableRow is a pure render component with zero callback props — interactive elements use `data-action` attributes (toggle, title, add-child, drag-handle). New actions require a handler case in TreeTable's `handleDelegatedClick`.
78
81
-**Svelte context for ambient state**: SelectionState and DragState are provided via `provideSelection`/`provideDrag` from `contexts.ts`. Components read with `useSelection()`/`useDrag()`. Tests must provide context via `makeTestContext()` from contexts.ts — pass as `context` option to `render()`.
79
82
-**Shared field components**: Use `StatusSelect`, `TypeSelect`, `PrioritySelect`, `EstimateSelect`, `TagEditor` from `web/src/lib/components/` instead of inline select/tag markup. Use `renderMarkdown()` from `web/src/lib/markdown.ts` instead of inline DOMPurify+marked. Use `.prose-nib` CSS class for markdown prose styling.
83
+
- There is no prettier config — **do not run prettier**; it reformats unrelated files (one run churned 129 lines of untouched code).
80
84
81
85
### Nib Data Model
82
86
83
-
Nibs are Markdown files with YAML front matter stored in `.nibs/`. Filename format: `{id}-{slug}.md` or `{id}.md`. Archived nibs go to `.nibs/archive/`. The `Nib` struct fields like `ID`, `Slug`, and `Path` are derived from the filename/path, not from front matter.
87
+
Nibs are Markdown files with YAML front matter stored in `.nibs/`. Filename format: `{id}-{slug}.md` or `{id}.md`. Archived nibs go to `.nibs/archive/` but **stay in the store and remain visible in all queries** — `Core.Archive` keeps the nib in memory and rewrites its `Path`. Archiving is a move, not a removal (only `Delete` removes). The `Nib` struct fields like `ID`, `Slug`, and `Path` are derived from the filename/path, not from front matter.
84
88
85
89
The `Path` field always uses forward slashes (normalized via `filepath.ToSlash`) for cross-platform portability. When using `Path` for filesystem operations, combine with `filepath.Join(c.root, b.Path)` which handles mixed separators.
86
90
87
91
### Configuration
88
92
89
-
Project config lives in `.nibs.yml` at project root (searched upward from cwd). Key settings: `nibs.prefix` (ID prefix like "myproj-"), `nibs.id_length`, `nibs.path` (data directory, default `.nibs`), `nibs.require_if_match` (optimistic concurrency). Nibs path can also be set via `--nibs-path` flag or `NIBS_PATH` env var.
93
+
Project config lives in `.nibs.yml` at project root (searched upward from cwd). Key settings: `nibs.prefix` (ID prefix like "myproj-"), `nibs.id_length`, `nibs.path` (data directory, default `.nibs`), `nibs.require_if_match` (optimistic concurrency). Nibs path can also be set via `--nibs-path` flag or `NIBS_PATH` env var — but those move **only the data directory**; config is still discovered from cwd, so pointing them at another project silently applies *this* project's prefix/id_length/defaults to that project's data. To work against another project, pass `--config <dir>/.nibs.yml` — it resolves that project's data directory too, so `--nibs-path` is unnecessary.
90
94
91
95
For optional config fields with non-zero defaults, use pointer types (`*int`, `*bool`) with `yaml:"...,omitempty"` so nil means "use default" vs explicit zero/false. See `ServerConfig` for the pattern.
92
96
93
97
### Agent Integration
94
98
95
-
`nibs prime` outputs a prompt template (`cmd/prompt.tmpl`) that teaches coding agents how to use the GraphQL CLI. This is the primary interface for AI agents.
99
+
`nibs prime` outputs the agent onboarding prompt (slim `cmd/prompt.tmpl`, or the full guide `cmd/prompt-full.tmpl` with `--full`). `nibs cheat` prints the whole CLI grammar on one screen, and `nibs catalog <topic>` emits generated vocabulary (fields, filters, hierarchy, recipes, examples, schema). Together these are the primary interface for AI agents.
96
100
97
101
## Branching & Workflow
98
102
@@ -127,15 +131,17 @@ Before starting any new work, run `git fetch` (and `git -C .nibs fetch`) and che
127
131
## Testing
128
132
129
133
- Always write or update tests for changes
134
+
-**Prove a new guard bites**: break the behavior it guards and confirm the test fails. A test that passes while its target is broken is decoration. This keeps happening here — guards placed after an assert that throws first (so they never run), and a mutation that survived the entire 1240-test suite.
130
135
- Use table-driven tests following Go conventions
131
136
- Never hardcode `/` or `\` in path assertions — use `filepath.Join` for OS paths and forward slashes for nib `Path` fields
132
137
- For manual CLI testing: `task nibs` compiles and runs the CLI
133
138
- For manual CLI testing, `task demo` serves the web UI with a temporary copy of the sample-project fixture (safe to mutate), and `task demo:tui` does the same for the TUI
134
-
-**Test fixture dataset**: `testdata/fixtures/sample-project/` has 87 curated nibs (prefix `tnib-`) covering all types, statuses, priorities, hierarchies, and relationships. Use `fixtures.CopySampleProject(t)` from `testdata/fixtures/` to get a temporary copy for write tests. Regenerate with `bash testdata/fixtures/gen-sample-project.sh`.
139
+
-**Test fixture dataset**: `testdata/fixtures/sample-project/` has 89 curated nibs (prefix `tnib-`) covering all types, statuses, priorities, hierarchies, and relationships. Use `fixtures.CopySampleProject(t)` from `testdata/fixtures/` to get a temporary copy for write tests. Regenerate with `bash testdata/fixtures/gen-sample-project.sh`.
135
140
- Web UI tests: `cd web && npm install && npx vitest run --reporter=agent` (Vitest + jsdom + @testing-library/svelte). Run `npm install` first — node_modules can go stale after branch switches.
136
141
- Web test commands require `web/` as the working directory. If cwd has drifted, `cd` to the project root's `web/` directory first.
137
142
-**Always use `--reporter=agent`** when running vitest — it keeps output concise. Never pipe vitest through grep; read the output once.
138
143
-`task test` runs both Go and web tests. No need to run them separately unless debugging a specific failure.
144
+
-**`-race` runs automatically**: `task test` runs `internal/nibcore` + `internal/graph` a second time under `-race` (via `task test:race`), and CI runs the same detector lane on Linux. These packages carry the concurrency invariants (live-pointer/copy-on-write, clone-under-lock), whose guards degrade to trivial checks without `-race` — so a reintroduced data race now fails the default gate, not just a manual `go test -race`.
139
145
-**Visual verification of the web UI**: `task screenshots` captures PNGs of the key UI states (table at each view level, detail panel, editor modal, context menu) into `web/screenshots/output/` (gitignored), served from a temp copy of the sample fixture. Read the PNGs to *see* rendered changes — jsdom tests can't verify pixels. One-time setup: `cd web && npx playwright install chromium` (plain `install`, not `--with-deps` — that flag is apt-only and fails on Fedora). Extend `web/screenshots/capture.spec.ts` when new views or themes land.
140
146
-**bits-ui timer flush**: `test-setup.ts` has an `afterAll` that waits 50ms so bits-ui's body-scroll-lock deferred cleanup (24ms setTimeout) fires while jsdom still exists. Without this, the timer fires after jsdom teardown causing a spurious "document is not defined" error.
141
147
@@ -160,4 +166,5 @@ When working from a plan or work item:
160
166
- No backwards compatibility requirements for CLI usage or APIs — this is a new, unreleased project. Only existing nibs data files (`.nibs/` Markdown+YAML format) must remain compatible. Feel free to make breaking CLI/API changes without migration shims.
161
167
-**Always prefer TDD when fixing bugs**: write a failing test that reproduces the bug first, then fix the code to make it pass.
162
168
-**Code review findings that are too large to fix in-place should be deferred as nibs**, not silently skipped. If a finding requires architectural redesign or broad refactoring beyond the current task's scope, create a follow-up nib to track it.
169
+
-**A finding is a claim, and a nib made from one inherits the claim without its evidence.** Defer findings with the command and output that demonstrate them, or label the claim `[Unverified]`. Reproduce a load-bearing premise before building on it: in one 7-nib batch, 4 premises were false — `disabled` blocks selection (it doesn't, in Chromium), a race detector fired 3/8 (80 runs say never), shorthand `#id` mentions don't link (they do), archiving removes a nib from the list (it doesn't). Every refutation came from running something; none from reading. The one premise that survived came from using the app.
163
170
-**When creating a new nib, place it at the appropriate position** using `reorderNib` (e.g. `afterId` of a related nib). Consider development dependencies, complexity, and type (bugs before refactors before features) when choosing where it belongs. Don't leave new nibs at the default position.
Copy file name to clipboardExpand all lines: README.md
+26-12Lines changed: 26 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,6 +56,17 @@ task build
56
56
57
57
Prebuilt binaries are also available on the [Releases](https://github.com/alphaleonis/nibs/releases) page.
58
58
59
+
### Updating
60
+
61
+
nibs notifies you when a newer release is available — a trailing line on the CLI, a footer hint in the TUI, and a banner in the web UI. To upgrade in place:
62
+
63
+
```bash
64
+
nibs upgrade # download, verify, and replace the running binary (rolls back on failure)
65
+
nibs upgrade --check # just report whether an update is available
66
+
```
67
+
68
+
If nibs was installed by a package manager (Homebrew, Nix, Scoop, Chocolatey, WinGet, or `go install`), `nibs upgrade` defers to that manager with guidance instead of replacing the binary itself. Set `NIBS_NO_UPDATE_CHECK=1` to silence the update notifications.
69
+
59
70
## Quick Start
60
71
61
72
Initialize nibs in your project:
@@ -67,10 +78,10 @@ nibs init
67
78
This creates a `.nibs/` directory and a `.nibs.yml` configuration file. Both should be tracked in version control.
68
79
69
80
```bash
70
-
nibs create"Set up CI pipeline" -t task -d "Configure GitHub Actions for build and test"
71
-
nibs list # list all nibs
72
-
nibs tui # interactive terminal UI
73
-
nibs web # open the web UI in your browser
81
+
nibs new"Set up CI pipeline" -t task # create a task
82
+
nibs list # list all nibs
83
+
nibs tui # interactive terminal UI
84
+
nibs web # open the web UI in your browser
74
85
```
75
86
76
87
## Agent Integration
@@ -111,30 +122,33 @@ Or, if your agent framework supports startup hooks, wire `nibs prime` to run at
111
122
| Command | Description |
112
123
|---------|-------------|
113
124
|`nibs init`| Initialize a new nibs project |
114
-
|`nibs create`| Create a new nib (task, bug, feature, epic, milestone) |
125
+
|`nibs new`| Create a new nib (milestone, epic, feature, task, bug, or research) |
115
126
|`nibs list`| List nibs with filtering by status, type, priority, tags |
116
-
|`nibs show <id>`| Display a nib's full contents |
117
-
|`nibs update <id>`| Update properties, body content, or relationships |
127
+
|`nibs get <id>`| Display one or more nibs (full document by default) |
128
+
|`nibs set <id>`| Update a nib's metadata and links, or clear a field |
129
+
|`nibs body <id>`| Edit a nib's Markdown body (set, append, or replace sections) |
130
+
|`nibs mv <id>`| Reposition a nib among its siblings or reparent it |
118
131
|`nibs close <id>`| Mark a nib completed with a summary |
119
132
|`nibs context`| Show project status summary with progress |
120
133
|`nibs plan <id>`| View an ordered plan of a parent nib's children |
121
-
|`nibs graphql`|Execute arbitrary GraphQL queries and mutations|
122
-
|`nibs roadmap`| Generate a Markdown roadmap from milestones |
134
+
|`nibs query`|Run a GraphQL query or mutation|
135
+
|`nibs roadmap`| Generate a Markdown roadmap from milestones and epics |
123
136
|`nibs check`| Validate configuration and data integrity |
124
137
|`nibs web`| Start the web UI server |
125
138
|`nibs tui`| Open the terminal UI |
126
139
|`nibs prime`| Output the agent integration prompt (slim default; pass `--full` for the complete reference) |
127
140
|`nibs archive`| Move completed/scrapped nibs to the archive |
141
+
|`nibs upgrade`| Update nibs to the latest release (checksum-verified, with rollback); `--check` to only check |
128
142
129
143
Run `nibs <command> --help` for full usage details.
130
144
131
145
## Data Model
132
146
133
147
Each nib has:
134
148
135
-
-**Type**: milestone, epic, feature, task, or bug
136
-
-**Status**: draft, todo, in-progress, completed, or scrapped
137
-
-**Priority** (optional): critical, high, normal, low, or deferred
149
+
-**Type**: milestone, epic, feature, task, bug, or research
150
+
-**Status**: draft, todo, in-progress, deferred, completed, or scrapped
151
+
-**Priority** (optional): critical, high, normal, or low
138
152
-**Estimate** (optional): s, m, l, or xl (t-shirt sizes)
0 commit comments