all repos — llm_aggregator @ af6da634ea141bc028760fd78253d03cee78a82f

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