free-coding-models 0.3.25 → 0.3.28
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 +62 -2
- package/README.md +23 -1
- package/package.json +1 -1
- package/sources.js +37 -19
- package/src/app.js +33 -6
- package/src/command-palette.js +1 -0
- package/src/installed-models-manager.js +636 -0
- package/src/key-handler.js +187 -14
- package/src/overlays.js +111 -2
- package/src/render-table.js +26 -10
- package/src/updater.js +127 -36
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,71 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
---
|
|
3
3
|
|
|
4
|
+
## [0.3.27] - 2026-03-27
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
- **Fluorescent green UPDATE AVAILABLE banner** — impossible-to-miss fluo green (🚀⬆️) banner at the bottom of the TUI when a new version is detected; click it to update instantly
|
|
8
|
+
- **Command Palette update entry** — `⬆️ UPDATE NOW` is always the first result in Ctrl+P when an update is available
|
|
9
|
+
- **Shift+U hotkey** — press Shift+U from the main table to trigger an immediate update
|
|
10
|
+
- **Mouse-clickable update banner** — click the fluo green banner to install the latest version and relaunch
|
|
11
|
+
- **Background version re-check every 5 minutes** — if a new version is published while the TUI is open, the banner appears live without restarting
|
|
12
|
+
- **Aggressive pre-TUI update prompt** — fluorescent green header, and "Continue without update" warns that reminders will follow
|
|
13
|
+
- **Last release date in footer** — light pink `Last release: Mar 27, 2026, 09:42 PM` shows when the package was last published to npm, so users know how fresh the model data is
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **Auto-update now detects the correct package manager** — bun, pnpm, and yarn users no longer get duplicate npm installs (fixes #46)
|
|
17
|
+
- Update banner in footer shows the correct install command for your package manager
|
|
18
|
+
|
|
19
|
+
## [0.3.26] - 2026-03-27
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- **Groq**: Added Compound + Compound Mini; fixed Llama 4 Scout context (10M)
|
|
23
|
+
- **OpenRouter**: Added MiniMax M2.5, Nemotron 3 Super, Hermes 3 405B, Gemma 3n E4B
|
|
24
|
+
- **HuggingFace**: Replaced invalid DeepSeek-V3-Coder + outdated starcoder2-15b with DeepSeek V3 0324 + Qwen2.5 Coder 32B
|
|
25
|
+
- **Replicate**: Replaced CodeLlama 70B (2023) with DeepSeek V3 0324 + Llama 3.3 70B
|
|
26
|
+
- **Cloudflare**: Added Kimi K2.5, GLM-4.7-Flash, Llama 4 Scout, Nemotron 3 Super, Qwen3 30B MoE
|
|
27
|
+
- **Scaleway**: Added Qwen3.5 400B VLM + Mistral Large 675B
|
|
28
|
+
- **DeepInfra**: Replaced Mixtral Code with Nemotron 3 Super + DeepSeek V3 0324 + Qwen3 235B
|
|
29
|
+
- **Fireworks**: Added Llama 4 Maverick + Qwen3 235B
|
|
30
|
+
- **Hyperbolic**: Added Qwen3 80B Thinking variant
|
|
31
|
+
- **Together AI**: Added Qwen3.5 400B VLM, MiniMax M2.5, GLM-5
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- **Rovo Dev CLI**: Updated Sonnet 4 → Sonnet 4.6, added Opus 4.6
|
|
35
|
+
- **Groq**: Removed 4 deprecated models (R1 Distill 70B, QwQ 32B, Kimi K2, Maverick)
|
|
36
|
+
- **OpenRouter**: Updated context sizes for multiple models
|
|
37
|
+
|
|
4
38
|
## [0.3.25] - 2026-03-19
|
|
5
39
|
|
|
40
|
+
### Added
|
|
41
|
+
- **Installed Models Manager** — View, launch, and disable models configured in external tools (Goose, Crush, Aider, Qwen, Pi, OpenHands, Amp)
|
|
42
|
+
- Access via Command Palette (Ctrl+P) → "Installed models"
|
|
43
|
+
- Scans all supported tool configs automatically on opening
|
|
44
|
+
- Displays all models per tool (e.g., Crush shows both large and small models)
|
|
45
|
+
- Actions: Launch (Enter), Disable (D) with backup, Reinstall (R)
|
|
46
|
+
- Soft delete: Comments out model entries and saves backups to ~/.free-coding-models-backups.json
|
|
47
|
+
- **Full mouse support for the TUI** — Click, right-click, double-click, and scroll work throughout the interface
|
|
48
|
+
- **Click column headers** — Sort by any column (click Rank, Tier, SWE%, CTX, Model, Provider, etc.)
|
|
49
|
+
- **Click model rows** — Move cursor to any model (left-click)
|
|
50
|
+
- **Right-click model rows** — Toggle favorite (same as F key)
|
|
51
|
+
- **Double-click model rows** — Select model and launch (same as Enter)
|
|
52
|
+
- **Mouse wheel** — Scroll through the main table, overlays (Settings, Help, Changelog), and command palette results
|
|
53
|
+
- **Click CLI Tools header** — Cycle through tool modes (same as Z key)
|
|
54
|
+
- **Click Tier header** — Cycle through tier filters (same as T key)
|
|
55
|
+
- **Click footer hotkeys** — Trigger any visible hotkey from the footer
|
|
56
|
+
- **Command palette click** — Click inside to select items, double-click to confirm; click outside to close
|
|
57
|
+
- **Recommend questionnaire click** — Click on option rows to select, double-click to confirm
|
|
58
|
+
- **Mouse unit tests** — 46 new tests covering SGR sequence parsing, double-click detection, modifiers, and COLUMN_SORT_MAP validation
|
|
59
|
+
|
|
6
60
|
### Changed
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
61
|
+
- **CLI Tools column redesigned** — Renamed from "Compatible with" to "CLI Tools", with left-aligned emoji display (compatible tools packed left instead of fixed slot positions)
|
|
62
|
+
- **Sort arrow overflow fixed** — SWE%, CTX, Stability, and Uptime columns now properly fit within their widths when sorted (arrow now `↑SWE%` instead of `↑ SWE%`)
|
|
63
|
+
- **Mouse sequence suppression** — SGR mouse sequences no longer leak into keypress handlers (prevents spurious sort/filter triggers when clicking)
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
- **Command palette scroll leak** — Mouse wheel no longer injects raw SGR sequence bytes into the command palette text input
|
|
67
|
+
- **Double-action on model click** — Clicking a model row now only moves the cursor; it no longer simultaneously triggers column sorting
|
|
68
|
+
- **Mouse event listener order** — Fixed race condition where readline emitted keypress events before mouse data was processed
|
|
9
69
|
|
|
10
70
|
## [0.3.24] - 2026-03-19
|
|
11
71
|
|
package/README.md
CHANGED
|
@@ -229,6 +229,8 @@ When a tool mode is active (via `Z`), models incompatible with that tool are hig
|
|
|
229
229
|
|
|
230
230
|
## ⌨️ TUI Keys
|
|
231
231
|
|
|
232
|
+
### Keyboard
|
|
233
|
+
|
|
232
234
|
| Key | Action |
|
|
233
235
|
|-----|--------|
|
|
234
236
|
| `↑↓` | Navigate models |
|
|
@@ -243,6 +245,7 @@ When a tool mode is active (via `Z`), models incompatible with that tool are hig
|
|
|
243
245
|
| `G` | Cycle global theme (`Auto → Dark → Light`) |
|
|
244
246
|
| `Ctrl+P` | Open ⚡️ command palette (search + run actions) |
|
|
245
247
|
| `R/S/C/M/O/L/A/H/V/B/U` | Sort columns |
|
|
248
|
+
| `Shift+U` | Update to latest version (when update available) |
|
|
246
249
|
| `P` | Settings (API keys, providers, updates, theme) |
|
|
247
250
|
| `Q` | Smart Recommend overlay |
|
|
248
251
|
| `N` | Changelog |
|
|
@@ -251,6 +254,23 @@ When a tool mode is active (via `Z`), models incompatible with that tool are hig
|
|
|
251
254
|
| `K` | Help overlay |
|
|
252
255
|
| `Ctrl+C` | Exit |
|
|
253
256
|
|
|
257
|
+
### Mouse
|
|
258
|
+
|
|
259
|
+
| Action | Result |
|
|
260
|
+
|--------|--------|
|
|
261
|
+
| **Click column header** | Sort by that column |
|
|
262
|
+
| **Click Tier header** | Cycle tier filter |
|
|
263
|
+
| **Click CLI Tools header** | Cycle tool mode |
|
|
264
|
+
| **Click model row** | Move cursor to model |
|
|
265
|
+
| **Double-click model row** | Select and launch model |
|
|
266
|
+
| **Right-click model row** | Toggle favorite |
|
|
267
|
+
| **Scroll wheel** | Navigate table / overlays / palette |
|
|
268
|
+
| **Click footer hotkey** | Trigger that action |
|
|
269
|
+
| **Click update banner** | Install latest version and relaunch |
|
|
270
|
+
| **Click command palette item** | Select item (double-click to confirm) |
|
|
271
|
+
| **Click recommend option** | Select option (double-click to confirm) |
|
|
272
|
+
| **Click outside modal** | Close command palette |
|
|
273
|
+
|
|
254
274
|
→ **[Stability score & column reference](./docs/stability.md)**
|
|
255
275
|
|
|
256
276
|
---
|
|
@@ -272,8 +292,10 @@ When a tool mode is active (via `Z`), models incompatible with that tool are hig
|
|
|
272
292
|
- **OpenCode Zen models** — 8 free models exclusive to OpenCode CLI/Desktop, powered by the Zen AI gateway
|
|
273
293
|
- **Width guardrail** — shows a warning instead of a broken table in narrow terminals
|
|
274
294
|
- **Readable everywhere** — semantic theme palette keeps table rows, overlays, badges, and help screens legible in dark and light terminals
|
|
275
|
-
- **Global theme switch** — `G` cycles `auto`, `dark`,
|
|
295
|
+
- **Global theme switch** — `G` cycles `auto`, `dark`, + `light` live without restarting
|
|
276
296
|
- **Auto-retry** — timeout models keep getting retried
|
|
297
|
+
- **Aggressive update nudging** — fluorescent green banner when an update is available, impossible to miss, Shift+U hotkey, command palette entry, background re-check every 5 min, mid-session updates the banner live without restarting
|
|
298
|
+
- **Last release timestamp** — light pink footer shows `Last release: Mar 27, 2026, 09:42 PM` from npm so users know how fresh the data is
|
|
277
299
|
|
|
278
300
|
---
|
|
279
301
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.28",
|
|
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",
|
package/sources.js
CHANGED
|
@@ -99,15 +99,13 @@ export const nvidiaNim = [
|
|
|
99
99
|
// 📖 Free API keys available at https://console.groq.com/keys
|
|
100
100
|
export const groq = [
|
|
101
101
|
['llama-3.3-70b-versatile', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
|
|
102
|
-
['meta-llama/llama-4-scout-17b-16e-preview', 'Llama 4 Scout', 'A', '44.0%', '
|
|
103
|
-
['meta-llama/llama-4-maverick-17b-128e-preview', 'Llama 4 Maverick', 'S', '62.0%', '1M'],
|
|
104
|
-
['deepseek-r1-distill-llama-70b', 'R1 Distill 70B', 'A', '43.9%', '128k'],
|
|
105
|
-
['qwen-qwq-32b', 'QwQ 32B', 'A+', '50.0%', '131k'],
|
|
106
|
-
['moonshotai/kimi-k2-instruct', 'Kimi K2 Instruct', 'S', '65.8%', '131k'],
|
|
102
|
+
['meta-llama/llama-4-scout-17b-16e-preview', 'Llama 4 Scout', 'A', '44.0%', '131k'],
|
|
107
103
|
['llama-3.1-8b-instant', 'Llama 3.1 8B', 'B', '28.8%', '128k'],
|
|
108
104
|
['openai/gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
|
|
109
105
|
['openai/gpt-oss-20b', 'GPT OSS 20B', 'A', '42.0%', '128k'],
|
|
110
106
|
['qwen/qwen3-32b', 'Qwen3 32B', 'A+', '50.0%', '131k'],
|
|
107
|
+
['groq/compound', 'Groq Compound', 'A', '45.0%', '131k'],
|
|
108
|
+
['groq/compound-mini', 'Groq Compound Mini', 'B+', '32.0%', '131k'],
|
|
111
109
|
]
|
|
112
110
|
|
|
113
111
|
// 📖 Cerebras source - https://cloud.cerebras.ai
|
|
@@ -158,36 +156,43 @@ export const sambanova = [
|
|
|
158
156
|
// 📖 API keys at https://openrouter.ai/keys
|
|
159
157
|
export const openrouter = [
|
|
160
158
|
['qwen/qwen3-coder:free', 'Qwen3 Coder 480B', 'S+', '70.6%', '262k'],
|
|
161
|
-
['
|
|
162
|
-
['
|
|
159
|
+
['minimax/minimax-m2.5:free', 'MiniMax M2.5', 'S+', '74.0%', '197k'],
|
|
160
|
+
['z-ai/glm-4.5-air:free', 'GLM 4.5 Air', 'S+', '72.0%', '131k'],
|
|
163
161
|
['stepfun/step-3.5-flash:free', 'Step 3.5 Flash', 'S+', '74.4%', '256k'],
|
|
164
|
-
['
|
|
165
|
-
['
|
|
166
|
-
['
|
|
162
|
+
['nvidia/nemotron-3-super-120b-a12b:free', 'Nemotron 3 Super', 'A+', '56.0%', '262k'],
|
|
163
|
+
['qwen/qwen3-next-80b-a3b-instruct:free', 'Qwen3 80B Instruct', 'S', '65.0%', '131k'],
|
|
164
|
+
['nousresearch/hermes-3-llama-3.1-405b:free', 'Hermes 3 405B', 'A', '44.0%', '131k'],
|
|
165
|
+
['openai/gpt-oss-120b:free', 'GPT OSS 120B', 'S', '60.0%', '131k'],
|
|
166
|
+
['openai/gpt-oss-20b:free', 'GPT OSS 20B', 'A', '42.0%', '131k'],
|
|
167
167
|
['nvidia/nemotron-3-nano-30b-a3b:free', 'Nemotron Nano 30B', 'A', '43.0%', '128k'],
|
|
168
|
-
['meta-llama/llama-3.3-70b-instruct:free', 'Llama 3.3 70B', 'A-', '39.5%', '
|
|
168
|
+
['meta-llama/llama-3.3-70b-instruct:free', 'Llama 3.3 70B', 'A-', '39.5%', '131k'],
|
|
169
169
|
['mistralai/mistral-small-3.1-24b-instruct:free', 'Mistral Small 3.1', 'B+', '30.0%', '128k'],
|
|
170
|
-
['google/gemma-3-
|
|
170
|
+
['google/gemma-3-27b-it:free', 'Gemma 3 27B', 'B', '22.0%', '131k'],
|
|
171
|
+
['google/gemma-3-12b-it:free', 'Gemma 3 12B', 'C', '15.0%', '131k'],
|
|
172
|
+
['google/gemma-3n-e4b-it:free', 'Gemma 3n E4B', 'C', '10.0%', '8k'],
|
|
171
173
|
]
|
|
172
174
|
|
|
173
175
|
// 📖 Hugging Face Inference source - https://huggingface.co
|
|
174
176
|
// 📖 OpenAI-compatible endpoint via router.huggingface.co/v1
|
|
175
177
|
// 📖 Free monthly credits on developer accounts (~$0.10) — token at https://huggingface.co/settings/tokens
|
|
176
178
|
export const huggingface = [
|
|
177
|
-
['deepseek-ai/DeepSeek-V3-
|
|
178
|
-
['
|
|
179
|
+
['deepseek-ai/DeepSeek-V3-0324', 'DeepSeek V3 0324', 'S', '62.0%', '128k'],
|
|
180
|
+
['Qwen/Qwen2.5-Coder-32B-Instruct', 'Qwen2.5 Coder 32B', 'A', '46.0%', '32k'],
|
|
179
181
|
]
|
|
180
182
|
|
|
181
183
|
// 📖 Replicate source - https://replicate.com
|
|
182
184
|
// 📖 Uses predictions endpoint (not OpenAI chat-completions) with token auth
|
|
183
185
|
export const replicate = [
|
|
184
|
-
['
|
|
186
|
+
['deepseek-ai/DeepSeek-V3-0324', 'DeepSeek V3 0324', 'S', '62.0%', '128k'],
|
|
187
|
+
['meta/llama-3.3-70b-instruct', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
|
|
185
188
|
]
|
|
186
189
|
|
|
187
190
|
// 📖 DeepInfra source - https://deepinfra.com
|
|
188
191
|
// 📖 OpenAI-compatible endpoint: https://api.deepinfra.com/v1/openai/chat/completions
|
|
189
192
|
export const deepinfra = [
|
|
190
|
-
['
|
|
193
|
+
['nvidia/Nemotron-3-Super', 'Nemotron 3 Super', 'A+', '56.0%', '128k'],
|
|
194
|
+
['deepseek-ai/DeepSeek-V3-0324', 'DeepSeek V3 0324', 'S', '62.0%', '128k'],
|
|
195
|
+
['Qwen/Qwen3-235B-A22B', 'Qwen3 235B', 'S+', '70.0%', '128k'],
|
|
191
196
|
['meta-llama/Meta-Llama-3.1-70B-Instruct', 'Llama 3.1 70B', 'A-', '39.5%', '128k'],
|
|
192
197
|
]
|
|
193
198
|
|
|
@@ -197,6 +202,8 @@ export const deepinfra = [
|
|
|
197
202
|
export const fireworks = [
|
|
198
203
|
['accounts/fireworks/models/deepseek-v3', 'DeepSeek V3', 'S', '62.0%', '128k'],
|
|
199
204
|
['accounts/fireworks/models/deepseek-r1', 'DeepSeek R1', 'S', '61.0%', '128k'],
|
|
205
|
+
['accounts/fireworks/models/llama4-maverick-instruct-basic', 'Llama 4 Maverick', 'S', '62.0%', '1M'],
|
|
206
|
+
['accounts/fireworks/models/qwen3-235b-a22b', 'Qwen3 235B', 'S+', '70.0%', '128k'],
|
|
200
207
|
]
|
|
201
208
|
|
|
202
209
|
// 📖 Mistral Codestral source - https://codestral.mistral.ai
|
|
@@ -215,6 +222,7 @@ export const hyperbolic = [
|
|
|
215
222
|
['openai/gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
|
|
216
223
|
['Qwen/Qwen3-235B-A22B', 'Qwen3 235B', 'S+', '70.0%', '128k'],
|
|
217
224
|
['qwen/qwen3-next-80b-a3b-instruct', 'Qwen3 80B Instruct', 'S', '65.0%', '128k'],
|
|
225
|
+
['Qwen/Qwen3-Next-80B-A3B-Thinking', 'Qwen3 80B Thinking', 'S', '68.0%', '128k'],
|
|
218
226
|
['deepseek-ai/DeepSeek-V3-0324', 'DeepSeek V3 0324', 'S', '62.0%', '128k'],
|
|
219
227
|
['Qwen/Qwen2.5-Coder-32B-Instruct', 'Qwen2.5 Coder 32B', 'A', '46.0%', '32k'],
|
|
220
228
|
['meta-llama/Llama-3.3-70B-Instruct', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
|
|
@@ -224,9 +232,10 @@ export const hyperbolic = [
|
|
|
224
232
|
// 📖 Scaleway source - https://console.scaleway.com
|
|
225
233
|
// 📖 1M free tokens — API keys at https://console.scaleway.com/iam/api-keys
|
|
226
234
|
export const scaleway = [
|
|
227
|
-
['devstral-2-123b-instruct-2512', 'Devstral 2 123B',
|
|
235
|
+
['devstral-2-123b-instruct-2512', 'Devstral 2 123B', 'S+', '72.2%', '256k'],
|
|
236
|
+
['qwen3.5-397b-a17b', 'Qwen3.5 400B VLM', 'S', '68.0%', '250k'],
|
|
237
|
+
['mistral/mistral-large-3-675b-instruct-2512', 'Mistral Large 675B', 'A+', '58.0%', '250k'],
|
|
228
238
|
['qwen3-235b-a22b-instruct-2507', 'Qwen3 235B', 'S+', '70.0%', '128k'],
|
|
229
|
-
['gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
|
|
230
239
|
['qwen3-coder-30b-a3b-instruct', 'Qwen3 Coder 30B', 'A+', '55.0%', '32k'],
|
|
231
240
|
['llama-3.3-70b-instruct', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
|
|
232
241
|
['deepseek-r1-distill-llama-70b', 'R1 Distill 70B', 'A', '43.9%', '128k'],
|
|
@@ -272,6 +281,9 @@ export const siliconflow = [
|
|
|
272
281
|
// 📖 Credits/promotions vary by account and region; verify current quota in console.
|
|
273
282
|
export const together = [
|
|
274
283
|
['moonshotai/Kimi-K2.5', 'Kimi K2.5', 'S+', '76.8%', '128k'],
|
|
284
|
+
['Qwen/Qwen3.5-397B-A17B', 'Qwen3.5 400B VLM', 'S', '68.0%', '250k'],
|
|
285
|
+
['MiniMaxAI/MiniMax-M2.5', 'MiniMax M2.5', 'S+', '80.2%', '200k'],
|
|
286
|
+
['zai-org/GLM-5', 'GLM-5', 'S+', '77.8%', '128k'],
|
|
275
287
|
['Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8', 'Qwen3 Coder 480B', 'S+', '70.6%', '256k'],
|
|
276
288
|
['deepseek-ai/DeepSeek-V3.1', 'DeepSeek V3.1', 'S', '62.0%', '128k'],
|
|
277
289
|
['deepseek-ai/DeepSeek-R1', 'DeepSeek R1', 'S', '61.0%', '128k'],
|
|
@@ -285,7 +297,12 @@ export const together = [
|
|
|
285
297
|
// 📖 https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1/chat/completions
|
|
286
298
|
// 📖 Free plan includes daily neuron quota and provider-level request limits.
|
|
287
299
|
export const cloudflare = [
|
|
300
|
+
['@cf/moonshotai/kimi-k2.5', 'Kimi K2.5', 'S+', '76.8%', '256k'],
|
|
301
|
+
['@cf/zhipu/glm-4.7-flash', 'GLM-4.7-Flash', 'S', '59.2%', '131k'],
|
|
288
302
|
['@cf/openai/gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
|
|
303
|
+
['@cf/meta/llama-4-scout-17b-16e-instruct', 'Llama 4 Scout', 'A', '44.0%', '131k'],
|
|
304
|
+
['@cf/nvidia/nemotron-3-120b-a12b', 'Nemotron 3 Super', 'A+', '56.0%', '128k'],
|
|
305
|
+
['@cf/qwen/qwen3-30b-a3b-fp8', 'Qwen3 30B MoE', 'A', '45.0%', '128k'],
|
|
289
306
|
['@cf/qwen/qwen2.5-coder-32b-instruct', 'Qwen2.5 Coder 32B', 'A', '46.0%', '32k'],
|
|
290
307
|
['@cf/deepseek-ai/deepseek-r1-distill-qwen-32b', 'R1 Distill 32B', 'A', '43.9%', '128k'],
|
|
291
308
|
['@cf/openai/gpt-oss-20b', 'GPT OSS 20B', 'A', '42.0%', '128k'],
|
|
@@ -350,7 +367,8 @@ export const iflow = [
|
|
|
350
367
|
// 📖 Free tier: 5M tokens/day (beta) - Claude Sonnet 4 (72.7% SWE-bench)
|
|
351
368
|
// 📖 Requires Atlassian account + Rovo Dev activated on your site
|
|
352
369
|
export const rovo = [
|
|
353
|
-
['anthropic/claude-sonnet-4',
|
|
370
|
+
['anthropic/claude-sonnet-4.6', 'Claude Sonnet 4.6', 'S+', '75.0%', '200k'],
|
|
371
|
+
['anthropic/claude-opus-4.6', 'Claude Opus 4.6', 'S+', '80.0%', '200k'],
|
|
354
372
|
]
|
|
355
373
|
|
|
356
374
|
// 📖 Gemini CLI source - https://github.com/google-gemini/gemini-cli
|
package/src/app.js
CHANGED
|
@@ -112,7 +112,7 @@ import { runFiableMode, filterByTierOrExit, fetchOpenRouterFreeModels } from '..
|
|
|
112
112
|
import { PROVIDER_METADATA, ENV_VAR_NAMES, isWindows, isMac } from '../src/provider-metadata.js'
|
|
113
113
|
import { parseTelemetryEnv, isTelemetryDebugEnabled, telemetryDebug, ensureTelemetryConfig, getTelemetryDistinctId, getTelemetrySystem, getTelemetryTerminal, isTelemetryEnabled, sendUsageTelemetry, sendBugReport } from '../src/telemetry.js'
|
|
114
114
|
import { ensureFavoritesConfig, toFavoriteKey, syncFavoriteFlags, toggleFavoriteModel } from '../src/favorites.js'
|
|
115
|
-
import { checkForUpdateDetailed, checkForUpdate, runUpdate, promptUpdateNotification } from '
|
|
115
|
+
import { checkForUpdateDetailed, checkForUpdate, runUpdate, promptUpdateNotification, fetchLastReleaseDate } from './updater.js'
|
|
116
116
|
import { promptApiKey } from '../src/setup.js'
|
|
117
117
|
import { stripAnsi, maskApiKey, displayWidth, padEndDisplay, tintOverlayLines, keepOverlayTargetVisible, sliceOverlayLines, calculateViewport, sortResultsWithPinnedFavorites, adjustScrollOffset } from '../src/render-helpers.js'
|
|
118
118
|
import { renderTable, PROVIDER_COLOR } from '../src/render-table.js'
|
|
@@ -295,6 +295,8 @@ export async function runApp(cliArgs, config) {
|
|
|
295
295
|
// 📖 Dynamic OpenRouter free model discovery — fetch live free models from API
|
|
296
296
|
// 📖 Replaces static openrouter entries in MODELS with fresh data.
|
|
297
297
|
// 📖 Fallback: if fetch fails, the static list from sources.js stays intact + warning shown.
|
|
298
|
+
const lastReleaseDate = await fetchLastReleaseDate()
|
|
299
|
+
state.lastReleaseDate = lastReleaseDate
|
|
298
300
|
const dynamicModels = await fetchOpenRouterFreeModels()
|
|
299
301
|
if (dynamicModels) {
|
|
300
302
|
// 📖 Remove all existing openrouter entries from MODELS
|
|
@@ -381,6 +383,7 @@ export async function runApp(cliArgs, config) {
|
|
|
381
383
|
lastUserActivityAt: now, // 📖 Any keypress refreshes this timer; inactivity can force slow mode.
|
|
382
384
|
resumeSpeedOnActivity: false, // 📖 Set after idle slowdown so the next activity restarts a 60s speed burst.
|
|
383
385
|
startupLatestVersion: latestVersion, // 📖 Startup auto-check result reused by the footer banner after "skip update".
|
|
386
|
+
lastReleaseDate: null, // 📖 Human-readable last npm publish date (fetched asynchronously).
|
|
384
387
|
versionAlertsEnabled: !isDevMode, // 📖 Dev checkouts should not tell contributors to upgrade the global npm package.
|
|
385
388
|
mode, // 📖 'opencode' or 'openclaw' — controls Enter action
|
|
386
389
|
tierFilterMode: 0, // 📖 Index into TIER_CYCLE (0=All, 1=S+, 2=S, ...)
|
|
@@ -471,6 +474,12 @@ export async function runApp(cliArgs, config) {
|
|
|
471
474
|
changelogPhase: 'index', // 📖 'index' (all versions) | 'details' (specific version)
|
|
472
475
|
changelogCursor: 0, // 📖 Selected row in index phase
|
|
473
476
|
changelogSelectedVersion: null, // 📖 Which version to show details for
|
|
477
|
+
// 📖 Installed Models overlay state (Command Palette → Installed models)
|
|
478
|
+
installedModelsOpen: false, // 📖 Whether the installed models overlay is active
|
|
479
|
+
installedModelsCursor: 0, // 📖 Selected row (tool or model)
|
|
480
|
+
installedModelsScrollOffset: 0, // 📖 Vertical scroll offset for overlay viewport
|
|
481
|
+
installedModelsData: [], // 📖 Cached scan results
|
|
482
|
+
installedModelsErrorMsg: null, // 📖 Error or status message
|
|
474
483
|
// 📖 Custom text filter (Ctrl+P palette → type text → Enter). Ephemeral — not saved to config.
|
|
475
484
|
customTextFilter: null, // 📖 Active free-text filter string (null = off). Matches model name, ctx, provider key/name.
|
|
476
485
|
}
|
|
@@ -667,10 +676,10 @@ export async function runApp(cliArgs, config) {
|
|
|
667
676
|
|
|
668
677
|
// 📖 Ensure we always leave alt screen cleanly (Ctrl+C, crash, normal exit)
|
|
669
678
|
const exit = (code = 0) => {
|
|
670
|
-
// 📖 Save cache before exiting so next run starts faster
|
|
671
679
|
saveCache(state.results, state.pingMode)
|
|
672
680
|
clearInterval(ticker)
|
|
673
681
|
clearTimeout(state.pingIntervalObj)
|
|
682
|
+
clearInterval(state.versionRecheckTimer)
|
|
674
683
|
process.stdout.write(ALT_LEAVE)
|
|
675
684
|
if (process.stdout.isTTY) {
|
|
676
685
|
process.stdout.flush && process.stdout.flush()
|
|
@@ -737,6 +746,7 @@ export async function runApp(cliArgs, config) {
|
|
|
737
746
|
const stopUi = ({ resetRawMode = false } = {}) => {
|
|
738
747
|
if (ticker) clearInterval(ticker)
|
|
739
748
|
clearTimeout(state.pingIntervalObj)
|
|
749
|
+
clearInterval(state.versionRecheckTimer)
|
|
740
750
|
if (onKeyPress) process.stdin.removeListener('keypress', onKeyPress)
|
|
741
751
|
if (onMouseData) process.stdin.removeListener('data', onMouseData)
|
|
742
752
|
if (process.stdin.isTTY && resetRawMode) process.stdin.setRawMode(false)
|
|
@@ -951,7 +961,7 @@ export async function runApp(cliArgs, config) {
|
|
|
951
961
|
refreshAutoPingMode()
|
|
952
962
|
state.frame++
|
|
953
963
|
// 📖 Cache visible+sorted models each frame so Enter handler always matches the display
|
|
954
|
-
if (!state.settingsOpen && !state.installEndpointsOpen && !state.toolInstallPromptOpen && !state.incompatibleFallbackOpen && !state.recommendOpen && !state.feedbackOpen && !state.changelogOpen && !state.commandPaletteOpen) {
|
|
964
|
+
if (!state.settingsOpen && !state.installEndpointsOpen && !state.toolInstallPromptOpen && !state.incompatibleFallbackOpen && !state.recommendOpen && !state.feedbackOpen && !state.changelogOpen && !state.installedModelsOpen && !state.commandPaletteOpen) {
|
|
955
965
|
const visible = state.results.filter(r => !r.hidden)
|
|
956
966
|
state.visibleSorted = sortResultsWithPinnedFavorites(visible, state.sortColumn, state.sortDirection, {
|
|
957
967
|
pinFavorites: state.favoritesPinnedAndSticky,
|
|
@@ -990,7 +1000,8 @@ export async function runApp(cliArgs, config) {
|
|
|
990
1000
|
state.startupLatestVersion,
|
|
991
1001
|
state.versionAlertsEnabled,
|
|
992
1002
|
state.favoritesPinnedAndSticky,
|
|
993
|
-
state.customTextFilter
|
|
1003
|
+
state.customTextFilter,
|
|
1004
|
+
state.lastReleaseDate
|
|
994
1005
|
)
|
|
995
1006
|
}
|
|
996
1007
|
tableContent = state.commandPaletteFrozenTable
|
|
@@ -1024,7 +1035,8 @@ export async function runApp(cliArgs, config) {
|
|
|
1024
1035
|
state.startupLatestVersion,
|
|
1025
1036
|
state.versionAlertsEnabled,
|
|
1026
1037
|
state.favoritesPinnedAndSticky,
|
|
1027
|
-
state.customTextFilter
|
|
1038
|
+
state.customTextFilter,
|
|
1039
|
+
state.lastReleaseDate
|
|
1028
1040
|
)
|
|
1029
1041
|
}
|
|
1030
1042
|
|
|
@@ -1034,6 +1046,8 @@ export async function runApp(cliArgs, config) {
|
|
|
1034
1046
|
? overlays.renderInstallEndpoints()
|
|
1035
1047
|
: state.toolInstallPromptOpen
|
|
1036
1048
|
? overlays.renderToolInstallPrompt()
|
|
1049
|
+
: state.installedModelsOpen
|
|
1050
|
+
? overlays.renderInstalledModels()
|
|
1037
1051
|
: state.incompatibleFallbackOpen
|
|
1038
1052
|
? overlays.renderIncompatibleFallback()
|
|
1039
1053
|
: state.commandPaletteOpen
|
|
@@ -1066,7 +1080,7 @@ export async function runApp(cliArgs, config) {
|
|
|
1066
1080
|
pinFavorites: state.favoritesPinnedAndSticky,
|
|
1067
1081
|
})
|
|
1068
1082
|
|
|
1069
|
-
process.stdout.write(ALT_HOME + renderTable(state.results, state.pendingPings, state.frame, state.cursor, state.sortColumn, state.sortDirection, state.pingInterval, state.lastPingTime, state.mode, state.tierFilterMode, state.scrollOffset, state.terminalRows, state.terminalCols, state.originFilterMode, null, state.pingMode, state.pingModeSource, state.hideUnconfiguredModels, state.widthWarningStartedAt, state.widthWarningDismissed, state.widthWarningShowCount, state.settingsUpdateState, state.settingsUpdateLatestVersion, false, state.startupLatestVersion, state.versionAlertsEnabled, state.favoritesPinnedAndSticky, state.customTextFilter))
|
|
1083
|
+
process.stdout.write(ALT_HOME + renderTable(state.results, state.pendingPings, state.frame, state.cursor, state.sortColumn, state.sortDirection, state.pingInterval, state.lastPingTime, state.mode, state.tierFilterMode, state.scrollOffset, state.terminalRows, state.terminalCols, state.originFilterMode, null, state.pingMode, state.pingModeSource, state.hideUnconfiguredModels, state.widthWarningStartedAt, state.widthWarningDismissed, state.widthWarningShowCount, state.settingsUpdateState, state.settingsUpdateLatestVersion, false, state.startupLatestVersion, state.versionAlertsEnabled, state.favoritesPinnedAndSticky, state.customTextFilter, state.lastReleaseDate))
|
|
1070
1084
|
if (process.stdout.isTTY) {
|
|
1071
1085
|
process.stdout.flush && process.stdout.flush()
|
|
1072
1086
|
}
|
|
@@ -1141,6 +1155,19 @@ export async function runApp(cliArgs, config) {
|
|
|
1141
1155
|
// 📖 Save cache after initial pings complete for faster next startup
|
|
1142
1156
|
saveCache(state.results, state.pingMode)
|
|
1143
1157
|
|
|
1158
|
+
// 📖 Background version re-check: poll npm registry every 5 minutes.
|
|
1159
|
+
// 📖 If a new version appears (wasn't there at startup), update the banner live.
|
|
1160
|
+
const VERSION_RECHECK_INTERVAL_MS = 5 * 60 * 1000
|
|
1161
|
+
state.versionRecheckTimer = setInterval(async () => {
|
|
1162
|
+
if (isDevMode || !state.versionAlertsEnabled) return
|
|
1163
|
+
try {
|
|
1164
|
+
const fresh = await checkForUpdate()
|
|
1165
|
+
if (fresh) {
|
|
1166
|
+
state.startupLatestVersion = fresh
|
|
1167
|
+
}
|
|
1168
|
+
} catch {}
|
|
1169
|
+
}, VERSION_RECHECK_INTERVAL_MS)
|
|
1170
|
+
|
|
1144
1171
|
// 📖 Keep interface running forever - user can select anytime or Ctrl+C to exit
|
|
1145
1172
|
// 📖 The pings continue running in background with dynamic interval
|
|
1146
1173
|
// 📖 User can press W to decrease interval (faster pings) or = to increase (slower)
|
package/src/command-palette.js
CHANGED
|
@@ -203,6 +203,7 @@ const BASE_COMMAND_TREE = [
|
|
|
203
203
|
{ id: 'open-feedback', label: 'Feedback', shortcut: 'I', icon: '📝', type: 'page', description: 'Report bugs or requests', keywords: ['feedback', 'bug', 'request'] },
|
|
204
204
|
{ id: 'open-recommend', label: 'Smart recommend', shortcut: 'Q', icon: '🎯', type: 'page', description: 'Find best model for task', keywords: ['recommend', 'best model'] },
|
|
205
205
|
{ id: 'open-install-endpoints', label: 'Install endpoints', icon: '🔌', type: 'page', description: 'Install provider catalogs', keywords: ['install', 'endpoints', 'providers'] },
|
|
206
|
+
{ id: 'open-installed-models', label: 'Installed models', icon: '🗂️', type: 'page', description: 'View models configured in tools', keywords: ['installed', 'models', 'configured', 'tools', 'manager', 'goose', 'crush', 'aider'] },
|
|
206
207
|
]
|
|
207
208
|
|
|
208
209
|
/**
|