free-coding-models 0.2.13 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ---
4
4
 
5
+ ## 0.2.15
6
+
7
+ ### Changed
8
+ - **Changelog scrolling experience**: Circular wrap-around scrolling in changelog details (N key) — up at the top now wraps to the bottom, down at the bottom wraps to the top. PageUp/PageDown also wrap for seamless infinite browsing, just like the main TUI list navigation. Home/End still jump to absolute first/last positions for quick access.
9
+
10
+ ---
11
+
12
+ ## 0.2.14
13
+
14
+ ### Fixed
15
+ - **Changelog scrolling viewport**: Scrolling in changelog details (N key) now respects viewport boundaries — content no longer scrolls beyond visible area. Down/PageDown/End keys now properly clamp to max scroll offset so you can view all content without it disappearing off screen.
16
+
17
+ ---
18
+
5
19
  ## 0.2.13
6
20
 
7
21
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "free-coding-models",
3
- "version": "0.2.13",
3
+ "version": "0.2.15",
4
4
  "description": "Find the fastest coding LLM models in seconds — ping free models from multiple providers, pick the best one for OpenCode, Cursor, or any AI coding assistant.",
5
5
  "keywords": [
6
6
  "nvidia",
@@ -820,12 +820,65 @@ export function createKeyHandler(ctx) {
820
820
  state.changelogScrollOffset = 0
821
821
  return
822
822
  }
823
- if (key.name === 'up') { state.changelogScrollOffset = Math.max(0, state.changelogScrollOffset - 1); return }
824
- if (key.name === 'down') { state.changelogScrollOffset += 1; return }
825
- if (key.name === 'pageup') { state.changelogScrollOffset = Math.max(0, state.changelogScrollOffset - pageStep); return }
826
- if (key.name === 'pagedown') { state.changelogScrollOffset += pageStep; return }
823
+
824
+ // 📖 Calculate total content lines for proper scroll boundary clamping
825
+ const calcChangelogLines = () => {
826
+ const lines = []
827
+ lines.push(` 🚀 free-coding-models`)
828
+ lines.push(` 📋 v${state.changelogSelectedVersion}`)
829
+ lines.push(` — ↑↓ / PgUp / PgDn scroll • B back • Esc close`)
830
+ lines.push('')
831
+ const changes = versions[state.changelogSelectedVersion]
832
+ if (changes) {
833
+ const sections = { added: '✨ Added', fixed: '🐛 Fixed', changed: '🔄 Changed', updated: '📝 Updated' }
834
+ for (const [key, label] of Object.entries(sections)) {
835
+ if (changes[key] && changes[key].length > 0) {
836
+ lines.push(` ${label}`)
837
+ for (const item of changes[key]) {
838
+ let displayText = item.replace(/\*\*([^*]+)\*\*/g, '$1').replace(/`([^`]+)`/g, '$1')
839
+ const maxWidth = state.terminalCols - 16
840
+ if (displayText.length > maxWidth) {
841
+ displayText = displayText.substring(0, maxWidth - 3) + '…'
842
+ }
843
+ lines.push(` • ${displayText}`)
844
+ }
845
+ lines.push('')
846
+ }
847
+ }
848
+ }
849
+ return lines.length
850
+ }
851
+ const totalChangelogLines = calcChangelogLines()
852
+ const viewportRows = Math.max(1, state.terminalRows || 1)
853
+ const maxScrollOffset = Math.max(0, totalChangelogLines - viewportRows)
854
+
855
+ // 📖 Circular wrap-around scrolling: up at top → bottom, down at bottom → top
856
+ if (key.name === 'up') {
857
+ state.changelogScrollOffset = state.changelogScrollOffset > 0
858
+ ? state.changelogScrollOffset - 1
859
+ : maxScrollOffset
860
+ return
861
+ }
862
+ if (key.name === 'down') {
863
+ state.changelogScrollOffset = state.changelogScrollOffset < maxScrollOffset
864
+ ? state.changelogScrollOffset + 1
865
+ : 0
866
+ return
867
+ }
868
+ if (key.name === 'pageup') {
869
+ state.changelogScrollOffset = state.changelogScrollOffset >= pageStep
870
+ ? state.changelogScrollOffset - pageStep
871
+ : maxScrollOffset - (pageStep - state.changelogScrollOffset - 1)
872
+ return
873
+ }
874
+ if (key.name === 'pagedown') {
875
+ state.changelogScrollOffset = state.changelogScrollOffset + pageStep <= maxScrollOffset
876
+ ? state.changelogScrollOffset + pageStep
877
+ : (state.changelogScrollOffset + pageStep - maxScrollOffset - 1)
878
+ return
879
+ }
827
880
  if (key.name === 'home') { state.changelogScrollOffset = 0; return }
828
- if (key.name === 'end') { state.changelogScrollOffset = Number.MAX_SAFE_INTEGER; return }
881
+ if (key.name === 'end') { state.changelogScrollOffset = maxScrollOffset; return }
829
882
  }
830
883
 
831
884
  if (key.ctrl && key.name === 'c') { exit(0); return }