docs: rewrite README and update CHANGELOG for v0.2.0
This commit is contained in:
parent
8576cc83a2
commit
38bf1f75c8
2 changed files with 267 additions and 53 deletions
81
CHANGELOG.md
81
CHANGELOG.md
|
|
@ -1,26 +1,81 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to noz-cli are documented here.
|
All notable changes to noz-cli are documented here.
|
||||||
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) — versioning follows [Semantic Versioning](https://semver.org/).
|
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning: [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.2.0] — 2026-05-17
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
**REPL commands**
|
||||||
|
- `mv <old> <new>` — rename a note and atomically rewrite all inbound wikilinks and markdown links
|
||||||
|
- `mkdir <name>` — create a folder by writing a `_index.md`; navigates into the new folder immediately
|
||||||
|
- `link <source> <target>` — add a wikilink to the "Siehe auch" section (or create it); `--both` for bidirectional
|
||||||
|
- `search <query>` — full-text search via Meilisearch; context-aware (defaults to current topic); `--topic`, `--limit` flags
|
||||||
|
- `templates` — list available server-side note templates
|
||||||
|
- `new --template <name> <slug>` — create a note from a template with `{{title}}`, `{{date}}`, `{{topic}}` placeholders
|
||||||
|
- `cat --raw <slug>` — print raw markdown (default now renders via MarkdownRenderer)
|
||||||
|
- `clear` — clear the terminal screen
|
||||||
|
|
||||||
|
**PowerShell module**
|
||||||
|
- `Get-NozGraph` — all wikilink edges as `NozGraphEdge` objects; filterable by `-Source` / `-Target`
|
||||||
|
- `Find-NozNote` — Meilisearch full-text search; `-Topic`, `-Limit`
|
||||||
|
- `Measure-NozGarden` — garden-wide statistics: note counts by status/topic/lang, link count, orphan count
|
||||||
|
- `Set-NozNoteStatus` — patch the `status:` frontmatter field in place; `SupportsShouldProcess`
|
||||||
|
- `Get-NozOrphans` — notes with no incoming wikilinks; `-Topic` filter
|
||||||
|
- `Rename-NozNote` — wraps `NoteRenamer` for pipeline use; `-PassThru`, `-WhatIf`
|
||||||
|
- `Get-NozTemplate` — list server-side templates
|
||||||
|
- `Add-NozLink` — add wikilinks between notes; `-Both`, `-Section`
|
||||||
|
|
||||||
|
**Server API routes** (noz Next.js app)
|
||||||
|
- `GET /api/cli/graph` — full wikilink adjacency list from pre-built index
|
||||||
|
- `GET /api/cli/search` — Meilisearch / local-search with `?q`, `?topic`, `?limit`
|
||||||
|
- `PUT /api/cli/folders/[...path]` — create `_index.md` for a folder
|
||||||
|
- `GET /api/cli/templates` — list templates from `_templates/`
|
||||||
|
- `GET /api/cli/templates/[name]` — fetch a single template body
|
||||||
|
- `PUT /api/cli/templates/[name]` — create or update a template
|
||||||
|
|
||||||
|
**Core library**
|
||||||
|
- `NoteRenamer` — fetches inbound edges, creates new note, rewrites links, deletes old slug
|
||||||
|
- `NoteLinkHelper` — `AddLink()` inserts wikilinks into existing sections or appends new ones; `ApplyPlaceholders()` for template rendering
|
||||||
|
- `NozApiClient.GetGraphAsync()`, `SearchAsync()`, `GetTemplatesAsync()`, `GetTemplateAsync()`, `PutFolderIndexAsync()`
|
||||||
|
|
||||||
|
**Templates**
|
||||||
|
- Four sample templates in `content/noosphere/_templates/`: `rezept`, `buch-notiz`, `konzept`, `meeting`
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `walkNotes` now skips directories with `_` prefix (previously only filenames were checked — `_templates/` content was indexed as regular notes)
|
||||||
|
- Notes listing API now includes the `date` field
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [0.1.0] — 2026-05-16
|
## [0.1.0] — 2026-05-16
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Interactive REPL with topic-based navigation (`cd`, `ls`, `ls -la`, `tree`)
|
- Interactive REPL with topic-based navigation (`cd`, `ls`, `ls -la`, `tree`)
|
||||||
- `cat` — print raw markdown of a note
|
- `cat` — render a note with MarkdownRenderer (headings, blockquotes, code blocks, inline formatting)
|
||||||
- `edit` — open note in terminal editor (nano/vim) or VS Code (`-c` flag)
|
- `edit` — open note in terminal editor (nano/vim) or VS Code / Zed / Sublime (`-c`)
|
||||||
- `new` — create a new note from a template
|
- `new` — create a note with frontmatter template, open in editor
|
||||||
- `rm` — delete a note
|
- `rm` — delete a note from server
|
||||||
- `sync` — pull notes from server to local directory (parallel, hash-diffed)
|
- `sync` — pull notes from server to local directory (parallel downloads, SHA-256 hash diffing, `--all`, `--dry-run`)
|
||||||
- `push` — push local markdown files to server
|
- `push` — push local `.md` files to server with slug validation
|
||||||
- `search` — full-text search via Meilisearch
|
- `status` — diff between a local folder and the server
|
||||||
- `config` — view and set editor preferences
|
- `config` — view and set `editor` / `code_editor` preferences
|
||||||
- `version` — show version and git hash
|
- `version` — print version and git hash
|
||||||
- JSON note cache (`~/.cache/noz/notes.json`) for instant startup + background refresh
|
- `help` — list all commands with usage
|
||||||
- Cache timestamp displayed in startup stats line
|
- `exit` / `quit` / `q` — quit the REPL
|
||||||
|
- JSON note cache (`~/.cache/noz/notes.json`) — instant startup, background refresh, `chmod 600`, atomic write
|
||||||
|
- Cache age shown in startup stats line ("vor 5 Min.")
|
||||||
|
- Ctrl+C: idle → exit REPL; during command → cancel command only
|
||||||
- Native AOT binary for macOS arm64 (~7.6 MB, no runtime required)
|
- Native AOT binary for macOS arm64 (~7.6 MB, no runtime required)
|
||||||
- Tab completion for commands, slugs and folder segments
|
- Tab completion for commands, slugs, and folder segments
|
||||||
|
- `SlugGuard` — path traversal prevention for all slug inputs and file operations
|
||||||
|
- `MarkdownRenderer` — segment-based inline escaping (prevents Spectre markup injection from note content)
|
||||||
|
- PowerShell module `Noz` with `Get-NozNote`, `Get-NozNoteContent`, `Set-NozNote`, `New-NozNote`, `Remove-NozNote`
|
||||||
|
- xUnit test suite (52 tests): `SlugGuardTests`, `ReplContextTests`, `NotesCacheTests`, `NoteRenamerTests`, `NoteLinkHelperTests`
|
||||||
|
- Forgejo Actions CI pipeline (`.forgejo/workflows/ci.yml`): build + test on every push/PR
|
||||||
|
- Version string from `AssemblyInformationalVersion` with embedded git short hash
|
||||||
|
|
|
||||||
239
README.md
239
README.md
|
|
@ -1,79 +1,214 @@
|
||||||
# noz-cli
|
# noz-cli
|
||||||
|
|
||||||
A terminal REPL for [noz](https://github.com/kryptomrx/noz) — a self-hosted digital garden built with Next.js.
|
A terminal REPL and PowerShell module for [noz](https://git.kryptomrx.de/krypto/noz) — a self-hosted digital garden built with Next.js.
|
||||||
|
|
||||||
Navigate, read, and edit your notes from the command line. Native AOT binary, no .NET runtime required.
|
Navigate, create, and manage your notes from the command line. Ships as a Native AOT binary (~7.6 MB, no .NET runtime required) and a PowerShell module for scripting and automation.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
Download the latest binary from [Releases](../../releases) and place it on your PATH:
|
### macOS / Linux — binary
|
||||||
|
|
||||||
|
Download from [Releases](../../releases) and place on your PATH:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# macOS (Apple Silicon)
|
# macOS Apple Silicon
|
||||||
curl -L https://github.com/kryptomrx/noz-cli/releases/latest/download/noz-osx-arm64 -o /usr/local/bin/noz
|
curl -L https://git.kryptomrx.de/krypto/noz-cli/releases/latest/download/noz-osx-arm64 \
|
||||||
chmod +x /usr/local/bin/noz
|
-o /usr/local/bin/noz && chmod +x /usr/local/bin/noz
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### PowerShell module
|
||||||
|
|
||||||
|
Requires PowerShell 7.2+ and .NET 8.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://git.kryptomrx.de/krypto/noz-cli
|
||||||
|
cd noz-cli
|
||||||
|
./Noz.PowerShell/Install-NozModule.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
noz init https://your-noz-instance.com your-api-token
|
noz init https://your-noz-instance.com your-api-token
|
||||||
```
|
```
|
||||||
|
|
||||||
This writes `~/.config/noz/config.json`.
|
Writes `~/.config/noz/config.json`. The token is the CLI token configured in your `noosphere.toml` under `[cli]`.
|
||||||
|
|
||||||
## Usage
|
---
|
||||||
|
|
||||||
```
|
## REPL
|
||||||
|
|
||||||
|
```bash
|
||||||
noz
|
noz
|
||||||
```
|
```
|
||||||
|
|
||||||
Starts the interactive REPL. Type `help` for a list of commands.
|
Starts the interactive REPL. A local note cache (`~/.cache/noz/notes.json`) is used for instant startup; a background refresh runs silently.
|
||||||
|
|
||||||
### Navigation
|
### Navigation
|
||||||
|
|
||||||
```
|
| Command | Description |
|
||||||
~ » ls # list topics
|
|---------|-------------|
|
||||||
~ » cd psychologie # enter a topic
|
| `ls` | List topics (at root) or notes in the current folder |
|
||||||
~/psychologie » ls -la # detailed view with status, date, title
|
| `ls -la` | Detailed list with status, date, language |
|
||||||
~/psychologie » tree # full hierarchy as a tree
|
| `cd <topic>` | Enter a topic or sub-folder |
|
||||||
~/psychologie » cd .. # go up
|
| `cd ..` | Go up one level |
|
||||||
```
|
| `tree` | Full hierarchy as a tree |
|
||||||
|
|
||||||
### Notes
|
### Notes
|
||||||
|
|
||||||
```
|
| Command | Description |
|
||||||
~ » cat psychologie/flow-theorie # print raw markdown
|
|---------|-------------|
|
||||||
~ » edit flow-theorie # open in terminal editor
|
| `cat <slug>` | Print a note (rendered markdown) |
|
||||||
~ » edit -c flow-theorie # open in VS Code
|
| `cat --raw <slug>` | Print raw markdown |
|
||||||
~ » new meine-neue-notiz # create note from template
|
| `new <name>` | Create a note and open in editor |
|
||||||
~ » rm alte-notiz # delete a note
|
| `new -c <name>` | Create a note and open in VS Code |
|
||||||
```
|
| `new --template <name> <slug>` | Create from a template |
|
||||||
|
| `edit <slug>` | Edit a note in terminal editor |
|
||||||
|
| `edit -c <slug>` | Edit in VS Code |
|
||||||
|
| `mv <old> <new>` | Rename a note — rewrites all inbound wikilinks |
|
||||||
|
| `rm <slug>` | Delete a note |
|
||||||
|
| `search <query>` | Full-text search (Meilisearch) |
|
||||||
|
| `search <query> --topic <topic>` | Search within a topic |
|
||||||
|
|
||||||
|
### Folders
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `mkdir <name>` | Create a folder (writes `_index.md`, navigates in) |
|
||||||
|
|
||||||
|
### Linking
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `link <source> <target>` | Add a wikilink from source to target |
|
||||||
|
| `link <source> <target> --both` | Bidirectional link |
|
||||||
|
|
||||||
|
### Templates
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `templates` | List available templates |
|
||||||
|
| `new --template <name> <slug>` | Create a note from a template |
|
||||||
|
|
||||||
|
Templates live in `content/noosphere/_templates/<name>.md` on the server. Placeholders: `{{title}}`, `{{topic}}`, `{{date}}`, `{{status}}`, `{{lang}}`.
|
||||||
|
|
||||||
### Sync
|
### Sync
|
||||||
|
|
||||||
```
|
| Command | Description |
|
||||||
~ » sync ~/vault # pull changed notes to local folder
|
|---------|-------------|
|
||||||
~ » sync ~/vault --all # pull everything (ignore local hashes)
|
| `sync <local-path>` | Pull changed notes from server to local folder |
|
||||||
~ » sync ~/vault --dry-run # preview what would be downloaded
|
| `sync <local-path> --all` | Pull everything (ignore local hashes) |
|
||||||
~ » push ~/vault # push local .md files to server
|
| `sync <local-path> --dry-run` | Preview what would be downloaded |
|
||||||
```
|
| `push <local-path>` | Push local `.md` files to server |
|
||||||
|
| `status <local-path>` | Show diff between local folder and server |
|
||||||
|
|
||||||
### Other
|
### Other
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `version` | Show version and git hash |
|
||||||
|
| `config` | Show editor settings |
|
||||||
|
| `config editor <name>` | Set terminal editor |
|
||||||
|
| `config code-editor <name>` | Set GUI editor |
|
||||||
|
| `clear` | Clear the screen |
|
||||||
|
| `help` | List all commands |
|
||||||
|
| `exit` | Quit |
|
||||||
|
|
||||||
|
**Ctrl+C** while idle exits the REPL. During a command it cancels only that command.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PowerShell Module
|
||||||
|
|
||||||
|
After installing, import with:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Import-Module Noz
|
||||||
```
|
```
|
||||||
~ » version # show version + git hash
|
|
||||||
~ » config # show editor settings
|
### Note commands
|
||||||
~ » config editor nano # set terminal editor
|
|
||||||
~ » config code-editor code # set GUI editor
|
```powershell
|
||||||
~ » exit
|
# List and filter notes
|
||||||
|
Get-NozNote
|
||||||
|
Get-NozNote -Topic psychologie
|
||||||
|
Get-NozNote -Status evergreen
|
||||||
|
Get-NozNote -Lang de
|
||||||
|
|
||||||
|
# Read content
|
||||||
|
Get-NozNoteContent -Slug psychologie/flow-theorie
|
||||||
|
|
||||||
|
# Create / update / delete
|
||||||
|
New-NozNote -Slug kochen/pasta -Title "Pasta Carbonara" -Topic kochen
|
||||||
|
Set-NozNote -Slug psychologie/flow-theorie -Markdown $content
|
||||||
|
Remove-NozNote -Slug alte-notiz
|
||||||
|
|
||||||
|
# Rename (rewrites all inbound links)
|
||||||
|
Rename-NozNote -Slug psychologie/old -NewSlug psychologie/new
|
||||||
|
|
||||||
|
# Change status
|
||||||
|
Set-NozNoteStatus -Slug psychologie/flow-theorie -Status evergreen
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Search
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Find-NozNote "flow"
|
||||||
|
Find-NozNote "hydroponik" -Topic biosysteme -Limit 5
|
||||||
|
```
|
||||||
|
|
||||||
|
### Graph & analysis
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# All wikilink edges
|
||||||
|
Get-NozGraph
|
||||||
|
Get-NozGraph -Source psychologie/flow
|
||||||
|
|
||||||
|
# Notes with no incoming links
|
||||||
|
Get-NozOrphans
|
||||||
|
Get-NozOrphans -Topic psychologie
|
||||||
|
|
||||||
|
# Garden-wide statistics
|
||||||
|
Measure-NozGarden
|
||||||
|
|
||||||
|
# Link two notes
|
||||||
|
Add-NozLink -Source psychologie/flow -Target biosysteme/brs-konzept
|
||||||
|
Add-NozLink -Source a -Target b -Both
|
||||||
|
```
|
||||||
|
|
||||||
|
### Templates
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Get-NozTemplate
|
||||||
|
Get-NozTemplate rezept
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pipeline examples
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Promote all seed notes in a topic to budding
|
||||||
|
Get-NozNote -Topic psychologie -Status seed |
|
||||||
|
Set-NozNoteStatus -Status budding -WhatIf
|
||||||
|
|
||||||
|
# Export all evergreen notes as markdown files
|
||||||
|
Get-NozNote -Status evergreen |
|
||||||
|
ForEach-Object { Get-NozNoteContent $_.Slug } |
|
||||||
|
ForEach-Object { Set-Content "$($_.Slug).md" $_.Markdown }
|
||||||
|
|
||||||
|
# Find orphans and link them to a topic overview
|
||||||
|
Get-NozOrphans -Topic biosysteme |
|
||||||
|
Add-NozLink -Target biosysteme/uebersicht
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Editor preferences are stored in `~/.config/noz/config.json`:
|
`~/.config/noz/config.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -84,19 +219,41 @@ Editor preferences are stored in `~/.config/noz/config.json`:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Editor is auto-detected from `$EDITOR` if not set. VS Code, Zed, and Sublime Text are detected automatically for `-c` mode.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Server-side setup
|
||||||
|
|
||||||
|
The CLI needs the `[cli]` block in your `noosphere.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[cli]
|
||||||
|
token = "your-secret-token"
|
||||||
|
allow_push = true
|
||||||
|
allow_delete = true
|
||||||
|
allow_vault = false
|
||||||
|
allow_rebuild = false
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Building from source
|
## Building from source
|
||||||
|
|
||||||
Requires [.NET 10 SDK](https://dotnet.microsoft.com/download) and `clang`.
|
Requires [.NET 10 SDK](https://dotnet.microsoft.com/download) and `clang`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/kryptomrx/noz-cli
|
git clone https://git.kryptomrx.de/krypto/noz-cli
|
||||||
cd noz-cli
|
cd noz-cli
|
||||||
|
|
||||||
# Run (no AOT)
|
# Run without AOT
|
||||||
dotnet run --project NozCli
|
dotnet run --project NozCli
|
||||||
|
|
||||||
# Native AOT binary (macOS arm64)
|
# Native AOT binary — macOS Apple Silicon
|
||||||
dotnet publish NozCli/NozCli.csproj -r osx-arm64 -c Release
|
dotnet publish NozCli/NozCli.csproj -r osx-arm64 -c Release
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
dotnet test NozCli.Tests/NozCli.Tests.csproj -c Release
|
||||||
```
|
```
|
||||||
|
|
||||||
On macOS, AOT linking requires OpenSSL via Homebrew:
|
On macOS, AOT linking requires OpenSSL via Homebrew:
|
||||||
|
|
@ -105,7 +262,9 @@ On macOS, AOT linking requires OpenSSL via Homebrew:
|
||||||
brew install openssl
|
brew install openssl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[Polyform Noncommercial 1.0.0](LICENSE) — free for personal and non-commercial use.
|
[Polyform Noncommercial 1.0.0](LICENSE) — free for personal and non-commercial use.
|
||||||
For commercial licensing, contact [Bruno Deanoz](mailto:bruno.deanoz1@gmail.com).
|
Commercial licensing: [bruno.deanoz1@gmail.com](mailto:bruno.deanoz1@gmail.com).
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue