free-coding-models 0.4.2 → 0.5.0
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 +7 -7
- package/bin/free-coding-models.js +9 -9
- package/changelog/v0.4.3.md +28 -0
- package/changelog/v0.5.0.md +15 -0
- package/package.json +1 -1
- package/sources.js +7 -5
- package/src/{analysis.js → core/analysis.js} +5 -5
- package/src/{constants.js → core/constants.js} +1 -1
- package/src/{endpoint-installer.js → core/endpoint-installer.js} +1 -1
- package/src/{installed-models-manager.js → core/installed-models-manager.js} +1 -1
- package/src/{kilo.js → core/kilo.js} +1 -2
- package/src/{openclaw.js → core/openclaw.js} +1 -1
- package/src/{opencode.js → core/opencode.js} +2 -1
- package/src/{ping-loop.js → core/ping-loop.js} +1 -1
- package/src/{router-daemon.js → core/router-daemon.js} +3 -3
- package/src/{router-dashboard.js → core/router-dashboard.js} +2 -2
- package/src/{setup.js → core/setup.js} +1 -1
- package/src/{sync-set.js → core/sync-set.js} +1 -1
- package/src/{telemetry.js → core/telemetry.js} +1 -1
- package/src/{tool-launchers.js → core/tool-launchers.js} +2 -2
- package/src/{updater.js → core/updater.js} +1 -1
- package/src/{app.js → tui/app.js} +38 -38
- package/src/{cli-help.js → tui/cli-help.js} +1 -1
- package/src/{command-palette.js → tui/command-palette.js} +2 -2
- package/src/{key-handler.js → tui/key-handler.js} +11 -11
- package/src/{overlays.js → tui/overlays.js} +2 -2
- package/src/{render-helpers.js → tui/render-helpers.js} +2 -2
- package/src/{render-table.js → tui/render-table.js} +8 -8
- package/src/{tui-filters.js → tui/tui-filters.js} +3 -3
- package/src/{tui-state.js → tui/tui-state.js} +1 -1
- package/web/README.md +43 -0
- package/web/dist/assets/{index-hIk1b0wm.js → index-CvMUM9Jr.js} +1 -1
- package/web/dist/index.html +1 -1
- package/web/server.js +3 -3
- package/src/graphify-out/cache/089db1c1def873cf6d112f1590da4490e61e691aff0db41e006aa2fb15ba0656.json +0 -1
- package/src/graphify-out/cache/0b510b53cf1a1393fb52b1fc3bbbf88b63938e961ec5b82119a2e9715fee8bd7.json +0 -1
- package/src/graphify-out/cache/0ec9a95a326bde58e0316889018b278062d06d494d0f31ba177c9de71e5fed2d.json +0 -1
- package/src/graphify-out/cache/1548663a24a68dce740ebab1bd1d3091048c9604e9d067a1650a42a6d82541d4.json +0 -1
- package/src/graphify-out/cache/1783af63cb6d0dfb4d469009f71ac83a74ba0b33d48186ff2c6e63f9429e900a.json +0 -1
- package/src/graphify-out/cache/1e109f5eb5dc4fd285871c3613e32b6b14a8c225f4080ee34b51c7e1a1764571.json +0 -1
- package/src/graphify-out/cache/1eb24dbeb69b46c8bc1caf925df2f2a964af0f33aea143adf8ddf88e017db6ca.json +0 -1
- package/src/graphify-out/cache/21e1bcfed11685e8347243f9d8516072dda183266a4bfe22c52fb31753a446c8.json +0 -1
- package/src/graphify-out/cache/2327473478b9c4b1940bf7ef66c9ee960b3cba8d5302e56b625df8274246e0b4.json +0 -1
- package/src/graphify-out/cache/25955b81fd25454c8fa90fb71a47db8d1215cf621beb8ff3cbd580aaf011b4f3.json +0 -1
- package/src/graphify-out/cache/2739677f19c702f88f3de0a0bac475066adbda98709907ad3de967aef689f86d.json +0 -1
- package/src/graphify-out/cache/2bba03422f6b3ee7f5b5d29cc90314a064d259e5822a176657bda3e04505cf00.json +0 -1
- package/src/graphify-out/cache/2ddf1d2c6d10147b0402446bc71a7988187b79b6210dd7e7250be8c555b9ff35.json +0 -1
- package/src/graphify-out/cache/2ee07457a5767c95a57f8e9eb95b28f800044f35666e0715e9d88ad1103a092e.json +0 -1
- package/src/graphify-out/cache/2fe9f75dc2951c417f2c8dd22749092cf550dc67599f1c8d1866900dc6e9154e.json +0 -1
- package/src/graphify-out/cache/41c4b7c27e7fc3e2948d3a4bf95a72de2ed9a6f0463994babdce8ed2cc84598c.json +0 -1
- package/src/graphify-out/cache/5028defd54b7fbd3c7e444973e493de036e097e9b1d2a7cae7f19b88d68aacde.json +0 -1
- package/src/graphify-out/cache/5b133aba3fb16410c5b1fdbd1730039fc7fa1ac93abd99d7be08f60da70fc8d4.json +0 -1
- package/src/graphify-out/cache/74252e5b0978d85ab3421a3de1a9384aa282ffd2be2cfe7db2530139089f4275.json +0 -1
- package/src/graphify-out/cache/7695ebeea056095edd14332963cc43354ef3a097caf46f1e28d0f01369642901.json +0 -1
- package/src/graphify-out/cache/777aa7085c395a935c6556bbde182cd871edb61f3a685ed8068ec0c8f6fb0075.json +0 -1
- package/src/graphify-out/cache/82a723881980e82273c113def8315533d7da28827e300413d9ad30f27b7407df.json +0 -1
- package/src/graphify-out/cache/86b87c9603e6cd188f42c7eed3b86c291d48a781c223a707e74f3e7ed0c02a21.json +0 -1
- package/src/graphify-out/cache/890fead9a78cadaed560a2d2453916121fa605c3e43a334910ac4bc951a9ef6d.json +0 -1
- package/src/graphify-out/cache/89d3ea66f52783caa775ef9a30923d7d6225e1d8ae9e962f4741b8c7785dab1e.json +0 -1
- package/src/graphify-out/cache/8cc82cd9edce41f0e1c092f14a94fd52bf847addf3237b616dc5a9e505bd05bd.json +0 -1
- package/src/graphify-out/cache/93ba2e25e3ff7ad525f397902345fbd375df7315de7b402e20cc803c14eccde8.json +0 -1
- package/src/graphify-out/cache/99beed29580b9c7bfecfee794cb3d8e535fcf0eb3b92113108f88bdd0a8e79b3.json +0 -1
- package/src/graphify-out/cache/aeeb931fa477c65ce2e51d8149957350fa54225c613222bbbe8448998d1afd3d.json +0 -1
- package/src/graphify-out/cache/baf91bef5b5ecb2a476433b6cc0c48c563c54ee2d07fc3c192e543685e3e7222.json +0 -1
- package/src/graphify-out/cache/bd98b94ac4e9b92b6336d47b26e0366b51a4eaf0711d722f05f98dfae23ab42b.json +0 -1
- package/src/graphify-out/cache/bfcb51e9328e9cbfbee4f6fee0f56635d7b03488addc9f6c4e4b190b70a73362.json +0 -1
- package/src/graphify-out/cache/c0d3dabeb093aa758c49eadf41b87ecc96a16c1449c2670aaf48cbfc891d8da6.json +0 -1
- package/src/graphify-out/cache/c20d6630236f473c1406068c3ae205853e649b216495c93dfec055dd222c55cf.json +0 -1
- package/src/graphify-out/cache/c22b9122816bebce0a2f79af41a986559d01e00163dbcd579c5755621b4cb483.json +0 -1
- package/src/graphify-out/cache/ca556ec14453ddb8f9e0c5a832dac90d77111b9bad5f8c2d80d272e2e7a06371.json +0 -1
- package/src/graphify-out/cache/d6dbc9135dfa35a756b3b09b06700e4bc229fdccba11bb963f2ba44028e0bbae.json +0 -1
- package/src/graphify-out/cache/e1cf71276f1779d0fa075f79bd7c8a9fd0b8eef6932ac043137451b7c7fa7cbe.json +0 -1
- package/src/graphify-out/cache/e4b3be14494467df2d2ed389bc4f18f099021cb5bc355b901fa88387b2d8b8a2.json +0 -1
- package/src/graphify-out/cache/eaea0dded097f6f9553b654220046c6ec0c9be592a5973d906564ee60af34e0d.json +0 -1
- package/src/graphify-out/cache/ef07d0cd2675d1f79d2a2fdbf3bc3319687638751e9ce89b0d0d97ed1cd9f7e1.json +0 -1
- package/src/graphify-out/cache/f81272d6eb8aaff9e96d5a1d9f06777db70ac3652a646b951ded51f79871d733.json +0 -1
- package/src/graphify-out/cache/f9619dd92186f75a6dbda937e0c606647153918524cdb5763f956e6ec2a9e386.json +0 -1
- package/src/graphify-out/cache/fd88b1b2ff4bfcae08559d9c2aaeeb9a3f1e2f5cd8928762c311196956c170a5.json +0 -1
- /package/src/{benchmark.js → core/benchmark.js} +0 -0
- /package/src/{cache.js → core/cache.js} +0 -0
- /package/src/{changelog-loader.js → core/changelog-loader.js} +0 -0
- /package/src/{config.js → core/config.js} +0 -0
- /package/src/{favorites.js → core/favorites.js} +0 -0
- /package/src/{kilo-config.js → core/kilo-config.js} +0 -0
- /package/src/{legacy-proxy-cleanup.js → core/legacy-proxy-cleanup.js} +0 -0
- /package/src/{model-merger.js → core/model-merger.js} +0 -0
- /package/src/{opencode-config.js → core/opencode-config.js} +0 -0
- /package/src/{ping.js → core/ping.js} +0 -0
- /package/src/{product-flags.js → core/product-flags.js} +0 -0
- /package/src/{provider-metadata.js → core/provider-metadata.js} +0 -0
- /package/src/{provider-quota-fetchers.js → core/provider-quota-fetchers.js} +0 -0
- /package/src/{quota-capabilities.js → core/quota-capabilities.js} +0 -0
- /package/src/{security.js → core/security.js} +0 -0
- /package/src/{shell-env.js → core/shell-env.js} +0 -0
- /package/src/{testfcm.js → core/testfcm.js} +0 -0
- /package/src/{token-usage-reader.js → core/token-usage-reader.js} +0 -0
- /package/src/{tool-bootstrap.js → core/tool-bootstrap.js} +0 -0
- /package/src/{tool-metadata.js → core/tool-metadata.js} +0 -0
- /package/src/{usage-reader.js → core/usage-reader.js} +0 -0
- /package/src/{utils.js → core/utils.js} +0 -0
- /package/src/{mouse.js → tui/mouse.js} +0 -0
- /package/src/{theme.js → tui/theme.js} +0 -0
- /package/src/{tier-colors.js → tui/tier-colors.js} +0 -0
- /package/src/{ui-config.js → tui/ui-config.js} +0 -0
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>Find the fastest free coding model in seconds</strong><br>
|
|
9
|
-
Track ~
|
|
9
|
+
Track ~153 models across 16 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
11
|
OpenCode CLI / Desktop / WebUI, OpenClaw, Crush, Goose, Aider, Kilo CLI, Qwen Code, OpenHands, Amp, Hermes, Continue, Cline, Xcode, Pi, Rovo, Gemini and more...<br><br>
|
|
12
12
|
<strong>Use Kimi K2, DeepSeek V3, GPT-OSS, Qwen3, MiniMax M2, GLM, Llama 4, Gemma 4, Devstral and more — for free</strong>
|
|
@@ -16,7 +16,7 @@
|
|
|
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-
|
|
19
|
+
<img src="https://img.shields.io/badge/models-153+-3d6b00?logo=nvidia" alt="models count" width="200"><br>
|
|
20
20
|
<img src="https://img.shields.io/badge/providers-16-1a56db" alt="providers count" width="200">
|
|
21
21
|
</p>
|
|
22
22
|
|
|
@@ -59,7 +59,7 @@ free-coding-models
|
|
|
59
59
|
|
|
60
60
|
## 💡 Why this tool?
|
|
61
61
|
|
|
62
|
-
There are **~
|
|
62
|
+
There are **~153 cataloged free or free-limited coding models** across 16 vetted providers. Which one is fastest right now? Which one is actually stable versus just lucky on the last ping?
|
|
63
63
|
|
|
64
64
|
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%).
|
|
65
65
|
|
|
@@ -73,18 +73,18 @@ It then writes the model you pick directly into your coding tool's config — so
|
|
|
73
73
|
|
|
74
74
|
Create a free account on one provider below to get started:
|
|
75
75
|
|
|
76
|
-
**~
|
|
76
|
+
**~153 coding models** across 16 active providers, ranked by practical free-tier usefulness.
|
|
77
77
|
|
|
78
78
|
| # | Provider | Models | Tier range | Free tier | Env var |
|
|
79
79
|
|---|----------|--------|-----------|-----------|--------|
|
|
80
|
-
| 1 | [NVIDIA NIM](https://build.nvidia.com) |
|
|
80
|
+
| 1 | [NVIDIA NIM](https://build.nvidia.com) | 27 | S+ → C | ~40 RPM (no credit card) | `NVIDIA_API_KEY` |
|
|
81
81
|
| 2 | [Groq](https://console.groq.com/keys) | 8 | S → B | 30 RPM, 1K‑14.4K req/day (no credit card) | `GROQ_API_KEY` |
|
|
82
82
|
| 3 | [Cerebras](https://cloud.cerebras.ai) | 2 | S+ → S | 30 RPM, 1M tokens/day (no credit card) | `CEREBRAS_API_KEY` |
|
|
83
83
|
| 4 | [Google AI Studio](https://aistudio.google.com/apikey) | 7 | S+ → A | Gemini free quotas vary by model/region | `GOOGLE_API_KEY` |
|
|
84
84
|
| 5 | [GitHub Models](https://models.github.ai) | 15 | S+ → C | Quota depends on GitHub/Copilot tier | `GITHUB_TOKEN` |
|
|
85
85
|
| 6 | [Mistral La Plateforme](https://console.mistral.ai/api-keys) | 5 | S+ → A | Experiment plan, free evaluation tier | `MISTRAL_API_KEY` |
|
|
86
|
-
| 7 | [Cloudflare Workers AI](https://dash.cloudflare.com) |
|
|
87
|
-
| 8 | [OpenRouter](https://openrouter.ai/keys) |
|
|
86
|
+
| 7 | [Cloudflare Workers AI](https://dash.cloudflare.com) | 13 | S+ → B | 10K neurons/day, 300 RPM (no credit card) | `CLOUDFLARE_API_TOKEN` + `CLOUDFLARE_ACCOUNT_ID` |
|
|
87
|
+
| 8 | [OpenRouter](https://openrouter.ai/keys) | 24 | S+ → C | 50 req/day free, 1K/day with $10 spend | `OPENROUTER_API_KEY` |
|
|
88
88
|
| 9 | [SambaNova](https://cloud.sambanova.ai/apis) | 7 | S+ → B+ | Small developer quota, useful for light usage | `SAMBANOVA_API_KEY` |
|
|
89
89
|
| 10 | [OVHcloud AI Endpoints](https://endpoints.ai.cloud.ovh.net) | 10 | S → B | 2 req/min/IP free, 400 RPM with key | `OVH_AI_ENDPOINTS_ACCESS_TOKEN` |
|
|
90
90
|
| 11 | [Codestral](https://console.mistral.ai/api-keys) | 1 | B+ | 30 RPM, 2K req/day | `MISTRAL_API_KEY` |
|
|
@@ -10,13 +10,13 @@ if (process.argv.includes('--dev')) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
import chalk from 'chalk';
|
|
13
|
-
import { parseArgs, TIER_LETTER_MAP } from '../src/utils.js';
|
|
14
|
-
import { loadConfig } from '../src/config.js';
|
|
15
|
-
import { ensureTelemetryConfig } from '../src/telemetry.js';
|
|
16
|
-
import { ensureFavoritesConfig } from '../src/favorites.js';
|
|
17
|
-
import { buildCliHelpText } from '../src/cli-help.js';
|
|
18
|
-
import { ALT_LEAVE } from '../src/constants.js';
|
|
19
|
-
import { runApp } from '../src/app.js';
|
|
13
|
+
import { parseArgs, TIER_LETTER_MAP } from '../src/core/utils.js';
|
|
14
|
+
import { loadConfig } from '../src/core/config.js';
|
|
15
|
+
import { ensureTelemetryConfig } from '../src/core/telemetry.js';
|
|
16
|
+
import { ensureFavoritesConfig } from '../src/core/favorites.js';
|
|
17
|
+
import { buildCliHelpText } from '../src/tui/cli-help.js';
|
|
18
|
+
import { ALT_LEAVE } from '../src/core/constants.js';
|
|
19
|
+
import { runApp } from '../src/tui/app.js';
|
|
20
20
|
|
|
21
21
|
// Global error handlers to ensure terminal is restored if something crashes catastrophically
|
|
22
22
|
process.on('uncaughtException', (err) => {
|
|
@@ -61,7 +61,7 @@ async function main() {
|
|
|
61
61
|
runRouterDaemon,
|
|
62
62
|
startRouterDaemonBackground,
|
|
63
63
|
stopRouterDaemon,
|
|
64
|
-
} = await import('../src/router-daemon.js');
|
|
64
|
+
} = await import('../src/core/router-daemon.js');
|
|
65
65
|
|
|
66
66
|
if (cliArgs.daemonMode) {
|
|
67
67
|
await runRouterDaemon();
|
|
@@ -80,7 +80,7 @@ async function main() {
|
|
|
80
80
|
|
|
81
81
|
// 📖 --sync-set [name] — auto-discover, probe, and populate a router set
|
|
82
82
|
if (cliArgs.syncSetMode) {
|
|
83
|
-
const { syncSet } = await import('../src/sync-set.js');
|
|
83
|
+
const { syncSet } = await import('../src/core/sync-set.js');
|
|
84
84
|
const result = await syncSet({ name: cliArgs.syncSetName || 'auto' });
|
|
85
85
|
console.log(JSON.stringify(result, null, 2));
|
|
86
86
|
process.exit(result.ok ? 0 : 1);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog v0.4.3 - 2026-05-31
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
- **[nvidia]** `stepfun-ai/step-3.7-flash` (Step 3.7 Flash, S+, 256k ctx) — new model appeared on NVIDIA NIM free tier on May 29, 2026
|
|
5
|
+
- **[qwen]** `qwen3.7-max` (Qwen3.7 Max, S+, 80.0% SWE, 1M ctx) — new flagship model confirmed on OpenRouter API (created 2026-05-20)
|
|
6
|
+
- **[openrouter]** `moonshotai/kimi-k2.6:free` (Kimi K2.6, S+, 262k ctx) — newly available with :free tier on OpenRouter
|
|
7
|
+
|
|
8
|
+
### Removed
|
|
9
|
+
- **[cloudflare]** `@cf/qwen/qwq-32b` (QwQ 32B) — upstream deprecation: Groq removed `qwen-qwq-32b` in July 2025, Cloudflare has mirrored this removal
|
|
10
|
+
- **[openrouter]** `minimax/minimax-m2.5:free` (MiniMax M2.5) — free tier removed from OpenRouter
|
|
11
|
+
- **[openrouter]** `deepseek/deepseek-v4-flash:free` (DeepSeek V4 Flash) — free tier removed from OpenRouter
|
|
12
|
+
- **[openrouter]** `baidu/cobuddy:free` (Baidu CoBuddy) — free tier removed from OpenRouter
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **[github-models]** `meta/llama-4-scout-17b-16e-instruct` ctx 10M → 1M — GitHub Models caps context at 1M, not 10M
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Model count: 155 → 153 (net -2)
|
|
19
|
+
- nvidia: 26 → 27 (+1)
|
|
20
|
+
- cloudflare: 14 → 13 (-1)
|
|
21
|
+
- openrouter: 26 → 24 (-3+1)
|
|
22
|
+
- qwen: 11 → 12 (+1)
|
|
23
|
+
- All other providers verified current (no changes needed)
|
|
24
|
+
|
|
25
|
+
### Notes
|
|
26
|
+
- **gemini-2.5-pro/flash/flash-lite** still active until **October 16, 2026** — schedule removal for next audit cycle
|
|
27
|
+
- **Mistral deprecations** in July/August 2026: devstral-2512, magistral-medium-2509 — schedule removal for next audit cycle
|
|
28
|
+
- **SambaNova**: `gemma-3-12b-it` is now PREVIEW (not production) — still usable but may be removed at short notice
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog v0.5.0 - 2026-05-31
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
- **Final Desktop PRD**: Completed `desktop/prd-desktop.md` defining Tauri v2 shell, Bun/Node sidecar integration, zombie process prevention (parent-death binding), and loopback-only security models.
|
|
5
|
+
- **Sub-Project Documentation**: Added `/web/README.md` and `/desktop/README.md` to guide modular frontend and desktop sidecar development.
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- **Architectural Segregation (Core vs. TUI)**: Partitioned the codebase into isolated layers:
|
|
9
|
+
- `src/core/` for 100% shared business logic (routing, scoring, pings, daemon, quota, and config management) shared 1:1 with CLI, Docker, and Tauri sidecar.
|
|
10
|
+
- `src/tui/` for terminal-only layouts, keystroke handlers, ANSI renderers, and interactive loops.
|
|
11
|
+
- **Relative Import Pathways**: Restructured and re-routed relative imports across all entry points, TUI assets, and core logic files.
|
|
12
|
+
- **Port Consistency**: Standardized loopback proxy and daemon endpoints on port `19280` across all CLI, Docker, and Desktop configurations.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Clean workspace**: Fully purged `.kandown` task manager logs, `.claude-mcp.json`, and stale planning/analysis documents to ensure a zero-noise, lightweight npm package profile.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
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
|
@@ -48,6 +48,7 @@ export const nvidiaNim = [
|
|
|
48
48
|
['deepseek-ai/deepseek-v4-flash', 'DeepSeek V4 Flash', 'S+', '72.0%', '128k'],
|
|
49
49
|
['z-ai/glm5', 'GLM 5', 'S+', '73.8%', '200k'],
|
|
50
50
|
['stepfun-ai/step-3.5-flash', 'Step 3.5 Flash', 'S+', '74.4%', '256k'],
|
|
51
|
+
['stepfun-ai/step-3.7-flash', 'Step 3.7 Flash', 'S+', '74.4%', '256k'],
|
|
51
52
|
['qwen/qwen3-coder-480b-a35b-instruct', 'Qwen3 Coder 480B', 'S+', '70.6%', '256k'],
|
|
52
53
|
// ── S tier — SWE-bench Verified 60–70% ──
|
|
53
54
|
['qwen/qwen3-next-80b-a3b-instruct', 'Qwen3 80B Instruct', 'S', '65.0%', '128k'],
|
|
@@ -135,11 +136,12 @@ export const sambanova = [
|
|
|
135
136
|
export const openrouter = [
|
|
136
137
|
// ── S+ tier — live :free chat/coding models ──
|
|
137
138
|
['qwen/qwen3-coder:free', 'Qwen3 Coder 480B', 'S+', '70.6%', '262k'],
|
|
138
|
-
|
|
139
|
+
// Removed (2026-05-31): minimax/minimax-m2.5:free (free tier removed from OpenRouter)
|
|
139
140
|
['z-ai/glm-4.5-air:free', 'GLM 4.5 Air', 'S+', '72.0%', '131k'],
|
|
140
|
-
|
|
141
|
+
// Removed (2026-05-31): deepseek/deepseek-v4-flash:free (free tier removed from OpenRouter)
|
|
141
142
|
['poolside/laguna-m.1:free', 'Poolside Laguna M.1', 'S+', '-', '131k'],
|
|
142
143
|
['poolside/laguna-xs.2:free', 'Poolside Laguna XS.2','S+', '-', '131k'],
|
|
144
|
+
['moonshotai/kimi-k2.6:free', 'Kimi K2.6', 'S+', '76.8%', '262k'],
|
|
143
145
|
// ── S tier — live :free chat/coding models ──
|
|
144
146
|
['qwen/qwen3-next-80b-a3b-instruct:free', 'Qwen3 80B Instruct', 'S', '65.0%', '262k'],
|
|
145
147
|
['openai/gpt-oss-120b:free', 'GPT OSS 120B', 'S', '60.0%', '131k'],
|
|
@@ -161,7 +163,7 @@ export const openrouter = [
|
|
|
161
163
|
['meta-llama/llama-3.2-3b-instruct:free', 'Llama 3.2 3B', 'B', '20.0%', '128k'],
|
|
162
164
|
// ── B+ tier ──
|
|
163
165
|
['nvidia/nemotron-nano-9b-v2:free', 'Nemotron Nano 9B', 'B+', '18.0%', '128k'],
|
|
164
|
-
|
|
166
|
+
// Removed (2026-05-31): baidu/cobuddy:free (free tier removed from OpenRouter)
|
|
165
167
|
// ── B tier ──
|
|
166
168
|
['openrouter/free', 'OpenRouter Free', 'B', '-', '200k'],
|
|
167
169
|
// ── C tier ──
|
|
@@ -187,7 +189,7 @@ export const githubModels = [
|
|
|
187
189
|
['deepseek/deepseek-v3-0324', 'DeepSeek V3 0324', 'S', '62.0%', '128k'],
|
|
188
190
|
['meta/meta-llama-3.1-405b-instruct', 'Llama 3.1 405B', 'A', '44.0%', '128k'],
|
|
189
191
|
['meta/llama-4-maverick-17b-128e-instruct-fp8', 'Llama 4 Maverick', 'S', '62.0%', '1M'],
|
|
190
|
-
['meta/llama-4-scout-17b-16e-instruct', 'Llama 4 Scout', 'A', '44.0%', '
|
|
192
|
+
['meta/llama-4-scout-17b-16e-instruct', 'Llama 4 Scout', 'A', '44.0%', '1M'],
|
|
191
193
|
['meta/llama-3.3-70b-instruct', 'Llama 3.3 70B', 'A-', '39.5%', '128k'],
|
|
192
194
|
['meta/llama-3.2-90b-vision-instruct', 'Llama 3.2 90B Vision','A-', '-', '128k'],
|
|
193
195
|
['meta/llama-3.2-11b-vision-instruct', 'Llama 3.2 11B Vision','B', '-', '128k'],
|
|
@@ -292,7 +294,7 @@ export const cloudflare = [
|
|
|
292
294
|
['@cf/zai-org/glm-4.7-flash', 'GLM-4.7-Flash', 'S', '59.2%', '131k'],
|
|
293
295
|
['@cf/openai/gpt-oss-120b', 'GPT OSS 120B', 'S', '60.0%', '128k'],
|
|
294
296
|
// ── A+ tier ──
|
|
295
|
-
|
|
297
|
+
// Removed (2026-05-31): @cf/qwen/qwq-32b (upstream deprecation — Groq removed qwen-qwq-32b July 2025)
|
|
296
298
|
['@cf/nvidia/nemotron-3-120b-a12b', 'Nemotron 3 Super', 'A+', '56.0%', '128k'],
|
|
297
299
|
// ── A tier ──
|
|
298
300
|
['@cf/meta/llama-4-scout-17b-16e-instruct', 'Llama 4 Scout', 'A', '44.0%', '131k'],
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
* @see {@link ../src/ping.js} ping implementation
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
|
-
import { MODELS, sources } from '
|
|
39
|
-
import { findBestModel, filterByTier, formatCtxWindow, labelFromId, TIER_LETTER_MAP } from '
|
|
40
|
-
import { isProviderEnabled, getApiKey } from '
|
|
41
|
-
import { ping } from '
|
|
42
|
-
import { PROVIDER_COLOR } from '
|
|
38
|
+
import { MODELS, sources } from '../../sources.js'
|
|
39
|
+
import { findBestModel, filterByTier, formatCtxWindow, labelFromId, TIER_LETTER_MAP } from './utils.js'
|
|
40
|
+
import { isProviderEnabled, getApiKey } from './config.js'
|
|
41
|
+
import { ping } from './ping.js'
|
|
42
|
+
import { PROVIDER_COLOR } from '../tui/render-table.js'
|
|
43
43
|
import chalk from 'chalk'
|
|
44
44
|
|
|
45
45
|
// 📖 runFiableMode: Analyze models for reliability over 10 seconds, output the best one.
|
|
@@ -48,7 +48,7 @@ import chalk from 'chalk'
|
|
|
48
48
|
// 📖 \x1b[?7l disables auto-wrap so wide rows clip at the right edge instead of
|
|
49
49
|
// 📖 wrapping to the next line (which would double the row height and overflow).
|
|
50
50
|
// 📖 Mouse tracking sequences are appended/prepended so clicks and scroll work in the TUI.
|
|
51
|
-
import { MOUSE_ENABLE, MOUSE_DISABLE } from '
|
|
51
|
+
import { MOUSE_ENABLE, MOUSE_DISABLE } from '../tui/mouse.js'
|
|
52
52
|
|
|
53
53
|
export const ALT_ENTER = '\x1b[?1049h\x1b[?25l\x1b[?7l' + MOUSE_ENABLE
|
|
54
54
|
export const ALT_LEAVE = MOUSE_DISABLE + '\x1b[?7h\x1b[?1049l\x1b[?25h'
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
44
44
|
import { homedir } from 'node:os'
|
|
45
45
|
import { dirname, join } from 'node:path'
|
|
46
|
-
import { MODELS, sources } from '
|
|
46
|
+
import { MODELS, sources } from '../../sources.js'
|
|
47
47
|
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'
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'node:fs'
|
|
49
49
|
import { homedir } from 'node:os'
|
|
50
50
|
import { join, dirname } from 'node:path'
|
|
51
|
-
import { sources } from '
|
|
51
|
+
import { sources } from '../../sources.js'
|
|
52
52
|
|
|
53
53
|
const BACKUP_PATH = join(homedir(), '.free-coding-models-backups.json')
|
|
54
54
|
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import chalk from 'chalk'
|
|
7
|
-
import {
|
|
7
|
+
import { sources } from '../../sources.js'
|
|
8
8
|
import { loadKiloConfig, saveKiloConfig, getKiloConfigPath } from './kilo-config.js'
|
|
9
9
|
import { getApiKey } from './config.js'
|
|
10
10
|
import { ENV_VAR_NAMES, OPENCODE_MODEL_MAP } from './provider-metadata.js'
|
|
11
11
|
import { resolveToolBinaryPath } from './tool-bootstrap.js'
|
|
12
|
-
import { sources } from '../sources.js'
|
|
13
12
|
|
|
14
13
|
// 📖 Map source model IDs to Kilo built-in IDs (same as OpenCode).
|
|
15
14
|
function getKiloModelId(providerKey, modelId) {
|
|
@@ -31,7 +31,7 @@ import { homedir } from 'os'
|
|
|
31
31
|
import { dirname, join } from 'path'
|
|
32
32
|
import { installProviderEndpoints } from './endpoint-installer.js'
|
|
33
33
|
import { ENV_VAR_NAMES } from './provider-metadata.js'
|
|
34
|
-
import { PROVIDER_COLOR } from '
|
|
34
|
+
import { PROVIDER_COLOR } from '../tui/render-table.js'
|
|
35
35
|
import { resolveToolBinaryPath } from './tool-bootstrap.js'
|
|
36
36
|
import { getApiKey } from './config.js'
|
|
37
37
|
import { syncShellEnv } from './shell-env.js'
|
|
@@ -28,7 +28,8 @@ import { request as httpsRequest } from 'https'
|
|
|
28
28
|
import { homedir } from 'os'
|
|
29
29
|
import { join } from 'path'
|
|
30
30
|
import { copyFileSync, existsSync } from 'fs'
|
|
31
|
-
import { PROVIDER_COLOR } from '
|
|
31
|
+
import { PROVIDER_COLOR } from '../tui/render-table.js'
|
|
32
|
+
import { sources } from '../../sources.js'
|
|
32
33
|
import { loadOpenCodeConfig, saveOpenCodeConfig } from './opencode-config.js'
|
|
33
34
|
import { getApiKey } from './config.js'
|
|
34
35
|
import { ENV_VAR_NAMES, OPENCODE_MODEL_MAP, isWindows, isMac, isLinux } from './provider-metadata.js'
|
|
@@ -37,7 +37,7 @@ import { randomUUID } from 'node:crypto'
|
|
|
37
37
|
import { appendFileSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs'
|
|
38
38
|
import { homedir } from 'node:os'
|
|
39
39
|
import { fileURLToPath } from 'node:url'
|
|
40
|
-
import { MODELS, sources } from '
|
|
40
|
+
import { MODELS, sources } from '../../sources.js'
|
|
41
41
|
import {
|
|
42
42
|
CONFIG_PATH,
|
|
43
43
|
DEFAULT_ROUTER_SETTINGS,
|
|
@@ -71,7 +71,7 @@ export function getRouterPortRange() {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
74
|
-
const CLI_ENTRY_PATH = join(__dirname, '..', 'bin', 'free-coding-models.js')
|
|
74
|
+
const CLI_ENTRY_PATH = join(__dirname, '..', '..', 'bin', 'free-coding-models.js')
|
|
75
75
|
const MAX_BODY_BYTES = 10 * 1024 * 1024
|
|
76
76
|
const MAX_REQUEST_LOG = 200
|
|
77
77
|
const MAX_SSE_CLIENTS = 10
|
|
@@ -365,7 +365,7 @@ function getWebConfigPayload(runtime) {
|
|
|
365
365
|
return { providers, totalModels: MODELS.length }
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
const WEB_DIST_DIR = resolvePath(__dirname, '..', 'web', 'dist')
|
|
368
|
+
const WEB_DIST_DIR = resolvePath(__dirname, '..', '..', 'web', 'dist')
|
|
369
369
|
|
|
370
370
|
function serveStaticFromDist(res, absPath) {
|
|
371
371
|
const ext = absPath.slice(absPath.lastIndexOf('.'))
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
|
|
42
42
|
import chalk from 'chalk'
|
|
43
43
|
import { existsSync, readFileSync } from 'node:fs'
|
|
44
|
-
import { displayWidth, padEndDisplay, sliceOverlayLines, tintOverlayLines } from '
|
|
44
|
+
import { displayWidth, padEndDisplay, sliceOverlayLines, tintOverlayLines } from '../tui/render-helpers.js'
|
|
45
45
|
import { ROUTER_DEFAULT_PORT, ROUTER_MAX_PORT, ROUTER_PID_PATH, ROUTER_PORT_PATH, getRouterPortRange } from './router-daemon.js'
|
|
46
|
-
import { themeColors, getTierRgb } from '
|
|
46
|
+
import { themeColors, getTierRgb } from '../tui/theme.js'
|
|
47
47
|
import { formatTokenTotalCompact } from './token-usage-reader.js'
|
|
48
48
|
import { sendUsageTelemetry } from './telemetry.js'
|
|
49
49
|
import { getAvg, getVerdict } from './utils.js'
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
import chalk from 'chalk'
|
|
37
37
|
import { createRequire } from 'module'
|
|
38
|
-
import { sources } from '
|
|
38
|
+
import { sources } from '../../sources.js'
|
|
39
39
|
import { PROVIDER_METADATA } from './provider-metadata.js'
|
|
40
40
|
import { saveConfig } from './config.js'
|
|
41
41
|
|
|
@@ -51,7 +51,7 @@ import { createRequire } from 'module'
|
|
|
51
51
|
import { saveConfig } from './config.js'
|
|
52
52
|
|
|
53
53
|
const require = createRequire(import.meta.url)
|
|
54
|
-
const pkg = require('
|
|
54
|
+
const pkg = require('../../package.json')
|
|
55
55
|
const LOCAL_VERSION = pkg.version
|
|
56
56
|
|
|
57
57
|
// 📖 PostHog capture endpoint and defaults.
|
|
@@ -41,8 +41,8 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from
|
|
|
41
41
|
import { homedir } from 'os'
|
|
42
42
|
import { dirname, join } from 'path'
|
|
43
43
|
import { spawn, spawnSync } from 'child_process'
|
|
44
|
-
import { sources } from '
|
|
45
|
-
import { PROVIDER_COLOR } from '
|
|
44
|
+
import { sources } from '../../sources.js'
|
|
45
|
+
import { PROVIDER_COLOR } from '../tui/render-table.js'
|
|
46
46
|
import { getApiKey } from './config.js'
|
|
47
47
|
import { ENV_VAR_NAMES, isWindows } from './provider-metadata.js'
|
|
48
48
|
import { getToolMeta, TOOL_METADATA } from './tool-metadata.js'
|
|
@@ -46,7 +46,7 @@ import { accessSync, constants } from 'fs'
|
|
|
46
46
|
|
|
47
47
|
const require = createRequire(import.meta.url)
|
|
48
48
|
const readline = require('readline')
|
|
49
|
-
const pkg = require('
|
|
49
|
+
const pkg = require('../../package.json')
|
|
50
50
|
const LOCAL_VERSION = pkg.version
|
|
51
51
|
|
|
52
52
|
/**
|
|
@@ -96,45 +96,45 @@ import { readFileSync, writeFileSync, existsSync, copyFileSync, mkdirSync } from
|
|
|
96
96
|
import { randomUUID } from 'crypto'
|
|
97
97
|
import { homedir } from 'os'
|
|
98
98
|
import { join, dirname } from 'path'
|
|
99
|
-
import { MODELS, sources } from '
|
|
100
|
-
import { getAvg, getVerdict, getUptime, getP95, getJitter, getStabilityScore, sortResults, filterByTier, findBestModel, parseArgs, TIER_ORDER, VERDICT_ORDER, TIER_LETTER_MAP, scoreModelForTask, getTopRecommendations, TASK_TYPES, PRIORITY_TYPES, CONTEXT_BUDGETS, formatCtxWindow, labelFromId, formatResultsAsJSON } from '../
|
|
101
|
-
import { loadConfig, saveConfig, getApiKey, resolveApiKeys, addApiKey, removeApiKey, isProviderEnabled, persistApiKeysForProvider } from '../
|
|
102
|
-
import { buildMergedModels } from '../
|
|
103
|
-
import { loadOpenCodeConfig, saveOpenCodeConfig } from '../
|
|
104
|
-
import { usageForRow as _usageForRow } from '../
|
|
105
|
-
import { buildProviderModelTokenKey, loadTokenUsageByProviderModel } from '../
|
|
106
|
-
import { parseOpenRouterResponse, fetchProviderQuota as _fetchProviderQuotaFromModule } from '../
|
|
107
|
-
import { isKnownQuotaTelemetry } from '../
|
|
108
|
-
import { ALT_ENTER, ALT_LEAVE, ALT_HOME, PING_TIMEOUT, PING_INTERVAL, FPS, COL_MODEL, COL_MS, CELL_W, FRAMES, TIER_CYCLE, VERDICT_CYCLE, HEALTH_CYCLE, SETTINGS_OVERLAY_BG, HELP_OVERLAY_BG, RECOMMEND_OVERLAY_BG, OVERLAY_PANEL_WIDTH, TABLE_HEADER_LINES, TABLE_FOOTER_LINES, TABLE_FIXED_LINES, WIDTH_WARNING_MIN_COLS, msCell, spinCell } from '../
|
|
109
|
-
import { TIER_COLOR } from '
|
|
110
|
-
import { resolveCloudflareUrl, buildPingRequest, ping, extractQuotaPercent, getProviderQuotaPercentCached, usagePlaceholderForProvider } from '../
|
|
111
|
-
import { runFiableMode, filterByTierOrExit, fetchOpenRouterFreeModels } from '../
|
|
112
|
-
import { PROVIDER_METADATA, ENV_VAR_NAMES, isWindows, isMac } from '../
|
|
113
|
-
import { parseTelemetryEnv, isTelemetryDebugEnabled, telemetryDebug, ensureTelemetryConfig, getTelemetryDistinctId, getTelemetrySystem, getTelemetryTerminal, isTelemetryEnabled, sendUsageTelemetry } from '../
|
|
114
|
-
import { ensureFavoritesConfig, toFavoriteKey, syncFavoriteFlags, toggleFavoriteModel, reorderFavorite, pruneOrphanedFavorites } from '../
|
|
115
|
-
import { checkForUpdateDetailed, checkForUpdate, runUpdate, fetchLastReleaseDate } from '
|
|
99
|
+
import { MODELS, sources } from '../../sources.js'
|
|
100
|
+
import { getAvg, getVerdict, getUptime, getP95, getJitter, getStabilityScore, sortResults, filterByTier, findBestModel, parseArgs, TIER_ORDER, VERDICT_ORDER, TIER_LETTER_MAP, scoreModelForTask, getTopRecommendations, TASK_TYPES, PRIORITY_TYPES, CONTEXT_BUDGETS, formatCtxWindow, labelFromId, formatResultsAsJSON } from '../core/utils.js'
|
|
101
|
+
import { loadConfig, saveConfig, getApiKey, resolveApiKeys, addApiKey, removeApiKey, isProviderEnabled, persistApiKeysForProvider } from '../core/config.js'
|
|
102
|
+
import { buildMergedModels } from '../core/model-merger.js'
|
|
103
|
+
import { loadOpenCodeConfig, saveOpenCodeConfig } from '../core/opencode-config.js'
|
|
104
|
+
import { usageForRow as _usageForRow } from '../core/usage-reader.js'
|
|
105
|
+
import { buildProviderModelTokenKey, loadTokenUsageByProviderModel } from '../core/token-usage-reader.js'
|
|
106
|
+
import { parseOpenRouterResponse, fetchProviderQuota as _fetchProviderQuotaFromModule } from '../core/provider-quota-fetchers.js'
|
|
107
|
+
import { isKnownQuotaTelemetry } from '../core/quota-capabilities.js'
|
|
108
|
+
import { ALT_ENTER, ALT_LEAVE, ALT_HOME, PING_TIMEOUT, PING_INTERVAL, FPS, COL_MODEL, COL_MS, CELL_W, FRAMES, TIER_CYCLE, VERDICT_CYCLE, HEALTH_CYCLE, SETTINGS_OVERLAY_BG, HELP_OVERLAY_BG, RECOMMEND_OVERLAY_BG, OVERLAY_PANEL_WIDTH, TABLE_HEADER_LINES, TABLE_FOOTER_LINES, TABLE_FIXED_LINES, WIDTH_WARNING_MIN_COLS, msCell, spinCell } from '../core/constants.js'
|
|
109
|
+
import { TIER_COLOR } from './tier-colors.js'
|
|
110
|
+
import { resolveCloudflareUrl, buildPingRequest, ping, extractQuotaPercent, getProviderQuotaPercentCached, usagePlaceholderForProvider } from '../core/ping.js'
|
|
111
|
+
import { runFiableMode, filterByTierOrExit, fetchOpenRouterFreeModels } from '../core/analysis.js'
|
|
112
|
+
import { PROVIDER_METADATA, ENV_VAR_NAMES, isWindows, isMac } from '../core/provider-metadata.js'
|
|
113
|
+
import { parseTelemetryEnv, isTelemetryDebugEnabled, telemetryDebug, ensureTelemetryConfig, getTelemetryDistinctId, getTelemetrySystem, getTelemetryTerminal, isTelemetryEnabled, sendUsageTelemetry } from '../core/telemetry.js'
|
|
114
|
+
import { ensureFavoritesConfig, toFavoriteKey, syncFavoriteFlags, toggleFavoriteModel, reorderFavorite, pruneOrphanedFavorites } from '../core/favorites.js'
|
|
115
|
+
import { checkForUpdateDetailed, checkForUpdate, runUpdate, fetchLastReleaseDate } from '../core/updater.js'
|
|
116
116
|
import { createTuiState, PING_MODE_INTERVALS, PING_MODE_CYCLE, SPEED_MODE_DURATION_MS, IDLE_SLOW_AFTER_MS, intervalToPingMode } from './tui-state.js'
|
|
117
|
-
import { createPingLoop } from '
|
|
117
|
+
import { createPingLoop } from '../core/ping-loop.js'
|
|
118
118
|
import { createTuiFilters } from './tui-filters.js'
|
|
119
|
-
import { promptApiKey } from '../
|
|
120
|
-
import { syncShellEnv, ensureShellRcSource, removeShellEnv } from '../
|
|
121
|
-
import { stripAnsi, maskApiKey, displayWidth, padEndDisplay, tintOverlayLines, keepOverlayTargetVisible, sliceOverlayLines, calculateViewport, sortResultsWithPinnedFavorites, adjustScrollOffset } from '
|
|
122
|
-
import { renderTable, PROVIDER_COLOR } from '
|
|
123
|
-
import { setOpenCodeModelData, startOpenCode, startOpenCodeDesktop, startOpenCodeWeb } from '../
|
|
124
|
-
import { startKilo } from '../
|
|
125
|
-
import { startOpenClaw } from '../
|
|
126
|
-
import { createOverlayRenderers } from '
|
|
127
|
-
import { createKeyHandler, createMouseEventHandler } from '
|
|
128
|
-
import { createMouseHandler, containsMouseSequence } from '
|
|
129
|
-
import { stopRouterDashboardClient } from '../
|
|
130
|
-
import { getToolModeOrder, getToolMeta } from '../
|
|
131
|
-
import { startExternalTool } from '../
|
|
132
|
-
import { getToolInstallPlan, installToolWithPlan, isToolInstalled } from '../
|
|
133
|
-
import { getConfiguredInstallableProviders, installProviderEndpoints, refreshInstalledEndpoints, getInstallTargetModes, getProviderCatalogModels } from '../
|
|
134
|
-
import { loadCache, saveCache, clearCache, getCacheAge } from '../
|
|
135
|
-
import { checkConfigSecurity } from '../
|
|
136
|
-
import { buildCliHelpText } from '
|
|
137
|
-
import { detectActiveTheme } from '
|
|
119
|
+
import { promptApiKey } from '../core/setup.js'
|
|
120
|
+
import { syncShellEnv, ensureShellRcSource, removeShellEnv } from '../core/shell-env.js'
|
|
121
|
+
import { stripAnsi, maskApiKey, displayWidth, padEndDisplay, tintOverlayLines, keepOverlayTargetVisible, sliceOverlayLines, calculateViewport, sortResultsWithPinnedFavorites, adjustScrollOffset } from './render-helpers.js'
|
|
122
|
+
import { renderTable, PROVIDER_COLOR } from './render-table.js'
|
|
123
|
+
import { setOpenCodeModelData, startOpenCode, startOpenCodeDesktop, startOpenCodeWeb } from '../core/opencode.js'
|
|
124
|
+
import { startKilo } from '../core/kilo.js'
|
|
125
|
+
import { startOpenClaw } from '../core/openclaw.js'
|
|
126
|
+
import { createOverlayRenderers } from './overlays.js'
|
|
127
|
+
import { createKeyHandler, createMouseEventHandler } from './key-handler.js'
|
|
128
|
+
import { createMouseHandler, containsMouseSequence } from './mouse.js'
|
|
129
|
+
import { stopRouterDashboardClient } from '../core/router-dashboard.js'
|
|
130
|
+
import { getToolModeOrder, getToolMeta } from '../core/tool-metadata.js'
|
|
131
|
+
import { startExternalTool } from '../core/tool-launchers.js'
|
|
132
|
+
import { getToolInstallPlan, installToolWithPlan, isToolInstalled } from '../core/tool-bootstrap.js'
|
|
133
|
+
import { getConfiguredInstallableProviders, installProviderEndpoints, refreshInstalledEndpoints, getInstallTargetModes, getProviderCatalogModels } from '../core/endpoint-installer.js'
|
|
134
|
+
import { loadCache, saveCache, clearCache, getCacheAge } from '../core/cache.js'
|
|
135
|
+
import { checkConfigSecurity } from '../core/security.js'
|
|
136
|
+
import { buildCliHelpText } from './cli-help.js'
|
|
137
|
+
import { detectActiveTheme } from './theme.js'
|
|
138
138
|
|
|
139
139
|
// 📖 mergedModels: cross-provider grouped model list (one entry per label, N providers each)
|
|
140
140
|
// 📖 mergedModelByLabel: fast lookup map from display label → merged model entry
|
|
@@ -149,7 +149,7 @@ const require = createRequire(import.meta.url)
|
|
|
149
149
|
const readline = require('readline')
|
|
150
150
|
|
|
151
151
|
// ─── Version check ────────────────────────────────────────────────────────────
|
|
152
|
-
const pkg = require('
|
|
152
|
+
const pkg = require('../../package.json')
|
|
153
153
|
const LOCAL_VERSION = pkg.version
|
|
154
154
|
|
|
155
155
|
// 📖 sendBugReport → imported from ../src/telemetry.js
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* @see ./tool-metadata.js — source of truth for launcher modes and their CLI flags
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { getToolModeOrder, getToolMeta } from '
|
|
21
|
+
import { getToolModeOrder, getToolMeta } from '../core/tool-metadata.js'
|
|
22
22
|
|
|
23
23
|
const ANALYSIS_FLAGS = [
|
|
24
24
|
{ flag: '--best', description: 'Show only top tiers (A+, S, S+)' },
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* @see src/overlays.js
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import { TOOL_METADATA, TOOL_MODE_ORDER } from '
|
|
19
|
-
import { sources } from '
|
|
18
|
+
import { TOOL_METADATA, TOOL_MODE_ORDER } from '../core/tool-metadata.js'
|
|
19
|
+
import { sources } from '../../sources.js'
|
|
20
20
|
|
|
21
21
|
const PROVIDER_FILTER_COMMANDS = Object.entries(sources).map(([providerKey, source]) => {
|
|
22
22
|
const label = source?.name || providerKey
|
|
@@ -31,21 +31,21 @@
|
|
|
31
31
|
* @exports { buildProviderModelsUrl, parseProviderModelIds, listProviderTestModels, classifyProviderTestOutcome, buildProviderTestDetail, createKeyHandler }
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
|
-
import { loadChangelog } from '
|
|
35
|
-
import { getToolMeta, isModelCompatibleWithTool, getCompatibleTools, findSimilarCompatibleModels } from '
|
|
36
|
-
import { loadConfig, saveConfig, replaceConfigContents, getApiKey } from '
|
|
37
|
-
import { sources } from '
|
|
34
|
+
import { loadChangelog } from '../core/changelog-loader.js'
|
|
35
|
+
import { getToolMeta, isModelCompatibleWithTool, getCompatibleTools, findSimilarCompatibleModels } from '../core/tool-metadata.js'
|
|
36
|
+
import { loadConfig, saveConfig, replaceConfigContents, getApiKey } from '../core/config.js'
|
|
37
|
+
import { sources } from '../../sources.js'
|
|
38
38
|
import { join, dirname } from 'node:path'
|
|
39
39
|
import { fileURLToPath } from 'node:url'
|
|
40
40
|
import { spawn } from 'node:child_process'
|
|
41
|
-
import { cleanupLegacyProxyArtifacts } from '
|
|
41
|
+
import { cleanupLegacyProxyArtifacts } from '../core/legacy-proxy-cleanup.js'
|
|
42
42
|
import { getLastLayout, COLUMN_SORT_MAP } from './render-table.js'
|
|
43
43
|
import { cycleThemeSetting, detectActiveTheme } from './theme.js'
|
|
44
|
-
import { syncShellEnv, ensureShellRcSource, removeShellEnv } from '
|
|
44
|
+
import { syncShellEnv, ensureShellRcSource, removeShellEnv } from '../core/shell-env.js'
|
|
45
45
|
import { buildCommandPaletteTree, flattenCommandTree, filterCommandPaletteEntries } from './command-palette.js'
|
|
46
|
-
import { WIDTH_WARNING_MIN_COLS, VERDICT_CYCLE, HEALTH_CYCLE } from '
|
|
47
|
-
import { scanAllToolConfigs, softDeleteModel } from '
|
|
48
|
-
import { startExternalTool } from '
|
|
46
|
+
import { WIDTH_WARNING_MIN_COLS, VERDICT_CYCLE, HEALTH_CYCLE } from '../core/constants.js'
|
|
47
|
+
import { scanAllToolConfigs, softDeleteModel } from '../core/installed-models-manager.js'
|
|
48
|
+
import { startExternalTool } from '../core/tool-launchers.js'
|
|
49
49
|
import {
|
|
50
50
|
clearRouterDashboardRequestLog,
|
|
51
51
|
closeRouterDashboardOverlay,
|
|
@@ -54,8 +54,8 @@ import {
|
|
|
54
54
|
openRouterDashboardOverlay,
|
|
55
55
|
restartRouterDashboardDaemon,
|
|
56
56
|
toggleRouterDashboardProbePause,
|
|
57
|
-
} from '
|
|
58
|
-
import { benchmarkModel } from '
|
|
57
|
+
} from '../core/router-dashboard.js'
|
|
58
|
+
import { benchmarkModel } from '../core/benchmark.js'
|
|
59
59
|
|
|
60
60
|
// 📖 Some providers need an explicit probe model because the first catalog entry
|
|
61
61
|
// 📖 is not guaranteed to be accepted by their chat endpoint.
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
* @see ./key-handler.js — handles keypresses for all overlay interactions
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { loadChangelog } from '
|
|
22
|
+
import { loadChangelog } from '../core/changelog-loader.js'
|
|
23
23
|
import { buildCliHelpLines } from './cli-help.js'
|
|
24
|
-
import { renderRouterDashboard as renderRouterDashboardOverlay } from '
|
|
24
|
+
import { renderRouterDashboard as renderRouterDashboardOverlay } from '../core/router-dashboard.js'
|
|
25
25
|
import { themeColors, getThemeStatusLabel, getProviderRgb } from './theme.js'
|
|
26
26
|
|
|
27
27
|
export function createOverlayRenderers(state, deps) {
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
*/
|
|
48
48
|
|
|
49
49
|
import chalk from 'chalk'
|
|
50
|
-
import { OVERLAY_PANEL_WIDTH, TABLE_FIXED_LINES, TABLE_HEADER_LINES, TABLE_FOOTER_LINES } from '
|
|
51
|
-
import { sortResults } from '
|
|
50
|
+
import { OVERLAY_PANEL_WIDTH, TABLE_FIXED_LINES, TABLE_HEADER_LINES, TABLE_FOOTER_LINES } from '../core/constants.js'
|
|
51
|
+
import { sortResults } from '../core/utils.js'
|
|
52
52
|
|
|
53
53
|
// 📖 stripAnsi: Remove ANSI color/control sequences to estimate visible text width before padding.
|
|
54
54
|
// 📖 Strips CSI sequences (SGR colors) and OSC sequences (hyperlinks).
|