Strea.md is a personal knowledge management and time-tracking CLI tool
  • Rust 96.2%
  • Nix 3.8%
Find a file
Konstantin Fickel 287cda9e6c
All checks were successful
Release / Build and Release (push) Successful in 5s
Continuous Integration / Build Package (push) Successful in 1m46s
Continuous Integration / Lint, Check & Test (push) Successful in 34s
bump: v0.9.0
Claude-Session: https://claude.ai/code/session_01JcPkMor6cBCXyEXEWGZufw
2026-09-17 18:04:13 +02:00
.forgejo/workflows ci: pass the release version through the environment 2026-09-12 15:10:00 +02:00
.vscode chore: improve dev setup 2025-06-22 12:52:15 +02:00
src fix(lsp): start task diagnostic ranges after line indentation 2026-09-17 18:04:06 +02:00
zed-extension fix(deps): update rust crate sha2 to 0.11 2026-09-13 00:07:37 +00:00
.envrc refactor: rewrite in rust 2026-03-29 18:28:03 +02:00
.gitignore feat(zed-extension): verify the downloaded language server 2026-09-12 15:10:13 +02:00
Cargo.lock bump: v0.9.0 2026-09-17 18:04:13 +02:00
Cargo.toml bump: v0.9.0 2026-09-17 18:04:13 +02:00
CLAUDE.md fix: clippy warnings 2026-04-07 13:43:40 +02:00
flake.lock chore(deps): lock file maintenance 2026-08-10 00:09:41 +00:00
flake.nix feat(zed-extension): verify the downloaded language server 2026-09-12 15:10:13 +02:00
LICENSE.md docs: license under AGPL 2025-10-12 11:19:03 +02:00
README.md fix(config): honour STREAMD_BASE_FOLDER as documented in R23 2026-09-14 13:46:22 +02:00
renovate.json ci: allow major upgrades from renovate 2026-01-18 17:42:16 +01:00
REQUIREMENTS.md fix(extract): end tags at punctuation other than hyphen, underscore and inner dots 2026-09-14 19:22:01 +02:00
streamd.svg feat: add streamd logo 2026-02-15 17:40:17 +01:00

strea.md

The Strea.md-Logo: A tag on an endless paper roll

Strea.md is a personal knowledge management and time-tracking CLI tool. It organizes time-ordered markdown files using @tag annotations, letting you manage tasks, track time, and query your notes from the terminal.

Installation

Debian/Ubuntu (.deb package)

Download and install the latest release:

wget https://git.konstantinfickel.de/kfickel/streamd/releases/download/vX.Y.Z/streamd_X.Y.Z_amd64.deb
sudo dpkg -i streamd_X.Y.Z_amd64.deb

This includes shell completions for bash, zsh, and fish.

Static Binary

Download the statically-linked binary:

wget https://git.konstantinfickel.de/kfickel/streamd/releases/download/vX.Y.Z/streamd-X.Y.Z-linux-x86_64
chmod +x streamd-X.Y.Z-linux-x86_64
sudo mv streamd-X.Y.Z-linux-x86_64 /usr/local/bin/streamd

Nix

Using the flake directly:

nix run git+https://git.konstantinfickel.de/kfickel/streamd

Or add to your NixOS/Home Manager configuration using the provided homeManagerModules.default.

Core Concepts

  • Shards — Sections of markdown files, organized hierarchically by headings. Each shard can contain markers, tags, and nested child shards.
  • Markers — Special @tags like @Task, @Done, @Waiting, or @Timesheet that give shards semantic meaning and place them into dimensions.
  • Dimensions — Classification axes (e.g. task state, project, timesheet) that categorize shards. Some dimensions propagate to child shards.

File Format

Markdown files are named with a timestamp: YYYYMMDD-HHMMSS [markers].md

For example: 20260131-210000 Task Streamd.md

An optional _file_type segment can follow the timestamp to classify the file:

YYYYMMDD-HHMMSS_<file_type> [markers].md

For example: 20260413-083000_daily.md — the daily prefix is stored as the file_type dimension and propagates to all child shards.

Within files, @-prefixed markers at the beginning of paragraphs or headings define how a shard is categorized.

Commands

  • streamd / streamd new — Create a new timestamped markdown entry, opening your editor
  • streamd daily [YYYYMMDD] — Open today's daily file (or create it if missing); pass a date to open that day's file instead
  • streamd todo — Show all open tasks (shards with @Task markers), numbered for easy reference
  • streamd todo N edit — Edit task N in your editor, jumping to the task's line
  • streamd todo N done — Mark task N as done by inserting @Done after @Task
  • streamd todo --show-future — Include tasks with future dates in the listing
  • streamd edit [number] — Edit a stream file by position (1 = most recent, -1 = oldest)
  • streamd timesheet — Generate time reports from @Timesheet markers
  • streamd tags — List every tag and marker used anywhere in the stream (subfolders included), alphabetically
  • streamd lsp — Start the LSP server (stdin/stdout transport; see Editor Integration below)
  • streamd cache — Show the local cache's location, size and contents (see Local Cache below)
  • streamd cache rebuild — Discard the cache and reindex the corpus from scratch
  • streamd cache clear — Delete the cache

Configuration

User Configuration

Streamd reads its user configuration from ~/.config/streamd/config.toml (XDG standard). The main setting is base_folder, which points to the directory containing your stream files (defaults to the current working directory).

Set STREAMD_BASE_FOLDER to use a different stream folder for one invocation. A non-empty value takes precedence over config.toml, which is then not read at all:

STREAMD_BASE_FOLDER=~/work-notes streamd todo

Repository Configuration

For timesheet reporting, create a .streamd.toml file in your stream files directory:

timezone = "Europe/Berlin"  # Optional: timezone for day boundaries

[timesheet]
[[timesheet.periods]]
start = "2026-01-01"
end = "2026-06-30"
hours_per_week = 38.0

[[timesheet.periods]]
start = "2026-07-01"
end = "2026-12-31"
hours_per_week = 40.0

The timesheet command will calculate expected vs actual working hours based on these periods, showing:

  • Daily breakdown with expected/actual hours
  • Special day types (sick leave, vacation, holidays, flex days)
  • Warnings for missing entries and overlapping timecards
  • Monthly and cumulative balance

Usage

Running streamd opens your editor to create a new entry. After saving, the file is renamed based on its timestamp and any markers found in the content.

Running streamd todo finds all shards marked as open tasks and displays them numbered in your terminal. Tasks with future dates are hidden by default (use --show-future to include them). Tasks are sorted by date with oldest first (task 1 is the oldest).

You can quickly edit or complete tasks by number:

  • streamd todo 1 edit opens task 1 in your editor at the correct line
  • streamd todo 1 done marks task 1 as done by inserting @Done after @Task

Local Cache

Streamd keeps a local cache of parsed stream files in an embedded graph database. Commands validate it with stat alone — comparing each file's size and modification time — and re-read only the files that actually changed.

On a local disk this makes little difference; parsing a few hundred small markdown files is already fast. It matters when the stream folder lives on a network-backed or synced share (OneDrive on WSL, for example), where opening each file is far more expensive than checking its metadata.

Location

Caches live under your XDG cache directory, not beside your notes:

~/.cache/streamd/<folder-name>-<hash>.grafeo

Each stream folder gets its own database, keyed by a hash of the folder's canonical path. Several streamd instances with different config.toml files therefore never share a cache, and two folders that happen to have the same name do not collide. Nothing is written into your stream folder, so there is nothing to add to .gitignore and nothing to exclude from file sync.

Set STREAMD_CACHE_DIR to override the location:

STREAMD_CACHE_DIR=/fast/local/disk streamd todo

On the rare platform that offers no cache directory at all, streamd does not guess one — it skips the cache and reads your markdown directly. Set STREAMD_CACHE_DIR to get the cache back.

Behaviour

The cache is derived state and never authoritative. It is rebuilt from your markdown whenever it is missing, corrupt, or written by a different schema version, and any failure to use it — including another process holding it open — silently falls back to reading the files directly. Deleting it is always safe.

streamd cache            # where it is, how big, how many files, whether a graph projection exists
streamd cache rebuild    # discard and reindex, including the graph projection
streamd cache clear      # delete it

Set STREAMD_NO_CACHE=1 to bypass it entirely for one invocation:

STREAMD_NO_CACHE=1 streamd todo

Graph queries

Beyond caching, streamd cache rebuild builds a projection layer that models tags, dimension values and calendar days as first-class graph nodes. This makes questions that previously required walking every shard of every file into single-hop traversals — which tags co-occur, how many shards sit in each project or task state, which files contribute to a given day. These are available in the library API (streamd::cache::query).

streamd tags and the LSP's @ completions read the list of used tags and markers from this projection. They rebuild it on demand whenever a file changed since it was last built, so there is no need to run streamd cache rebuild first.

Editor Integration

streamd lsp starts a Language Server Protocol server that provides IDE features for your stream markdown files. The server communicates over stdin/stdout and auto-activates only when a .streamd.toml file is present in the workspace root.

Features

Feature Description
@ completions Suggests known markers from your config, then every tag and marker already used anywhere in the workspace; conditional suggestions (e.g. @Done when @Task is on the line) come first. Newly used names become suggestible as soon as the file is saved
Temporal snippets @ followed by a digit offers YYYYMMDD / HHMMSS format snippets
Diagnostics File-name format warnings (R15); timesheet errors (overlapping timecards, unclosed days)
Workspace todo diagnostics Every open/waiting @Task across all .md files in the workspace (not just open buffers) is reported as an Information-severity diagnostic via LSP 3.17 pull diagnostics (textDocument/diagnostic, workspace/diagnostic) — shows up in Zed's diagnostics: deploy panel as a global todo list, and refreshes automatically on save or external file changes
Document symbols Shard tree exposed as outline symbols
"Mark task as done" Quick-fix code action: inserts @Done after @Task
Workspace symbols Search shards across all .md files; open/waiting todos are additionally indexed by their own text so they're findable by content
References Find all occurrences of an @Marker across the workspace
Rename Rename an @Marker across all files

Zed

Install the streamd Zed extension — it's the only supported way to get streamd running in Zed. It works for local Windows and Linux Zed, and for Zed Remote Development (SSH or WSL2 remotes) — the extension runs the wasm inside whichever host Zed is talking to and downloads the matching binary there automatically.

Once the extension is installed, no settings.json changes are needed: extension.toml already declares languages = ["Markdown"], so Zed registers the streamd language server for Markdown files on its own.

If you want to point Zed at a specific streamd binary instead of letting the extension resolve one from PATH (or download it), add to ~/.config/zed/settings.json:

{
  "lsp": {
    "streamd": {
      "binary": {
        "path": "streamd",
        "arguments": ["lsp"]
      }
    }
  }
}

This only overrides which binary the already-registered streamd adapter launches — it does not register the server by itself, so it's only useful with the extension installed.

Zed Extension

The extension resolves the language server binary in this order:

  1. An existing streamd already on PATH (e.g. installed via Nix, apt, or cargo install) is used as-is.
  2. Otherwise, it downloads the matching prebuilt binary for the current platform (Linux x86_64 or Windows x86_64) from the releases page into Zed's private extension directory, and reuses it on subsequent starts.

macOS and non-x86_64 platforms: no prebuilt binary is published yet. Install streamd manually and make sure it's on PATH — otherwise Zed will show a clear "no precompiled binary available" error instead of starting the language server.

1. Download the extension from the releases page:

streamd-zed-extension-X.Y.Z.zip

2. Extract the zip to a permanent folder, e.g. C:\Users\<you>\zed-extensions\streamd-zed-extension\ on Windows or ~/zed-extensions/streamd-zed-extension/ on Linux:

The folder must contain extension.toml and extension.wasm.

3. Install the extension in Zed via the command palette (Ctrl+Shift+P):

zed: install dev extension

Point Zed to the extracted folder. For Remote Development, install it in the local Zed client — Zed propagates the extension to the remote host automatically.

4. Verify by opening a Markdown file inside a directory that contains .streamd.toml@ completions and diagnostics should become active.

Neovim (nvim-lspconfig)

1. Register the server — add to your Neovim config (e.g. ~/.config/nvim/init.lua or a plugin file):

local lspconfig = require('lspconfig')
local configs = require('lspconfig.configs')

if not configs.streamd then
  configs.streamd = {
    default_config = {
      cmd = { 'streamd', 'lsp' },
      filetypes = { 'markdown' },
      root_dir = lspconfig.util.root_pattern('.streamd.toml'),
      single_file_support = false,
    },
  }
end

lspconfig.streamd.setup {}

The server activates automatically when Neovim opens a Markdown file inside a directory that contains a .streamd.toml file.

2. Using LSP features — standard Neovim LSP keymaps apply (:help lsp):

Action Default keymap Notes
Trigger @ completions <C-x><C-o> (insert mode) Or via your completion plugin (nvim-cmp, blink.cmp, …)
Show diagnostics for current line <C-w>d / gl File-name format warnings, timesheet errors
Jump to next / previous diagnostic ]d / [d Navigate between warnings
Code actions (mark task as done) <leader>ca (Neovim ≥ 0.10) Place cursor on a line with @Task
Rename marker across all files <leader>cr / grn Renames the @Marker under the cursor everywhere
Find all references to a marker grr / <leader>fr Lists every occurrence of @Marker across the workspace
Document outline (shard tree) :lua vim.lsp.buf.document_symbol() Or via Telescope: :Telescope lsp_document_symbols
Workspace symbol search :lua vim.lsp.buf.workspace_symbol() Or via Telescope: :Telescope lsp_workspace_symbols

Note: default keymaps (grn, grr, <C-w>d, ]d/[d) are available from Neovim 0.10+. On older versions use :lua vim.lsp.buf.* commands or set up keymaps manually in your on_attach callback.

VS Code (tasks.json / manual)

Use any extension that lets you configure custom LSP servers, pointing cmd to streamd lsp.