6.3 KiB
6.3 KiB
Personal Knowledge Manager (PKM) — Concrete Backlog
Scope for v1 (agreed)
- Single vault folder on disk (user-provided path).
- Files are Markdown with YAML front matter; Obsidian-compatible (front matter, WikiLinks, relative links, optional inline #tags).
- Flask backend; Tailwind + DaisyUI frontend; server-rendered pages with light JS.
- CodeMirror 6 editor from the start.
- Search/index via SQLite FTS5 stored under .kb/index.sqlite within the vault.
- No Git versioning and no graph view in v1 (reserved for later).
Non-goals for v1
- Multi-user auth, sync, remote deployment concerns.
- Git auto-commit/history UI.
- Graph visualization.
- Plugin system.
Definitions and conventions
- Note file naming: slugified from title, e.g.,
notes/event-sourcing-overview.md
. - Front matter includes: id (UUID), title, created, updated; optional aliases, tags, status, summary, template.
- Backlinks stored in index (not written into files).
- WikiLinks resolve by title/alias/slug; Markdown links preserved and resolved relatively.
- Vault internals live under
<vault>/.kb/
(SQLite index, config, cache).
Milestone 0 — Project scaffolding
- Tasks
- Initialize Flask app scaffolding and configuration.
- Tailwind + DaisyUI build pipeline via Tailwind CLI.
- Base Jinja templates and minimal layout with DaisyUI theme.
- Environment/config management (vault path, debug).
- Acceptance criteria
- App starts with
flask run
(or apython -m
entrypoint). - Tailwind builds and serves CSS; DaisyUI classes render correctly.
- Config reads vault path from env/config and shows a welcome page.
- App starts with
Milestone 1 — Vault and note model
- Tasks
- Filesystem repository for notes (read/write Markdown + YAML front matter).
- Create new note with required metadata; slugify filenames from
title
. - Validate and normalize metadata (UUID, ISO timestamps).
- Resolve note identity by
id
independent of filename changes.
- Acceptance criteria
- Can create a note; it is saved to disk with valid front matter.
- Can read an existing note and get parsed metadata + body.
- Tests for slug generation and metadata normalization.
Milestone 2 — Rendering and viewing
- Tasks
- Markdown rendering via markdown-it-py with plugins (tables, task lists, footnotes, admonitions).
- HTML sanitization (bleach) with a safe allowlist.
- Obsidian-compatible rendering: WikiLinks clickable, resolve to note routes; render relative links and attachments; optionally parse inline #tags.
- Basic note view page: title, metadata pills (tags/status), content, attachments preview.
- Acceptance criteria
- Visiting a note route renders sanitized HTML.
- WikiLinks and relative links resolve; unknown links are indicated.
- Attachment links/images load from the vault.
Milestone 3 — Editor with CodeMirror 6
- Tasks
- Note edit page using CodeMirror 6 (Markdown extensions, basic shortcuts).
- Front matter editor (simple form for title/tags/status; syncs with file).
- Save flow: update
updated
; create if new; optimistic UI. - Drag-and-drop/paste image => save under
attachments/
and insert relative path.
- Acceptance criteria
- Can create, edit, and save notes from the browser.
- Pasting/dragging an image adds a file and inserts a link.
- Title change updates slug/filename on save (see Milestone 6 for link rewrites).
Milestone 4 — Indexing and search (SQLite FTS5)
- Tasks
- SQLite schema under
<vault>/.kb/index.sqlite
. - Initial indexing pass: ingest existing notes (title, body, tags, path, id).
- File watching (watchdog) for incremental index updates on add/edit/delete/rename.
- Search API with filters (q=, tag=, status=, path=) and boosting (title > tags > body).
- Search UI with instant results (debounced) and simple filters.
- SQLite schema under
- Acceptance criteria
- Searching returns relevant notes quickly.
- Edits trigger index updates without manual rebuild.
- Tag list and per-tag results available.
Milestone 5 — Links and backlinks
- Tasks
- Outbound link extraction (Markdown links + WikiLinks); store in index.
- Backlinks computation and storage; display backlinks in note view.
- Handle aliases/title collisions deterministically (id/slug precedence).
- Acceptance criteria
- Each note shows backlinks (with context snippet if available).
- Creating a link updates backlinks after save.
Milestone 6 — Rename/move and link maintenance
- Tasks
- Rename/move note (on title or folder change): update slug/path on disk.
- Inbound link rewrite: update Markdown files that link to the old path/slug.
- Safe operations (backup to temp, atomic writes) and dry-run option (internal).
- Acceptance criteria
- Renaming a note updates its filename and maintains working links in other notes.
- Index reflects new paths; no broken links in backlinking notes.
Milestone 7 — UX polish
- Tasks
- Command palette / quick open (fuzzy search) and keyboard shortcuts.
- DaisyUI theme switch (light/dark/system) and remember preference.
- Empty states, loading states, toasts for save operations.
- Acceptance criteria
- Keyboard-driven navigation works end-to-end.
- Theme switch persists and is applied.
Milestone 8 — Packaging and quality
- Tasks
- CLI launcher:
pkm run --vault /path/to/vault
(orpython -m pkm
). - Basic error pages and diagnostics (e.g., FTS5 availability, permission errors).
- Unit tests for core services (parsing, indexing, link rewrite).
- Minimal Dockerfile (optional) for local use with volume mount.
- CLI launcher:
- Acceptance criteria
- One-command startup with vault path.
- Tests for core logic pass in CI (if configured).
Deferred items (post-v1)
- Git auto-commit/history and diffs.
- Graph view.
- Auth for remote hosting.
- Templates/daily notes generator; import/export UI; plugin hooks.
Risks and mitigations
- FTS5 availability: detect and warn at startup; fall back to basic search read-path if unavailable (optional).
- Large vault performance: chunked indexing, debounced file watcher, background tasks with status UI.
- Link rewrite safety: transactional writes with backups; verify before replace.
flowchart LR
A[Vault] -->|Parse| B[Note Model]
B --> C[Render Markdown]
B --> D[Index FTS5]
D --> E[Search API/UI]
B --> F[Link Extract]
F --> G[Backlinks]
B --> H[Editor (CM6)]
H -->|Save| A
H -->|Save| D
H -->|Save| F