Release v3.8.40

v3.8.40 cycle integration → main. All test gates green (Unit/Integration/Coverage/Node-compat/Quality-Ratchet). The only red check, 'PR Test Policy', is the test-masking heuristic firing on the cumulative ~57-commit release diff (legitimate assert consolidations already reviewed per-PR — Gemini CLI removal #5246, retired GPT models #5280, provider catalog refreshes); overridden with --admin per the documented release-PR convention. CodeQL/SonarQube advisory scans non-blocking; #5278's code already passed CodeQL on main. Homologated on VPS 192.168.0.15 (v3.8.40 healthy).
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-29 08:40:06 -03:00
committed by GitHub
parent 1c18be4f8f
commit 7c23dab64d
1007 changed files with 16451 additions and 21343 deletions

View File

@@ -58,13 +58,9 @@ export const KNOWN_STALE_DOC_REFS = new Set([
// existing guardrailRegistry); the fictional enable/disable/logs rows and the entire
// shadow table were removed from the doc (shadow A-B comparison is combo-config +
// /api/combos/metrics). No allowlist entries needed for these anymore.
// docs/research/DISCOVERY_TOOL_DESIGN.md — design doc de feature NÃO implementada
// (Phase 2). Refs INTENCIONAIS: o doc agora traz um banner "⚠️ Not yet implemented
// — Phase 2" acima da tabela de endpoints. Mantidos aqui até a feature existir. — #3498
"/api/discovery/results",
"/api/discovery/results/:id",
"/api/discovery/scan",
"/api/discovery/verify/:id",
// (DISCOVERY_TOOL_DESIGN.md saiu de docs/research/ para o repo isolado _tasks/research/
// — gitignored, fora do escopo deste gate. As 4 entradas /api/discovery/* viraram
// obsoletas e foram removidas para satisfazer o stale-enforcement da allowlist.)
// docs/reference/ENVIRONMENT.md — endpoint UPSTREAM do provedor Blackbox Web,
// citado na descrição de env var (não é rota do OmniRoute):
"/api/chat",
@@ -85,9 +81,7 @@ function walk(dir, filter, acc = []) {
export function collectRouteFiles() {
return new Set(
walk(API, (n) => /^route\.tsx?$/.test(n)).map((p) =>
path.relative(ROOT, p).replace(/\\/g, "/")
)
walk(API, (n) => /^route\.tsx?$/.test(n)).map((p) => path.relative(ROOT, p).replace(/\\/g, "/"))
);
}

View File

@@ -107,8 +107,6 @@ const ENV_VAR_ALLOWLIST = new Set([
"NINEROUTER_API_KEY", // injected into the 9router subprocess at spawn (EMBEDDED-SERVICES.md)
"CLAUDE_CODE_MAX_OUTPUT_TOKENS", // Claude Code CLI's own env var (CODEX-CLI-CONFIGURATION.md)
"CODEX_HOME", // Codex CLI's own config-home env var (CODEX-CLI-CONFIGURATION.md)
"GEMINI_API_KEY", // Gemini CLI's own API-key env var, set by `omniroute setup-gemini` (REMOTE-MODE.md)
"GOOGLE_GEMINI_BASE_URL", // Gemini CLI's own base-URL env var, set by `omniroute setup-gemini` (REMOTE-MODE.md)
"OPENAI_API_BASE", // legacy OpenAI base-URL env var some downstream tools (e.g. Aider) read (CLI-INTEGRATIONS.md)
"PROMPTFOO_PROVIDER_KEY", // promptfoo's own provider-key env var, used by the red-team suite (GUARDRAILS.md)
"REDIS_PORT", // docker-compose host-port override (DOCKER_GUIDE.md)
@@ -361,9 +359,6 @@ const SKIP_DOC_FILES = new Set([
"docs/reference/PROVIDER_REFERENCE.md", // auto-generated from providers.ts
"docs/openapi.yaml",
"docs/i18n", // translations — separate workflow
// Point-in-time documentation audit (v3.8.24): intentionally references drift,
// counts, and not-yet-existing files as part of documenting them — not living docs.
"docs/ops/DOCUMENTATION_AUDIT_REPORT.md",
// Design / research / plan docs: by definition describe not-yet-built files and
// proposed (not-yet-shipped) endpoints (each carries a `Status: Design`/`Active
// research`/`Plano` header). Same rationale as the audit report above — these are

View File

@@ -181,8 +181,6 @@ export const KNOWN_TRANSLATOR_PAIRS: readonly string[] = [
"claude:gemini",
"claude:openai",
"cursor:openai",
"gemini-cli:claude",
"gemini-cli:openai",
"gemini:claude",
"gemini:openai",
"kiro:openai",
@@ -191,7 +189,6 @@ export const KNOWN_TRANSLATOR_PAIRS: readonly string[] = [
"openai:claude",
"openai:cursor",
"openai:gemini",
"openai:gemini-cli",
"openai:kiro",
"openai:openai-responses",
];
@@ -200,10 +197,7 @@ export const KNOWN_TRANSLATOR_PAIRS: readonly string[] = [
* Pares frozen que sumiram do registry vivo (regressão). frozen = snapshot;
* live = pares observados em runtime. Retorna os que estão no frozen mas não no live.
*/
export function findMissingTranslatorPairs(
frozen: readonly string[],
live: Set<string>
): string[] {
export function findMissingTranslatorPairs(frozen: readonly string[], live: Set<string>): string[] {
return frozen.filter((pair) => !live.has(pair));
}
@@ -375,10 +369,7 @@ export type A2ASkillDiff = {
* - inHandlersNotCard: skill is routable but agents can't discover it
* - inCardNotHandlers: skill is advertised but calling it fails silently
*/
export function diffA2ASkills(
handlers: Set<string>,
agentCard: Set<string>
): A2ASkillDiff {
export function diffA2ASkills(handlers: Set<string>, agentCard: Set<string>): A2ASkillDiff {
const inHandlersNotCard = [...handlers].filter((s) => !agentCard.has(s)).sort();
const inCardNotHandlers = [...agentCard].filter((s) => !handlers.has(s)).sort();
return { inHandlersNotCard, inCardNotHandlers };
@@ -456,13 +447,12 @@ async function main(): Promise<void> {
const executorsMod = await import("@omniroute/open-sse/executors/index.ts");
const getExecutor = executorsMod.getExecutor as (alias: string) => ExecutorLike;
const BaseExecutor = executorsMod.BaseExecutor as new (...args: never[]) => unknown;
const indexSource = readFileSync(
resolvePath(REPO_ROOT, "open-sse/executors/index.ts"),
"utf8"
);
const indexSource = readFileSync(resolvePath(REPO_ROOT, "open-sse/executors/index.ts"), "utf8");
const aliases = extractExecutorAliases(indexSource);
if (aliases.length === 0) {
failures.push("[executor] parse do mapa `executors` não encontrou nenhum alias (regex quebrada?)");
failures.push(
"[executor] parse do mapa `executors` não encontrou nenhum alias (regex quebrada?)"
);
}
const isExecutorInstance = (value: unknown) => value instanceof BaseExecutor;
const badExecutors = findNonConformingExecutors(aliases, getExecutor, isExecutorInstance);
@@ -493,7 +483,11 @@ async function main(): Promise<void> {
// EMPTY implicit-defaults map). An entry whose key IS already in `handled` suppresses
// nothing → it is stale and the gate must fail asking for its removal.
const liveImplicitNeeded = diffComboStrategies(canonical, handled, {}).canonicalNotHandled;
assertNoStale(Object.keys(IMPLICIT_DEFAULT_STRATEGIES), liveImplicitNeeded, "known-symbols:combo");
assertNoStale(
Object.keys(IMPLICIT_DEFAULT_STRATEGIES),
liveImplicitNeeded,
"known-symbols:combo"
);
const { canonicalNotHandled, handledNotCanonical } = diffComboStrategies(
canonical,
@@ -554,9 +548,8 @@ async function main(): Promise<void> {
const { MCP_TOOLS } = await import("@omniroute/open-sse/mcp-server/schemas/tools.ts");
const { memoryTools } = await import("@omniroute/open-sse/mcp-server/tools/memoryTools.ts");
const { skillTools } = await import("@omniroute/open-sse/mcp-server/tools/skillTools.ts");
const { gamificationTools } = await import(
"@omniroute/open-sse/mcp-server/tools/gamificationTools.ts"
);
const { gamificationTools } =
await import("@omniroute/open-sse/mcp-server/tools/gamificationTools.ts");
const { pluginTools } = await import("@omniroute/open-sse/mcp-server/tools/pluginTools.ts");
const { notionTools } = await import("@omniroute/open-sse/mcp-server/tools/notionTools.ts");
const { obsidianTools } = await import("@omniroute/open-sse/mcp-server/tools/obsidianTools.ts");
@@ -669,7 +662,9 @@ async function main(): Promise<void> {
// ── Resultado ─────────────────────────────────────────────────────────────
if (failures.length) {
console.error(`[known-symbols] ${failures.length} sub-checagem(ns) falharam:\n\n${failures.join("\n\n")}`);
console.error(
`[known-symbols] ${failures.length} sub-checagem(ns) falharam:\n\n${failures.join("\n\n")}`
);
process.exit(1);
}
// assertNoStale (combo) seta process.exitCode=1 sem lançar — não imprima o OK
@@ -695,7 +690,9 @@ async function main(): Promise<void> {
if (import.meta.url === pathToFileURL(process.argv[1] || "").href) {
main().catch((err) => {
console.error(`[known-symbols] erro fatal: ${err instanceof Error ? err.message : String(err)}`);
console.error(
`[known-symbols] erro fatal: ${err instanceof Error ? err.message : String(err)}`
);
process.exit(1);
});
}

View File

@@ -67,6 +67,7 @@ export const COLLECTORS = [
// vitest.mcp.config.ts — test:vitest
{ glob: "open-sse/mcp-server/__tests__/**/*.test.ts", sources: ["vitest.mcp.config.ts"] },
{ glob: "open-sse/services/autoCombo/__tests__/**/*.test.ts", sources: ["vitest.mcp.config.ts"] },
{ glob: "open-sse/services/combo/__tests__/**/*.test.ts", sources: ["vitest.mcp.config.ts"] },
// Single-file include: the rest of open-sse/services/__tests__/ are frozen orphans
// (empty/dormant stubs); only this one is wired to run under test:vitest.
{