lerko 36999cd825 feat(tui): add bubbletea terminal UI with entity list, detail, and capture
Adds `nib tui` command and `make tui` target. Scrollable entity list
with j/k navigation, enter for detail view, `a` to capture new entries
using the existing parse grammar, and `d` to delete.
2026-05-17 20:07:45 -04:00
2026-05-15 22:01:47 -04:00
2026-05-15 22:01:47 -04:00

nib

Capture-first note system. Catch thoughts, todos, and events before they slip — from terminal or browser. Everything lives in a single SQLite file.

nib uses a tiny grammar to extract structure from plain text. You type naturally, and nib figures out what it is: a thought, a todo with a due date, an event, a titled reference. Tags, descriptions, and time anchors are pulled out automatically. The body stays as markdown.

When something proves useful, promote it to a card (snippet, template, checklist, decision, link) for quick reuse. Cards track usage and float to the top.

Install

Requires Go 1.24+.

go build -o nib .

Data lives at ~/.nib/nib.db by default. Override with NIB_DB=/path/to/file.db.

Quick start

# capture a thought
nib "proxy_pass needs a trailing slash"

# todo
nib "- buy mass gainer @tomorrow #errands"

# titled entry with description
nib "|nginx proxy trick // always forget this #ops"

# todo with a title
nib "- |deploy staging // rebuild docker image #ops"

# list recent entries
nib ls

# list by tag
nib ls --tag ops

# list a specific month
nib ls --month 2026-05

# start the web UI
nib serve

Open http://localhost:4444 for the browser interface.

Grammar

The full grammar fits on an index card. Here's what matters:

Kind prefixes

The first character decides what kind of entry you're creating.

Input Kind Example
bare text thought just an idea
- text todo - buy milk @tomorrow
@time text event @friday 2pm lunch with alex
!time text reminder !3pm call dentist

The dash needs a space after it. -deploy is a thought, - deploy is a todo.

Titles and descriptions

Give an entry a name with | at the start. Add a description with //.

|nginx proxy trick
proxy_pass http://backend/;

|deploy checklist // for staging #ops
1. docker build
2. docker push
3. ssh prod && restart

// quick reference for proxy config
the actual body text goes here

body text // this part becomes the description

Title shows as the scan label in list view. Description appears in the detail pane. Both are optional — most captures won't need them.

Tags and flags

Tags and flags work anywhere in the input. They're extracted and removed from the body.

deploy nginx #ops #infra        → tags: ops, infra
important thing !pin            → pinned to top
use ##channel in slack          → literal #channel in body (escaped)

Cards

Promote a fluid entry to a card for reuse:

nib promote <id> snippet    # code trick, copy-to-clipboard
nib promote <id> template   # has ${slots} to fill
nib promote <id> checklist  # step-through items
nib promote <id> decision   # chose/why/rejected
nib promote <id> link       # URL with an open button

Or use ^type inline: nib "proxy trick #nginx ^card"

CLI commands

Command What it does
nib <input> Capture (shorthand for nib add)
nib ls List entries — filter with --tag, --date, --month, --from/--to
nib cards List cards sorted by usage
nib edit <id> Open in $EDITOR
nib copy <id> Copy body to clipboard
nib promote <id> [type] Promote to card
nib demote <id> Strip card, back to fluid
nib absorb <target> <source> Merge source into target
nib delete <id> Soft delete (repeat to hard delete)
nib serve Start web UI on :4444 (or --port)

IDs are prefix-matchable. If 01KRQ4 is unique, that's enough.

Web UI

nib serve starts a local web interface with:

  • Capture bar — same grammar as the CLI
  • Stream view — entries grouped by date, newest first
  • Cards view — promoted cards sorted by use count
  • Tag rail — filter by tag
  • Month navigator — browse by date range
  • Detail pane — full entry view, double-click to edit
  • Keyboard shortcutsj/k navigate, n to capture, p to promote, e to edit, dd to delete

Dark and light themes. Toggle with the button in the header.

Data

Everything is one SQLite file. Back it up, sync it, move it between machines — it's just a file. WAL mode is on for concurrent reads.

# back up
cp ~/.nib/nib.db ~/.nib/nib.db.bak

# use a different database
NIB_DB=/path/to/other.db nib ls

License

MIT

S
Description
No description provided
Readme MIT 931 KiB
Languages
Go 63.9%
JavaScript 19%
CSS 12.4%
HTML 4.2%
Makefile 0.5%