free-coding-models 0.3.22 → 0.3.24
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 +48 -0
- package/README.md +76 -19
- package/package.json +1 -1
- package/sources.js +60 -0
- package/src/app.js +43 -17
- package/src/command-palette.js +103 -6
- package/src/config.js +4 -2
- package/src/endpoint-installer.js +3 -2
- package/src/key-handler.js +311 -29
- package/src/overlays.js +119 -8
- package/src/provider-metadata.js +25 -0
- package/src/render-helpers.js +15 -2
- package/src/render-table.js +81 -7
- package/src/theme.js +6 -0
- package/src/tool-bootstrap.js +22 -0
- package/src/tool-launchers.js +93 -2
- package/src/tool-metadata.js +94 -11
- package/src/utils.js +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,54 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
---
|
|
3
3
|
|
|
4
|
+
## [0.3.24] - 2026-03-19
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
- **Unique emoji per tool** — Every CLI tool now has a dedicated emoji shown in the Compatible column, Z-cycle badge, command palette, help overlay, and README (📦 OpenCode, 🦞 OpenClaw, 💘 Crush, 🪿 Goose, π Pi, 🛠 Aider, 🐉 Qwen, 🤲 OpenHands, ⚡ Amp, 🦘 Rovo, ♊ Gemini)
|
|
8
|
+
- **Merged compat column** — OpenCode CLI and Desktop share 📦 in a single slot (11 slots instead of 12 separate initials)
|
|
9
|
+
- **COMPAT_COLUMN_SLOTS** — New export in tool-metadata.js for merged compatible-column rendering
|
|
10
|
+
- **Width warning now always shows** - Terminal width warning displays every time terminal is resized below 80 columns (previously limited to 2 shows per session)
|
|
11
|
+
- **Gemini CLI integration** - New CLI-only tool provider with 3 models (Gemini 3 Pro 🆕, Gemini 2.5 Pro, Gemini 2.5 Flash)
|
|
12
|
+
- **Rovo Dev CLI integration** - New CLI-only tool provider with Claude Sonnet 4 🆕
|
|
13
|
+
- **Tool compatibility alerts** - When trying to launch Rovo/Gemini models with wrong tool, shows alert and offers to switch
|
|
14
|
+
- **Auto-install detection** - Prompt to install CLI tools when binary not found (Rovo/Gemini)
|
|
15
|
+
- **OpenAI-compatible API support for Gemini** - Gemini CLI can use custom providers via environment variables
|
|
16
|
+
- **New CLI flags** - Added `--rovo` and `--gemini` launch options
|
|
17
|
+
- **"🆕" badges** - Mark newly added models in the table (Claude Sonnet 4, Gemini 3 Pro)
|
|
18
|
+
- **OpenCode Zen free models** - 5 new free models (Big Pickle, GPT 5 Nano, MiMo V2 Flash Free, MiniMax M2.5 Free, Nemotron 3 Super Free) exclusive to OpenCode CLI/Desktop via `opencode-zen` provider
|
|
19
|
+
- **"Compatible with" column** - New TUI column showing colored emojis for each tool a model supports; incompatible tools show dim spaces
|
|
20
|
+
- **Tool color system** - Each of the 12 supported tools now has a unique RGB color and emoji used in the Z-cycle badge and compatibility column
|
|
21
|
+
- **Incompatible model highlighting** - When a tool mode is active (via Z), models that can't run with that tool get a dark red background for instant visibility — they stay in their normal sorted position (not pushed to the bottom)
|
|
22
|
+
- **Tool compatibility functions** - `getCompatibleTools()` and `isModelCompatibleWithTool()` in tool-metadata.js for programmatic compatibility checks
|
|
23
|
+
- **Incompatible model fallback overlay** - When pressing Enter on a model that can't run on the active tool (red-highlighted row), an in-TUI overlay appears with two options: (1) switch to a compatible tool, or (2) pick a similar model by SWE score that works with the current tool
|
|
24
|
+
- **findSimilarCompatibleModels()** - New function in tool-metadata.js that finds models with closest SWE scores compatible with the active tool
|
|
25
|
+
- **Updated provider/model counts** - Now 23 providers with 171 models (was 20/160)
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- **Z key cycle** - Rovo and Gemini added to tool mode cycle (last in order)
|
|
29
|
+
- **Tool metadata** - Removed `initial` field (replaced by emojis), added `cliOnly` flag for CLI-only tools, `emoji` and `color` properties for all 12 tools
|
|
30
|
+
- **Provider metadata** - Added Rovo, Gemini, and OpenCode Zen provider information
|
|
31
|
+
- **Responsive column hiding** - Compatible column hides first (before Rank) on narrow terminals
|
|
32
|
+
- **Key handler** - Zen models auto-switch to OpenCode CLI on launch; API key warnings skip Zen models
|
|
33
|
+
- **Documentation** - Updated README with CLI-only tools section, Zen models, compatibility matrix
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- **Missing import error** - Fixed `getToolMeta` not defined in key-handler.js
|
|
37
|
+
- **CLI-only tools API key requirement** - Gemini CLI and Rovo Dev CLI no longer require API keys to be configured before launching; these tools manage their own authentication
|
|
38
|
+
|
|
39
|
+
## 0.3.23
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
- **Favorites display mode (`Y`)**: Added a global toggle to switch favorites between `pinned + always visible` and `normal rows` (starred only, fully obeying active filters/sort).
|
|
43
|
+
- **Favorites mode row in Settings**: Added a dedicated Settings row to inspect/toggle favorites display behavior without leaving the maintenance screen.
|
|
44
|
+
- **Expanded command palette action menus**: Added nested menus for Ping Mode (speed/normal/slow/forced with explanations), Target Tool (all supported tools with explanations), and Favorites Mode (including the new `Y` flow).
|
|
45
|
+
- **Active text-filter footer alert**: When a custom search filter is active (for example `deep`), the last TUI footer line now shows a high-visibility inline badge (between `N Changelog` and `Ctrl+C Exit`) with the exact query and an `X` shortcut to clear it instantly.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
- **Favorites sorting/filtering behavior**: Sort/filter logic now respects the selected favorites mode across the table refresh loop, hotkeys, and renderer so non-pinned mode behaves consistently everywhere.
|
|
49
|
+
- **Favorites default mode**: New/legacy configs now default to `Normal filter/sort` favorites mode (not pinned) until users press `Y` to opt into pinned+sticky behavior.
|
|
50
|
+
- **Footer/help/docs shortcut hints**: Surfaced `Y` in the TUI footer, Help overlay, and README so the new favorites mode is discoverable.
|
|
51
|
+
|
|
4
52
|
## 0.3.22
|
|
5
53
|
|
|
6
54
|
### Added
|
package/README.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
<img src="https://img.shields.io/npm/v/free-coding-models?color=76b900&label=npm&logo=npm" alt="npm version">
|
|
3
3
|
<img src="https://img.shields.io/node/v/free-coding-models?color=76b900&logo=node.js" alt="node version">
|
|
4
4
|
<img src="https://img.shields.io/npm/l/free-coding-models?color=76b900" alt="license">
|
|
5
|
-
<img src="https://img.shields.io/badge/models-
|
|
6
|
-
<img src="https://img.shields.io/badge/providers-
|
|
5
|
+
<img src="https://img.shields.io/badge/models-174-76b900?logo=nvidia" alt="models count">
|
|
6
|
+
<img src="https://img.shields.io/badge/providers-23-blue" alt="providers count">
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
<h1 align="center">free-coding-models</h1>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<strong>Find the fastest free coding model in seconds</strong><br>
|
|
13
|
-
<sub>Ping
|
|
13
|
+
<sub>Ping 174 models across 23 AI Free providers in real-time </sub><br><sub> Install Free API endpoints to your favorite AI coding tool: <br>📦 OpenCode, 🦞 OpenClaw, 💘 Crush, 🪿 Goose, 🛠 Aider, 🐉 Qwen Code, 🤲 OpenHands, ⚡ Amp, π Pi, 🦘 Rovo or ♊ Gemini in one keystroke</sub>
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
|
|
@@ -47,7 +47,7 @@ create a free account on one of the [providers](#-list-of-free-ai-providers)
|
|
|
47
47
|
|
|
48
48
|
## 💡 Why this tool?
|
|
49
49
|
|
|
50
|
-
There are **
|
|
50
|
+
There are **174+ free coding models** scattered across 23 providers. Which one is fastest right now? Which one is actually stable versus just lucky on the last ping?
|
|
51
51
|
|
|
52
52
|
This CLI pings them all in parallel, shows live latency, and calculates a **live Stability Score (0-100)**. Average latency alone is misleading if a model randomly spikes to 6 seconds; the stability score measures true reliability by combining **p95 latency** (30%), **jitter/variance** (30%), **spike rate** (20%), and **uptime** (20%).
|
|
53
53
|
|
|
@@ -61,7 +61,7 @@ It then writes the model you pick directly into your coding tool's config — so
|
|
|
61
61
|
|
|
62
62
|
Create a free account on one provider below to get started:
|
|
63
63
|
|
|
64
|
-
**
|
|
64
|
+
**174 coding models** across 23 providers, ranked by [SWE-bench Verified](https://www.swebench.com).
|
|
65
65
|
|
|
66
66
|
| Provider | Models | Tier range | Free tier | Env var |
|
|
67
67
|
|----------|--------|-----------|-----------|--------|
|
|
@@ -85,6 +85,9 @@ Create a free account on one provider below to get started:
|
|
|
85
85
|
| [Cloudflare Workers AI](https://dash.cloudflare.com) | 6 | S → B | Free: 10k neurons/day, text-gen 300 RPM | `CLOUDFLARE_API_TOKEN` + `CLOUDFLARE_ACCOUNT_ID` |
|
|
86
86
|
| [Perplexity API](https://www.perplexity.ai/settings/api) | 4 | A+ → B | Tiered limits by spend (default ~50 RPM) | `PERPLEXITY_API_KEY` |
|
|
87
87
|
| [Replicate](https://replicate.com/account/api-tokens) | 1 | A- | 6 req/min (no payment) – up to 3,000 RPM with payment | `REPLICATE_API_TOKEN` |
|
|
88
|
+
| [Rovo Dev CLI](https://www.atlassian.com/rovo) | 1 | S+ | 5M tokens/day (beta) | CLI tool 🦘 |
|
|
89
|
+
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | 3 | S+ → A+ | 1,000 req/day | CLI tool ♊ |
|
|
90
|
+
| [OpenCode Zen](https://opencode.ai/zen) | 8 | S+ → A+ | Free with OpenCode account | Zen models ✨ |
|
|
88
91
|
|
|
89
92
|
> 💡 One key is enough. Add more at any time with **`P`** inside the TUI.
|
|
90
93
|
|
|
@@ -121,7 +124,7 @@ Need to fix contrast because your terminal theme is fighting the TUI? Press **`G
|
|
|
121
124
|
↑↓ navigate → Enter to launch
|
|
122
125
|
```
|
|
123
126
|
|
|
124
|
-
The model you select is automatically written into your tool's config (OpenCode, OpenClaw, Crush, etc.) and the tool opens immediately. Done.
|
|
127
|
+
The model you select is automatically written into your tool's config (📦 OpenCode, 🦞 OpenClaw, 💘 Crush, etc.) and the tool opens immediately. Done.
|
|
125
128
|
|
|
126
129
|
If the active CLI tool is missing, FCM now catches it before launch, offers a tiny Yes/No install prompt, installs the tool with its official global command, then resumes the same model launch automatically.
|
|
127
130
|
|
|
@@ -157,19 +160,69 @@ free-coding-models --openclaw --origin groq
|
|
|
157
160
|
|
|
158
161
|
| Flag | Launches |
|
|
159
162
|
|------|----------|
|
|
160
|
-
| `--opencode` | OpenCode CLI |
|
|
161
|
-
| `--opencode-desktop` | OpenCode Desktop |
|
|
162
|
-
| `--openclaw` | OpenClaw |
|
|
163
|
-
| `--crush` | Crush |
|
|
164
|
-
| `--goose` | Goose |
|
|
165
|
-
| `--aider` | Aider |
|
|
166
|
-
| `--qwen` | Qwen Code |
|
|
167
|
-
| `--openhands` | OpenHands |
|
|
168
|
-
| `--amp` | Amp |
|
|
169
|
-
| `--pi` | Pi |
|
|
163
|
+
| `--opencode` | 📦 OpenCode CLI |
|
|
164
|
+
| `--opencode-desktop` | 📦 OpenCode Desktop |
|
|
165
|
+
| `--openclaw` | 🦞 OpenClaw |
|
|
166
|
+
| `--crush` | 💘 Crush |
|
|
167
|
+
| `--goose` | 🪿 Goose |
|
|
168
|
+
| `--aider` | 🛠 Aider |
|
|
169
|
+
| `--qwen` | 🐉 Qwen Code |
|
|
170
|
+
| `--openhands` | 🤲 OpenHands |
|
|
171
|
+
| `--amp` | ⚡ Amp |
|
|
172
|
+
| `--pi` | π Pi |
|
|
173
|
+
| `--rovo` | 🦘 Rovo Dev CLI |
|
|
174
|
+
| `--gemini` | ♊ Gemini CLI |
|
|
170
175
|
|
|
171
176
|
Press **`Z`** in the TUI to cycle between tools without restarting.
|
|
172
177
|
|
|
178
|
+
### CLI-Only Tools
|
|
179
|
+
|
|
180
|
+
**🦘 Rovo Dev CLI**
|
|
181
|
+
- Provider: [Atlassian Rovo](https://www.atlassian.com/rovo)
|
|
182
|
+
- Install: [Installation Guide](https://support.atlassian.com/rovo/docs/install-and-run-rovo-dev-cli-on-your-device/)
|
|
183
|
+
- Free tier: 5M tokens/day (beta, requires Atlassian account)
|
|
184
|
+
- Model: Claude Sonnet 4 (72.7% SWE-bench)
|
|
185
|
+
- Launch: `free-coding-models --rovo` or press `Z` until Rovo mode
|
|
186
|
+
- Features: Jira/Confluence integration, MCP server support
|
|
187
|
+
|
|
188
|
+
**♊ Gemini CLI**
|
|
189
|
+
- Provider: [Google Gemini](https://github.com/google-gemini/gemini-cli)
|
|
190
|
+
- Install: `npm install -g @google/gemini-cli`
|
|
191
|
+
- Free tier: 1,000 requests/day (personal Google account, no credit card)
|
|
192
|
+
- Models: Gemini 3 Pro (76.2% SWE-bench), Gemini 2.5 Pro, Gemini 2.5 Flash
|
|
193
|
+
- Launch: `free-coding-models --gemini` or press `Z` until Gemini mode
|
|
194
|
+
- Features: OpenAI-compatible API support, MCP server support, Google Search grounding
|
|
195
|
+
|
|
196
|
+
**Note:** When launching these tools via `Z` key or command palette, if the current mode doesn't match the tool, you'll see a confirmation alert asking to switch to the correct tool before launching.
|
|
197
|
+
|
|
198
|
+
### OpenCode Zen Free Models
|
|
199
|
+
|
|
200
|
+
[OpenCode Zen](https://opencode.ai/zen) is a hosted AI gateway offering 8 free coding models exclusively through OpenCode CLI and OpenCode Desktop. These models are **not** available through other tools.
|
|
201
|
+
|
|
202
|
+
| Model | Tier | SWE-bench | Context |
|
|
203
|
+
|-------|------|-----------|---------|
|
|
204
|
+
| Big Pickle | S+ | 72.0% | 200k |
|
|
205
|
+
| MiniMax M2.5 Free | S+ | 80.2% | 200k |
|
|
206
|
+
| MiMo V2 Pro Free | S+ | 78.0% | 1M |
|
|
207
|
+
| MiMo V2 Omni Free | S | 64.0% | 128k |
|
|
208
|
+
| MiMo V2 Flash Free | S+ | 73.4% | 256k |
|
|
209
|
+
| Nemotron 3 Super Free | A+ | 52.0% | 128k |
|
|
210
|
+
| GPT 5 Nano | S | 65.0% | 128k |
|
|
211
|
+
| Trinity Large Preview Free | S | 62.0% | 128k |
|
|
212
|
+
|
|
213
|
+
To use Zen models: sign up at [opencode.ai/auth](https://opencode.ai/auth) and enter your Zen API key via `P` (Settings). Zen models appear in the main table and auto-switch to OpenCode CLI on launch.
|
|
214
|
+
|
|
215
|
+
### Tool Compatibility
|
|
216
|
+
|
|
217
|
+
The TUI shows a **"Compatible with"** column displaying colored emojis for each supported tool. When a tool mode is active (via `Z`), models incompatible with that tool are highlighted with a dark red background so you can instantly see which models work with your current tool.
|
|
218
|
+
|
|
219
|
+
| Model Type | Compatible Tools |
|
|
220
|
+
|------------|-----------------|
|
|
221
|
+
| Regular (NVIDIA, Groq, etc.) | All tools except 🦘 Rovo and ♊ Gemini |
|
|
222
|
+
| Rovo | 🦘 Rovo Dev CLI only |
|
|
223
|
+
| Gemini | ♊ Gemini CLI only |
|
|
224
|
+
| OpenCode Zen | 📦 OpenCode CLI and 📦 OpenCode Desktop only |
|
|
225
|
+
|
|
173
226
|
→ **[Full flags reference](./docs/flags.md)**
|
|
174
227
|
|
|
175
228
|
---
|
|
@@ -185,6 +238,8 @@ Press **`Z`** in the TUI to cycle between tools without restarting.
|
|
|
185
238
|
| `D` | Cycle provider filter |
|
|
186
239
|
| `E` | Toggle configured-only mode |
|
|
187
240
|
| `F` | Favorite / unfavorite model |
|
|
241
|
+
| `Y` | Toggle favorites mode (`Normal filter/sort` default ↔ `Pinned + always visible`) |
|
|
242
|
+
| `X` | Clear active custom text filter |
|
|
188
243
|
| `G` | Cycle global theme (`Auto → Dark → Light`) |
|
|
189
244
|
| `Ctrl+P` | Open ⚡️ command palette (search + run actions) |
|
|
190
245
|
| `R/S/C/M/O/L/A/H/V/B/U` | Sort columns |
|
|
@@ -202,17 +257,19 @@ Press **`Z`** in the TUI to cycle between tools without restarting.
|
|
|
202
257
|
|
|
203
258
|
## ✨ Features
|
|
204
259
|
|
|
205
|
-
- **Parallel pings** — all
|
|
260
|
+
- **Parallel pings** — all 174 models tested simultaneously via native `fetch`
|
|
206
261
|
- **Adaptive monitoring** — 2s burst for 60s → 10s normal → 30s idle
|
|
207
262
|
- **Stability score** — composite 0–100 (p95 latency, jitter, spike rate, uptime)
|
|
208
263
|
- **Smart ranking** — top 3 highlighted 🥇🥈🥉
|
|
209
|
-
- **Favorites** —
|
|
264
|
+
- **Favorites** — star models with `F`, persisted across sessions, default to normal rows, and switch display mode with `Y` (pinned+sticky vs normal rows)
|
|
210
265
|
- **Configured-only default** — only shows providers you have keys for
|
|
211
266
|
- **Keyless latency** — models ping even without an API key (show 🔑 NO KEY)
|
|
212
267
|
- **Smart Recommend** — questionnaire picks the best model for your task type
|
|
213
268
|
- **⚡️ Command Palette** — `Ctrl+P` opens a searchable action launcher for filters, sorting, overlays, and quick toggles
|
|
214
|
-
- **Install Endpoints** — push a full provider catalog into any tool's config (`
|
|
269
|
+
- **Install Endpoints** — push a full provider catalog into any tool's config (from Settings `P` or ⚡️ Command Palette)
|
|
215
270
|
- **Missing tool bootstrap** — detect absent CLIs, offer one-click install, then continue the selected launch automatically
|
|
271
|
+
- **Tool compatibility matrix** — colored emojis show which tools each model supports; incompatible rows highlighted in dark red when a tool mode is active
|
|
272
|
+
- **OpenCode Zen models** — 8 free models exclusive to OpenCode CLI/Desktop, powered by the Zen AI gateway
|
|
216
273
|
- **Width guardrail** — shows a warning instead of a broken table in narrow terminals
|
|
217
274
|
- **Readable everywhere** — semantic theme palette keeps table rows, overlays, badges, and help screens legible in dark and light terminals
|
|
218
275
|
- **Global theme switch** — `G` cycles `auto`, `dark`, and `light` live without restarting
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.24",
|
|
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
|
@@ -344,6 +344,40 @@ export const iflow = [
|
|
|
344
344
|
['qwen3-max', 'Qwen3 Max', 'A+', '55.0%', '256k'],
|
|
345
345
|
]
|
|
346
346
|
|
|
347
|
+
// 📖 Rovo Dev CLI source - https://www.atlassian.com/rovo
|
|
348
|
+
// 📖 CLI tool only - no API endpoint - requires 'acli rovodev run'
|
|
349
|
+
// 📖 Install: https://support.atlassian.com/rovo/docs/install-and-run-rovo-dev-cli-on-your-device/
|
|
350
|
+
// 📖 Free tier: 5M tokens/day (beta) - Claude Sonnet 4 (72.7% SWE-bench)
|
|
351
|
+
// 📖 Requires Atlassian account + Rovo Dev activated on your site
|
|
352
|
+
export const rovo = [
|
|
353
|
+
['anthropic/claude-sonnet-4', 'Claude Sonnet 4 🆕', 'S+', '72.7%', '200k'],
|
|
354
|
+
]
|
|
355
|
+
|
|
356
|
+
// 📖 Gemini CLI source - https://github.com/google-gemini/gemini-cli
|
|
357
|
+
// 📖 CLI tool with OpenAI-compatible API support
|
|
358
|
+
// 📖 Install: npm install -g @google/gemini-cli
|
|
359
|
+
// 📖 Free tier: 1,000 req/day with personal Google account (no credit card)
|
|
360
|
+
// 📖 Models: Gemini 3 Pro (76.2% SWE-bench), Gemini 2.5 Pro, Gemini 2.5 Flash
|
|
361
|
+
// 📖 Supports custom OpenAI-compatible providers via GEMINI_API_BASE_URL
|
|
362
|
+
export const gemini = [
|
|
363
|
+
['google/gemini-3-pro', 'Gemini 3 Pro 🆕', 'S+', '76.2%', '1M'],
|
|
364
|
+
['google/gemini-2.5-pro', 'Gemini 2.5 Pro', 'S+', '63.2%', '1M'],
|
|
365
|
+
['google/gemini-2.5-flash', 'Gemini 2.5 Flash', 'A+', '50.0%', '1M'],
|
|
366
|
+
]
|
|
367
|
+
|
|
368
|
+
// 📖 OpenCode Zen free models — hosted AI gateway accessed through OpenCode CLI/Desktop
|
|
369
|
+
// 📖 Endpoint: https://opencode.ai/zen/v1/... — requires OpenCode Zen API key
|
|
370
|
+
// 📖 These models are FREE on the Zen platform and only run on OpenCode CLI or OpenCode Desktop
|
|
371
|
+
// 📖 Login: https://opencode.ai/auth — get your Zen API key
|
|
372
|
+
// 📖 Config: set provider to opencode/<model-id> in OpenCode config
|
|
373
|
+
export const opencodeZen = [
|
|
374
|
+
['big-pickle', 'Big Pickle 🆕', 'S+', '72.0%', '200k'],
|
|
375
|
+
['gpt-5-nano', 'GPT 5 Nano 🆕', 'S', '65.0%', '128k'],
|
|
376
|
+
['mimo-v2-flash-free', 'MiMo V2 Flash Free 🆕', 'S+', '73.4%', '256k'],
|
|
377
|
+
['minimax-m2.5-free', 'MiniMax M2.5 Free 🆕', 'S+', '80.2%', '200k'],
|
|
378
|
+
['nemotron-3-super-free', 'Nemotron 3 Super Free 🆕', 'A+', '52.0%', '128k'],
|
|
379
|
+
]
|
|
380
|
+
|
|
347
381
|
// 📖 All sources combined - used by the main script
|
|
348
382
|
// 📖 Each source has: name (display), url (API endpoint), models (array of model tuples)
|
|
349
383
|
export const sources = {
|
|
@@ -447,6 +481,32 @@ export const sources = {
|
|
|
447
481
|
url: 'https://apis.iflow.cn/v1/chat/completions',
|
|
448
482
|
models: iflow,
|
|
449
483
|
},
|
|
484
|
+
// 📖 CLI-only tools (no API endpoint - launched directly)
|
|
485
|
+
rovo: {
|
|
486
|
+
name: 'Rovo Dev CLI',
|
|
487
|
+
url: null, // CLI tool - no API endpoint
|
|
488
|
+
models: rovo,
|
|
489
|
+
cliOnly: true,
|
|
490
|
+
installUrl: 'https://support.atlassian.com/rovo/docs/install-and-run-rovo-dev-cli-on-your-device/',
|
|
491
|
+
binary: 'acli',
|
|
492
|
+
checkArgs: ['rovodev', '--help'],
|
|
493
|
+
},
|
|
494
|
+
gemini: {
|
|
495
|
+
name: 'Gemini CLI',
|
|
496
|
+
url: null, // CLI tool - no API endpoint (can use OpenAI-compatible via env)
|
|
497
|
+
models: gemini,
|
|
498
|
+
cliOnly: true,
|
|
499
|
+
installUrl: 'https://github.com/google-gemini/gemini-cli',
|
|
500
|
+
binary: 'gemini',
|
|
501
|
+
checkArgs: ['--version'],
|
|
502
|
+
},
|
|
503
|
+
// 📖 OpenCode Zen free models — hosted AI gateway, only runs on OpenCode CLI / Desktop
|
|
504
|
+
'opencode-zen': {
|
|
505
|
+
name: 'OpenCode Zen',
|
|
506
|
+
url: 'https://opencode.ai/zen/v1/chat/completions',
|
|
507
|
+
models: opencodeZen,
|
|
508
|
+
zenOnly: true,
|
|
509
|
+
},
|
|
450
510
|
}
|
|
451
511
|
|
|
452
512
|
// 📖 Flatten all models from all sources — each entry includes providerKey as 6th element
|
package/src/app.js
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
* - JSON config stored in ~/.free-coding-models.json (auto-migrates from old plain-text)
|
|
22
22
|
* - Multi-provider support via sources.js (NIM/Groq/Cerebras/OpenRouter/Hugging Face/Replicate/DeepInfra/... — extensible)
|
|
23
23
|
* - Settings screen (P key) to manage API keys, provider toggles, manual updates, and provider-key diagnostics
|
|
24
|
-
* - Install Endpoints flow (
|
|
25
|
-
* - Favorites system: toggle with F,
|
|
24
|
+
* - Install Endpoints flow (Settings / Command Palette) to push provider catalogs into OpenCode, OpenClaw, Crush, and Goose
|
|
25
|
+
* - Favorites system: toggle with F, switch pinning mode with Y, persist between sessions
|
|
26
26
|
* - Uptime percentage tracking (successful pings / total pings)
|
|
27
27
|
* - Sortable columns (R/O/M/L/A/S/C/H/V/B/U/G keys)
|
|
28
28
|
* - Tier filtering via T key (cycles S+→S→A+→A→A-→B+→B→C→All)
|
|
@@ -233,6 +233,8 @@ export async function runApp(cliArgs, config) {
|
|
|
233
233
|
openhands: cliArgs.openHandsMode,
|
|
234
234
|
amp: cliArgs.ampMode,
|
|
235
235
|
pi: cliArgs.piMode,
|
|
236
|
+
rovo: cliArgs.rovoMode,
|
|
237
|
+
gemini: cliArgs.geminiMode,
|
|
236
238
|
}
|
|
237
239
|
return flagByMode[toolMode] === true
|
|
238
240
|
})
|
|
@@ -307,7 +309,7 @@ export async function runApp(cliArgs, config) {
|
|
|
307
309
|
}
|
|
308
310
|
|
|
309
311
|
// 📖 Re-sync tracked external-tool catalogs after the live provider catalog has settled.
|
|
310
|
-
// 📖 This keeps prior
|
|
312
|
+
// 📖 This keeps prior endpoint installs aligned with the current FCM model list.
|
|
311
313
|
refreshInstalledEndpoints(config)
|
|
312
314
|
|
|
313
315
|
// 📖 Build results from MODELS — only include enabled providers
|
|
@@ -383,12 +385,13 @@ export async function runApp(cliArgs, config) {
|
|
|
383
385
|
tierFilterMode: 0, // 📖 Index into TIER_CYCLE (0=All, 1=S+, 2=S, ...)
|
|
384
386
|
originFilterMode: 0, // 📖 Index into ORIGIN_CYCLE (0=All, then providers)
|
|
385
387
|
hideUnconfiguredModels: config.settings?.hideUnconfiguredModels === true, // 📖 Hide providers with no configured API key when true.
|
|
388
|
+
favoritesPinnedAndSticky: config.settings?.favoritesPinnedAndSticky === true, // 📖 false by default: favorites follow normal sort/filter rules until Y enables pinned+sticky mode.
|
|
386
389
|
scrollOffset: 0, // 📖 First visible model index in viewport
|
|
387
390
|
terminalRows: process.stdout.rows || 24, // 📖 Current terminal height
|
|
388
391
|
terminalCols: process.stdout.columns || 80, // 📖 Current terminal width
|
|
389
392
|
widthWarningStartedAt: (process.stdout.columns || 80) < WIDTH_WARNING_MIN_COLS ? now : null, // 📖 Start immediately in very narrow viewports.
|
|
390
393
|
widthWarningDismissed: false, // 📖 Esc hides the narrow-terminal warning early for the current narrow-width session.
|
|
391
|
-
widthWarningShowCount: 0, // 📖
|
|
394
|
+
widthWarningShowCount: 0, // 📖 No longer used — kept for backward compatibility. Warning now shows every time terminal is too small.
|
|
392
395
|
// 📖 Settings screen state (P key opens it)
|
|
393
396
|
settingsOpen: false, // 📖 Whether settings overlay is active
|
|
394
397
|
settingsCursor: 0, // 📖 Which provider row is selected in settings
|
|
@@ -409,11 +412,11 @@ export async function runApp(cliArgs, config) {
|
|
|
409
412
|
commandPaletteScrollOffset: 0, // 📖 Vertical scroll offset for the command palette result viewport.
|
|
410
413
|
commandPaletteResults: [], // 📖 Cached fuzzy-filtered command entries for the command palette.
|
|
411
414
|
commandPaletteFrozenTable: null, // 📖 Frozen table snapshot rendered behind the command palette overlay.
|
|
412
|
-
commandPaletteExpandedIds: new Set(['filters']), // 📖
|
|
415
|
+
commandPaletteExpandedIds: new Set(['filters', 'actions']), // 📖 Expanded category IDs (filters + actions open by default for quick access).
|
|
413
416
|
helpVisible: false, // 📖 Whether the help overlay (K key) is active
|
|
414
417
|
settingsScrollOffset: 0, // 📖 Vertical scroll offset for Settings overlay viewport
|
|
415
418
|
helpScrollOffset: 0, // 📖 Vertical scroll offset for Help overlay viewport
|
|
416
|
-
// 📖 Install Endpoints overlay state (
|
|
419
|
+
// 📖 Install Endpoints overlay state (opened from Settings or Command Palette)
|
|
417
420
|
installEndpointsOpen: false, // 📖 Whether the install-endpoints overlay is active
|
|
418
421
|
installEndpointsPhase: 'providers', // 📖 providers | tools | scope | models | result
|
|
419
422
|
installEndpointsCursor: 0, // 📖 Selected row within the current install phase
|
|
@@ -433,6 +436,15 @@ export async function runApp(cliArgs, config) {
|
|
|
433
436
|
toolInstallPromptModel: null,
|
|
434
437
|
toolInstallPromptPlan: null,
|
|
435
438
|
toolInstallPromptErrorMsg: null,
|
|
439
|
+
// 📖 Incompatible model fallback overlay — shown when user presses Enter on a red-highlighted model.
|
|
440
|
+
// 📖 Offers two options: switch to a compatible tool, or pick a similar SWE-scored model.
|
|
441
|
+
incompatibleFallbackOpen: false,
|
|
442
|
+
incompatibleFallbackCursor: 0,
|
|
443
|
+
incompatibleFallbackScrollOffset: 0,
|
|
444
|
+
incompatibleFallbackModel: null, // 📖 The incompatible model the user tried to launch
|
|
445
|
+
incompatibleFallbackTools: [], // 📖 Compatible tools for the selected model
|
|
446
|
+
incompatibleFallbackSimilarModels: [], // 📖 Similar SWE models compatible with current tool
|
|
447
|
+
incompatibleFallbackSection: 'tools', // 📖 'tools' or 'models' — which section cursor is in
|
|
436
448
|
// 📖 Smart Recommend overlay state (Q key opens it)
|
|
437
449
|
recommendOpen: false, // 📖 Whether the recommend overlay is active
|
|
438
450
|
recommendPhase: 'questionnaire', // 📖 'questionnaire'|'analyzing'|'results' — current phase
|
|
@@ -471,7 +483,6 @@ export async function runApp(cliArgs, config) {
|
|
|
471
483
|
if (prevCols >= WIDTH_WARNING_MIN_COLS || state.widthWarningDismissed) {
|
|
472
484
|
state.widthWarningStartedAt = Date.now()
|
|
473
485
|
state.widthWarningDismissed = false
|
|
474
|
-
state.widthWarningShowCount++ // 📖 Increment counter when showing the warning again
|
|
475
486
|
} else if (!state.widthWarningStartedAt) {
|
|
476
487
|
state.widthWarningStartedAt = Date.now()
|
|
477
488
|
}
|
|
@@ -678,12 +689,16 @@ export async function runApp(cliArgs, config) {
|
|
|
678
689
|
const activeTier = TIER_CYCLE[state.tierFilterMode]
|
|
679
690
|
const activeOrigin = ORIGIN_CYCLE[state.originFilterMode]
|
|
680
691
|
state.results.forEach(r => {
|
|
681
|
-
// 📖
|
|
682
|
-
if (r.isFavorite) {
|
|
692
|
+
// 📖 Sticky-favorites mode keeps favorites visible regardless of configured-only, tier, or provider filters.
|
|
693
|
+
if (state.favoritesPinnedAndSticky && r.isFavorite) {
|
|
683
694
|
r.hidden = false
|
|
684
695
|
return
|
|
685
696
|
}
|
|
686
|
-
|
|
697
|
+
// 📖 CLI-only tools (rovo, gemini) and Zen models don't need traditional API keys —
|
|
698
|
+
// 📖 they authenticate via their own CLI login flow, so "configured only" should never hide them.
|
|
699
|
+
const providerMeta = PROVIDER_METADATA[r.providerKey]
|
|
700
|
+
const noKeyNeeded = providerMeta?.cliOnly || providerMeta?.zenOnly
|
|
701
|
+
const unconfiguredHide = state.hideUnconfiguredModels && !noKeyNeeded && !getApiKey(state.config, r.providerKey)
|
|
687
702
|
if (unconfiguredHide) {
|
|
688
703
|
r.hidden = true
|
|
689
704
|
return
|
|
@@ -799,6 +814,7 @@ export async function runApp(cliArgs, config) {
|
|
|
799
814
|
startOpenCode,
|
|
800
815
|
startExternalTool,
|
|
801
816
|
getToolModeOrder,
|
|
817
|
+
getToolMeta,
|
|
802
818
|
getToolInstallPlan,
|
|
803
819
|
isToolInstalled,
|
|
804
820
|
installToolWithPlan,
|
|
@@ -825,7 +841,7 @@ export async function runApp(cliArgs, config) {
|
|
|
825
841
|
if (cliArgs.tierFilter) {
|
|
826
842
|
const allowed = TIER_LETTER_MAP[cliArgs.tierFilter]
|
|
827
843
|
state.results.forEach(r => {
|
|
828
|
-
r.hidden = r.isFavorite ? false : !allowed.includes(r.tier)
|
|
844
|
+
r.hidden = (state.favoritesPinnedAndSticky && r.isFavorite) ? false : !allowed.includes(r.tier)
|
|
829
845
|
})
|
|
830
846
|
}
|
|
831
847
|
|
|
@@ -861,9 +877,11 @@ export async function runApp(cliArgs, config) {
|
|
|
861
877
|
refreshAutoPingMode()
|
|
862
878
|
state.frame++
|
|
863
879
|
// 📖 Cache visible+sorted models each frame so Enter handler always matches the display
|
|
864
|
-
if (!state.settingsOpen && !state.installEndpointsOpen && !state.toolInstallPromptOpen && !state.recommendOpen && !state.feedbackOpen && !state.changelogOpen && !state.commandPaletteOpen) {
|
|
880
|
+
if (!state.settingsOpen && !state.installEndpointsOpen && !state.toolInstallPromptOpen && !state.incompatibleFallbackOpen && !state.recommendOpen && !state.feedbackOpen && !state.changelogOpen && !state.commandPaletteOpen) {
|
|
865
881
|
const visible = state.results.filter(r => !r.hidden)
|
|
866
|
-
state.visibleSorted = sortResultsWithPinnedFavorites(visible, state.sortColumn, state.sortDirection
|
|
882
|
+
state.visibleSorted = sortResultsWithPinnedFavorites(visible, state.sortColumn, state.sortDirection, {
|
|
883
|
+
pinFavorites: state.favoritesPinnedAndSticky,
|
|
884
|
+
})
|
|
867
885
|
}
|
|
868
886
|
let tableContent = null
|
|
869
887
|
if (state.commandPaletteOpen) {
|
|
@@ -896,7 +914,9 @@ export async function runApp(cliArgs, config) {
|
|
|
896
914
|
state.settingsUpdateLatestVersion,
|
|
897
915
|
false,
|
|
898
916
|
state.startupLatestVersion,
|
|
899
|
-
state.versionAlertsEnabled
|
|
917
|
+
state.versionAlertsEnabled,
|
|
918
|
+
state.favoritesPinnedAndSticky,
|
|
919
|
+
state.customTextFilter
|
|
900
920
|
)
|
|
901
921
|
}
|
|
902
922
|
tableContent = state.commandPaletteFrozenTable
|
|
@@ -928,7 +948,9 @@ export async function runApp(cliArgs, config) {
|
|
|
928
948
|
state.settingsUpdateLatestVersion,
|
|
929
949
|
false,
|
|
930
950
|
state.startupLatestVersion,
|
|
931
|
-
state.versionAlertsEnabled
|
|
951
|
+
state.versionAlertsEnabled,
|
|
952
|
+
state.favoritesPinnedAndSticky,
|
|
953
|
+
state.customTextFilter
|
|
932
954
|
)
|
|
933
955
|
}
|
|
934
956
|
|
|
@@ -938,6 +960,8 @@ export async function runApp(cliArgs, config) {
|
|
|
938
960
|
? overlays.renderInstallEndpoints()
|
|
939
961
|
: state.toolInstallPromptOpen
|
|
940
962
|
? overlays.renderToolInstallPrompt()
|
|
963
|
+
: state.incompatibleFallbackOpen
|
|
964
|
+
? overlays.renderIncompatibleFallback()
|
|
941
965
|
: state.commandPaletteOpen
|
|
942
966
|
? tableContent + overlays.renderCommandPalette()
|
|
943
967
|
: state.recommendOpen
|
|
@@ -964,9 +988,11 @@ export async function runApp(cliArgs, config) {
|
|
|
964
988
|
|
|
965
989
|
// 📖 Populate visibleSorted before the first frame so Enter works immediately
|
|
966
990
|
const initialVisible = state.results.filter(r => !r.hidden)
|
|
967
|
-
state.visibleSorted = sortResultsWithPinnedFavorites(initialVisible, state.sortColumn, state.sortDirection
|
|
991
|
+
state.visibleSorted = sortResultsWithPinnedFavorites(initialVisible, state.sortColumn, state.sortDirection, {
|
|
992
|
+
pinFavorites: state.favoritesPinnedAndSticky,
|
|
993
|
+
})
|
|
968
994
|
|
|
969
|
-
|
|
995
|
+
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))
|
|
970
996
|
if (process.stdout.isTTY) {
|
|
971
997
|
process.stdout.flush && process.stdout.flush()
|
|
972
998
|
}
|
package/src/command-palette.js
CHANGED
|
@@ -15,6 +15,74 @@
|
|
|
15
15
|
* @see src/overlays.js
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { TOOL_METADATA, TOOL_MODE_ORDER } from './tool-metadata.js'
|
|
19
|
+
|
|
20
|
+
const TOOL_MODE_DESCRIPTIONS = {
|
|
21
|
+
opencode: 'Launch in OpenCode CLI with the selected model.',
|
|
22
|
+
'opencode-desktop': 'Set model in shared config, then open OpenCode Desktop.',
|
|
23
|
+
openclaw: 'Set default model in OpenClaw and launch it.',
|
|
24
|
+
crush: 'Launch Crush with this provider/model pair.',
|
|
25
|
+
goose: 'Launch Goose and preselect the active model.',
|
|
26
|
+
pi: 'Launch Pi with model/provider flags.',
|
|
27
|
+
aider: 'Launch Aider configured on the selected model.',
|
|
28
|
+
qwen: 'Launch Qwen Code using the selected provider model.',
|
|
29
|
+
openhands: 'Launch OpenHands with the selected model endpoint.',
|
|
30
|
+
amp: 'Launch Amp with this model as active target.',
|
|
31
|
+
rovo: 'Rovo Dev CLI model (launch with Rovo tool only).',
|
|
32
|
+
gemini: 'Gemini CLI model (launch with Gemini tool only).',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const TOOL_MODE_COMMANDS = TOOL_MODE_ORDER.map((toolMode) => {
|
|
36
|
+
const meta = TOOL_METADATA[toolMode] || { label: toolMode, emoji: '🧰' }
|
|
37
|
+
return {
|
|
38
|
+
id: `action-set-tool-${toolMode}`,
|
|
39
|
+
label: `${meta.emoji} ${meta.label}`,
|
|
40
|
+
toolMode,
|
|
41
|
+
icon: meta.emoji,
|
|
42
|
+
description: TOOL_MODE_DESCRIPTIONS[toolMode] || 'Set this as the active launch target.',
|
|
43
|
+
keywords: ['tool', 'target', 'mode', toolMode, meta.label.toLowerCase()],
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const PING_MODE_COMMANDS = [
|
|
48
|
+
{
|
|
49
|
+
id: 'action-cycle-ping-mode',
|
|
50
|
+
label: 'Cycle ping mode',
|
|
51
|
+
shortcut: 'W',
|
|
52
|
+
icon: '⚡',
|
|
53
|
+
description: 'Rotate speed → normal → slow → forced.',
|
|
54
|
+
keywords: ['ping', 'mode', 'cycle', 'speed', 'normal', 'slow', 'forced'],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'action-set-ping-speed',
|
|
58
|
+
label: 'Speed mode (2s)',
|
|
59
|
+
pingMode: 'speed',
|
|
60
|
+
description: 'Fast 2s bursts for short live checks.',
|
|
61
|
+
keywords: ['ping', 'mode', 'speed', '2s', 'fast'],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'action-set-ping-normal',
|
|
65
|
+
label: 'Normal mode (10s)',
|
|
66
|
+
pingMode: 'normal',
|
|
67
|
+
description: 'Balanced default cadence for daily use.',
|
|
68
|
+
keywords: ['ping', 'mode', 'normal', '10s', 'default'],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'action-set-ping-slow',
|
|
72
|
+
label: 'Slow mode (30s)',
|
|
73
|
+
pingMode: 'slow',
|
|
74
|
+
description: 'Lower refresh cost when you are mostly idle.',
|
|
75
|
+
keywords: ['ping', 'mode', 'slow', '30s', 'idle'],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: 'action-set-ping-forced',
|
|
79
|
+
label: 'Forced mode (4s)',
|
|
80
|
+
pingMode: 'forced',
|
|
81
|
+
description: 'Keeps 4s cadence until manually changed.',
|
|
82
|
+
keywords: ['ping', 'mode', 'forced', '4s', 'manual'],
|
|
83
|
+
},
|
|
84
|
+
]
|
|
85
|
+
|
|
18
86
|
// 📖 Base command tree template (will be enhanced with dynamic model list)
|
|
19
87
|
const BASE_COMMAND_TREE = [
|
|
20
88
|
{
|
|
@@ -93,6 +161,41 @@ const BASE_COMMAND_TREE = [
|
|
|
93
161
|
{ id: 'sort-uptime', label: 'Sort by uptime', shortcut: 'U', description: 'Success rate', keywords: ['sort', 'uptime'] },
|
|
94
162
|
]
|
|
95
163
|
},
|
|
164
|
+
{
|
|
165
|
+
id: 'actions',
|
|
166
|
+
label: 'Actions',
|
|
167
|
+
icon: '⚙️',
|
|
168
|
+
children: [
|
|
169
|
+
{
|
|
170
|
+
id: 'action-target-tool',
|
|
171
|
+
label: 'Target tool',
|
|
172
|
+
icon: '🧰',
|
|
173
|
+
children: [
|
|
174
|
+
{ id: 'action-cycle-tool-mode', label: 'Cycle target tool', shortcut: 'Z', icon: '🔄', description: 'Rotate through every launcher mode.', keywords: ['tool', 'mode', 'cycle', 'target'] },
|
|
175
|
+
...TOOL_MODE_COMMANDS,
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: 'action-ping-mode',
|
|
180
|
+
label: 'Ping mode',
|
|
181
|
+
icon: '📶',
|
|
182
|
+
children: PING_MODE_COMMANDS,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: 'action-favorites-mode',
|
|
186
|
+
label: 'Favorites mode',
|
|
187
|
+
icon: '⭐',
|
|
188
|
+
children: [
|
|
189
|
+
{ id: 'action-toggle-favorite-mode', label: 'Toggle favorites mode', shortcut: 'Y', icon: '⭐', description: 'Switch pinned+sticky ↔ normal list behavior.', keywords: ['favorite', 'favorites', 'mode', 'toggle', 'y'] },
|
|
190
|
+
{ id: 'action-favorites-mode-pinned', label: 'Pinned + always visible', favoritesPinned: true, description: 'Favorites stay on top and bypass current filters.', keywords: ['favorite', 'favorites', 'pinned', 'sticky', 'always visible'] },
|
|
191
|
+
{ id: 'action-favorites-mode-normal', label: 'Normal rows (starred only)', favoritesPinned: false, description: 'Favorites keep ⭐ but follow active filters and sort.', keywords: ['favorite', 'favorites', 'normal', 'sort', 'filter'] },
|
|
192
|
+
{ id: 'action-toggle-favorite', label: 'Toggle favorite on selected row', shortcut: 'F', icon: '⭐', description: 'Star/unstar the highlighted model.', keywords: ['favorite', 'star', 'toggle'] },
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
{ id: 'action-cycle-theme', label: 'Cycle theme', shortcut: 'G', icon: '🌗', description: 'Switch dark/light/auto', keywords: ['theme', 'dark', 'light', 'auto'] },
|
|
196
|
+
{ id: 'action-reset-view', label: 'Reset view', shortcut: 'Shift+R', icon: '🔄', description: 'Reset filters and sort', keywords: ['reset', 'view', 'sort', 'filters'] },
|
|
197
|
+
],
|
|
198
|
+
},
|
|
96
199
|
// 📖 Pages - directly at root level, not in submenu
|
|
97
200
|
{ id: 'open-settings', label: 'Settings', shortcut: 'P', icon: '⚙️', type: 'page', description: 'API keys and preferences', keywords: ['settings', 'config', 'api key'] },
|
|
98
201
|
{ id: 'open-help', label: 'Help', shortcut: 'K', icon: '❓', type: 'page', description: 'Show all shortcuts', keywords: ['help', 'shortcuts', 'hotkeys'] },
|
|
@@ -100,12 +203,6 @@ const BASE_COMMAND_TREE = [
|
|
|
100
203
|
{ id: 'open-feedback', label: 'Feedback', shortcut: 'I', icon: '📝', type: 'page', description: 'Report bugs or requests', keywords: ['feedback', 'bug', 'request'] },
|
|
101
204
|
{ id: 'open-recommend', label: 'Smart recommend', shortcut: 'Q', icon: '🎯', type: 'page', description: 'Find best model for task', keywords: ['recommend', 'best model'] },
|
|
102
205
|
{ id: 'open-install-endpoints', label: 'Install endpoints', icon: '🔌', type: 'page', description: 'Install provider catalogs', keywords: ['install', 'endpoints', 'providers'] },
|
|
103
|
-
// 📖 Actions - directly at root level, not in submenu
|
|
104
|
-
{ id: 'action-cycle-theme', label: 'Cycle theme', shortcut: 'G', icon: '🌗', type: 'action', description: 'Switch dark/light/auto', keywords: ['theme', 'dark', 'light', 'auto'] },
|
|
105
|
-
{ id: 'action-cycle-tool-mode', label: 'Target Tool', shortcut: 'Z', icon: '🔄', type: 'action', description: 'Change target AI Coding CLI Tool.', keywords: ['tool', 'mode', 'launcher', 'target'] },
|
|
106
|
-
{ id: 'action-cycle-ping-mode', label: 'Cycle ping mode', shortcut: 'W', icon: '⚡', type: 'action', description: 'Adjust ping speed', keywords: ['ping', 'cadence', 'speed', 'slow'] },
|
|
107
|
-
{ id: 'action-toggle-favorite', label: 'Toggle favorite', shortcut: 'F', icon: '⭐', type: 'action', description: 'Pin to favorites', keywords: ['favorite', 'star'] },
|
|
108
|
-
{ id: 'action-reset-view', label: 'Reset view', shortcut: 'Shift+R', icon: '🔄', type: 'action', description: 'Reset filters and sort', keywords: ['reset', 'view', 'sort', 'filters'] },
|
|
109
206
|
]
|
|
110
207
|
|
|
111
208
|
/**
|