Skip to content

Releases: vibecoder11200/9router

v0.6.57

Choose a tag to compare

@github-actions github-actions released this 01 Oct 12:08

Full Changelog: v0.6.56...v0.6.57

v0.6.56

Choose a tag to compare

@github-actions github-actions released this 30 Sep 05:40

Full Changelog: v0.6.55...v0.6.56

v0.6.55

Choose a tag to compare

@github-actions github-actions released this 28 Sep 19:01

Full Changelog: v0.6.54...v0.6.55

v0.6.54

Choose a tag to compare

@github-actions github-actions released this 28 Sep 13:11

v0.6.54 (2026-09-28)

Two usage-dashboard fixes: the live topology now lights up for noAuth/free providers, and the By Provider / Top Models breakdown charts render correctly in both themes.

Fixed — topology live animation never lit for free/noAuth providers

  • getActiveRequests() derived activeRequests only from pendingRequests.byAccount, and pending tracking only populates byAccount when the request carries a connectionId — so live requests to connection-less (noAuth/free) providers never reached the SSE stream and the usage topology stayed dark for exactly those providers. Same behavior since upstream 0.4.x.
  • Connection-less pending requests are now surfaced from byModel with a Free (no connection) account label. Regression-tested (tests/unit/usage-active-requests.test.js, fails 3/3 without the fix) and verified E2E against a live server: a real oc/mimo-v2.5-free stream went from an always-empty activeRequests to a lit electric edge for the whole request (0/77 → 82/82 lit DOM samples).
  • The topology's provider list was fetched once on mount, so providers added after the page loaded stayed invisible until reload — now re-polled every 60s.

Fixed — By Provider / Top Models charts vs dark & light mode

  • The Tokens/Requests segmented toggle used purged design tokens (bg-bg-subtle, bg-bg-hover) → transparent container, no hover feedback. Now the same tokens as the Tokens & Cost chart (bg-surface-2, hover:bg-black/5 dark:hover:bg-white/5).
  • Tooltip text fell back to recharts' default black (the Bar had no Bar-level fill; colors lived on per-index Cells) → invisible black-on-dark tooltip in dark mode. The tooltip now forces var(--color-text-main) for item and label, truncates the provider label at 24 chars (node ids are UUID-length), gains a proper swatch color from the Bar-level fill, and uses a theme-neutral hover cursor band (#888 @ 0.15) instead of recharts' harsh default.
  • --color-primary-foreground was referenced across the dashboard but never defined — active chips silently inherited per-theme text color (washed-out coral chips in dark mode). Now defined once (#2b1610, ~5:1 contrast on the coral #E56A4A primary in both themes), standardizing every coral chip app-wide.

v0.6.53 — Example Run works under Require-API-Key + System One auth gate fix

Choose a tag to compare

@vibecoder11200 vibecoder11200 released this 28 Sep 10:12

v0.6.53 (2026-09-28)

Makes the dashboard Example/Test Run buttons work under Require-API-Key = on — the same trusted path the provider-page Test button uses — and fixes the System One endpoint's auth gate that upstream shipped without the fork's internal-caller hardening.

Fixed — System One auth gate (upstream regression vs fork doctrine)

  • Upstream's new handleSystemone copied the old requireApiKey gate without the fork's isTrustedInternalRequest bypass (loopback + x-9r-cli-token) that every other media endpoint has — so the provider-page Test button and any internal caller got 401 Missing API key for systemone models even though they authenticate as trusted-internal. Added the canonical gate (bypass + enforceKeyBudget, matching fetch/search/stt/tts/embeddings/imageGeneration/videoGeneration/chat).

Added — internal example runner (/api/example/run)

  • The Example cards' Run button is a browser call to the public /v1/* endpoints, which Require-API-Key gates behind a client key — and since S7 the dashboard can't prefill one (masked display values only). New session-authed internal proxy replays the request against the server's own loopback listener with the CLI token, streaming the upstream response (JSON / binary / SSE) back untouched. All five example/test cards (Generic — image/video/music/imageToText/systemone, TTS, STT, Embedding, Combo detail) now:
    • No key pasted → run via the internal proxy (works regardless of Require-API-Key) — verified E2E against a live server with requireApiKey=on: oc/jev-1.13-free returns a real Jev decision.
    • RAW key pasted → still exercises the real public endpoint exactly like the curl snippet.
  • The proxy is deliberately not a general relay: POST only, exact-path whitelist from MEDIA_PROVIDER_KINDS, target always this process's own origin, dashboard session required (proxy-enforced + explicit check). Verified: no session → 401, non-whitelisted path → 400, direct public call without key → still 401 (the gate for real off-box clients is unchanged).

v0.6.52 — masked-key proofing for example cards + drop NEW badges

Choose a tag to compare

@vibecoder11200 vibecoder11200 released this 28 Sep 02:29

v0.6.52 (2026-09-28)

Fork-polish release on top of the v0.5.91 sync: drops upstream's NEW badges and fixes the masked-API-key bug that broke every dashboard Example/Test "Run" button (surfaced by the new System One card).

Removed

  • NEW badges from upstream v0.5.91: sidebar Media Providers expander tag, per-kind (System One) tag, and the 9Remote tag — this fork doesn't ship promo badges.

Fixed — masked API keys never reach a credential slot (S7 follow-up)

  • All five dashboard example/test cards (Generic — image/video/music/imageToText/System One, TTS, STT, Embedding, Combo detail) prefilled their API-Key field from /api/keys, which since S7 returns the MASKED display value (sk-{id}-••••{last4}). The Run button built Authorization: Bearer sk-…••••… and the browser threw Failed to read the 'headers' property from 'RequestInit': String contains non ISO-8859-1 code point before any request was sent — every media-provider example page was affected, not just System One.
    • The prefill is gone; the key field is now a RAW-key input (empty = local mode, no Authorization header — works with Require-API-Key off, exactly like the server-side model ping's documented behavior). With Require-API-Key on, paste the raw key shown once at creation.
    • A guard rejects pasted masked values (•) with a clear message instead of the cryptic fetch crash.
  • Audited every other API-key flow that arrived with v0.5.91: the provider-page Test button and System One probe go through the server-side ping (x-9r-cli-token, S7-safe); Codex profiles take keys from ApiKeySelect (already S7-filtered); the new aggregator providers use per-connection credentials — all safe.

v0.6.51 — upstream v0.5.91 sync (OpenCode Zen, Qoder CN, aggregators, MiMo v2.6, System One, analytics)

Choose a tag to compare

@vibecoder11200 vibecoder11200 released this 27 Sep 20:32

v0.6.51 (2026-09-28)

Upstream-sync release: merges upstream v0.5.91 (79 commits, v0.5.81 → v0.5.91 — includes the v0.5.85, v0.5.86, and v0.5.91 releases). All fork subsystems preserved (xray multi-subscription + binary updates, genspark-web/ds2api/gemini-web/orcarouter/totu-ai providers, masked-key S7 plumbing, strict-proxy pools, archive encryption, key portability). Upstream README changes were skipped per fork policy — this fork keeps its own README.

Upstream highlights now in the fork

New providers & models

  • OpenCode Zen (opencode-zen, alias ocz): free-tier provider with its own executor, registry entry, usage module, and fingerprint gating.
  • Qoder CN (qoder-cn, alias qdcn): qoder.com.cn with OAuth flow, COSY protocol, and CN gateway routing; shares Qoder's executor/usage path with region-correct catalogs.
  • Aggregators: Token Harbor, dahl, atria, agnes, bai (OpenAI-compatible).
  • Claude Opus 5.5 support (spoofed CLI version bumped to 2.1.280); Codex GPT-6 Sol and Luna; Xiaomi MiMo v2.6 pro/flash/pro-ultraspeed with five account clusters (cn/sgp/ams/ru/in) and server-assisted desktop login for headless/Docker; OpenCode Go complete 40-model Go catalog with auto-fetch + family endpoint regex; Cline cline-free/* tier priced at zero; Hermes multi-role model config (delegation + auxiliary slots).

Features

  • System One: /v1/systemone decision endpoint (Jev models), sidebar + Media Providers integration with probe testing.
  • CLI tools: multiple model profiles for Codex CLI; dynamic configuration + logos for Pi, OMP, Crush, ForgeCode, Smelt, CodeWhale; Codex settings refresh after apply; existing ANTHROPIC_AUTH_TOKEN preserved when applying Claude settings.
  • Analytics/Usage: Requests mode + provider/model breakdown charts, All Time period, bounded 2-day lastUsed overlay, per-API-key usage attribution keyed by full key (team keys no longer collide), free limit resets shown/redeemed for cc accounts.
  • Model capabilities: capability metadata on /v1/models, aggregated across combo targets; vision adapter models in an ordered combos table.
  • Claude: x-claude-code-session-id forwarded on OAuth requests; client anthropic-beta flags merged + rate-limit headers forwarded; thinking text returned to OpenAI-format clients; upstream response headers propagated onto SSE/error responses.
  • i18n: React text rewrites translated via characterData mutation observer.
  • Tray: native arm64 macOS menubar binary (no Rosetta) built by scripts/buildTrayArm64.js + tray-binaries.yml CI.
  • Docker CI: release pipeline rewritten — native amd64/arm64 runners, per-platform + resolved-manifest health checks, verified manifests, workflow_dispatch republish with promote_latest opt-in, FIFO concurrency queue, tag/version validation.

Fixes

  • Command Code: raw byte-chunk replay preserves every NDJSON line under any chunk split (merged with the fork's C8/N8 peek hardening: raw-chunk happy path + fork line-replay catch path + buffer cap).
  • Providers API: POST /api/providers is O(1) and refuses silent key overwrite; capabilities catalog no longer cached per module copy; model selector filtered by active connections/noAuth.
  • Qoder: signed-request replay prevention (403/103 Duplicate request), code 110 billing blocks, upstream SSE error status preserved.
  • Gemini/STT: normalizeGeminiContents guards terminal model turns + unresponded functionCalls; live-API-only Gemini models dispatch over the Live WebSocket transport; Responses response.completed carries streamed output items and usage.
  • Translator: Claude refusal maps to content_filter with explanation; empty <think> markers no longer emitted into OpenAI content; replayed reasoning fields stripped for Groq/Mistral/Cerebras.
  • Cursor: AgentService empty turns/hangs (fold system prompts, ModelDetails, Composer/Grok thinking_delta, reject IDE execs); RTK compresses Cursor tool_result pre-translation.
  • Antigravity: drops requestType agent (false 429 RESOURCE_EXHAUSTED); weekly vs 5-hour quotas separated and deduplicated; all Hermes identity variants rewritten.
  • Hugging Face: Inference Providers router migration, expanded image catalog, STT route. Proxy pools: lossless header forwarding through Vercel/Cloudflare/Deno relays. Tailscale: enable-flow health wait capped at 20s. OAuth: Zed paste-token crash fixed + IDE auto-import.
  • OpenCode free tier: fingerprint quartet (bash/glob/grep/read) applied to every request with case-canonicalisation and response-side name restoration.

Merge notes & fork deltas on top

  • GLM-5.2 reasoning_effort restored: upstream's new exact-model capability entry for glm-5.2 (1M context) accidentally dropped thinkingEffortSupported, regressing reasoning_effort — fails upstream's own thinking-unified test. The fork re-adds the flag (keeps upstream's 1M context).
  • strictProxy semantics bridged: the fork's P1 rule (connection-scoped strict ignores env proxies) now only applies when connection-proxy fields are present; executor-level bare { strictProxy: true } (upstream's qoder anti-replay guard) honors env proxies and still refuses direct fallback after transport loss. Both the fork's proxy-fetch-strict-env (P1/P5) and upstream's qoder-proxy-replay suites pass.
  • Provider registry renumbering: fork providers moved p124–p128 → p131–p135 (upstream took p124–p130 for qoder-cn/opencode-zen/aggregators); providers/alias baselines re-snapshotted (93 providers, 117 alias tokens) — also fixes a stale genspark-web modelKeys entry shipped since v0.6.50.
  • CodexToolCard: upstream's auto-select of apiKeys[0].key on mount was kept OUT — in this fork that column holds the masked display key (S7), never a credential.
  • usageRepo byApiKey: fork's raw-key map + resolveApiKeyMeta fingerprint retained (upstream's masked-tail keying is weaker under the fork's S7 schema).
  • Docker CI adapted: upstream's new pipeline kept with the fork's image namespaces (vibecoder11200/9router Docker Hub + derived GHCR), the fork-defining-files release gate (gemini-web/ds2api), and the post-publish deploy trigger.
  • Tests: 3 fork tests adapted to upstream v0.5.91 behavior (opencode fingerprint quartet on tools assertions; image-generation pins the Codex version from the registry instead of a literal). Suite: 3627→3642 passing; no regressions vs the pre-merge Windows-local baseline.

v0.6.50 — xray multi-subscription + in-dashboard binary updates + hardening

Choose a tag to compare

@vibecoder11200 vibecoder11200 released this 23 Sep 17:28

Xray/v2go feature release: multi-subscription support and in-dashboard Xray-core binary updates, with hardened install orchestration.

Multi-subscription sync

The dashboard's V2Ray Proxy now supports multiple subscription sources (v2rayN-style), each with its own schedule and settings:

  • Subscriptions manager — add/delete subscriptions, per-sub enable toggle, sync interval (presets, custom, or manual-only), and a "keep dropped servers" retention per subscription (7 days / 24 hours / delete after sync / forever).
  • Per-subscription sync — "Sync Now" refreshes exactly one subscription; "Sync All" refreshes every enabled one. A failing subscription never blocks or wipes the others; a broken fetch (HTTP 200 with no parseable servers, or a suspiciously shrunken catalog) aborts only that subscription's sync.
  • Traffic & expiry display — subscriptions that report a subscription-userinfo header show "X GB / Y GB used" (with percentage) and expiry countdown right on their row.
  • Source badges — the server table shows which subscription(s) each server came from; the same share link in two subscriptions is stored once and badged twice.
  • Safe deletes — deleting a server from the table now tombstones it (recoverable from the new Deleted servers expander with Restore / Delete permanently); subscription syncs never resurrect a deleted server, and automatic retention cleanup never touches one. The model-filter auto-prune keeps physically deleting (never tombstones).
  • Automatic migration — the previous single "Subscription URL" setting becomes a "Default" subscription on first boot: same URL, same schedule, all existing servers kept, selected server untouched. Removing all subscriptions later does not re-create it.
  • Subscription CRUD + sync routes are local-only (localhost/CLI-token), matching the install route, since subscription URLs can contain provider tokens.

Xray-core binary updates from the dashboard

  • Update / Reinstall button (always visible) with an "Installed vX / Latest vY" badge — the latest check compares against the stable release only, so Xray-core pre-releases never trigger the update badge.
  • Version picker — lists recent releases (drafts hidden, pre-releases labeled) and supports deliberate downgrades with a confirmation step.
  • Auto-restart — if the proxy was running before an update, it restarts automatically on the new binary. If the new binary fails to start, the installer auto-rolls back to the previous version and retries, reporting honestly which version you ended up on.
  • Install integrity hardened: version tags are strictly validated before any download URL is built, installs are serialized (a second concurrent install gets a 409), and orphaned install staging directories are reaped at boot.
  • Download failures (restricted networks) surface an actionable message; the version check degrades gracefully to "unknown" instead of erroring the dashboard.

Hardening from code review + hands-on E2E testing

Found by a dedicated code-review pass and a manual browser walk against a live dev server (real subscriptions, real binary install → proxy start → stop):

  • Pre-release install confirm on fresh installs — the confirmation dialog for pre-release binaries was skipped when no binary was installed yet; it now always shows. Only the downgrade comparison still requires an installed version.
  • Rollback reports the truth — a failed update that auto-rolled back no longer leaves the failed version recorded on disk; status/APIs report the version actually running, and reinstalling that tag no longer short-circuits as "already installed".
  • Sync scheduler resilience — a transient DB error can no longer leave the auto-sync scheduler disarmed until reboot, and a queued per-subscription sync runs with its own outcome instead of replaying the previous run's error.
  • UI fixes — the "Default (inherit)" retention option actually resets to inherit mode (was a silent no-op); the version "Check" button reports the fresh result; no fake uninstallable version is offered when GitHub is unreachable; "Installed vvX" double-prefix fixed; subscription names capped at 128 chars.
  • Data hygiene — permanently deleting a server also clears its model-filter cache row (re-syncing the same link can't resurrect a stale pass/fail badge); deleting a subscription resolves inherit-mode retention against the configured global default; includeDeleted repo queries combined with other filters no longer risk a SQL parameter mismatch.

v0.6.49 — upstream v0.5.81 sync + genspark-web + xray fix

Choose a tag to compare

@vibecoder11200 vibecoder11200 released this 28 Sep 13:28

v0.6.49 (2026-09-20)

Upstream-sync release: merges upstream v0.5.81 (33 commits, v0.5.75 →
v0.5.81), merges PR #12 (genspark-web live AI Chat), and cherry-picks the
xray model-filter prune fix from PR #11. PR #11's opencode fingerprint
commits are superseded by upstream's implementation of the same gates
(better: anti-429 stable sessions, exact CLI id derivation, generic
forceStream); the fork's live-UA + catalog routing deltas are re-ported on
top. PR #13 (auto-release CI) was declined — releases stay manual.

Upstream highlights now in the fork

  • Xiaomi MiMo: MiMo Desktop support merged into xiaomi-mimo with dual
    auth (API key + Desktop/OAuth session), Preview models, encrypted-callback
    OAuth flow.
  • Claude Code: 1M-context toggle ([1m] marker) and
    CLAUDE_CODE_AUTO_COMPACT_WINDOW driven from the dashboard.
  • OpenCode / OpenCode Go: zen free-tier 403 FreeTierError and 429s
    fixed with canonical session ids (exact CLI derivation), version-gated UA
    relay, stable session per identity (LRU+TTL), decoy bash+read tools
    for both chat and Responses shapes, forceStream SSE aggregation for
    non-stream clients, Muse Free tool-choice normalization, reasoning-item
    stripping, Union Alpha via Messages API, China-region handling.
  • Kiro: underscores preserved in tool names (mcp__server__tool) and
    client names restored in responses; neutral placeholder for
    tool-result-only turns; tool-result images forwarded.
  • Stream: aborts after HTTP 200 are reported in-band (per-format error
    frames carrying a stall/disconnect message) instead of closing silently.
  • Models: DeepSeek-V4.1-Flash on DeepSeek/CodeBuddy-Intl/Ollama
    (deepseek-v4.1-flash:cloud); low..max effort levels + vision for
    DeepSeek-V4.*.
  • Command Code: images and reasoning_effort preserved on
    /alpha/generate; transient stream-error retry without fake stop chunks;
    Quota Tracker support.
  • Zed: OAuth lifecycle hardened (systemId preserved, proxy timeout
    renewed), live model resolution with error surfacing on the provider
    page.
  • Antigravity: cached thought signatures scoped to model family; Claude
    Code billing headers stripped from system prompts; Hermes identity
    sanitized.
  • Auth: an account is no longer cooled down for request-scoped 4xx
    errors; dashboard session cookie maxAge hardened.
  • Usage: DeepSeek credit balance displayed as currency credit.
  • i18n: Persian (fa) translation integrated (merged key-union with the
    fork's existing fa literals).

Features (PR #12, qkhalk) — genspark-web overhaul

  • Live AI Chat endpoint: genspark.ai retired /api/copilot/ask ("This
    feature has been retired. Please use AI Chat instead") — every chat
    request through the provider returned that notice as the assistant
    message. The executor now speaks the live AI Chat protocol: POST
    /api/agent/ask_proxy with body type ai_chat (ai_chat_model,
    ai_chat_enable_search, per-message ids, session_state mirror,
    user_s_input), including the Python TLS sidecar (curl_cffi Chrome
    impersonation) required by genspark's Cloudflare edge, full cookie-jar
    parsing (session_id + __cf_bm + c1/c2 + gslogin), Cloudflare
    cookie auto-refresh and the -search web-grounding suffix. The sidecar
    lazily bootstraps its venv (fail-open with a clear error when Python is
    unavailable).
  • Dynamic model catalog: the hardcoded 15-id list (mirroring
    genspark2api constants.go) shipped stale ids while genspark rotates its
    lineup weekly. New providers/gensparkCatalog.js mirrors the AI Chat
    selector endpoints (api/moa_models_config + api/models_config) on a
    6h background refresh that fails open to the previous snapshot. Model ids
    forward verbatim as ai_chat_model — brand-new genspark models work
    even before the catalog refreshes; MOA comma mixes accepted upstream.
  • Vector logo: icon resolution gained a per-id extension map
    (genspark-web → svg), provider-icon regexes accept .svg, and a proper
    four-point spark SVG ships as public/providers/genspark-web.svg;
    literal .png srcs across providers/media-providers/usage pages now go
    through getProviderIconSrc.

Fixes (cherry-picked from PR #11, qkhalk) — xray filter prune policy

  • The model filter no longer prunes configs whose tunnel works: the
    filter pruned ANY config whose probe failed, but a 429/403/5xx probe
    result proves the opposite of a dead config — an HTTP response traveled
    through the tunnel, so the exit is healthy and the rejection is upstream
    (shared-IP free-tier quota, fingerprint gates). Those conditions are
    transient; pruning permanently destroyed rotation inventory ("108 tested,
    0 usable" was 108 healthy tunnels misread as dead). Probe results now
    carry tunnelOk, and filterPrunePolicy.js only ever deletes
    connection-level failures (no response at all). Upstream-rejected rows
    are still recorded ok=false so rotation skips those exits and the
    fail-retry policy re-tests after the quota reset; a wiring regression
    that suppressed ALL cache rows when prune was disabled (observed on a
    649-config sweep: zero rows persisted) is fixed in the follow-up commit.
    +7 unit tests.

Merge notes

  • Conflicts resolved preserving fork behavior: opencode executor = upstream
    taken wholesale with fork deltas re-ported (live npm-resolved CLI UA +
    registry/catalog-driven responses routing); streamHandler.js = fork N7
    onFirstChunk + upstream abortMessage terminal; provider detail page =
    fork opencode deprecation badges + upstream zed live-catalog error
    surfacing; fa.json = key union (16 fork + 16 upstream keys, no
    overlap); capabilities/registry = union.
  • PR version numbers v0.6.50–52 that PR #11 carried are not used; their
    content is folded into this single release as decided.
  • README.md untouched (upstream README changes are not followed on this
    fork).

v0.6.48 — Upstream sync v0.5.75 (video generation, Kiro/Cline/Qoder fixes, Codex image models)

Choose a tag to compare

@vibecoder11200 vibecoder11200 released this 28 Sep 13:28

Upstream-sync release: merges upstream decolua/9router v0.5.75 (48 commits, v0.5.65 → v0.5.75) into the fork. Every fork subsystem preserved — v2go/Xray, proxy pools, DS2API, TOTU auto-fetch, orcarouter, encrypted backup, alerts, circuit breaker (N7/C7-C9), masked-key ping.

Upstream highlights

  • Video: OpenRouter + Vertex AI (Veo) video generation on /v1/videos/* via a provider adapter layer
  • Antigravity: weekly quota tracking + free-tier handling; OAuth refresh protected from Google anti-abuse rate limits
  • Codex: GPT Image 2.5, Flare, Sunburst image models; Unicode-property tool-schema strip; Version header restored
  • Qoder: usage reported to all clients; large attachments no longer inlined (upload via /api/v2/image/upload, context tier auto-escalates)
  • OpenCode Go: new models — glm-5.3, kimi-k3, deepseek-flash (V4.1), longcat-2.0, hy4-preview, hy3, qwen3.8-max/flash, grok-4.6, gpt-5.6-luna
  • Kiro: q.* surface always first (#3776); no top-level systemPrompt (fixes 400 REQUEST_BODY_INVALID)
  • Cline/ClinePass: live catalog; API keys no longer workos:-prefixed (fixes #2333); token refresh; {success,data} envelope unwrap
  • Claude: re-anchored cache_control capped at the 4-marker budget (no more 400 → combo failover)
  • Tools: Claude tool type defaulting scoped to requireClaudeToolType gateways (#3905)
  • Providers: stale health state cleared on re-validation (#3810/#3830); duplicate qwen removed; Airforce free models refreshed
  • Security: video/Vertex URL path-escape (SSRF) rejection; cowork-mcp-tools SSRF guard (#3783)
  • Auth: dashboard session cookie 24h maxAge
  • CLI tools: model selector grouped by provider with full-text search

Merge & verification

  • 12 conflicts resolved preserving fork behavior (streaming N7 + upstream credentials; masked-key ping + cline unwrap; opencode-go fork rewrite kept)
  • Tests: 3164 total — failing set identical to pre-merge baseline (+1 upstream node:test-styled file whose 4 assertions pass at import); 2 fork tests adapted to upstream's deliberate new behavior, no assertions weakened; 0 pass→fail regression
  • Production build (next build --webpack) passes; CLI tarball rebuilt

Full Changelog: v0.6.47...v0.6.48
Upstream changelog: https://github.com/decolua/9router/releases/tag/v0.5.75