WIP: rustic #8

Draft
panda wants to merge 7 commits from rustic into main
Owner
No description provided.
panda self-assigned this 2026-01-10 16:07:26 +08:00
This change introduces a Valkey/Redis-backed list manager script (`vk-list.rs`) and ensures the bootstrapped test runner (`tests.sh`) is executable.

**Capabilities**

- New `vk-list` CLI (via `rust-script`) that manages named lists with:
  - Commands: `add`, `get`, `edit`, `remove`, `clear`, `list` (default), `export`, `import`, `config`, `help`.
  - 1-based stable IDs, position-safe deletion (marker + `LREM`), and contextual error messages.
- Robust data handling:
  - Line-delimited and null-delimited import/export.
  - Exact content preservation in null-delimited mode (including newlines).
  - Size limits: max item size and max list length to reduce DoS risk.
- Bootstrap improvement:
  - `bootstrap-dev.sh` now runs `chmod +x tests.sh`, making tests directly runnable.

**Operations / Workflows**

- Typical flows:
  - `todo add "task"` → validated add → Redis `LPUSH` → list view.
  - `todo remove 3` → mark index with unique token → `LREM` that token → list view.
  - `todo export [-|FILE]` → `LRANGE` → stream to stdout/file, SIGPIPE-safe for pipelines like `| head`.
  - `todo import [-|FILE]` → read stdin/file (line or `\0` delimited) → `add` per item → list view.
- Dev workflow:
  - `bootstrap-dev.sh` produces `tests.sh` and makes it executable for `./tests.sh`.

**Systems & Integration**

- Components:
  - `vk-list.rs` with `Config`, `VkList`, `Valkey` abstractions.
  - `valkey-cli --raw` as the underlying storage interface (no shell, arguments passed directly).
- Interfaces:
  - Env vars:
    - `VK_APPNAME` (CLI name), `VK_PREFIX` (key prefix), `VK_LIST` (validated list name), `VK_NULL_DELIM` (delimiter mode).
  - Redis key format: `{prefix}:{list}`, with strict validation on `list`.

**Data & Information**

- Key semantics:
  - ID translation: user ID `n` → Redis index `n-1`.
  - List name constraints: non-empty, ≤ 100 chars, no `:`, only `[A-Za-z0-9_-]`.
  - Import: skips empty/whitespace-only lines in line mode; preserves all bytes except `\0` in null mode.

**Project Impact & Risks**

- Moves toward self-contained, scriptable Valkey-based tooling and smoother bootstrap (tests immediately runnable).
- Risks / follow-ups:
  - `valkey-cli` availability and connection configuration are assumed, not managed.
  - `LRANGE`-based export still loads full lists in memory for very large lists.
  - Potential subtlety from trimming stdout in `Valkey::exec` (whitespace-sensitive items should be tested).

---
This introduces a new `vlists` Cargo package with two Rust-script binaries:

- `vlist`: a Valkey-backed list manager for a single list.
- `vlists`: a multi-list manager for all lists under a prefix.

**Capabilities**

- `vlist` supports:
  - `add`, `get`, `edit`, `remove`, `clear`, `export`, `import`, `config`, `help`, and default `list`.
  - Line-delimited and null-delimited exports/imports with streaming I/O.
  - Strict list-name validation and size limits (`MAX_ITEM_SIZE`, `MAX_LIST_LENGTH`).
  - Safe, position-based deletion using a unique marker (`LSET` + `LREM`).
- `vlists` supports:
  - Listing all lists under `VK_PREFIX:*` with item counts.
  - Renaming, deleting, copying lists, and `info` (metadata + usage hints).

**Operations / Workflows**

- Typical `vlist` flows:
  - `vlist` → show tasks.
  - `vlist add "task"` → append and re-list.
  - `vlist edit ID "new text"` / `vlist remove ID` → mutate and re-list.
  - `vlist export [FILE|-]` / `import [FILE|-]` → pipeline-friendly data transfer; null-delim preserves newlines.
- Typical `vlists` flows:
  - `vlists` / `vlists list` → overview of all lists.
  - `vlists rename OLD NEW`, `vlists delete LIST`, `vlists copy SRC DST`, `vlists info LIST`.

**Systems & Integration**

- New Cargo package `vlists` (edition 2024) with `[[bin]]` targets `vlist` and `vlists`.
- Both binaries use `valkey-cli --raw` for all data operations (no shell invocation; arguments passed via `Command::args`).
- Configuration via environment:
  - `VK_LIST`, `VK_PREFIX`, `VK_APPNAME`, `VK_NULL_DELIM` (for `vlist`).
  - `VK_PREFIX` (for `vlists`).

**Data & Information**

- Redis key format: `{VK_PREFIX}:{VK_LIST}` (e.g. `vk-list:todo`), with strict name rules for `VK_LIST`.
- `vlist` exports:
  - Line mode: one task per line; whitespace-only lines skipped on import.
  - Null mode: tasks delimited by `\0`, preserving all other content; SIGPIPE/BrokenPipe on export treated as normal termination.

**Project Impact & Risks**

- Establishes a layered, self-documenting architecture for Valkey-backed lists and provides a coherent multi-list story.
- Enables future features like tagging, archiving, and CI integration around stable CLIs.
- Risks/notes:
  - `vlists` uses `KEYS`, which may be expensive on large keyspaces.
  - `vlists` does not yet reuse the strict list-name validation logic from `vlist`.
  - Large lists are always fully retrieved for listing; pagination is a possible follow-up.

---
**Overview**

Convert the Valkey-backed list manager from a rust‑script and subdirectory layout into a standard Cargo crate at the repo root, with compiled binaries `vlists` and `vlist`. Clean up Git tracking for Rust artifacts.

---

**Capabilities**

- Project is now a conventional Rust crate with:
  - `[[bin]] vlists` → `src/vlists.rs`
  - `[[bin]] vlist`  → `src/vlist.rs`
- Functionality from `vk-list.rs` is preserved via compiled binaries instead of an inline `rust-script`.
- `.gitignore` now excludes `Cargo.lock` and `target/`, keeping builds local and untracked.

---

**Operations / Workflows**

- Recommended usage shifts to:
  - `cargo run --bin vlist -- …` or `cargo build` then run `target/*/vlist` / `vlists`.
- Any prior workflow invoking `vk-list.rs` directly should be updated to call the compiled binaries or use Cargo.

---

**Systems & Integration**

- Root `Cargo.toml` now owns the binary configuration (moved from `vlists/Cargo.toml`), simplifying integration with:
  - Developer tooling (`rust-analyzer`, `cargo fmt`, `cargo clippy`).
  - CI (`cargo build`, `cargo test`, `cargo install`).
- Source files relocate from `vlists/` into `src/`, aligning with standard Rust project layout.

---

**Data & Information**

- Build configuration and binary metadata are centralized in root `Cargo.toml`.
- Ignoring `Cargo.lock` favors flexible dependency resolution across environments (inferred), at the cost of strict reproducibility.

---

**Project Impact**

- Advances architecture consolidation by:
  - Standardizing layout and build process.
  - Enabling future testing, refactoring, and packaging using native Rust workflows.
- Unblocks:
  - CI pipelines using stock Cargo commands.
  - Potential `cargo install`-based distribution of `vlist`/`vlists`.

---

**Issues / Risks & Obsolete Behavior**

- `vk-list.rs` is removed; any scripts, docs, or aliases relying on it are now broken and must be updated to `vlist`/`vlists`.
- Ignoring `Cargo.lock` may introduce version drift between environments; policy should be confirmed for long‑term distribution.

---
This commit replaces the litblock-based shell tooling with a Rust-backed CLI stack for Valkey-backed lists, and wires it into a conventional Cargo/Make build.

**Capabilities**

- New Rust `vlist` binary:
  - Per-list operations: `add`, `remove|rm`, `edit`, `get`, `clear`, `export`, `import`, `config`, `help`.
  - Correct delete-by-position using a unique marker (`LSET` + `LREM`), safe with duplicate values.
  - NUL-delimited import/export via `VK_NULL_DELIM=1`, preserving embedded newlines/binary-like content.
  - `VK_SILENT=1` to suppress auto-printing after mutations for pipeline use.
- New `vlists` binary:
  - Discover lists under `VK_PREFIX:*`.
  - `list`, `rename`, `delete|del|rm`, `copy|cp`, `info`.

**Operations / Workflows**

- Usage now centers on:
  - `vlist` / `vlist <LIST>`: list items.
  - `vlist <LIST> add TEXT`, `remove N`, `edit N TEXT`, `get N`, `clear`.
  - `vlist <LIST> export [FILE|-]` ↔ `import [FILE|-]`, with optional NUL mode.
- Multi-list management:
  - `vlists` / `vlists list` to see all lists and item counts.
  - `vlists rename OLD NEW`, `delete LIST`, `copy SRC DST`, `info LIST`.
- Build/install:
  - `make build|release|test|install|uninstall|install-man|install-fish` wraps Cargo and installs binaries, manpages, and fish completions under configurable PREFIX.

**Systems & Integration**

- `vlist`/`vlists` are Rust binaries calling `valkey-cli --raw` through a `Valkey` helper (no shell).
- New environment surface:
  - `VK_PREFIX` (default `vk-list`), `VK_LIST` (default list name, now `default`), `VK_NULL_DELIM`, `VK_SILENT`.
- New artifacts:
  - `man/vlist.1`, `man/vlists.1`.
  - `completions/vlist.fish`, `completions/vlists.fish` (dynamic list-name completion from `vlist` output).

**Data & Information**

- Centralized error type `VkError` and list-name validation (`validate_name`) enforce non-empty, ≤200 chars, no whitespace/NUL.
- Export/import semantics:
  - Line mode: `LRANGE` + newline, skipping blank imports.
  - NUL mode: `LLEN`/`LINDEX` with exact `\0` separation.
- Integration tests (`tests/vlist_cli.rs`) verify import/export, namespace isolation, `clear`, and NUL-mode round-trips against a real Valkey.

**Project Impact & Obsolescence**

- Transitions from a literate shell prototype to a conventional, testable Rust CLI with packaging-friendly build targets.
- Removes `bin/todo`, `bin/vlist`, `bootstrap-dev.sh`, `install-local.sh`, and the README-embedded Makefile/test suite.
- Remaining work:
  - Align no-arg `vlist` behavior across README, manpages, and implementation.
  - Add coverage for `vlists` and completion scripts, and document migration from old `todo`-based flows.

---
**Summary**

This change tightens the contract for `vlist`’s default behavior, aligns the man page with the actual CLI semantics, and cleans up Fish completions by giving `vlists` its own completion file. The legacy `NOTES.md` design document is removed.

**Capabilities**

- `vlist` with no arguments is now explicitly documented and implemented as: “show items in the default list” (using `VK_LIST` or an internal default).
- `vlist <LIST>` is clarified as “show items in LIST”.
- `vlist lists` remains the way to list all lists.
- `vlists` gains proper Fish completions with subcommands: `list`, `rename`, `delete|del|rm`, `copy|cp`, `info`, `help`.
- List-name completion for both `vlist` and `vlists` is now based on `vlists` output, reflecting `vlists` as the canonical list-management interface.

**Usage & Workflows**

- Typical flows:
  - View default list: `vlist` (honors `VK_LIST`).
  - View specific list: `vlist todo`.
  - Manage lists: `vlists rename <old> <new>`, `vlists delete <name>`, etc., with Fish completions suggesting list names from `vlists`.
  - Export items and pipe to other tools: `vlist files export - | xargs cat` (example updated in man page).

**Systems & Data**

- Updated components:
  - `src/vlist.rs`: argument parsing and default behavior comments simplified to match “show default list items”.
  - `man/vlist.1`: clarifies `VK_LIST`, default invocation, and examples.
  - `completions/vlist.fish`: now uses `vlists` to enumerate list names; removed embedded `vlists` snippet.
  - `completions/vlists.fish`: new dedicated completion file.
  - `tests/vlist-cli.rs`: renamed for consistent hyphenated CLI test naming.
- `NOTES.md` removed; architectural notes are no longer kept there.

---

**Project Impact**

- Strengthens the user-facing and scriptable contract for `vlist`, which is important for editor integration and automation.
- Clarifies the separation of responsibilities:
  - `vlist` for per-list items,
  - `vlists` for list administration.
- Reduces duplication and drift by removing an outdated design notes file.

**Issues / Risks**

- Fish completions now depend on `vlists` being installed; on systems without `vlists`, list-name completion will be empty.
- Any external docs or examples that assumed `vlist` with no args lists all lists are now incorrect and should be updated.
- The removal of `NOTES.md` requires ensuring equivalent design intent is captured elsewhere (README/ADRs/tests).
This change makes `vlists` output a stable, script-friendly format, aligns fish completions with it, and enriches crate metadata for publication. Version is bumped to `0.1.1`.

**Capabilities**

- `vlists` now prints each list as a single line: `name count` (space-separated, no headers).
- Help text documents this output format under an “Output format” section.
- “No lists found” is now reported to stderr with guidance to create a list via `vlist <name> add "item"`.
- `Cargo.toml` gains description, readme, keywords, and categories suitable for crates.io discovery.

**Operations / Workflows**

- CLI usage:
  - `vlists` can be safely piped into tools (`cut`, `awk`, `fzf`, etc.) without stripping headers or column padding.
  - Empty result sets now yield an empty stdout stream (only stderr messaging), which is friendlier for `while read` and similar loops.
- Fish completion:
  - `__vlists_list_names` now assumes `vlists` emits `"<name> <count>"` and uses `string split ' ' -f1` to feed completions for `rename/delete/del/rm/copy/cp/info`.

**Systems & Integration**

- Binaries:
  - `vlists` output and help are updated; `vlist` is untouched.
- Shell integration:
  - `completions/vlists.fish` updated to the new format; it now directly mirrors the documented `vlists` contract.
- Manifest:
  - `Cargo.toml` version `0.1.1` plus metadata: `readme = "README.md"`, keywords (`shell`, `cli`, `list`, `todo`, `valkey`), categories (`command-line-utilities`, `database`).

**Data & Behavior**

- Old format:
  - Header row (`LIST`, `ITEMS`), separator line, formatted columns.
- New format:
  - One line per list: `name count`, no decoration.
  - On no lists: no data on stdout; user message on stderr only.

**Project Impact & Risks**

- Moves the CLI toward a clear, documented text interface suitable for scripting and shell integration.
- Improves crate readiness for publishing and discovery in registries.
- Breaking aspects (for consumers of old behavior):
  - Scripts that relied on headers, table layout, or that parsed the “No lists found.” message on stdout will need updating.
- Recommended follow-ups:
  - Audit docs and scripts for assumptions about the old `LIST/ITEMS` table.
  - Consider formalizing output stability (and possibly adding modes like `--json`) for future evolution.

---
**Summary**

Adds namespace globbing to `vlist` (`*` and `**` patterns), defines clear CLI behavior for globbed list names, documents usage patterns, and introduces a fix for null-delimited import. Manpages and workspace docs are updated; a new test script validates core glob scenarios.

**Capabilities**

- `vlist` now treats `*` and `**` in list names as glob patterns:
  - `vlist ctx:*` lists matching namespaces (single level).
  - `vlist ctx:**` lists all descendant namespaces (recursive).
- `export` with a glob outputs matching namespace names (one per line), suitable for piping:
  - `vlist ctx:** export | parallel vlist {} export`.
- Non-`export` commands (`add/remove/edit/clear/...`) with globbed names now error, preventing accidental multi-list mutation.
- Null-delimited import is fixed to use a persistent `BufReader`, avoiding record corruption and `nul byte found in provided data` failures.

**Operations / Workflows**

- New namespace workflows:
  - Discover and iterate over structured list hierarchies:
    `vlist ctx:** export | cut -f1-2 -d: | uniq`.
  - Build trees with `treeify-rs` via `vlist 'ctx:**' export | parallel vlist {} export`.
- Null-delim workflows remain:
  - `VK_NULL_DELIM=1 vlist LIST import -` for robust filename/content ingestion.

**Systems & Integration**

- `src/vlist.rs`:
  - New helpers: `contains_glob`, `expand_glob`, `match_single_level`, `match_recursive`, `list_namespaces`, `export_namespaces`.
  - `main()` branches behavior on glob presence and enforces glob/mutation restrictions.
- Tests:
  - `tests/test_glob.sh` checks single-level, recursive, and export-piping behavior.
- Manpages:
  - `man/vlist.1` gains a **NAMESPACE PATTERNS** section; dates updated for both `vlist.1` and `vlists.1`.

**Data & Information**

- Glob semantics (documented in `docs/namespace_glob_design.md`):
  - `*`: matches exactly one colon-delimited segment.
  - `**`: matches deeper descendants; current implementation excludes the bare prefix itself.
- Extensive usage patterns are documented in `docs/usage-guide.md` and mirrored in `workspace/docs`.

**Project Impact**

- Moves `vlist` toward a proper namespace-aware shell primitive suitable for hierarchical list operations and integration with `treeify-rs`.
- Improves documentation and test coverage for critical behaviors (globbing, null-delim IO), paying down previous “AI-confused” README/notes.

**Issues / Risks**

- `Valkey::keys("{}:*")` can be expensive for large keyspaces; future work should consider `SCAN`-like strategies.
- Design notes call for listing parent namespaces when only descendants exist (e.g. `ctx:terminal-ai:*` when only `ctx:terminal-ai:foo:bar` exists); this is not yet implemented and tracked as a high-priority follow-up.

---
This pull request is marked as a work in progress.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin rustic:rustic
git switch rustic

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff rustic
git switch rustic
git rebase main
git switch main
git merge --ff-only rustic
git switch rustic
git rebase main
git switch main
git merge --no-ff rustic
git switch main
git merge --squash rustic
git switch main
git merge --ff-only rustic
git switch main
git merge rustic
git push origin main
Sign in to join this conversation.
No reviewers
No labels
CHORE
DOCS
IDEA
ISSUE
UX
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
panda/vlist!8
No description provided.