Commit Graph

38 Commits

Author SHA1 Message Date
Diego Rodrigues de Sa e Souza
75d9a83c25 Release v3.8.3 (#2617)
* chore(config): ignore additional agent workflow command files

Add newly introduced agent workflow and Claude command files to
.gitignore so proprietary automation assets are not committed.

* feat(deepseek-web): fix auth to use userToken + WASM PoW solver

Rewrite deepseek-web executor from broken cookie auth to userToken
Bearer flow (like Chat2API). Replace pure JS Keccak PoW with WASM
solver (5.8s → 86ms). Add 14 models, validation, and dashboard UX.

* fix(deepseek-web): update target_path to use challenge property

* refactor(deepseek-web): streamline token handling and implement cache eviction

* fix(deepseek-web): fix SSE parser, prompt format, and error handling

- Handle all 3 DeepSeek SSE stream formats: initial fragments,
  APPEND operations, and bare string tokens (fixes truncated responses)
- Simplify prompt builder to send system + last user message only
  (DeepSeek web API is single-turn, full history caused marker leakage)
- Check json.code before token extraction (fixes "did not return
  access token: Authorization" on code 40003 with HTTP 200)
- Clear session cache alongside token cache on auth errors
- Add dev origin for remote testing

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: ignore memory-bank and cursor agent rules from tracking

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: enhance documentation and configuration for Fumadocs integration

- Added Fumadocs MDX support in the Next.js configuration.
- Updated transpile packages to include fumadocs-ui and fumadocs-core.
- Implemented a comprehensive set of redirects for documentation paths to improve navigation.
- Removed the generate-docs-index script as it is no longer needed.
- Updated various documentation titles for consistency and clarity.
- Enhanced global styles to incorporate Fumadocs UI themes and styles.

* refactor(docs): cleanup fumadocs PR — revert deepseek, add i18n fallback, restore LanguageSelector

- Revert unrelated deepseek-web.ts changes (should be separate PR)
- Add .source/ to .gitignore (Fumadocs generated files)
- Remove contributor IP from allowedDevOrigins
- Add i18n runtime fallback: reads NEXT_LOCALE cookie, loads translated
  .md from docs/i18n/<locale>/docs/ (preserves existing translation pipeline)
- Restore LanguageSelector in Fumadocs layout nav
- Restore SEO metadata (title template, description, robots)

* fix(codex): use allowlist to strip non-Responses-API fields in non-passthrough path (#2608) (#2615)

Integrated into release/v3.8.3 — fix(codex): allowlist-based sanitization for gpt-5.5 Responses API

* fix(deepseek-web): fix SSE parser, prompt format, error handling, and cache keys (#2616)

Integrated into release/v3.8.3 — fix(deepseek-web): SSE parser (APPEND + bare tokens), prompt builder, error handling, session cache cleanup

* chore(config): ignore additional agent workflow command files

Add newly introduced agent workflow and Claude command files to
.gitignore so proprietary automation assets are not committed.

* feat(docs): migrate /docs to Fumadocs MDX with nested routes (#2614)

Integrated into release/v3.8.3 — Fumadocs MDX migration with nested routes, search API, and 50+ URL redirects

* fix(catalog): skip static PROVIDER_MODELS when synced models exist (#2625)

Integrated into release/v3.8.3

* fix(qoder): Cosy auth fallback for PAT tokens + vision support for qwen3-vl-plus (#2629)

Integrated into release/v3.8.3

* fix(cli): register tsx loader and add opencode config subcommand (#2631)

Integrated into release/v3.8.3

* feat(dashboard): add search and filters to /dashboard/api-manager (#2628)

Integrated into release/v3.8.3

* fix(claude): improve Pi and OpenCode compatibility (#2621)

Integrated into release/v3.8.3

* fix: restore semantic passthrough system-role-only extraction instead of full normalization (#2620)

Integrated into release/v3.8.3

* fix(kiro): stabilize conversationId across prompt compression (#2630)

Integrated into release/v3.8.3

* fix(deepseek-web): SSE thinking/search routing and session lifecycle (#2624)

Integrated into release/v3.8.3 — DeepSeek Web SSE thinking/search routing overhaul

* feat(dashboard): free-tier grouping with symbolic link in /providers (#2632)

Integrated into release/v3.8.3

* fix: close implementation gaps — t3-chat-web, stream_options, combo_strategy, batch config (#2634)

Integrated into release/v3.8.3

* feat(dashboard): risk notice modal for sensitive providers (#2633)

Integrated into release/v3.8.3

* fix(reasoning): extend reasoning_content injection to Kimi K2 and other replay models (#2639)

Integrated into release/v3.8.3

* fix(cli): Linux autostart via systemd user service (fixes #2627) (#2635)

Integrated into release/v3.8.3

* Refactor/providers free tier (#2640)

Integrated into release/v3.8.3

* fix(tests): remove duplicate assertion in schema coercion & fix(cli): ignore system vars in env check

* fix(combo): preserve omniModel tag in streaming output for round-trip context pinning (#2646)

Integrated into release/v3.8.3

* feat(dashboard): media providers pages + Web Fetch category (#2645)

Integrated into release/v3.8.3

* Feature provider adapta org com tutorial de conexão em modal (#2643)

Integrated into release/v3.8.3

* fix(rtk): skip content-based filter matching for non-shell tool results (#2642)

Integrated into release/v3.8.3

* fix(translator): enable Claude extended thinking for Copilot Responses-API requests (#2647)

Integrated into release/v3.8.3

* feat(dashboard): add search and filters to /dashboard/api-manager (#2641)

Integrated into release/v3.8.3

* feat(dashboard): risk notice modal for sensitive providers (#2638)

Integrated into release/v3.8.3

* feat(dashboard): mini-playground inline (Phase 4) (#2648)

Integrated into release/v3.8.3

* fix(settings): fix Require Login modal Cancel button text and dismissal (#2649)

Integrated into release/v3.8.3

* feat(combos): universal context handoff for cross-model conversation continuity (#2653)

Integrated into release/v3.8.3

* chore(release): bump to v3.8.3 — changelog, docs, version sync

* feat(i18n): complete zh-CN translations for 1220 missing keys (#2655)

Integrated into release/v3.8.3

* chore(release): include electron package changes in v3.8.3

* docs(changelog): integrate PR #2655 into v3.8.3

* feat(i18n): translate 377 additional zh-CN entries (81 new keys + 296 same-as-en) (#2659)

Integrated into release/v3.8.3

* feat(dashboard): add Cmd+K / Ctrl+K command palette for sidebar navigation (#2656)

Integrated into release/v3.8.3

* docs: update changelog for PR integrations under v3.8.3

* feat(cli): integrate native updates, autostart and headless CLI mode (#2662)

Integrated into release/v3.8.3

* fix(proxy): save dashboard custom proxies in registry (#2661)

Integrated into release/v3.8.3

* feat(dashboard): chat-first test slide-over (Option A) (#2660)

Integrated into release/v3.8.3

* docs: update changelog with Batch 2 PR merges for v3.8.3

* fix: add xhigh+max to effortLevel schema; add opencode-plugin publish job (#2666)

Integrated into release/v3.8.3

* docs: update changelog with Batch 3 PR #2666 merge for v3.8.3

* feat(quota+providers): card-grid layout, provider group headers, Codex race fix (#2667)

Integrated into release/v3.8.3

* feat(dashboard): real-time live WebSocket monitoring (#2668)

Integrated into release/v3.8.3

* feat(copilot): AI assistant with CodeGraph + CLI + knowledge base (#2669)

Integrated into release/v3.8.3

* feat(pipeline): pre-request middleware hooks (#2670)

Integrated into release/v3.8.3

* feat(resilience): credential health check + adaptive circuit breaker (#2671)

Integrated into release/v3.8.3

* feat(playground): combo routing visual simulator (#2672)

Integrated into release/v3.8.3

* feat(auth): API key groups with model-level permissions (#2673)

Integrated into release/v3.8.3

* feat(pwa): enhanced manifest + push notification support (#2674)

Integrated into release/v3.8.3

* feat(proxy): serverless relay endpoints with rate limiting (#2675)

Integrated into release/v3.8.3

* docs(changelog): update changelog for PRs 2667-2675 & fix: resolve typescript compile-time errors

* fix(db): remove transactions from migrations

Remove explicit transaction wrappers from recent migrations and correct
the API key groups migration metadata. Also fix codegraph path resolution
for ESM environments and refresh generated fumadocs source output.

---------

Co-authored-by: Ömer Vehbe <ovehbe@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mr. Meowgi <mr@meowgi.dev>
Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com>
Co-authored-by: amogus22877769 <y.lev357@gmail.com>
Co-authored-by: Halil Tezcan KARABULUT <info@hlltzcnkb.com>
Co-authored-by: Tentoxa <53821604+Tentoxa@users.noreply.github.com>
Co-authored-by: HALDRO <121296348+HALDRO@users.noreply.github.com>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: janeza2 <49841619+janeza2@users.noreply.github.com>
Co-authored-by: df4p <38404+df4p@users.noreply.github.com>
Co-authored-by: ivan-mezentsev <ivan@mezentsev.me>
Co-authored-by: Chewji <126886556+Chewji9875@users.noreply.github.com>
Co-authored-by: L-aros <107354918+L-aros@users.noreply.github.com>
Co-authored-by: M.M <mr.maatoug@gmail.com>
Co-authored-by: Benson K B <bensonkbmca@gmail.com>
Co-authored-by: terence71-glitch <mcdowellterence71@gmail.com>
2026-05-24 18:05:58 -03:00
Diego Rodrigues de Sa e Souza
6248699ce5 Release/v3.8.0 — full changelog with 660+ commits (#2419)
* fix(cli-tools): guard modelId type before calling indexOf

E2E shakedown v3.8.0: cli-tools quebrava com TypeError quando dynamicModels
continha entradas sem .id (objeto retornado diretamente em vez de string).

* fix(offline): avoid SSR/CSR hydration mismatch on navigator.onLine

Replace useState+lazy-initializer with useSyncExternalStore so the server
snapshot (() => false) and client snapshot (() => navigator.onLine) are
declared separately. React hydrates with the server value and switches to
the real online status client-side without a mismatch.

* chore(i18n): add missing en.json keys for translator, cli-tools, memory, onboarding

Adds 58 missing keys identified by the new dashboard audit script:
- cliTools: 18 custom CLI builder keys (CustomCliCard)
- translator: 24 keys covering stream transformer, live monitor, test bench
- memory: 12 health/pagination/dialog keys
- onboarding.tier: 8 keys for the tier tour walkthrough

Also adds scripts/i18n/audit-dashboard-pages.mjs which scans all dashboard
pages, reports t() calls referencing missing en.json keys, and flags
candidate hardcoded JSX/attribute strings.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 1)

Subagents refactored 8 high-impact dashboard pages, replacing 81 of the
407 hardcoded English/PT strings flagged by the audit with proper
useTranslations() lookups. Added 73 corresponding keys to en.json across
the home, apiManager, providers, settings, and usage namespaces.

Pages affected:
- BudgetTab (27 → 0)
- HomePageClient (2 → 0)
- RoutingTab (25 → 7)
- ResilienceTab (38 → 18)
- SystemStorageTab (42 → 21)
- providers/[id] (17 → 15)
- ApiManagerPageClient (14 → 13)
- OneproxyTab (13 → 10)

Also adds two helper scripts:
- scripts/i18n/extract-keys-from-diff.mjs — extracts new keys from git diff
- scripts/i18n/merge-keys.mjs — merges a pending-keys JSON into en.json

Remaining hardcoded strings will be addressed in follow-up rounds.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 2)

Continues round 1 (commit 8d34f4c65). Round-2 subagents refactored
additional dashboard pages, replacing 77 more hardcoded strings with
useTranslations() lookups. Added 79 corresponding keys to en.json
across the a2aDashboard, agents, analytics, apiManager, cliTools,
common, and settings namespaces.

Pages affected:
- a2a/page (new useTranslations + 6 keys)
- agent-skills/page (new useTranslations + 9 keys)
- AutoRoutingAnalyticsTab (new useTranslations + 6 keys)
- AppearanceTab (8 → 6 remaining)
- OneproxyTab (10 → 0)
- ResilienceTab (18 → 0 missing key)
- RoutingTab (7 → 0 missing key)
- VisionBridgeSettingsTab (new useTranslations + 6 keys)
- CopilotToolCard (7 → 0 missing key)
- ApiManagerPageClient (13 → 0 missing key)
- gamification/admin (new useTranslations + 7 keys)

Hardcoded total: 326 → 249. Real missing keys: 0 (the 6 still flagged
are false positives in exampleTemplates.tsx where t is passed as a
parameter — keys exist at translator.templatePayloads.*).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 3)

Round-3 subagents and manual edits refactored 9 more dashboard pages
(plus 2 small extras), replacing ~80 hardcoded strings with
useTranslations() lookups. Added 79 corresponding keys to en.json
across analytics, cloudAgents, combos, common, health, settings, and
usage namespaces.

Pages affected:
- analytics/ComboHealthTab (new useTranslations + 15 keys)
- analytics/CompressionAnalyticsTab (new useTranslations + 11 keys)
- settings/SystemStorageTab (21 → 0 missing key)
- tokens/page (new useTranslations + 13 keys)
- usage/BudgetTab (9 missing fixed)
- health/page (manual: 6 keys)
- cloud-agents/page (manual: 3 keys)
- combos/page (manual: 1 key)

Hardcoded total: 249 → 164. Real missing keys: 0 (6 remaining are
exampleTemplates.tsx false positives).

Also adds scripts/i18n/build-pending-from-missing.mjs which reads
_audit.json and locates English values from HEAD to rebuild
_pending-keys.json after race-condition resets between subagent edits.

* chore(i18n): localize remaining dashboard settings labels

Replace hardcoded labels in compression and resilience settings with
translation lookups to continue the dashboard i18n cleanup.

Add the v3.8.0 dashboard shakedown runbook to document the manual
smoke-test process and known dev environment pitfalls.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 4)

Round-4 subagent + manual key-resolution refactored remaining strings in
3 high-traffic settings/API tabs, plus extracted English values for
keys that were already added as t() calls but lost during the previous
en.json race-condition resets.

Pages affected:
- api-manager/ApiManagerPageClient (7 → 0 missing key)
- settings/CompressionSettingsTab (8 → 0 missing key)
- settings/MemorySkillsTab (8 → 0 missing key)
- settings/ResilienceTab (4 more keys recovered)

Hardcoded total: 164 → 140. Real missing keys: 0 (6 remaining are the
exampleTemplates.tsx false positives — t passed as parameter).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 5)

Round-5 agent began processing the remaining smaller dashboard files.
Added 5 more keys to en.json for providers/[id]/page.tsx OAuth flow
labels and the cross-OS auto-detection hint.

Pages affected:
- providers/[id]/page.tsx (5 keys)

Hardcoded total: 140 → 136. Real missing keys: 0.

* chore(i18n): resolve last 2 missing providers/[id] keys

Adds providerDetailMyClaudeAccountPlaceholder and
providerDetailPathAutoDetected — the final user-visible labels in the
providers/[id] page that the round-5 subagent rewrote to t() calls
without yet adding to en.json.

Real missing keys: 0 (6 remaining are exampleTemplates.tsx false
positives — t is passed as a parameter so the audit cannot resolve the
namespace; keys do exist at translator.templatePayloads.*).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 6 — 10 parallel agents)

Round-6 dispatched 10 parallel subagents covering all 57 remaining
dashboard files. Each agent worked on a disjoint file set to avoid
en.json race conditions. Added ~60 new i18n keys across 9 namespaces
covering small UI labels, table headers, search placeholders, and
empty-state messages.

Major changes:
- analytics: SearchAnalyticsTab, ProviderUtilizationTab, DiversityScoreCard, CompressionAnalyticsTab (new useTranslations + keys)
- batch: BatchDetailModal, BatchListTab, FileDetailModal, FilesListTab (new useTranslations + keys)
- settings: CliproxyapiSettingsTab, PayloadRulesTab, ModelCooldownsCard, AppearanceTab, PricingTab (mostly new useTranslations)
- endpoint: TokenSaverCard, ApiEndpointsTab, EndpointPageClient
- cache: CachePerformance, IdempotencyLayer, ReasoningCacheTab, MediaPageClient, page
- combos: IntelligentComboPanel, page
- playground: ChatPlayground, SearchPlayground
- providers: ProviderCard
- onboarding: TierFlowDiagram
- changelog: ChangelogViewer
- home: ProviderTopology, TierCoverageWidget, BootstrapBanner, BadgeToast
- usage: BudgetTab, BudgetTelemetryCards, QuotaTable
- quotaShare: QuotaSharePageClient
- profile: page
- leaderboard: page
- skills: page

Hardcoded total: 131 → 60. Real missing keys: 0 plus 1 false-positive
for combos.modePack (lookup via prop-passed t).

* chore(i18n): finalize round-6 keys for batch/cache/endpoint/usage

Adds the remaining keys produced by parallel agents A4, A6, A8, A9:
- common: batch-related labels (BatchDetailModal, BatchListTab,
  FileDetailModal, FilesListTab, page) + profile/leaderboard
- cache: hit rate, latency, retry, avg chars
- endpoint: token saver, API endpoints, copy URL, cloud/local labels
- usage: noSpend, activeSessions, quotaAlerts, budget timing
- skills: install/marketplace/filter
- proxyRegistry/quotaShare/mcpDashboard: misc labels

Hardcoded total: 60 → 48. Real missing keys: 0 (modePack remaining is a
false positive — combos.modePack exists but the audit can't resolve it
since IntelligentComboPanel receives t as a prop).

* fix(playground): dedupe filteredModels to avoid duplicate React key warning

The /v1/models endpoint can return the same model id twice (e.g., when a
model is listed by both an alias and its canonical provider), which made
the <Select> emit two <option> elements with the same key — triggering
"Encountered two children with the same key, codex/gpt-5.5".

Replace the chained filter + map with a single pass that skips ids
already added.

* fix(playground): guard against non-string model ids before .split/.startsWith

The /v1/models endpoint can include synthetic entries (combos, locals,
in-progress imports) with a null/undefined id. The playground used to
call m.id.split("/") in the provider-discovery loop, which threw on the
first non-string entry; the surrounding .catch(() => {}) silently
swallowed the error, so the provider/model/account dropdowns ended up
empty even though /v1/models returned thousands of valid entries.

- Skip entries without a string id before split/startsWith.
- Log the rejection in the .catch handler so future regressions are
  visible in DevTools instead of silently emptying the UI.

* fix(playground): guard ChatPlayground filteredModels for non-string ids

Same root cause as commit 49fe356b9: ChatPlayground filtered models
with m.id.startsWith(...) which crashed on null/undefined ids returned
by /v1/models (synthetic combo entries). Apply the same defensive guard
and dedupe used in the parent page.

* fix(claude): drop orphan tool_result after fixToolAdjacency strip (discussion #2410)

Discussion #2410 reports Claude returning 400 for sequences like:
  assistant: tool_use(id=X)
  user: <plain text>           ← breaks adjacency
  user: tool_result(id=X)

The previous round added `fixToolAdjacency` (commit 44d9abac9) which
correctly strips the orphan tool_use from the assistant message. But
that left the now-unmatched tool_result intact, so the upstream
rejected the request with:

  messages.N.content.M: unexpected `tool_use_id` found in `tool_result`
  blocks: X. Each tool_result block must have a corresponding tool_use
  block in the previous message.

Fix: after running `fixToolAdjacency`, re-run `fixToolPairs` to drop
the orphaned tool_result blocks. All three call sites updated:
  - contextManager.purifyHistory (both inside the binary-search loop
    and the final pass)
  - BaseExecutor message-prep (Claude path)
  - claudeCodeCompatible request signer

Also tightens an unrelated dynamic-key access in
readNestedString (claudeCodeCompatible) to satisfy the prototype-
pollution scanner triggered by the post-tool semgrep hook.

* fix(mitm): point runtime manager re-export to js entrypoint

Use the emitted `.js` path for the runtime manager re-export so dynamic
runtime loading resolves correctly outside the Turbopack alias handling.

* docs: add AgentRouter setup guide (#2422)

Integrated into release/v3.8.0 — AgentRouter setup guide docs.

* feat: add new feature on combos - falloverBeforeRetry (#2417)

Integrated into release/v3.8.0 — falloverBeforeRetry for per-model quota skipping in combos.

* feat(batch): implement 10 feature requests harvested  (#2414)

Integrated into release/v3.8.0 — batch of 10 feature requests: llama.cpp local provider, upstream error exposure, Termux detection, providers rotate CLI, t3.chat web skeleton, Zed Docker integration, Kiro multi-account OAuth isolation, auto-combo cost blending, auto-combo context filter, combo provider-level exhaustion tracking (#1731). Conflicts with #2417 (falloverBeforeRetry) resolved.

* fix(gamification): resolve SQL bug, auth gap, pagination, and anomaly scoring (#2421)

Integrated into release/v3.8.0 — 6 critical gamification bug fixes: SQL SELECT in checkActionCountBadges, federation auth enforcement, leaderboard pagination offset, real z-score computation, addXp level calculation, and barrel index.ts

* docs(changelog): add post-release entries for #2414 #2417 #2421 #2422

- feat(batch): T3-Chat-Web executor, exhaustedProviders set (#1731), Zed Docker
- feat(combos): falloverBeforeRetry + setTry loop (#2417 — @hartmark)
- fix(gamification): SQL SELECT bug, federation auth, pagination, z-score (#2421 — @oyi77)
- docs: AgentRouter setup guide (#2422 — @leninejunior)

* fix(security): resolve CodeQL random/password-hash alerts and sync docs & tests

---------

Co-authored-by: diegosouzapw <diego.souza.pw@gmail.com>
Co-authored-by: Lenine Júnior <lenine@engrene.com.br>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
2026-05-20 02:05:50 -03:00
Diego Rodrigues de Sa e Souza
79d03575ee feat(cli): suporte i18n completo — 42 locales, --lang flag, config lang get/set/list (#2285)
feat(cli): suporte i18n completo — 42 locales, --lang flag, config lang get/set/list

- 42 locale files in bin/cli/locales/ (en + pt-BR fully translated, 29 with common/program, 11 scaffolds)
- --lang <code> global flag for per-execution override
- config lang get/set/list subcommands
- Locale persistence via ~/.omniroute/.env
- Path traversal protection via regex validation in normalize()
- Script generate-locales.mjs for scaffolding new locales
- Unit tests for lang commands + normalization security

Integrated into release/v3.8.0
2026-05-15 13:14:14 -03:00
diegosouzapw
f320caa724 fix(cli): code-review-2 — I1/I2/M1/M2
I1 (logs): implementar filtragem runtime das 7 flags registradas mas ignoradas:
  --request-id, --api-key, --combo, --status, --duration-min, --duration-max,
  --export. Filtragem client-side via buildLogFilter(); --export grava jsonl.
I2 (keys): adicionar isServerUp() check + try/catch nos 8 comandos que chamavam
  apiFetch diretamente sem proteção: regenerate/revoke/reveal/usage/policy-show/
  policy-set/expiration-list/rotate. Garante exit code 1 com mensagem amigável
  quando servidor offline.
M1 (tunnel): substituir string hardcoded inglesa em runTunnelStopCommand linha 151
  por t("tunnel.typeRequired").
M2 (logs): substituir "Log stream stopped." e "Log stream error: ..." por t()
  calls; adicionar logs.stopped / logs.streamError / logs.exported a en.json e
  pt-BR.json.
2026-05-15 10:24:30 -03:00
diegosouzapw
69a2b27a33 fix(cli): code-review — C1/C2/C3/I1/I3/I4/I5/m1/m2/m4
C1: sanitize opts.name and backupId against path traversal (replace /\\ with _)
C2: read backup files locally as base64 instead of sending local path to cloud API
C3: implement markOAuthDone/markOAuthFailed via module-level callbacks registered
    in useEffect — TUI now transitions to DONE/FAILED when polling signals completion
I1: fix matchesGlob — equality-only for non-glob patterns (removes false-positive
    startsWith), and support multi-wildcard patterns (e.g. **.json) by iterating parts
I3: replace two hardcoded English strings in tunnel.mjs with t() calls; add
    tunnel.notAvailable and tunnel.noTunnels to en.json and pt-BR.json
I4: log HTTP 4xx errors in runKeysAddCommand and return 1 instead of falling
    through silently to DB write on client errors
I5: truncate err.message to 100 chars in ProvidersTestAll.jsx and test-provider.mjs
m1: fix EvalWatch StatusBadge — completed state now uses status="ok" instead of "running"
m2: replace hardcoded ~/.omniroute/backup-schedule.json with resolveDataDir()-based path
m4: remove ...opts spread from all apiFetch calls in keys.mjs — pass only explicit options
    (method, body, retry, acceptNotOk) to avoid leaking apiKey/baseUrl/yes/etc.
2026-05-15 09:48:30 -03:00
diegosouzapw
09db1129a1 feat(cli): R7 — OAuthFlow/EvalWatch/ProvidersTestAll TUI + integração (spec 8.10)
Adiciona 3 componentes TUI Ink faltantes da spec 8.10:
- OAuthFlow.jsx: spinner + URL interativo para fluxo browser OAuth
- EvalWatch.jsx: monitor live de eval run com ProgressBar e DataTable
- ProvidersTestAll.jsx: teste paralelo com concorrência configurável

Integração nos comandos:
- oauth start browser flow → OAuthFlow quando TTY
- eval run --watch → EvalWatch quando TTY (fallback texto sem TTY)
- test --all-providers → ProvidersTestAll quando TTY (fallback tabela sem TTY)
2026-05-15 09:13:56 -03:00
diegosouzapw
2faf3608b2 fix(cli): R6 — i18n para strings literais em logs.mjs e tunnel.mjs
Substitui 13 strings hardcoded em logs.mjs e 2 em tunnel.mjs por chamadas
t() com chaves adicionadas nas locales en.json e pt-BR.json.
2026-05-15 09:01:48 -03:00
diegosouzapw
dcc21f1052 feat(cli): R5 — test --latency/--repeat/--compare/--save (spec 8.7 test-provider)
Adiciona medição de latência (avg/min/max), repetição de testes N vezes,
comparação de múltiplos modelos side-by-side e exportação de resultados
em JSON via --save. Inclui testes para todas as novas flags.
2026-05-15 08:45:11 -03:00
diegosouzapw
8a471e712c feat(cli): R4 — backup --cloud/--encrypt/--exclude/--retention/auto (spec 8.7)
Expande o comando backup com subcomandos create e auto enable/disable/status.
Adiciona suporte a criptografia AES-256-GCM, exclusão por glob, retenção e
upload cloud. Glob matcher usa apenas operações de string (sem RegExp dinâmico).
2026-05-15 08:40:50 -03:00
diegosouzapw
d8445caf90 feat(cli): R3 — tunnel status/logs/info/rotate (completa spec 8.7 tunnels)
- tunnel.mjs: adiciona runTunnelStatusCommand, runTunnelLogsCommand,
  runTunnelInfoCommand, runTunnelRotateCommand
- 4 novos subcomandos: status (uptime/requests/latency), logs (--tail),
  info (config completo JSON/table), rotate (novo URL com confirmação)
- locales: tunnel.statusDescription/logsDescription/infoDescription/
  rotateDescription/tailOpt/typeRequired/noLogs/infoTitle/rotated/confirmRotate
- testes: valida exports e registro dos 7 subcomandos (list/create/stop+novos)
2026-05-15 08:32:41 -03:00
diegosouzapw
d577759002 fix(cli): R1+R2 — keys.mjs HTTP-first + eliminar SQL cru + policy/expiration/rotate
- provider-store.mjs: adiciona removeProviderConnectionByProvider() para
  abstrair o DELETE que estava inline em keys.mjs (elimina SQL cru de bin/)
- keys.mjs: runKeysListCommand e runKeysRemoveCommand agora tentam HTTP
  primeiro; fallback DB usa funções do provider-store sem SQL inline
- keys.mjs: novos subcomandos keys policy show/set, keys expiration list,
  keys rotate (completa spec 8.7 para keys)
- locales: chaves i18n completas incluindo common.jsonOpt e common.yesOpt
- testes: cobre novos exports e comportamento offline de runKeysListCommand
2026-05-15 08:28:15 -03:00
diegosouzapw
b3e5ee3333 feat(cli): fase 9.4 — plugin system (omniroute-cmd-*)
Adds plugin discovery, loading, and management to the omniroute CLI.

- bin/cli/plugins.mjs: discoverPlugins / loadPlugins / buildPluginContext
- bin/cli/commands/plugin.mjs: list / install / remove / info / search / update / scaffold
- examples/omniroute-cmd-hello/: minimal working plugin example
- docs/dev/plugins.md: plugin API contract and authoring guide
- .env.example + ENVIRONMENT.md: document OMNIROUTE_PLUGIN_PATH
2026-05-15 05:11:18 -03:00
diegosouzapw
d28d756e80 feat(cli): fase 8.11 — REPL interativo multi-turn com Ink (runRepl, session, slash commands)
Adiciona REPL Ink com painel lateral de tokens/custo, 16 slash commands (/model, /combo,
/system, /clear, /save, /load, /list, /export, /history, /tokens, /help, /exit etc.),
persistência de sessão em ~/.omniroute/repl-sessions/, autosave ao sair, e comando
`omniroute repl` com flags --model, --combo, --system, --resume.
2026-05-15 04:51:23 -03:00
diegosouzapw
59128b6742 feat(cli): TUI dashboard interativo e menu de interface (Fases 8.10+8.9)
Adiciona dashboard TUI com 7 abas (Overview, Combos, Providers, Keys, Logs, Health, Cost)
via Ink, 13 componentes reutilizáveis em tui-components/, menu interativo ao iniciar sem
subcomando, e flag --tui no comando dashboard.
2026-05-15 04:36:21 -03:00
diegosouzapw
b3cfac3c14 feat(cli): fase 8.8 — system tray + autostart (omniroute serve --tray)
- bin/cli/tray/index.mjs: initTray/killTray/isTrayActive/isTraySupported
- bin/cli/tray/traySystray.mjs: systray2 para macOS/Linux (graceful fallback)
- bin/cli/tray/trayWindows.mjs: PowerShell NotifyIcon (sem binário extra)
- bin/cli/tray/autostart.mjs: launchd (macOS), reg (Windows), .desktop (Linux)
- bin/cli/commands/tray.mjs: subcomandos show/hide/quit
- bin/cli/commands/autostart.mjs: subcomandos enable/disable/status
- serve.mjs: flags --tray/--no-tray, integração após servidor iniciar
- i18n: chaves tray.*, autostart.*, serve.tray/no_tray em en.json e pt-BR.json
- check-env-doc-sync: DISPLAY e WAYLAND_DISPLAY adicionados ao allowlist (sinais do host OS)
- 8 testes unitários cobrindo autostart por plataforma e importação dos módulos
2026-05-15 04:07:20 -03:00
diegosouzapw
27f7e5c4fe feat(cli): fase 8.3 — i18n completude e linter check-cli-i18n
- Adiciona health.description e health.noServer em en.json e pt-BR.json
- scripts/check/check-cli-i18n.mjs: valida que todas as 567 chaves t() dos
  comandos existem em en.json e que pt-BR.json tem as mesmas seções top-level
- Adiciona check-cli-i18n ao hook pre-commit
- 7 testes unitários: completude do catálogo, detecção de locale (OMNIROUTE_LANG),
  fallback en, interpolação {var}, t() pt-BR
2026-05-15 03:52:13 -03:00
diegosouzapw
b329cfc84a feat(cli): fase 8.13 — self-heal native deps (omniroute runtime check/repair/clean)
- bin/cli/runtime/nativeDeps.mjs: ensureRuntimeDir, hasModule, isBetterSqliteBinaryValid
  (ELF/Mach-O/PE magic bytes), npmInstallRuntime (shell:false, cmd.exe /c no Windows),
  ensureBetterSqliteRuntime, buildEnvWithRuntime com NODE_PATH extendido
- bin/cli/commands/runtime.mjs: subcomandos check/repair --force/clean --yes
- Registrado em commands/registry.mjs
- Chaves i18n runtime.* em en.json e pt-BR.json
- 9 testes unitários cobrindo todas as funções exportadas
2026-05-15 03:46:26 -03:00
diegosouzapw
ed19c824c0 feat(cli): fase 8.4 — profiles/contexts (omniroute config contexts)
- contexts.mjs: loadContexts/saveContexts/resolveActiveContext (~/.omniroute/config.json)
- commands/contexts.mjs: CRUD completo (add/use/list/show/remove/rename/export/import)
- config.mjs: subgroup contexts registrado sob config contexts
- program.mjs: flag global --context <name> com env OMNIROUTE_CONTEXT
- en.json/pt-BR.json: chaves program.context e config.contexts adicionadas
- import usa validação explícita de campos (sem Object.assign cru)
2026-05-15 03:36:51 -03:00
diegosouzapw
fe6cffb54b feat(cli): fase 8.5/8.7 — completion dinâmico e expansão de comandos
- 8.5: completion reescrito com subcomandos install/refresh e scripts zsh/bash/fish dinâmicos
       com cache TTL 1h em ~/.omniroute/completion-cache.json
- 8.7: logs novas flags (--request-id --api-key --combo --status --duration-min/max --export)
- 8.7: health.watch (live dashboard) + health.components + --alerts-only
- 8.7: update --apply (npm install -g) + --check (exit 1 se outdated) + --changelog
- 8.7: keys regenerate/revoke/reveal/usage (gestão de management keys)
- en.json/pt-BR.json: chaves completion e logs adicionadas
2026-05-15 03:24:50 -03:00
diegosouzapw
7a2682efb5 feat(cli): fase 8.1/8.6/8.14 — spinner, open, clipboard e environment helpers
- spinner.mjs: withSpinner/shouldUseSpinner com suporte a quiet/output/CI/NO_COLOR
- open.mjs: comando `open` com 16 recursos, respeita ambientes restritos
- environment.mjs: detectRestrictedEnvironment/getEnvBanner (codespaces/wsl/gitpod/replit/ci)
- clipboard.mjs: copyToClipboard/isClipboardSupported (pbcopy/clip/xclip/xsel/wl-copy)
- check-env-doc-sync: vars de plataforma/OS adicionadas ao IGNORE_FROM_CODE
2026-05-15 03:00:52 -03:00
diegosouzapw
2f2583a02f feat(cli): fase 7 — context-eng/sessions/tags/openapi/combo-suggest/oneproxy/telemetry
- 7.1: context-eng (alias ctx) — caveman/rtk config/filters/test, analytics, combos
- 7.2: sessions list/show/expire/expire-all/current
- 7.3: tags list/add/remove/assign/unassign/resources
- 7.4: openapi dump/validate/try/endpoints/paths (YAML sem js-yaml via toYaml inline)
- 7.5: combo suggest via MCP omniroute_best_combo_for_task (extendComboSuggest)
- 7.6: oneproxy status/stats/fetch/rotate/config/pool via MCP + REST
- 7.7: telemetry summary/export com fmtMetric/fmtDelta
45 novos testes passando
2026-05-15 02:47:49 -03:00
diegosouzapw
761ff3e781 feat(cli): fase 6.1+6.2 — batches e files API (upload/CRUD/output/errors) 2026-05-15 02:24:45 -03:00
diegosouzapw
3cfba85461 feat(cli): fase 5.1 — mcp call com stream e mcp scopes 2026-05-15 02:05:06 -03:00
diegosouzapw
8c48abc40c feat(cli): fase 4.1 — comando oauth com fluxos browser/import/social/device 2026-05-15 01:51:07 -03:00
diegosouzapw
28629bf7f0 feat(cli): adicionar omniroute audit (Fase 3.4)
5 subcomandos: tail, search, export, stats, get.
Mescla compliance e MCP por timestamp. --follow faz polling 2s.
--source filtra entre compliance|mcp|all. Mascaramento de actor.
2026-05-15 01:30:18 -03:00
diegosouzapw
2468ebf8f7 feat(cli): adicionar omniroute skills e marketplace (Fases 3.2 e 3.3)
skills: list, get, install, enable, disable, delete, execute, executions, skillssh.
marketplace: search, info, install, categories, featured.
Suporta --from-file, --from-url, --input-file, --type, --enabled, --status.
2026-05-15 01:24:36 -03:00
diegosouzapw
33ad5012c6 feat(cli): adicionar omniroute memory (Fase 3.1)
7 subcomandos: search, add, clear, list, get, delete, health.
Suporta --type, --api-key, --older-than (parser 30d/6m/1y), --token-budget.
Strings i18n em en.json e pt-BR.json.
2026-05-15 01:18:58 -03:00
diegosouzapw
ba14064ea4 feat(cli): adicionar omniroute providers metrics (Fase 2.6)
Extende o grupo `providers` com dois subcomandos:
- `providers metrics`: lista métricas de performance de todos os provedores
  (latência avg/P95, success rate, custo, breaker state, erros).
  Suporta --provider, --connection-id, --period, --sort-by, --limit,
  --watch (refresh 5s) e --compare (filtro multi-provider).
- `providers metric <id> <metric>`: retorna valor escalar de uma métrica
  específica para uma conexão.

Fonte: GET /api/provider-metrics — normaliza tanto formato objeto
{metrics: {[provider]: {}}} quanto array de providers.
2026-05-15 01:10:10 -03:00
diegosouzapw
85489a0295 feat(cli): adicionar grupo usage com 7 subcomandos (Fase 2.5)
Implementa `omniroute usage` com subcomandos:
- analytics: agregados por provedor com filtro --period/--provider
- budget list|get|set|reset: gerenciamento de budgets de custo
- quota: estado de quota por provedor com --check
- logs: call-logs com --search, --since, --api-key e --follow (tail 2s)
- utilization: métricas de uso por API key
- history: histórico de requisições
- proxy-logs: logs em nível de proxy

API keys mascaradas em outputs human. Todos os subcomandos suportam
--output json/table/csv/jsonl via emit().
2026-05-15 00:59:21 -03:00
diegosouzapw
993cd32829 feat(cli): adicionar comando cost com breakdown de custos (Fase 2.4)
Implementa `omniroute cost` que consulta /api/usage/analytics com:
- --period <range>: 1d|7d|30d|90d|ytd|all (padrão: 30d)
- --since/--until: faixa de datas ISO (substitui --period)
- --group-by: provider|model|api-key|combo|day (padrão: provider)
- --api-key: filtrar por chave específica
- --limit: top N resultados
- Total em stderr ao final (modo tabela)
- Ordenação por custo decrescente
2026-05-15 00:52:15 -03:00
diegosouzapw
18e5bf26a6 feat(cli): adicionar comando simulate para dry-run de routing (Fase 2.3)
Implementa `omniroute simulate [prompt]` que consulta /api/combos,
/api/monitoring/health e /api/usage/quota para mostrar qual caminho
de routing seria escolhido sem executar chamada upstream. Suporta:
- Tabela com provider, model, probabilidade, custo estimado, breaker e quota
- --explain: imprime árvore de fallback e faixa de custo no stderr
- --output json: retorna array de targets completo
- --file <path>: carrega body JSON para estimar tokens
- --combo <name>: filtra por combo específico
- Tratamento gracioso quando servidor está offline (exit 3)
2026-05-15 00:45:35 -03:00
diegosouzapw
7c128b0f4e feat(cli): adicionar comando stream com inspeção SSE (Fase 2.2)
Implementa `omniroute stream [prompt]` com suporte a:
- --raw: imprime linhas SSE brutas sem parsing
- --debug: timing por chunk no stderr com timestamp relativo
- --save <path>: persiste eventos em arquivo .jsonl
- --output json: retorna chunks + métricas (TTFT, totalMs, tokens/s)
- --responses-api: usa /v1/responses e lê campo delta
- SIGINT gracioso via reader.cancel()
- Métricas de TTFT e tokens/s no stderr ao final
2026-05-15 00:36:41 -03:00
diegosouzapw
685954c0dd feat(cli): adicionar comando chat one-shot (Fase 2.1)
Implementa `omniroute chat [prompt]` com suporte a --file, --stdin, --system,
--model, --max-tokens, --temperature, --top-p, --reasoning-effort,
--thinking-budget, --combo, --responses-api, --stream e --no-history.

Respostas impressas no stdout; latência e token count no stderr (não interfere
em pipes). Histórico salvo em ~/.omniroute/cli-history.jsonl. Streaming via
SSE com print incremental de deltas.
2026-05-15 00:28:36 -03:00
diegosouzapw
a5fa94bdcb feat(cli): crash recovery com backoff exponencial e PID granular (Fase 1.9)
Adiciona ServerSupervisor (bin/cli/runtime/processSupervisor.mjs) que reinicia o
servidor com backoff exponencial (1s, 2s, 4s... cap 10s) em caso de crash.
Após maxRestarts falhas em 30s exibe crash log e encerra. Detecta MITM como
causa do crash via heurística e desabilita automaticamente.

PID management agora é granular por subprocesso (~/.omniroute/{service}/.pid)
suportando server, mitm e tunnel/cloudflared|tailscale. `stop` e
`killAllSubprocesses` encerram todos os serviços registrados.

Novas opções em `serve`: --log (passa stdout/stderr inline), --no-recovery
(comportamento legado sem supervisor), --max-restarts <n> (padrão 2).
2026-05-15 00:18:53 -03:00
diegosouzapw
162e2f4b98 feat(cli): migrar backup/restore/health/quota/cache/mcp/a2a/tunnel/env/test/completion (Fase 1.4) 2026-05-14 23:24:52 -03:00
diegosouzapw
22d27ca273 feat(cli): migrar serve/stop/restart/dashboard/keys/models/combo (Fase 1.3)
Extrai 7 grupos de comandos do monolito bin/cli-commands.mjs (2853 linhas)
para módulos individuais em bin/cli/commands/, registrados via Commander.

- stop.mjs: SIGTERM/SIGKILL via process.kill(); fallback por porta usa execFile
  com array de args (evita injeção de shell / Semgrep CWE-78)
- restart.mjs: delega para runStopCommand + runServe
- dashboard.mjs: alias "open", fallback nativo por plataforma via execFile
- keys.mjs: server-first (POST /api/v1/providers/keys) → DB fallback; valida
  provider via loadAvailableProviders(); suporte a --stdin
- models.mjs: GET /api/models → fallback /api/v1/models; filtro por provider e --search
- combo.mjs: list/switch/create/delete; switch server-first → DB fallback via key_value;
  TODO(1.5) marcados para substituir SQL cru por src/lib/db/combos.ts
- serve.mjs: escreve PID via writePidFile() no spawn; limpa no shutdown; suporte daemon

utils/pid.mjs e i18n keys (en.json + pt-BR.json) já criados em iteração anterior.

Testes: cli-keys-command.test.ts atualizado para novos runners;
        cli-serve-stop-command.test.ts, cli-combo-command.test.ts,
        cli-models-command.test.ts adicionados (23 testes, 0 falhas).
2026-05-14 23:11:30 -03:00
diegosouzapw
31031422d3 feat(cli): adotar Commander.js como framework CLI (Fase 1.1)
- Instala commander@^14.0.0 com suporte nativo a ESM
- Cria bin/cli/program.mjs: programa raiz com opções globais
  (--output, --quiet, --no-color, --timeout, --api-key, --base-url)
- Cria bin/cli/commands/registry.mjs: adaptadores legados que delegam
  para os run*Command existentes sem quebrar compatibilidade
- Cria bin/cli/commands/serve.mjs: ação padrão (isDefault: true) com
  lógica de spawn extraída de omniroute.mjs, imports de runtime lazy
- Cria bin/cli/commands/reset-encrypted-columns.mjs: bypass de recuperação
- Refatora bin/omniroute.mjs: ~500 → ~90 linhas, delega ao Commander
- Adiciona strings i18n program.* e serve.description/port/no_open/daemon
  em en.json e pt-BR.json
- Adiciona 21 testes em tests/unit/cli-program.test.ts
2026-05-14 22:09:53 -03:00
diegosouzapw
2e494f8f07 feat(cli): Fase 0.3 — helpers base + convenções (api, i18n, output, runtime)
- bin/cli/CONVENTIONS.md: fonte normativa de flags, exit codes, output,
  retry/backoff, i18n, secrets, auditoria de ações destrutivas
- bin/cli/api.mjs: apiFetch() com retry/backoff, Retry-After, ApiError,
  statusToExitCode, isServerUp; computeBackoff/shouldRetryStatus exportados
- bin/cli/runtime.mjs: withRuntime/withHttp/withDb — server-first / DB-fallback;
  ServerOfflineError com exitCode 3
- bin/cli/i18n.mjs: t() com Map achatado (sem bracket em prototype), interpolação
  {vars}, setLocale/detectLocale/resetForTests; hardened contra __proto__ traversal
- bin/cli/output.mjs: emit() (table/json/jsonl/csv), EXIT_CODES, maskSecret,
  printSuccess/printError/printWarning/exitWith; output → stdout, diagnóstico → stderr
- bin/cli/locales/en.json + pt-BR.json: strings base (setup/doctor/providers/
  keys/combo/serve/backup/update/health/mcp/tunnel)
- bin/cli/README.md: mapa da estrutura e guia de uso dos helpers
- tests/unit/cli-exit-codes.test.ts: 10 casos — EXIT_CODES, statusToExitCode,
  backoff exponencial, jitter ±25%, t() i18n com pt-BR e anti-__proto__
- .env.example + docs/reference/ENVIRONMENT.md: documentar 4 novas env vars CLI
  (OMNIROUTE_LANG, OMNIROUTE_CLI_TOKEN, OMNIROUTE_HTTP_TIMEOUT_MS, OMNIROUTE_VERBOSE)
- scripts/check/check-env-doc-sync.mjs: adicionar LC_MESSAGES ao allowlist de sistema
2026-05-14 21:42:57 -03:00