Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ae2a0e3
chore(release): v3.8.24 — cycle open
diegosouzapw Jun 13, 2026
62a0f6a
fix(publish): clean opencode-plugin node_modules after tsup build to …
diegosouzapw Jun 13, 2026
33667fc
fix(cli): coerce ServerSupervisor exit code to number — prevents Type…
diegosouzapw Jun 13, 2026
de12d1c
Expose emergency fallback in Feature Flags (#3752)
rdself Jun 13, 2026
15ab183
Fix Request Logs clean history purge (#3751)
rdself Jun 13, 2026
01b1dab
Inject memory into Codex Responses WebSocket requests (#3749)
kkkayye Jun 13, 2026
37116fd
fix(antigravity): skip credits retry on full_quota_exhausted, persist…
diegosouzapw Jun 13, 2026
c5924a7
Preserve xhigh reasoning effort by default (#3756)
rdself Jun 13, 2026
da58330
fix logs light mode controls (#3760)
rdself Jun 13, 2026
d8b6ae3
fix(dashboard): self-host Material Symbols icon font (#3695) (#3764)
diegosouzapw Jun 13, 2026
d1088f0
fix(oauth): preserve non-rotating providers' refresh_token on unrecov…
diegosouzapw Jun 13, 2026
06e85a9
fix: preserve streamed tool call arguments (#3762)
Mffff4 Jun 13, 2026
0e07eb0
fix(providers): repair qwen-web validation + stop mislabeling benign …
diegosouzapw Jun 13, 2026
3c8f347
fix(providers): correct Ollama Cloud kimi-k2.7-code capabilities (#37…
diegosouzapw Jun 13, 2026
f7d895e
Quality Gates → 100% (Fase 6A + Fase 7 + plano Fase 8) (#3757)
diegosouzapw Jun 13, 2026
32b0f93
fix(docs): correct OAuth redirect URI to /callback in Fly.io guide (#…
diegosouzapw Jun 13, 2026
f3cc266
fix(mcp): resolve server entry from dist/ instead of app/ (#3765)
megamen32 Jun 13, 2026
27c5772
chore(quality): re-baseline providerRegistry.ts file-size (4692→4703)…
diegosouzapw Jun 13, 2026
969adde
fix(cursor): add ModelDetails envelope so pinned thinking models reso…
diegosouzapw Jun 13, 2026
821a1f0
fix(dashboard): repair Playground model selector for custom providers…
diegosouzapw Jun 13, 2026
e4f1324
fix(cli): enrich lookup PATH with the macOS login-shell PATH for CLI …
diegosouzapw Jun 13, 2026
f842eba
docs: close remaining proxy/skills/memory/rtk/compression gaps (#3453)
oyi77 Jun 13, 2026
7efd407
feat: custom plugin marketplace support (#3656)
oyi77 Jun 13, 2026
abbbf90
chore(docs): prune internal planning/spec artifacts + sync i18n CHANG…
diegosouzapw Jun 13, 2026
7f23fb5
fix(security): harden marketplace SSRF guard (IPv6/redirect/DNS-rebin…
diegosouzapw Jun 13, 2026
1aac066
fix(security): resolve CodeQL + Dependabot alerts (cache-key hash FP,…
diegosouzapw Jun 13, 2026
c0a57d2
fix(sse): pass Claude passthrough thinking blocks through unchanged (…
havockdev Jun 13, 2026
6956edc
fix(anthropic): normalize sampling params under extended thinking (te…
zhiru Jun 13, 2026
7219f2b
feat(proxy): IPv6-only egress enforcement + close IP-leak paths (#3777)
diegosouzapw Jun 13, 2026
d4f253b
feat(api-keys): strict-mode controls for Claude Code default models (…
Witroch4 Jun 13, 2026
0a68f51
chore(release): reconcile v3.8.24 CHANGELOG — full commit coverage + …
diegosouzapw Jun 13, 2026
971b54c
docs: refresh root + docs/ documentation to current architecture (v3.…
diegosouzapw Jun 13, 2026
b444f51
docs(changelog): record the v3.8.24 documentation refresh under Maint…
diegosouzapw Jun 13, 2026
db6b408
fix(docs): stop check:doc-links false-positive on its own QUALITY_GAT…
diegosouzapw Jun 13, 2026
45b0672
Combo + quota-shared deep audit: 5 fixes + strategy validation + E2E …
diegosouzapw Jun 13, 2026
0c5ae0e
refactor: modularize 3.2K-line usage.ts (Issue #3594)
oyi77 Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,13 @@ NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=true
# ALL_PROXY=socks5://127.0.0.1:7890
# NO_PROXY=localhost,127.0.0.1

# Proxy fail-open mode (default: false = fail-closed).
# When false, a request whose assigned proxy fails to resolve is REFUSED rather than
# falling back to a direct connection — prevents real-IP leaks in egress-controlled
# deployments. Set true to restore the legacy DIRECT fallback (legacy behaviour).
# Used by: src/sse/handlers/chatHelpers.ts
# PROXY_FAIL_OPEN=false

# TLS fingerprint spoofing (opt-in) — mimics Chrome 124 TLS handshake via wreq-js.
# Reduces risk of JA3/JA4 fingerprint-based blocking by providers (e.g., Google).
# Used by: open-sse/executors — replaces Node.js default TLS fingerprint.
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ jobs:
- run: npm run check:known-symbols
- run: npm run check:route-guard-membership
- run: npm run check:test-discovery
- run: npm run check:tracked-artifacts
- run: npm run check:lockfile
- run: npm run check:licenses
- run: npm run check:docs-sync
- run: npm run typecheck:core
# typecheck:noimplicit:core is a forward-looking gate (noImplicitAny).
Expand Down Expand Up @@ -102,6 +105,43 @@ jobs:
path: .artifacts/quality-ratchet.md
if-no-files-found: warn

# Phase 7 extended quality gates — ADVISORY (continue-on-error). The 5 npm-based
# ratchets (dead-code/cognitive-complexity/type-coverage/circular-deps/bundle-size)
# run for real. The external scans (vuln/secrets/workflows) skip gracefully until the
# owner adds install steps for osv-scanner/gitleaks/actionlint/zizmor; CodeQL ratchet
# works via the runner's gh token. SonarQube needs SONAR_TOKEN/SONAR_HOST_URL secrets.
quality-extended:
name: Quality Gates (Extended, advisory)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ env.CI_NODE_VERSION }}
cache: npm
- run: npm ci
- name: Dead-code (knip)
run: npm run check:dead-code
- name: Cognitive complexity (sonarjs)
run: npm run check:cognitive-complexity
- name: Type coverage
run: npm run check:type-coverage
- name: Circular deps (dpdm)
run: npm run check:circular-deps
- name: Bundle size
run: npm run check:bundle-size
- name: CodeQL alerts ratchet
run: npm run check:codeql-ratchet
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Secret scan (gitleaks; skips if absent)
run: npm run check:secrets
- name: Vulnerability ratchet (osv-scanner; skips if absent)
run: npm run check:vuln-ratchet
- name: Workflow lint (actionlint+zizmor; skips if absent)
run: npm run check:workflows

docs-sync-strict:
name: Docs Sync (Strict)
runs-on: ubuntu-latest
Expand Down Expand Up @@ -198,6 +238,11 @@ jobs:
# Anti test-masking: flag net assert removal / new assert.ok(true) in changed tests.
- name: Detect test-masking (weakened assertions)
run: npm run check:test-masking
# Evidence-in-PR-body (Hard Rule #18 mechanized): claims of "tests pass" must carry output.
- name: Require evidence in PR body
run: npm run check:pr-evidence
env:
PR_BODY: ${{ github.event.pull_request.body }}
- name: Publish PR test policy summary
if: always()
run: |
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Quality Gates

on:
pull_request:
branches: ["release/**"]
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
CI_NODE_VERSION: "24"

jobs:
fast-gates:
name: Fast Quality Gates
runs-on: ubuntu-latest
# tsx gates (known-symbols, route-guard-membership) import modules that open
# SQLite on load; provide DB env so a fresh CI DB initializes cleanly.
env:
JWT_SECRET: ci-lint-secret-with-sufficient-length-for-validation
API_KEY_SECRET: ci-lint-api-key-secret-long
DISABLE_SQLITE_AUTO_BACKUP: "true"
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ env.CI_NODE_VERSION }}
cache: npm
- run: npm ci
- run: npm run check:provider-consistency
- run: npm run check:fetch-targets
- run: npm run check:openapi-routes
- run: npm run check:docs-symbols
- run: npm run check:deps
- run: npm run check:file-size
- run: npm run check:error-helper
- run: npm run check:migration-numbering
- run: npm run check:public-creds
- run: npm run check:db-rules
- run: npm run check:known-symbols
- run: npm run check:route-guard-membership
- run: npm run check:test-discovery
- run: npm run check:any-budget:t11
68 changes: 68 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# .gitleaks.toml — Configuração do gitleaks para OmniRoute
# Task 7.18 — PLANO-QUALITY-GATES-FASE7.md
#
# Estende as regras padrão do gitleaks com allowlists específicas do projeto.
#
# INSTRUÇÕES para allowlists:
# Findings legítimos (fixtures de teste, creds OAuth públicas já cobertas pelo
# check-public-creds.mjs, valores de exemplo em docs) devem ser registrados abaixo
# em [[allowlist]] com um comentário explicativo obrigatório.
#
# NÃO adicione uma entrada de allowlist sem justificativa. Cada entrada é revisada
# a cada release (stale-enforcement). Regra: se o finding é um valor real que o
# sistema usa em produção, é um verdadeiro positivo — não allowliste, corrija.
#
# Referência: docs/security/PUBLIC_CREDS.md (credenciais OAuth públicas conhecidas)
# CLAUDE.md Hard Rule #11 (resolvePublicCred obrigatório)

# Usar as regras padrão do gitleaks (não declaramos [rules] aqui para herdar tudo)
# Para desabilitar uma regra específica, usar:
# [[rules]]
# id = "rule-id"
# [rules.allowlist]
# description = "..."

# ---------------------------------------------------------------------------
# Allowlist global do projeto
# Entradas aqui são ignoradas em TODAS as varreduras.
# ---------------------------------------------------------------------------
[allowlist]
description = "OmniRoute project-level allowlist — fixtures, test vectors, public OAuth creds"

# Paths a ignorar completamente (node_modules, builds, etc.)
paths = [
'''node_modules''',
'''\.next''',
'''dist''',
'''\.git''',
'''coverage''',
'''\.nyc_output''',
]

# Commits específicos a ignorar (ex: commit que introduziu fixtures de teste)
# commits = []

# Regexes de stopwords — linhas que contêm estes padrões são ignoradas.
# Usar apenas para falsos positivos comprovados com justificativa abaixo.
# stopwords = []

# Regexes de targets (paths de arquivos) que podem ser allowlistados por regra.
# Ver [[allowlist]] por-regra abaixo para granularidade.

# ---------------------------------------------------------------------------
# Allowlist por-regra (adicionar conforme necessário durante o stale review)
# ---------------------------------------------------------------------------
#
# Exemplo (REMOVER / SUBSTITUIR por entradas reais quando necessário):
#
# [[rules]]
# # Allowlistar fixtures de teste que contêm tokens OAuth de exemplo/inválidos
# # Adicionado: 2026-06-13 | Revisar em: v3.9.0 | Justificativa: valores não-reais de teste
# id = "github-fine-grained-pat"
# [rules.allowlist]
# description = "Test fixture PATs — valores sintéticos, não funcionais"
# paths = [
# '''tests/fixtures/''',
# '''tests/unit/''',
# ]
#
16 changes: 10 additions & 6 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/usr/bin/env sh
#if ! command -v npm >/dev/null 2>&1; then
# echo "⚠️ npm not found in PATH — skipping pre-push hooks"
# echo " Run 'npm test' manually before pushing."
# exit 0
#fi
# .husky/pre-push — fast deterministic gates (<10s total)
# Intentionally excludes test:unit (slow; covered by CI pre-push remote run).
# Activated: 2026-06-13 (6A.12 — replaced commented-out test:unit stub)

#npm run test:unit
if ! command -v npm >/dev/null 2>&1; then
echo "⚠️ npm not found in PATH — skipping pre-push hooks"
echo " Run 'npm run check:any-budget:t11 && npm run check:tracked-artifacts' manually before pushing."
exit 0
fi

npm run check:any-budget:t11 && npm run check:tracked-artifacts
85 changes: 85 additions & 0 deletions .license-allowlist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"_comment": "SPDX license allowlist for OmniRoute (MIT project). Task 7.20 / PLANO-QUALITY-GATES-FASE7.md.",
"_policy": "Production deps with a license outside 'allowed' and not in 'exceptions' fail the gate. devDeps get an advisory warning only.",

"allowed": [
"MIT",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"0BSD",
"CC0-1.0",
"Unlicense",
"Python-2.0",
"BlueOak-1.0.0",
"Artistic-2.0",
"Zlib",
"X11",
"WTFPL",
"PSF-2.0",
"CC-BY-3.0"
],

"allowedExpressions": [
"MIT*",
"MIT AND ISC",
"Apache-2.0 AND MIT",
"(MIT OR Apache-2.0)",
"(MIT OR CC0-1.0)",
"(MIT OR WTFPL)",
"(BSD-2-Clause OR MIT OR Apache-2.0)",
"(MPL-2.0 OR Apache-2.0)"
],

"exceptions": {
"@img/sharp-libvips-linux-x64": {
"license": "LGPL-3.0-or-later",
"justification": "Prebuilt native binary (libvips shared library) pulled in transitively by the 'sharp' package (optional dep of next/transformers). LGPL-3.0 on dynamically-linked native code allows use in non-GPL applications as long as the user can replace the library — satisfied here because this is a pre-built shared-object (.so) binary distributed by the sharp project, not source linked into OmniRoute code. OmniRoute does not modify or statically link libvips.",
"risk": "low",
"reviewAt": "v4.0.0"
},
"@img/sharp-libvips-linuxmusl-x64": {
"license": "LGPL-3.0-or-later",
"justification": "Same rationale as @img/sharp-libvips-linux-x64 — musl variant of the same prebuilt libvips shared library. Dynamically linked, not modified, not statically bundled.",
"risk": "low",
"reviewAt": "v4.0.0"
},
"lightningcss": {
"license": "MPL-2.0",
"justification": "MPL-2.0 is a weak, file-level copyleft: only modifications to MPL-licensed files must be released under MPL. OmniRoute does not modify lightningcss source. It is pulled in transitively as a runtime dep of vite (via monaco-editor, a production dep). MPL-2.0 is explicitly compatible with Apache/MIT combinations per the Mozilla FAQ and is routinely used in Node.js production stacks. The OmniRoute codebase remains MIT.",
"risk": "low",
"reviewAt": "v4.0.0"
},
"lightningcss-linux-x64-gnu": {
"license": "MPL-2.0",
"justification": "Platform-specific native binding for lightningcss. Same MPL-2.0 rationale as lightningcss itself: file-level copyleft, not modified by OmniRoute, compatible with MIT project.",
"risk": "low",
"reviewAt": "v4.0.0"
},
"lightningcss-linux-x64-musl": {
"license": "MPL-2.0",
"justification": "Musl variant of lightningcss native binding. Same MPL-2.0 rationale.",
"risk": "low",
"reviewAt": "v4.0.0"
},
"dompurify": {
"license": "(MPL-2.0 OR Apache-2.0)",
"justification": "dompurify is dual-licensed: MPL-2.0 OR Apache-2.0. The Apache-2.0 option is permissive and compatible with MIT. OmniRoute uses it indirectly via monaco-editor and mermaid (UI rendering). The gate expression matcher already accepts (MPL-2.0 OR Apache-2.0) as an allowed expression, but this exception is kept for explicitness and audit trail.",
"risk": "none",
"reviewAt": "v4.0.0"
},
"caniuse-lite": {
"license": "CC-BY-4.0",
"justification": "CC-BY-4.0 applies to the caniuse browser-support data (a dataset, not code). The Creative Commons Attribution license requires attribution when distributing — OmniRoute does not distribute caniuse-lite data directly to end users; it is consumed by browserslist/PostCSS at build time to generate CSS compatibility info. This is a widely accepted pattern in the Node.js ecosystem (caniuse-lite is in millions of projects). Attribution is satisfied by keeping the package in node_modules with its original license file.",
"risk": "low",
"reviewAt": "v4.0.0"
},
"tls-client-node": {
"license": "Custom: LICENSE (Apache-2.0 + Commons Clause)",
"justification": "TODO: revisar — tls-client-node uses Apache-2.0 with a 'Commons Clause' addendum that restricts 'Selling' the software (i.e., offering it as a hosted/commercial service whose value derives substantially from tls-client-node). OmniRoute is an open-source proxy; however if deployed as a paid SaaS/hosting service, this restriction could apply. The package is used by grokTlsClient.ts for Grok TLS fingerprinting. RISK: medium — legal review recommended before commercial deployment. Alternatives: consider replacing with a native TLS fingerprinting approach or a truly permissive library.",
"risk": "medium",
"reviewAt": "v3.9.0"
}
}
}
22 changes: 22 additions & 0 deletions .size-limit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"name": "CLI entry (omniroute.mjs)",
"path": "bin/omniroute.mjs",
"limit": "15 KB"
},
{
"name": "MCP server entry (mcp-server.mjs)",
"path": "bin/mcp-server.mjs",
"limit": "5 KB"
},
{
"name": "Node runtime support (nodeRuntimeSupport.mjs)",
"path": "bin/nodeRuntimeSupport.mjs",
"limit": "8 KB"
},
{
"name": "Reset password entry (reset-password.mjs)",
"path": "bin/reset-password.mjs",
"limit": "6 KB"
}
]
1 change: 0 additions & 1 deletion .source/source.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ var docs = defineDocs({
dir: "docs",
docs: {
files: [
"./getting-started/**/*.md",
"./architecture/**/*.md",
"./guides/**/*.md",
"./reference/**/*.md",
Expand Down
51 changes: 51 additions & 0 deletions .zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# .zizmor.yml — zizmor security audit configuration
# https://github.com/woodruffw/zizmor
#
# zizmor audits GitHub Actions workflows for security anti-patterns:
# • Unpinned third-party actions (supply-chain risk)
# • Script injection via ${{ github.* }} in run: steps
# • pull_request_target misuse (allows untrusted code to reach secrets)
# • Excessive permissions / overly broad GITHUB_TOKEN scopes
# • Cache poisoning via actions/cache with unguarded keys
# • … 20+ additional audits
#
# MOTIVATION (2026-03 incident): the trivy-action/LiteLLM supply-chain attack
# exploited exactly the kind of pull_request_target misconfiguration that zizmor
# detects statically. OmniRoute's npm/Docker/Electron publish workflows are high-
# value targets that warrant proactive audit.
#
# BASELINE STRATEGY: this file starts with an EMPTY ignores list. As zizmor is
# first run against the existing workflows, findings will be reviewed:
# • True positives → fix the workflow (preferred)
# • Accepted risk → add an entry below with a justification comment
# This enforces the same stale-enforcement discipline as other allowlists in
# this project: every ignore requires human sign-off and is subject to review
# at each release cycle.
#
# RATCHET: zizmorFindings metric in quality-baseline.json (direction: down)
# starts advisory; current baseline is frozen at first green run; new findings
# must be remediated or explicitly ignored here.

# ── Global settings ──────────────────────────────────────────────────────────
# Uncomment to pin to a specific minimum severity level.
# min-severity: low # low | medium | high | critical (default: low = all)

# ── Per-finding ignores ──────────────────────────────────────────────────────
# Format:
# ignores:
# - id: <zizmor-audit-id> # e.g. "unpinned-uses", "script-injection"
# reason: "<justification>"
# # Optional: scope to a specific workflow or step
# # workflow: .github/workflows/ci.yml
#
# Example (do not uncomment without real justification):
#
# ignores:
# - id: unpinned-uses
# reason: >
# actions/checkout@v6 is pinned at the major-version tag intentionally:
# GitHub-managed first-party action; SHA pinning buys little against a
# GitHub-side compromise and adds significant maintenance burden.
# workflow: .github/workflows/ci.yml

ignores: []
Loading