GTK4 frontend for the Knot knowledge base application.
This project uses the same daemon-backed architecture as Knot:
┌─────────────┐ Unix Socket/JSON-RPC ┌─────────────┐
│ knotty │ ◄──────────────────────────► │ knotd │
│ (GTK4 UI) │ │ (daemon) │
└─────────────┘ └──────┬──────┘
│
┌──────┴──────┐
│ Vault/Notes │
│ (SQLite) │
└─────────────┘
- knotty: GTK4/libadwaita UI application
- knotd: daemon process that handles vault operations, search, graph, and settings
- Rust toolchain installed
knotdavailable on the machine you are developing against
# Build the GTK4 app
cargo build --release
# Or run directly
cargo run- Start a compatible
knotddaemon:
# Example: listen on the default XDG socket path
mkdir -p "$XDG_RUNTIME_DIR/knot"
knotd --vault /path/to/vault --listen-unix "$XDG_RUNTIME_DIR/knot/knotd.sock"- Run the GTK4 UI:
cd /path/to/knotty
cargo run# Use default socket path from XDG_RUNTIME_DIR
cargo run
# Specify custom socket path
cargo run -- --socket /path/to/custom.sock
# or
cargo run -- -s /path/to/custom.sock
# Use environment variable
KNOTD_SOCKET_PATH=/tmp/knotd.sock cargo runThe default socket path is determined in this priority:
--socketCLI argumentKNOTD_SOCKET_PATHenvironment variable$XDG_RUNTIME_DIR/knot/knotd.sock
If XDG_RUNTIME_DIR is unavailable, pass --socket or set KNOTD_SOCKET_PATH explicitly. The app does not guess a /run/user/<uid> fallback.
The GTK4 app integrates with knotd via JSON-RPC to provide:
get_vault_info()- Get current vault informationopen_vault(path)- Open a vaultcreate_vault(path)- Create and open a new vaultis_vault_open()- Check vault status
get_note(path)- Load note contentsave_note(path, content)- Save note changescreate_note(path, content)- Create new notedelete_note(path)- Delete a noterename_note(old_path, new_path)- Rename/move note
get_explorer_tree()- Get folder/note tree structureset_folder_expanded(path, expanded)- Persist folder statecreate_directory(path)- Create new folderrename_directory(old_path, new_path)- Rename folderremove_directory(path, recursive)- Delete folder
search_notes(query, limit)- Full-text search
get_graph_layout(width, height)- Get graph layout for visualizationgraph_neighbors(path, depth)- Get linked notes
get_vault_settings()- Read vault settingsupdate_vault_settings(patch)- Update settings
knotty/
├── Cargo.toml # Dependencies
├── src/
│ ├── main.rs # Application entry point
│ ├── client/
│ │ └── mod.rs # knotd JSON-RPC client
│ └── ui/
│ ├── mod.rs # UI module exports
│ ├── window.rs # Main window
│ ├── sidebar.rs # Notes list sidebar
│ └── editor.rs # Note editor
└── README.md
- 🪟 Modern GTK4/libadwaita UI - Native GNOME look and feel
- 🛤️ ToolRail - Switch between Notes, Search, and Graph modes
- 📑 ContextPanel - Shows notes list, search results, or graph controls
- 🔍 InspectorRail - Details and settings panel
- 📝 Note Editor - Full-featured markdown editing
- 🔌 Daemon Integration - Full JSON-RPC client for knotd
- 📚 Note Explorer - Browse folders and notes from vault
- 🔎 Live Search - Real-time search with suggestions
- ⚡ Lightweight - Minimal resource usage
| Shortcut | Action |
|---|---|
Ctrl+N |
New Note |
Ctrl+W |
Close |
F9 |
Toggle Sidebar |
Ctrl+Q |
Quit |
This repository includes local git gate scripts in scripts/ and repo-local hooks in .githooks/.
just pre-commit-gate: run the staged-work gatejust full-gate: run the strongest local gatejust verify: alias for the pre-commit gatejust install-hooks: configurecore.hooksPath=.githooksbash scripts/install-hooks.sh: install hooks withoutjust
The pre-commit gate checks:
- staged documentation evidence
CHANGELOG.mdpresence and Common Changelog structure- staged
CHANGELOG.mdupdates for staged implementation, tooling, hook, docs, and policy changes cargo fmt --checkcargo check- Rust tests
- property-test detection and reporting
- fuzz smoke run if a runnable harness exists
If staged changes include code or build files under src/, scripts/, .githooks/, Cargo.toml, Cargo.lock, build.rs, or justfile, then the commit must also stage documentation updates under docs/ or README.md.
If staged changes include src/, scripts/, .githooks/, Cargo.toml, Cargo.lock, build.rs, justfile, README.md, AGENTS.md, or docs/, then the commit must also stage an update to CHANGELOG.md in Common Changelog format.
Docs-only commits are allowed.
This repository maintains a root CHANGELOG.md using the Common Changelog standard.
- required heading:
# Changelog - allowed group headings:
Added,Changed,Fixed,Removed - update
CHANGELOG.mdfor any task-completion change in code, tooling, hooks, docs policy, or workflow - stage the changelog update in the same commit as the implementation or policy change
The full gate re-runs the pre-commit gate and then runs the strongest available local checks again:
- full Rust test suite
- property-test detection
- full fuzz run if a runnable harness exists
If a fuzz harness is detected but no runnable backend or target can be determined, the gate fails instead of claiming success.
MIT OR Apache-2.0 (same as Knot)