Documentation
¶
Overview ¶
Package notes implements the disk-backed notes subsystem ported from kgraph. Notes are Markdown files on disk (source of truth) with an optional YAML frontmatter block. An FTS5 index in the per-project SQLite database is maintained as a derived, rebuildable view.
Index ¶
- Constants
- Variables
- func Delete(notesDir, key string) error
- func EncodeFrontmatter(data map[string]any, body []byte) ([]byte, error)
- func ExtractWikilinks(body []byte) []string
- func ListKeys(notesDir string) ([]string, error)
- func ParseFrontmatter(raw []byte) (map[string]any, []byte, error)
- func Related(g *Graph, key string) []string
- func ValidateKey(key string) error
- func Watch(notesDir string, onChange func(key string)) (func(), error)
- func Write(notesDir string, n *Note) error
- type Edge
- type Graph
- type Note
- type NoteNode
- type TreeNode
Constants ¶
const MaxKeyLen = 512
MaxKeyLen caps note keys. Keeps paths well under filesystem limits even with the `.md` suffix and nested dirs. Phase-2 decision.
Variables ¶
var ErrInvalidKey = errors.New("invalid note key")
ErrInvalidKey is returned when a key contains path-traversal components, absolute path prefixes, null bytes, or exceeds MaxKeyLen.
var ErrNotFound = errors.New("note not found")
ErrNotFound is returned when a note key does not exist on disk.
Functions ¶
func EncodeFrontmatter ¶
EncodeFrontmatter emits `---\n<yaml>\n---\n<body>`. An empty map emits the body verbatim (no leading delimiter). Keys are sorted by yaml.v3's default encoder (alphabetical); kgraph's gray-matter also sorts, so round-trips are stable.
func ExtractWikilinks ¶
ExtractWikilinks returns the de-duplicated list of note keys referenced by `[[wikilink]]` or `[[wikilink|alias]]` occurrences in body, in the order of first appearance. Whitespace inside a target is preserved verbatim (Obsidian-style keys can contain spaces, though we normalize them to paths at the call site).
func ListKeys ¶
ListKeys is the cheap variant of List: it walks the tree once and returns keys only. Useful for the lean `GET /api/projects/.../notes` endpoint where frontmatter isn't needed.
func ParseFrontmatter ¶
ParseFrontmatter splits raw note bytes into a frontmatter map and a body. If the input does not begin with a `---` delimiter line the whole input is returned as the body with an empty map — this matches the kgraph gray-matter behavior (no frontmatter is not an error).
A body that happens to contain `---` on its own line elsewhere is preserved verbatim; only the FIRST delimiter pair is consumed.
func Related ¶
Related returns the set of note keys directly connected to `key`, in either direction (outlinks + backlinks). Self-links are deduped. The result is sorted for deterministic API output.
func ValidateKey ¶
ValidateKey enforces the invariants documented on ErrInvalidKey. Public so handlers can short-circuit on bad input before touching the filesystem.
func Watch ¶
Watch scans notesDir every second and fires onChange(key) whenever a `.md` file's mtime changes, a new `.md` file appears, or an existing one is removed. The returned `stop` func halts the background goroutine.
This is a polling watcher — chosen over fsnotify to keep the watcher dependency-free and cross-platform. kgraph uses fs.watch (Node), which is similarly coarse in practice; the 1-second cadence is adequate for the "re-index after a user edits a note in their IDE" use case.
Types ¶
type Graph ¶
Graph is the wikilink-derived relation between notes in a project.
func BuildGraph ¶
BuildGraph walks every note in notesDir, extracts wikilinks from the body, and returns the resulting node+edge graph. Edges may point to nonexistent targets (dangling wikilinks) — that is intentional, and matches kgraph's behavior.
type Note ¶
type Note struct {
Key string `json:"key"`
Content string `json:"content"`
Author string `json:"author,omitempty"`
Tags []string `json:"tags,omitempty"`
Frontmatter map[string]any `json:"frontmatter,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Note is the in-memory representation of a Markdown note.
Frontmatter is the raw YAML map; Author/Tags are convenience copies hoisted from common keys. Timestamps are derived from filesystem mtime on Read and from time.Now() on Write.
type NoteNode ¶
type NoteNode struct {
Key string `json:"key"`
Title string `json:"title"`
Folder string `json:"folder"`
Tags []string `json:"tags,omitempty"`
}
NoteNode is a lean projection of a Note for graph rendering.