{"_id":"@bytonylee/free-router","_rev":"2-bc6192cc3fe394e596dcd5ffb49e153c","name":"@bytonylee/free-router","dist-tags":{"latest":"1.2.1"},"versions":{"1.2.0":{"name":"@bytonylee/free-router","version":"1.2.0","keywords":["ai","cli","tui","free-models","openrouter","nvidia","nim","opencode","openclaw","llm","free-api"],"author":{"name":"Tony Lee"},"license":"MIT","_id":"@bytonylee/free-router@1.2.0","maintainers":[{"name":"jyoung105","email":"jeongmin1604@gmail.com"}],"homepage":"https://github.com/bytonylee/free-router#readme","bugs":{"url":"https://github.com/bytonylee/free-router/issues"},"bin":{"free-router":"dist/bin/free-router.js"},"dist":{"shasum":"f6fc9fee4085ed9140f7b5f4308fbc2c8fce4b9e","tarball":"https://registry.npmjs.org/@bytonylee/free-router/-/free-router-1.2.0.tgz","fileCount":19,"integrity":"sha512-ULR0N1OZMAR3pvd0zz4PcfJM1zeBvWJAf/3T0L06KGeuixNUWvaU6LYFYV2wbeSq/cFb/jbxSGPbqGu4h9ueyg==","signatures":[{"sig":"MEUCIQDenDBnbnivGyE2cxikQvrawC+P7XDpNZI7HT+DnswkHQIgMzcrnJEX+NAWzJv85N6tybRqbJLpalEq5XugPswBQFo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":249060},"type":"module","engines":{"node":">=22.0.0"},"gitHead":"b21b14d7d9661fd6be717c97d7686bdcef845cca","scripts":{"lint":"eslint src --max-warnings=0","build":"tsc -p tsconfig.json && cp data/model-rankings.json data/model-support.json dist/","prepack":"npm run build","lint:fix":"eslint src --fix","typecheck":"tsc -p tsconfig.json --noEmit","models:sync":"npx tsx scripts/update-models.ts","models:sync:apply":"npx tsx scripts/update-models.ts --apply"},"_npmUser":{"name":"jyoung105","email":"jeongmin1604@gmail.com"},"repository":{"url":"git+https://github.com/bytonylee/free-router.git","type":"git"},"_npmVersion":"11.11.0","description":"Free model router — discover, ping, and configure free AI models for OpenCode / OpenClaw","directories":{},"_nodeVersion":"25.8.1","dependencies":{"ink":"^7.0.1","react":"^19.2.5","@inkjs/ui":"^2.0.0"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.5","devDependencies":{"eslint":"^10.2.1","globals":"^17.5.0","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^25.6.0","@types/react":"^19.2.14","typescript-eslint":"^8.59.0"},"_npmOperationalInternal":{"tmp":"tmp/free-router_1.2.0_1777387259185_0.03850880811592283","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@bytonylee/free-router","version":"1.2.1","description":"Free model router — discover, ping, and configure free AI models for OpenCode / OpenClaw","bin":{"free-router":"dist/bin/free-router.js"},"type":"module","packageManager":"bun@1.3.5","scripts":{"build":"tsc -p tsconfig.json && cp data/model-rankings.json data/model-support.json dist/","typecheck":"tsc -p tsconfig.json --noEmit","lint":"eslint src --max-warnings=0","lint:fix":"eslint src --fix","models:sync":"npx tsx scripts/update-models.ts","models:sync:apply":"npx tsx scripts/update-models.ts --apply","prepack":"npm run build"},"engines":{"node":">=22.0.0"},"repository":{"type":"git","url":"git+https://github.com/bytonylee/free-router.git"},"homepage":"https://github.com/bytonylee/free-router#readme","author":{"name":"Tony Lee"},"keywords":["ai","cli","tui","free-models","openrouter","nvidia","nim","opencode","openclaw","llm","free-api"],"license":"MIT","dependencies":{"ink":"^7.0.1","react":"^19.2.5"},"devDependencies":{"@types/react":"^19.2.14","@eslint/js":"^10.0.1","@types/node":"^25.6.0","eslint":"^10.2.1","globals":"^17.5.0","typescript":"^6.0.3","typescript-eslint":"^8.59.0"},"gitHead":"d677d39b8ef23eba7d40c9a2e9700df35a548066","_id":"@bytonylee/free-router@1.2.1","bugs":{"url":"https://github.com/bytonylee/free-router/issues"},"_nodeVersion":"25.8.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-cw9vhbyPD3DL2QmXV2R1USCmZQoqmm1BBo8y4CwEB6Yv0FNe6uRwg+uhSV7uXhFc5TSpn/UU9HDr3TjOfdZ1mA==","shasum":"56148bd02d939cbb9f5f94fbc5f7b8ac14eab1d3","tarball":"https://registry.npmjs.org/@bytonylee/free-router/-/free-router-1.2.1.tgz","fileCount":19,"unpackedSize":252171,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD/NJAlxhgedN14+KSc7klkEfDPW+BMazKbx4chOBWOSQIhALS5mmjnU7PxSIs7VFBAlzRBNzC9gail2eSPpqzUGhDG"}]},"_npmUser":{"name":"jyoung105","email":"jeongmin1604@gmail.com"},"directories":{},"maintainers":[{"name":"jyoung105","email":"jeongmin1604@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/free-router_1.2.1_1777402952146_0.07933741906817038"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-28T14:40:58.981Z","modified":"2026-04-28T19:02:32.503Z","1.2.0":"2026-04-28T14:40:59.319Z","1.2.1":"2026-04-28T19:02:32.386Z"},"bugs":{"url":"https://github.com/bytonylee/free-router/issues"},"author":{"name":"Tony Lee"},"license":"MIT","homepage":"https://github.com/bytonylee/free-router#readme","keywords":["ai","cli","tui","free-models","openrouter","nvidia","nim","opencode","openclaw","llm","free-api"],"repository":{"type":"git","url":"git+https://github.com/bytonylee/free-router.git"},"description":"Free model router — discover, ping, and configure free AI models for OpenCode / OpenClaw","maintainers":[{"name":"jyoung105","email":"jeongmin1604@gmail.com"}],"readme":"[English](./README.md) | [한국어](./README.ko.md)\n\n![Version](https://img.shields.io/badge/version-1.2.1-333333?style=flat-square)\n[![License: MIT License](https://img.shields.io/badge/License-MIT%20License-yellow.svg)](./LICENSE)\n[![npm downloads](https://img.shields.io/npm/dm/%40bytonylee%2Ffree-router)](https://www.npmjs.com/package/@bytonylee/free-router)\n[![CI](https://github.com/bytonylee/free-router/actions/workflows/ci.yml/badge.svg)](https://github.com/bytonylee/free-router/actions/workflows/ci.yml)\n\nFree model router CLI - discover, ping, and configure free AI models for OpenCode / OpenClaw.\n\n![free-router-gif](./public/example.gif)\n\n## Install\n\n```bash\nnpx @bytonylee/free-router\n# or\nnpm i -g @bytonylee/free-router\n# or\nbunx @bytonylee/free-router\n# or\nbun install -g @bytonylee/free-router\n```\n\n## Run\n\n```bash\nfree-router\n```\n\nOn first run, a setup wizard prompts for API keys (ESC to skip any provider).\n\nIf you accept the in-app update prompt (`Y`), free-router now updates globally and\nrestarts automatically, so you can continue without running `free-router` again.\n\n## Ways to use free-router\n\n1. **First-run onboarding wizard**\n   Launch `free-router`, open provider websites in-browser from the wizard, paste keys, and start.\n2. **Interactive model search + launch**\n   Use `/` to filter models, then `Enter` to update OpenCode config and open `opencode`.\n3. **Quick API key rescue from main screen**\n   Press `A` (or `R` for expired/missing provider) to jump into key editing with auto browser opening for missing keys.\n4. **Full settings workflow**\n   Press `P` to edit keys, toggle providers, run live key tests, and onboard missing keys provider-by-provider.\n5. **Non-interactive best-model selection**\n   Run `free-router --best` to print the best responding model ID for scripts.\n\n## Providers\n\n| Provider       | Free key                                                                             |\n| -------------- | ------------------------------------------------------------------------------------ |\n| **NVIDIA NIM** | [build.nvidia.com](https://build.nvidia.com/settings/api-keys) - prefix `nvapi-`     |\n| **OpenRouter** | [openrouter.ai/settings/keys](https://openrouter.ai/settings/keys) - prefix `sk-or-` |\n\nAPI key priority: environment variable → `~/.free-router.json` → keyless ping (latency still shown).\n\n```bash\nNVIDIA_API_KEY=nvapi-xxx free-router\nOPENROUTER_API_KEY=sk-or-xxx free-router\n\n# Optional: pause auto re-sorting while you scroll (milliseconds)\nFREE_ROUTER_SCROLL_SORT_PAUSE_MS=2500 free-router\n\n# Optional: disable rolling metrics cache and force legacy recompute path\nFREE_ROUTER_METRICS_CACHE=0 free-router\n```\n\n## TUI\n\nThe interactive TUI pings all models in parallel every 2 seconds and shows live latency, uptime, and verdict.\nThe selected row uses a stable marker, and redraws are deferred while the terminal is unfocused to avoid background-tab blinking.\n\n### Columns\n\n| Column     | Description                                                    |\n| ---------- | -------------------------------------------------------------- |\n| `#`        | Rank                                                           |\n| `Tier`     | Capability tier derived from SWE-bench score (S+ → C)          |\n| `Provider` | NIM or OpenRouter                                              |\n| `Model`    | Display name                                                   |\n| `Ctx`      | Context window size                                            |\n| `AA`       | Arena Elo / intelligence score                                 |\n| `Avg`      | Rolling average latency (HTTP 200 only)                        |\n| `Lat`      | Latest measured ping latency                                   |\n| `Up%`      | Uptime percentage this session                                 |\n| `Verdict`  | Condition summary (✓ Perfect / ✓ Normal / x Overloaded / …)    |\n\nDefault ranking: **availability first**, then **higher tier first** (S+ → S → A+ …), then lower latency.\n\nSearch bar provider badges:\n\n- `Name:✓` key exists and looks healthy\n- `Name:✗` provider appears expired/no-auth\n- `Name:○` key missing\n\nThe `?` help overlay and `A` API-key editor use the same terminal header/footer\nchrome as the main list. Their mode tags stay left-aligned, and help body text\nuses the same foreground color as the table rows.\n\n### Keyboard shortcuts\n\n**Navigation**\n\n| Key             | Action         |\n| --------------- | -------------- |\n| `↑` / `k`       | Move up        |\n| `↓` / `j`       | Move down      |\n| `PgUp` / `PgDn` | Page up / down |\n| `g`             | Jump to top    |\n| `G`             | Jump to bottom |\n\n**Actions**\n\n| Key            | Action                                                     |\n| -------------- | ---------------------------------------------------------- |\n| `Enter`        | Save config + open current model in `opencode`             |\n| `/`            | Search / filter models (Enter in search = open `opencode`) |\n| `A`            | Quick API key add/change (opens key editor in Settings)    |\n| `R`            | Edit API key for likely expired/missing provider           |\n| `T`            | Cycle tier filter: All → S+ → S → A+ → …                   |\n| `P`            | Settings screen (edit keys, toggle providers, test)        |\n| `W` / `X`      | Faster / slower ping interval                              |\n| `?`            | Help overlay                                               |\n| `q` / `Ctrl+C` | Quit                                                       |\n\n**Sort** (press to sort, press again to reverse)\n\n| Key | Column             |\n| --- | ------------------ |\n| `0` | Priority (default) |\n| `1` | Tier               |\n| `2` | Provider           |\n| `3` | Model name         |\n| `4` | Avg latency        |\n| `5` | Latest ping        |\n| `6` | Uptime %           |\n| `7` | Context window     |\n| `8` | Verdict            |\n| `9` | AA Intelligence    |\n\n### OpenCode handoff\n\nPressing `Enter` on a model writes the OpenCode config and immediately opens `opencode`.\n\nIf OpenCode fallback remaps the provider (for example NIM Stepfun → OpenRouter)\nand the effective provider key is missing, free-router asks:\n`Add API key now? (Y/n, default: Y)`.\n\nIf model metadata says the selected model is unsupported by the known target\nsupport list, free-router falls back to NVIDIA NIM `deepseek-ai/deepseek-v4-pro`\nas the default high-performance model.\n\nConfigs written:\n\n- **OpenCode CLI** → `~/.config/opencode/opencode.json`\n- **OpenClaw** → `~/.openclaw/openclaw.json`\n\nExisting configs are backed up before writing.\n\nWhen free-router launches OpenCode, it now sets `OPENCODE_CLI_RUN_MODE=true`\nby default (unless you already set it) to reduce startup log noise from\nplugin auto-update checks in the OpenCode TUI.\n\nIf you want OpenCode's default startup hook behavior instead, launch free-router with:\n\n```bash\nOPENCODE_CLI_RUN_MODE=false free-router\n```\n\n### Settings screen (`P`)\n\nTip: press `A` from the main list to jump directly into API key editing.\nTip: if a selected provider has no key, free-router auto-opens that provider key page\nin browser (once per provider per settings session), including when you move selection.\n\n| Key                   | Action                             |\n| --------------------- | ---------------------------------- |\n| `↑` / `↓` / `j` / `k` | Navigate providers                 |\n| `Enter`               | Edit API key inline                |\n| `Space`               | Toggle provider enabled / disabled |\n| `T`                   | Fire a live test ping              |\n| `D`                   | Delete key for this provider       |\n| `ESC`                 | Back to main list                  |\n\n## Flags\n\n| Flag            | Behavior                                                      |\n| --------------- | ------------------------------------------------------------- |\n| _(none)_        | Interactive TUI                                               |\n| `--best`        | Non-interactive: ping 4 rounds, print best model ID to stdout |\n| `--help` / `-h` | Show help                                                     |\n\n### `--best` scripted usage\n\n```bash\n# Print best model ID after ~10 s analysis\nfree-router --best\n\n# Capture in a variable\nMODEL=$(free-router --best)\necho \"Best model: $MODEL\"\n```\n\nRequires at least one API key to be configured. Selection tri-key sort: status=up → lowest avg latency → highest uptime.\n\n## Config\n\nStored at `~/.free-router.json` (permissions `0600`).\n\n```json\n{\n  \"apiKeys\": {\n    \"nvidia\": \"nvapi-xxx\",\n    \"openrouter\": \"sk-or-xxx\"\n  },\n  \"providers\": {\n    \"nvidia\": { \"enabled\": true },\n    \"openrouter\": { \"enabled\": true }\n  },\n  \"ui\": {\n    \"scrollSortPauseMs\": 1500\n  }\n}\n```\n\n`ui.scrollSortPauseMs` sets how long (ms) auto re-sorting stays paused after navigation input.\n`FREE_ROUTER_SCROLL_SORT_PAUSE_MS` overrides config. Set to `0` to disable pause.\n\n## Tier scale (SWE-bench Verified)\n\n| Tier   | Score  | Description        |\n| ------ | ------ | ------------------ |\n| **S+** | ≥ 70%  | Elite frontier     |\n| **S**  | 60–70% | Excellent          |\n| **A+** | 50–60% | Great              |\n| **A**  | 40–50% | Good               |\n| **A-** | 35–40% | Decent             |\n| **B+** | 30–35% | Average            |\n| **B**  | 20–30% | Below average      |\n| **C**  | < 20%  | Lightweight / edge |\n\n## Verdict legend\n\n| Verdict      | Trigger                   |\n| ------------ | ------------------------- |\n| x Overloaded | Last HTTP code = 429      |\n| x Unstable   | Was up, now failing       |\n| x Not Active | Never responded           |\n| - Pending    | Waiting for first success |\n| ✓ Perfect    | Avg < 400 ms              |\n| ✓ Normal     | Avg < 1000 ms             |\n| x Slow       | Avg < 3000 ms             |\n| x Very Slow  | Avg < 5000 ms             |\n| x Unusable   | Avg ≥ 5000 ms             |\n\n## Development notes\n\n- TypeScript source of truth: `src/`\n- ESLint config is TypeScript: `eslint.config.ts`\n- Runtime JS output is generated only in `dist/` via `npm run build`\n\n## License\n\nMIT License. See [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}