# Changelog

All notable changes to this project will be documented in this file.

## [0.1.0]

### Forth Language

**Bracket syntax `[ ... ]`**
- `[ v1 v2 v3 ]` pushes all items plus their count. Sugar for `v1 v2 v3 3`.

**New words:**
- `index` — select item at explicit index (wraps with modulo).
- `pbounce` — ping-pong cycle keyed by pattern iteration (vs `bounce` which is step-keyed).
- `except` — inverse of `every`: run quotation on all iterations except every nth.
- `every+` / `except+` — `every`/`except` with a phase offset.
- `all` / `noall` — apply current params globally to all emitted sounds; clear global params.
- `linmap` / `expmap` — linear and exponential range mapping.
- `rec` / `overdub` (`dub`) — toggle recording/overdubbing master audio to a named sample.
- `orec` / `odub` — toggle recording/overdubbing a single orbit to a named sample.

**Harmony and voicing words:**
- `key!` — set tonal center for scale operations.
- `triad` / `seventh` — diatonic triad/seventh from scale degree (follows a scale word).
- `inv` / `dinv` — chord inversion / down inversion.
- `drop2` / `drop3` — drop-2 / drop-3 voicings.
- `tp` — transpose all ints on stack by N semitones.

**New chord types:**
- `pwr`, `augmaj7`, `7sus4`, `9sus4`, `maj69`, `min69`, `maj11`, `maj13`, `min13`, `dom7s11`.

**Ducking compressor params:**
- `comp`, `compattack`/`cattack`, `comprelease`/`crelease`, `comporbit`/`corbit`.

### Engine
- SF2 soundfont support: auto-scans sample directories for `.sf2` files and loads them.
- Audio stream errors surfaced as flash messages instead of printing to stderr.

### UI / Visualization
- Lissajous XY scope: stereo phase display using Braille characters, togglable via Options.
- Gain boost (1x–16x) and normalize toggle for scope/lissajous/spectrum.
- Pattern description field: editable via `d` on Patterns page, shown in pattern row and properties.
- Mute/solo on main page now apply immediately (no staging).
- 10 bundled demo projects loaded on fresh startup (togglable in Options).

### Themes
- 5 new themes: Iceberg, Everforest, Fauve, Tropicalia, Jaipur.

### Desktop (egui)
- Fixed Alt/Option key on macOS (dead-key composition now works).
- Fixed multi-character text paste.
- Extended function key support (F13–F20).

### Fixed
- CycleList + ArpList index collision: arp uses timing index, cycle uses polyphony slot.
- Scope widget not drawing completely in some terminal sizes.

### Documentation
- New tutorials: Recording (`docs/tutorials/recording.md`), Soundfonts (`docs/tutorials/soundfont.md`).

### UI / UX (breaking cosmetic changes)
- **Options page**: Each option now shows a short description line below when focused, replacing the static header box.
- **Dictionary page**: Removed the Forth description box at the top. The word list now uses the full page height.

### CLAP Plugin (experimental)
- Early CLAP plugin support via nih-plug, baseview, and egui. Feature-gated builds separate CLI from plugin targets.

### Forth Language
- Removed `chain` word (replaced by pattern-level Follow Up setting).
- `case/of/endof/endcase` control flow for pattern-matching dispatch.
- `bjork` / `pbjork` — euclidean rhythm gates using quotations: execute a block only on Bjorklund-distributed hits.
- `arp` — arpeggio list type that spreads notes across time positions instead of stacking them simultaneously.
- `,varname` assignment syntax (SetKeep): assign to a variable without consuming the value from the stack.
- `every` reworked to accept quotations for cleaner conditional step logic.
- All parameter words now accept varargs — over 100 words updated to consume the full stack.
- Reverb parameter words added.

### Engine
- Follow-up actions: patterns now have a configurable follow-up behavior (Loop, Stop, or Chain to another pattern). Replaces the Forth `chain` word with a declarative setting in the Pattern Properties modal (`e` key). Chain targets specify bank and pattern via UI fields.
- Delta-time MIDI scheduling for tighter, sample-accurate timing.
- Tempo and current beat exposed in sequencer snapshot.
- Spectrum analyzer rescaling.

### UI / UX
- Patterns view redesign: new layout with banks column (showing pattern counts), expandable detail rows for the focused pattern (quantization, sync mode, progress bar), and a bottom preview strip with mini step grid and pattern properties.
- Smooth playback progress: playing patterns display a real-time progress bar interpolated between steps.
- Dynamic step grid sizing: `steps_per_page` adapts to terminal height instead of using a fixed constant.
- Mouse support: click navigation on the pattern grid, panels, and modals.
- F1–F6 page navigation across the 3×2 page grid.
- Collapsible help sections with code block copy.
- Onboarding system for first-time users.
- New reusable widgets: CategoryList, HintBar, PropsForm, ScrollIndicators, SearchBar, SectionHeader.
- Show/hide preview pane toggle and zoom factor setting.

### Documentation
- Complete reorganization into `docs/` subdirectories.
- 10 getting-started guides, 5 interactive tutorials.
- New topics: control flow, generators, harmony, randomness, variables, timing.

### Theme System
- Palette-based generation: all 18 themes now derived from a 14-field Palette via Oklab color space.
- Theme definitions reduced from ~300 lines each to ~20 lines.

### Codebase
- `src/app.rs` split into 10 focused modules (dispatch, clipboard, editing, navigation, persistence, scripting, sequencer, staging, undo).
- `src/input.rs` split into 8 page-specific handlers.
- Undo/redo system with scope-based tracking.
- Feature-gated CLI vs plugin builds.

## [0.0.9]

### Website
- Compressed screenshot images: resized to 1600px and converted PNG to WebP (8MB → 538KB).
- Version number displayed in subtitle, read automatically from `Cargo.toml` at build time.

### Added
- `arp` word for arpeggios: wraps stack values into an arpeggio list that spreads notes across time positions instead of playing them all simultaneously. With explicit `at` deltas, arp items zip with deltas (cycling the shorter list); without `at`, the step is auto-subdivided evenly. Example: `sine s c4 e4 g4 b4 arp note .` plays a 4-note arpeggio across the step.
- Resolved value annotations: nondeterministic words (`rand`, `choose`, `cycle`, `bounce`, `wchoose`, `coin`, `chance`, `prob`, `exprand`, `logrand`) now display their resolved value inline (e.g., `choose [sine]`, `rand [7]`, `chance [yes]`) during playback in both Preview and Editor modals.
- Inline sample finder in the editor: press `Ctrl+B` to open a fuzzy-search popup of all sample folder names. Type to filter, `Ctrl+N`/`Ctrl+P` to navigate, `Tab`/`Enter` to insert the folder name at cursor, `Esc` to dismiss. Mutually exclusive with word completion.
- Sample browser now displays the 0-based file index next to each sample name, making it easy to reference samples by index in Forth scripts (e.g., `"drums" bank 0 n`).

### Improved
- Header bar stats block (CPU/voices/Link peers) is now centered like all other header sections.
- CPU percentage changes color when load is high: accent color at 50%+, error color at 80%+.
- Extracted 6 reusable TUI components into `cagire-ratatui`: `CategoryList`, `render_scroll_indicators`, `render_search_bar`, `render_section_header`, `render_props_form`, `hint_line`. Reduces duplication across views.

### Fixed
- Soundless emits (e.g., `1 gain .`) no longer stack infinite voices. All emitted commands now receive a default duration of one beat unless the user explicitly sets `dur`. Use `0 dur` for intentionally infinite voices.

## [0.0.8] - 2026-02-07

### Fixed
- macOS `.pkg` installer bundle relocation: disabled `BundleIsRelocatable` so `Cagire.app` always installs to `/Applications/` instead of being redirected to an existing bundle location.

### Added
- Syntax highlighting for user-defined Forth words: words created with `: name ... ;` now render with a distinct color in both the editor and step preview, instead of dimmed gray.
- Multi-selection in Patterns view: Shift+Up/Down selects adjacent ranges of banks or patterns using anchor-based selection. Works with copy/paste (Ctrl+C/V), reset (Delete), toggle play (`p`), mute (`m`), and solo (`x`). Selection is column-scoped and clears on plain arrows, column switch, or Esc. Single-only actions (rename, pattern props, enter) are disabled during multi-selection.
- Audio-rate modulation DSL: LFO words (`lfo`, `tlfo`, `wlfo`, `qlfo` for sine/triangle/sawtooth/square), transition envelopes (`slide`, `expslide`, `sslide` for linear/exponential/smooth), random modulation (`jit`, `sjit`, `drunk` for random hold/smooth random/drunk walk), and multi-segment envelope (`env`). These produce modulation strings consumed by parameter words for continuous audio-rate control.
- Feedback delay FX words: `feedback`/`fb` (level), `fbtime`/`fbt` (delay time), `fbdamp`/`fbd` (damping), `fblfo` (LFO rate), `fblfodepth` (LFO depth), `fblfoshape` (LFO shape).
- `bounce` word: ping-pong cycle through n items by step runs (e.g., `60 64 67 72 4 bounce` → 60 64 67 72 67 64 60 64...).
- `wchoose` word: weighted random selection from n value/weight pairs (e.g., `60 0.6  64 0.3  67 0.1  3 wchoose`). Supports quotations.
- New themes: **Eden** (dark forest — green-only palette on black), **Georges** (Commodore 64 palette on black), **Ember** (warm dark tones), **Letz Light** (light theme).
- Proper desktop app icon and metadata across all platforms: moved icon to `assets/Cagire.png`, added Windows `.exe` icon and file properties embedding via `winres` build script, added PNG to cargo-bundle icon list for Linux `.deb` packaging.
- Universal macOS `.pkg` installer in CI: combines Intel and Apple Silicon builds into fat binaries via `lipo`, then packages `Cagire.app` and CLI into a single `.pkg` installer.
- Waveform rendering widget in the TUI.

### Improved
- Sample library browser: search now shows folder names only (no files) while typing, sorted by fuzzy match score. After confirming search with Enter, folders can be expanded and collapsed normally. Esc clears the search filter before closing the panel. Left arrow on a file collapses the parent folder. Cursor and scroll position stay valid after expand/collapse operations.
- RAM optimizations saving ~5 MB at startup plus smaller enums and fewer hot-path allocations:
  - Removed dead `Step::command` field (~3.1 MB)
  - Narrowed `Step::source` from `Option<usize>` to `Option<u8>` (~1.8 MB)
  - `Op::SetParam` and `Op::GetContext` now use `&'static str` instead of `String`
  - `SourceSpan` fields narrowed from `usize` to `u32`
  - Dirty pattern tracking uses fixed `[[bool; 32]; 32]` array instead of `HashSet`
  - Boxed `FileBrowserState` in `Modal` enum to shrink all variants
  - `StepContext::cc_access` borrows instead of cloning `Arc<dyn CcAccess>`
  - Removed unnecessary `Arc` wrapper from `Stack` type
  - Variable key cache computes on-demand with reusable buffers instead of pre-allocating 2048 Strings
- Render pipeline: background fill uses `Clear` widget instead of generating blank paragraph lines.

### Fixed
- Sequencer sync: auto-loaded patterns now use PhaseLock instead of Reset, so they align to the global beat grid and stay in sync with manually-started patterns.
- PhaseLock off-by-one: start step calculation now uses the frontier beat instead of the lookahead end, eliminating a systematic 1-step offset.
- Stale pattern cache on load: dirty patterns are now flushed before queued start/stop changes, ensuring pattern data arrives before activation.
- Loading while paused no longer drops auto-started patterns; pending starts are preserved and activate on resume.

### Changed
- Header bar is now always 3 lines tall with vertically centered content and full-height background colors, replacing the previous 1-or-2-line width-dependent layout.
- Help view Welcome page: BigText title is now gated behind `cfg(not(feature = "desktop"))`, falling back to a plain text title in the desktop build (same strategy as the splash screen).
- Space now toggles play/pause on all views, including the Patterns page where it previously toggled pattern play. Pattern play on the Patterns page is now bound to `p`.

## [0.0.7] - 2026-05-02

### Added
- 3-operator FM synthesis words: `fm2` (operator 2 depth), `fm2h` (operator 2 harmonic ratio), `fmalgo` (algorithm: 0=cascade, 1=parallel, 2=branch), `fmfb` (feedback amount). Extends the existing 2-OP FM engine to a full 3-OP architecture with configurable routing and operator feedback.
- Background head-preload for sample libraries. At startup, a background thread decodes the first 4096 frames (~93ms) of every sample into RAM. Short samples (most percussion/drums) are fully captured and play instantly on first trigger. Eliminates first-hit misses for live performance.
- Most changes are on doux side. It makes sense to recompile and release now to ship a version that comes with these improvements.

### Fixed
- Code editor now scrolls vertically to keep the cursor visible. Previously, lines beyond the visible area were clipped and the cursor could move off-screen.

## [0.0.6] - 2026-05-02

### Added
- TachyonFX based animations
- Prelude: project-level Forth script for persistent word definitions. Press `d` to edit, `D` to re-evaluate. Runs automatically on playback start and project load.
- Varargs stack words: `rev`, `shuffle`, `sort` (ascending), `rsort` (descending), `sum`, `prod`. All take a count and operate on the top n items.
- Euclidean rhythm words: `euclid` (k n -- hits) distributes k hits across n steps, `euclidrot` (k n r -- hits) adds rotation offset.
- Shorthand float syntax: `.25` parses as `0.25`, `-.5` parses as `-0.5`.

### Changed
- Split `words.rs` (3,078 lines) into a `words/` directory module with category-based files: `core.rs`, `sound.rs`, `effects.rs`, `sequencing.rs`, `music.rs`, `midi.rs`, plus `compile.rs` and `mod.rs`.
- Renamed `tri` Forth word to `triangle`.
- Sequencer rewritten with prospective lookahead scheduling. Instead of sleeping until a substep, waking late, and detecting past events, the sequencer now pre-computes all events within a ~20ms forward window. Events arrive at doux with positive time deltas, scheduled before they need to fire. Sleep+spin-wait replaced by `recv_timeout(3ms)` on the command channel. Timing no longer depends on OS sleep precision.
- `audio_sample_pos` updated at buffer start instead of end, so `engine_time` reflects current playback position.
- Doux grace period increased from 1ms to 50ms as a safety net (events should never be late with lookahead).
- Flattened model re-export indirection; `script.rs` now exports only `ScriptEngine`.
- Hue rotation step size increased from 1° to 5° for faster adjustment.
- Moved catalog data (DOCS, CATEGORIES) from views to `src/model/`, eliminating state-to-view layer inversion.
- Extracted shared initialization into `src/init.rs`, deduplicating ~140 lines between terminal and desktop binaries.
- Split App dispatch into focused service modules (`help_nav`, `dict_nav`, `euclidean`, `clipboard`, extended `pattern_editor`), reducing `app.rs` by ~310 lines.
- Moved stack preview computation from render path to input time, making editor rendering pure.
- Decoupled script runtime state between UI and sequencer threads, eliminating shared mutexes on the RT path.

### Fixed
- Prelude content no longer leaks into step editor. Closing the prelude editor now restores the current step's content to the buffer.
- Desktop binary now loads color theme and connects MIDI devices on startup (was missing).
- Audio commands no longer silently dropped when channel is full; switched to unbounded channel matching MIDI dispatch pattern.
- PatternProps and EuclideanDistribution modals now use the global theme background instead of the terminal default.
- Changing pattern properties is now a stage/commit operation.
- Changing pattern speed only happens at pattern boundaries.
- `mlockall` warning no longer appears on macOS; memory locking is now Linux-only.
- `clear` now resets `at` deltas, so subsequent emits default to a single emit at position 0.

## [0.0.5] - 2026-04-02

### Added
- Mute/solo for patterns: stage with `m`/`x`, commit with `c`. Solo mutes all other patterns. Clear with `M`/`X`.
- Lookahead scheduling: scripts are pre-evaluated ahead of time and audio commands are scheduled at precise beat positions, improving timing accuracy under CPU load.
- Realtime thread scheduling (`SCHED_FIFO`) for sequencer thread on Unix systems, improving timing reliability.
- Deep into the Linux hellscape: trying to get reliable performance, better stability, etc.

### Fixed
- Editor completion popup no longer steals arrow keys. Arrow keys always move the cursor; use Ctrl+N/Ctrl+P to navigate the completion list.

## [0.0.4] - 2026-02-02

### Added
- Double-stack words: `2dup`, `2drop`, `2swap`, `2over`.
- `forget` word to remove user-defined words from the dictionary.
- Active patterns panel showing playing patterns with bank, pattern, iteration count, and step position.
- Configurable visualization layout (Top/Bottom/Left/Right) for scope and spectrum placement.
- Euclidean distribution modal to spread a step's script across the pattern using Euclidean rhythms.
- Fairyfloss theme (pastel candy colors by sailorhg).
- Hot Dog Stand theme (classic Windows 3.1 red/yellow).
- Hue rotation option in Options menu to shift all theme colors (0-360°).

### Changed
- Title view now adapts to smaller terminal sizes gracefully.

### Fixed
- Scope/spectrum ratio asymmetry in Left/Right layout modes.
- Updated `cpal` dependency from 0.15 to 0.17 to fix type mismatch with `doux` audio backend.
- Copy/paste (Ctrl+C/V/X) not working in desktop version due to egui intercepting clipboard shortcuts.

## [0.0.3] - 2026-02-02

### Added
- Polyphonic parameters: param words (`note`, `freq`, `gain`, etc.) and sound words now consume the entire stack, enabling polyphony (e.g., `60 64 67 note sine s .` emits 3 voices).
- New random distribution words: `exprand` (exponential) and `logrand` (logarithmic).
- Music theory chord words: `maj`, `m`, `dim`, `aug`, `sus2`, `sus4`, `maj7`, `min7`, `dom7`, `dim7`, `m7b5`, `minmaj7`, `aug7`, `maj6`, `min6`, `dom9`, `maj9`, `min9`, `dom11`, `min11`, `dom13`, `add9`, `add11`, `madd9`, `dom7b9`, `dom7s9`, `dom7b5`, `dom7s5`.
- Playing patterns are now saved with the project and restored on load.

### Changed
- `at` now consumes the entire stack for time offsets; polyphony multiplies with deltas (2 notes × 2 times = 4 voices).
- Iterator (`iter`) now resets when a pattern restarts.
- Project loading now properly resets state: stops all patterns, clears user variables/dictionary, and clears queued changes.

### Removed
- `tcycle` word (replaced by polyphonic parameter behavior).

## [0.0.2] - 2026-02-01
- CI testing and codebase cleanup

## [0.0.1] - Initial Release
- CI testing
