Documentation
¶
Overview ¶
Package note implements nt's markdown notes with light YAML frontmatter (SPEC §5). Notes are one file each under notes/, so they need no shared lock: creation and edits are atomic single-file writes.
Index ¶
Constants ¶
const TaskNoteFolder = "__tasks__"
TaskNoteFolder is the subfolder under notes/ where a task's "body" notes live (auto-split paragraph captures and explicit task detail). The double-underscore name is deliberately "reserved-looking" so it won't collide with a plain "tasks" folder a user might keep for their own hand-curated notes; grouping these machine-created notes here keeps them out of a human's folders — like the "journal" folder does for daily notes.
Variables ¶
This section is empty.
Functions ¶
func Slug ¶
Slug derives a filesystem-safe slug from a title, falling back to a timestamp when the title yields nothing usable (à la nb).
func TitleOverlap ¶ added in v0.20.0
TitleOverlap is the word-set Jaccard (0..1) of two titles, ignoring short and stopword tokens — the similarity heuristic behind duplicate detection, exported so task-side dedup can reuse the exact same notion nt uses for notes.
Types ¶
type Cache ¶ added in v0.4.0
type Cache struct {
// contains filtered or unexported fields
}
Cache is an mtime-keyed parse cache for note files. List walks notes/ but only re-reads and re-parses files whose size or mtime changed since last time — turning a snapshot rebuild from "read+parse every note" into "stat every note, read+parse the few that changed". This is what lets the in-memory read-model scale to thousands of notes (a single edit no longer re-reads the whole store).
Returned *Note values are shared with the cache; the read-model treats them as read-only, so this is safe. Cache is safe for concurrent use.
type Note ¶
type Note struct {
Path string
Rel string // path relative to notes/ (slash-separated), set by List
ID string
Title string
Tags []string
Aliases []string
Source string
Created string
Updated string // stamped when nt rewrites the note (retag, --field)
Archived bool // frontmatter archived: true — retired from active views, still on disk
Favorite bool // frontmatter favorite: true — starred/pinned for quick access
// SupersededBy is the id of the note that replaces this one (frontmatter
// superseded_by:). A superseded note is dropped from active views like an
// archived one — so a resume sees the single canonical decision, not both
// forks — while the pointer preserves the trail.
SupersededBy string
// ModTime is the note file's last-modified time, set by List/Load/cache. It
// captures every change — including edits made outside nt (Obsidian, git) that
// never touch the `updated:` frontmatter — so "changed since T" is reliable.
ModTime time.Time
Body string
Extra []string // raw frontmatter lines for keys nt doesn't model (preserved verbatim)
}
Note is a parsed markdown note.
func Active ¶ added in v0.12.0
Active drops notes retired from the working set: archived notes and superseded ones (a superseded note has a newer canonical version, so views show only the current decision, not both forks).
func Create ¶
func Create(s *store.Store, title, body string, tags []string, source, folder string) (*Note, error)
Create builds and writes a new note, returning it. The body is prefixed with an H1 title when it doesn't already start with one. Create writes a new note. folder, when non-empty, is a slash-separated subfolder under notes/ (e.g. "work" or "work/auth"); it is created as needed. The filename is slugged from the title; the body and frontmatter are written by Save.
func FindSimilar ¶ added in v0.20.0
FindSimilar returns active, non-reserved notes that look like near-duplicates of a note with the given title and tags — a guard against concurrent forks (two agents independently recording the same decision). A candidate matches when it has the identical slug, OR it shares a tag AND its title word-set overlaps heavily (Jaccard ≥ 0.5). This is a cheap heuristic, not semantic dedup.
func Load ¶
Load parses a note file (frontmatter + body). Unknown frontmatter keys are ignored, not an error.
func (*Note) Description ¶ added in v0.20.0
List loads all notes in the store's notes directory, recursing into subfolders so an Obsidian-style nested vault works. Hidden dirs (.obsidian/, .trash/, .git/) and non-.md files are skipped. Each note's Rel (path relative to notes/, slash-separated) is set for link resolution; results are sorted by Rel for deterministic ordering. Active drops archived notes — the working set, for views/search that should hide retired notes. List itself returns everything (archived included) so link-rewriting and the archived view still see them. Description returns the note's one-line summary for index/stub views: its `description:` frontmatter if set (kept in Extra, since nt doesn't model the key), else the first non-heading body line. Clamped to a single line ≤max chars. This is the "one-sentence summary" granularity of progressive disclosure — what an agent reads to decide whether to open the full note.
func (*Note) Reserved ¶ added in v0.20.0
Reserved reports whether a note lives in a machine-managed folder that isn't part of the human/agent knowledge base — currently notes/__tasks__/, where nt files the detail bodies of split tasks. These are reachable by id/link but are kept out of the KB catalog (nt index) and search so they don't pollute it.