# 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.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.3.0] - 2026-02-XX

### Changed
- **UI Framework**: Complete migration from Rich/prompt_toolkit REPL to Textual TUI framework
  - Full terminal user interface with scrollable chat log, persistent stats bar, and multiline input bar
  - `ZoracApp(App)` replaces `Zorac` class as the main application controller
  - Stats bar (`Static#stats-bar`) pinned to bottom — always visible, never scrolls away
  - Real-time streaming via `Markdown.get_stream()` for efficient batched markdown rendering
  - First-time setup runs before Textual alternate screen (since `input()` is incompatible with alt screen)

- **Architecture**: Refactored monolithic main.py into mixin-based composition
  - `CommandHandlersMixin` (handlers.py) — all `cmd_*` command handler methods
  - `StreamingMixin` (streaming.py) — `_stream_response` worker for LLM streaming
  - `HistoryMixin` (history.py) — command history load/save and Up/Down arrow navigation
  - `ChatInput` widget (widgets.py) — multiline input with command suggestions
  - `ZoracApp(CommandHandlersMixin, StreamingMixin, HistoryMixin, App)` composes all modules

- **Async Throughout**: Migrated from synchronous to async I/O
  - `OpenAI` (sync) → `AsyncOpenAI` for non-blocking API calls
  - `check_connection()`, `summarize_old_messages()`, and all command handlers are now async
  - Worker-based streaming with `@work(exclusive=True)` for cancellable, non-blocking responses

- **Command Registry**: Changed from `"command"` key to `"triggers"` list in CommandInfo TypedDict
  - Allows multiple triggers per command (e.g., `/quit` and `/exit` as aliases)

- **Token Counting**: `count_tokens()` now uses configurable encoding via `TIKTOKEN_ENCODING`
  - Signature changed from `count_tokens(messages, model="gpt-4")` to `count_tokens(messages, encoding_name=None)`
  - Falls back to `cl100k_base` if configured encoding is invalid

- **Documentation**: Comprehensive docstrings added to every module, class, and function
  - README.md restructured for clarity and conciseness
  - docs/USAGE.md updated with keyboard shortcuts and new features
  - docs/DEVELOPMENT.md updated for Textual TUI architecture
  - CLAUDE.md expanded with full architecture overview

### Added
- **Textual TUI**: `textual>=1.0.0` dependency for modern terminal user interface
  - `VerticalScroll#chat-log` — scrollable chat area with mounted message widgets
  - `ChatInput#user-input` — multiline input (1-5 lines auto-resize) with Enter to submit, Shift+Enter for newlines
  - `Static#stats-bar` — persistent performance metrics bar (tokens, duration, tok/s)

- **Keyboard Shortcuts**:
  - `Ctrl+C` — cancel in-progress streaming (re-enables input, stays in session)
  - `Ctrl+D` — save session and exit
  - `Shift+Enter` — insert newline in input (works in iTerm2, kitty, WezTerm via Kitty protocol)
  - `Tab` — accept inline command suggestion

- **Command Suggestions**: Inline ghost text suggestions as you type `/` commands via `SuggestFromList`

- **`/reconnect` Command**: Retry vLLM server connection after initial failure

- **Configurable Token Encoding** (`TIKTOKEN_ENCODING`): Choose tokenizer encoding (default `cl100k_base`, also supports `o200k_base`, `p50k_base`, etc.)

- **Configurable Code Theme** (`CODE_THEME`): Pygments theme for syntax-highlighted code blocks (default `monokai`)

- **Version Display**: Header now shows package version via `importlib.metadata`

- **`docs/CONFIGURATION.md`**: New standalone configuration reference documenting all 13 settings

- **Automated Homebrew Updates**: CI/CD release workflow now auto-updates the Homebrew formula after PyPI publish

- **Test Infrastructure**: Migrated to pytest with async support
  - `pytest-asyncio>=0.23.0` with `asyncio_mode = "auto"`
  - Pytest fixtures replace unittest setUp/tearDown
  - Expanded test coverage (~3x increase in test lines)

### Removed
- `prompt-toolkit` dependency (replaced by `textual`)
- `SlashCommandCompleter` class (replaced by `SuggestFromList` ghost text)
- `ConstrainedWidth` class (Textual handles layout width)
- Rich `Live`/`Group` inline streaming display (replaced by Textual widgets)
- `readline`/`atexit` history management (replaced by `HistoryMixin`)
- `screenshots/zorac-screenshot-2.png` (consolidated to single screenshot)
- `requirements/help_feature.md` (integrated into codebase)

### Migration Notes
- **No user-facing configuration changes required** — existing `.env` and `~/.zorac/config.json` files work as-is
- **Command history is backward-compatible** — handles prompt_toolkit `+` prefix format
- **Session files are fully compatible** — conversations restore seamlessly
- **All interactive commands work identically** — same commands, same behavior
- **New optional settings**: `TIKTOKEN_ENCODING` and `CODE_THEME` default to sensible values
- **Terminal compatibility**: Shift+Enter for newlines requires a modern terminal (iTerm2, kitty, WezTerm); in terminals where Shift+Enter is indistinguishable from Enter (e.g., macOS Terminal.app), multiline input is still possible via paste

## [1.2.0] - 2026-02-02

### Changed
- **Distribution**: Migrated from binary releases to PyPI + Homebrew
  - Install via `pip install zorac` or `pipx install zorac`
  - Install via `brew tap chris-colinsky/zorac && brew install zorac`
  - Removed PyInstaller binary builds
  - Automated releases via GitHub Actions with Trusted Publisher (OIDC)

### Removed
- Binary releases (zorac-linux-x86_64, zorac-macos-arm64)
- PyInstaller build files (`zorac.spec`, `run_zorac.py`)

### Improved
- Simpler installation process - standard Python packaging
- Automatic dependency management via pip/brew
- Easier upgrades (`pip install --upgrade zorac` or `brew upgrade zorac`)
- No more macOS Gatekeeper warnings for unsigned binaries

### Migration Notes
- Users of binary releases should switch to pip/pipx/brew installation
- All functionality remains the same
- Configuration in `~/.zorac/` is preserved

## [1.1.0] - 2026-02-01

### Added
- **`/help` Command**: Interactive command to display all available commands with descriptions
  - Shows formatted list of all commands (zorac/main.py:188-191)
  - Includes special formatting for `/config` subcommands
  - Provides quick reference for users without leaving the chat

- **Command Registry System**: Centralized command management infrastructure (zorac/commands.py)
  - `COMMANDS` list with TypedDict definitions for type safety
  - `get_help_text()` - Generates formatted help text for `/help` display
  - `get_system_prompt_commands()` - Generates command descriptions for LLM context
  - Single source of truth for all command definitions

- **LLM Command Awareness**: Enhanced system prompt with command information
  - LLM can now answer questions about Zorac's functionality
  - Suggests relevant commands naturally in conversation
  - Provides usage examples and explanations when helpful

- **Enhanced Markdown Rendering**: Custom renderer with improved layout (zorac/markdown_custom.py)
  - Left-aligned headings (H1, H2, H3) instead of centered panels
  - Cleaner, more readable terminal output
  - Monkey-patches Rich's Heading class for consistent styling

- **Styled Input Bar**: Modern prompt with dark background and placeholder text
  - `> ` prompt with `bg:#1a1a2e` dark background
  - Placeholder text "Type your message or /\<command\>" when input is empty
  - Bottom toolbar showing real-time stats and session info

- **Multi-GPU Training Guide**: Comprehensive documentation for training setups (docs/TEST_TRAINING.md)
  - 220-line guide covering multi-GPU configuration
  - Detailed setup instructions and optimization tips
  - Training best practices and troubleshooting

- **Test Coverage**: New test suite for command registry (tests/test_commands.py)
  - 154 lines of comprehensive tests
  - Validates command structure, help text generation, and system prompt formatting
  - Ensures command registry integrity

### Changed
- **Stats Display**: Changed from Rich Panel to plain text for cleaner appearance
  - Stats now displayed as dim text without border
  - Reduced visual clutter in terminal output

- **System Message**: Enhanced initial system message with command information
  - Replaces simple "You are a helpful assistant" with command-aware prompt
  - Enables LLM to understand and reference Zorac functionality

- **Documentation Updates**:
  - **README.md**: Improved clarity and added new feature descriptions
  - **DEVELOPMENT.md**: Expanded with 178 additional lines of developer guidance
  - **SERVER_SETUP.md**: Restructured for better organization (213 lines modified)
  - **USAGE.md**: Added 36 lines documenting `/help` command and new features
  - **CLAUDE.md**: Enhanced with 46 lines covering new architecture components

### Improved
- **Code Organization**: Command definitions centralized in dedicated module
- **Type Safety**: Full TypedDict annotations for command structures
- **Documentation**: Comprehensive multi-GPU training documentation
- **User Experience**: More discoverable commands via `/help` and LLM awareness
- **Readability**: Better terminal layout with constrained width and left-aligned headings

### Technical Details
- Added `zorac/commands.py` module (134 lines)
- Added `zorac/markdown_custom.py` module (43 lines)
- Enhanced `zorac/main.py` with 76 additional lines
- Added `tests/test_commands.py` (154 lines)
- Extended `tests/test_zorac.py` with 64 additional lines
- Total: ~1,375 additions, 132 deletions across 13 files

## [1.0.0]

### Added
- **Modular Package Structure**: Refactored from monolithic file to organized package with 8 focused modules
  - `config.py` - Configuration management with priority system
  - `console.py` - Rich console singleton
  - `llm.py` - LLM operations and summarization
  - `main.py` - Main event loop and CLI logic
  - `session.py` - Session persistence
  - `utils.py` - Utility functions (token counting, header, connection check)
  - `__init__.py` - Package exports and public API
  - `__main__.py` - Module entry point for `python -m zorac`

- **Configurable Parameters**: All token limits and model parameters are now configurable
  - `MAX_INPUT_TOKENS` (default: 12000)
  - `MAX_OUTPUT_TOKENS` (default: 4000)
  - `KEEP_RECENT_MESSAGES` (default: 6)
  - `TEMPERATURE` (default: 0.1)
  - `STREAM` (default: true)

- **Multiple Configuration Methods**:
  - Environment variables via `.env` file
  - Persistent configuration file (`~/.zorac/config.json`)
  - Runtime configuration via `/config` command

- **Configuration Management**:
  - `/config list` - View all current settings
  - `/config set <KEY> <VALUE>` - Update settings at runtime
  - `/config get <KEY>` - Retrieve specific setting value
  - Configuration priority: Environment Variables > Config File > Defaults

- **Non-Streaming Mode**: Support for disabling real-time streaming (`STREAM=false`)

- **Type Safety**: Full type annotations with mypy validation
  - Added type hints for all configuration functions
  - Proper handling of int, float, and bool settings

- **Organized Configuration**:
  - Centralized `~/.zorac/` directory for all user data
  - Session storage: `~/.zorac/session.json`
  - Command history: `~/.zorac/history`
  - Configuration: `~/.zorac/config.json`

- **First-Run Setup Wizard**: Interactive configuration on first launch
  - Prompts for vLLM server URL and model name
  - Creates configuration file at `~/.zorac/config.json`
  - Only runs once, on first startup
  - Can be reconfigured anytime with `/config` command

- **Multi-line Input Support**: Enhanced input handling for better user experience
  - Paste multi-line text directly from clipboard
  - Newlines are preserved when pasting
  - Press Enter to submit prompt
  - Prevents treating each pasted line as separate prompt

- **Binary Releases**: Automated build system for distribution
  - Pre-built binaries for Linux (x86_64) and macOS (ARM64)
  - Automated builds via GitHub Actions
  - No Python installation required for end users

- **Modular Documentation**: Reorganized documentation for better navigation
  - Separate guides for Installation, Configuration, Usage, and Development
  - All documentation consolidated in `docs/` directory
  - Cleaner, more focused README as navigation hub

### Changed
- **Architecture**: Transitioned from single-file to modular package structure for better maintainability
- **Entry Points**: Now supports three execution methods:
  - `python -m zorac` (module execution)
  - `zorac` (console script after installation)
  - `uv run zorac` (via uv)
- **Status**: Promoted to Production/Stable (Development Status: 5)
- **Platform Support**: Linux and macOS officially supported (Windows users can use WSL)

### Improved
- **Code Organization**: 53% reduction in perceived complexity through modularization
- **Testability**: Each module can be tested independently
- **Documentation**: Comprehensive updates to README.md, CLAUDE.md, and CONTRIBUTING.md
- **Configuration Flexibility**: Users can adjust all parameters without code changes
- **Code Coverage**: Improved test coverage to 37% with 28 passing tests

### Technical Details
- Python 3.13+ required
- Full mypy type checking support
- Ruff linting compliance
- Pre-commit hooks configuration
- Comprehensive test suite (28 tests, 100% passing)

### Migration Notes
For users upgrading from development versions:
- Session file moved from `~/.zorac_session.json` to `~/.zorac/session.json`
- Run `mkdir -p ~/.zorac && mv ~/.zorac_session.json ~/.zorac/session.json` to migrate
- All previous environment variables still work as before
- New configuration options are optional with sensible defaults

[1.3.0]: https://github.com/chris-colinsky/zorac/releases/tag/v1.3.0
[1.2.0]: https://github.com/chris-colinsky/zorac/releases/tag/v1.2.0
[1.1.0]: https://github.com/chris-colinsky/zorac/releases/tag/v1.1.0
[1.0.0]: https://github.com/chris-colinsky/zorac/releases/tag/v1.0.0
