1 unstable release
Uses new Rust 2024
| 0.1.0 | Sep 11, 2025 |
|---|
#302 in Filesystem
17KB
244 lines
Linkleaf
Manage protobuf-only Linkleaf feeds (linkleaf.v1) within your terminal.
linkleaf is a simple, protobuf-backed feed manager for storing and organizing links.
It uses a Protocol Buffers schema to define a portable, versioned format for feeds and individual link entries.
The command-line interface (linkleaf) lets you create a feed, add links and list/inspect entries from a compact .pb file.
⚠️ Warning: both the CLI and the public API are under active development; details may change between versions.
Features
- Portable format — uses protobuf messages (
Feed,Link). - Minimal metadata — title, URL, datetime, tags, optional summary/referrer.
- Stable IDs — default ID is a UUID v4 (you can override with
--id, which must be a valid UUID). - Local-first — single binary
.pbfile; no server required. - Filtering — list by tags and/or by date (day-precision).
Usage
linkleaf init [FILE] [--title <TITLE>] [--version <N>]
linkleaf add [FILE]
--title <TITLE> --url <URL>
[--summary <S>] [--tags <CSV>] [--via <URL>] [--id <UUID>]
linkleaf list [FILE]
[-l|--long]
[--tags <CSV>]
[--date <YYYY-MM-DD>]
Defaults
FILEdefaults tofeed/mylinks.pbfor all commands.adduses today’s date automatically (YYYY-MM-DD, UTC).--tagsis comma-separated (e.g.,rust,book,learning).add --idmust be a valid UUID (v4 recommended). Without--id, a new UUID is generated.addsets the link’s datetime to local time in the formatYYYY-MM-DD HH:MM:SS.- Re-adding a link updates an existing entry when the ID matches or the URL matches; the updated link moves to the front.
list --dateacceptsYYYY-MM-DDand matches links on that calendar day (local time).- Links are kept newest-first (inserts and updates end up at index
0)
Examples
Initialize a feed
Create the default feed in feed/mylinks.pb:
linkleaf init
Custom location, title and version:
linkleaf init my/links.pb --title "Reading List" --version 1
Add a link
Basic add (date is auto):
linkleaf add --title "Tokio - Asynchronous Rust" \
--url "https://tokio.rs/"
With summary, tags and via:
linkleaf add --title "Tokio — Async Rust" \
--url "https://tokio.rs/" \
--summary "The async runtime for Rust" \
-g rust,async,tokio \
--via "https://github.com/tokio-rs"
If no --id is given, one is derived automatically. Explicit ID (overrides the derived one):
linkleaf add --title "Serde" \
--url "https://serde.rs/" \
--id 123e4567-e89b-12d3-a456-426614174000
Update an existing entry (same derived/explicit ID):
# Re-adding same URL on the same day reuses the same derived ID → updates fields
linkleaf add --title "Tokio — Asynchronous Rust" \
--url "https://tokio.rs/" \
--summary "Updated summary"
Use a non-default feed path:
linkleaf add my/links.pb --title "Prost" --url "https://docs.rs/prost"
List links
Compact view:
linkleaf list
Example output:
Feed: 'My Links' (v1) — 2 links
1. 2025-08-23 Tokio - Asynchronous Rust
https://tokio.rs/
2. 2025-08-23 The Rust Book [rust,learning,book]
https://doc.rust-lang.org/book/
Detailed (multi-line) view:
linkleaf list -l
Example output:
Feed: 'My Links' (v1)
- [2025-08-23] Tokio - Asynchronous Rust
id: f47ac10b-58cc-4372-a567-0e02b2c3d479
url: https://tokio.rs/
- [2025-08-23] The Rust Book
id: 3f2504e0-4f89-41d3-9a0c-0305e82c3301
url: https://doc.rust-lang.org/book/
via: https://rust-lang.org
tags: rust, learning, book
Filter by tags or by date (day-precision):
# Any of the listed tags will match (case-insensitive)
linkleaf list --tags rust,book
# Only links from that calendar day (local time)
linkleaf list --date 2025-08-23
Feed Schema
Defined in proto/linkleaf/v1/feed.proto:
-
Link
id(string) — auto-derived if omittedtitle(string, required)url(string, required)date(string, YYYY-MM-DD)summary(optional string)tags(optional repeated strings)via(optional string)
-
Feed
title(string)version(uint32)links(repeated Link, newest first)
Development
Protobufs are compiled at build time via prost-build.
To recompile after changing the .proto schema:
cargo clean
cargo build
Dependencies
~11–19MB
~326K SLoC