# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Added - Database index on `items(ts)` column for faster ORDER BY sorting - Server API `ItemInfo` now includes `file_size` — actual filesystem-reported size of the item data file ### Changed - Filter plugins check size before loading content into memory (prevents OOM on large inputs) - Status page pre-allocates collections with known capacities (meta plugins, compression info) - `#[inline]` on HTML escape helper functions (`esc`, `esc_attr`) for hot path performance - Removed `once_cell` crate (replaced with `std::sync::LazyLock` from Rust 1.80) - Removed `lazy_static` crate (replaced with `std::sync::LazyLock`) ### Fixed - CLI help text typo: "metatdata" → "metadata" in `--get` and `--info` descriptions ### Refactored - Added module-level documentation to `services/` module ### Documentation - README.md: Fixed compression table — zstd is native (not external), "none" renamed to "raw" - DESIGN.md: Updated schema to reflect current `items` table columns and meta plugin inventory ## [0.1.0] - 2026-03-21 ### Added - Streaming tar-based export (`--export`) producing `.keep.tar` archives without loading entire files into memory - Streaming tar-based import (`--import`) extracting `.keep.tar` archives with new IDs - Server endpoints `GET /api/export` and `POST /api/import` - ID-based filtering for `--list` (`keep -l 1 2 3` lists specific items by ID) - Server API accepts optional `ids` query parameter on `GET /api/item/` - `--ids-only` flag for `--list` mode for scripting - `infer` and `tree_magic_mini` meta plugins for MIME type detection - Native `zstd` compression plugin as default - Configurable compression via `--compression` flag - Export/import modes with format detection (JSON, YAML, binary) - `XDG_CONFIG_HOME` support for default config file location - `XDG_DATA_HOME` support for default storage location - Tilde (`~`) expansion in config file paths ### Changed - `CompressionType::None` renamed to `CompressionType::Raw` (with `"none"` as alias for backward compatibility) - `items.size` column renamed to `items.uncompressed_size` - Added `items.compressed_size` column tracking compressed file size on disk - Added `items.closed` column tracking whether an item is fully written - Default `list_format` in config now matches CLI default (7 vs 5 columns) - All filter plugins share deduplicated option implementations ### Refactored - Extracted `spawn_body_reader()` and `check_binary_content()` helpers for streaming uploads - Extracted `yaml_value_to_string()` helper for meta plugins - Extracted `item_path()` helper in `ItemService` to reduce path duplication - Unified `get_item_meta_name`/`value` to take `&str` instead of `String` - Shared `ItemInfo` struct between client and server - Compression service now returns `Result` types instead of panicking via `.expect()` - `ApiResponse::ok()` and `ApiResponse::empty()` constructors - `meta_filter()` helper on `Settings` for consistent filtering - Added `tag_names()` method on `ItemWithMeta` - `filter_clone_box!` macro for filter plugin cloning ### Fixed - Panic guards in diff, compression engine, and spawned threads - Pre-existing borrow errors in export handler and `TryFrom` implementation - TOCTOU race in `stream_raw_content_response` - Swallowed write errors in meta plugins (digest, magic_file, exec) - Truncated uploads (413) now properly store compressed data - `term::stderr().unwrap()` panic in `item_service` - `.unwrap()` panics in compression engine `Read`/`Write` impls - Client API errors now propagate to user instead of being swallowed - Import endpoint returns 413 on `max_body_size` instead of truncating - `keep --list` uses `list_format` from config in all modes - All tables respect `table_config` from settings - `DisplayListItem` struct removed (was unused) - `#[serde(alias = "size")]` on `ImportMeta` for backward compatibility