5.3 KiB
PKM — Flask + Tailwind (v4) + DaisyUI (v5)
Personal Knowledge Manager with file-first storage (Markdown + YAML front matter), a minimal Flask backend, and a clean Tailwind + DaisyUI UI.
Current milestone: M2 (Rendering and viewing)
- Filesystem vault with
notes/
,attachments/
, and.kb/
- Create and list notes (M1)
- Render Markdown safely with plugins and sanitization (M2)
- Obsidian-compatible WikiLinks (
[[Note]]
,[[Note|Alias]]
,[[Note#Heading]]
) - Attachment serving from
/attachments/...
Upcoming (M3)
- CodeMirror 6 editor, front matter form, paste/drag image upload
Prerequisites
- Python 3.9+
- Node.js 18+
- SQLite (FTS5 needed later in M4; not required yet)
Setup (Python)
Create and activate a virtual environment:
python3 -m venv .venv
# macOS/Linux
source .venv/bin/activate
# Windows PowerShell
# .venv\Scripts\Activate.ps1
Install Python dependencies:
python3 -m pip install -r requirements.txt
# or, if you prefer editable install:
python3 -m pip install -e .
(Optional) For tests:
python3 -m pip install -e .[dev]
Setup (CSS build with Tailwind v4 + DaisyUI v5)
Install Node dev dependencies (uses the Tailwind v4 CLI package):
npm install
Build CSS once:
npm run build:css
Or keep a watcher running during development:
npm run watch:css
This repository uses:
tailwind.config.js
(ESM) with DaisyUI pluginapp/static/css/input.css
with:@import "tailwindcss";
@plugin "daisyui";
If the page looks unstyled, see Troubleshooting below.
Configure your vault
You can configure the vault in either of two ways:
- Environment file
- Copy
.env.example
to.env
and setKB_VAULT_PATH
to an absolute path. - You can also set
SECRET_KEY
andFLASK_DEBUG
.
cp .env.example .env
# edit .env to set KB_VAULT_PATH=/absolute/path/to/your/vault
- CLI flags
- Pass
--vault /path/to/vault
when running the app (takes precedence over env).
Initialize a vault (optional but recommended)
This creates the standard layout and a sample “Welcome” note:
python3 cli.py init --vault /absolute/path/to/vault
# Options:
# --no-sample Skip creating the sample note
# --force Proceed even if the directory is not empty
The vault structure will be:
<vault>/
├─ notes/
├─ attachments/
└─ .kb/
├─ config.yml
└─ (index.sqlite will be added in M4)
Run the app
Using the provided CLI (explicit python3):
python3 cli.py run --vault /absolute/path/to/vault
# Options:
# --host 127.0.0.1
# --port 5000
# --debug/--no-debug
Or, if you set KB_VAULT_PATH
in .env
:
python3 cli.py run
Open the app at:
http://127.0.0.1:5000/
You can:
- Create a note at “New Note”
- View “Notes” to list them
- Use
[[WikiLinks]]
between notes - Reference attachments via
attachments/<filename>
(served from/attachments/...
)
Tests
python3 -m pip install -e .[dev]
python3 -m pytest
Troubleshooting (Tailwind/DaisyUI v4)
Symptoms: CSS is loaded but the page is unstyled or missing DaisyUI components.
Checklist:
- Ensure Tailwind v4 CLI is used via npm scripts:
npm run build:css
(usesnpx @tailwindcss/cli
under the hood as configured)
- Confirm ESM config is in place and unique:
- Keep only
tailwind.config.js
(remove anytailwind.config.cjs
)
- Keep only
- Confirm input CSS contains:
@import "tailwindcss";
@plugin "daisyui";
- Verify template scan globs match your files:
content: ["./app/templates/**/*.html", "./app/static/js/**/*.js"]
- Rebuild:
rm -f app/static/css/app.css && npm run build:css
- Check built CSS for DaisyUI classes:
grep -n "btn" app/static/css/app.css
If your shell resolves a Ruby tailwindcss
gem, always invoke via npm scripts (or npx @tailwindcss/cli
) to ensure the Node CLI runs.
Security notes
- Rendered HTML is sanitized with
bleach
; external links are made safe. - Attachments are served with path traversal protection.
- For local use, no authentication is enabled yet (planned later if remote hosting is needed).
Project structure (high level)
app/
__init__.py # Flask app factory
config.py # Env/.env config
routes/
home.py # Welcome page
notes.py # Notes list/view/create
attachments.py # Safe serving of attachments
services/
vault.py # Vault paths and structure
notes_fs.py # Markdown + YAML read/write
renderer.py # Markdown rendering + sanitization + wikilinks
utils/
slugs.py # Slug generation
time.py # ISO timestamp helpers
paths.py # Atomic write & path utilities
templates/
... # Jinja templates (DaisyUI)
static/
css/input.css # Tailwind v4 entry (import + plugin)
css/app.css # Built output (gitignored)
js/app.js # Theme toggle, small helpers
cli.py # CLI: init vault, run server
Roadmap
- M3: CodeMirror 6 editor, metadata edit form, image paste/drag to
attachments/
. - M4: Indexing/search with SQLite FTS5 under
<vault>/.kb/index.sqlite
. - Later: Renames + link rewrites, Git history, command palette, etc.