From 38bf1f75c8982005b14d62165e119d647d37b691 Mon Sep 17 00:00:00 2001 From: kryptomrx Date: Sun, 17 May 2026 00:38:19 +0200 Subject: [PATCH] docs: rewrite README and update CHANGELOG for v0.2.0 --- CHANGELOG.md | 81 ++++++++++++++--- README.md | 239 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 267 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9e4029..eee8455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,26 +1,81 @@ # Changelog 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] +## [0.2.0] — 2026-05-17 + +### Added + +**REPL commands** +- `mv ` — rename a note and atomically rewrite all inbound wikilinks and markdown links +- `mkdir ` — create a folder by writing a `_index.md`; navigates into the new folder immediately +- `link ` — add a wikilink to the "Siehe auch" section (or create it); `--both` for bidirectional +- `search ` — full-text search via Meilisearch; context-aware (defaults to current topic); `--topic`, `--limit` flags +- `templates` — list available server-side note templates +- `new --template ` — create a note from a template with `{{title}}`, `{{date}}`, `{{topic}}` placeholders +- `cat --raw ` — 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 ### Added - Interactive REPL with topic-based navigation (`cd`, `ls`, `ls -la`, `tree`) -- `cat` — print raw markdown of a note -- `edit` — open note in terminal editor (nano/vim) or VS Code (`-c` flag) -- `new` — create a new note from a template -- `rm` — delete a note -- `sync` — pull notes from server to local directory (parallel, hash-diffed) -- `push` — push local markdown files to server -- `search` — full-text search via Meilisearch -- `config` — view and set editor preferences -- `version` — show version and git hash -- JSON note cache (`~/.cache/noz/notes.json`) for instant startup + background refresh -- Cache timestamp displayed in startup stats line +- `cat` — render a note with MarkdownRenderer (headings, blockquotes, code blocks, inline formatting) +- `edit` — open note in terminal editor (nano/vim) or VS Code / Zed / Sublime (`-c`) +- `new` — create a note with frontmatter template, open in editor +- `rm` — delete a note from server +- `sync` — pull notes from server to local directory (parallel downloads, SHA-256 hash diffing, `--all`, `--dry-run`) +- `push` — push local `.md` files to server with slug validation +- `status` — diff between a local folder and the server +- `config` — view and set `editor` / `code_editor` preferences +- `version` — print version and git hash +- `help` — list all commands with usage +- `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) -- 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 diff --git a/README.md b/README.md index 80d5cdf..af7751a 100644 --- a/README.md +++ b/README.md @@ -1,79 +1,214 @@ # 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 -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 -# macOS (Apple Silicon) -curl -L https://github.com/kryptomrx/noz-cli/releases/latest/download/noz-osx-arm64 -o /usr/local/bin/noz -chmod +x /usr/local/bin/noz +# macOS Apple Silicon +curl -L https://git.kryptomrx.de/krypto/noz-cli/releases/latest/download/noz-osx-arm64 \ + -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 ```bash 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 ``` -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 -``` -~ » ls # list topics -~ » cd psychologie # enter a topic -~/psychologie » ls -la # detailed view with status, date, title -~/psychologie » tree # full hierarchy as a tree -~/psychologie » cd .. # go up -``` +| Command | Description | +|---------|-------------| +| `ls` | List topics (at root) or notes in the current folder | +| `ls -la` | Detailed list with status, date, language | +| `cd ` | Enter a topic or sub-folder | +| `cd ..` | Go up one level | +| `tree` | Full hierarchy as a tree | ### Notes -``` -~ » cat psychologie/flow-theorie # print raw markdown -~ » edit flow-theorie # open in terminal editor -~ » edit -c flow-theorie # open in VS Code -~ » new meine-neue-notiz # create note from template -~ » rm alte-notiz # delete a note -``` +| Command | Description | +|---------|-------------| +| `cat ` | Print a note (rendered markdown) | +| `cat --raw ` | Print raw markdown | +| `new ` | Create a note and open in editor | +| `new -c ` | Create a note and open in VS Code | +| `new --template ` | Create from a template | +| `edit ` | Edit a note in terminal editor | +| `edit -c ` | Edit in VS Code | +| `mv ` | Rename a note — rewrites all inbound wikilinks | +| `rm ` | Delete a note | +| `search ` | Full-text search (Meilisearch) | +| `search --topic ` | Search within a topic | + +### Folders + +| Command | Description | +|---------|-------------| +| `mkdir ` | Create a folder (writes `_index.md`, navigates in) | + +### Linking + +| Command | Description | +|---------|-------------| +| `link ` | Add a wikilink from source to target | +| `link --both` | Bidirectional link | + +### Templates + +| Command | Description | +|---------|-------------| +| `templates` | List available templates | +| `new --template ` | Create a note from a template | + +Templates live in `content/noosphere/_templates/.md` on the server. Placeholders: `{{title}}`, `{{topic}}`, `{{date}}`, `{{status}}`, `{{lang}}`. ### Sync -``` -~ » sync ~/vault # pull changed notes to local folder -~ » sync ~/vault --all # pull everything (ignore local hashes) -~ » sync ~/vault --dry-run # preview what would be downloaded -~ » push ~/vault # push local .md files to server -``` +| Command | Description | +|---------|-------------| +| `sync ` | Pull changed notes from server to local folder | +| `sync --all` | Pull everything (ignore local hashes) | +| `sync --dry-run` | Preview what would be downloaded | +| `push ` | Push local `.md` files to server | +| `status ` | Show diff between local folder and server | ### Other +| Command | Description | +|---------|-------------| +| `version` | Show version and git hash | +| `config` | Show editor settings | +| `config editor ` | Set terminal editor | +| `config code-editor ` | 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 -~ » config editor nano # set terminal editor -~ » config code-editor code # set GUI editor -~ » exit + +### Note commands + +```powershell +# 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 -Editor preferences are stored in `~/.config/noz/config.json`: +`~/.config/noz/config.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 Requires [.NET 10 SDK](https://dotnet.microsoft.com/download) and `clang`. ```bash -git clone https://github.com/kryptomrx/noz-cli +git clone https://git.kryptomrx.de/krypto/noz-cli cd noz-cli -# Run (no AOT) +# Run without AOT 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 + +# Run tests +dotnet test NozCli.Tests/NozCli.Tests.csproj -c Release ``` On macOS, AOT linking requires OpenSSL via Homebrew: @@ -105,7 +262,9 @@ On macOS, AOT linking requires OpenSSL via Homebrew: brew install openssl ``` +--- + ## License [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).