free-coding-models 0.3.67 → 0.3.69

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.
Files changed (173) hide show
  1. package/README.md +13 -13
  2. package/changelog/v0.1.1.md +3 -0
  3. package/changelog/v0.1.10.md +3 -0
  4. package/changelog/v0.1.11.md +10 -0
  5. package/changelog/v0.1.12.md +16 -0
  6. package/changelog/v0.1.13.md +3 -0
  7. package/changelog/v0.1.14.md +3 -0
  8. package/changelog/v0.1.15.md +3 -0
  9. package/changelog/v0.1.16.md +13 -0
  10. package/changelog/v0.1.17.md +3 -0
  11. package/changelog/v0.1.18.md +3 -0
  12. package/changelog/v0.1.19.md +3 -0
  13. package/changelog/v0.1.2.md +3 -0
  14. package/changelog/v0.1.20.md +14 -0
  15. package/changelog/v0.1.21.md +12 -0
  16. package/changelog/v0.1.22.md +6 -0
  17. package/changelog/v0.1.23.md +16 -0
  18. package/changelog/v0.1.24.md +9 -0
  19. package/changelog/v0.1.25.md +13 -0
  20. package/changelog/v0.1.26.md +6 -0
  21. package/changelog/v0.1.27.md +6 -0
  22. package/changelog/v0.1.28.md +5 -0
  23. package/changelog/v0.1.29.md +5 -0
  24. package/changelog/v0.1.3.md +3 -0
  25. package/changelog/v0.1.31.md +10 -0
  26. package/changelog/v0.1.32.md +8 -0
  27. package/changelog/v0.1.33.md +5 -0
  28. package/changelog/v0.1.34.md +6 -0
  29. package/changelog/v0.1.35.md +5 -0
  30. package/changelog/v0.1.36.md +16 -0
  31. package/changelog/v0.1.37.md +5 -0
  32. package/changelog/v0.1.38.md +9 -0
  33. package/changelog/v0.1.39.md +3 -0
  34. package/changelog/v0.1.4.md +3 -0
  35. package/changelog/v0.1.40.md +3 -0
  36. package/changelog/v0.1.41.md +11 -0
  37. package/changelog/v0.1.42.md +3 -0
  38. package/changelog/v0.1.43.md +3 -0
  39. package/changelog/v0.1.44.md +17 -0
  40. package/changelog/v0.1.45.md +6 -0
  41. package/changelog/v0.1.46.md +9 -0
  42. package/changelog/v0.1.47.md +6 -0
  43. package/changelog/v0.1.48.md +11 -0
  44. package/changelog/v0.1.49.md +10 -0
  45. package/changelog/v0.1.5.md +3 -0
  46. package/changelog/v0.1.50.md +7 -0
  47. package/changelog/v0.1.51.md +4 -0
  48. package/changelog/v0.1.52.md +10 -0
  49. package/changelog/v0.1.54.md +41 -0
  50. package/changelog/v0.1.55.md +3 -0
  51. package/changelog/v0.1.56.md +11 -0
  52. package/changelog/v0.1.57.md +7 -0
  53. package/changelog/v0.1.58.md +7 -0
  54. package/changelog/v0.1.59.md +7 -0
  55. package/changelog/v0.1.6.md +3 -0
  56. package/changelog/v0.1.60.md +7 -0
  57. package/changelog/v0.1.61.md +9 -0
  58. package/changelog/v0.1.62.md +9 -0
  59. package/changelog/v0.1.63.md +15 -0
  60. package/changelog/v0.1.64.md +22 -0
  61. package/changelog/v0.1.65.md +15 -0
  62. package/changelog/v0.1.66.md +22 -0
  63. package/changelog/v0.1.67.md +40 -0
  64. package/changelog/v0.1.68.md +38 -0
  65. package/changelog/v0.1.69.md +3 -0
  66. package/changelog/v0.1.7.md +3 -0
  67. package/changelog/v0.1.70.md +7 -0
  68. package/changelog/v0.1.71.md +7 -0
  69. package/changelog/v0.1.72.md +7 -0
  70. package/changelog/v0.1.73.md +7 -0
  71. package/changelog/v0.1.74.md +3 -0
  72. package/changelog/v0.1.75.md +9 -0
  73. package/changelog/v0.1.76.md +13 -0
  74. package/changelog/v0.1.77.md +13 -0
  75. package/changelog/v0.1.78.md +7 -0
  76. package/changelog/v0.1.79.md +8 -0
  77. package/changelog/v0.1.8.md +3 -0
  78. package/changelog/v0.1.80.md +7 -0
  79. package/changelog/v0.1.81.md +19 -0
  80. package/changelog/v0.1.82.md +9 -0
  81. package/changelog/v0.1.83.md +22 -0
  82. package/changelog/v0.1.84.md +25 -0
  83. package/changelog/v0.1.85.md +19 -0
  84. package/changelog/v0.1.86.md +17 -0
  85. package/changelog/v0.1.87.md +7 -0
  86. package/changelog/v0.1.88.md +167 -0
  87. package/changelog/v0.1.89.md +22 -0
  88. package/changelog/v0.1.9.md +3 -0
  89. package/changelog/v0.2.0.md +30 -0
  90. package/changelog/v0.2.1.md +17 -0
  91. package/changelog/v0.2.10.md +7 -0
  92. package/changelog/v0.2.11.md +6 -0
  93. package/changelog/v0.2.12.md +16 -0
  94. package/changelog/v0.2.13.md +16 -0
  95. package/changelog/v0.2.14.md +6 -0
  96. package/changelog/v0.2.15.md +6 -0
  97. package/changelog/v0.2.17.md +14 -0
  98. package/changelog/v0.2.2.md +16 -0
  99. package/changelog/v0.2.3.md +7 -0
  100. package/changelog/v0.2.4.md +7 -0
  101. package/changelog/v0.2.5.md +12 -0
  102. package/changelog/v0.2.7.md +3 -0
  103. package/changelog/v0.2.8.md +107 -0
  104. package/changelog/v0.2.9.md +10 -0
  105. package/changelog/v0.3.0.md +30 -0
  106. package/changelog/v0.3.1.md +17 -0
  107. package/changelog/v0.3.11.md +20 -0
  108. package/changelog/v0.3.12.md +18 -0
  109. package/changelog/v0.3.13.md +4 -0
  110. package/changelog/v0.3.14.md +6 -0
  111. package/changelog/v0.3.15.md +4 -0
  112. package/changelog/v0.3.16.md +3 -0
  113. package/changelog/v0.3.17.md +4 -0
  114. package/changelog/v0.3.18.md +12 -0
  115. package/changelog/v0.3.19.md +12 -0
  116. package/changelog/v0.3.2.md +5 -0
  117. package/changelog/v0.3.21.md +13 -0
  118. package/changelog/v0.3.22.md +29 -0
  119. package/changelog/v0.3.23.md +12 -0
  120. package/changelog/v0.3.24.md +34 -0
  121. package/changelog/v0.3.25.md +40 -0
  122. package/changelog/v0.3.26.md +85 -0
  123. package/changelog/v0.3.28.md +3 -0
  124. package/changelog/v0.3.29.md +107 -0
  125. package/changelog/v0.3.3.md +11 -0
  126. package/changelog/v0.3.30.md +3 -0
  127. package/changelog/v0.3.31.md +113 -0
  128. package/changelog/v0.3.32.md +123 -0
  129. package/changelog/v0.3.33.md +129 -0
  130. package/changelog/v0.3.34.md +156 -0
  131. package/changelog/v0.3.35.md +173 -0
  132. package/changelog/v0.3.36.md +186 -0
  133. package/changelog/v0.3.37.md +182 -0
  134. package/changelog/v0.3.38.md +3 -0
  135. package/changelog/v0.3.39.md +3 -0
  136. package/changelog/v0.3.4.md +9 -0
  137. package/changelog/v0.3.40.md +18 -0
  138. package/changelog/v0.3.41.md +7 -0
  139. package/changelog/v0.3.42.md +9 -0
  140. package/changelog/v0.3.43.md +13 -0
  141. package/changelog/v0.3.44.md +10 -0
  142. package/changelog/v0.3.45.md +12 -0
  143. package/changelog/v0.3.46.md +5 -0
  144. package/changelog/v0.3.47.md +4 -0
  145. package/changelog/v0.3.48.md +10 -0
  146. package/changelog/v0.3.49.md +18 -0
  147. package/changelog/v0.3.5.md +5 -0
  148. package/changelog/v0.3.50.md +41 -0
  149. package/changelog/v0.3.51.md +37 -0
  150. package/changelog/v0.3.52.md +43 -0
  151. package/changelog/v0.3.54.md +55 -0
  152. package/changelog/v0.3.55.md +62 -0
  153. package/changelog/v0.3.56.md +53 -0
  154. package/changelog/v0.3.57.md +61 -0
  155. package/changelog/v0.3.58.md +10 -0
  156. package/changelog/v0.3.59.md +3 -0
  157. package/changelog/v0.3.6.md +12 -0
  158. package/changelog/v0.3.60.md +3 -0
  159. package/changelog/v0.3.61.md +3 -0
  160. package/changelog/v0.3.62.md +3 -0
  161. package/changelog/v0.3.63.md +20 -0
  162. package/changelog/v0.3.64.md +10 -0
  163. package/changelog/v0.3.65.md +10 -0
  164. package/changelog/v0.3.66.md +17 -0
  165. package/{CHANGELOG.md → changelog/v0.3.67.md} +1 -1
  166. package/changelog/v0.3.68.md +18 -0
  167. package/changelog/v0.3.69.md +47 -0
  168. package/changelog/v0.3.9.md +10 -0
  169. package/package.json +2 -2
  170. package/sources.js +98 -74
  171. package/src/changelog-loader.js +41 -41
  172. package/web/dist/assets/{index-DCwSuNgI.js → index-CugpJNf7.js} +1 -1
  173. package/web/dist/index.html +1 -1
package/sources.js CHANGED
@@ -50,8 +50,6 @@ export const nvidiaNim = [
50
50
  ['stepfun-ai/step-3.5-flash', 'Step 3.5 Flash', 'S+', '74.4%', '256k'],
51
51
  ['qwen/qwen3-coder-480b-a35b-instruct', 'Qwen3 Coder 480B', 'S+', '70.6%', '256k'],
52
52
  // ── S tier — SWE-bench Verified 60–70% ──
53
- ['minimaxai/minimax-m2', 'MiniMax M2', 'S', '69.4%', '128k'],
54
- ['qwen/qwen3-next-80b-a3b-thinking', 'Qwen3 80B Thinking', 'S', '68.0%', '128k'],
55
53
  ['qwen/qwen3-next-80b-a3b-instruct', 'Qwen3 80B Instruct', 'S', '65.0%', '128k'],
56
54
  ['qwen/qwen3.5-397b-a17b', 'Qwen3.5 400B VLM', 'S', '68.0%', '128k'],
57
55
  ['openai/gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
@@ -60,37 +58,37 @@ export const nvidiaNim = [
60
58
  ['mistralai/mistral-small-4-119b-2603', 'Mistral Small 4', 'S', '60.0%', '128k'],
61
59
  ['qwen/qwen3.5-122b-a10b', 'Qwen3.5 122B', 'S', '64.0%', '128k'],
62
60
  // ── A+ tier — SWE-bench Verified 50–60% ──
63
- ['nvidia/llama-3.1-nemotron-ultra-253b-v1', 'Nemotron Ultra 253B', 'A+', '56.0%', '128k'],
64
61
  ['mistralai/mistral-large-3-675b-instruct-2512', 'Mistral Large 675B', 'A+', '58.0%', '256k'],
65
62
  ['nvidia/nemotron-3-super-120b-a12b', 'Nemotron 3 Super', 'A+', '56.0%', '128k'],
66
63
  ['nvidia/nemotron-3-nano-omni-30b-a3b-reasoning','Nemotron 3 Omni', 'A+', '52.0%', '128k'],
67
64
  // ── A tier — SWE-bench Verified 40–50% ──
68
- ['nvidia/llama-3.3-nemotron-super-49b-v1.5', 'Nemotron Super 49B', 'A', '49.0%', '128k'],
69
65
  ['nvidia/nemotron-3-nano-30b-a3b', 'Nemotron Nano 30B', 'A', '43.0%', '128k'],
70
66
  ['openai/gpt-oss-20b', 'GPT OSS 20B', 'A', '42.0%', '128k'],
71
67
  ['google/gemma-4-31b-it', 'Gemma 4 31B', 'A', '45.0%', '256k'],
72
68
  // ── A- tier — SWE-bench Verified 35–40% ──
73
- ['meta/llama-3.3-70b-instruct', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
74
69
  ['bytedance/seed-oss-36b-instruct', 'Seed OSS 36B', 'A-', '38.0%', '32k'],
75
70
  ['stockmark/stockmark-2-100b-instruct', 'Stockmark 100B', 'A-', '36.0%', '32k'],
76
71
  // ── B+ tier — SWE-bench Verified 30–35% ──
77
- ['mistralai/mixtral-8x22b-instruct-v0.1', 'Mixtral 8x22B', 'B+', '32.0%', '64k'],
78
72
  ['mistralai/ministral-14b-instruct-2512', 'Ministral 14B', 'B+', '34.0%', '32k'],
79
- ['ibm/granite-34b-code-instruct', 'Granite 34B Code', 'B+', '30.0%', '32k'],
80
73
  // ── B tier — SWE-bench Verified 20–30% ──
81
- ['meta/llama-3.1-8b-instruct', 'Llama 3.1 8B', 'B', '28.8%', '128k'],
74
+ ['meta/llama-3.2-11b-vision-instruct', 'Llama 3.2 11B Vision','B', '28.0%', '128k'],
82
75
  // ── C tier — SWE-bench Verified <20% or lightweight edge models ──
83
76
  ['microsoft/phi-4-mini-instruct', 'Phi 4 Mini', 'C', '14.0%', '128k'],
77
+ // Removed (2026-05-26): minimax-m2 (deprecated), qwen3-next-80b-a3b-thinking (deprecated),
78
+ // llama-3.1-nemotron-ultra-253b-v1 (404), llama-3.3-nemotron-super-49b-v1.5 (404),
79
+ // llama-3.3-70b-instruct (404), mixtral-8x22b-instruct-v0.1 (404),
80
+ // granite-34b-code-instruct (deprecated), llama-4-scout-17b-16e-instruct (deprecated, not in nvidiaNim),
81
+ // llama-3.1-8b-instruct (404) → replaced by llama-3.2-11b-vision-instruct
84
82
  ]
85
83
 
86
84
  // 📖 Groq source - https://console.groq.com
87
85
  // 📖 Free API keys available at https://console.groq.com/keys
88
86
  export const groq = [
89
- ['llama-3.3-70b-versatile', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
87
+ ['llama-3.3-70b-versatile', 'Llama 3.3 70B', 'A-', '39.5%', '131k'],
90
88
  ['meta-llama/llama-4-scout-17b-16e-instruct', 'Llama 4 Scout', 'A', '44.0%', '131k'],
91
- ['llama-3.1-8b-instant', 'Llama 3.1 8B', 'B', '28.8%', '128k'],
92
- ['openai/gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
93
- ['openai/gpt-oss-20b', 'GPT OSS 20B', 'A', '42.0%', '128k'],
89
+ ['llama-3.1-8b-instant', 'Llama 3.1 8B', 'B', '28.8%', '131k'],
90
+ ['openai/gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '131k'],
91
+ ['openai/gpt-oss-20b', 'GPT OSS 20B', 'A', '42.0%', '131k'],
94
92
  ['qwen/qwen3-32b', 'Qwen3 32B', 'A+', '50.0%', '131k'],
95
93
  ['groq/compound', 'Groq Compound', 'A', '45.0%', '131k'],
96
94
  ['groq/compound-mini', 'Groq Compound Mini', 'B+', '32.0%', '131k'],
@@ -99,10 +97,10 @@ export const groq = [
99
97
  // 📖 Cerebras source - https://cloud.cerebras.ai
100
98
  // 📖 Free API keys available at https://cloud.cerebras.ai
101
99
  export const cerebras = [
102
- ['gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
103
- ['qwen-3-235b-a22b-instruct-2507', 'Qwen3 235B', 'S+', '70.0%', '128k'], // ⚠️ Deprecation: May 27, 2026
104
- ['llama3.1-8b', 'Llama 3.1 8B', 'B', '28.8%', '128k'],
105
- ['zai-glm-4.7', 'GLM 4.7', 'S+', '73.8%', '200k'],
100
+ ['gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '131k'],
101
+ ['zai-glm-4.7', 'GLM 4.7', 'S+', '73.8%', '131k'],
102
+ // Removed (2026-05-26): qwen-3-235b-a22b-instruct-2507 (deprecated May 27, 2026)
103
+ // Removed (2026-05-26): llama3.1-8b (deprecated May 27, 2026)
106
104
  ]
107
105
 
108
106
  // 📖 SambaNova source - https://cloud.sambanova.ai
@@ -110,14 +108,18 @@ export const cerebras = [
110
108
  // 📖 Keep this catalog conservative: only models surfaced in current SambaNova docs.
111
109
  export const sambanova = [
112
110
  // ── S+ tier ──
113
- ['MiniMax-M2.5', 'MiniMax M2.5', 'S+', '74.0%', '160k'],
111
+ ['MiniMax-M2.7', 'MiniMax M2.7', 'S+', '56.2%', '192k'],
114
112
  // ── S tier ──
115
113
  ['DeepSeek-V3.1', 'DeepSeek V3.1', 'S', '62.0%', '128k'],
116
114
  ['DeepSeek-V3.2', 'DeepSeek V3.2', 'S+', '70.0%', '32k'],
117
- ['Llama-4-Maverick-17B-128E-Instruct', 'Llama 4 Maverick', 'S', '62.0%', '1M'],
115
+ ['Llama-4-Maverick-17B-128E-Instruct', 'Llama 4 Maverick', 'S', '62.0%', '128k'],
118
116
  ['gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
119
117
  // ── A- tier ──
120
118
  ['Meta-Llama-3.3-70B-Instruct', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
119
+ // ── B+ tier ──
120
+ ['gemma-3-12b-it', 'Gemma 3 12B IT', 'B+', '46.0%', '128k'],
121
+ // Removed (2026-05-26): MiniMax-M2.5 (deprecated, replaced by MiniMax-M2.7)
122
+ // Fix (2026-05-26): Llama-4-Maverick context 1M → 128k (SambaNova actual limit)
121
123
  ]
122
124
 
123
125
  // 📖 OpenRouter source - https://openrouter.ai
@@ -133,24 +135,24 @@ export const sambanova = [
133
135
  export const openrouter = [
134
136
  // ── S+ tier — live :free chat/coding models ──
135
137
  ['qwen/qwen3-coder:free', 'Qwen3 Coder 480B', 'S+', '70.6%', '262k'],
136
- ['minimax/minimax-m2.5:free', 'MiniMax M2.5', 'S+', '74.0%', '197k'],
138
+ ['minimax/minimax-m2.5:free', 'MiniMax M2.5', 'S+', '80.2%', '197k'],
137
139
  ['z-ai/glm-4.5-air:free', 'GLM 4.5 Air', 'S+', '72.0%', '131k'],
138
- ['tencent/hy3-preview:free', 'Tencent HY3 Preview','S+', '-', '262k'],
139
- ['poolside/laguna-m.1:free', 'Poolside Laguna M.1', 'S+', '-', '256k'],
140
- ['poolside/laguna-xs.2:free', 'Poolside Laguna XS.2','S+', '-', '256k'],
140
+ ['deepseek/deepseek-v4-flash:free', 'DeepSeek V4 Flash', 'S', '-', '1M'],
141
+ ['poolside/laguna-m.1:free', 'Poolside Laguna M.1', 'S+', '-', '131k'],
142
+ ['poolside/laguna-xs.2:free', 'Poolside Laguna XS.2','S+', '-', '131k'],
141
143
  // ── S tier — live :free chat/coding models ──
142
- ['qwen/qwen3-next-80b-a3b-instruct:free', 'Qwen3 80B Instruct', 'S', '65.0%', '131k'],
144
+ ['qwen/qwen3-next-80b-a3b-instruct:free', 'Qwen3 80B Instruct', 'S', '65.0%', '262k'],
143
145
  ['openai/gpt-oss-120b:free', 'GPT OSS 120B', 'S', '60.0%', '131k'],
144
- ['inclusionai/ling-2.6-1t:free', 'Ling 2.6 1T', 'S', '-', '128k'],
146
+ ['arcee-ai/trinity-large-thinking:free', 'Arcee Trinity Large', 'A', '-', '262k'],
145
147
  ['nvidia/nemotron-3-super-120b-a12b:free', 'Nemotron 3 Super', 'A+', '56.0%', '262k'],
146
148
  // ── A+ tier — live :free chat/coding models ──
147
- ['nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free', 'Nemotron 3 Omni', 'A+', '52.0%', '128k'],
149
+ ['nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free', 'Nemotron 3 Omni', 'A+', '52.0%', '256k'],
148
150
  ['nvidia/nemotron-nano-12b-v2-vl:free', 'Nemotron Nano 12B VL','A', '20.0%', '128k'],
149
- ['openrouter/owl-alpha', 'Owl Alpha', 'A+', '-', '128k'],
151
+ ['openrouter/owl-alpha', 'Owl Alpha', 'A+', '-', '1M'],
150
152
  // ── A tier — live :free chat/coding models ──
151
153
  ['nousresearch/hermes-3-llama-3.1-405b:free', 'Hermes 3 405B', 'A', '44.0%', '131k'],
152
154
  ['openai/gpt-oss-20b:free', 'GPT OSS 20B', 'A', '42.0%', '131k'],
153
- ['nvidia/nemotron-3-nano-30b-a3b:free', 'Nemotron Nano 30B', 'A', '43.0%', '128k'],
155
+ ['nvidia/nemotron-nano-30b-a3b:free', 'Nemotron Nano 30B', 'A', '43.0%', '256k'],
154
156
  ['cognitivecomputations/dolphin-mistral-24b-venice-edition:free', 'Dolphin Mistral 24B', 'B+', '30.0%', '33k'],
155
157
  ['google/gemma-4-31b-it:free', 'Gemma 4 31B', 'A', '45.0%', '256k'],
156
158
  ['google/gemma-4-26b-a4b-it:free', 'Gemma 4 26B MoE', 'A-', '38.0%', '256k'],
@@ -159,17 +161,20 @@ export const openrouter = [
159
161
  ['meta-llama/llama-3.2-3b-instruct:free', 'Llama 3.2 3B', 'B', '20.0%', '128k'],
160
162
  // ── B+ tier ──
161
163
  ['nvidia/nemotron-nano-9b-v2:free', 'Nemotron Nano 9B', 'B+', '18.0%', '128k'],
162
- ['google/gemma-3n-e2b-it:free', 'Gemma 3n E2B', 'B+', '-', '8k'],
164
+ ['baidu/cobuddy:free', 'Baidu CoBuddy', 'B+', '-', '131k'],
163
165
  // ── B tier ──
164
- ['google/gemma-3-27b-it:free', 'Gemma 3 27B', 'B', '22.0%', '131k'],
165
- ['google/gemma-4-31b-a4b-it:free', 'Gemma 4 31B MoE', 'B', '-', '256k'],
166
- ['openrouter/free', 'OpenRouter Free', 'B', '-', '128k'],
166
+ ['openrouter/free', 'OpenRouter Free', 'B', '-', '200k'],
167
167
  // ── C tier ──
168
- ['google/gemma-3-12b-it:free', 'Gemma 3 12B', 'C', '15.0%', '131k'],
169
- ['google/gemma-3n-e4b-it:free', 'Gemma 3n E4B', 'C', '10.0%', '8k'],
170
- ['google/gemma-3-4b-it:free', 'Gemma 3 4B', 'C', '10.0%', '33k'],
171
168
  ['liquid/lfm-2.5-1.2b-instruct:free', 'LFM 2.5 1.2B', 'C', '-', '32k'],
172
169
  ['liquid/lfm-2.5-1.2b-thinking:free', 'LFM 2.5 Thinking', 'C', '-', '32k'],
170
+ // Removed (2026-05-26): tencent/hy3-preview:free (free tier removed)
171
+ // Removed (2026-05-26): inclusionai/ling-2.6-1t:free (free tier removed)
172
+ // Removed (2026-05-26): google/gemma-3n-e2b-it:free (free tier removed)
173
+ // Removed (2026-05-26): google/gemma-3-27b-it:free (free tier removed)
174
+ // Removed (2026-05-26): google/gemma-3-12b-it:free (free tier removed)
175
+ // Removed (2026-05-26): google/gemma-3n-e4b-it:free (free tier removed)
176
+ // Removed (2026-05-26): google/gemma-3-4b-it:free (free tier removed)
177
+ // Removed (2026-05-26): google/gemma-4-31b-a4b-it:free (never existed — data error)
173
178
  ]
174
179
 
175
180
  // 📖 GitHub Models source - https://models.github.ai
@@ -190,53 +195,57 @@ export const githubModels = [
190
195
  ['mistral-ai/codestral-2501', 'Codestral 2501', 'B+', '34.0%', '256k'],
191
196
  ['mistral-ai/mistral-medium-2505', 'Mistral Medium 2505', 'A', '48.0%', '128k'],
192
197
  ['mistral-ai/mistral-small-2503', 'Mistral Small 2503', 'B+', '30.0%', '128k'],
193
- ['mistral-ai/ministral-3b', 'Ministral 3B', 'C', '-', '32k'],
198
+ ['mistral-ai/ministral-3b', 'Ministral 3B', 'C', '-', '128k'],
194
199
  ]
195
200
 
196
201
  // 📖 Mistral La Plateforme source - https://console.mistral.ai
197
202
  // 📖 Experiment plan is free for evaluation/prototyping and exposes general + coding models.
198
203
  // 📖 Keep Codestral as a separate provider key for backward compatibility with existing configs.
199
204
  export const mistral = [
200
- ['mistral-large-latest', 'Mistral Large', 'S+', '70.0%', '256k'],
201
- ['mistral-medium-latest', 'Mistral Medium', 'S', '66.0%', '128k'],
202
- ['mistral-small-latest', 'Mistral Small', 'A', '48.0%', '128k'],
203
- ['devstral-medium-latest', 'Devstral Medium', 'S+', '72.2%', '128k'],
204
- ['devstral-small-latest', 'Devstral Small', 'A+', '55.0%', '128k'],
205
- ['magistral-medium-latest', 'Magistral Medium', 'A+', '52.0%', '128k'],
206
- ['magistral-small-latest', 'Magistral Small', 'A', '45.0%', '128k'],
205
+ ['mistral-large-2512', 'Mistral Large 3', 'S+', '70.0%', '256k'],
206
+ ['mistral-medium-3-5', 'Mistral Medium 3.5', 'S+', '77.6%', '256k'],
207
+ ['devstral-2512', 'Devstral 2', 'S+', '72.2%', '256k'],
208
+ ['magistral-medium-2509', 'Magistral Medium 1.2','A+', '52.0%', '128k'],
209
+ ['mistral-small-2603', 'Mistral Small 4', 'A', '48.0%', '256k'],
210
+ // Removed (2026-05-26): devstral-medium-latest (deprecated, replaced by devstral-2512)
211
+ // Removed (2026-05-26): devstral-small-latest (deprecated, replaced by devstral-2512)
212
+ // Removed (2026-05-26): magistral-small-latest (deprecated, replaced by mistral-small-2603)
207
213
  ]
208
214
 
209
215
  // 📖 Mistral Codestral source - https://codestral.mistral.ai
210
216
  // 📖 Free coding model — 30 req/min, 2000/day (phone number required for key)
211
217
  // 📖 API keys now use the Mistral platform key format; CODESTRAL_API_KEY remains supported as an alias.
212
218
  export const codestral = [
213
- ['codestral-latest', 'Codestral', 'B+', '34.0%', '256k'],
219
+ ['codestral-2508', 'Codestral', 'B+', '34.0%', '128k'],
214
220
  ]
215
221
 
216
222
  // 📖 Scaleway source - https://console.scaleway.com
217
223
  // 📖 1M free tokens — API keys at https://console.scaleway.com/iam/api-keys
218
224
  export const scaleway = [
219
- ['devstral-2-123b-instruct-2512', 'Devstral 2 123B', 'S+', '72.2%', '256k'],
225
+ ['devstral-2-123b-instruct-2512', 'Devstral 2 123B', 'S+', '72.2%', '200k'],
220
226
  ['qwen3.5-397b-a17b', 'Qwen3.5 400B VLM', 'S', '68.0%', '250k'],
221
227
  ['mistral/mistral-large-3-675b-instruct-2512','Mistral Large 675B', 'A+', '58.0%', '250k'],
222
- ['qwen3-235b-a22b-instruct-2507', 'Qwen3 235B', 'S+', '70.0%', '128k'],
223
- ['gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '131k'],
224
- ['qwen3-coder-30b-a3b-instruct', 'Qwen3 Coder 30B', 'A+', '55.0%', '32k'],
225
- ['holo2-30b-a3b', 'Holo2 30B', 'A+', '52.0%', '131k'],
226
- ['llama-3.3-70b-instruct', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
228
+ ['qwen3-235b-a22b-instruct-2507', 'Qwen3 235B', 'S+', '70.0%', '250k'],
229
+ ['gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
230
+ ['qwen3-coder-30b-a3b-instruct', 'Qwen3 Coder 30B', 'A+', '55.0%', '128k'],
231
+ ['holo2-30b-a3b', 'Holo2 30B', 'A+', '52.0%', '22k'],
232
+ ['llama-3.3-70b-instruct', 'Llama 3.3 70B', 'A-', '39.5%', '100k'],
227
233
  ['mistral-small-3.2-24b-instruct-2506', 'Mistral Small 3.2', 'B+', '30.0%', '128k'],
228
- ['gemma-3-27b-it', 'Gemma 3 27B', 'B', '22.0%', '128k'],
234
+ ['gemma-3-27b-it', 'Gemma 3 27B', 'B', '22.0%', '40k'],
229
235
  ]
230
236
 
231
237
  // 📖 Google AI Studio source - https://aistudio.google.com
232
238
  // 📖 OpenAI-compatible endpoint exposes Gemini models; free quotas vary by model and region.
233
239
  export const googleai = [
240
+ ['gemini-3.5-flash', 'Gemini 3.5 Flash', 'S+', '-', '1M'],
234
241
  ['gemini-3.1-pro-preview', 'Gemini 3.1 Pro Preview', 'S+', '78.0%', '1M'],
235
242
  ['gemini-3-flash-preview', 'Gemini 3 Flash Preview', 'S', '65.0%', '1M'],
236
- ['gemini-3.1-flash-lite-preview', 'Gemini 3.1 Flash Lite Preview','A+', '55.0%', '1M'],
243
+ ['gemini-3.1-flash-lite', 'Gemini 3.1 Flash Lite', 'A+', '55.0%', '1M'],
244
+ // ⚠️ DEPRECATED — shutdown Oct 16, 2026
237
245
  ['gemini-2.5-pro', 'Gemini 2.5 Pro', 'S+', '63.2%', '1M'],
238
246
  ['gemini-2.5-flash', 'Gemini 2.5 Flash', 'A+', '50.0%', '1M'],
239
247
  ['gemini-2.5-flash-lite', 'Gemini 2.5 Flash Lite', 'A', '42.0%', '1M'],
248
+ // Removed (2026-05-26): gemini-3.1-flash-lite-preview (endpoint shutdown May 25, 2026 → replaced by gemini-3.1-flash-lite)
240
249
  ]
241
250
 
242
251
  // 📖 ZAI source - https://open.z.ai
@@ -254,17 +263,22 @@ export const zai = [
254
263
  // 📖 Qwen3-Coder models: optimized coding models with excellent SWE-bench scores
255
264
  export const qwen = [
256
265
  // ── S+ tier — SWE-bench Verified ≥70% ──
257
- ['qwen3-max', 'Qwen3 Max', 'S+', '78.8%', '1M'],
258
- ['qwen3-235b-a22b-instruct', 'Qwen3 235B', 'S+', '70.0%', '256k'],
266
+ ['qwen3.7-max', 'Qwen3.7 Max', 'S+', '80.0%', '1M'],
267
+ ['qwen3-max', 'Qwen3 Max', 'S+', '78.8%', '256k'],
268
+ ['qwen3.6-plus', 'Qwen3.6 Plus', 'S+', '72.0%', '1M'],
269
+ ['qwen3-235b-a22b', 'Qwen3 235B', 'S+', '70.0%', '256k'],
259
270
  // ── S tier — SWE-bench Verified 60–70% ──
260
271
  ['qwen3.5-plus', 'Qwen3.5 Plus', 'S', '68.0%', '1M'],
261
- ['qwen3-coder-plus', 'Qwen3 Coder Plus', 'S', '69.6%', '256k'],
272
+ ['qwen3-coder-plus', 'Qwen3 Coder Plus', 'S', '69.6%', '1M'],
262
273
  ['qwen3-coder-next', 'Qwen3 Coder Next', 'S', '65.0%', '256k'],
263
274
  // ── A+ tier — SWE-bench Verified 50–60% ──
275
+ ['qwen3.6-flash', 'Qwen3.6 Flash', 'A+', '60.0%', '1M'],
264
276
  ['qwen3.5-flash', 'Qwen3.5 Flash', 'A+', '55.0%', '1M'],
265
- ['qwen3-coder-flash', 'Qwen3 Coder Flash', 'A+', '55.0%', '256k'],
266
- ['qwen3-32b', 'Qwen3 32B', 'A+', '50.0%', '128k'],
267
- ['qwen2.5-coder-32b-instruct', 'Qwen2.5 Coder 32B', 'A', '46.0%', '32k'],
277
+ ['qwen3-coder-flash', 'Qwen3 Coder Flash', 'A+', '55.0%', '1M'],
278
+ ['qwen3-32b', 'Qwen3 32B', 'A+', '50.0%', '256k'],
279
+ // Removed (2026-05-26): qwen2.5-coder-32b-instruct (legacy, replaced by qwen3-coder-plus/flash)
280
+ // Fix (2026-05-26): qwen3-max ctx 1M→256k, qwen3-coder-plus ctx 256k→1M, qwen3-coder-flash ctx 256k→1M, qwen3-32b ctx 128k→256k
281
+ // Fix (2026-05-26): qwen3-235b-a22b-instruct ID → qwen3-235b-a22b
268
282
  ]
269
283
 
270
284
  // 📖 Cloudflare Workers AI source - https://developers.cloudflare.com/workers-ai
@@ -273,7 +287,7 @@ export const qwen = [
273
287
  // 📖 Free plan includes daily neuron quota and provider-level request limits.
274
288
  export const cloudflare = [
275
289
  // ── S+ tier ──
276
- ['@cf/moonshotai/kimi-k2.6', 'Kimi K2.6', 'S+', '76.8%', '256k'],
290
+ ['@cf/moonshotai/kimi-k2.6', 'Kimi K2.6', 'S+', '76.8%', '262k'],
277
291
  // ── S tier ──
278
292
  ['@cf/zai-org/glm-4.7-flash', 'GLM-4.7-Flash', 'S', '59.2%', '131k'],
279
293
  ['@cf/openai/gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
@@ -287,12 +301,14 @@ export const cloudflare = [
287
301
  ['@cf/openai/gpt-oss-20b', 'GPT OSS 20B', 'A', '42.0%', '128k'],
288
302
  // ── A- tier ──
289
303
  ['@cf/meta/llama-3.3-70b-instruct-fp8-fast','Llama 3.3 70B', 'A-', '39.5%', '128k'],
290
- ['@cf/google/gemma-4-31b-it', 'Gemma 4 31B', 'A', '45.0%', '256k'],
291
304
  ['@cf/google/gemma-4-26b-a4b-it', 'Gemma 4 26B MoE', 'A-', '38.0%', '256k'],
292
305
  ['@cf/mistralai/mistral-small-3.1-24b-instruct', 'Mistral Small 3.1', 'B+', '30.0%', '128k'],
306
+ ['@cf/deepseek-ai/deepseek-r1-distill-qwen-32b', 'DeepSeek R1 Distill 32B', 'A-', '45.0%', '80k'],
293
307
  // ── B tier ──
294
308
  ['@cf/ibm/granite-4.0-h-micro', 'Granite 4.0 Micro', 'B+', '30.0%', '128k'],
295
- ['@cf/meta/llama-3.1-8b-instruct', 'Llama 3.1 8B', 'B', '28.8%', '128k'],
309
+ // Removed (2026-05-26): @cf/google/gemma-4-31b-it (never existed on Cloudflare)
310
+ // Removed (2026-05-26): @cf/meta/llama-3.1-8b-instruct (deprecated May 30 + actual ctx = 8k, not 128k)
311
+ // Fix (2026-05-26): @cf/moonshotai/kimi-k2.6 ctx 256k → 262k
296
312
  ]
297
313
 
298
314
  // 📖 OVHcloud AI Endpoints - https://endpoints.ai.cloud.ovh.net
@@ -300,16 +316,18 @@ export const cloudflare = [
300
316
  // 📖 Free sandbox: 2 req/min per IP per model (no API key needed), 400 RPM with API key
301
317
  // 📖 Env var: OVH_AI_ENDPOINTS_ACCESS_TOKEN
302
318
  export const ovhcloud = [
319
+ ['Qwen3.5-397B-A17B', 'Qwen3.5 397B MoE', 'S', '-', '262k'],
303
320
  ['Qwen3-Coder-30B-A3B-Instruct', 'Qwen3 Coder 30B MoE', 'A+', '55.0%', '256k'],
304
321
  ['gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '131k'],
305
322
  ['gpt-oss-20b', 'GPT OSS 20B', 'A', '42.0%', '131k'],
306
323
  ['Meta-Llama-3_3-70B-Instruct', 'Llama 3.3 70B', 'A-', '39.5%', '131k'],
307
324
  ['Qwen3-32B', 'Qwen3 32B', 'A+', '50.0%', '32k'],
308
- ['Mistral-Small-3.2-24B-Instruct-2506', 'Mistral Small 3.2', 'B+', '34.0%', '131k'],
309
- ['Mistral-7B-Instruct-v0.3', 'Mistral 7B Instruct', 'B', '25.0%', '32k'],
310
- ['Mistral-Nemo-Instruct-2407', 'Mistral Nemo', 'B+', '30.0%', '128k'],
311
- ['Qwen3.5-9B', 'Qwen3.5 9B', 'B+', '30.0%', '128k'],
312
- ['Llama-3.1-8B-Instruct', 'Llama 3.1 8B', 'B', '28.8%', '131k'],
325
+ ['Mistral-Small-3.2-24B-Instruct-2506', 'Mistral Small 3.2', 'B+', '34.0%', '128k'],
326
+ ['Mistral-7B-Instruct-v0.3', 'Mistral 7B Instruct', 'B', '25.0%', '127k'],
327
+ ['Mistral-Nemo-Instruct-2407', 'Mistral Nemo', 'B+', '30.0%', '118k'],
328
+ ['Qwen3.5-9B', 'Qwen3.5 9B', 'B+', '30.0%', '262k'],
329
+ // Removed (2026-05-26): Llama-3.1-8B-Instruct (delisted from OVHcloud catalog)
330
+ // Fix (2026-05-26): Qwen3.5-9B ctx 128k→262k, Mistral-Small ctx 131k→128k, Mistral-Nemo ctx 128k→118k, Mistral-7B ctx 32k→127k
313
331
  ]
314
332
 
315
333
  // 📖 Gemini CLI source - https://github.com/google-gemini/gemini-cli
@@ -319,12 +337,15 @@ export const ovhcloud = [
319
337
  // 📖 Models track Google AI Studio IDs; no stale google/ prefix.
320
338
  // 📖 Supports custom OpenAI-compatible providers via GEMINI_API_BASE_URL
321
339
  export const gemini = [
340
+ ['gemini-3.5-flash', 'Gemini 3.5 Flash', 'S+', '-', '1M'],
322
341
  ['gemini-3.1-pro-preview', 'Gemini 3.1 Pro Preview', 'S+', '78.0%', '1M'],
323
342
  ['gemini-3-flash-preview', 'Gemini 3 Flash Preview', 'S', '65.0%', '1M'],
324
- ['gemini-3.1-flash-lite-preview', 'Gemini 3.1 Flash Lite Preview','A+', '55.0%', '1M'],
343
+ ['gemini-3.1-flash-lite', 'Gemini 3.1 Flash Lite', 'A+', '55.0%', '1M'],
344
+ // ⚠️ DEPRECATED — shutdown Oct 16, 2026
325
345
  ['gemini-2.5-pro', 'Gemini 2.5 Pro', 'S+', '63.2%', '1M'],
326
346
  ['gemini-2.5-flash', 'Gemini 2.5 Flash', 'A+', '50.0%', '1M'],
327
347
  ['gemini-2.5-flash-lite', 'Gemini 2.5 Flash Lite', 'A', '42.0%', '1M'],
348
+ // Removed (2026-05-26): gemini-3.1-flash-lite-preview (endpoint shutdown May 25, 2026)
328
349
  ]
329
350
 
330
351
  // 📖 OpenCode Zen free models — hosted AI gateway accessed through OpenCode CLI/Desktop
@@ -333,14 +354,17 @@ export const gemini = [
333
354
  // 📖 Login: https://opencode.ai/auth — get your Zen API key
334
355
  // 📖 Config: set provider to opencode/<model-id> in OpenCode config
335
356
  export const opencodeZen = [
336
- ['big-pickle', 'Big Pickle', 'S+', '72.0%', '200k'],
337
- ['minimax-m2.5-free', 'MiniMax M2.5 Free', 'S+', '80.2%', '200k'],
338
- ['nemotron-3-super-free', 'Nemotron 3 Super Free','A+', '52.0%', '1M'],
339
- ['gpt-5-nano', 'GPT 5 Nano', 'S', '65.0%', '400k'],
340
- ['hy3-preview-free', 'HY3 Preview Free', 'A+', '-', '128k'],
341
- ['ling-2.6-flash-free', 'Ling 2.6 Flash Free', 'S', '-', '128k'],
342
- ['trinity-mini-free', 'Trinity Mini Preview', 'A', '-', '128k'],
343
- ['trinity-large-preview-free', 'Trinity Large Preview','S', '-', '128k'],
357
+ ['big-pickle', 'Big Pickle', 'S+', '72.0%', '200k'],
358
+ ['minimax-m2.5-free', 'MiniMax M2.5 Free', 'S+', '80.2%', '200k'],
359
+ ['deepseek-v4-flash-free', 'DeepSeek V4 Flash Free', 'S+', '79.0%', '200k'],
360
+ ['qwen3.6-plus-free', 'Qwen3.6 Plus Free', 'S+', '78.8%', '1M'],
361
+ ['nemotron-3-super-free', 'Nemotron 3 Super Free', 'A+', '52.0%', '200k'],
362
+ ['gpt-5-nano', 'GPT 5 Nano', 'S', '65.0%', '400k'],
363
+ // Removed (2026-05-26): hy3-preview-free (deleted from Zen)
364
+ // Removed (2026-05-26): ling-2.6-flash-free (deleted from Zen)
365
+ // Removed (2026-05-26): trinity-mini-free (deleted from Zen)
366
+ // Removed (2026-05-26): trinity-large-preview-free (deleted from Zen)
367
+ // Fix (2026-05-26): nematron-3-super-free ctx 1M → 200k (Zen limits it)
344
368
  ]
345
369
 
346
370
  // 📖 All sources combined - used by the main script
@@ -1,75 +1,75 @@
1
1
  /**
2
2
  * @file changelog-loader.js
3
- * @description Load and parse CHANGELOG.md for display in the TUI
3
+ * @description Load and parse per-version changelog files from the changelog/ directory
4
+ *
5
+ * Each version has its own file: changelog/vX.Y.Z.md
6
+ * The file starts with `# Changelog vX.Y.Z - YYYY-MM-DD` followed by
7
+ * `### Added`, `### Fixed`, `### Changed` sections with bullet points.
4
8
  *
5
9
  * @functions
6
- * → loadChangelog() — Read and parse CHANGELOG.md into structured format
10
+ * → loadChangelog() — Read and parse all changelog files into structured format
7
11
  * → getLatestChanges(version) — Return changelog for a specific version
8
12
  * → formatChangelogForDisplay(version) — Format for TUI rendering
9
13
  *
10
14
  * @exports loadChangelog, getLatestChanges, formatChangelogForDisplay
11
15
  */
12
16
 
13
- import { readFileSync, existsSync } from 'fs'
17
+ import { readFileSync, existsSync, readdirSync } from 'fs'
14
18
  import { dirname, join } from 'path'
15
19
  import { fileURLToPath } from 'url'
16
20
 
17
21
  const __filename = fileURLToPath(import.meta.url)
18
22
  const __dirname = dirname(__filename)
19
- const CHANGELOG_PATH = join(__dirname, '..', 'CHANGELOG.md')
23
+ const CHANGELOG_DIR = join(__dirname, '..', 'changelog')
20
24
 
21
25
  /**
22
- * 📖 loadChangelog: Read and parse CHANGELOG.md
26
+ * 📖 loadChangelog: Read and parse all per-version changelog files
23
27
  * @returns {Object} { versions: { '0.2.11': { added: [], fixed: [], changed: [] }, ... } }
24
28
  */
25
29
  export function loadChangelog() {
26
- if (!existsSync(CHANGELOG_PATH)) return { versions: {} }
30
+ if (!existsSync(CHANGELOG_DIR)) return { versions: {} }
27
31
 
28
- const content = readFileSync(CHANGELOG_PATH, 'utf8')
29
32
  const versions = {}
30
- const lines = content.split('\n')
31
- let currentVersion = null
32
- let currentSection = null
33
- let currentItems = []
33
+ const files = readdirSync(CHANGELOG_DIR).filter(f => f.endsWith('.md'))
34
+
35
+ for (const file of files) {
36
+ const filePath = join(CHANGELOG_DIR, file)
37
+ const content = readFileSync(filePath, 'utf8')
38
+ const lines = content.split('\n')
39
+ let currentSection = null
40
+ let currentItems = []
34
41
 
35
- for (const line of lines) {
36
- // 📖 Match version headers: ## 0.2.11
37
- const versionMatch = line.match(/^## ([\d.]+)/)
38
- if (versionMatch) {
39
- if (currentVersion && currentSection && currentItems.length > 0) {
40
- if (!versions[currentVersion]) versions[currentVersion] = {}
41
- versions[currentVersion][currentSection] = currentItems
42
+ // 📖 Extract version from filename (e.g. v0.3.67.md 0.3.67)
43
+ const verMatch = file.match(/^v([\d.]+)\.md$/)
44
+ if (!verMatch) continue
45
+ const currentVersion = verMatch[1]
46
+
47
+ for (const line of lines) {
48
+ // 📖 Match section headers: ### Added, ### Fixed, ### Changed
49
+ const sectionMatch = line.match(/^### (Added|Fixed|Changed|Updated)/)
50
+ if (sectionMatch) {
51
+ if (currentSection && currentItems.length > 0) {
52
+ if (!versions[currentVersion]) versions[currentVersion] = {}
53
+ versions[currentVersion][currentSection] = currentItems
54
+ }
55
+ currentSection = sectionMatch[1].toLowerCase()
56
+ currentItems = []
57
+ continue
42
58
  }
43
- currentVersion = versionMatch[1]
44
- currentSection = null
45
- currentItems = []
46
- continue
47
- }
48
59
 
49
- // 📖 Match section headers: ### Added, ### Fixed, ### Changed
50
- const sectionMatch = line.match(/^### (Added|Fixed|Changed|Updated)/)
51
- if (sectionMatch) {
52
- if (currentVersion && currentSection && currentItems.length > 0) {
53
- if (!versions[currentVersion]) versions[currentVersion] = {}
54
- versions[currentVersion][currentSection.toLowerCase()] = currentItems
60
+ // 📖 Match bullet points: - **text**: description
61
+ if (line.match(/^- /) && currentSection) {
62
+ currentItems.push(line.replace(/^- /, ''))
55
63
  }
56
- currentSection = sectionMatch[1].toLowerCase()
57
- currentItems = []
58
- continue
59
64
  }
60
65
 
61
- // 📖 Match bullet points: - **text**: description
62
- if (line.match(/^- /) && currentVersion && currentSection) {
63
- currentItems.push(line.replace(/^- /, ''))
66
+ // 📖 Save the last section
67
+ if (currentSection && currentItems.length > 0) {
68
+ if (!versions[currentVersion]) versions[currentVersion] = {}
69
+ versions[currentVersion][currentSection] = currentItems
64
70
  }
65
71
  }
66
72
 
67
- // 📖 Save the last section
68
- if (currentVersion && currentSection && currentItems.length > 0) {
69
- if (!versions[currentVersion]) versions[currentVersion] = {}
70
- versions[currentVersion][currentSection] = currentItems
71
- }
72
-
73
73
  return { versions }
74
74
  }
75
75