diff --git a/.vscode/settings.json b/.vscode/settings.json index c6b72dd90d..c5699ad0fa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,30 +19,70 @@ } }, "git.ignoreLimitWarning": true, + + // ─── Performance: não seguir o symlink de node_modules criado pelas worktrees ─── + // As worktrees em .worktrees/ apontam node_modules para o checkout principal; + // sem isto a busca atravessa o symlink mesmo com node_modules excluído. + "search.followSymlinks": false, + + // ─── TypeScript server (monorepo grande: ~6,6k arquivos rastreados, Next.js 16) ─── + "typescript.tsserver.maxTsServerMemory": 4096, + "typescript.disableAutomaticTypeAcquisition": true, + "typescript.tsc.autoDetect": "off", + "npm.autoDetect": "off", + // O tsserver tem o próprio watcher (independente de files.watcherExclude). + // excludeDirectories evita que ele vigie as árvores pesadas. + "typescript.tsserver.watchOptions": { + "excludeDirectories": [ + "**/node_modules", + "**/.next", + "**/.build", + "**/dist", + "**/coverage", + "**/.worktrees" + ] + }, + + // Para esconder os diretórios gerados da árvore do Explorer, descomente: // "files.exclude": { + // "**/.worktrees": true, + // "**/coverage": true, + // "**/dist": true, + // "**/.build": true, + // "**/.next": true, // "**/_references": true, // "**/_mono_repo": true, - // "**/electron": true, - // "**/node_modules": true, - // "**/.next": true, - // "**/coverage": true, - // "**/omniroute-*.tgz": true, - // "**/_tasks": true + // "**/_tasks": true, + // "**/omniroute-*.tgz": true // }, "files.watcherExclude": { - "**/_references/**": true, - "**/_mono_repo/**": true, - "**/electron/**": true, + "**/.git/objects/**": true, + "**/.git/subtree-cache/**": true, "**/node_modules/**": true, "**/.next/**": true, - "**/coverage/**": true, - "**/_tasks/**": true, - "**/.git/objects/**": true, + "**/.build/**": true, "**/dist/**": true, "**/build/**": true, "**/out/**": true, + "**/coverage/**": true, + "**/.coverage/**": true, + "**/.nyc_output/**": true, "**/.cache/**": true, "**/.turbo/**": true, + "**/.swc/**": true, + "**/.stryker-tmp/**": true, + "**/stryker-output-*/**": true, + "**/playwright-report/**": true, + "**/test-results/**": true, + "**/.worktrees/**": true, + "**/.claude/worktrees/**": true, + "**/electron/**": true, + "**/_references/**": true, + "**/_mono_repo/**": true, + "**/_tasks/**": true, + "**/logs/**": true, + "**/*.tgz": true, + "**/*.tsbuildinfo": true, "**/OmniRoute-*/**": true, "**/*-merge-*/**": true, "**/*-worktree-*/**": true, @@ -50,16 +90,32 @@ "**/*-reorg*/**": true }, "search.exclude": { - "**/_references": true, - "**/_mono_repo": true, - "**/electron": true, "**/node_modules": true, "**/.next": true, - "**/coverage": true, - "**/_tasks": true, + "**/.build": true, "**/dist": true, "**/build": true, "**/out": true, + "**/coverage": true, + "**/.coverage": true, + "**/.nyc_output": true, + "**/.cache": true, + "**/.turbo": true, + "**/.swc": true, + "**/.stryker-tmp": true, + "**/stryker-output-*": true, + "**/playwright-report": true, + "**/test-results": true, + "**/.worktrees": true, + "**/.claude/worktrees": true, + "**/electron": true, + "**/_references": true, + "**/_mono_repo": true, + "**/_tasks": true, + "**/logs": true, + "**/*.tgz": true, + "**/*.tsbuildinfo": true, + "**/package-lock.json": true, "**/OmniRoute-*": true, "**/*-merge-*": true, "**/*-worktree-*": true, diff --git a/docs/bdd/proxy-egress-isolation.feature b/docs/bdd/proxy-egress-isolation.feature deleted file mode 100644 index 5c980d4f01..0000000000 --- a/docs/bdd/proxy-egress-isolation.feature +++ /dev/null @@ -1,29 +0,0 @@ -Feature: Proxy egress isolation and IPv6-only enforcement - As an operator routing provider traffic through proxies - I want every request to egress only through the assigned proxy (and only over IPv6 when an IPv6 proxy is set) - So that the real host IP and IPv4 are never leaked - - Scenario: IPv6-literal proxy de-brackets and connects over IPv6 - Given a proxy configured as socks5://[2001:db8::1]:1080 - When the dispatcher options are built - Then the SOCKS host is 2001:db8::1 and the resolved family is 6 - - Scenario: IPv6 hostname proxy forces IPv6-only egress - Given a proxy hostname with family=ipv6 - When the dispatcher family is resolved - Then the connect family is pinned to 6 - - Scenario: IPv6-only egress is fail-closed when no AAAA exists - Given a proxy hostname with family=ipv6 and no AAAA record - When the family is asserted - Then it is refused and never egresses over IPv4 - - Scenario: Family directive contradicting a literal is rejected - Given a proxy 203.0.113.7 with family=ipv6 - When the dispatcher family is resolved - Then it throws a configuration error - - Scenario: Web TLS clients are fail-closed - Given a web TLS client whose proxy resolution throws - When the proxy URL is resolved - Then it throws instead of connecting directly diff --git a/docs/fix-opencode-context.md b/docs/fix-opencode-context.md deleted file mode 100644 index 47b3274942..0000000000 --- a/docs/fix-opencode-context.md +++ /dev/null @@ -1,108 +0,0 @@ -# Fix: OpenCode combo context window detection - -## Bug - -OpenCode v1's `opencode.json` requires an explicit `limit.context` (and -`limit.output`) for every model. Without these fields, OpenCode's heuristic -kicks in and reports a wrong context window. - -The OmniRoute `/v1/models` catalog is the single source of truth for context -windows. The bug was that some combos were published to the catalog WITHOUT -a computed `context_length`, so any OpenCode client pulling the catalog got -no answer for them. - -## Root cause - -The "Opencode FREE Omni" combo references four `opencode/` targets -(`big-pickle`, `deepseek-v4-flash-free`, `minimax-m3-free`, -`nemotron-3-super-free`). The catalog's `buildComboCatalogMetadata` computes -the combo's `context_length` as the **minimum of its targets' known -contexts**, but every target's lookup was returning `null`. - -The lookup chain in `getCanonicalModelMetadata`: - -1. `getSyncedCapability("opencode", "big-pickle")` → returns `null` because - the DB row is stored under `provider = "opencode-zen"`, not `"opencode"`. -2. `getRegistryModel("opencode", "big-pickle")` → returns `null` because - `PROVIDER_MODELS["opencode"]` (and `["oc"]`) don't have static entries - for these models. -3. `getModelSpec("big-pickle")` → returns `null` (no static spec). - -All three lookups fail → metadata is `null` → combo has no context. - -Why was the DB row under `"opencode-zen"` and not `"opencode"`? -`MODELS_DEV_PROVIDER_MAP["opencode"]` was `["opencode-zen"]` only — a -historical one-way mapping. New syncs continued to write under the alias -side of the pair, while the catalog & combo targets use the canonical id -side. - -## Fix (3 layers, in this order) - -### 1. `src/lib/modelsDevSync.ts` — symmetric `mapProviderId` mapping - -```ts -// Before: -opencode: ["opencode-zen"], -"opencode-go": ["opencode-go"], - -// After: -opencode: ["opencode", "opencode-zen"], -"opencode-go": ["opencode-go", "opencode-zen"], -``` - -Now models.dev data lands under BOTH the canonical id and the historical -alias, so any future sync keeps the lookup paths in sync. - -### 2. `src/lib/modelsDevSync.ts` — alias-aware fallback in `getSyncedCapability` - -The runtime fix that takes effect **immediately**, without waiting for a -re-sync. Existing DB rows under `"opencode-zen"` are now found when -callers pass `"opencode"` (or vice-versa). - -```ts -const SYNCED_CAPABILITY_FALLBACK_ALIASES: Record = { - opencode: ["opencode-zen"], - "opencode-zen": ["opencode"], - "opencode-go": ["opencode-zen"], -}; -``` - -### 3. `src/lib/cli-helper/config-generator/opencode.ts` — drop the hardcoded 128K fallback - -The previous band-aid hardcoded `FALLBACK_CONTEXT_LENGTH = 128_000` for -models whose context was unknown. That's wrong: combos like "Opencode -FREE Omni" should report **200K** (the min of their 200K targets), not -the universal 128K default. - -The generator now: - -- Uses the catalog as the **single source of truth** for `limit.context`. -- Emits the model **without** `limit.context` if the catalog has no entry - — OpenCode's own heuristic applies and the user can fix the upstream. -- **Throws** if the catalog fetch fails outright — the CLI catches and - surfaces the error. We never silently write a stale opencode.json. - -## Deployment steps (for the operator) - -1. Pull the latest from the branch: - `git fetch && git checkout fix/opencode-context-window` -2. Rebuild OmniRoute: `npm run build` -3. Restart the OmniRoute server (kill the running process and re-run). -4. Trigger a models.dev sync from the Settings → Models.dev panel - (or POST `/api/settings/models-dev` with `{"action": "sync"}`). -5. Re-run the opencode.json generator (the CLI command or the - `scripts/regen-opencode-config.ts` script). - -After step 5, `Opencode FREE Omni`'s `limit.context` will be **200000** -and every other combo will reflect its targets' min context. - -## Verification - -After the rebuild, hit `GET /v1/models` and inspect the response: - -```bash -curl -s http://localhost:20128/v1/models \ - -H "Authorization: Bearer $API_KEY" \ - | jq '.data[] | select(.id == "Opencode FREE Omni") | .context_length' -# → 200000 -``` diff --git a/docs/DOCUMENTATION_OVERHAUL_PLAN.md b/docs/guides/DOCUMENTATION_OVERHAUL_PLAN.md similarity index 99% rename from docs/DOCUMENTATION_OVERHAUL_PLAN.md rename to docs/guides/DOCUMENTATION_OVERHAUL_PLAN.md index 6e95ee67ab..05d7bf7ce6 100644 --- a/docs/DOCUMENTATION_OVERHAUL_PLAN.md +++ b/docs/guides/DOCUMENTATION_OVERHAUL_PLAN.md @@ -29,8 +29,10 @@ ## Phase 1: User-Facing Quick Start Docs (Highest Impact) ### 1.1 `docs/guides/QUICK-START.md` — NEW + **Replaces**: Condensed version of README.md **Content**: + - Install (npm, Docker, source) - Connect a free provider (3 steps) - Point your IDE to OmniRoute @@ -38,8 +40,10 @@ - "What's next?" → link to other guides ### 1.2 `docs/guides/AUTO-COMBO-GUIDE.md` — NEW + **Complements**: `docs/routing/AUTO-COMBO.md` **Content**: + - What auto-combo does (30-second version) - Which `auto` should I use? (table) - How it picks providers (simple version) @@ -47,8 +51,10 @@ - "Learn more" → link to technical reference ### 1.3 `docs/guides/PROVIDERS-GUIDE.md` — NEW + **Complements**: `docs/reference/PROVIDER_REFERENCE.md` **Content**: + - What is a provider? (analogy) - How to connect a provider (step-by-step) - Free vs paid providers (table) @@ -57,8 +63,10 @@ - "Learn more" → link to provider reference ### 1.4 `docs/guides/FREE-TIERS-GUIDE.md` — NEW + **Complements**: `docs/reference/FREE_TIERS.md` **Content**: + - What are free tiers? (analogy) - Best free providers (table with quotas) - How to stack free tiers for unlimited usage @@ -66,9 +74,11 @@ - "Learn more" → link to free tiers reference ### 1.5 `docs/guides/TROUBLESHOOTING.md` — REWRITE + **Current**: Technical, code-heavy **New**: "I see X → Do Y" format **Content**: + - Problem → Solution table - Common error messages (with screenshots) - "Still stuck?" → link to community @@ -78,64 +88,84 @@ ## Phase 2: Refine Existing User Docs ### 2.1 `docs/guides/USER_GUIDE.md` — UPDATE + **Changes**: + - Add "What you'll learn" section at top - Remove jargon, explain terms - Add step-by-step screenshots - Add "Common mistakes" section ### 2.2 `docs/guides/SETUP_GUIDE.md` — UPDATE + **Changes**: + - Add "Prerequisites" section - Simplify commands (one-liners) - Add "Verify it works" step - Add "Troubleshooting" section ### 2.3 `docs/guides/FEATURES.md` — UPDATE + **Changes**: + - Add "Why this matters" for each feature - Add use-case examples - Add "How to enable" for each feature - Add screenshots ### 2.4 `docs/guides/DOCKER_GUIDE.md` — UPDATE + **Changes**: + - Add "Docker for beginners" section - Simplify commands - Add "Common Docker issues" section - Add "What's next?" section ### 2.5 `docs/guides/ELECTRON_GUIDE.md` — UPDATE + **Changes**: + - Add "What is Electron?" explanation - Add screenshots - Add "Common issues" section ### 2.6 `docs/guides/TERMUX_GUIDE.md` — UPDATE + **Changes**: + - Add "What is Termux?" explanation - Add step-by-step with screenshots - Add "Common issues" section ### 2.7 `docs/guides/PWA_GUIDE.md` — UPDATE + **Changes**: + - Add "What is a PWA?" explanation - Add step-by-step with screenshots - Add "Common issues" section ### 2.8 `docs/guides/I18N.md` — UPDATE + **Changes**: + - Add "How to change language" (user perspective) - Add "How to contribute translations" (contributor perspective) ### 2.9 `docs/guides/KIRO_SETUP.md` — UPDATE + **Changes**: + - Add "What is Kiro?" explanation - Add step-by-step with screenshots - Add "Common issues" section ### 2.10 `docs/guides/UNINSTALL.md` — UPDATE + **Changes**: + - Add "Why uninstall?" section (common reasons) - Add "Before you uninstall" checklist - Simplify commands @@ -145,7 +175,9 @@ ## Phase 3: Technical Docs (Add Cross-Links, Keep As-Is) ### 3.1 `docs/architecture/` (6 files) + **Changes**: Add "For Users" callout at top → link to user guide + - ARCHITECTURE.md - AUTHZ_GUIDE.md - CODEBASE_DOCUMENTATION.md @@ -154,7 +186,9 @@ - RESILIENCE_GUIDE.md ### 3.2 `docs/frameworks/` (16 files) + **Changes**: Add "For Users" callout at top → link to user guide + - A2A-SERVER.md - AGENT-SKILLS.md - AGENTBRIDGE.md @@ -173,7 +207,9 @@ - WEBHOOKS.md ### 3.3 `docs/security/` (9 files) + **Changes**: Add "For Users" callout at top → link to user guide + - CLI_TOKEN.md - CLI_TOKEN_AUTH.md - COMPLIANCE.md @@ -185,7 +221,9 @@ - STEALTH_GUIDE.md ### 3.4 `docs/ops/` (8 files) + **Changes**: Add "For Users" callout at top → link to user guide + - COVERAGE_PLAN.md - E2E_DASHBOARD_SHAKEDOWN_v3.8.0.md - FLY_IO_DEPLOYMENT_GUIDE.md @@ -196,7 +234,9 @@ - VM_DEPLOYMENT_GUIDE.md ### 3.5 `docs/compression/` (5 files) + **Changes**: Add "For Users" callout at top → link to user guide + - COMPRESSION_ENGINES.md - COMPRESSION_GUIDE.md - COMPRESSION_LANGUAGE_PACKS.md @@ -204,13 +244,17 @@ - RTK_COMPRESSION.md ### 3.6 `docs/routing/` (3 files) + **Changes**: Add "For Users" callout at top → link to user guide + - AUTO-COMBO.md (→ link to AUTO-COMBO-GUIDE.md) - QUOTA_SHARE.md - REASONING_REPLAY.md ### 3.7 `docs/reference/` (5 files) + **Changes**: Add "For Users" callout at top → link to user guide + - API_REFERENCE.md - CLI-TOOLS.md - ENVIRONMENT.md @@ -218,6 +262,7 @@ - PROVIDER_REFERENCE.md (→ link to PROVIDERS-GUIDE.md) ### 3.8 Other Docs (keep as-is) + - `docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md` — Already user-friendly - `docs/marketing/TIERS.md` — Already user-friendly - `docs/diagrams/README.md` — Keep as-is @@ -239,6 +284,7 @@ ## Phase 4: Update Main README.md **Changes**: + - Add "Quick Start" section (3 steps) - Add "Which `auto` should I use?" table - Add "Free providers" table @@ -250,6 +296,7 @@ ## Execution Order ### Week 1: Phase 1 (User-Facing Quick Start Docs) + 1. `docs/guides/QUICK-START.md` — NEW 2. `docs/guides/AUTO-COMBO-GUIDE.md` — NEW 3. `docs/guides/PROVIDERS-GUIDE.md` — NEW @@ -257,6 +304,7 @@ 5. `docs/guides/TROUBLESHOOTING.md` — REWRITE ### Week 2: Phase 2 (Refine Existing User Docs) + 1. `docs/guides/USER_GUIDE.md` — UPDATE 2. `docs/guides/SETUP_GUIDE.md` — UPDATE 3. `docs/guides/FEATURES.md` — UPDATE @@ -269,6 +317,7 @@ 10. `docs/guides/UNINSTALL.md` — UPDATE ### Week 3: Phase 3 (Technical Docs Cross-Links) + 1. `docs/architecture/` — Add cross-links 2. `docs/frameworks/` — Add cross-links 3. `docs/security/` — Add cross-links @@ -278,6 +327,7 @@ 7. `docs/reference/` — Add cross-links ### Week 4: Phase 4 (Update Main README.md) + 1. Update README.md with user-friendly sections --- @@ -308,18 +358,23 @@ # [Feature Name]: [One-Line Description] ## What It Does + [2-3 sentences explaining what the feature does in plain language] ## Quick Start + [Step-by-step instructions to get started] ## [Main Section] + [Detailed explanation with tables, examples, screenshots] ## Common Questions + [FAQ section with common questions and answers] ## What's Next? + [Links to related guides and technical docs] ``` diff --git a/docs/AGENTROUTER.md b/docs/providers/AGENTROUTER.md similarity index 100% rename from docs/AGENTROUTER.md rename to docs/providers/AGENTROUTER.md