- scripts/docs/gen-openapi-module.mjs (new): build helper that loads
docs/reference/openapi.yaml via js-yaml, flattens paths × methods, and
emits src/app/docs/lib/openapi.generated.ts with strongly-typed
OPENAPI_ENDPOINTS, OPENAPI_TAGS, OPENAPI_VERSION, OPENAPI_TITLE plus
the OpenApiEndpoint interface (no `any`, deterministic ordering).
By default it skips internal management paths (anything under /api/
that isn't /api/v1/*) so the Api Explorer focuses on the OpenAI-
compatible public surface — 19 endpoints for v3.8.0 (Chat, Messages,
Responses, Embeddings, Images, Audio, Moderations, Rerank, Models,
System). Add --include-management to emit all 121 paths if needed.
- src/app/docs/components/ApiExplorerClient.tsx: drop the 13-entry
hardcoded API_ENDPOINTS array; the component now imports from
@/app/docs/lib/openapi.generated. Tags come from the spec; the
"Try It" form picks an example body keyed by full path (8 well-known
bodies pre-seeded, everything else starts empty). The header pill
now shows endpoint count + OpenAPI version, and an "auth" pill is
rendered next to operations whose spec declares non-empty security.
- package.json: prebuild:docs now chains gen-openapi-module after the
docs index generator so `next build` always sees a fresh module.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Every .md under docs/{architecture,guides,reference,frameworks,routing,
security,compression,ops,diagrams} plus docs/README.md now opens with:
---
title: "<inferred from first H1>"
version: 3.8.0
lastUpdated: 2026-05-13
---
46 files updated (no docs were skipped — none had pre-existing
frontmatter). [slug]/page.tsx already reads frontmatter.version and
frontmatter.lastUpdated via gray-matter and renders a "v3.8.0" pill
plus a "Last updated" caption, so the UI picks these up automatically.
Helper: scripts/docs/add-frontmatter.mjs — idempotent (skips files that
already start with `---`), falls back to a humanized basename when no
leading H1 exists. Excludes docs/i18n/, docs/screenshots/,
docs/superpowers/, docs/diagrams/exported/. Re-runnable safely.
Also regenerated src/app/docs/lib/docs-auto-generated.ts: 44 docs across
8 sections (Architecture / Guides / Reference / Frameworks / Routing /
Security / Compression / Ops), which now includes the 14 docs that were
missing from the v3.7 sidebar (Cloud Agents, Guardrails, Memory, Skills,
Webhooks, Evals, Authz, Agent Protocols, Repository Map, Provider
Reference, Reasoning Replay, Stealth Guide, Tunnels Guide, Electron
Guide).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ARCHITECTURE.md and CODEBASE_DOCUMENTATION.md: 179 → 177 registered
providers (canonical from src/shared/constants/providers.ts).
- FEATURES.md and en.json wizard step: 13 → 14 routing strategies; lists
all 14 explicitly including reset-aware (the missing one).
- llm.txt root: combo strategy count corrected in 3 places (UI tree,
dashboard summary, fallback semantics).
- MCP-SERVER.md: 37 tool count was already correct; added a "Related
Frameworks (v3.8.0)" section pointing to Cloud Agents
(docs/frameworks/CLOUD_AGENT.md) and Guardrails
(docs/security/GUARDRAILS.md), both sibling frameworks intentionally
outside the MCP tool catalog.
- scripts/i18n/sync-llm-mirrors.mjs (new): idempotent helper to push
root llm.txt body into the 40 docs/i18n/<locale>/llm.txt mirrors
while preserving each locale's heading + language bar prefix; ran
it to refresh all 40 mirrors so `check:docs-sync` is green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reads the current request locale via `getLocale()` from next-intl and
prefers a translated markdown copy under
`docs/i18n/<locale>/docs/<fileName>` when one exists. Falls back to
the English source otherwise, so locales with partial coverage stay
readable instead of 404ing.
Path resolution is hardened: every read is resolved against an
absolute docs root and verified to live inside it, so a stray
filename in the docs index cannot escape the directory.
This is the runtime counterpart to the DocsI18n removal: the locale
preference set by the shared LanguageSelector in the docs layout now
materially affects what content the page renders.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The cosmetic DocsI18n.tsx shim duplicated the locale catalog that
already lives in config/i18n.json and consumed it through a separate
client hook (useDocsLocale + a 10-entry hard-coded SECTION_LABELS
map). It only ever translated sidebar section titles — the docs
content itself was always English.
Now the /docs page uses the same `LanguageSelector` component as the
rest of the dashboard, backed by next-intl + config/i18n.json. The
locale cookie set there is consumed by the [slug] page server
component (next commit) to actually serve translated markdown.
Removed:
- src/app/docs/components/DocsI18n.tsx (203 lines)
Updated:
- src/app/docs/layout.tsx — swaps DocsLocaleSwitcher for the shared
LanguageSelector
- tests/unit/docs-site-overhaul.test.ts — replaces the DocsI18n
importability assertions with checks that (a) the shared next-intl
config covers the same locales, (b) the global LanguageSelector
is the new docs switcher, and (c) the DocsI18n module is gone.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ran `npm run i18n:sync-ui` against every non-English locale to
replicate the full key tree from `src/i18n/messages/en.json`. Missing
strings now show up as `__MISSING__:<english_value>` placeholders,
which:
- keep the catalogs the same shape as the source-of-truth, so a
runtime `useTranslations('feature.x')` call no longer falls back
to the English bundle for every drifted key;
- are visible to reviewers (and to the optional `--translate-markers`
pass in sync-ui-keys.mjs) so the drift can be paid down
incrementally.
Volume summary (40 locales):
- 25,234 placeholders inserted in total
- zh-CN closest to parity (+105)
- most European/Asian locales (+710)
- pt-BR slightly ahead (+589)
- bn/fa/gu/in/mr/sw/ta/te/ur (+445)
No existing translated strings were touched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
src/i18n/config.ts is now a thin adapter that reads config/i18n.json
(canonical locale list) and exports the same shape — LOCALES, LANGUAGES,
RTL_LOCALES, DEFAULT_LOCALE, Locale type, LOCALE_COOKIE — that
LanguageSelector, layout.tsx, request.ts, and the rest of the codebase
already consume. No call-site changes were required. Adds
DOCS_TARGET_LOCALES and getLanguage() helpers for new code.
The legacy scripts now print a deprecation warning on stderr at startup:
- scripts/i18n/i18n_autotranslate.py (banner + module-level warn)
- scripts/i18n/generate-multilang.mjs (banner + console.warn)
They keep working for messages and readme modes (UI strings / root README
variants), which are still outside the new pipeline's scope. Both will be
removed in v3.10.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reorganizes /docs into 8 subfolders (architecture, guides, reference, frameworks,
routing, security, compression, ops). Resolves two conflicts:
- scripts/docs/gen-provider-reference.ts: combined FASE 1's new __dirname-based
ROOT (two levels up from scripts/docs/) with FASE 3's new output path
(docs/reference/PROVIDER_REFERENCE.md).
- scripts/check-env-doc-sync.mjs: deleted by FASE 1, modified by FASE 3; FASE 1's
delete wins (file is at scripts/check/ now). The FASE 3 intent (point to
docs/reference/ENVIRONMENT.md) was applied to the strict checker at the new path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves conflict in scripts/check/check-env-doc-sync.mjs (FASE 1 moved it from scripts/ to scripts/check/, FASE 2 modified it at the old path). Applies FASE 2's strict checker version at the new path, fixes __dirname-based REPO_ROOT to traverse two levels up, and updates the unit test import to the new path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- src/app/docs/lib/docs-auto-generated.ts is regenerated from docs/<sub>/ with
fileName values like "architecture/ARCHITECTURE.md". The dynamic slug page
joins these against process.cwd()/docs so resolution still works.
- src/app/api/openapi/spec/route.ts now looks for the spec at
docs/reference/openapi.yaml first, with the flat-path fallback retained for
older bundles.
- tests updated: integration-wiring expects docs/reference/{API_REFERENCE.md,
openapi.yaml}; docs-site-overhaul reflects the new 8-section nav titles
(Architecture, Guides, Reference, Frameworks, Routing, Security, Compression,
Ops) and the new section for setup-guide ("Guides").
- open-sse/mcp-server/README.md picks up the rewritten docs/ reference.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Centralizes a handful of hardcoded URLs, fetch timeouts, and circuit-breaker
constants behind opt-in environment variables. Behavior is unchanged when
the variables are unset because every call site keeps its current default.
- open-sse/services/usage.ts: extracts CROF_USAGE_URL,
GEMINI_CLI_USAGE_URL, CODEWHISPERER_BASE_URL constants backed by
OMNIROUTE_CROF_USAGE_URL, OMNIROUTE_GEMINI_CLI_USAGE_URL, and
OMNIROUTE_CODEWHISPERER_BASE_URL. Lets operators redirect quota probes
through corporate mirrors or a test fixture.
- open-sse/config/constants.ts: PROVIDER_PROFILES circuit-breaker
thresholds and reset timeouts now honor OMNIROUTE_CIRCUIT_BREAKER_*
env vars (oauth/api-key/local) with the same defaults as before.
- src/shared/utils/fetchTimeout.ts: DEFAULT_TIMEOUT_MS reads
OMNIROUTE_DEFAULT_FETCH_TIMEOUT_MS (fallback 120000) so deployments can
raise the global fallback without changing FETCH_TIMEOUT_MS semantics.
- open-sse/services/chatgptTlsClient.ts: DEFAULT_TIMEOUT_MS and
HARD_TIMEOUT_GRACE_MS now honor OMNIROUTE_CHATGPT_TLS_TIMEOUT_MS and
OMNIROUTE_CHATGPT_TLS_GRACE_MS (defaults 60000 / 10000).
- .env.example: documents the 11 new variables in the URLs and TIMEOUT
sections.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Refresh the v3.8.0 documentation set across API, setup, Docker,
environment, Fly.io, VM deployment, and troubleshooting guides.
Document the updated budget payload, management-auth requirements,
WebSocket bridge secret, Compose profiles, production deployment
details, and expanded Node support. Also update the OpenAPI catalog,
raise coverage thresholds to match the current baseline, and align
cloud-agent task route typing and schemas with the stricter runtime
behavior.
Centralize optional API key capability checks so dashboard forms and
provider schemas share the same rules, including keyless Pollinations
support and cloud-agent batch testing mode.
Also align auto-combo config on `routerStrategy`, keep legacy combo
reads compatible, preserve MCP routes as management APIs, narrow
`require-login` public access to readonly/bootstrap flows, and make
cloud-agent CORS reflect the request origin for credentialed requests.
Protect cloud agent task routes and model cooldown management endpoints
with management-session auth and consistent CORS handling.
Also align cloud agent API serialization with the dashboard, reuse the
provider connection schema for CLI key storage, and accept active OAuth
tokens when building virtual auto-combo candidates.
Integrated into release/v3.8.0 after syncing the contributor branch, removing unrelated workflow/package-lock changes, and validating Command Code provider, auth, validation, and Responses coverage locally.
Integrated into release/v3.8.0 after syncing the contributor branch, removing unrelated workflow/docker/package-lock changes, and validating provider-scoped models coverage locally.
Integrated into release/v3.8.0 after syncing the contributor branch, removing unrelated dependency churn, and validating executor/default URL coverage locally.
Integrated into release/v3.8.0 — adds target-based metadata aggregation for combo entries in /v1/models using least-common-denominator approach (context_length, max_output_tokens, capabilities, modalities).
Integrated into release/v3.8.0 — allows optional-key providers (SearXNG, Petals, self-hosted chat, OpenAI/Anthropic-compatible) to pass connection test by centralizing the check in providerAllowsOptionalApiKey().
Integrated into release/v3.8.0 — removes .ts import extensions, replaces as any casts with proper types, and normalizes provider alias resolution in combo context_length calculation.
## OAuth (browser PKCE)
- **`poll-callback`**: generalise from codex-only to all
`PKCE_CALLBACK_PROVIDERS` (codex, windsurf, devin-cli); state slot
is now dynamic (`__codexCallbackState` vs `__windsurfCallbackState`)
- **`OAuthModal`**: replace the codex-specific callback-server block
with a shared `PKCE_CALLBACK_SERVER_PROVIDERS` branch covering all
three providers; same start-callback-server + poll-callback polling
loop, same 2-second interval, same 5-minute timeout
- **`OAuthModal` redirect URI fallback**: windsurf/devin-cli now use
`http://localhost:{port}/auth/callback` (correct path) instead of
the generic `/callback` on non-true-localhost
- **`/auth/callback` page**: new Next.js route (`src/app/auth/callback`)
that re-exports `/callback/page`; Windsurf redirects to `/auth/callback`
so the popup auto-completes without manual URL paste (postMessage +
BroadcastChannel + localStorage)
## API-token (WINDSURF_API_KEY / paste-token)
- **`route.ts` — `import-token` action**: new POST action for
`IMPORT_TOKEN_PROVIDERS` (windsurf, devin-cli); calls
`provider.mapTokens({ accessToken: token })` skipping the HTTP
exchange and creating the connection directly
- **`oauthImportTokenSchema`**: Zod schema `{ token, connectionId? }`
- **`OAuthModal` — "Paste API Key" tab**: tab-switcher UI for
windsurf/devin-cli; sends `POST /import-token`; errors shown inline
## Security: remove hardcoded Firebase API key (GH secret alert)
- `AIzaSyBpLTEGSt59AUPKxBb7lIWjSE2ZXQH7mgU` removed from both
`oauth.ts` and `tokenRefresh.ts`; code now reads only
`process.env.WINDSURF_FIREBASE_API_KEY`
- Added `WINDSURF_FIREBASE_API_KEY` to `.env.example` with the
public key value and an explanation that it is a client-side
credential embedded in the Windsurf app (not a secret)
- `tokenRefresh.ts`: graceful `return null` with warn log when
key is absent (import tokens are long-lived and skip refresh anyway)
## Docs
- Sync 40 i18n CHANGELOG mirrors to v3.8.0 root content
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Update Pollinations request transformation to send the selected model
and stream flag so requests match the active endpoint behavior.
Align the ChatGPT TLS client with shared proxy resolution so dashboard
proxy context is honored before falling back to environment settings.
Also refresh provider display names across dashboard pages, correct the
Claude extra-usage toggle messaging and visual state, and mark
Pollinations as offering a free public endpoint.
Adds two providers for Windsurf/Devin CLI access:
**`devin-cli`** — official path via ACP JSON-RPC over stdio
- Spawns `devin acp --agent-type summarizer` as a subprocess
- Full streaming via session/update notifications
- Auth: WINDSURF_API_KEY env var or `devin auth login` stored creds
- Binary auto-discovered: %LOCALAPPDATA%\devin\cli\bin\devin.exe (Win),
~/.local/share/devin/bin/devin (Linux), PATH fallback
- Model IDs verified from model_configs_v2.bin in Devin CLI binary
(swe-1.6-fast, claude-opus-4.7-max, gpt-5.5-high, gemini-3.1-pro-high, etc.)
**`windsurf`** — direct gRPC-web fallback (no binary needed)
- Calls server.self-serve.windsurf.com directly via gRPC-web+proto
- Auth: token from windsurf.com/show-auth-token
- MODEL_ALIAS_MAP dot-to-dash normalisation for all 100+ catalog models
Supporting changes:
- cliRuntime.ts: add `devin` to CLI_TOOLS with Windows/Linux binary paths
- tokenRefresh.ts: Firebase STS refresh for devin-cli + windsurf
- oauth providers: windsurf + devin-cli (token import / device-code)
- providerRegistry: full model list from CLI binary (GPT-5.5, GPT-5.4,
GPT-5.3-Codex, Claude Opus 4.7, SWE-1.6, DeepSeek V4, Kimi K2.6, etc.)
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>