#6228 Fix Agent Memory review findings - #1
Closed
abrookins wants to merge 172 commits into
Closed
Conversation
) * feat(RI-7390): promote dev-vectorSet feature flag to vectorSet Rename the flag end-to-end (backend config, KnownFeatures enum, registry and strategy registration; frontend enum, slice default, selector and all consumers; E2E specs). Bump features-config.json to version 3.92. Flag stays default-off, so E2E specs that exercise Vector Set UI keep their explicit { vectorSet: true } override. * feat(RI-7390): enable vectorSet and prodMode for 10% rollout Flip both flags to flag: true with perc: [[0, 10]] in features-config.json and bump version to 3.93.
electron-builder 26.15.0 replaced the Go app-builder-bin snap builder with a pure-TS rewrite (#9829) that ships a broken snap: the launcher references $SNAP/desktop-init.sh that is never staged, and even past that the bundled NSS/NSPR libs are unreachable (libnspr4.so: cannot open shared object file) because SNAP_DESKTOP_RUNTIME / LD_LIBRARY_PATH are not wired up. 26.15.1-.3 all carry the regression. The snap Wayland fix that motivated moving off 26.0.12 (#9337/#9320) shipped in 26.2.0 — well before the 26.15.0 rewrite. Pinning to 26.14.0 keeps that fix (DISABLE_WAYLAND / allowNativeWayland handling) and the proven Go-based snap builder, which correctly sets SNAP_DESKTOP_RUNTIME and LD_LIBRARY_PATH. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Linux snap failed to launch on modern systems: native modules built on the ubuntu-24.04 CI runner (glibc 2.39) couldn't load on the core20 base (glibc 2.31) -> "libm.so.6: version GLIBC_2.38 not found" loading better_sqlite3.node. The old gnome-3-28-1804 platform also lacked a working GPU driver for current hardware. Migrate the snap to base core24 via electron-builder's `snapcraft.core24`: - base core24 -> glibc 2.39, matching the build toolchain (fixes the fatal load) - GNOME extension (default) -> gnome-46-2404 + mesa-2404/gpu-2404 (modern GPU) - XDG_SESSION_TYPE=x11 -> forces XWayland, restoring the old allowNativeWayland:false behavior (Electron 40 removed ELECTRON_OZONE_PLATFORM_HINT and snapcraft core24 rejects '=' in an app command, so this env var is the supported mechanism) - plain browser-support plug -> auto-connects on install (snapd only blocks auto-connect for allow-sandbox:true); electron-builder adds --no-sandbox itself - network / home / password-manager-service plugs preserved CI: core24 builds via the snapcraft CLI in an LXD container, so the x64 Linux job installs snapcraft + lxd, grants the LXD socket, and allows iptables FORWARD (the runner's Docker sets it to DROP, blocking the build container's network). Gated to runs where the snap target is actually built. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Why 41 and not 42 Electron 42 ships ABI 146. better-sqlite3@12.10.1 fixed the code paths for Electron 42, but the WiseLibs release does not yet publish prebuilt .node assets for ABI 146 — only ABI 145 (Electron 41) and below. Targeting 42 today would silently force every dev install and CI job into a local C++ build (node-gyp), which is exactly what the prebuilt pipeline is here to avoid. Electron 41 is the highest version with verified prebuilt better-sqlite3 coverage for all our targets (macOS x64/arm64, Linux x64/arm64 glibc + musl, Windows x64). Once WiseLibs publishes the ABI 146 assets, the follow-up to 42 is a one-line bump.
merge release/3.6.0 to latest
…ED-194228) Redis Copilot answers are rendered via react-jsx-parser with raw HTML passed through (allowDangerousHtml). The only blacklisted tags were `iframe` and `script`, so an AI response containing `<img src=...>` (or other passive network tags) rendered as a live element and issued an outbound request on load. Because message content can be influenced by untrusted data through indirect prompt injection (a malicious instruction stored in a database field that Copilot later summarizes), an attacker could smuggle stolen data into an `<img>` URL and exfiltrate it to an attacker-controlled host — the core of VDP-4596 / HackerOne #3680497. Block every tag able to trigger an outbound request (img, image, picture, source, video, audio, track, object, embed, link, svg, input) and strip the `style` attribute (CSS `background-image: url(...)` is another beacon). Scoped to the AI-chat render path only; tutorials use a separate renderer and legitimately display images. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ring - Remove 'link' from tag blacklist: JsxParser matches blacklistedTags case-insensitively, so it also suppressed the legit PascalCase <Link> component and dropped rendered links. Strip raw <link> via regex instead, mirroring InternalPage. - Add 'style' to the tag blacklist for parity with InternalPage (defense in depth against CSS @import beacons). - Anchor the style-attribute matcher to /^style$/i. - Make security tests await the async render before asserting absence, and add <style>/<link> element cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat(ui): add Markdown value-encoding format
Adds Markdown to the value formatter chain so stored values render as
sanitized GitHub-Flavored Markdown for every key type. Rendering goes
through a synchronous MarkdownViewer component (unified pipeline plus a
DOMPurify pass over the final HTML, then a hardened JsxParser), keeping
untrusted values inert; editing keeps the raw markdown source.
The Array view gains the format selector next to Add Elements on both
the View and Search tabs, inline markdown rendering in value cells, and
expandable rows that show the full formatted value for any encoding.
Link sanitization now also adds rel="noopener noreferrer" alongside
target="_blank".
Also removes redundant jest.mock() calls that shadowed the shared
moduleNameMapper stubs for unified/unist-util-visit - the split mock
instances broke the markdown plugin specs on fresh macOS installs.
References: #RI-8228
* refactor(ui): trim narrating comments in markdown value components
Keeps only the comments code cannot express: the JSX symbol-wrap
round-trip, the plugin type casts, and the DOMPurify hook dependency.
References: #RI-8228
* fix(ui): render markdown as sanitized HTML, not parsed JSX
react-jsx-parser evaluated {...} expressions embedded in raw HTML, so a
value like <div>{"".constructor.constructor("...")()}</div> executed
code that DOMPurify does not neutralize. The viewer registers no custom
components, so it renders the DOMPurify-sanitized HTML directly via
dangerouslySetInnerHTML and drops the JSX parser and brace-wrapping
entirely. Adds a regression test plus the payload to the e2e XSS case.
References: #RI-8228
* fix(ui): block remote-loading elements in markdown value viewer
Untrusted Redis values could render img/video/audio/svg/source, all of
which fetch remote resources on view - leaking the viewer's IP and
enabling tracking. DOMPurify now forbids those plus embedding/input tags
via FORBID_TAGS, matching the hostile-input posture already applied to
links. Extends the unit and e2e XSS coverage to images and media.
References: #RI-8228
* fix(ui): render Markdown inline for every key type on selection
Markdown only rendered rich when a caller passed expanded=true (String)
or special-cased it (Array), so Hash/List/Set/ZSet/Stream showed raw
source in collapsed cells until each row was expanded. The formatter now
returns the MarkdownViewer whenever it is not building a tooltip, so
picking Markdown renders it inline everywhere, consistent with String.
Drops the now-redundant Array cell special-case. Renames the markdown
e2e to value-markdown and adds List and Hash inline-render coverage.
References: #RI-8228
* fix(ui): drive value-format selector from Redux, not local state
ArrayDetails keeps the View and Search tabs mounted together, so each
rendered its own KeyDetailsHeaderFormatter with a private typeSelected
copy that only updated on its own change - changing the format on one
tab left the other's selector stale while cells rendered the new format.
The selector now reads viewFormat straight from the store, so every
mounted instance stays in sync.
References: #RI-8228
Array values render inline on format selection (Markdown rich, other formats compact), so the per-row expand chevron and its sub-panel added nothing but a redundant duplicate. Removes the View-tab expand wiring and the ArrayExpandedValue component. The Search tab's context band (neighbouring elements around a match) is a separate feature and stays. References: #RI-8228
Address bot review on the previous commit:
- Remove the LOWERCASE_LINK_TAG global string replace. It ran over the whole
formatted JSX (including fenced code emitted as <Code>{JSON.stringify(...)}
</Code>), so a <link> inside a code snippet was deleted, corrupting the
block. Raw <link> elements are already stripped by remarkSanitize (DOMPurify)
during formatting, before the PascalCase <Link> component is generated, so
the regex was redundant as well as harmful.
- Block the legacy `background` URI attribute (/^background$/i): DOMPurify keeps
it on <table>/<td> and browsers load it as an image URL, another render-time
exfiltration vector.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* refactor(ui): reuse the Array command preview in Vector Set
Promote CommandPreview from array-details to key-details/shared and
adopt it in the Vector Set similarity-search form, replacing the
duplicated component. Existing test ids are preserved via a new
data-testid prop; the loading placeholder is unified on the Array
copy ("Building command…").
References: #RI-8219
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor(ui): reuse the Array preview toggle in Vector Set
Promote PreviewToggle and useResponsivePreviewLabel from array-details
to key-details/shared and adopt them in the similarity-search form, so
the toggle label expands to "Preview command" on wide layouts exactly
like the Array forms. The shared toggle gains disabled/disabledTooltip
props for the vector set's query-not-ready state; its show/hide
tooltips unify on the Array copy.
References: #RI-8219
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(e2e): seed vector sets with NOQUANT to stabilize self-match score
The default int8 quantization makes the VSIM ELE self-match score land
slightly below 1 (0.9993-0.9998 observed) for most random vectors, so
the "100 %" self-match assertion in similarity-search.spec was a coin
flip on the seeded data - it failed all three CI retries with 99.93 %,
99.94 % and 99.98 %. fp32 storage keeps the self-match at 1 within
float epsilon, which always renders as "100.00 %".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore: trim comments in the command-preview refactor
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(e2e): scope NOQUANT seeding to the similarity self-match spec
Seeding every vector set as fp32 broke the add-elements specs: the
app's VADD sends no quantization token, and Redis rejects writes whose
implied int8 default mismatches an fp32 set. Make NOQUANT an opt-in
seed option used only by the "100 %" self-match assertion, which needs
fp32 to avoid int8 self-similarity drift.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(e2e): assert similarity self-match score with tolerance
Replace the exact "100" text match with |100 - shown| <= 0.1: the
default int8 quantization lands the self-match at 99.93-99.98 % for
most random vectors, so exactness was testing the quantizer rather
than the ranking. Seeding returns to plain VADD (the NOQUANT opt-in
is no longer needed), keeping test sets identical to what the app
itself writes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(ui): rename Redis Query Engine to Redis Search in user-facing text * feat(ui): rename RQE to Redis Search on the vector search page * feat(ui): rename RQE to Redis Search in workbench plugins * test(e2e): rename RQE references to Redis Search * fix(e2e): align RedisSearchNotAvailable locators with derived test ids * refactor: limit RQE rename to user-visible text only
…dis#6184) * test(e2e): fix databases edit-flow failures — search the target row into view before edit (pagination could page it out) and accept the "Edit Database" title in the shared dialog locator * fix(ui): make vector set element test ids format-independent — derive from the raw element name instead of formattingBuffer output (JSX under Markdown/JSON), and reset the persisted view format after each value-markdown e2e test
redis#6170) * feat(ui): expand index view when opening it from key details * refactor(ui): keep openIndexPanel param, send key-details telemetry at click time
- migrate workbench strings (RI-8275) - document plural convention (RI-8275) - translate shared query components and Full Screen (RI-8275) Refs RI-8275
* feat(i18n): migrate vector search list page (RI-8275) * feat(i18n): migrate vector search create-index flow and query page (RI-8275) * feat(i18n): migrate vector search welcome and state screens (RI-8275)
…-block-html-exfiltration fix(copilot): block HTML exfiltration vectors in AI chat rendering (RED-194228)
…with 3 updates (redis#6367) Bumps the development-minor group with 3 updates in the /redisinsight/api directory: [@hey-api/openapi-ts](https://github.com/hey-api/hey-api/tree/HEAD/packages/openapi-ts), [joi](https://github.com/hapijs/joi) and [tsconfig-paths](https://github.com/dividab/tsconfig-paths). Updates `@hey-api/openapi-ts` from 0.97.3 to 0.99.0 - [Release notes](https://github.com/hey-api/hey-api/releases) - [Changelog](https://github.com/hey-api/hey-api/blob/main/packages/openapi-ts/CHANGELOG.md) - [Commits](https://github.com/hey-api/hey-api/commits/@hey-api/openapi-ts@0.99.0/packages/openapi-ts) Updates `joi` from 17.9.2 to 17.13.4 - [Commits](hapijs/joi@v17.9.2...v17.13.4) Updates `tsconfig-paths` from 3.14.2 to 3.15.0 - [Changelog](https://github.com/jonaskello/tsconfig-paths/blob/v3.15.0/CHANGELOG.md) - [Commits](jonaskello/tsconfig-paths@v3.14.2...v3.15.0) --- updated-dependencies: - dependency-name: "@hey-api/openapi-ts" dependency-version: 0.99.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor - dependency-name: joi dependency-version: 17.13.4 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor - dependency-name: tsconfig-paths dependency-version: 3.15.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.16 to 1.1.18. - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](juliangruber/brace-expansion@v1.1.16...v1.1.18) --- updated-dependencies: - dependency-name: brace-expansion dependency-version: 1.1.18 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…4 updates (redis#6369) Bumps the production-patch group with 4 updates in the /redisinsight/api directory: [express](https://github.com/expressjs/express), [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken), [swagger-ui-express](https://github.com/scottie1984/swagger-ui-express) and [uuid](https://github.com/uuidjs/uuid). Updates `express` from 5.2.0 to 5.2.1 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](expressjs/express@v5.2.0...v5.2.1) Updates `jsonwebtoken` from 9.0.2 to 9.0.3 - [Changelog](https://github.com/auth0/node-jsonwebtoken/blob/master/CHANGELOG.md) - [Commits](auth0/node-jsonwebtoken@v9.0.2...v9.0.3) Updates `swagger-ui-express` from 4.6.2 to 4.6.3 - [Release notes](https://github.com/scottie1984/swagger-ui-express/releases) - [Commits](scottie1984/swagger-ui-express@4.6.2...4.6.3) Updates `uuid` from 14.0.0 to 14.0.1 - [Release notes](https://github.com/uuidjs/uuid/releases) - [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md) - [Commits](uuidjs/uuid@v14.0.0...v14.0.1) --- updated-dependencies: - dependency-name: express dependency-version: 5.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-patch - dependency-name: jsonwebtoken dependency-version: 9.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-patch - dependency-name: swagger-ui-express dependency-version: 4.6.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-patch - dependency-name: uuid dependency-version: 14.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…es (redis#6365) Bumps the babel group with 2 updates in the /redisinsight/api directory: [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) and [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env). Updates `@babel/core` from 7.29.6 to 7.29.7 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.7/packages/babel-core) Updates `@babel/preset-env` from 7.29.2 to 7.29.7 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.7/packages/babel-preset-env) --- updated-dependencies: - dependency-name: "@babel/core" dependency-version: 7.29.7 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: babel - dependency-name: "@babel/preset-env" dependency-version: 7.29.7 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: babel ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…updates (redis#6353) Bumps the electron-build group with 2 updates in the / directory: [node-abi](https://github.com/electron/node-abi) and [electron](https://github.com/electron/electron). Updates `node-abi` from 4.31.0 to 4.33.0 - [Release notes](https://github.com/electron/node-abi/releases) - [Commits](electron/node-abi@v4.31.0...v4.33.0) Updates `electron` from 43.2.0 to 43.3.0 - [Release notes](https://github.com/electron/electron/releases) - [Commits](electron/electron@v43.2.0...v43.3.0) --- updated-dependencies: - dependency-name: electron dependency-version: 43.3.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: electron-build - dependency-name: node-abi dependency-version: 4.33.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: electron-build ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…es (redis#6351) Bumps the types group with 4 updates in the /redisinsight/api directory: [@types/adm-zip](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/adm-zip), [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash), [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [@types/ssh2](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ssh2). Updates `@types/adm-zip` from 0.5.0 to 0.5.8 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/adm-zip) Updates `@types/lodash` from 4.14.194 to 4.17.25 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) Updates `@types/node` from 24.13.0 to 24.13.3 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `@types/ssh2` from 1.11.11 to 1.15.5 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ssh2) --- updated-dependencies: - dependency-name: "@types/adm-zip" dependency-version: 0.5.8 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: types - dependency-name: "@types/lodash" dependency-version: 4.17.25 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: types - dependency-name: "@types/node" dependency-version: 24.13.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: types - dependency-name: "@types/ssh2" dependency-version: 1.15.5 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: types ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
redis#6381) * fix(configs): resolve modules with node16 in the build config project @sentry/webpack-plugin 5.4.0 became a shim that re-exports from @sentry/bundler-plugins, which exposes its subpaths only through an exports map. Classic node resolution ignores exports maps, so the re-export resolved to nothing and every member disappeared: configs/webpack.config.main.prod.ts(6,10): error TS2305: Module '"@sentry/webpack-plugin"' has no exported member 'sentryWebpackPlugin' node16 honours the map, so the symbol resolves again. Only moduleResolution changes. module stays CommonJS because this tsconfig is also TS_NODE_PROJECT for build:main, and ts-node emit has to stay CommonJS for `webpack --config` to load the config. Verified by loading webpack.config.main.prod.ts through ts-node with the same environment the build uses. The project still reports zero errors both before and after the plugin bump, and the other three projects sit at their recorded baselines. * fix(configs): pair module and moduleResolution as nodenext node16 resolution with CommonJS module is an unpaired combination that newer TypeScript rejects, so it would need revisiting at the next compiler upgrade. nodenext for both is the coherent pair and models the Node version in .nvmrc rather than Node 16 semantics. Emit is unchanged. The root package.json declares no type, so .ts files stay CommonJS and ts-node still emits require and exports. Verified by loading all three webpack config entrypoints the build scripts use.
… 2 updates (redis#6374) Bumps the observability group with 2 updates in the / directory: [@sentry/vite-plugin](https://github.com/getsentry/sentry-javascript-bundler-plugins) and [@sentry/webpack-plugin](https://github.com/getsentry/sentry-javascript-bundler-plugins). Updates `@sentry/vite-plugin` from 5.3.0 to 5.4.0 - [Release notes](https://github.com/getsentry/sentry-javascript-bundler-plugins/releases) - [Changelog](https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/CHANGELOG.md) - [Commits](getsentry/sentry-javascript-bundler-plugins@5.3.0...5.4.0) Updates `@sentry/webpack-plugin` from 5.3.0 to 5.4.0 - [Release notes](https://github.com/getsentry/sentry-javascript-bundler-plugins/releases) - [Changelog](https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/CHANGELOG.md) - [Commits](getsentry/sentry-javascript-bundler-plugins@5.3.0...5.4.0) --- updated-dependencies: - dependency-name: "@sentry/vite-plugin" dependency-version: 5.4.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: observability - dependency-name: "@sentry/webpack-plugin" dependency-version: 5.4.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: observability ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* feat(desktop): add update strategy storage and IPC contract Introduces the electron-store key and IPC surface needed for a per-installation update strategy (auto vs notify): get/set the strategy, request a download, skip a version, and receive update-state events from the main process. No behavior change yet - auto mode remains the only strategy in effect until the next commit wires it into the updater. * feat(desktop): support notify-mode update checks and downloads Notify mode checks for updates without downloading automatically, notifies the renderer, downloads only on explicit request, and persists a skipped version so it isn't re-prompted. Auto mode's existing silent background download-and-install flow is untouched and remains the default. Update-state sends are re-checked at delivery time (not just when scheduled) and repeated unconditionally on every periodic check, so a single dropped IPC message self-heals instead of leaving the user with no notification at all. * feat(api,ui): add appUpdateStrategySettings feature flag Electron-only flag gating the Settings dropdown's visibility (wired up in a follow-up PR), so the setting can be hidden remotely without a release if the notify-mode flow needs to be pulled. Defaults to enabled. * fix(desktop): guard against concurrent manual update downloads startUpdateDownload() had no re-entrancy guard, so a duplicate appUpdateDownload IPC call (e.g. a fast double-click before the UI reflects the downloading state) could kick off a second overlapping download. The isDownloading flag was also only ever cleared by the autoUpdater 'error' listener, which relies on it firing in lockstep with the downloadUpdate() promise rejection - not guaranteed by the API - so a failure could leave it stuck true forever. * fix(desktop): resend the restart prompt if already downloaded The delayed notify-mode check silently skipped re-sending anything once a version was already downloaded, relying on a single IPC message from the 'update-downloaded' handler. If that message was dropped (e.g. renderer not yet subscribed), the user would never see the restart prompt again for that version. Track the full downloaded UpdateDownloadedEvent instead of just the version, and resend it from the periodic check when a drop is suspected - the same self-healing approach already used for the "update available" notification. * fix(desktop): address update-notification review follow-ups - Cancel the pending delayed "available" check when the real update-downloaded event fires, so a fast download no longer causes a duplicate restart-prompt send within the same window. Later periodic checks still retry independently if a message was genuinely dropped. - Move the download-failure notification into startUpdateDownload's own catch, which is a 1:1 signal for a manual download failing. The previous isDownloading-guarded 'error' listener depended on event ordering against that same catch and could silently skip notifying the renderer once the catch cleared the flag first. - Snapshot the update strategy when a check starts and persist that value instead of re-reading live settings at download completion, so switching strategies mid-download no longer misattributes the completed download in telemetry. * fix(desktop): hide update strategy control on Mac App Store builds checkForUpdate already bails out on process.mas, so the updater never runs in MAS builds. getUpdateStrategy only checked RI_DISABLE_AUTO_UPGRADE though, so the Settings dropdown would still show and let the user pick a strategy that has no effect. Return null for MAS the same way, matching the existing disabled-updater behavior. * fix(desktop): harden update-strategy and download concurrency handling - getUpdateStrategy now validates the persisted value against AppUpdateStrategy, matching setUpdateStrategy's existing validation. A corrupted/invalid config.json entry silently fell back to auto behavior with no notify semantics otherwise. - checkForUpdate now skips entirely while a download is already in flight, and also sets isDownloading around auto mode's own silent downloadPromise (previously only startUpdateDownload set it). This closes several related gaps in one place: a periodic check could no longer re-snapshot the strategy or trigger an unrelated error mid-download, and a manual download can no longer overlap with an in-progress auto-mode silent download either. - updateDownloaded's restart-notification delay now only skips the startup buffer for a download this session actually triggered by clicking Update (manuallyTriggered), using the strategy snapshot rather than live settings. A download resumed/cached from a previous session still gets the delay regardless of strategy, so it can't race the renderer subscribing right after launch. * fix(desktop): apply strategy changes immediately setUpdateStrategy only persisted to electron-store; the new strategy had no effect until the next periodic checkForUpdate, which defaults to every 84 hours. Trigger an immediate re-check right after persisting so switching strategies actually takes effect away. * fix(desktop): close remaining update-state edge cases - Clear the previous pendingAvailableTimeout before scheduling a new one in the update-available handler, instead of just overwriting the reference - the orphaned timer could otherwise still fire later with stale info. - Skipping a version now also clears isUpdateAvailable, so it can't be reported as still available after the user dismissed it. - manuallyTriggered now resets after a download completes or fails, instead of staying true for the rest of the session. - RI_DISABLE_AUTO_UPGRADE and MAS builds are now also respected by setUpdateStrategy and startUpdateDownload directly, not just the getUpdateStrategy query - defense in depth for a flag meant to be a hard disable, even though neither is reachable through the normal UI today (initAutoUpdateChecks never runs when disabled). * fix(desktop): clear update availability when skipping a version skipUpdateVersion persisted the skip but left isUpdateAvailable true, only cleared later by the delayed check callback if it happens to re-encounter the same skipped version - which may not happen for a while at the default 84-hour interval. This is the more direct fix at the point the skip actually happens. * fix(desktop): close two more update-timing gaps - checkForUpdate now holds isDownloading for its entire duration (metadata check included), not just an eventual download. Two concurrent calls - e.g. the periodic loop racing the immediate re-check triggered by a strategy change - could otherwise both mutate initiatingStrategy/autoDownload at once. - Also verified locally: with a short check interval, the delayed notify-mode notification could keep getting rescheduled by identical repeat checks before it ever fired. A pending check for the same version no longer resets the timer, only a genuinely newer one does. - update-not-available now also cancels any pending delayed check, so a stale one from an earlier update-available can't still fire after the feed reports nothing available. * fix(desktop): close three more update-check edge cases - checkForUpdate no longer drops a call that arrives while another is in flight (e.g. a strategy change racing the startup/periodic check) - it's queued and retried once the current one finishes, so the newly persisted strategy actually gets applied. - update-available now cancels any pending notify-mode timer when autoDownload is true, so a stale timer from before a switch to auto can't still surface the notify prompt after the fact. - The delayed callback's "already downloaded" check now requires downloadedInfo to actually exist before comparing versions - a malformed feed response with a missing version could otherwise match null against null and send a null payload the renderer crashes trying to destructure. * fix(desktop): drain queued rechecks from every completion path queuedRecheckUrl was only ever drained inside checkForUpdate's own finally. If the blocking operation was a manual download instead (startUpdateDownload, a separate function), neither its success nor failure path drained it, so a strategy-change recheck queued during a manual download could be stranded until an unrelated check happened to run - up to the next 84h interval. drainQueuedRecheck is now called from all three places that can release isDownloading. Also: startUpdateDownload now redirects straight to the restart flow if a version is already downloaded and waiting to install, instead of asking electron-updater to download it again. * fix(desktop): fix two regressions from the last round of fixes - drainQueuedRecheck was called mid-handler in update-downloaded, before the same handler finished reading initiatingStrategy and manuallyTriggered - draining synchronously starts checkForUpdate(), which overwrites both. A strategy change during an active download could therefore have its completion recorded under the newly selected strategy instead of the one that actually initiated it. Moved the drain to the very end of the handler. - startUpdateDownload's "already downloaded" redirect checked for any downloadedInfo, not specifically the version being requested. If an older version was downloaded and awaiting restart while a genuinely newer one became available, clicking Update on the newer one just re-showed the old restart prompt instead of downloading it - the user had no way to get the newer version. Threaded the version through the IPC call so the check can compare it against downloadedInfo.version precisely. * fix(desktop): mark cached-download restart as manually triggered startUpdateDownload's already-downloaded shortcut called updateDownloaded() without setting manuallyTriggered/initiatingStrategy, so clicking "Update" on a stale notify-mode prompt still incurred the 60s delay meant only for unprompted background detections. * fix(desktop): clear manual state and drain recheck on auto-updater error The error handler reset isDownloading but not manuallyTriggered, and never called drainQueuedRecheck, unlike the other two failure paths (startUpdateDownload's catch and update-downloaded). An error surfacing only through this event left stale manual-trigger state and a queued strategy recheck stranded until the next periodic check. * fix(desktop): honor explicit skip before a cached download, report manual event-only failures The pending-timer callback checked for an already-downloaded installer before checking whether the user explicitly skipped that version, so a skip could still be overridden by a stale cached download. Swapped the order so skip wins. The error handler also now reports AppUpdateStatus.Error when a manually-triggered download fails only through the event (not the downloadUpdate() promise rejection) - otherwise the renderer never learns the download failed and the "Downloading..." toast never resolves. * fix(desktop): stop double-reporting a manual download failure Both the downloadUpdate() promise rejection and the auto-updater's 'error' event were finalizing the same failure - sending AppUpdateStatus.Error twice, and risking the second handler resetting isDownloading right after a queued recheck had already claimed it. The 'error' event is the authoritative signal (it's what covers the event-only failure path), so the promise catch now only logs. * fix(desktop): reset manuallyTriggered after the cached-download shortcut startUpdateDownload's already-downloaded branch set manuallyTriggered to true and returned without resetting it, so the next unrelated check/download failure got misclassified by the error handler as a manual download failure. * fix(desktop): report failure instead of silently dropping a busy manual download startUpdateDownload silently returned when isDownloading was already true (owned by a startup/periodic/strategy-switch check), leaving a manual click with no response. The renderer optimistically shows a non-dismissible "Downloading..." toast on click, so with no failure signal it got stuck forever with no way to recover. Now sends AppUpdateStatus.Error in that case, reusing the existing retry-prompt path already built for real download failures. * fix(desktop): finalize manual download failures that reject without an error event The catch was simplified to just log, assuming the 'error' event always fires alongside a rejection. electron-updater can also reject downloadUpdate() directly without emitting 'error' (e.g. missing cached update metadata), which left isDownloading/manuallyTriggered stuck true forever - every later check would queue, and every later manual download would hit the busy-error path permanently. Only finalize in the catch when manuallyTriggered still owns the operation, so the ordinary emit-and-reject path (already finalized by the event handler) stays a no-op and isn't double-reported.
* feat(ui): add update notification content Toast copy/layout for the states a notify-mode check can produce: found, downloading, ready to restart, and failed. Each links to release notes instead of restating "there's an update" with no context. * feat(ui): wire update notifications to the auto-updater Subscribes to the main process's update-state channel and dispatches the corresponding toast, download, skip, and restart actions. Auto mode's existing "restart to install" toast is unaffected - this only adds the notify-mode found/downloading/failed states around it. * feat(ui): add update strategy setting to Settings, behind a feature flag Dropdown in the General settings section for choosing between automatic (default) and notify-only updates. Hidden entirely when the strategy resolves to null (web build, or enterprise's RI_DISABLE_AUTO_UPGRADE) or when appUpdateStrategySettings is off. * fix(ui): track closes of the notify-mode update-found toast UPDATE_NOTIFICATION_CLOSED only fired for the appUpdateAvailable (restart) toast's close button, not appUpdateFound - undercounting dismissals in the update-notification telemetry funnel. * fix(ui): fix update-toast ordering bugs in ConfigElectron - updateAvailableAction awaited the update-strategy IPC call before dispatching the restart notification. Overlapping calls to this handler could then resolve out of order, letting a stale version overwrite a newer one, and left a stale "Downloading..." toast visible briefly after the download actually finished. Dispatch synchronously first; fetch the strategy for telemetry afterward. - The Available (notify-mode "found") case never cleared an existing appUpdateAvailable (restart-to-install) entry. Since only the last queued toast is shown, a pending restart prompt for an already-downloaded version could be hidden behind a newer "found" toast until that one resolved. * fix(ui): guard update-found toast against stale actions and telemetry The generic close-telemetry switch case added for appUpdateFound last round fired on every dismissal of that id, including programmatic ones (Update/Skip resolving the toast, or it being replaced by Downloading), not just a real "x" click - corrupting the funnel the same way it would have for appUpdateAvailable. Revert that switch case and gate more precisely instead: a local "resolved" flag, set the moment Update or Skip is clicked, both prevents the other action from also firing if the throttled toast is still interactive for a moment after (so a version can't be skipped after its download has already started) and gates the close telemetry to genuine dismissals only. * fix(ui): keep the update-found prompt open until explicitly dismissed Every toast auto-closed after an hour, including appUpdateFound. That automatic expiry fires the same onClose the resolved-flag guard in ConfigElectron relies on, so it recorded UPDATE_NOTIFICATION_CLOSED as if the user had actually clicked "x". An actionable prompt like this shouldn't silently expire anyway. * fix(ui): keep a retry path after a notify-mode download failure A failed manual download removed the only notification with the Update action and never showed another one - a transient network failure left the user with no way to retry short of restarting the app or waiting for the next periodic check (up to 84h). Factor the found-toast construction into a reusable helper and re-show it with the last known version after reporting the error. * fix(ui): record the restored retry prompt as displayed Restoring the found-toast after a download failure skipped the UPDATE_NOTIFICATION_DISPLAYED telemetry that the normal Available path always sent, so a retry's DOWNLOAD_CLICKED had no matching DISPLAYED, skewing the funnel. Moved the telemetry call into showUpdateFoundToast itself so both callers emit it consistently. * fix(ui): fix two more update-toast edge cases - Pass the version through to ipcAppUpdateDownload, matching the backend's IPC contract change that lets startUpdateDownload distinguish "already downloaded" from "a newer version is now available and still needs downloading". - The found-toast's "resolved" flag was local to showUpdateFoundToast, invisible to updateAvailableAction. If a completed download (e.g. the user switched to auto while the prompt was open) removed the toast programmatically, onClose still read resolved=false and incorrectly logged a close. Lifted the flag to component scope so both handlers share it. - The error-retry restore checked lastAvailableVersion's truthiness, but a version can legitimately be falsy while still having been shown. Track hasShownFoundToast separately so the retry isn't skipped just because the version was empty. * fix(ui): remove found-update toast from store when dismissed with X Dismissing the toast only called riToast.dismiss(), so the notification stayed in the infinite-notifications queue. Any later add/remove of an unrelated infinite notification (e.g. OAuth) caused it to be redisplayed in the same session, contradicting the postpone-until-next-launch design. * fix(ui): isolate resolution state per found-toast instance foundToastResolved was a single component-scoped flag shared across successive found-toast instances. If a manual download failed before the throttled notification queue replaced the toast, showing the retry prompt reset that shared flag - so the stale, still-mounted original toast's onClose later fired as an unresolved close, deleting the retry prompt it had already been replaced by. Each toast now gets its own resolution ref; a component-scoped pointer tracks the current one so updateAvailableAction can resolve it without touching an older toast's already-captured ref. * fix(ui): stop resending a dismissed update version until next launch Removing the found toast from the store on X-close (previous commit) broke the reducer's same-version no-op, which was what kept main's unconditional per-check resend from redisplaying it. A dismissed version is now tracked client-side and skipped on resend, while a genuinely newer version is still announced. * fix(ui): resolve the previous found-toast before replacing it showUpdateFoundToast reassigned the resolution ref for a new toast without resolving the one it replaced. When a newer version arrives while an older found-toast is still open and unactioned, the old toast's throttled dismiss later fires its stale onClose, which deleted the newer prompt since both share the same notification id. * fix(ui): stop killing a still-open found toast on resend, suppress dismissed restart prompts A same-version resend while the found toast is still open re-created its resolution ref even though addInfiniteNotification no-ops on an identical id+variation, permanently disabling the live toast's buttons. Skip re-showing when the version matches what's already open and unresolved. The restart-to-install toast had no close handler, so X-dismissing it never removed it from the store - the same resend/queue-churn resurrection bug already fixed for the found toast, just uncovered here. Wired an onClose through APP_UPDATE_AVAILABLE and track a dismissed restart version the same way. * fix(ui): apply the found-toast persistence and resolution guards to the restart toast The restart-to-install toast still auto-closed after an hour, and that auto-expiry fires the same onClose as an explicit dismiss - silently recording it as dismissed and suppressing it until next launch even though the user never closed it. Exempted it from auto-close the same way the found toast already is. updateAvailableAction also replaced an open restart toast with a newer version's without resolving the one being replaced first, so a stale toast's throttled dismiss could delete the newer prompt. Applied the same two-part guard already used for the found toast: skip re-showing an unresolved, still-open same version, and resolve the previous instance before installing the next one. * refactor(ui): consolidate found/restart toast resend-guard state into one helper Both toasts had grown their own hand-duplicated dismissed/last-version/ resolved-ref trio with identical guard logic - the exact duplication that caused the restart-toast fix to miss pieces the found-toast one already had. Extracted a single createToastGuard() factory and instantiate it once per toast type; behavior is unchanged, verified by the full existing test suite passing without modification. * fix(ui): attribute the restart prompt's telemetry to the initiating strategy UPDATE_NOTIFICATION_DISPLAYED read the live update strategy instead of the one that actually caused the download, so it could disagree with APPLICATION_UPDATED (which persists and reads the initiating strategy) if the setting changed while a download was in progress. Now reads the same persisted updateDownloadedStrategy value via the store, mirroring the existing pattern in ipcCheckUpdates.ts. * fix(ui): fix TS2339 from calling .then on the IPC invoke union type window.app.ipc.invoke's return type is Promise<any> | Error (the preload script returns a bare Error for disallowed channels), so .then() didn't type-check on the Error branch even behind optional chaining. Extracted the read into ipcGetUpdateDownloadedStrategy, mirroring the existing ipcGetUpdateStrategy helper, which uses await inside an async function instead - TS resolves the union correctly there. * fix(ui): resolve the restart toast before a found toast replaces it updateAvailableAction (restart path) already resolved foundGuard before removing an open found toast, but the symmetric direction was missing: showing a found toast removed an open restart toast without resolving restartGuard first. The stale toast's later throttled dismiss then fired unresolved, session-suppressing a version the user never actually closed. * fix(ui): fix TS2345 on PERSISTENT_NOTIFICATION_IDS.includes notification.id is typed as string, but the array literal was inferred as InfiniteMessagesIds[] - .includes() requires exact element-type matching (unlike the === comparison this replaced), so it didn't type-check. Typed the array as string[] to match. * fix(ui): guard the restart click with the same resolve pattern as Update/Skip The Restart action never set resolvedRef, unlike Update/Skip on the found toast. If quitAndInstall doesn't quit immediately and the toast is later dismissed for any other reason (e.g. queue displacement), onClose still saw an unresolved ref and ran the session-dismiss path, suppressing further restart prompts for a version the user already acted on.
…10 updates (redis#6368) * chore(deps): bump the production-minor group across 1 directory with 10 updates Bumps the production-minor group with 10 updates in the /redisinsight/api directory: | Package | From | To | | --- | --- | --- | | [@azure/msal-node](https://github.com/AzureAD/microsoft-authentication-library-for-js) | `5.0.2` | `5.5.0` | | [@okta/okta-auth-js](https://github.com/okta/okta-auth-js) | `7.12.1` | `7.14.5` | | [@segment/analytics-node](https://github.com/segmentio/analytics-next/tree/HEAD/packages/node) | `2.2.0` | `2.3.0` | | [@supercharge/promise-pool](https://github.com/superchargejs/promise-pool) | `3.2.0` | `3.3.0` | | [axios](https://github.com/axios/axios) | `1.18.1` | `1.19.0` | | [class-validator](https://github.com/typestack/class-validator) | `0.14.1` | `0.15.1` | | [date-fns](https://github.com/date-fns/date-fns) | `2.29.3` | `2.30.0` | | [detect-port](https://github.com/node-modules/detect-port) | `1.5.1` | `1.6.1` | | [quicktype-core](https://github.com/glideapps/quicktype) | `23.0.116` | `23.3.25` | | [winston](https://github.com/winstonjs/winston) | `3.8.2` | `3.19.0` | Updates `@azure/msal-node` from 5.0.2 to 5.5.0 - [Release notes](https://github.com/AzureAD/microsoft-authentication-library-for-js/releases) - [Commits](AzureAD/microsoft-authentication-library-for-js@msal-node-v5.0.2...msal-node-v5.5.0) Updates `@okta/okta-auth-js` from 7.12.1 to 7.14.5 - [Release notes](https://github.com/okta/okta-auth-js/releases) - [Changelog](https://github.com/okta/okta-auth-js/blob/okta-auth-js-7.14.5/CHANGELOG.md) - [Commits](okta/okta-auth-js@okta-auth-js-7.12.1...okta-auth-js-7.14.5) Updates `@segment/analytics-node` from 2.2.0 to 2.3.0 - [Release notes](https://github.com/segmentio/analytics-next/releases) - [Changelog](https://github.com/segmentio/analytics-next/blob/master/packages/node/CHANGELOG.md) - [Commits](https://github.com/segmentio/analytics-next/commits/@segment/analytics-node@2.3.0/packages/node) Updates `@supercharge/promise-pool` from 3.2.0 to 3.3.0 - [Changelog](https://github.com/supercharge/promise-pool/blob/main/CHANGELOG.md) - [Commits](supercharge/promise-pool@v3.2.0...v3.3.0) Updates `axios` from 1.18.1 to 1.19.0 - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](axios/axios@v1.18.1...v1.19.0) Updates `class-validator` from 0.14.1 to 0.15.1 - [Release notes](https://github.com/typestack/class-validator/releases) - [Changelog](https://github.com/typestack/class-validator/blob/develop/CHANGELOG.md) - [Commits](typestack/class-validator@v0.14.1...v0.15.1) Updates `date-fns` from 2.29.3 to 2.30.0 - [Release notes](https://github.com/date-fns/date-fns/releases) - [Changelog](https://github.com/date-fns/date-fns/blob/v2.30.0/CHANGELOG.md) - [Commits](date-fns/date-fns@v2.29.3...v2.30.0) Updates `detect-port` from 1.5.1 to 1.6.1 - [Release notes](https://github.com/node-modules/detect-port/releases) - [Changelog](https://github.com/node-modules/detect-port/blob/master/CHANGELOG.md) - [Commits](node-modules/detect-port@v1.5.1...v1.6.1) Updates `quicktype-core` from 23.0.116 to 23.3.25 - [Release notes](https://github.com/glideapps/quicktype/releases) - [Commits](https://github.com/glideapps/quicktype/commits) Updates `winston` from 3.8.2 to 3.19.0 - [Release notes](https://github.com/winstonjs/winston/releases) - [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md) - [Commits](winstonjs/winston@v3.8.2...v3.19.0) --- updated-dependencies: - dependency-name: "@azure/msal-node" dependency-version: 5.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: "@okta/okta-auth-js" dependency-version: 7.14.5 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: "@segment/analytics-node" dependency-version: 2.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: "@supercharge/promise-pool" dependency-version: 3.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: axios dependency-version: 1.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: class-validator dependency-version: 0.15.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: date-fns dependency-version: 2.30.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: detect-port dependency-version: 1.6.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: quicktype-core dependency-version: 23.3.25 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: winston dependency-version: 3.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor ... Signed-off-by: dependabot[bot] <support@github.com> * chore(deps): hold quicktype-core and class-validator back in the group quicktype-core 23.1+ ships .d.ts using TS 5.0 const type parameters and TS 5.4 NoInfer, which the api's TypeScript 4.9 cannot parse. These are parse errors, so skipLibCheck does not suppress them. Hold at 23.0.x. class-validator 0.15 falls outside the peer range nestjs-form-data declares (^0.13.2 || ^0.14.0), which its latest release still caps at. Hold at 0.14.x. winston 3.19 pulls logform 2.7, which types format options as unknown rather than any. Narrow them in prepareLogsData. * test(api): cover prepareLogsData log sanitization prepareLogsData is the winston format that applies error sanitization, including the omitSensitiveData flag that strips stack traces from logs, and it had no coverage. Assert the transform runs and that the flag is honoured through winston's format wrapper. * fix(api): annotate winston format exports logform resolves to two installed copies, so the inferred types for prepareLogsData and prettyFileFormat named a nested path and failed declaration emit with TS2742. Only the plain nest build emits declarations, so build:prod and the type-check baselines both pass without it. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Pavel Angelov <pavel.angelov@redis.com>
- migrate Tips recommendation chrome strings to i18n - translate tip titles by stable content id References: #RI-8270
redis#6383) Clears GHSA-mh99-v99m-4gvg and GHSA-rgw5-rvv9-x895 (brace-expansion DoS) and GHSA-5p4m-2wfm-xmqj (js-yaml quadratic CPU) across all audited trees. Both were prod-reachable in the API tree, via typeorm -> glob -> minimatch and @nestjs/swagger respectively. Every bump stays within its major, so no ESM-only jump.
…orking (redis#6382) * fix(ui): keep monitor autoscroll working on fractional panel heights The profiler panel is resizable, so its height can be fractional, which makes react-window report a fractional scrollOffset. Comparing scrollOffset plus offsetHeight against a rounded scrollHeight with strict equality then never matches, so scrolling back to the bottom fails to re-enable autoscroll and live output stops following new commands. Allow a pixel of slack instead of requiring an exact match. * chore(deps): bump the virtualization group and adopt the stricter types @types/react-virtualized 9.22.3 models AutoSizer as a discriminated union on disableHeight and disableWidth, so two things had to change. disableHeight now takes a literal rather than a computed boolean, which VirtualList satisfies by rendering the same list from either branch. Every AutoSizer children callback also needs its parameters annotated, because a union with no props gives the checker nothing to infer from. The stricter types remove errors as well as adding them. VirtualGrid loses two TS2345, and VirtualList and BulkDeleteContent lose one each of TS18048 and TS2769, so the ui baseline drops from 1292 to 1287. * chore(deps): hold react-virtualized at 9.22.5 Bumping it to 9.22.6 makes the stream groups table render no data rows under jsdom, so GroupsViewWrapper can no longer click a row and two of its tests fail. Pinned all five packages to exact versions to bisect, since the caret ranges let npm keep the newer builds, and 9.22.6 alone reproduces it while the other four are clean. The release carries no changelog and no dependency changes, and is nearly two years newer than 9.22.5, so there is no stated benefit to weigh against the breakage. The other four bumps stay: @types drives the AutoSizer typing work and auto-sizer drives the autoscroll fix. Dependabot will offer 9.22.6 again on its own, which is the right place to work out what changed.
…edis#6385) Bumps the internationalization group with 1 update: [i18next-cli](https://github.com/i18next/i18next-cli). Updates `i18next-cli` from 1.67.7 to 1.67.8 - [Changelog](https://github.com/i18next/i18next-cli/blob/main/CHANGELOG.md) - [Commits](i18next/i18next-cli@v1.67.7...v1.67.8) --- updated-dependencies: - dependency-name: i18next-cli dependency-version: 1.67.8 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: internationalization ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* fix(ci): use a literal encryption key for E2E instead of a secret Workflow runs whose actor is dependabot[bot] cannot read Actions secrets, so E2E_RI_ENCRYPTION_KEY arrived as an empty string. With no key the API falls back to the OS keychain, which a CI runner does not have, and every request touching a saved connection answers 503 KeytarUnavailable. Playwright reaches maxFailures at 20 and abandons the remaining tests, which is why these runs report the same 21 failed / 6 passed / 273 did not run every time. No E2E run with dependabot[bot] as the actor has ever passed: 23 failures and 70 cancellations against zero successes, while every success belongs to a human actor. The key encrypts credentials for Redis containers that live for the duration of a single job, so it protects nothing and is now a literal. E2E works for every actor, and an unset secret can no longer fail silently as an empty string. References: #RI-8373 * style(ci): tighten the E2E encryption key comments States only what the assignment does not: why the value is deliberately not a secret.
…ng CI runs (redis#6406) * ci: run E2E on dependency branches and stop label events cancelling runs Dependabot applies four labels within two seconds of opening a PR. Every label event started a pipeline, and because all runs for a PR share one concurrency group with cancel-in-progress, each new run killed the one before it, leaving 7 of 9 runs cancelled on every dependency PR. E2E also only triggered on `labeled`, so it never reran when a PR was rebased, and a dependency PR could be merged with an E2E result belonging to a different commit. E2E now triggers on pushes to dependabot/** branches, which is the only way to limit it to Dependabot: `pull_request` has no filter for who opened a PR. Label events a workflow does not act on now go to a throwaway concurrency group where they cancel nothing, which has to happen in the concurrency key because the group is resolved before any job condition is read. Adds a `skip-e2e` label to turn E2E off for a PR, and rewrites the comments in both files around a numbered list of the cases in which they run. References: #RI-8373 * fix(ci): keep deployment cleanup out of no-op label runs The clean job runs under always(), so it fires even when every test job skips. A run started by a label this workflow ignores would delete the staging, production and gh-pages deployments while doing no other work. It now also needs `changes`, and skips when that job does.
…10 updates (redis#6398) Bumps the production-minor group with 10 updates in the / directory: | Package | From | To | | --- | --- | --- | | [ajv](https://github.com/ajv-validator/ajv) | `8.18.0` | `8.20.0` | | [axios](https://github.com/axios/axios) | `1.18.1` | `1.19.0` | | [classnames](https://github.com/JedWatson/classnames) | `2.3.2` | `2.5.1` | | [connection-string](https://github.com/vitaly-t/connection-string) | `4.3.6` | `4.4.0` | | [d3](https://github.com/d3/d3) | `7.8.4` | `7.9.0` | | [html-entities](https://github.com/mdevils/html-entities) | `2.5.2` | `2.6.0` | | [msgpackr](https://github.com/kriszyp/msgpackr) | `1.10.1` | `1.12.1` | | [pako](https://github.com/nodeca/pako) | `2.1.0` | `2.2.0` | | [react-focus-on](https://github.com/theKashey/react-focus-on) | `3.9.4` | `3.10.2` | | [react-rnd](https://github.com/bokuweb/react-rnd) | `10.4.1` | `10.5.3` | Updates `ajv` from 8.18.0 to 8.20.0 - [Release notes](https://github.com/ajv-validator/ajv/releases) - [Commits](ajv-validator/ajv@v8.18.0...v8.20.0) Updates `axios` from 1.18.1 to 1.19.0 - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](axios/axios@v1.18.1...v1.19.0) Updates `classnames` from 2.3.2 to 2.5.1 - [Changelog](https://github.com/JedWatson/classnames/blob/main/HISTORY.md) - [Commits](JedWatson/classnames@v2.3.2...v2.5.1) Updates `connection-string` from 4.3.6 to 4.4.0 - [Release notes](https://github.com/vitaly-t/connection-string/releases) - [Commits](vitaly-t/connection-string@4.3.6...4.4.0) Updates `d3` from 7.8.4 to 7.9.0 - [Release notes](https://github.com/d3/d3/releases) - [Changelog](https://github.com/d3/d3/blob/main/CHANGES.md) - [Commits](d3/d3@v7.8.4...v7.9.0) Updates `html-entities` from 2.5.2 to 2.6.0 - [Release notes](https://github.com/mdevils/html-entities/releases) - [Changelog](https://github.com/mdevils/html-entities/blob/main/CHANGELOG.md) - [Commits](mdevils/html-entities@v2.5.2...v2.6.0) Updates `msgpackr` from 1.10.1 to 1.12.1 - [Release notes](https://github.com/kriszyp/msgpackr/releases) - [Commits](kriszyp/msgpackr@v1.10.1...v1.12.1) Updates `pako` from 2.1.0 to 2.2.0 - [Changelog](https://github.com/nodeca/pako/blob/master/CHANGELOG.md) - [Commits](nodeca/pako@2.1.0...2.2.0) Updates `react-focus-on` from 3.9.4 to 3.10.2 - [Release notes](https://github.com/theKashey/react-focus-on/releases) - [Changelog](https://github.com/theKashey/react-focus-on/blob/master/CHANGELOG.md) - [Commits](https://github.com/theKashey/react-focus-on/commits) Updates `react-rnd` from 10.4.1 to 10.5.3 - [Release notes](https://github.com/bokuweb/react-rnd/releases) - [Commits](bokuweb/react-rnd@v10.4.1...10.5.3) --- updated-dependencies: - dependency-name: ajv dependency-version: 8.20.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: axios dependency-version: 1.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: classnames dependency-version: 2.5.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: connection-string dependency-version: 4.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: d3 dependency-version: 7.9.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: html-entities dependency-version: 2.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: msgpackr dependency-version: 1.12.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: pako dependency-version: 2.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: react-focus-on dependency-version: 3.10.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor - dependency-name: react-rnd dependency-version: 10.5.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…with 3 updates (redis#6399) Bumps the development-patch group with 3 updates in the / directory: [csv-stringify](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-stringify), [ts-node](https://github.com/TypeStrong/ts-node) and [whatwg-fetch](https://github.com/github/fetch). Updates `csv-stringify` from 6.8.1 to 6.8.3 - [Changelog](https://github.com/adaltas/node-csv/blob/master/packages/csv-stringify/CHANGELOG.md) - [Commits](https://github.com/adaltas/node-csv/commits/csv-stringify@6.8.3/packages/csv-stringify) Updates `ts-node` from 10.9.1 to 10.9.2 - [Release notes](https://github.com/TypeStrong/ts-node/releases) - [Changelog](https://github.com/TypeStrong/ts-node/blob/main/development-docs/release-template.md) - [Commits](TypeStrong/ts-node@v10.9.1...v10.9.2) Updates `whatwg-fetch` from 3.6.2 to 3.6.20 - [Release notes](https://github.com/github/fetch/releases) - [Changelog](https://github.com/JakeChampion/fetch/blob/main/CHANGELOG.md) - [Commits](JakeChampion/fetch@v3.6.2...v3.6.20) --- updated-dependencies: - dependency-name: csv-stringify dependency-version: 6.8.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: development-patch - dependency-name: ts-node dependency-version: 10.9.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: development-patch - dependency-name: whatwg-fetch dependency-version: 3.6.20 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: development-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…with 6 updates (redis#6400) Bumps the development-minor group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [concurrently](https://github.com/open-cli-tools/concurrently) | `9.0.1` | `9.2.4` | | [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) | `3.30.1` | `3.50.0` | | [google-auth-library](https://github.com/googleapis/google-cloud-node/tree/HEAD/core/packages/google-auth-library-nodejs) | `10.6.2` | `10.9.1` | | [moment](https://github.com/moment/moment) | `2.29.4` | `2.30.1` | | [regenerator-runtime](https://github.com/facebook/regenerator) | `0.13.11` | `0.14.1` | | [tsx](https://github.com/privatenumber/tsx) | `4.22.0` | `4.23.11` | Updates `concurrently` from 9.0.1 to 9.2.4 - [Release notes](https://github.com/open-cli-tools/concurrently/releases) - [Commits](open-cli-tools/concurrently@v9.0.1...v9.2.4) Updates `core-js` from 3.30.1 to 3.50.0 - [Release notes](https://github.com/zloirock/core-js/releases) - [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/zloirock/core-js/commits/v3.50.0/packages/core-js) Updates `google-auth-library` from 10.6.2 to 10.9.1 - [Release notes](https://github.com/googleapis/google-cloud-node/releases) - [Changelog](https://github.com/googleapis/google-cloud-node/blob/main/core/packages/google-auth-library-nodejs/CHANGELOG.md) - [Commits](https://github.com/googleapis/google-cloud-node/commits/google-auth-library-v10.9.1/core/packages/google-auth-library-nodejs) Updates `moment` from 2.29.4 to 2.30.1 - [Release notes](https://github.com/moment/moment/releases) - [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md) - [Commits](moment/moment@2.29.4...2.30.1) Updates `regenerator-runtime` from 0.13.11 to 0.14.1 - [Release notes](https://github.com/facebook/regenerator/releases) - [Commits](https://github.com/facebook/regenerator/compare/regenerator-runtime@0.13.11...regenerator-runtime@0.14.1) Updates `tsx` from 4.22.0 to 4.23.11 - [Release notes](https://github.com/privatenumber/tsx/releases) - [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs) - [Commits](privatenumber/tsx@v4.22.0...v4.23.11) --- updated-dependencies: - dependency-name: concurrently dependency-version: 9.2.4 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor - dependency-name: core-js dependency-version: 3.50.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor - dependency-name: google-auth-library dependency-version: 10.9.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor - dependency-name: moment dependency-version: 2.30.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor - dependency-name: regenerator-runtime dependency-version: 0.14.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor - dependency-name: tsx dependency-version: 4.23.11 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…es (redis#6395) Bumps the babel group with 3 updates in the / directory: [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env), [@babel/preset-react](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react) and [@babel/preset-typescript](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-typescript). Updates `@babel/preset-env` from 7.25.4 to 7.29.7 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.7/packages/babel-preset-env) Updates `@babel/preset-react` from 7.28.5 to 7.29.7 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.7/packages/babel-preset-react) Updates `@babel/preset-typescript` from 7.24.1 to 7.29.7 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.7/packages/babel-preset-typescript) --- updated-dependencies: - dependency-name: "@babel/preset-env" dependency-version: 7.29.7 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: babel - dependency-name: "@babel/preset-react" dependency-version: 7.29.7 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: babel - dependency-name: "@babel/preset-typescript" dependency-version: 7.29.7 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: babel ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…2 updates (redis#6389) Bumps the electron-runtime group with 2 updates in the / directory: [electron-store](https://github.com/sindresorhus/electron-store) and [electron-devtools-installer](https://github.com/MarshallOfSound/electron-devtools-installer). Updates `electron-store` from 8.1.0 to 8.2.0 - [Release notes](https://github.com/sindresorhus/electron-store/releases) - [Commits](sindresorhus/electron-store@v8.1.0...v8.2.0) Updates `electron-devtools-installer` from 3.2.0 to 3.2.1 - [Release notes](https://github.com/MarshallOfSound/electron-devtools-installer/releases) - [Commits](MarshallOfSound/electron-devtools-installer@v3.2.0...v3.2.1) --- updated-dependencies: - dependency-name: electron-devtools-installer dependency-version: 3.2.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: electron-runtime - dependency-name: electron-store dependency-version: 8.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: electron-runtime ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* ci: stop Dependabot rebasing every open dependency PR Every pull request from the npm entries edits the same lockfile, so merging one conflicts the rest and Dependabot rebases them. Each rebase pushes a commit, which now also starts E2E, so working through a weekly batch multiplies CI runs. Conflicts are resolved on request with `@dependabot rebase`. The github-actions entry keeps the default, since it opens a single grouped pull request that edits workflow files and has no cascade to prevent. References: #RI-8373 * ci: collapse Dependabot groups so a week lands in fewer pull requests A group opens at most one pull request, so the number of groups sets how many arrive. 33 groups across the npm entries produce around 17, past the point where anyone reviews them. The root entry keeps frontend, electron, tooling and testing, split by what a reviewer checks rather than by name prefix, plus one catch-all. The api entry keeps shared-natives, backend and testing, plus a catch-all. Neither catch-all filters update-types. An update matching no group opens its own pull request, and a prerelease reaching its release version counts as a major, so a patch-and-minor filter there lets those escape. open-pull-requests-limit stays at 15 and 10. Lowering it while more are open than the new cap would leave no headroom to replace them. References: #RI-8373 * ci: run the Dependabot batch overnight on Monday Without a day and time GitHub picks both, which puts the batch mid-afternoon on Tuesday. Creating a batch takes around 25 minutes and each pull request runs CI for about 35, so an 02:00 start settles everything before the working day. Security updates are unaffected: they fire when an advisory publishes and ignore the schedule. References: #RI-8373 * ci: record why some dependencies are held back Each entry says what breaks, so the next person does not retry the same bump or wonder why a package stopped moving. @redis-ui needs manual visual work on an upgrade, so it moves by hand. The two monaco packages are pre-1.0 and the same bump has twice failed lint, type-check and the Linux build. react-vtree sits on a prerelease whose release changes the tree typings, and that step is neither patch, minor nor major, so it needs a version pin rather than an update-type. Patch and minor are named on each entry rather than ignoring a package outright, which would also suppress its security updates. @redis-ui and the unused @redislabsdev pattern leave the frontend group, since nothing there can produce an update now. References: #RI-8373 * ci: hold back the Redis clients and react-virtualized A minor on ioredis, ioredis-mock or redis has broken lint, type-check and both builds. react-virtualized stays at 9.22.5: 9.22.6 fails the frontend tests, and the components rendering through it need work first. Patches still flow for all four. References: #RI-8373 * ci: hold back the packages carrying patch-package patches A patch under patches/ or redisinsight/api/patches/ is keyed to an exact version. Any bump either fails postinstall or drops the patch, and CI installs with npm ci, so it surfaces as an unexplained build failure. Covers monaco-yaml, @elastic/eui and redis-parser. ioredis and react-vtree are already held for other reasons and carry patches too. References: #RI-8373 * style(ci): trim the Dependabot comments to what the config does not show Each note keeps the fact that is not visible from the keys around it and drops the prose. 106 comment lines to 63, with no change to the parsed configuration. * ci: block ioredis patch bumps as well ioredis carries a patch-package patch keyed to 5.3.2, so a patch release breaks it the same way a minor does. It moves next to redis-parser, which already blocks both. ioredis-mock and redis carry no patch and keep taking patches.
Author
|
GitHub Actions marked both pull-request workflows as action_required. A maintainer of this fork must approve the workflow runs before CI jobs can start. Local validation results are in the PR description. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
maininto the Agent Memory inspector branch and resolve the migration, lockfile, storage, and accessibility conflicts.This PR is stacked on redis#6228.
Testing
npm run lintNODE_OPTIONS=--max-old-space-size=8192 npm run type-checkAmerica/Los_Angelesand passed withTZ=UTCRefs redis#6228