docs: add man pages for llm_aggregator
- Add `docs/llm_aggregator.1` (user command man page)
- Document all command-line options (feed aggregation, content
filtering, LLM API, output formats, TUI interface)
- Include environment variables, configuration precedence, examples,
exit status, and dependencies
- Add `docs/llm_aggregator.5` (configuration file man page)
- Describe TOML config file structure with sections for
feed_aggregation, filtering, llm_api, system, and output
- Provide full example configuration and security considerations
Maxwell Jensen 85795372+maxwelljens@users.noreply.github.com
Wed, 22 Apr 2026 15:12:45 +0200
feat: add comprehensive test suite, --base-url option, and central defaults package
- Add comprehensive unit test suite across all major packages
- `internal/cli/args_test.go`: CLI argument tests for all flags
- `internal/aggregator/aggregator_test.go` and `article_test.go`: feed
parsing, filtering, sorting
- `internal/output/formatter_test.go`: JSON, Markdown, and text output
formatting
- `internal/processor/processor_test.go`: article processing, keyword
filtering, sorting
- `internal/config/config_test.go`: configuration loading and Viper
integration
- `internal/defaults/defaults_test.go`: default constants validation
- Add `--base-url` CLI option to configure custom LLM API endpoints
- Support any OpenAI-compatible provider (e.g., local Ollama, Azure
OpenAI)
- Environment variable: `LLM_AGGREGATOR_BASE_URL`
- Default: `https://api.deepseek.com`
- Add `internal/defaults` package to centralise all default constants
- `internal/config`, `internal/runtime`, `internal/llm` now use
`defaults.Default*`
- Eliminates hard-coded default values scattered across packages
- Add `docs/TESTING.md` with comprehensive testing guide
- Explains test structure, helper functions, and coverage goals
- Includes examples of table-driven tests and nil safety testing
- Fix nil pointer safety in `internal/aggregator`
- Add nil checks for `progressCtx` before each log/warning/debug call
- `FeedAggregator` now works correctly when progress context is nil
- Tests explicitly use `NewFeedAggregatorWithProgress` with proper
context
- Update `README.md` to document `--base-url` flag and environment
variable
- Update `CHANGELOG.md` with version 0.6.0 changes
Maxwell Jensen 85795372+maxwelljens@users.noreply.github.com
Wed, 22 Apr 2026 14:54:49 +0200
feat: add accurate token counting, concurrent feed fetching, and scrollable TUI summary
- Add accurate token counting with tiktoken
- New `internal/tokeniser` package using
`github.com/pkoukk/tiktoken-go`
- BPE tokenisation for precise counting vs rough character estimation
- Encoding caching and model-aware encoding selection (cl100k_base,
o200k_base, etc.)
- `CountTokens()` and `CountMessagesTokens()` functions
- Fallback to rough estimation when tiktoken initialisation fails
- Add concurrent feed fetching with errgroup
- Fetch feeds in parallel using `golang.org/x/sync/errgroup`
- Semaphore limits concurrent requests to 10 to avoid server overload
- Mutex-protected shared state for thread-safe article collection
- Partial feed failures do not stop other feeds from being processed
- Add scrollable summary view in TUI
- Integrate `bubbles/viewport` component for browsing long summaries
- Keyboard navigation: j/k or arrows (scroll), Space/B (page), g/G
(start/end)
- Mouse wheel scrolling support
- Scroll progress indicator showing position and total lines
- Streamline configuration management
- Use global Viper instance with automatic precedence handling
- Simplify configuration flow: Parse → GetViper → BindCLIArgs →
ViperToRuntime
- Remove manual precedence logic from `cmd/llm_aggregator.go`
- Replace TUI hex colour codes with ANSI 256-colour palette
- Fix viewport scroll event handling and content pre-wrapping before
display
- Rename `internal/llm/deepseek.go` to `internal/llm/llm.go` (generalise
LLM client)
- Update `CHANGELOG.md` (v0.5.0) and `README.md` to document new
features
Maxwell Jensen 85795372+maxwelljens@users.noreply.github.com
Wed, 22 Apr 2026 10:46:14 +0200
refactor: generalise Deepseek-specific naming to generic LLM
- Rename `DeepseekClient` to `LLMClient` in `internal/llm/deepseek.go`
- Update constructor `NewDeepseekClient` → `NewLLMClient`
- Change all comments and log messages from "Deepseek" to "LLM"
- Update `internal/runtime/runtime.go` to use `NewLLMClient` instead
- Replace all references to "Deepseek API" with "LLM API" across:
- `README.md` – section headings, environment variables, examples
- `configs/config.example.toml` – comments and section titles
- `internal/cli/args.go` – flag help text, description, environment
note
- `internal/config/config.go` – struct comments and bindEnv calls
- Keep default model as `deepseek-chat` and base URL as
`https://api.deepseek.com`
- The client remains compatible with Deepseek but clearly supports any
OpenAI‑compatible LLM provider
- Improve error messages to be provider‑agnostic (e.g., "invalid API
key" without mentioning Deepseek)
Maxwell Jensen 85795372+maxwelljens@users.noreply.github.com
Wed, 22 Apr 2026 09:33:31 +0200
fix: restructure TUI with bubbletea command pattern and progress interface
- Replace manual goroutine and signal handling with native bubbletea
commands
- Move runtime execution into `Model.startProcessing()` tea.Cmd
- Remove `runWithTUI` goroutine orchestration and channel
synchronisation
- Introduce `progress.Progress` interface and inject into
`runtime.Runtime`
- Add `SetStage`, `SetSubStage`, `SetArticleCount` methods to
`SimpleLogger` and `NoopLogger`
- Replace internal `logger *progress.Context` with `Progress
progress.Progress` field
- Simplify `TUIProgress` to only send messages to existing `tea.Program`
- Remove program creation and runtime execution from `TUIProgress`
- Use `StageMsg`, `SubStageMsg`, `ArticleCountMsg` for updates
- Update `Model` to hold `*runtime.Runtime` and display spinner
- Add `spinner` model and tick command for visual feedback
- Show checkmark on completion, capture elapsed time, and display
summary inline
- Clean up unused `StepMsg` related functions and redundant blank lines
- Adjust `applyConfiguration` formatting and remove unused imports
(`os/signal`, `syscall`)
Maxwell Jensen 85795372+maxwelljens@users.noreply.github.com
Tue, 21 Apr 2026 21:47:59 +0200
feat: add configuration file and environment variable support
- Add `internal/config` package with Viper-based TOML loading
- Load configuration from `~/.config/llm_aggregator/config.toml` (XDG
compliant)
- Support all aggregation, API, and output options in config file
- Implement precedence: CLI args > env vars > config file > built‑in
defaults
- Integrate config loading into `cmd/llm_aggregator.go`
- Call `config.Load()` before argument parsing
- Apply config values to runtime with `applyConfiguration()`
- Gracefully warn if config file exists but fails to load
- Rename environment variable prefix from `DEEPSEEK_API_KEY` to
`LLM_AGGREGATOR_API_KEY`
- Update `internal/cli/args.go` help text and environment variable
reference
- Update `internal/llm/deepseek.go` to read `LLM_AGGREGATOR_API_KEY`
- Update `README.md` and `CHANGELOG.md` to reflect new variable name
- Add `configs/config.example.toml` with documented configuration
options
- Add `internal/config/config_test.go` covering defaults, path
resolution, save/load, and environment variable precedence
- Update `go.mod` / `go.sum` with new dependencies:
- `github.com/spf13/viper` for configuration management
- `github.com/adrg/xdg` for XDG base directory support
- `github.com/pelletier/go-toml/v2` (indirect via viper)
- Revise `README.md` to document the new configuration system,
precedence order, and environment variables
- Update `CHANGELOG.md` for version 0.3.0
- Remove unused `internal/config` global flags (`QuietMode`,
`VerboseMode`) replaced by runtime configuration
Maxwell Jensen 85795372+maxwelljens@users.noreply.github.com
Tue, 21 Apr 2026 18:37:19 +0200
feat: add verbose flag to control progress and status messages
- Make CLI silent by default; only final output and errors are displayed
- Move all progress logs, warnings, and debug messages behind
`-v/--verbose`
- Introduce logger interface (`progress.Context`) for consistent logging
- Add `NoopLogger` for silent mode, `SimpleLogger` for verbose output
- Update components to use logger instead of direct `fmt.Print` calls
- `aggregator.FeedAggregator` accepts logger via
`NewFeedAggregatorWithProgress`
- `processor.ContentProcessor` gains `SetLogger` method
- `llm.DeepseekClient` gains `SetLogger` method
- Modify `runtime.Runtime` to create appropriate logger from `Verbose`
flag
- Update CLI flag description: `--verbose` now says "Show verbose
output"
- Remove redundant conditional logging blocks (if verbose) from
`cmd/llm_aggregator.go`
- Ensure token estimates, filtering summaries, and API call logs only
appear in verbose mode
Maxwell Jensen 85795372+maxwelljens@users.noreply.github.com
Tue, 21 Apr 2026 15:41:41 +0200
feat: initial implementation of LLM RSS aggregator with DeepSeek summarisation
- Add core aggregation engine (`internal/aggregator/`)
- Parse RSS/Atom/JSON feeds using `gofeed`
- Extract article metadata (title, link, date, author)
- Fallback to web scraping with `goquery` for minimal content
- Add content processing and filtering (`internal/processor/`)
- Keyword-based include/exclude filtering
- Sort by date, title, or source
- Token estimation and context preparation
- Add DeepSeek API integration (`internal/llm/`)
- OpenAI-compatible client for chat completions
- Configurable model, max tokens, temperature
- Support custom system prompts
- Add command-line interface (`internal/cli/`)
- `go-arg` based argument parsing
- Options for feeds file, prompt, filtering, output formats
- Environment variable support for API key
- Add output formatting (`internal/output/`)
- Plain text, GitHub‑flavoured markdown, and JSON outputs
- Optional inclusion of original articles
- Add terminal user interface (`internal/tui/`)
- Bubble Tea based progress bar with gradient colours
- Live article counters and elapsed time
- Keyboard controls (q/Ctrl+C to quit)
- Add runtime orchestration (`internal/runtime/`)
- Pipeline execution (aggregate → process → summarise → output)
- File output support
- Add project documentation
- `README.md` with usage examples and dependencies
- `CHANGELOG.md` for version 0.1.0
- `LICENCE.txt` (EUPL 1.2)
- Third‑party library READMEs in `docs/` for reference
- Add build configuration
- `go.mod` with dependencies (gofeed, openai-go, bubbletea, lipgloss,
go-arg, goquery)
- `.goreleaser.yaml` for cross‑platform releases
- `.gitignore` for Go binaries and test artifacts
Maxwell Jensen 85795372+maxwelljens@users.noreply.github.com
Tue, 21 Apr 2026 14:44:42 +0200