fix(lint): drain release-green hard failures on release/v3.8.50 (#9985) - #11317
diegosouzapw merged 18 commits into
Conversation
…osouzapw#9985) - FirstRunReadinessCard: read dismissal via useSyncExternalStore instead of setState inside an effect (react-hooks/set-state-in-effect); hydration-safe - EndpointPageClient: drop dead code left by the Traffic Inspector header refactor (Link import, expandedEndpoint state, mcp/a2a status derivations, cloudflaredUrlNotice, EndpointSection component) and underscore the two intentionally-unused status bindings - CommandPalette: include activePreset in allItems memo deps (fixes exhaustive-deps and lets the compiler preserve the memoization) - cli-mcp-call/resilience/skills test files: remove or underscore unused helpers and fetch params flagged as net-new errors
…review repair
Follow-up to the lint-drain commit, two independent leftovers:
1. EditConnectionModal.tsx — drop the
eslint-disable-next-line react-hooks/set-state-in-effect directive.
It guards a conditional setState (isOpen/connection guard), which the
rule does not flag, so ESLint reported an unused disable and failed
the 'No new ESLint warnings' gate for every branch at this tip.
2. tests/unit/cli-mcp-call-commands.test.ts — repair an over-broad rename
from the previous commit: its sweep renamed every '(url: string,
opts: unknown)' fetch-stub parameter to _url, including stubs whose
bodies reference url ('mcp call sends JSON-RPC initialize…' and
'prints result content' died with ReferenceError; CI unit shard 3
caught it). Restores those parameters; keeps genuinely unused ones
underscored.
9d1b9cc to
38514ff
Compare
…egosouzapw#9985) The prepublish Step 10.7 prune reused the npm-tarball rule (PACK_ARTIFACT_NEVER_ALLOWED_SEGMENTS = ['node_modules']), which overrides the staging allowlist. That deleted the standalone server's runtime deps — Turbopack-hashed sql.js (dist/sql-wasm.wasm!) and @huggingface/transformers ort-wasm — so packaged boots (dast-smoke, omniroute CLI) threw at instrumentation: '[sqljsAdapter] Packaged sql.js runtime is incomplete' and every DB-backed management route (/api/keys*, /api/auth/logout) returned 500 while /api/monitoring/health stayed green. findUnexpectedArtifactPaths gains a neverAllowedSegments option; the publish gate keeps the strict default, and the staging prune passes [] because its allowlist prefixes (.build/next/, node_modules/) are the runtime contract. RED→GREEN covered by pack-artifact-policy tests; live validation via dast-smoke on PR diegosouzapw#11317.
|
The prepublish Step 10.7 prune reused the npm-tarball rule findUnexpectedArtifactPaths gains a neverAllowedSegments option; the |
ESLint 9 exits 2 (not a report) when config/quality/eslint-suppressions.json contains entries that no longer occur — the lint-guard gate died on that instead of evaluating. The drain commits removed the underlying violations; this prunes their now-stale entries (counts only decrease; one no-unused-vars rule block fully resolved).
…stream ids (diegosouzapw#11326) Merging --admin with red discrimination (merge-gates §4). Fails: ESLint warnings ratchet drift (inherited base-red), Unit Tests shards containing stream-timing.test.ts (CPU-contention timing flake, assert.ok(total >= 15)ms — unrelated to this PR's scope, open-sse/handlers/imageGeneration.ts), and dast-smoke (advisory, isRequired:null).
…rve.tls_key (diegosouzapw#9985) Mirrors en.json parity for the CLI locale catalog — same gap as upstream diegosouzapw#11322 — letting tests/unit/i18n-pt-br.test.ts pass at this tip.
) i18nUiCoverage ratchet read 99.4 vs baseline 100: recent merges (diegosouzapw#11166/diegosouzapw#11178/diegosouzapw#11179/diegosouzapw#11224/diegosouzapw#11227/diegosouzapw#11283) shipped new UI keys without mirroring them into the 41 non-en catalogs. Fill via the documented EN- fallback convention (scripts/i18n/fill-missing-from-en.mjs semantics: absent keys only, never overwrite) so every locale reaches parity; translations can be refined in place later without touching code.
…rtener (diegosouzapw#11329) Validated on a 17-PR combined board: TSX parses clean, eslint clean. Adapta tutorial CTA href now points at the branded shortener (link.omniroute.online/adapta) while keeping the visible link text as the real domain. Completes diegosouzapw#11196's shortener rollout.
…ream (diegosouzapw#11328) Validated on a 17-PR combined board: upstream-headers-proxy-auth within the board's 287/287, typecheck:core clean, gates within baseline. proxy-authorization and proxy-authenticate join the FORBIDDEN denylist — forwarding proxy-authorization to a model provider would hand that provider the operator's own proxy credential. Thank you @ntdat812!
… 3 DB-state tests (diegosouzapw#11327) Validated on a 17-PR combined board: capture-critical-db-state 7/7 (all three previously-skipped tests now run) within the board's 287/287, typecheck:core clean. Fixes the racy DATA_DIR-after-dynamic-import isolation and removes a duplicate type declaration. Thank you @pacocartones!
…iegosouzapw#11325) Validated on a 17-PR combined board: i18n-placeholder-parity within the board's 287/287, typecheck:core clean. Restores 3 dropped placeholders in pt.json (the visible one: the cache tile's subtitle was repeating its own label instead of showing the total) and adds a 42-locale placeholder-set gate so this class of drift can't recur silently. Thank you @ntdat812!
…diegosouzapw#11322) Validated on a 17-PR combined board: typecheck:core clean, gates within baseline. Restores 3 missing pt-BR CLI keys (setup.opencode, serve.tls_cert, serve.tls_key) — parity restored, 823/823. Thank you @pacocartones!
…i.yml gates (diegosouzapw#11321) Validated on a 17-PR combined board: validate-release-green within the board's 287/287, typecheck:core clean. Two accuracy bugs in the release-green verdict tool: an unanchored regex blamed a passing test line (matching a filename containing 'fail'), and 6 gates were double-recorded as both hard-failure and drift due to an id-format mismatch (ci.yml script name vs curated id). Found while reading the diegosouzapw#9985 verdict — good catch.
…11320) Validated on a 17-PR combined board: token-health-check + token-health-no-refresh-token-expired-5326 + token-refresh-service within the board's 287/287, typecheck:core clean. GitHub access-token-only connections are now actively verified on each due health interval (via the existing Copilot token exchange); the parent credential is marked expired only on a confirmed 401, never on 403/429/5xx/network failures; response bodies and transport messages no longer enter token-refresh logs. Closes diegosouzapw#10352. Thank you @RaviTharuma!
…ouzapw#11319) Validated on a 17-PR combined board: upstream-proxy-host-spelling 8/8 within the board's 287/287, typecheck:core clean. Routes src/lib/db/upstreamProxy.ts through the shared outbound-guard helpers instead of a private dotted-quad regex copy that had drifted since diegosouzapw#10843 — closes the IPv4-mapped IPv6, ULA, link-local and CGNAT bypasses while preserving the deliberate loopback allow (CLIProxyAPI on localhost:8317). Multicast widened from /224\. to the full 224.0.0.0/4, called out explicitly. Thank you @ntdat812!
…souzapw#11318) Validated on a 17-PR combined board: compression-worker + colocate-standalone-esm-scope within the board's 287/287, typecheck:core clean, env-doc-sync clean. Offloads eligible sync compression engines into a bounded worker_threads pool with a strict serializable DTO boundary and fail-open on spawn/worker/timeout failure. Closes diegosouzapw#11023. Thank you @RaviTharuma!
Validated on a 17-PR combined board: gemini-tts + vertex-media + audio-speech-handler (41/41) within the board's 287/287, typecheck:core clean. Registers public google/gemini-*-tts speech models and translates OpenAI-compatible /v1/audio/speech to the AI Studio generateContent audio contract, reusing the Vertex inline-audio/PCM/WAV conversion path. Batch TTS only, Gemini Live is out of scope. Thank you @RaviTharuma!
c21460f
into
diegosouzapw:release/v3.8.50
…osouzapw#9985) (diegosouzapw#11317) Validated on the resolved merge against the current release tip: pack-artifact-policy + cli-mcp-call-commands + cli-resilience-commands + cli-skills-commands + model-hide-multikey-11300 39/39, typecheck:core clean, eslint clean. Resolved a pt-BR.json wording conflict against diegosouzapw#11322 (kept the tip's wording, semantically identical). Drains the real lint-fallout from the wave that was blocking the release-green verdict — dead code + newly-enforced React-Compiler hook rules. Thank you @jonlwheat2-gif!
Drains the live release-green hard failures on
release/v3.8.50tracked in #9985 (see also #10296 — this is the gate blocking the v3.8.50 publish). Rebased on current tipac02c5b42.What was failing (RED)
npm run lintat tipac02c5b42^reported 22 net-new errors across 6 files; the release-green eslint step consequently died ("could not parse eslint json" — the report never came back clean, so the verdict never reached a passing state):All of it is fallout from already-merged work (#11283 Traffic Inspector header refactor left dead code; the React-Compiler hooks rules newly enforced). No behavior regressions were involved on our side — verified by the full targeted test families below.
After (GREEN) — per-file changes
src/app/(dashboard)/dashboard/FirstRunReadinessCard.tsxBefore: dismissal read via
useState(false)+useEffectthat calledsetVisible(...)synchronously (:23-33).After (lines 15-37): module-level external store (
readinessListeners,subscribeReadiness,isReadinessDismissed) read throughuseSyncExternalStore(line 46) with server snapshot = dismissed (hydration-safe);dismissis now auseCallbackthat writes storage and notifies listeners (48-56); render guardif (setupComplete || dismissed)(58). Net effect: zero setState-in-effect, no cascading renders, same UX including private-mode fallback.src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.tsx(dead code left by #11283)Linkimport — removedAI_PROVIDERS/getProviderByAlias/getProviderDisplayNameimports — removedexpandedEndpointstate pair — removedmcpStatus/a2aStatusbindings renamed_…(setters still drive refreshes)cloudflaredUrlNotice— removedEndpointSectioncomponent — deleted (−134 lines)src/shared/components/CommandPalette.tsx:159deps array[hiddenItems, radarAdminUrl, safeTranslate]→[hiddenItems, radarAdminUrl, safeTranslate, activePreset]— fixes exhaustive-deps and lets React Compiler preserve the memoization (bothpreserve-manual-memoizationerrors clear).Tests (mechanical):
cli-mcp-call-commands.test.ts—makeCmdhelper removed (old :34-36), three(url, opts)fetch stubs →(_url, opts)(now :131/:196/:231),init→_init(:282).cli-resilience-commands.test.ts— import trimmed tomakeMcpStreamFetch; unusedcaptureStdout(:19-31) andmakeCmd(:34-36) removed.cli-skills-commands.test.ts— import trimmed tomakeMcpStreamFetch.Verification matrix
npm run lint(suppressions config, exact CI invocation)--format json --suppressions-location … --pass-on-unpruned-suppressions)npm run typecheck:coreHonest scope notes
eslint-disabledirective warning in EditConnectionModal.tsx:297 (untouched file; removing it could regress under different plugin versions).Diff vs
upstream/release/v3.8.50: 6 files changed, +45/−199.dast-smoke: root cause found and fixed on this branch
Symptom (RED, every branch at this tip — including the maintainer's own #11309/#11310): 14 unique Schemathesis failures, all
[500] Internal Server Error, spanningGET/POST/PATCH/DELETE/OPTIONS /api/keys*,/api/keys/{id}/devices,POST /api/auth/logout, and even the bare list call (curl -X GET …/api/keys) plus CORS preflights. Reproducers were trivial (id=0), proving it was not fuzz damage: the whole DB-backed management surface crashed at request time in the packaged boot.Diagnosis: the workflow's uploaded
server.logartifact contains the real stack, repeated per request:The build log shows the sql.js overlays did run ("Synced module: sql.js WASM fallback runtime"), immediately followed by Step 10.7 of
scripts/build/prepublish.tsdeleting them:Root cause:
findUnexpectedArtifactPaths()enforcesPACK_ARTIFACT_NEVER_ALLOWED_SEGMENTS = ["node_modules"]— an npm-tarball rule from the 79 MB devDependencies leak — which overrides the staging allowlist prefixes (.build/next/,node_modules/). The prepublish staging prune reuses that matcher, so it deleted the standalone server's runtimenode_modules: Turbopack-hashedsql.js-*(includingsql-wasm.wasm) and@huggingface/transformers-*(ort-wasm). Result: in every packaged boot the sqljs fallback adapter throws at instrumentation and every route touching SQLite returns 500 while/api/monitoring/health(DB-free) stays green — which is exactly why health-passing checks masked it.Fix (commit
51bad4135):findUnexpectedArtifactPaths()gains aneverAllowedSegmentsoption. The publish gate keeps the strict default (the tarball guard is intact — pinned by a new default-mode test), while the staging prune passesneverAllowedSegments: []because its allowlist prefixes are the runtime contract.Validation:
tests/unit/pack-artifact-policy.test.tsfail on the old matcher (staged wasm path flagged) and pass after; the tarball-guard test still asserts node_modules stays rejected in pack mode.dast-smokewent from ❌ 14 failures to ✅ SUCCESS on this PR's CI after the fix landed.