free-coding-models 0.3.16 → 0.3.18
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 +23 -0
- package/README.md +195 -120
- package/package.json +1 -1
- package/src/app.js +20 -2
- package/src/config.js +3 -0
- package/src/key-handler.js +184 -38
- package/src/openclaw.js +39 -5
- package/src/opencode.js +2 -1
- package/src/overlays.js +314 -223
- package/src/render-helpers.js +1 -1
- package/src/render-table.js +152 -180
- package/src/theme.js +315 -0
- package/src/tier-colors.js +15 -17
- package/src/tool-bootstrap.js +310 -0
- package/src/tool-launchers.js +12 -7
- package/src/ui-config.js +24 -31
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## 0.3.18
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Missing tool bootstrap flow**: FCM now detects when a target CLI is absent, offers a minimal in-TUI install confirmation, runs the official global install command, then resumes the selected model launch automatically.
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **TUI readability overhaul across every screen**: the main table, Settings, Help, Smart Recommend, Feedback, and Changelog overlays now share a semantic high-contrast theme system instead of a patchwork of hardcoded colors.
|
|
12
|
+
- **Global theme switching now works for real**: press `G` to cycle `auto → dark → light` live, and the Settings screen now exposes a visible `Global Theme` row for the same control.
|
|
13
|
+
- **Launcher binary resolution**: direct tool launches now search PATH plus common user bin directories so a freshly installed CLI can be reused immediately in the same FCM session.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **Theme repaint bugs**: provider colors, tier colors, separators, badges, cursor highlights, and overlay backgrounds now update immediately when the theme changes instead of keeping stale import-time colors.
|
|
17
|
+
|
|
18
|
+
## 0.3.17
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- **Auto Light/Dark Theme**: Implemented automatic detection of the user's terminal theme (dark or light) so that the TUI is always readable. Added semantic color tokens, and users can override the theme as `dark`, `light`, or `auto` via the Settings interface.
|
|
22
|
+
|
|
23
|
+
## 0.3.16
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- **iFlow free coding models**: Added the iFlow provider to the README and TUI, supporting `deepseek-v3`, `mini-max-m2.5`, etc.
|
|
27
|
+
|
|
5
28
|
## 0.3.15
|
|
6
29
|
|
|
7
30
|
### Added
|
package/README.md
CHANGED
|
@@ -1,184 +1,259 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://img.shields.io/npm/v/free-coding-models?color=76b900&label=npm&logo=npm" alt="npm version">
|
|
3
|
+
<img src="https://img.shields.io/node/v/free-coding-models?color=76b900&logo=node.js" alt="node version">
|
|
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-160-76b900?logo=nvidia" alt="models count">
|
|
6
|
+
<img src="https://img.shields.io/badge/providers-20-blue" alt="providers count">
|
|
7
|
+
</p>
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
<h1 align="center">free-coding-models</h1>
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
<strong>Find the fastest free coding model in seconds</strong><br>
|
|
13
|
+
<sub>Ping 160 models across 20 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 or Pi in one keystroke</sub>
|
|
14
|
+
</p>
|
|
6
15
|
|
|
7
|
-
## Install
|
|
8
16
|
|
|
9
|
-
```bash
|
|
10
|
-
pnpm install
|
|
11
|
-
pnpm start
|
|
12
|
-
```
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
<p align="center">
|
|
15
19
|
|
|
16
20
|
```bash
|
|
17
21
|
npm install -g free-coding-models
|
|
18
22
|
free-coding-models
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<a href="#-why-this-tool">Why</a> •
|
|
29
|
+
<a href="#-quick-start">Quick Start</a> •
|
|
30
|
+
<a href="#-providers">Providers</a> •
|
|
31
|
+
<a href="#-usage">Usage</a> •
|
|
32
|
+
<a href="#-tui-keys">TUI Keys</a> •
|
|
33
|
+
<a href="#-contributing">Contributing</a>
|
|
34
|
+
</p>
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<img src="demo.gif" alt="free-coding-models demo" width="100%">
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
<p align="center">
|
|
41
|
+
<sub>Made with ❤️ and ☕ by <a href="https://vanessadepraute.dev">Vanessa Depraute</a> (aka <a href="https://vavanessa.dev">Vava-Nessa</a>)</sub>
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 💡 Why this tool?
|
|
22
47
|
|
|
23
|
-
|
|
24
|
-
- Pings models continuously and shows latency, uptime, stability, verdict, and usage snapshots
|
|
25
|
-
- Lets you filter, sort, favorite, and compare models inside a full-screen TUI
|
|
26
|
-
- Launches supported coding tools with the currently selected model, after writing that exact selection as the tool default
|
|
27
|
-
- Installs provider catalogs into compatible external tool configs through the `Y` flow
|
|
48
|
+
There are **160+ free coding models** scattered across 20 providers. Which one is fastest right now? Which one is actually stable versus just lucky on the last ping?
|
|
28
49
|
|
|
29
|
-
|
|
50
|
+
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%).
|
|
30
51
|
|
|
31
|
-
|
|
52
|
+
It then writes the model you pick directly into your coding tool's config — so you go from "which model?" to "coding" in under 10 seconds.
|
|
32
53
|
|
|
33
|
-
|
|
34
|
-
- `OpenCode Desktop`
|
|
35
|
-
- `OpenClaw`
|
|
36
|
-
- `Crush`
|
|
37
|
-
- `Goose`
|
|
38
|
-
- `Pi`
|
|
39
|
-
- `Aider`
|
|
40
|
-
- `Qwen Code`
|
|
41
|
-
- `OpenHands`
|
|
42
|
-
- `Amp`
|
|
54
|
+
---
|
|
43
55
|
|
|
44
|
-
|
|
56
|
+
## ⚡ Quick Start
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
- `Codex`
|
|
48
|
-
- `Gemini`
|
|
49
|
-
- the old FCM global proxy / daemon / log overlay flow
|
|
58
|
+
**① Get a free API key** — you only need one to get started:
|
|
50
59
|
|
|
51
|
-
|
|
60
|
+
**160 coding models** across 20 providers, ranked by [SWE-bench Verified](https://www.swebench.com).
|
|
61
|
+
|
|
62
|
+
| Provider | Models | Tier range | Free tier | Env var |
|
|
63
|
+
|----------|--------|-----------|-----------|--------|
|
|
64
|
+
| [NVIDIA NIM](https://build.nvidia.com) | 44 | S+ → C | 40 req/min (no credit card needed) | `NVIDIA_API_KEY` |
|
|
65
|
+
| [iFlow](https://platform.iflow.cn) | 11 | S+ → A+ | Free for individuals (no req limits, 7-day key expiry) | `IFLOW_API_KEY` |
|
|
66
|
+
| [ZAI](https://z.ai) | 7 | S+ → S | Free tier (generous quota) | `ZAI_API_KEY` |
|
|
67
|
+
| [Alibaba DashScope](https://modelstudio.console.alibabacloud.com) | 8 | S+ → A | 1M free tokens per model (Singapore region, 90 days) | `DASHSCOPE_API_KEY` |
|
|
68
|
+
| [Groq](https://console.groq.com/keys) | 10 | S → B | 30‑50 RPM per model (varies by model) | `GROQ_API_KEY` |
|
|
69
|
+
| [Cerebras](https://cloud.cerebras.ai) | 7 | S+ → B | Generous free tier (developer tier 10× higher limits) | `CEREBRAS_API_KEY` |
|
|
70
|
+
| [SambaNova](https://sambanova.ai/developers) | 12 | S+ → B | Dev tier generous quota | `SAMBANOVA_API_KEY` |
|
|
71
|
+
| [OpenRouter](https://openrouter.ai/keys) | 11 | S+ → C | Free on :free: 50/day <$10, 1000/day ≥$10 (20 req/min) | `OPENROUTER_API_KEY` |
|
|
72
|
+
| [Hugging Face](https://huggingface.co/settings/tokens) | 2 | S → B | Free monthly credits (~$0.10) | `HUGGINGFACE_API_KEY` |
|
|
73
|
+
| [Together AI](https://api.together.ai/settings/api-keys) | 7 | S+ → A- | Credits/promos vary by account (check console) | `TOGETHER_API_KEY` |
|
|
74
|
+
| [DeepInfra](https://deepinfra.com/login) | 2 | A- → B+ | 200 concurrent requests (default) | `DEEPINFRA_API_KEY` |
|
|
75
|
+
| [Fireworks AI](https://fireworks.ai) | 2 | S | $1 credits – 10 req/min without payment | `FIREWORKS_API_KEY` |
|
|
76
|
+
| [Mistral Codestral](https://codestral.mistral.ai) | 1 | B+ | 30 req/min, 2000/day | `CODESTRAL_API_KEY` |
|
|
77
|
+
| [Hyperbolic](https://app.hyperbolic.ai/settings) | 10 | S+ → A- | $1 free trial credits | `HYPERBOLIC_API_KEY` |
|
|
78
|
+
| [Scaleway](https://console.scaleway.com/iam/api-keys) | 7 | S+ → B+ | 1M free tokens | `SCALEWAY_API_KEY` |
|
|
79
|
+
| [Google AI Studio](https://aistudio.google.com/apikey) | 3 | B → C | 14.4K req/day, 30/min | `GOOGLE_API_KEY` |
|
|
80
|
+
| [SiliconFlow](https://cloud.siliconflow.cn/account/ak) | 6 | S+ → A | Free models: usually 100 RPM, varies by model | `SILICONFLOW_API_KEY` |
|
|
81
|
+
| [Cloudflare Workers AI](https://dash.cloudflare.com) | 6 | S → B | Free: 10k neurons/day, text-gen 300 RPM | `CLOUDFLARE_API_TOKEN` + `CLOUDFLARE_ACCOUNT_ID` |
|
|
82
|
+
| [Perplexity API](https://www.perplexity.ai/settings/api) | 4 | A+ → B | Tiered limits by spend (default ~50 RPM) | `PERPLEXITY_API_KEY` |
|
|
83
|
+
| [Replicate](https://replicate.com/account/api-tokens) | 1 | A- | 6 req/min (no payment) – up to 3,000 RPM with payment | `REPLICATE_API_TOKEN` |
|
|
84
|
+
|
|
85
|
+
> 💡 One key is enough. Add more at any time with **`P`** inside the TUI.
|
|
86
|
+
|
|
87
|
+
### Tier scale
|
|
88
|
+
|
|
89
|
+
| Tier | SWE-bench | Best for |
|
|
90
|
+
|------|-----------|----------|
|
|
91
|
+
| **S+** | ≥ 70% | Complex refactors, real-world GitHub issues |
|
|
92
|
+
| **S** | 60–70% | Most coding tasks, strong general use |
|
|
93
|
+
| **A+/A** | 40–60% | Solid alternatives, targeted programming |
|
|
94
|
+
| **A-/B+** | 30–40% | Smaller tasks, constrained infra |
|
|
95
|
+
| **B/C** | < 30% | Code completion, edge/minimal setups |
|
|
96
|
+
|
|
97
|
+
**② Install and run:**
|
|
52
98
|
|
|
53
99
|
```bash
|
|
100
|
+
npm install -g free-coding-models
|
|
54
101
|
free-coding-models
|
|
55
102
|
```
|
|
56
103
|
|
|
57
|
-
|
|
104
|
+
On first run, you'll be prompted to enter your API key(s). You can skip providers and add more later with **`P`**.
|
|
105
|
+
|
|
106
|
+
Need to fix contrast because your terminal theme is fighting the TUI? Press **`G`** at any time to cycle **Auto → Dark → Light**. The switch recolors the full interface live: table, Settings, Help, Smart Recommend, Feedback, and Changelog.
|
|
107
|
+
|
|
108
|
+
**③ Pick a model and launch your tool:**
|
|
58
109
|
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
free-coding-models --openclaw --tier S
|
|
62
|
-
free-coding-models --crush
|
|
63
|
-
free-coding-models --json
|
|
64
|
-
free-coding-models --recommend
|
|
65
|
-
free-coding-models --help
|
|
110
|
+
```
|
|
111
|
+
↑↓ navigate → Enter to launch
|
|
66
112
|
```
|
|
67
113
|
|
|
68
|
-
|
|
114
|
+
The model you select is automatically written into your tool's config (OpenCode, OpenClaw, Crush, etc.) and the tool opens immediately. Done.
|
|
69
115
|
|
|
70
|
-
|
|
116
|
+
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.
|
|
71
117
|
|
|
72
|
-
-
|
|
73
|
-
- `Enter` launch/select the current model in the active tool mode
|
|
74
|
-
- `Z` cycle tool mode
|
|
75
|
-
- `T` cycle tier filter
|
|
76
|
-
- `D` cycle provider filter
|
|
77
|
-
- `R/O/M/L/A/S/C/H/V/B/U/G` sort columns
|
|
78
|
-
- `E` toggle configured models only
|
|
79
|
-
- `F` favorite/unfavorite the selected model
|
|
80
|
-
- `W` cycle ping cadence
|
|
81
|
-
- `P` open Settings
|
|
82
|
-
- `Y` open Install Endpoints
|
|
83
|
-
- `Q` open Smart Recommend
|
|
84
|
-
- `I` open feedback / bug report form
|
|
85
|
-
- `N` open changelog
|
|
86
|
-
- `K` open help
|
|
87
|
-
- `Ctrl+C` exit
|
|
118
|
+
> 💡 You can also run `free-coding-models --goose --tier S` to pre-filter to S-tier models for Goose before the TUI even opens.
|
|
88
119
|
|
|
89
|
-
## Settings
|
|
90
120
|
|
|
91
|
-
Press `P` to:
|
|
92
121
|
|
|
93
|
-
|
|
94
|
-
- enable or disable providers
|
|
95
|
-
- test provider keys
|
|
96
|
-
- check for updates
|
|
97
|
-
- toggle the terminal width warning
|
|
98
|
-
- clean discontinued proxy-era config left behind by older builds
|
|
122
|
+
## 🚀 Usage
|
|
99
123
|
|
|
100
|
-
|
|
124
|
+
### Common scenarios
|
|
101
125
|
|
|
102
|
-
|
|
126
|
+
```bash
|
|
127
|
+
# "I want the most reliable model right now"
|
|
128
|
+
free-coding-models --fiable
|
|
103
129
|
|
|
104
|
-
|
|
130
|
+
# "I want to configure Goose with an S-tier model"
|
|
131
|
+
free-coding-models --goose --tier S
|
|
105
132
|
|
|
106
|
-
|
|
133
|
+
# "I want NVIDIA's top models only"
|
|
134
|
+
free-coding-models --origin nvidia --tier S
|
|
107
135
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
3. Choose scope: all models or selected models
|
|
111
|
-
4. Write the managed config/env files
|
|
136
|
+
# "Show me only elite models that are currently healthy"
|
|
137
|
+
free-coding-models --premium
|
|
112
138
|
|
|
113
|
-
|
|
139
|
+
# "I want to script this — give me JSON"
|
|
140
|
+
free-coding-models --tier S --json | jq -r '.[0].modelId'
|
|
114
141
|
|
|
115
|
-
|
|
142
|
+
# "I want to configure OpenClaw with Groq's fastest model"
|
|
143
|
+
free-coding-models --openclaw --origin groq
|
|
144
|
+
```
|
|
116
145
|
|
|
117
|
-
|
|
146
|
+
### Tool launcher flags
|
|
118
147
|
|
|
119
|
-
|
|
148
|
+
| Flag | Launches |
|
|
149
|
+
|------|----------|
|
|
150
|
+
| `--opencode` | OpenCode CLI |
|
|
151
|
+
| `--opencode-desktop` | OpenCode Desktop |
|
|
152
|
+
| `--openclaw` | OpenClaw |
|
|
153
|
+
| `--crush` | Crush |
|
|
154
|
+
| `--goose` | Goose |
|
|
155
|
+
| `--aider` | Aider |
|
|
156
|
+
| `--qwen` | Qwen Code |
|
|
157
|
+
| `--openhands` | OpenHands |
|
|
158
|
+
| `--amp` | Amp |
|
|
159
|
+
| `--pi` | Pi |
|
|
120
160
|
|
|
121
|
-
|
|
122
|
-
- Selecting a model and pressing `Enter` updates the config and launches the target mode
|
|
161
|
+
Press **`Z`** in the TUI to cycle between tools without restarting.
|
|
123
162
|
|
|
124
|
-
|
|
163
|
+
→ **[Full flags reference](./docs/flags.md)**
|
|
125
164
|
|
|
126
|
-
|
|
127
|
-
- OpenClaw itself is not launched by FCM
|
|
165
|
+
---
|
|
128
166
|
|
|
129
|
-
|
|
167
|
+
## ⌨️ TUI Keys
|
|
130
168
|
|
|
131
|
-
|
|
169
|
+
| Key | Action |
|
|
170
|
+
|-----|--------|
|
|
171
|
+
| `↑↓` | Navigate models |
|
|
172
|
+
| `Enter` | Launch selected model in active tool |
|
|
173
|
+
| `Z` | Cycle target tool |
|
|
174
|
+
| `T` | Cycle tier filter |
|
|
175
|
+
| `D` | Cycle provider filter |
|
|
176
|
+
| `E` | Toggle configured-only mode |
|
|
177
|
+
| `F` | Favorite / unfavorite model |
|
|
178
|
+
| `G` | Cycle global theme (`Auto → Dark → Light`) |
|
|
179
|
+
| `R/S/C/M/O/L/A/H/V/B/U` | Sort columns |
|
|
180
|
+
| `P` | Settings (API keys, providers, updates, theme) |
|
|
181
|
+
| `Y` | Install Endpoints (push provider into tool config) |
|
|
182
|
+
| `Q` | Smart Recommend overlay |
|
|
183
|
+
| `N` | Changelog |
|
|
184
|
+
| `W` | Cycle ping cadence |
|
|
185
|
+
| `I` | Feedback / bug report |
|
|
186
|
+
| `K` | Help overlay |
|
|
187
|
+
| `Ctrl+C` | Exit |
|
|
132
188
|
|
|
133
|
-
|
|
189
|
+
→ **[Stability score & column reference](./docs/stability.md)**
|
|
134
190
|
|
|
135
|
-
|
|
136
|
-
- it binds to localhost on a random port
|
|
137
|
-
- it shuts down automatically when OpenCode exits
|
|
191
|
+
---
|
|
138
192
|
|
|
139
|
-
|
|
193
|
+
## ✨ Features
|
|
140
194
|
|
|
141
|
-
|
|
195
|
+
- **Parallel pings** — all 160 models tested simultaneously via native `fetch`
|
|
196
|
+
- **Adaptive monitoring** — 2s burst for 60s → 10s normal → 30s idle
|
|
197
|
+
- **Stability score** — composite 0–100 (p95 latency, jitter, spike rate, uptime)
|
|
198
|
+
- **Smart ranking** — top 3 highlighted 🥇🥈🥉
|
|
199
|
+
- **Favorites** — pin models with `F`, persisted across sessions
|
|
200
|
+
- **Configured-only default** — only shows providers you have keys for
|
|
201
|
+
- **Keyless latency** — models ping even without an API key (show 🔑 NO KEY)
|
|
202
|
+
- **Smart Recommend** — questionnaire picks the best model for your task type
|
|
203
|
+
- **Install Endpoints** — push a full provider catalog into any tool's config (`Y`)
|
|
204
|
+
- **Missing tool bootstrap** — detect absent CLIs, offer one-click install, then continue the selected launch automatically
|
|
205
|
+
- **Width guardrail** — shows a warning instead of a broken table in narrow terminals
|
|
206
|
+
- **Readable everywhere** — semantic theme palette keeps table rows, overlays, badges, and help screens legible in dark and light terminals
|
|
207
|
+
- **Global theme switch** — `G` cycles `auto`, `dark`, and `light` live without restarting
|
|
208
|
+
- **Auto-retry** — timeout models keep getting retried
|
|
142
209
|
|
|
143
|
-
|
|
210
|
+
---
|
|
144
211
|
|
|
145
|
-
|
|
212
|
+
## 📋 Contributing
|
|
146
213
|
|
|
147
|
-
|
|
148
|
-
pnpm test:fcm
|
|
149
|
-
pnpm test:fcm:mock
|
|
150
|
-
```
|
|
214
|
+
We welcome contributions — issues, PRs, new provider integrations.
|
|
151
215
|
|
|
152
|
-
|
|
216
|
+
**Q:** How accurate are the latency numbers?
|
|
217
|
+
**A:** Real round-trip times measured by your machine. Results depend on your network and provider load at that moment.
|
|
153
218
|
|
|
154
|
-
|
|
219
|
+
**Q:** Can I add a new provider?
|
|
220
|
+
**A:** Yes — see [`sources.js`](./sources.js) for the model catalog format.
|
|
155
221
|
|
|
156
|
-
|
|
222
|
+
→ **[Development guide](./docs/development.md)** · **[Config reference](./docs/config.md)** · **[Tool integrations](./docs/integrations.md)**
|
|
157
223
|
|
|
158
|
-
|
|
159
|
-
pnpm test
|
|
160
|
-
```
|
|
224
|
+
---
|
|
161
225
|
|
|
162
|
-
|
|
226
|
+
## 📧 Support
|
|
163
227
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
228
|
+
[GitHub Issues](https://github.com/vava-nessa/free-coding-models/issues) · [Discord](https://discord.gg/ZTNFHvvCkU)
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## 📄 License
|
|
167
233
|
|
|
168
|
-
|
|
234
|
+
MIT © [vava](https://github.com/vava-nessa)
|
|
169
235
|
|
|
170
|
-
|
|
171
|
-
- Pure helpers and sorting logic: [`src/utils.js`](./src/utils.js)
|
|
172
|
-
- OpenCode launch/config helpers: [`src/opencode.js`](./src/opencode.js), [`src/opencode-config.js`](./src/opencode-config.js)
|
|
173
|
-
- External tool launchers: [`src/tool-launchers.js`](./src/tool-launchers.js)
|
|
174
|
-
- Endpoint installer flow: [`src/endpoint-installer.js`](./src/endpoint-installer.js)
|
|
236
|
+
---
|
|
175
237
|
|
|
176
|
-
|
|
238
|
+
<p align="center">
|
|
239
|
+
<strong>Contributors</strong><br>
|
|
240
|
+
<a href="https://github.com/vava-nessa"><img src="https://avatars.githubusercontent.com/u/5466264?v=4&s=60" width="60" height="60" style="border-radius:50%" alt="vava-nessa"></a>
|
|
241
|
+
<a href="https://github.com/erwinh22"><img src="https://avatars.githubusercontent.com/u/6641858?v=4&s=60" width="60" height="60" style="border-radius:50%" alt="erwinh22"></a>
|
|
242
|
+
<a href="https://github.com/whit3rabbit"><img src="https://avatars.githubusercontent.com/u/12357518?v=4&s=60" width="60" height="60" style="border-radius:50%" alt="whit3rabbit"></a>
|
|
243
|
+
<a href="https://github.com/skylaweber"><img src="https://avatars.githubusercontent.com/u/172871734?v=4&s=60" width="60" height="60" style="border-radius:50%" alt="skylaweber"></a>
|
|
244
|
+
<a href="https://github.com/PhucTruong-ctrl"><img src="https://github.com/PhucTruong-ctrl.png?s=60" width="60" height="60" style="border-radius:50%" alt="PhucTruong-ctrl"></a>
|
|
245
|
+
<br>
|
|
246
|
+
<sub>
|
|
247
|
+
<a href="https://github.com/vava-nessa">vava-nessa</a> ·
|
|
248
|
+
<a href="https://github.com/erwinh22">erwinh22</a> ·
|
|
249
|
+
<a href="https://github.com/whit3rabbit">whit3rabbit</a> ·
|
|
250
|
+
<a href="https://github.com/skylaweber">skylaweber</a> ·
|
|
251
|
+
<a href="https://github.com/PhucTruong-ctrl">PhucTruong-ctrl</a>
|
|
252
|
+
</sub>
|
|
253
|
+
</p>
|
|
177
254
|
|
|
178
|
-
The app surface is intentionally narrowed right now to keep releases stable:
|
|
179
255
|
|
|
180
|
-
- direct provider launches are the supported path
|
|
181
|
-
- the old cross-tool proxy stack has been removed from the app
|
|
182
|
-
- Claude Code, Codex, and Gemini stay hidden until the rewrite is production-ready
|
|
183
256
|
|
|
184
|
-
|
|
257
|
+
<p align="center">
|
|
258
|
+
<sub>Anonymous usage data collected to improve the tool. No personal information ever.</sub>
|
|
259
|
+
</p>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.18",
|
|
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/src/app.js
CHANGED
|
@@ -122,10 +122,12 @@ import { createOverlayRenderers } from '../src/overlays.js'
|
|
|
122
122
|
import { createKeyHandler } from '../src/key-handler.js'
|
|
123
123
|
import { getToolModeOrder, getToolMeta } from '../src/tool-metadata.js'
|
|
124
124
|
import { startExternalTool } from '../src/tool-launchers.js'
|
|
125
|
+
import { getToolInstallPlan, installToolWithPlan, isToolInstalled } from '../src/tool-bootstrap.js'
|
|
125
126
|
import { getConfiguredInstallableProviders, installProviderEndpoints, refreshInstalledEndpoints, getInstallTargetModes, getProviderCatalogModels } from '../src/endpoint-installer.js'
|
|
126
127
|
import { loadCache, saveCache, clearCache, getCacheAge } from '../src/cache.js'
|
|
127
128
|
import { checkConfigSecurity } from '../src/security.js'
|
|
128
129
|
import { buildCliHelpText } from '../src/cli-help.js'
|
|
130
|
+
import { detectActiveTheme } from '../src/theme.js'
|
|
129
131
|
|
|
130
132
|
// 📖 mergedModels: cross-provider grouped model list (one entry per label, N providers each)
|
|
131
133
|
// 📖 mergedModelByLabel: fast lookup map from display label → merged model entry
|
|
@@ -174,7 +176,8 @@ const LOCAL_VERSION = pkg.version
|
|
|
174
176
|
|
|
175
177
|
export async function runApp(cliArgs, config) {
|
|
176
178
|
|
|
177
|
-
|
|
179
|
+
// 📖 Detect user active terminal theme
|
|
180
|
+
detectActiveTheme(config.settings?.theme || 'auto')
|
|
178
181
|
|
|
179
182
|
// 📖 Check config file security — warn and offer auto-fix if permissions are too open
|
|
180
183
|
const securityCheck = checkConfigSecurity()
|
|
@@ -418,6 +421,14 @@ export async function runApp(cliArgs, config) {
|
|
|
418
421
|
installEndpointsSelectedModelIds: new Set(), // 📖 Multi-select buffer for the selected-models phase
|
|
419
422
|
installEndpointsErrorMsg: null, // 📖 Temporary validation/error message inside the install flow
|
|
420
423
|
installEndpointsResult: null, // 📖 Final install result shown in the result phase
|
|
424
|
+
// 📖 Missing-tool bootstrap overlay — confirms a one-click install before retrying the launch.
|
|
425
|
+
toolInstallPromptOpen: false,
|
|
426
|
+
toolInstallPromptCursor: 0,
|
|
427
|
+
toolInstallPromptScrollOffset: 0,
|
|
428
|
+
toolInstallPromptMode: null,
|
|
429
|
+
toolInstallPromptModel: null,
|
|
430
|
+
toolInstallPromptPlan: null,
|
|
431
|
+
toolInstallPromptErrorMsg: null,
|
|
421
432
|
// 📖 Smart Recommend overlay state (Q key opens it)
|
|
422
433
|
recommendOpen: false, // 📖 Whether the recommend overlay is active
|
|
423
434
|
recommendPhase: 'questionnaire', // 📖 'questionnaire'|'analyzing'|'results' — current phase
|
|
@@ -748,6 +759,8 @@ export async function runApp(cliArgs, config) {
|
|
|
748
759
|
getInstallTargetModes,
|
|
749
760
|
getProviderCatalogModels,
|
|
750
761
|
getToolMeta,
|
|
762
|
+
getToolInstallPlan,
|
|
763
|
+
padEndDisplay,
|
|
751
764
|
})
|
|
752
765
|
|
|
753
766
|
onKeyPress = createKeyHandler({
|
|
@@ -783,6 +796,9 @@ export async function runApp(cliArgs, config) {
|
|
|
783
796
|
startOpenCode,
|
|
784
797
|
startExternalTool,
|
|
785
798
|
getToolModeOrder,
|
|
799
|
+
getToolInstallPlan,
|
|
800
|
+
isToolInstalled,
|
|
801
|
+
installToolWithPlan,
|
|
786
802
|
startRecommendAnalysis: overlays.startRecommendAnalysis,
|
|
787
803
|
stopRecommendAnalysis: overlays.stopRecommendAnalysis,
|
|
788
804
|
sendBugReport,
|
|
@@ -842,7 +858,7 @@ export async function runApp(cliArgs, config) {
|
|
|
842
858
|
refreshAutoPingMode()
|
|
843
859
|
state.frame++
|
|
844
860
|
// 📖 Cache visible+sorted models each frame so Enter handler always matches the display
|
|
845
|
-
if (!state.settingsOpen && !state.installEndpointsOpen && !state.recommendOpen && !state.feedbackOpen && !state.changelogOpen) {
|
|
861
|
+
if (!state.settingsOpen && !state.installEndpointsOpen && !state.toolInstallPromptOpen && !state.recommendOpen && !state.feedbackOpen && !state.changelogOpen) {
|
|
846
862
|
const visible = state.results.filter(r => !r.hidden)
|
|
847
863
|
state.visibleSorted = sortResultsWithPinnedFavorites(visible, state.sortColumn, state.sortDirection)
|
|
848
864
|
}
|
|
@@ -850,6 +866,8 @@ export async function runApp(cliArgs, config) {
|
|
|
850
866
|
? overlays.renderSettings()
|
|
851
867
|
: state.installEndpointsOpen
|
|
852
868
|
? overlays.renderInstallEndpoints()
|
|
869
|
+
: state.toolInstallPromptOpen
|
|
870
|
+
? overlays.renderToolInstallPrompt()
|
|
853
871
|
: state.recommendOpen
|
|
854
872
|
? overlays.renderRecommend()
|
|
855
873
|
: state.feedbackOpen
|
package/src/config.js
CHANGED
|
@@ -210,6 +210,7 @@ function normalizeSettingsSection(settings) {
|
|
|
210
210
|
...safeSettings,
|
|
211
211
|
hideUnconfiguredModels: typeof safeSettings.hideUnconfiguredModels === 'boolean' ? safeSettings.hideUnconfiguredModels : true,
|
|
212
212
|
disableWidthsWarning: safeSettings.disableWidthsWarning === true,
|
|
213
|
+
theme: ['dark', 'light', 'auto'].includes(safeSettings.theme) ? safeSettings.theme : 'auto',
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
216
|
|
|
@@ -230,6 +231,7 @@ function normalizeProfileSettings(settings) {
|
|
|
230
231
|
..._emptyProfileSettings(),
|
|
231
232
|
...safeSettings,
|
|
232
233
|
disableWidthsWarning: safeSettings.disableWidthsWarning === true,
|
|
234
|
+
theme: ['dark', 'light', 'auto'].includes(safeSettings.theme) ? safeSettings.theme : 'auto',
|
|
233
235
|
}
|
|
234
236
|
}
|
|
235
237
|
|
|
@@ -842,6 +844,7 @@ export function _emptyProfileSettings() {
|
|
|
842
844
|
hideUnconfiguredModels: true, // 📖 true = default to providers that are actually configured
|
|
843
845
|
preferredToolMode: 'opencode', // 📖 remember the last Z-selected launcher across app restarts
|
|
844
846
|
disableWidthsWarning: false, // 📖 Disable widths warning (default off)
|
|
847
|
+
theme: 'auto', // 📖 'auto' follows the terminal/OS theme, override with 'dark' or 'light' if needed
|
|
845
848
|
}
|
|
846
849
|
}
|
|
847
850
|
|