free-coding-models 0.5.25 → 0.5.26
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/README.md +9 -32
- package/changelog/v0.5.26.md +21 -0
- package/package.json +1 -1
- package/sources.js +3 -29
- package/src/core/benchmark.js +0 -10
- package/src/core/config.js +0 -1
- package/src/core/endpoint-installer.js +1 -2
- package/src/core/legacy-proxy-cleanup.js +2 -2
- package/src/core/provider-metadata.js +0 -17
- package/src/core/quota-capabilities.js +0 -1
- package/src/core/tool-bootstrap.js +0 -22
- package/src/core/tool-launchers.js +1 -89
- package/src/core/tool-metadata.js +6 -13
- package/src/core/utils.js +2 -6
- package/src/tui/app.js +0 -2
- package/src/tui/command-palette.js +0 -2
- package/src/tui/key-handler.js +6 -21
- package/src/tui/overlays.js +1 -1
- package/src/tui/theme.js +0 -4
- package/src/tui/tui-filters.js +1 -1
- package/web/dist/assets/{index-BaQs4odm.js → index-BDV-Qeuc.js} +3 -3
- package/web/dist/index.html +1 -1
- package/web/src/components/atoms/ProviderLogo.jsx +0 -1
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>Find the fastest free coding model in seconds</strong><br>
|
|
9
|
-
Track ~
|
|
9
|
+
Track ~146 models across 15 trusted free or free-limited AI providers in real time<br><br>
|
|
10
10
|
<strong>Install Free API endpoints to your favorite AI coding tools:</strong><br>
|
|
11
|
-
OpenCode CLI / Desktop / WebUI, OpenClaw, Crush, Goose, Aider, Kilo CLI, Qwen Code, OpenHands, Amp, Hermes, Continue, Cline, Xcode, Pi
|
|
11
|
+
OpenCode CLI / Desktop / WebUI, OpenClaw, Crush, Goose, Aider, Kilo CLI, Qwen Code, OpenHands, Amp, Hermes, Continue, Cline, Xcode, Pi and more...<br><br>
|
|
12
12
|
<strong>Use Kimi K2, DeepSeek V3, GPT-OSS, Qwen3, MiniMax M3, GLM, Llama 4, Gemma 4, Devstral and more — for free</strong>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
<img src="https://img.shields.io/npm/v/free-coding-models?color=3d6b00&label=npm&logo=npm" alt="npm version" width="200"><br>
|
|
17
17
|
<img src="https://img.shields.io/node/v/free-coding-models?color=3d6b00&logo=node.js" alt="node version" width="200"><br>
|
|
18
18
|
<img src="https://img.shields.io/npm/l/free-coding-models?color=3d6b00" alt="license" width="200"><br>
|
|
19
|
-
<img src="https://img.shields.io/badge/models-
|
|
20
|
-
<img src="https://img.shields.io/badge/providers-
|
|
19
|
+
<img src="https://img.shields.io/badge/models-146-3d6b00?logo=nvidia" alt="models count" width="200"><br>
|
|
20
|
+
<img src="https://img.shields.io/badge/providers-15-1a56db" alt="providers count" width="200">
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
23
|
```bash
|
|
@@ -91,12 +91,11 @@ Create a free account on one provider below to get started:
|
|
|
91
91
|
| 12 | [ZAI](https://z.ai) | 2 | S | Free Flash models only | `ZAI_API_KEY` |
|
|
92
92
|
| 13 | [Scaleway](https://console.scaleway.com/iam/api-keys) | 10 | S+ → B | 1M free tokens | `SCALEWAY_API_KEY` |
|
|
93
93
|
| 14 | [Alibaba DashScope](https://modelstudio.console.alibabacloud.com) | 11 | S+ → A+ | 1M free tokens/model, Singapore, 90 days | `DASHSCOPE_API_KEY` |
|
|
94
|
-
| 15 | [
|
|
95
|
-
| 16 | [OpenCode Zen](https://opencode.ai/zen) | 6 | S+ → A | Free with OpenCode account | Zen models ✨ |
|
|
94
|
+
| 15 | [OpenCode Zen](https://opencode.ai/zen) | 6 | S+ → A | Free with OpenCode account | Zen models ✨ |
|
|
96
95
|
|
|
97
96
|
> 💡 One key is enough. Add more at any time with **`P`** inside the TUI.
|
|
98
97
|
|
|
99
|
-
> 🧹 Audit cleanup: `iFlow` was removed because it shut down on April 17, 2026. `Together AI`, `Perplexity API`, `DeepInfra`, `Replicate`, `Fireworks`, `Hyperbolic`, `Hugging Face`, `SiliconFlow`, `Chutes AI
|
|
98
|
+
> 🧹 Audit cleanup: `iFlow` was removed because it shut down on April 17, 2026. `Together AI`, `Perplexity API`, `DeepInfra`, `Replicate`, `Fireworks`, `Hyperbolic`, `Hugging Face`, `SiliconFlow`, `Chutes AI` were removed from the active free catalog because they are paid, trial-credit only, too tiny to be useful, unclear as a stable free API, or tool-specific rather than a generally usable free provider. `Rovo` and `Gemini CLI` were also wiped out as tool integrations (CLI-only, not generally usable free providers).
|
|
100
99
|
|
|
101
100
|
---
|
|
102
101
|
|
|
@@ -425,8 +424,6 @@ Routing behavior:
|
|
|
425
424
|
| `--cline` | 🧠 Cline |
|
|
426
425
|
| `--xcode` | 🛠️ Xcode Intelligence |
|
|
427
426
|
| `--pi` | π Pi |
|
|
428
|
-
| `--rovo` | 🦘 Rovo Dev CLI |
|
|
429
|
-
| `--gemini` | ♊ Gemini CLI |
|
|
430
427
|
| `--copilot` | 🤖 Copilot CLI |
|
|
431
428
|
| `--forgecode` | 🔥 ForgeCode |
|
|
432
429
|
|
|
@@ -434,22 +431,6 @@ Press **`Z`** in the TUI to cycle between tools without restarting.
|
|
|
434
431
|
|
|
435
432
|
### CLI-Only Tools
|
|
436
433
|
|
|
437
|
-
**🦘 Rovo Dev CLI**
|
|
438
|
-
- Provider: [Atlassian Rovo](https://www.atlassian.com/rovo)
|
|
439
|
-
- Install: [Installation Guide](https://support.atlassian.com/rovo/docs/install-and-run-rovo-dev-cli-on-your-device/)
|
|
440
|
-
- Free tier: conditional Atlassian/Rovo allowance, not a general free API provider
|
|
441
|
-
- Catalog status: not included in the active free-provider table because access depends on Rovo availability for your account/site
|
|
442
|
-
- Launch: `free-coding-models --rovo` or press `Z` until Rovo mode
|
|
443
|
-
- Features: Jira/Confluence integration, MCP server support
|
|
444
|
-
|
|
445
|
-
**♊ Gemini CLI**
|
|
446
|
-
- Provider: [Google Gemini](https://github.com/google-gemini/gemini-cli)
|
|
447
|
-
- Install: `npm install -g @google/gemini-cli`
|
|
448
|
-
- Free tier: 1,000 requests/day (personal Google account, no credit card)
|
|
449
|
-
- Models: Gemini 3.1 Pro Preview, Gemini 3 Flash Preview, Gemini 2.5 Pro, Gemini 2.5 Flash
|
|
450
|
-
- Launch: `free-coding-models --gemini` or press `Z` until Gemini mode
|
|
451
|
-
- Features: OpenAI-compatible API support, MCP server support, Google Search grounding
|
|
452
|
-
|
|
453
434
|
**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.
|
|
454
435
|
|
|
455
436
|
### OpenCode Zen Free Models
|
|
@@ -472,10 +453,8 @@ When a tool mode is active (via `Z`), models incompatible with that tool are hig
|
|
|
472
453
|
|
|
473
454
|
| Model Type | Compatible Tools |
|
|
474
455
|
|------------|-----------------|
|
|
475
|
-
| Regular (NVIDIA, Groq, etc.) | All tools
|
|
476
|
-
|
|
|
477
|
-
| Gemini | ♊ Gemini CLI only |
|
|
478
|
-
| OpenCode Zen | 📦 OpenCode CLI and 📦 OpenCode Desktop only |
|
|
456
|
+
| Regular (NVIDIA, Groq, etc.) | All tools |
|
|
457
|
+
| OpenCode Zen | All tools (OpenAI-compatible endpoint) |
|
|
479
458
|
|
|
480
459
|
→ **[Full flags reference](./docs/flags.md)**
|
|
481
460
|
|
|
@@ -534,7 +513,7 @@ When a tool mode is active (via `Z`), models incompatible with that tool are hig
|
|
|
534
513
|
|
|
535
514
|
## ✨ Features
|
|
536
515
|
|
|
537
|
-
- **Parallel pings** — all ~
|
|
516
|
+
- **Parallel pings** — all ~150 API/Zen-callable models tested simultaneously via native `fetch` (~152 total cataloged models)
|
|
538
517
|
- **AI benchmark columns** — `Ctrl+A` benchmarks the selected model, `Ctrl+U` benchmarks visible models, and results split cleanly into **AI Latency** plus **TPS**. Settings includes an opt-in **Startup AI Speed Scan** toggle to run the global benchmark automatically after launch.
|
|
539
518
|
- **Tiny verdict indicator** — the first `❔` column mirrors the full Verdict as a compact emoji (`🟩`, `🟢`, `🟡`, `🟠`, etc.) and sorts by the same verdict order.
|
|
540
519
|
- **Adaptive monitoring** — 2s burst for 60s → 10s normal → 30s idle
|
|
@@ -724,8 +703,6 @@ Telemetry is enabled by default and can be disabled with any of the following:
|
|
|
724
703
|
| IDE | Free tier | Credit card |
|
|
725
704
|
|-----|-----------|-------------|
|
|
726
705
|
| [Qwen Code](https://github.com/QwenLM/qwen-code) | 2,000 requests/day | No |
|
|
727
|
-
| [Rovo Dev CLI](https://www.atlassian.com/rovo) | Conditional Atlassian/Rovo allowance | No |
|
|
728
|
-
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | 1,000 requests/day | No |
|
|
729
706
|
| [Jules](https://jules.google/) | 15 tasks/day | No |
|
|
730
707
|
| [AWS Kiro](https://kiro.dev/) | 50 credits/month | No |
|
|
731
708
|
| [Trae](https://trae.ai/) | 10 fast + 50 slow requests/month | No |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog v0.5.26 - 2026-06-11
|
|
2
|
+
|
|
3
|
+
### Removed
|
|
4
|
+
- **Gemini CLI** wiped out as a tool integration across the entire stack (TUI cycle `Z`, command palette, theme, key handler, provider metadata, tool bootstrap, tool launchers, benchmark, endpoint installer, audit state, docker-compose, docs)
|
|
5
|
+
- **Rovo Dev CLI** wiped out the same way — block removed from `tool-metadata.js`, `tool-bootstrap.js`, `provider-metadata.js`, `tool-launchers.js` (incl. `writeRovoConfig`), `benchmark.js`, `endpoint-installer.js`, `utils.js`, `command-palette.js`, `theme.js`, `key-handler.js`, `app.js`, plus the `--rovo` CLI flag
|
|
6
|
+
- Both removed from the website's social proof bar (`Gemini CLI` and `Rovo Dev` chips)
|
|
7
|
+
- `cliOnly` tool concept collapsed — no remaining CLI-only providers, so `getCompatibleTools` simplified to return `REGULAR_TOOLS` for both `regular` and `opencode-zen`
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- `sources.js` JSDoc `@exports` no longer lists the stale `gemini` provider
|
|
11
|
+
- `audit_state.json` clone entry `gemini` removed (was a fingerprint duplicate of `googleai`)
|
|
12
|
+
- `.pi/skills/update_models/SKILL.md`: `googleai` audit diff now applies directly to `sources.js` (no more `gemini` clone)
|
|
13
|
+
- `docker-compose.yml`: dead `GEMINI_API_KEY` env var removed (not referenced anywhere in code)
|
|
14
|
+
- `README.md`: tool list, compatibility table, IDE table, model count all updated
|
|
15
|
+
- `tui/overlays.js` `Z` cycle help: `🦘 Rovo → ♊ Gemini` segment dropped
|
|
16
|
+
|
|
17
|
+
### Tests
|
|
18
|
+
- `tool compatibility matrix` test suite updated: removed 5 rovo/gemini-specific assertions, kept Zen compatibility coverage
|
|
19
|
+
- `sortResultsWithPinnedFavorites` mock data swapped from `rovo` fixtures to `caveman` fixtures (caveman is also cliOnly-equivalent for sort order testing)
|
|
20
|
+
- `benchmarkModel` no longer has a `providerKey === 'rovo'` UNSUPPORTED guard test (guard itself was removed with the wipeout)
|
|
21
|
+
- 520/520 tests pass after refactor
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.26",
|
|
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
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* 📖 Secondary: https://swe-rebench.com (independent evals, scores are lower)
|
|
30
30
|
* 📖 Leaderboard tracker: https://www.marc0.dev/en/leaderboard
|
|
31
31
|
*
|
|
32
|
-
* @exports nvidiaNim, groq, cerebras, sambanova, openrouter, githubModels, mistral, codestral, scaleway, googleai, zai, qwen, cloudflare, ovhcloud,
|
|
32
|
+
* @exports nvidiaNim, groq, cerebras, sambanova, openrouter, githubModels, mistral, codestral, scaleway, googleai, zai, qwen, cloudflare, ovhcloud, opencodeZen — model arrays per active provider
|
|
33
33
|
* @exports sources — map of active free/free-limited providers, each with { name, url, models }
|
|
34
34
|
|
|
35
35
|
* @exports MODELS — flat array of [modelId, label, tier, sweScore, ctx, providerKey]
|
|
@@ -339,25 +339,7 @@ export const ovhcloud = [
|
|
|
339
339
|
// 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
|
|
340
340
|
]
|
|
341
341
|
|
|
342
|
-
|
|
343
|
-
// 📖 CLI tool with OpenAI-compatible API support
|
|
344
|
-
// 📖 Install: npm install -g @google/gemini-cli
|
|
345
|
-
// 📖 Free tier: 1,000 req/day with personal Google account (no credit card)
|
|
346
|
-
// 📖 Models track Google AI Studio IDs; no stale google/ prefix.
|
|
347
|
-
// 📖 Supports custom OpenAI-compatible providers via GEMINI_API_BASE_URL
|
|
348
|
-
export const gemini = [
|
|
349
|
-
['gemini-3.5-flash', 'Gemini 3.5 Flash', 'S+', '-', '1M'],
|
|
350
|
-
['gemini-3.1-pro-preview', 'Gemini 3.1 Pro Preview', 'S+', '78.0%', '1M'],
|
|
351
|
-
['gemini-3-flash-preview', 'Gemini 3 Flash Preview', 'S', '65.0%', '1M'],
|
|
352
|
-
['gemini-3.1-flash-lite', 'Gemini 3.1 Flash Lite', 'A+', '55.0%', '1M'],
|
|
353
|
-
// ⚠️ DEPRECATED — shutdown Oct 16, 2026
|
|
354
|
-
['gemini-2.5-pro', 'Gemini 2.5 Pro', 'S+', '63.2%', '1M'],
|
|
355
|
-
// ⚠️ DEPRECATED — shutdown Oct 16, 2026
|
|
356
|
-
['gemini-2.5-flash', 'Gemini 2.5 Flash', 'A+', '50.0%', '1M'],
|
|
357
|
-
// ⚠️ DEPRECATED — shutdown Oct 16, 2026
|
|
358
|
-
['gemini-2.5-flash-lite', 'Gemini 2.5 Flash Lite', 'A', '42.0%', '1M'],
|
|
359
|
-
// Removed (2026-05-26): gemini-3.1-flash-lite-preview (endpoint shutdown May 25, 2026)
|
|
360
|
-
]
|
|
342
|
+
|
|
361
343
|
|
|
362
344
|
// 📖 OpenCode Zen free models — hosted AI gateway accessed through OpenCode CLI/Desktop
|
|
363
345
|
// 📖 Endpoint: https://opencode.ai/zen/v1/... — requires OpenCode Zen API key
|
|
@@ -456,15 +438,7 @@ export const sources = {
|
|
|
456
438
|
url: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions',
|
|
457
439
|
models: qwen,
|
|
458
440
|
},
|
|
459
|
-
|
|
460
|
-
name: 'Gemini CLI',
|
|
461
|
-
url: null, // CLI tool - no API endpoint (can use OpenAI-compatible via env)
|
|
462
|
-
models: gemini,
|
|
463
|
-
cliOnly: true,
|
|
464
|
-
installUrl: 'https://github.com/google-gemini/gemini-cli',
|
|
465
|
-
binary: 'gemini',
|
|
466
|
-
checkArgs: ['--version'],
|
|
467
|
-
},
|
|
441
|
+
|
|
468
442
|
'opencode-zen': {
|
|
469
443
|
name: 'OpenCode Zen',
|
|
470
444
|
url: 'https://opencode.ai/zen/v1/chat/completions',
|
package/src/core/benchmark.js
CHANGED
|
@@ -257,16 +257,6 @@ async function benchmarkSingleAttempt({ apiKey, modelId, providerKey, url, timeo
|
|
|
257
257
|
// 📖 Returns on failure (all attempts exhausted):
|
|
258
258
|
// 📖 { ok: false, code, totalMs, error, retries }
|
|
259
259
|
export async function benchmarkModel({ apiKey, modelId, providerKey, url, timeoutMs = BENCHMARK_TIMEOUT_MS, maxRetries = BENCHMARK_MAX_RETRIES, retryDelayMs = BENCHMARK_RETRY_DELAY_MS }) {
|
|
260
|
-
// 📖 Guard: unsupported providers that don't do chat completions
|
|
261
|
-
if (providerKey === 'rovo' || providerKey === 'gemini' || providerKey === 'opencode-zen') {
|
|
262
|
-
return {
|
|
263
|
-
ok: false,
|
|
264
|
-
code: 'UNSUPPORTED',
|
|
265
|
-
totalMs: 0,
|
|
266
|
-
error: 'Provider does not support chat completions',
|
|
267
|
-
retries: 0,
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
260
|
|
|
271
261
|
let lastResult = null
|
|
272
262
|
|
package/src/core/config.js
CHANGED
|
@@ -132,7 +132,6 @@ const ENV_VARS = {
|
|
|
132
132
|
cloudflare: ['CLOUDFLARE_API_TOKEN', 'CLOUDFLARE_API_KEY'],
|
|
133
133
|
qwen: 'DASHSCOPE_API_KEY',
|
|
134
134
|
zai: 'ZAI_API_KEY',
|
|
135
|
-
gemini: 'GEMINI_API_KEY',
|
|
136
135
|
ovhcloud: 'OVH_AI_ENDPOINTS_ACCESS_TOKEN',
|
|
137
136
|
'opencode-zen': 'OPENCODE_ZEN_API_KEY',
|
|
138
137
|
}
|
|
@@ -48,10 +48,9 @@ import { getApiKey, saveConfig } from './config.js'
|
|
|
48
48
|
import { ENV_VAR_NAMES, PROVIDER_METADATA } from './provider-metadata.js'
|
|
49
49
|
import { getToolMeta } from './tool-metadata.js'
|
|
50
50
|
|
|
51
|
-
// 📖 CLI-only providers (rovo, gemini) cannot be installed into other tools — they manage their own auth.
|
|
52
51
|
// 📖 replicate uses /v1/predictions (not /chat/completions), so it's not OpenAI-compatible.
|
|
53
52
|
// 📖 zai and opencode-zen ARE OpenAI-compatible and CAN be installed into any tool.
|
|
54
|
-
const DIRECT_INSTALL_UNSUPPORTED_PROVIDERS = new Set(['replicate'
|
|
53
|
+
const DIRECT_INSTALL_UNSUPPORTED_PROVIDERS = new Set(['replicate'])
|
|
55
54
|
// 📖 Install Endpoints only lists tools whose persisted config shape is actually supported here.
|
|
56
55
|
// 📖 Launch-only tools stay out: the Web dashboard configures endpoints, it never starts CLIs.
|
|
57
56
|
const INSTALL_TARGET_MODES = ['opencode', 'opencode-desktop', 'opencode-web', 'openclaw', 'crush', 'goose', 'pi', 'aider', 'qwen', 'openhands', 'amp', 'forgecode', 'fcm_router']
|
|
@@ -27,9 +27,9 @@ import { existsSync, readFileSync, writeFileSync, unlinkSync, readdirSync } from
|
|
|
27
27
|
import { homedir } from 'node:os'
|
|
28
28
|
import { join } from 'node:path'
|
|
29
29
|
|
|
30
|
-
const LEGACY_TOOL_MODES = new Set(['claude-code', 'codex'
|
|
30
|
+
const LEGACY_TOOL_MODES = new Set(['claude-code', 'codex'])
|
|
31
31
|
const LEGACY_RUNTIME_FILES = ['daemon.json', 'daemon-stdout.log', 'daemon-stderr.log', 'request-log.jsonl']
|
|
32
|
-
const LEGACY_ENV_FILES = ['.fcm-claude-code-env', '.fcm-codex-env'
|
|
32
|
+
const LEGACY_ENV_FILES = ['.fcm-claude-code-env', '.fcm-codex-env']
|
|
33
33
|
|
|
34
34
|
function getDefaultPaths(homeDir) {
|
|
35
35
|
return {
|
|
@@ -52,7 +52,6 @@ export const ENV_VAR_NAMES = {
|
|
|
52
52
|
googleai: 'GOOGLE_API_KEY',
|
|
53
53
|
cloudflare: 'CLOUDFLARE_API_TOKEN',
|
|
54
54
|
zai: 'ZAI_API_KEY',
|
|
55
|
-
gemini: 'GEMINI_API_KEY',
|
|
56
55
|
ovhcloud: 'OVH_AI_ENDPOINTS_ACCESS_TOKEN',
|
|
57
56
|
qwen: 'DASHSCOPE_API_KEY',
|
|
58
57
|
'opencode-zen': 'OPENCODE_ZEN_API_KEY',
|
|
@@ -236,22 +235,6 @@ export const PROVIDER_METADATA = {
|
|
|
236
235
|
signupHint: 'Install @mariozechner/pi-coding-agent and set ANTHROPIC_API_KEY',
|
|
237
236
|
rateLimits: 'Depends on provider subscription (e.g., Anthropic, OpenAI)',
|
|
238
237
|
},
|
|
239
|
-
rovo: {
|
|
240
|
-
label: 'Rovo Dev CLI',
|
|
241
|
-
color: chalk.rgb(148, 163, 184), // slate blue
|
|
242
|
-
signupUrl: 'https://www.atlassian.com/rovo',
|
|
243
|
-
signupHint: 'Install ACLI and run: acli rovodev auth login',
|
|
244
|
-
rateLimits: 'Free tier: 5M tokens/day (beta, requires Atlassian account)',
|
|
245
|
-
cliOnly: true,
|
|
246
|
-
},
|
|
247
|
-
gemini: {
|
|
248
|
-
label: 'Gemini CLI',
|
|
249
|
-
color: chalk.rgb(66, 165, 245), // blue
|
|
250
|
-
signupUrl: 'https://github.com/google-gemini/gemini-cli',
|
|
251
|
-
signupHint: 'Install: npm install -g @google/gemini-cli',
|
|
252
|
-
rateLimits: 'Free tier: 1,000 req/day with personal Google account',
|
|
253
|
-
cliOnly: true,
|
|
254
|
-
},
|
|
255
238
|
'opencode-zen': {
|
|
256
239
|
label: 'OpenCode Zen',
|
|
257
240
|
color: chalk.rgb(139, 92, 246), // violet — distinctive from other providers
|
|
@@ -53,7 +53,6 @@ export const PROVIDER_CAPABILITIES = {
|
|
|
53
53
|
// Providers with no reliable quota signal
|
|
54
54
|
cloudflare: { telemetryType: 'unknown', supportsEndpoint: false, usageDisplay: 'ok', resetCadence: 'daily' },
|
|
55
55
|
zai: { telemetryType: 'unknown', supportsEndpoint: false, usageDisplay: 'ok', resetCadence: 'none' },
|
|
56
|
-
gemini: { telemetryType: 'unknown', supportsEndpoint: false, usageDisplay: 'ok', resetCadence: 'daily' },
|
|
57
56
|
'opencode-zen': { telemetryType: 'unknown', supportsEndpoint: false, usageDisplay: 'ok', resetCadence: 'unknown' },
|
|
58
57
|
}
|
|
59
58
|
|
|
@@ -227,17 +227,6 @@ export const TOOL_BOOTSTRAP_METADATA = {
|
|
|
227
227
|
},
|
|
228
228
|
},
|
|
229
229
|
},
|
|
230
|
-
rovo: {
|
|
231
|
-
binary: 'acli',
|
|
232
|
-
docsUrl: 'https://support.atlassian.com/rovo/docs/install-and-run-rovo-dev-cli-on-your-device/',
|
|
233
|
-
install: {
|
|
234
|
-
default: {
|
|
235
|
-
shellCommand: 'npm install -g acli',
|
|
236
|
-
summary: 'Rovo Dev CLI requires ACLI installation. Visit the documentation for platform-specific instructions.',
|
|
237
|
-
note: 'Rovo is an Atlassian tool that requires an Atlassian account with Rovo Dev activated.',
|
|
238
|
-
},
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
230
|
'continue': {
|
|
242
231
|
binary: 'cn',
|
|
243
232
|
docsUrl: 'https://docs.continue.dev/cli/overview',
|
|
@@ -279,17 +268,6 @@ export const TOOL_BOOTSTRAP_METADATA = {
|
|
|
279
268
|
win32: 'Hermes Agent does not support native Windows. Use WSL2 instead.',
|
|
280
269
|
},
|
|
281
270
|
},
|
|
282
|
-
gemini: {
|
|
283
|
-
binary: 'gemini',
|
|
284
|
-
docsUrl: 'https://github.com/google-gemini/gemini-cli',
|
|
285
|
-
install: {
|
|
286
|
-
default: {
|
|
287
|
-
shellCommand: 'npm install -g @google/gemini-cli',
|
|
288
|
-
summary: 'Install Gemini CLI globally via npm.',
|
|
289
|
-
note: 'After installation, run `gemini` to authenticate with your Google account.',
|
|
290
|
-
},
|
|
291
|
-
},
|
|
292
|
-
},
|
|
293
271
|
caveman: {
|
|
294
272
|
binary: 'caveman',
|
|
295
273
|
docsUrl: 'https://github.com/JuliusBrussee/caveman-code',
|
|
@@ -427,29 +427,6 @@ function writeOpenHandsEnv(model, apiKey, baseUrl, paths = getDefaultToolPaths()
|
|
|
427
427
|
return { filePath, backupPath }
|
|
428
428
|
}
|
|
429
429
|
|
|
430
|
-
/**
|
|
431
|
-
* 📖 writeRovoConfig - Configure Rovo Dev CLI model selection
|
|
432
|
-
*
|
|
433
|
-
* Rovo Dev CLI uses ~/.rovodev/config.yml for configuration.
|
|
434
|
-
* We write the model ID to the config file before launching.
|
|
435
|
-
*
|
|
436
|
-
* @param {Object} model - Selected model with modelId
|
|
437
|
-
* @param {string} configPath - Path to Rovo config file
|
|
438
|
-
* @returns {{ filePath: string, backupPath: string | null }}
|
|
439
|
-
*/
|
|
440
|
-
function writeRovoConfig(model, configPath = join(homedir(), '.rovodev', 'config.yml')) {
|
|
441
|
-
const backupPath = backupIfExists(configPath)
|
|
442
|
-
const config = {
|
|
443
|
-
agent: {
|
|
444
|
-
modelId: model.modelId,
|
|
445
|
-
},
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
ensureDir(configPath)
|
|
449
|
-
writeFileSync(configPath, `agent:\n modelId: "${model.modelId}"\n`)
|
|
450
|
-
return { filePath: configPath, backupPath }
|
|
451
|
-
}
|
|
452
|
-
|
|
453
430
|
// 📖 writeContinueConfig — write ~/.continue/config.yaml with the selected model.
|
|
454
431
|
// 📖 Continue CLI uses YAML config with `provider: openai` for OpenAI-compatible endpoints.
|
|
455
432
|
function writeContinueConfig(model, apiKey, baseUrl, paths = getDefaultToolPaths()) {
|
|
@@ -606,33 +583,6 @@ function restartHermesGateway() {
|
|
|
606
583
|
spawnSync(hermesBin, ['gateway', 'restart'], { stdio: 'ignore', timeout: 10000 })
|
|
607
584
|
}
|
|
608
585
|
|
|
609
|
-
/**
|
|
610
|
-
* 📖 buildGeminiEnv - Build environment variables for Gemini CLI
|
|
611
|
-
*
|
|
612
|
-
* Gemini CLI supports OpenAI-compatible APIs via environment variables:
|
|
613
|
-
* - GEMINI_API_BASE_URL: Custom API endpoint
|
|
614
|
-
* - GEMINI_API_KEY: API key for custom endpoint
|
|
615
|
-
*
|
|
616
|
-
* @param {Object} model - Selected model with providerKey
|
|
617
|
-
* @param {Object} config - Full app config
|
|
618
|
-
* @param {Object} options - Env options
|
|
619
|
-
* @returns {NodeJS.ProcessEnv}
|
|
620
|
-
*/
|
|
621
|
-
function buildGeminiEnv(model, config, options = {}) {
|
|
622
|
-
const providerKey = model.providerKey || 'gemini'
|
|
623
|
-
const apiKey = getApiKey(config, providerKey)
|
|
624
|
-
const baseUrl = getProviderBaseUrl(providerKey)
|
|
625
|
-
|
|
626
|
-
const env = cloneInheritedEnv(process.env, SANITIZED_TOOL_ENV_KEYS)
|
|
627
|
-
|
|
628
|
-
// If we have a custom API key and base URL, configure OpenAI-compatible mode
|
|
629
|
-
if (apiKey && baseUrl && options.includeProviderEnv) {
|
|
630
|
-
env.GEMINI_API_BASE_URL = baseUrl
|
|
631
|
-
env.GEMINI_API_KEY = apiKey
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
return env
|
|
635
|
-
}
|
|
636
586
|
|
|
637
587
|
/**
|
|
638
588
|
* 📖 buildCavemanEnv - Build environment variables for Caveman Code
|
|
@@ -643,7 +593,7 @@ function buildGeminiEnv(model, config, options = {}) {
|
|
|
643
593
|
*
|
|
644
594
|
* Supported env vars (from caveman-code source):
|
|
645
595
|
* - ANTHROPIC_API_KEY, OPENAI_API_KEY, GROQ_API_KEY, CEREBRAS_API_KEY
|
|
646
|
-
* - MISTRAL_API_KEY, GOOGLE_API_KEY,
|
|
596
|
+
* - MISTRAL_API_KEY, GOOGLE_API_KEY, etc.
|
|
647
597
|
*
|
|
648
598
|
* @param {Object} model - Selected model with providerKey
|
|
649
599
|
* @param {Object} config - Full app config
|
|
@@ -894,34 +844,6 @@ export function prepareExternalToolLaunch(mode, model, config, options = {}) {
|
|
|
894
844
|
}
|
|
895
845
|
}
|
|
896
846
|
|
|
897
|
-
if (mode === 'rovo') {
|
|
898
|
-
const result = writeRovoConfig(model, join(homedir(), '.rovodev', 'config.yml'), paths)
|
|
899
|
-
console.log(chalk.dim(` 📖 Rovo Dev CLI configured with model: ${model.modelId}`))
|
|
900
|
-
return {
|
|
901
|
-
command: 'acli',
|
|
902
|
-
args: ['rovodev', 'run'],
|
|
903
|
-
env,
|
|
904
|
-
apiKey: null,
|
|
905
|
-
baseUrl: null,
|
|
906
|
-
meta,
|
|
907
|
-
configArtifacts: [{ path: result.filePath, backupPath: result.backupPath, label: 'config' }],
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
if (mode === 'gemini') {
|
|
912
|
-
const geminiEnv = buildGeminiEnv(model, config, { includeProviderEnv: options.includeProviderEnv })
|
|
913
|
-
console.log(chalk.dim(` 📖 Gemini CLI will use model: ${model.modelId}`))
|
|
914
|
-
return {
|
|
915
|
-
command: 'gemini',
|
|
916
|
-
args: [],
|
|
917
|
-
env: { ...env, ...geminiEnv },
|
|
918
|
-
apiKey: geminiEnv.GEMINI_API_KEY || null,
|
|
919
|
-
baseUrl: geminiEnv.GEMINI_API_BASE_URL || null,
|
|
920
|
-
meta,
|
|
921
|
-
configArtifacts: [],
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
|
|
925
847
|
if (mode === 'caveman') {
|
|
926
848
|
const cavemanEnv = buildCavemanEnv(model, config, { includeProviderEnv: options.includeProviderEnv })
|
|
927
849
|
console.log(chalk.dim(` 📖 Caveman Code will use model: ${model.modelId}`))
|
|
@@ -1108,16 +1030,6 @@ export async function startExternalTool(mode, model, config) {
|
|
|
1108
1030
|
return spawnCommand(launchPlan.command, launchPlan.args, launchPlan.env)
|
|
1109
1031
|
}
|
|
1110
1032
|
|
|
1111
|
-
if (mode === 'rovo') {
|
|
1112
|
-
console.log(chalk.dim(` 📖 Launching Rovo Dev CLI in interactive mode...`))
|
|
1113
|
-
return spawnCommand(resolveLaunchCommand(mode, launchPlan.command), launchPlan.args, launchPlan.env)
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
if (mode === 'gemini') {
|
|
1117
|
-
console.log(chalk.dim(` 📖 Launching Gemini CLI...`))
|
|
1118
|
-
return spawnCommand(resolveLaunchCommand(mode, launchPlan.command), launchPlan.args, launchPlan.env)
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
1033
|
if (mode === 'caveman') {
|
|
1122
1034
|
console.log(chalk.dim(` 📖 Launching Caveman Code...`))
|
|
1123
1035
|
return spawnCommand(resolveLaunchCommand(mode, launchPlan.command), launchPlan.args, launchPlan.env)
|
|
@@ -41,8 +41,7 @@ export const TOOL_METADATA = {
|
|
|
41
41
|
hermes: { label: 'Hermes', emoji: '🔮', flag: '--hermes', color: [200, 160, 255] },
|
|
42
42
|
'continue': { label: 'Continue CLI', emoji: '▶️', flag: '--continue', color: [255, 100, 100] },
|
|
43
43
|
cline: { label: 'Cline', emoji: '🧠', flag: '--cline', color: [100, 220, 180] },
|
|
44
|
-
|
|
45
|
-
gemini: { label: 'Gemini CLI', emoji: '♊', flag: '--gemini', color: [66, 165, 245], cliOnly: true },
|
|
44
|
+
|
|
46
45
|
caveman: { label: 'Caveman Code', emoji: '🪨', flag: '--caveman', color: [180, 130, 80] },
|
|
47
46
|
jcode: { label: 'jcode', emoji: '🪼', flag: '--jcode', color: [255, 140, 0] },
|
|
48
47
|
xcode: { label: 'Xcode Intelligence',emoji: '🛠️', flag: '--xcode', color: [20, 126, 251] },
|
|
@@ -69,8 +68,7 @@ export const COMPAT_COLUMN_SLOTS = [
|
|
|
69
68
|
{ emoji: '▶️', toolKeys: ['continue'], color: [255, 100, 100] },
|
|
70
69
|
{ emoji: '🧠', toolKeys: ['cline'], color: [100, 220, 180] },
|
|
71
70
|
{ emoji: '🧭', toolKeys: ['fcm_router'], color: [80, 200, 120] },
|
|
72
|
-
|
|
73
|
-
{ emoji: '♊', toolKeys: ['gemini'], color: [66, 165, 245] },
|
|
71
|
+
|
|
74
72
|
{ emoji: '🪨', toolKeys: ['caveman'], color: [180, 130, 80] },
|
|
75
73
|
{ emoji: '🪼', toolKeys: ['jcode'], color: [255, 140, 0] },
|
|
76
74
|
{ emoji: '🛠️', toolKeys: ['xcode'], color: [20, 126, 251] },
|
|
@@ -97,8 +95,7 @@ export const TOOL_MODE_ORDER = [
|
|
|
97
95
|
'cline',
|
|
98
96
|
'xcode',
|
|
99
97
|
'fcm_router',
|
|
100
|
-
|
|
101
|
-
'gemini',
|
|
98
|
+
|
|
102
99
|
'caveman',
|
|
103
100
|
'copilot',
|
|
104
101
|
'forgecode',
|
|
@@ -112,27 +109,23 @@ export function getToolModeOrder() {
|
|
|
112
109
|
return [...TOOL_MODE_ORDER]
|
|
113
110
|
}
|
|
114
111
|
|
|
115
|
-
// 📖 Regular tools: all tools EXCEPT
|
|
112
|
+
// 📖 Regular tools: all tools EXCEPT cliOnly ones (which have exclusive models).
|
|
116
113
|
// 📖 Used as the default compatible set for normal provider models.
|
|
117
114
|
const REGULAR_TOOLS = Object.keys(TOOL_METADATA).filter(k => !TOOL_METADATA[k].cliOnly)
|
|
118
115
|
|
|
119
116
|
// 📖 Zen models use OpenAI-compatible endpoints (https://opencode.ai/zen/v1/chat/completions)
|
|
120
117
|
// 📖 and can be used by ANY tool that supports custom OpenAI-compatible providers.
|
|
121
118
|
// 📖 They are NOT locked to OpenCode — confirmed by OpenCode's own "no lock-in" design goal.
|
|
122
|
-
// 📖 Only CLI-only tools
|
|
119
|
+
// 📖 Only CLI-only tools are excluded since they have their own exclusive models.
|
|
123
120
|
|
|
124
121
|
/**
|
|
125
122
|
* 📖 Returns the list of tool keys a model is compatible with.
|
|
126
|
-
* - Rovo models → only 'rovo'
|
|
127
|
-
* - Gemini models → only 'gemini'
|
|
128
123
|
* - OpenCode Zen models → all non-cliOnly tools (Zen uses OpenAI-compatible endpoints)
|
|
129
124
|
* - Regular models → all non-cliOnly tools
|
|
130
|
-
* @param {string} providerKey — the source key from sources.js (e.g. 'nvidia', '
|
|
125
|
+
* @param {string} providerKey — the source key from sources.js (e.g. 'nvidia', 'opencode-zen')
|
|
131
126
|
* @returns {string[]} — array of compatible tool keys
|
|
132
127
|
*/
|
|
133
128
|
export function getCompatibleTools(providerKey) {
|
|
134
|
-
if (providerKey === 'rovo') return ['rovo']
|
|
135
|
-
if (providerKey === 'gemini') return ['gemini']
|
|
136
129
|
// 📖 Zen models use /v1/chat/completions — compatible with any OpenAI-compatible tool
|
|
137
130
|
if (providerKey === 'opencode-zen') return REGULAR_TOOLS
|
|
138
131
|
return REGULAR_TOOLS
|
package/src/core/utils.js
CHANGED
|
@@ -520,8 +520,8 @@ export function findBestModel(results) {
|
|
|
520
520
|
// - API key: first positional arg that does not look like a CLI flag (e.g., "nvapi-xxx")
|
|
521
521
|
// - Boolean flags: --best, --fiable, --opencode, --opencode-desktop, --opencode-web, --openclaw,
|
|
522
522
|
// --aider, --crush, --goose, --qwen, --kilo,
|
|
523
|
-
// --openhands, --amp, --pi, --
|
|
524
|
-
// --xcode, --
|
|
523
|
+
// --openhands, --amp, --pi, --hermes, --continue, --cline,
|
|
524
|
+
// --xcode, --jcode, --copilot, --forgecode,
|
|
525
525
|
// --daemon, --daemon-bg, --daemon-stop,
|
|
526
526
|
// --daemon-status, --no-telemetry, --json, --help/-h (case-insensitive)
|
|
527
527
|
// --playground / playground subcommand (open the in-TUI chat playground)
|
|
@@ -600,12 +600,10 @@ export function parseArgs(argv) {
|
|
|
600
600
|
const openHandsMode = flags.includes('--openhands')
|
|
601
601
|
const ampMode = flags.includes('--amp')
|
|
602
602
|
const piMode = flags.includes('--pi')
|
|
603
|
-
const rovoMode = flags.includes('--rovo')
|
|
604
603
|
const hermesMode = flags.includes('--hermes')
|
|
605
604
|
const continueMode = flags.includes('--continue')
|
|
606
605
|
const clineMode = flags.includes('--cline')
|
|
607
606
|
const xcodeMode = flags.includes('--xcode')
|
|
608
|
-
const geminiMode = flags.includes('--gemini')
|
|
609
607
|
const cavemanMode = flags.includes('--caveman')
|
|
610
608
|
const jcodeMode = flags.includes('--jcode')
|
|
611
609
|
const copilotMode = flags.includes('--copilot')
|
|
@@ -669,8 +667,6 @@ export function parseArgs(argv) {
|
|
|
669
667
|
continueMode,
|
|
670
668
|
clineMode,
|
|
671
669
|
xcodeMode,
|
|
672
|
-
rovoMode,
|
|
673
|
-
geminiMode,
|
|
674
670
|
cavemanMode,
|
|
675
671
|
jcodeMode,
|
|
676
672
|
copilotMode,
|
package/src/tui/app.js
CHANGED
|
@@ -249,8 +249,6 @@ export async function runApp(cliArgs, config, startupOptions = {}) {
|
|
|
249
249
|
cline: cliArgs.clineMode,
|
|
250
250
|
xcode: cliArgs.xcodeMode,
|
|
251
251
|
pi: cliArgs.piMode,
|
|
252
|
-
rovo: cliArgs.rovoMode,
|
|
253
|
-
gemini: cliArgs.geminiMode,
|
|
254
252
|
caveman: cliArgs.cavemanMode,
|
|
255
253
|
copilot: cliArgs.copilotMode,
|
|
256
254
|
forgecode: cliArgs.forgecodeMode,
|
|
@@ -45,8 +45,6 @@ const TOOL_MODE_DESCRIPTIONS = {
|
|
|
45
45
|
hermes: 'Launch Hermes Agent with the selected model.',
|
|
46
46
|
'continue': 'Launch Continue CLI with the selected model.',
|
|
47
47
|
cline: 'Launch Cline CLI with the selected model.',
|
|
48
|
-
rovo: 'Rovo Dev CLI model (launch with Rovo tool only).',
|
|
49
|
-
gemini: 'Gemini CLI model (launch with Gemini tool only).',
|
|
50
48
|
caveman: 'Caveman Code — token-efficient coding agent (launch with Caveman tool only).',
|
|
51
49
|
jcode: 'Launch jcode coding agent with the selected model.',
|
|
52
50
|
}
|
package/src/tui/key-handler.js
CHANGED
|
@@ -107,8 +107,6 @@ const PROVIDER_AUTH_ENDPOINTS = {
|
|
|
107
107
|
zai: null, // 📖 ZAI undocumented; use ping only
|
|
108
108
|
googleai: null, // 📖 Google AI Studio has no OpenAI-compatible /models; use ping
|
|
109
109
|
'opencode-zen': null, // 📖 OpenCode Zen uses OpenCode auth only; use ping
|
|
110
|
-
rovo: null, // 📖 CLI tool — no API key
|
|
111
|
-
gemini: null, // 📖 CLI tool — no API key
|
|
112
110
|
}
|
|
113
111
|
|
|
114
112
|
// 📖 Sleep helper kept local to this module so the Settings key test flow can
|
|
@@ -337,7 +335,7 @@ export function createKeyHandler(ctx) {
|
|
|
337
335
|
}
|
|
338
336
|
|
|
339
337
|
function getModelTelemetryFamily(providerKey) {
|
|
340
|
-
if (providerKey === '
|
|
338
|
+
if (providerKey === 'opencode-zen') return providerKey
|
|
341
339
|
return 'standard'
|
|
342
340
|
}
|
|
343
341
|
|
|
@@ -443,15 +441,14 @@ export function createKeyHandler(ctx) {
|
|
|
443
441
|
console.log()
|
|
444
442
|
|
|
445
443
|
// 📖 CLI-only tool compatibility checks:
|
|
446
|
-
// 📖 Case A: Active tool mode is CLI-only
|
|
444
|
+
// 📖 Case A: Active tool mode is CLI-only but selected model doesn't belong to it
|
|
447
445
|
// 📖 Case B: Selected model belongs to a CLI-only provider but active mode is something else
|
|
448
446
|
const activeMeta = getToolMeta(state.mode)
|
|
449
447
|
const isActiveModeCliOnly = activeMeta.cliOnly === true
|
|
450
|
-
const isModelFromCliOnly = selected.providerKey === 'rovo' || selected.providerKey === 'gemini'
|
|
451
448
|
const isModelFromZen = selected.providerKey === 'opencode-zen'
|
|
452
449
|
const modelBelongsToActiveMode = selected.providerKey === state.mode
|
|
453
450
|
|
|
454
|
-
// 📖 Case A: User is in
|
|
451
|
+
// 📖 Case A: User is in a CLI-only tool mode but selected a model from a different provider
|
|
455
452
|
if (isActiveModeCliOnly && !modelBelongsToActiveMode) {
|
|
456
453
|
trackAppUseResult(selected, 'blocked_incompatible_model', {
|
|
457
454
|
blocked_by_tool_mode: state.mode,
|
|
@@ -472,23 +469,11 @@ export function createKeyHandler(ctx) {
|
|
|
472
469
|
process.exit(0)
|
|
473
470
|
}
|
|
474
471
|
|
|
475
|
-
// 📖 Case B: Selected model is from a CLI-only provider but active mode is different
|
|
476
|
-
if (isModelFromCliOnly && !modelBelongsToActiveMode) {
|
|
477
|
-
const modelMeta = getToolMeta(selected.providerKey)
|
|
478
|
-
console.log(chalk.yellow(` ⚠ ${selected.label} is a ${modelMeta.label}-exclusive model.`))
|
|
479
|
-
console.log(chalk.yellow(` Your current tool is: ${activeMeta.label}`))
|
|
480
|
-
console.log()
|
|
481
|
-
console.log(chalk.cyan(` Switching to ${modelMeta.label} and launching...`))
|
|
482
|
-
setToolMode(selected.providerKey)
|
|
483
|
-
console.log(chalk.green(` ✓ Switched to ${modelMeta.label}`))
|
|
484
|
-
console.log()
|
|
485
|
-
}
|
|
486
|
-
|
|
487
472
|
// 📖 Case C removed: Zen models now work with any OpenAI-compatible tool (Pi, Aider, etc.)
|
|
488
473
|
// 📖 The Zen endpoint (https://opencode.ai/zen/v1/chat/completions) is standard OpenAI-compatible.
|
|
489
474
|
|
|
490
|
-
// 📖 OpenClaw
|
|
491
|
-
if (state.mode !== 'openclaw' && !
|
|
475
|
+
// 📖 OpenClaw and Zen models manage auth differently — skip API key warning for them.
|
|
476
|
+
if (state.mode !== 'openclaw' && !isModelFromZen) {
|
|
492
477
|
const selectedApiKey = getApiKey(state.config, selected.providerKey)
|
|
493
478
|
if (!selectedApiKey) {
|
|
494
479
|
console.log(chalk.yellow(` Warning: No API key configured for ${selected.providerKey}.`))
|
|
@@ -500,7 +485,7 @@ export function createKeyHandler(ctx) {
|
|
|
500
485
|
|
|
501
486
|
// 📖 CLI-only tool auto-install check — verify the CLI binary is available before launch.
|
|
502
487
|
const toolModeForProvider = selected.providerKey
|
|
503
|
-
if (
|
|
488
|
+
if (isActiveModeCliOnly && !isToolInstalled(toolModeForProvider)) {
|
|
504
489
|
const installPlan = getToolInstallPlan(toolModeForProvider)
|
|
505
490
|
if (installPlan.supported) {
|
|
506
491
|
console.log()
|
package/src/tui/overlays.js
CHANGED
|
@@ -944,7 +944,7 @@ export function createOverlayRenderers(state, deps) {
|
|
|
944
944
|
lines.push(` ${key('Ctrl+A')} AI Speed Test ${hint('(benchmark selected model → time + TPS)')}`)
|
|
945
945
|
lines.push(` ${key('Ctrl+U')} Global AI Speed Test ${hint('(benchmark all models; Settings can auto-run it on startup)')}`)
|
|
946
946
|
lines.push(` ${key('E')} Cycle filter mode ${hint('(Normal → Configured only → Usable only)')}`)
|
|
947
|
-
lines.push(` ${key('Z')} Cycle tool mode ${hint('(📦 OpenCode → π Pi → 🪼 jcode → 📦 Desktop → 🦞 OpenClaw → 💘 Crush → 🪿 Goose → 🛠 Aider → 🐉 Qwen → 🤲 OpenHands → ⚡ Amp
|
|
947
|
+
lines.push(` ${key('Z')} Cycle tool mode ${hint('(📦 OpenCode → π Pi → 🪼 jcode → 📦 Desktop → 🦞 OpenClaw → 💘 Crush → 🪿 Goose → 🛠 Aider → 🐉 Qwen → 🤲 OpenHands → ⚡ Amp)')}`)
|
|
948
948
|
lines.push(` ${key('F')} Toggle favorite on selected row ${hint('(1️⃣2️⃣3️⃣ = router fallback order, capped at 🔟)')}`)
|
|
949
949
|
lines.push(` ${key('⇧↑/⇧↓')} Reorder selected favorite up/down ${hint('(changes router priority)')}`)
|
|
950
950
|
lines.push(` ${key('Y')} Toggle favorites mode ${hint('(Pinned + always visible ↔ Normal filter/sort behavior)')}`)
|