all repos — llm_aggregator @ 26eb79c063daa25ab326497558d2b3bf17a675bd

A CLI tool to aggregate RSS feeds and summarise them with LLMs

CHANGELOG.md (view raw)

  1# Changelog
  2
  3All notable changes to this project will be documented in this file.
  4
  5The format is based on [Keep a
  6Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
  7[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
  8
  9## [0.10.0] - 2026-04-23
 10
 11### Added
 12
 13- **Short command-line flags**: Single-character shortcuts for the most
 14  commonly used options:
 15  - `-f` / `--feeds-file` — feeds file path
 16  - `-p` / `--prompt` — summarisation prompt
 17  - `-n` / `--max-articles-per-feed` — articles per feed limit
 18  - `-d` / `--max-days-old` — article age filter
 19  - `-i` / `--include-keywords` — keyword include filter
 20  - `-e` / `--exclude-keywords` — keyword exclude filter
 21  - `-m` / `--model` — LLM model selection
 22  - `-o` / `--output` — output format
 23  - `-t` / `--tui` — enable TUI
 24  - `-D` / `--dry-run` — dry run mode
 25- **Styled help output**: Custom lipgloss-styled help text at
 26  `internal/cli/help.go` replaces go-arg's default plain-text output. Flags are
 27  rendered in cyan, section headers in bold, with consistent column alignment.
 28  Respects `$NO_COLOR`.
 29
 30## [0.9.0] - 2026-04-23
 31
 32### Added
 33
 34- **Markdown rendering in TUI**: Implemented `charmbracelet/glamour` to
 35  render LLM summary output with proper markdown styling. Headers, bold,
 36  italic, code blocks, lists, and other markdown elements are now styled
 37  for better readability in the terminal.
 38- **Formalised infobar keybinds**: TUI keybinds are now defined as
 39  dedicated style variables at the top of the model for easier maintenance.
 40  Keybinds are bold while separators and action text are subtle but
 41  distinguishable.
 42- **Thinking indicator as separate element**: The `[💭 Thinking: ON/OFF]`
 43  toggle indicator is now on its own line above the keybinds, using a
 44  distinct style (magenta+bold when ON, subtle+italic when OFF).
 45- **Dynamic text wrapping on resize**: TUI summary text now re-wraps when
 46  the terminal window size or font changes, with proper markdown re-rendering.
 47
 48## [0.8.0] - 2026-04-23
 49
 50### Added
 51
 52- **Thinking tags toggle in TUI**: LLMs that output `<think>`/`</think>`
 53  thinking tags now have those sections automatically removed from the summary
 54  display by default. Users can press `t` to toggle the thinking section back
 55  on, displayed in gray at the head of the output with XML tags stripped for
 56  cleaner presentation. A status indicator shows whether thinking is currently
 57  visible.
 58
 59## [0.7.1] - 2026-04-22
 60
 61### Fixed
 62
 63- Environment variables were correctly overriding config file values, but CLI
 64  arguments without explicit flags were also overriding config file values
 65  unintentionally.
 66  - Root cause: `go-arg` was populating struct fields with default values
 67    from `default:` tags even when those CLI flags weren't provided
 68  - Fix: Removed `default:` tags from Args struct fields for LLM options
 69    (`model`, `base-url`, `api-key`, `max-tokens`, `temperature`);
 70    Viper's own default handling is sufficient
 71  - Fix: Changed Args struct fields from value types to pointer types
 72    (`*string`, `*int`, `*float64`) so that "not provided on CLI" can be
 73    distinguished from "provided but zero/empty"
 74  - Fix: Updated `BindCLIArgs()` and `isZero()` to properly handle pointer
 75    types and distinguish nil pointers from zero values
 76- `isZero()` with compound type switch cases: Compound type cases like `case
 77  *int, *int8, *int16, *int32, *int64` don't properly handle nil comparison when
 78  stored in an interface variable. Fixed by splitting into individual type cases.
 79- `isZero()` missing nil interface handling: When a nil pointer is stored
 80  in an `any` interface, `value != nil` returns `true` (the interface itself
 81  is not nil). Added early `if v == nil { return true }` check.
 82
 83## [0.7.0] - 2026-04-22
 84
 85### Added
 86
 87- **`--dry-run` option**: Validate configuration and preview what would happen
 88  without making any LLM API calls. Useful for validating feeds file and
 89  configuration, checking article counts and filtering results and anything
 90  else that can be done "offline".
 91- **Styled terminal output using `lipgloss`**: All CLI output now uses ANSI
 92  colour codes for better readability:
 93- **`$NO_COLOR` environment variable support**: Respects the ["no
 94color"](https://no-color.org/) standard. When `NO_COLOR` is set, all styling is
 95disabled and plain text is output instead.
 96
 97### Changed
 98
 99- API key validation now only occurs when not using `--dry-run` mode
100
101## [0.6.0] - 2026-04-22
102
103### Added
104
105- **Comprehensive unit test suite**, including CLI argument tests
106  (`--feeds-file`, `--prompt`, `--api-key`, `--model`, `--base-url`),
107  configuration tests, aggregator tests, output formatter tests, processor
108  tests and defaults tests.
109- **`--base-url` CLI option**: configure custom API endpoints for different LLM
110  providers. Should support any OpenAI-compatible provider.
111  - Environment variable: `LLM_AGGREGATOR_BASE_URL`
112- `internal/defaults` package
113- `docs/TESTING.md` which contains a comprehensive testing guide with test
114  descriptions
115
116### Changed
117
118- **Configuration defaults**: All packages now use `defaults.Default*` constants
119  - `internal/config`: Uses `defaults.Default*` for default values
120  - `internal/runtime`: Uses `defaults.Default*` for runtime defaults
121  - `internal/llm`: Uses `defaults.Default*` for LLM client defaults
122
123### Fixed
124
125- `nil` pointer safety in aggregator
126  - Added nil checks for `progressCtx` across all log statements
127  - `FeedAggregator` now works correctly when progress context is nil
128  - Tests use `NewFeedAggregatorWithProgress` with explicit progress context
129
130## [0.5.0] - 2026-04-22
131
132### Added
133
134- **Accurate token counting with tiktoken**
135  - New `internal/tokeniser` package using OpenAI's tiktoken-go library
136  - BPE tokenisation for accurate token counting vs rough character estimation
137  - Encoding caching to avoid repeated initialisation overhead
138  - Model-aware encoding selection (cl100k_base, o200k_base, etc.)
139  - `CountTokens()` and `CountMessagesTokens()` functions
140  - Fallback to rough estimation when tiktoken initialisation fails
141- **Concurrent feed fetching**: Feeds are now fetched concurrently using
142  `golang.org/x/sync/errgroup`
143  - Semaphore limits concurrent requests to 10 to avoid server overload
144  - Mutex-protected shared state for thread-safe article collection
145  - Partial failures don't stop other feeds from being processed
146- **Scrollable summary in TUI**
147  - Bubble Tea viewport component for browsing long summaries
148  - Keyboard navigation: j/k or arrows (scroll), Space/B (page), g/G
149  (start/end)
150  - Mouse wheel scrolling support
151  - Scroll progress indicator showing position and total lines
152
153### Changed
154
155- **Streamlined configuration management**: Viper now uses global instance with
156automatic precedence handling. Simplified configuration flow: Parse → GetViper
157→ BindCLIArgs → ViperToRuntime
158- **TUI colour scheme**: All hex colour codes replaced with ANSI 256-colour
159  palette
160
161### Fixed
162
163- Viewport now properly handles scroll events via `Update()`. Summary content
164  pre-wrapped to viewport width before display
165- Fixed string literal colour names to use actual variables
166
167## [0.4.0] - 2026-04-21
168
169### Changed 
170
171- **TUI is now fully functional and production-ready**: Replaced the
172work-in-progress TUI implementation with a robust Bubble Tea command pattern:
173  - Runtime execution now uses native `tea.Cmd` instead of manual goroutine
174  orchestration.
175  - Added real-time progress updates via `progress.Progress` interface with
176  stage, substage, and article count messages.
177  - TUI displays a spinner, elapsed time, and final summary inline.
178  - Removed signal handling and channel synchronisation in favour of Bubble
179  Tea's built-in lifecycle.
180  - `TUIProgress` now only sends messages to an existing program, simplifying
181  integration.
182  - Both verbose mode (`SimpleLogger`) and TUI mode share the same
183  `progress.Progress` interface.
184
185## [0.3.0] - 2026-04-21
186
187### Added
188
189- **Configuration file support via TOML** (XDG-compliant and cross-platform)
190  - Load settings from `~/.config/llm_aggregator/config.toml`
191  - Supports all aggregation, API, and output options
192  - Example configuration file at `configs/config.example.toml`
193- **Environment variable support with `LLM_AGGREGATOR_` prefix**
194  - All configuration options can be set via environment variables
195  - Precedence order: CLI arguments > environment variables > config file >
196  built‑in defaults
197- New `internal/config` package with Viper integration
198  - `Load()` and `Save()` methods for configuration management
199  - `GetConfigPath()` for XDG‑compliant config file location
200  - `ConfigExists()` to check for existing configuration
201- Comprehensive unit tests for configuration loading, saving, and environment
202  variable precedence (`internal/config/config_test.go`)
203
204### Changed
205
206- **Environment variable renamed:** `DEEPSEEK_API_KEY`207  `LLM_AGGREGATOR_API_KEY`
208- **CLI help text** now reflects the new API key environment variable and
209  general configuration options
210- **Command‑line argument precedence** implemented in `cmd/llm_aggregator.go`
211via `applyConfiguration()`
212- Updated all help text, documentation, and code references
213- `README.md` completely revised with a new "Configuration" section
214
215### Removed
216
217- Global `QuietMode` and `VerboseMode` variables from
218`internal/config/config.go`. Replaced by runtime‑specific configuration in
219`runtime.Runtime` and CLI arguments
220- Hardcoded system prompt in `runtime.NewRuntime()`. Now left empty, allowing
221configuration or client default to be used
222- CLI flags now correctly override config file and environment variables
223
224## [0.2.0] - 2026-04-21
225
226### Changed
227
228- Moved all progress and status messages behind `-v/--verbose` flag
229- Default CLI mode is now silent except for final output and errors
230- Components (aggregator, processor, LLM client) use logger interface
231controlled by verbose flag
232
233## [0.1.0] - 2026-04-21
234
235### Added
236
237- Complete translation from Python prototype to Go implementation
238- RSS/Atom feed parsing using `gofeed` library
239- DeepSeek API integration via `openai-go` client, configured for `/chat/completions` endpoint
240- Content filtering and processing with keyword‑based include/exclude, date filtering, and sorting
241- Command‑line interface using `go‑arg` with automatic help and version flags
242- Multiple output formats: plain text, GitHub‑flavoured markdown, and JSON
243- Terminal user interface (TUI) built with `bubbletea` featuring:
244  - Animated progress bar with gradient colours (`#FF7CCB` to `#FDFF8C`)
245  - Live article counters (aggregated/processed)
246  - Elapsed time display
247  - Coloured status indicators using `lipgloss` styling
248  - Keyboard controls (q/Ctrl+C to quit)
249- Web content extraction fallback using `goquery` when feed descriptions are minimal
250- Configurable limits: articles per feed, maximum age, total articles
251- Token estimation and API usage logging
252- Environment variable support (`LLM_AGGREGATOR_API_KEY`) for authentication
253- Example feeds file with technology, programming, and free software sources
254
255### Changed
256
257- Program structure organised into standard Go layout: `cmd/`, `internal/`, `pkg/`
258- English spelling conventions maintained throughout (colour, initialise, summarise)
259- Error handling improved with specific messages for common API failures (invalid key, rate limits, etc.)
260- Progress reporting unified through a `ProgressContext` interface for both TUI and CLI modes
261
262### Fixed
263
264- Initial API endpoint mismatch (using `/responses` instead of `/chat/completions`)
265- Nil pointer dereferences when handling optional feed metadata (author, dates)
266- String repetition syntax errors in Go (replaced `"="*80` with `strings.Repeat`)
267- CLI help/version flag handling to show information without requiring other arguments
268- Type compatibility issues with `openai-go` v3 API (message parameters, token usage fields)