| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
RI-8394 Add a manual "Check for Updates" action for notify mode (#6453) - add manual update-check engine - wire up manual update-check IPC channel - expose Check for Updates in tray and app menu - show a toast when a manual check finds no update - add Check for Updates button to Settings References: RI-8394 | 1 个月前 | |
Dev: Apply eslint & prettier suggestions (#4500) * backend * desktop * UI | 1 年前 | |
chore(deps): bump the everything-else group across 1 directory with 12 updates (#6443) * chore(deps): bump the everything-else group across 1 directory with 12 updates Bumps the everything-else group with 12 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@sentry/electron](https://github.com/getsentry/sentry-electron) | `7.16.0` | `7.17.0` | | [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.69.0` | `10.70.0` | | [dompurify](https://github.com/cure53/DOMPurify) | `3.4.13` | `3.4.14` | | [@types/detect-port](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/detect-port) | `1.3.2` | `1.3.5` | | [@types/file-saver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/file-saver) | `2.0.5` | `2.0.7` | | [@types/is-glob](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/is-glob) | `4.0.2` | `4.0.4` | | [@types/json-bigint](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/json-bigint) | `1.0.1` | `1.0.4` | | [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) | `4.14.194` | `4.17.25` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `14.14.10` | `14.18.63` | | [@types/segment-analytics](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/segment-analytics) | `0.0.34` | `0.0.38` | | [@types/webpack-env](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/webpack-env) | `1.18.4` | `1.18.8` | | [tsx](https://github.com/privatenumber/tsx) | `4.23.11` | `4.23.12` | Updates `@sentry/electron` from 7.16.0 to 7.17.0 - [Release notes](https://github.com/getsentry/sentry-electron/releases) - [Changelog](https://github.com/getsentry/sentry-electron/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-electron/compare/7.16.0...7.17.0) Updates `@sentry/react` from 10.69.0 to 10.70.0 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/10.70.0/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/10.69.0...10.70.0) Updates `dompurify` from 3.4.13 to 3.4.14 - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](https://github.com/cure53/DOMPurify/compare/3.4.13...3.4.14) Updates `@types/detect-port` from 1.3.2 to 1.3.5 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/detect-port) Updates `@types/file-saver` from 2.0.5 to 2.0.7 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/file-saver) Updates `@types/is-glob` from 4.0.2 to 4.0.4 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/is-glob) Updates `@types/json-bigint` from 1.0.1 to 1.0.4 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/json-bigint) 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 14.14.10 to 14.18.63 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `@types/segment-analytics` from 0.0.34 to 0.0.38 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/segment-analytics) Updates `@types/webpack-env` from 1.18.4 to 1.18.8 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/webpack-env) Updates `tsx` from 4.23.11 to 4.23.12 - [Release notes](https://github.com/privatenumber/tsx/releases) - [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs) - [Commits](https://github.com/privatenumber/tsx/compare/v4.23.11...v4.23.12) --- updated-dependencies: - dependency-name: "@sentry/electron" dependency-version: 7.17.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: everything-else - dependency-name: "@sentry/react" dependency-version: 10.70.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: everything-else - dependency-name: "@types/detect-port" dependency-version: 1.3.5 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: everything-else - dependency-name: "@types/file-saver" dependency-version: 2.0.7 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: everything-else - dependency-name: "@types/is-glob" dependency-version: 4.0.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: everything-else - dependency-name: "@types/json-bigint" dependency-version: 1.0.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: everything-else - dependency-name: "@types/lodash" dependency-version: 4.17.25 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: everything-else - dependency-name: "@types/node" dependency-version: 14.18.63 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: everything-else - dependency-name: "@types/segment-analytics" dependency-version: 0.0.38 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: everything-else - dependency-name: "@types/webpack-env" dependency-version: 1.18.8 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: everything-else - dependency-name: dompurify dependency-version: 3.4.14 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: everything-else - dependency-name: tsx dependency-version: 4.23.12 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: everything-else ... Signed-off-by: dependabot[bot] <support@github.com> * fix(tests): import lodash minBy in the BarChart spec `min` takes a collection only, so aliasing it to `minBy` and passing an iteratee types the result as `{}` under @types/lodash 4.17, which is where the four TS2339 errors on `smallestBar.x` and `.y` come from. The older types carried a permissive overload that hid it. Runtime is unchanged: both calls return the same element, so the spec still asserts on the same bar. * chore(types): refresh the ui TS error baseline The gate fails on a decrease as well as an increase, so fixing errors without refreshing leaves it red on "baseline is outdated". Seven recorded errors no longer occur: two in the BarChart spec from the lodash import fix, two TS7053 in the consents components and three in the generated api-client, both from the bumped @types packages. Verified against this branch's own dependencies: `type-check` reports the same 1280 remaining and 7 fixed as CI, and passes after the refresh. * chore(types): refresh the desktop TS error baseline The desktop project also reads ../api-client, so the three errors the bumped @types fixed in the generated queryKeySerializer show up in its baseline too. Verified with the full `npm run type-check`: ui 1280, api 3992, desktop 308, configs clean. * fix(deps): move the @sentry/core override to 10.70.0 @sentry/react, @sentry/electron and the Sentry packages they pull each pin @sentry/core to an exact version, and on this branch that is 10.70.0. The override still forced 10.69.0, so seven packages were given a version none of them asked for. That is the divergence the exact pin from #6372 exists to surface. @sentry/bundler-plugins asked for 10.69.0 as well, so move it too. It is dev-only, behind @sentry/vite-plugin and @sentry/webpack-plugin, and its `^10.64.0` range already allowed it, so nothing changes in package.json. The tree holds one copy of @sentry/core at 10.70.0 and no package asks for a version it does not get. Full type-check clean: ui 1280, api 3992, desktop 308, configs. --------- 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> | 1 个月前 | |
RI-8113 Add Sentry error tracking for the Electron app (#6073) * RI-7977: setup Sentry projects * remove sentry from api * update sentry env variables * link electron sentry project * remove docs * chore: reconcile yarn.lock after rebase onto main Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): report main-process test crash via captureException A synchronous throw inside the globalShortcut callback is swallowed by Electron's native dispatch and never reaches Sentry's uncaughtException handler, so Cmd/Ctrl+Shift+K reported nothing. Capture the error explicitly instead, matching the shortcut's non-crashing intent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add RI-8113 production-readiness design Two-tier consent model inside Sentry (anonymous Tier 1 / consented Tier 2), scrubbing security-review checklist, early-crash + consent-caching handling, and mapping to the RI-8113 scope. Intended for Legal/Security review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): record Legal/Security decisions in readiness doc Tier-1 allowlist accepted; IP not tracked; region confirmation pending (EU recommended); retention defaulted to 90 days. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): record Sentry org region as US (residency decision pending) Org is US-region (per DSN host). Region is fixed at org creation, so Legal should confirm US is acceptable for anonymized crash data, or an EU org must be created before launch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): confirm US region approved (residency resolved) Sentry is an org-approved vendor; all data stored in US. No EU org needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): two-tier consent gating + shared scrubbing (RI-8113) Implements the consent model from docs/sentry-production-readiness.md: - Shared, SDK-agnostic scrubbing module (ui/src/services/sentry) used by both the main process and renderer so the layers cannot drift: scrubEvent (redacts extra/contexts/request/breadcrumbs, normalizes stack-frame paths, strips server_name/IP) + minimizeEvent (Tier 1 anonymous allowlist under a shared sentinel id). - Main process: default-deny consent flag cached in electron-store for a synchronous boot read; beforeSend sends full (scrubbed) events with consent and minimized anonymous events without; breadcrumbs gated on consent; native crashReporter upload gated behind consent (start-once); setConsent() updates the tier at runtime. - Renderer: beforeSend self-gates per-event via checkIsAnalyticsGranted. - Consent plumbing: useSentryConsentSync pushes agreements.analytics to the main process over IPC (setSentryConsent) on startup and on toggle. - Unit tests for the scrubbing module. Note: autoSessionTracking/serverName options dropped where the Sentry v10 type no longer accepts them (renderer); server_name is cleared per-event. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(desktop): type-correct rollup external in vite.main.config The PoC added a predicate function into rollup's `external` array, which only accepts string | RegExp — a TS2769 overload error surfaced after the rebase pulled in newer vite/rollup types. Fold the module list, regex patterns, and the api-dist predicate into a single `external` function (behavior-preserving). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(test): preserve subpaths in @redislabsdev->@redis-ui jest mapping @redis-ui/components v44 (pulled in by the rebase) imports icons via subpaths, e.g. @redislabsdev/redis-ui-icons/multicolor. The moduleNameMapper matched only the bare package name and dropped the subpath, so the mapped module resolved to the package root and LoaderLargeIcon was undefined — styled(undefined) crashed every UI test suite at setup. Anchor each mapping and capture the optional subpath ($1) so deep imports survive the rename. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): redesign ErrorBoundary fallback (RI-8113) Make the title the visual focal point (was small/faded vs the button), mute the supporting copy, and replace the alarming brand-red action with the calm primary blue (recovery, not crash). Colors are theme-aware via the persisted document.body theme class and mirror redis-ui neutral/ primary tokens — inlined because the boundary renders above ThemeProvider, where useTheme()/themed CSS variables are unavailable when a crash is caught. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): adjust ErrorBOundary copy * refactor(sentry): split reporting from the error boundary Separate the generic ErrorBoundary (catch + fallback UI + onError callback) from SentryErrorBoundary (a thin wrapper that injects Sentry reporting). Fixes a real robustness gap: the Sentry capture call previously ran unguarded in componentDidCatch, so if it threw, the error escaped the boundary and the fallback UI never rendered. ErrorBoundary now invokes onError inside try/catch, so a reporting failure can never prevent the fallback from showing. The generic boundary is also reusable/testable without any Sentry dependency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): adjust ErrorBoundary copy * refactor(sentry): split ErrorBoundary into types/styles/constants/utils Follow the component-folder convention: extract ErrorBoundaryProps/State and Palette to .types.ts, the inline CSSProperties to .styles.ts, the palettes + copy to .constants.ts, and getPalette to .utils.ts. The component file is now just the boundary logic + markup. Styles stay plain CSSProperties (not styled-components) because the boundary renders above ThemeProvider; the rationale lives in the constants/styles file headers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(sentry): add ErrorBoundary tests Cover the fallback rendering, custom fallback, onError forwarding, and the robustness guarantee that the fallback still renders when onError throws. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add source-maps decision (version-only release + debug IDs) Record §9: source maps are required for real debugging value; decision is release=pkg.version (no per-build SHA) + debug IDs for bundle/map matching, SHA as metadata only. Captures current build state, implementation outline, and the build-determinism open question. Also mark ErrorBoundary refinement done. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): upload source maps via bundler plugins (RI-8113) Add @sentry/vite-plugin (renderer) and @sentry/webpack-plugin (main), gated on SENTRY_AUTH_TOKEN so they are a no-op for local/dev builds. When the token is present (CI) they generate hidden source maps, inject debug IDs into bundle+map, upload to Sentry, and delete the maps so they never ship in the app. Release name = pkg.version (matches the runtime release); debug IDs handle bundle/map matching, so no per-build SHA is needed. Wire the env vars into all four build pipelines, and add the missing RI_SENTRY_UI_DSN (the renderer Sentry layer reads it but it was never passed). New CI config required (see readiness doc): SENTRY_AUTH_TOKEN (secret), SENTRY_ORG / SENTRY_PROJECT_UI / SENTRY_PROJECT_ELECTRON (vars), and the RI_SENTRY_UI_DSN secret. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): mark source maps implemented; list required CI secrets/vars Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): RI_ prefix source-map env vars + report from web build 1. Prefix the source-map env vars with RI_ for consistency: RI_SENTRY_AUTH_TOKEN / RI_SENTRY_ORG / RI_SENTRY_PROJECT_UI / RI_SENTRY_PROJECT_ELECTRON (vite + webpack configs and all four pipelines). Note: the auth token is build-time only and must never be read via import.meta.env in client code. 2. Initialize Sentry in the web entry (index.tsx) via a new services/sentryWeb.ts using @sentry/react, mirroring the Electron renderer (consent-gated two-tier reporting, shared scrubbing). All three targets now report: Electron main, Electron renderer, and web/docker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): UI config uses RI_SENTRY_UI_DSN, not the electron DSN A PoC commit (link electron sentry project) repointed the UI sentry.dsn at RI_SENTRY_ELECTRON_DSN, so the renderer and web reported to the Electron project and RI_SENTRY_UI_DSN was never read. Point it back at the UI DSN. Also document that this sentry block is runtime-overridable per host via the domainConfig merge in config/index.ts — the channel the cloud deployment will use to point the web build at its own Sentry project (no refactor of the init code needed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add cloud (RedisInsight-Cloud) compatibility note Capture that this PR is forward-compatible with the cloud runtime-config approach (getConfig deep-merges per-host domainConfig; init reads config not env; sync resolution = no re-init), the additive cloud work, and the exact integration point. Records that cloud serves a prebuilt S3 web artifact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): single RI_SENTRY_DSN for all layers Consolidate the split RI_SENTRY_ELECTRON_DSN / RI_SENTRY_UI_DSN into one RI_SENTRY_DSN shared by the Electron main process, renderer, and web — one Sentry project, filtered by platform/environment within it (no second project to maintain). Update the main init, UI config, webpack EnvironmentPlugin, all four pipelines, and the readiness doc. Also drop the redundant source-map comment lines from the workflow env blocks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): single RI_SENTRY_PROJECT for source-map uploads With one Sentry project, the renderer and main source-map uploads target the same project. Collapse RI_SENTRY_PROJECT_UI / RI_SENTRY_PROJECT_ELECTRON into a single RI_SENTRY_PROJECT (vite + webpack configs, all four pipelines, doc). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): default RI_SENTRY_ENVIRONMENT to development in main bundle The webpack EnvironmentPlugin defaulted RI_SENTRY_ENVIRONMENT to 'production' while the runtime code and UI config default to 'development'. Align it to 'development' and fix the stale doc comment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): stop tracking the production-readiness doc Keep the readiness/planning doc local-only (added to .git/info/exclude), like docs/pr-plan-RI-7682-decouple-fe-be.md. It should not land in the PR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * revert(test): drop jest mapper change; pin @redis-ui to main's 44.0.2 The jest.config.cjs subpath-mapping change wasn't actually needed — it was masking an unintended lockfile drift. package.json specs match main (^44.0.2 etc.), but the lockfile had drifted @redis-ui to 44.1.0/6.11.0/ 15.1.0/3.8.0 (44.1.0 introduced the @redislabsdev/*/subpath imports that broke the old mapper). main pins 44.0.2, where the original mapper works. Pin the four @redis-ui packages back to main's resolved versions (Sentry SDKs untouched at 10.39.0/7.8.0) and revert jest.config.cjs to match main. Tests pass and type-check is clean at 44.0.2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: restore api/yarn.lock to match main The rebase resolved the api/yarn.lock conflict with --theirs (the month-old PoC lockfile) and it was never reconciled, leaving ~1300 lines of stale churn against main even though redisinsight/api/package.json is identical to main. The PoC removed its API Sentry deps, so there is no API dependency change on this branch — restore main's api/yarn.lock (frozen-lockfile consistent with the unchanged package.json). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: rebuild root yarn.lock as main + Sentry subtree only The rebase-era reinstall had drifted hundreds of unrelated transitive deps (babel, jest, inquirer, colordx, @electron/get, rollup, ...) within their caret ranges, bloating the diff vs main. Rebuild from main's lockfile and re-add only the Sentry deps, pinning @sentry/react@10.39.0 and @sentry/electron@7.8.0 (the pair that dedupes @sentry/core — newer 10.57/ 7.13 resolve a duplicate core and fail type-check). @redis-ui stays at main's 44.0.2. Net result: diff vs main is now just the Sentry/OpenTelemetry subtree (+ magic-string 0.30.19->0.30.21, pulled transitively). frozen-lockfile consistent, type-check clean, tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): drop verbose comments Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): make source-map upload failures non-fatal Add an errorHandler to both bundler plugins so a failed upload (Sentry outage, bad token, network blip) warns and continues instead of failing the build — matching the cloud-ui convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): gate source-map generation+upload on RI_SENTRY_ENABLED Previously the upload was gated only on RI_SENTRY_AUTH_TOKEN, so a build with the token but RI_SENTRY_ENABLED=false would still generate and upload maps — and since generation was token-only while the deleting plugin was gated separately, those maps could ship inside the asar. Couple both map generation and upload to (auth token AND RI_SENTRY_ENABLED === 'true') in the vite and webpack configs, so a disabled build produces no maps at all. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): read RI_SENTRY_ENABLED from vars, not secrets RI_SENTRY_ENABLED is a non-sensitive flag and is configured as a Repository variable, but the pipelines read it from secrets.* — which silently resolved to empty, disabling Sentry everywhere. Read it from vars.* so the repository variable is actually picked up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): correct error-boundary theme detection + tidy logging - getPalette read lowercase 'theme_light/dark' but themeService writes the Theme enum value uppercase ('theme_LIGHT'/'theme_DARK'), so it never matched and always fell back to OS/dark. Use the Theme enum to build the class name. - Replace console.log with console.warn in the renderer Sentry services and drop the eslint-disable (no console.log in production code); remove the noisy success-init logs. - Fix stale setConsent JSDoc (revoke does not close the client). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style(sentry): prettier-format scrubbing spec Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: refresh desktop tscheck baseline (-6 from vite.main.config fix) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): tag events with app.layer (electron-main/renderer/web) Distinguishes which layer a crash came from — a dimension not otherwise captured (renderer and web are both javascript-platform). OS stays in the auto-captured os context. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): label source-map bundles by build OS via dist Set the upload dist to the build OS (macos/windows/linux from process.platform on each per-OS CI runner) so the per-platform source-map bundles are distinguishable in Sentry's Source Maps view. inject: false keeps dist on the uploaded bundle only (release is already set in Sentry.init) — events are untouched and still match via debug IDs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(build): raise vite build heap to 8192 (source-map OOM on macOS CI) Enabling hidden source maps + the Sentry upload plugin pushed the renderer vite build over the V8 heap limit, OOM-crashing build:renderer (SIGABRT) only on the macOS runner (~7GB RAM vs more on linux/windows). Bump NODE_OPTIONS=--max-old-space-size=8192 on the vite build, matching the repo's existing stats script and the cloud-ui convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): use process.platform directly for source-map dist Drop the cosmetic darwin->macos map; process.platform (darwin/win32/linux) is fine as the dist label. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): remove PoC crash-trigger code Remove the test crash triggers added during the PoC: the Cmd+Shift+K/C global shortcuts and triggerTestCrash/triggerNativeCrash imports in app.ts, the Test Helpers block (triggerTestCrash/triggerNativeCrash) in sentry.ts, and the Crash Handler / Crash React buttons in HelpMenu.tsx. HelpMenu.tsx returns to 0 diff vs main; app.ts keeps only initSentry(). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): wire renderer IPC bridge via @sentry/electron/preload The renderer SDK (@sentry/electron/renderer) relays events to the main process over an IPC bridge that the preload script must establish. Without it the renderer falls back to the unsupported `sentry-ipc://` protocol ("URL scheme not supported" / "failed to establish connection with the Electron main process"), so renderer-side errors (React errors, the error boundary) were never reported — only main-process crashes were. Importing `@sentry/electron/preload` sets up the bridge. The package is a root dependency and not externalized by webpack.config.base, so it is bundled into preload.js (prod webpack and dev vite alike). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): correct web source-map deletion path and release Address two Cursor Bugbot findings on the web/Docker build path: - filesToDeleteAfterUpload was hardcoded to the Electron renderer outDir (`../dist/renderer`), so web builds (outDir `./dist`) uploaded hidden source maps but never deleted them — they could ship in the artifact. Use the build's actual `outDir` glob instead. - sentryWeb.ts set `release` from redisinsight/ui/package.json (2.66.0) while the Vite upload plugin uses defaultConfig.app.version (redisinsight/package.json, 3.6.0). Web events and uploaded maps would disagree on release and fail to symbolicate. Use riConfig.app.version, the same source the upload plugin uses. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): gate native crash minidumps on consent; init renderer early Addresses AI review findings on the Sentry PR: - Disable @sentry/electron's default minidump integration. It starts Electron's crashReporter at init and uploads minidumps (process memory) via the SDK transport regardless of analytics consent — bypassing the Tier-1 gate (beforeSend cannot scrub a minidump attachment) and conflicting with our own consent-gated crashReporter.start. Native crashes now flow only through the consent-gated initCrashReporter. - Honour consent revocation/grant at runtime: setConsent now toggles crashReporter.setUploadToServer so minidump uploads stop immediately on revoke and resume on re-grant, instead of only taking effect next launch. - Initialize the renderer Sentry before the windowId IPC round-trip so renderer errors during early startup are captured (matching the web entrypoint). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): remove unused main-process exports captureException, setUser and isSentryInitialized are no longer referenced in production code (the PoC crash triggers that used them were removed). Dropping them keeps the main-process Sentry surface to initSentry/setConsent. Note: anonymity for non-consenting users does not depend on setUser — the Tier-1 path (minimizeEvent) already stamps the shared NON_TRACKING_ANONYMOUS_ID on every no-consent event. This commit is isolated so the sentry-tracking-crash branch can restore the crash-test helpers by reverting just this commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): redact secrets embedded in free-text event fields scrubSensitiveData only redacts by key name, so a secret living inside a string value — most notably a Redis connection URI in a thrown error (redis://user:pass@host) — passed through untouched on the consented path (beforeSend returns scrubEvent's result directly; only Tier 1 minimized it). Add scrubSecretsInText, applied in scrubEvent to the free-text fields: event.message, exception.values[].value, breadcrumbs[].message, request.url/query_string, and stack-frame source context. It redacts URI userinfo credentials and password/token/secret/apiKey assignments. Runs on both tiers (defense-in-depth); best-effort/heuristic, not a guarantee. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): accept RI_SENTRY_ENABLED=1 in main; cover Windows file URLs - Main process now enables Sentry on 'true' OR '1', matching the renderer/web booleanEnv semantics, so the two layers no longer diverge when RI_SENTRY_ENABLED=1 (main was strict-'true' only). - Add normalizePath regression tests for C:/Users/... and file:///C:/Users/... — the /Users/ branch already normalizes these (prefix-agnostic); the tests lock it in against regex regressions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): align source-map gates with runtime; widen free-text token scrubbing - Source-map upload gates (vite + webpack) now accept RI_SENTRY_ENABLED='1' as well as 'true', matching the runtime/booleanEnv semantics so a build configured with '1' still symbolicates (previously: events on, maps off). - Free-text scrubber now redacts Bearer/Basic auth scheme credentials and OAuth-prefixed token names (access_token, refreshToken, ...), which the previous assignment pattern missed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): disable release-health session tracking (consent bypass) Default session integrations emit release-health envelopes on load/navigation that are NOT events, so they bypass the beforeSend consent gate and would send usage telemetry for opted-out users. Disable them in all three layers: - web + Electron renderer: BrowserSession - main: MainProcessSession Also align the Electron renderer's `release` to riConfig.app.version (same source as the web init and the Vite upload plugin) for consistency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): delete hidden source maps even when upload fails filesToDeleteAfterUpload only runs after a successful upload, and the upload errorHandler is intentionally non-fatal — so a failed upload (bad token, 5xx, network) left the emitted .js.map files in the output dir to be packaged. Delete them in the errorHandler too (both vite + webpack) so maps never ship regardless of upload outcome. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): keep debug_meta in Tier-1 so anonymous crashes symbolicate minimizeEvent dropped debug_meta and minimizeFrame dropped abs_path, so no-consent (Tier-1) events could not be matched to uploaded source maps and showed minified frames. Keep debug_meta (code_file + debug_id) and abs_path, normalizing any user path defensively. These carry no PII — build paths + debug-id UUIDs — so anonymous stacks become readable without weakening the Tier-1 redaction. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): scrub secrets in structured-bag string values; normalize request url scrubSensitiveData only redacts by key name, so a secret inside a string value (e.g. a token/credential in a breadcrumb's data.url) passed through on the consented path. Add scrubSecretsDeep, applied to extra/contexts/request/ breadcrumb data, so string values are also free-text scrubbed. Also run normalizePath over request.url to strip an OS account name from a Windows file:// page URL (matching how stack-frame paths are handled). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): skip native crashReporter in Mac App Store builds Electron's crashReporter is unsupported under the MAS App Sandbox. Guard process.mas in initCrashReporter so MAS builds skip native minidumps while JS-level Sentry reporting continues to work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): error boundary message wording * refactor(sentry): trim comments; guard renderer/web init with try/catch Addresses review feedback on the PR: - Trim comments across the Sentry modules to short why-only notes (per the comments rule in #6091); drop how/story comments and stale doc references. - Wrap Sentry.init in try/catch in the web and Electron-renderer initSentry (matching the main process) so a Sentry init failure can't break app startup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 3 个月前 | |
RI-8113 Add Sentry error tracking for the Electron app (#6073) * RI-7977: setup Sentry projects * remove sentry from api * update sentry env variables * link electron sentry project * remove docs * chore: reconcile yarn.lock after rebase onto main Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): report main-process test crash via captureException A synchronous throw inside the globalShortcut callback is swallowed by Electron's native dispatch and never reaches Sentry's uncaughtException handler, so Cmd/Ctrl+Shift+K reported nothing. Capture the error explicitly instead, matching the shortcut's non-crashing intent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add RI-8113 production-readiness design Two-tier consent model inside Sentry (anonymous Tier 1 / consented Tier 2), scrubbing security-review checklist, early-crash + consent-caching handling, and mapping to the RI-8113 scope. Intended for Legal/Security review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): record Legal/Security decisions in readiness doc Tier-1 allowlist accepted; IP not tracked; region confirmation pending (EU recommended); retention defaulted to 90 days. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): record Sentry org region as US (residency decision pending) Org is US-region (per DSN host). Region is fixed at org creation, so Legal should confirm US is acceptable for anonymized crash data, or an EU org must be created before launch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): confirm US region approved (residency resolved) Sentry is an org-approved vendor; all data stored in US. No EU org needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): two-tier consent gating + shared scrubbing (RI-8113) Implements the consent model from docs/sentry-production-readiness.md: - Shared, SDK-agnostic scrubbing module (ui/src/services/sentry) used by both the main process and renderer so the layers cannot drift: scrubEvent (redacts extra/contexts/request/breadcrumbs, normalizes stack-frame paths, strips server_name/IP) + minimizeEvent (Tier 1 anonymous allowlist under a shared sentinel id). - Main process: default-deny consent flag cached in electron-store for a synchronous boot read; beforeSend sends full (scrubbed) events with consent and minimized anonymous events without; breadcrumbs gated on consent; native crashReporter upload gated behind consent (start-once); setConsent() updates the tier at runtime. - Renderer: beforeSend self-gates per-event via checkIsAnalyticsGranted. - Consent plumbing: useSentryConsentSync pushes agreements.analytics to the main process over IPC (setSentryConsent) on startup and on toggle. - Unit tests for the scrubbing module. Note: autoSessionTracking/serverName options dropped where the Sentry v10 type no longer accepts them (renderer); server_name is cleared per-event. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(desktop): type-correct rollup external in vite.main.config The PoC added a predicate function into rollup's `external` array, which only accepts string | RegExp — a TS2769 overload error surfaced after the rebase pulled in newer vite/rollup types. Fold the module list, regex patterns, and the api-dist predicate into a single `external` function (behavior-preserving). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(test): preserve subpaths in @redislabsdev->@redis-ui jest mapping @redis-ui/components v44 (pulled in by the rebase) imports icons via subpaths, e.g. @redislabsdev/redis-ui-icons/multicolor. The moduleNameMapper matched only the bare package name and dropped the subpath, so the mapped module resolved to the package root and LoaderLargeIcon was undefined — styled(undefined) crashed every UI test suite at setup. Anchor each mapping and capture the optional subpath ($1) so deep imports survive the rename. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): redesign ErrorBoundary fallback (RI-8113) Make the title the visual focal point (was small/faded vs the button), mute the supporting copy, and replace the alarming brand-red action with the calm primary blue (recovery, not crash). Colors are theme-aware via the persisted document.body theme class and mirror redis-ui neutral/ primary tokens — inlined because the boundary renders above ThemeProvider, where useTheme()/themed CSS variables are unavailable when a crash is caught. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): adjust ErrorBOundary copy * refactor(sentry): split reporting from the error boundary Separate the generic ErrorBoundary (catch + fallback UI + onError callback) from SentryErrorBoundary (a thin wrapper that injects Sentry reporting). Fixes a real robustness gap: the Sentry capture call previously ran unguarded in componentDidCatch, so if it threw, the error escaped the boundary and the fallback UI never rendered. ErrorBoundary now invokes onError inside try/catch, so a reporting failure can never prevent the fallback from showing. The generic boundary is also reusable/testable without any Sentry dependency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): adjust ErrorBoundary copy * refactor(sentry): split ErrorBoundary into types/styles/constants/utils Follow the component-folder convention: extract ErrorBoundaryProps/State and Palette to .types.ts, the inline CSSProperties to .styles.ts, the palettes + copy to .constants.ts, and getPalette to .utils.ts. The component file is now just the boundary logic + markup. Styles stay plain CSSProperties (not styled-components) because the boundary renders above ThemeProvider; the rationale lives in the constants/styles file headers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(sentry): add ErrorBoundary tests Cover the fallback rendering, custom fallback, onError forwarding, and the robustness guarantee that the fallback still renders when onError throws. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add source-maps decision (version-only release + debug IDs) Record §9: source maps are required for real debugging value; decision is release=pkg.version (no per-build SHA) + debug IDs for bundle/map matching, SHA as metadata only. Captures current build state, implementation outline, and the build-determinism open question. Also mark ErrorBoundary refinement done. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): upload source maps via bundler plugins (RI-8113) Add @sentry/vite-plugin (renderer) and @sentry/webpack-plugin (main), gated on SENTRY_AUTH_TOKEN so they are a no-op for local/dev builds. When the token is present (CI) they generate hidden source maps, inject debug IDs into bundle+map, upload to Sentry, and delete the maps so they never ship in the app. Release name = pkg.version (matches the runtime release); debug IDs handle bundle/map matching, so no per-build SHA is needed. Wire the env vars into all four build pipelines, and add the missing RI_SENTRY_UI_DSN (the renderer Sentry layer reads it but it was never passed). New CI config required (see readiness doc): SENTRY_AUTH_TOKEN (secret), SENTRY_ORG / SENTRY_PROJECT_UI / SENTRY_PROJECT_ELECTRON (vars), and the RI_SENTRY_UI_DSN secret. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): mark source maps implemented; list required CI secrets/vars Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): RI_ prefix source-map env vars + report from web build 1. Prefix the source-map env vars with RI_ for consistency: RI_SENTRY_AUTH_TOKEN / RI_SENTRY_ORG / RI_SENTRY_PROJECT_UI / RI_SENTRY_PROJECT_ELECTRON (vite + webpack configs and all four pipelines). Note: the auth token is build-time only and must never be read via import.meta.env in client code. 2. Initialize Sentry in the web entry (index.tsx) via a new services/sentryWeb.ts using @sentry/react, mirroring the Electron renderer (consent-gated two-tier reporting, shared scrubbing). All three targets now report: Electron main, Electron renderer, and web/docker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): UI config uses RI_SENTRY_UI_DSN, not the electron DSN A PoC commit (link electron sentry project) repointed the UI sentry.dsn at RI_SENTRY_ELECTRON_DSN, so the renderer and web reported to the Electron project and RI_SENTRY_UI_DSN was never read. Point it back at the UI DSN. Also document that this sentry block is runtime-overridable per host via the domainConfig merge in config/index.ts — the channel the cloud deployment will use to point the web build at its own Sentry project (no refactor of the init code needed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add cloud (RedisInsight-Cloud) compatibility note Capture that this PR is forward-compatible with the cloud runtime-config approach (getConfig deep-merges per-host domainConfig; init reads config not env; sync resolution = no re-init), the additive cloud work, and the exact integration point. Records that cloud serves a prebuilt S3 web artifact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): single RI_SENTRY_DSN for all layers Consolidate the split RI_SENTRY_ELECTRON_DSN / RI_SENTRY_UI_DSN into one RI_SENTRY_DSN shared by the Electron main process, renderer, and web — one Sentry project, filtered by platform/environment within it (no second project to maintain). Update the main init, UI config, webpack EnvironmentPlugin, all four pipelines, and the readiness doc. Also drop the redundant source-map comment lines from the workflow env blocks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): single RI_SENTRY_PROJECT for source-map uploads With one Sentry project, the renderer and main source-map uploads target the same project. Collapse RI_SENTRY_PROJECT_UI / RI_SENTRY_PROJECT_ELECTRON into a single RI_SENTRY_PROJECT (vite + webpack configs, all four pipelines, doc). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): default RI_SENTRY_ENVIRONMENT to development in main bundle The webpack EnvironmentPlugin defaulted RI_SENTRY_ENVIRONMENT to 'production' while the runtime code and UI config default to 'development'. Align it to 'development' and fix the stale doc comment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): stop tracking the production-readiness doc Keep the readiness/planning doc local-only (added to .git/info/exclude), like docs/pr-plan-RI-7682-decouple-fe-be.md. It should not land in the PR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * revert(test): drop jest mapper change; pin @redis-ui to main's 44.0.2 The jest.config.cjs subpath-mapping change wasn't actually needed — it was masking an unintended lockfile drift. package.json specs match main (^44.0.2 etc.), but the lockfile had drifted @redis-ui to 44.1.0/6.11.0/ 15.1.0/3.8.0 (44.1.0 introduced the @redislabsdev/*/subpath imports that broke the old mapper). main pins 44.0.2, where the original mapper works. Pin the four @redis-ui packages back to main's resolved versions (Sentry SDKs untouched at 10.39.0/7.8.0) and revert jest.config.cjs to match main. Tests pass and type-check is clean at 44.0.2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: restore api/yarn.lock to match main The rebase resolved the api/yarn.lock conflict with --theirs (the month-old PoC lockfile) and it was never reconciled, leaving ~1300 lines of stale churn against main even though redisinsight/api/package.json is identical to main. The PoC removed its API Sentry deps, so there is no API dependency change on this branch — restore main's api/yarn.lock (frozen-lockfile consistent with the unchanged package.json). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: rebuild root yarn.lock as main + Sentry subtree only The rebase-era reinstall had drifted hundreds of unrelated transitive deps (babel, jest, inquirer, colordx, @electron/get, rollup, ...) within their caret ranges, bloating the diff vs main. Rebuild from main's lockfile and re-add only the Sentry deps, pinning @sentry/react@10.39.0 and @sentry/electron@7.8.0 (the pair that dedupes @sentry/core — newer 10.57/ 7.13 resolve a duplicate core and fail type-check). @redis-ui stays at main's 44.0.2. Net result: diff vs main is now just the Sentry/OpenTelemetry subtree (+ magic-string 0.30.19->0.30.21, pulled transitively). frozen-lockfile consistent, type-check clean, tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): drop verbose comments Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): make source-map upload failures non-fatal Add an errorHandler to both bundler plugins so a failed upload (Sentry outage, bad token, network blip) warns and continues instead of failing the build — matching the cloud-ui convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): gate source-map generation+upload on RI_SENTRY_ENABLED Previously the upload was gated only on RI_SENTRY_AUTH_TOKEN, so a build with the token but RI_SENTRY_ENABLED=false would still generate and upload maps — and since generation was token-only while the deleting plugin was gated separately, those maps could ship inside the asar. Couple both map generation and upload to (auth token AND RI_SENTRY_ENABLED === 'true') in the vite and webpack configs, so a disabled build produces no maps at all. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): read RI_SENTRY_ENABLED from vars, not secrets RI_SENTRY_ENABLED is a non-sensitive flag and is configured as a Repository variable, but the pipelines read it from secrets.* — which silently resolved to empty, disabling Sentry everywhere. Read it from vars.* so the repository variable is actually picked up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): correct error-boundary theme detection + tidy logging - getPalette read lowercase 'theme_light/dark' but themeService writes the Theme enum value uppercase ('theme_LIGHT'/'theme_DARK'), so it never matched and always fell back to OS/dark. Use the Theme enum to build the class name. - Replace console.log with console.warn in the renderer Sentry services and drop the eslint-disable (no console.log in production code); remove the noisy success-init logs. - Fix stale setConsent JSDoc (revoke does not close the client). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style(sentry): prettier-format scrubbing spec Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: refresh desktop tscheck baseline (-6 from vite.main.config fix) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): tag events with app.layer (electron-main/renderer/web) Distinguishes which layer a crash came from — a dimension not otherwise captured (renderer and web are both javascript-platform). OS stays in the auto-captured os context. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): label source-map bundles by build OS via dist Set the upload dist to the build OS (macos/windows/linux from process.platform on each per-OS CI runner) so the per-platform source-map bundles are distinguishable in Sentry's Source Maps view. inject: false keeps dist on the uploaded bundle only (release is already set in Sentry.init) — events are untouched and still match via debug IDs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(build): raise vite build heap to 8192 (source-map OOM on macOS CI) Enabling hidden source maps + the Sentry upload plugin pushed the renderer vite build over the V8 heap limit, OOM-crashing build:renderer (SIGABRT) only on the macOS runner (~7GB RAM vs more on linux/windows). Bump NODE_OPTIONS=--max-old-space-size=8192 on the vite build, matching the repo's existing stats script and the cloud-ui convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): use process.platform directly for source-map dist Drop the cosmetic darwin->macos map; process.platform (darwin/win32/linux) is fine as the dist label. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): remove PoC crash-trigger code Remove the test crash triggers added during the PoC: the Cmd+Shift+K/C global shortcuts and triggerTestCrash/triggerNativeCrash imports in app.ts, the Test Helpers block (triggerTestCrash/triggerNativeCrash) in sentry.ts, and the Crash Handler / Crash React buttons in HelpMenu.tsx. HelpMenu.tsx returns to 0 diff vs main; app.ts keeps only initSentry(). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): wire renderer IPC bridge via @sentry/electron/preload The renderer SDK (@sentry/electron/renderer) relays events to the main process over an IPC bridge that the preload script must establish. Without it the renderer falls back to the unsupported `sentry-ipc://` protocol ("URL scheme not supported" / "failed to establish connection with the Electron main process"), so renderer-side errors (React errors, the error boundary) were never reported — only main-process crashes were. Importing `@sentry/electron/preload` sets up the bridge. The package is a root dependency and not externalized by webpack.config.base, so it is bundled into preload.js (prod webpack and dev vite alike). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): correct web source-map deletion path and release Address two Cursor Bugbot findings on the web/Docker build path: - filesToDeleteAfterUpload was hardcoded to the Electron renderer outDir (`../dist/renderer`), so web builds (outDir `./dist`) uploaded hidden source maps but never deleted them — they could ship in the artifact. Use the build's actual `outDir` glob instead. - sentryWeb.ts set `release` from redisinsight/ui/package.json (2.66.0) while the Vite upload plugin uses defaultConfig.app.version (redisinsight/package.json, 3.6.0). Web events and uploaded maps would disagree on release and fail to symbolicate. Use riConfig.app.version, the same source the upload plugin uses. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): gate native crash minidumps on consent; init renderer early Addresses AI review findings on the Sentry PR: - Disable @sentry/electron's default minidump integration. It starts Electron's crashReporter at init and uploads minidumps (process memory) via the SDK transport regardless of analytics consent — bypassing the Tier-1 gate (beforeSend cannot scrub a minidump attachment) and conflicting with our own consent-gated crashReporter.start. Native crashes now flow only through the consent-gated initCrashReporter. - Honour consent revocation/grant at runtime: setConsent now toggles crashReporter.setUploadToServer so minidump uploads stop immediately on revoke and resume on re-grant, instead of only taking effect next launch. - Initialize the renderer Sentry before the windowId IPC round-trip so renderer errors during early startup are captured (matching the web entrypoint). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): remove unused main-process exports captureException, setUser and isSentryInitialized are no longer referenced in production code (the PoC crash triggers that used them were removed). Dropping them keeps the main-process Sentry surface to initSentry/setConsent. Note: anonymity for non-consenting users does not depend on setUser — the Tier-1 path (minimizeEvent) already stamps the shared NON_TRACKING_ANONYMOUS_ID on every no-consent event. This commit is isolated so the sentry-tracking-crash branch can restore the crash-test helpers by reverting just this commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): redact secrets embedded in free-text event fields scrubSensitiveData only redacts by key name, so a secret living inside a string value — most notably a Redis connection URI in a thrown error (redis://user:pass@host) — passed through untouched on the consented path (beforeSend returns scrubEvent's result directly; only Tier 1 minimized it). Add scrubSecretsInText, applied in scrubEvent to the free-text fields: event.message, exception.values[].value, breadcrumbs[].message, request.url/query_string, and stack-frame source context. It redacts URI userinfo credentials and password/token/secret/apiKey assignments. Runs on both tiers (defense-in-depth); best-effort/heuristic, not a guarantee. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): accept RI_SENTRY_ENABLED=1 in main; cover Windows file URLs - Main process now enables Sentry on 'true' OR '1', matching the renderer/web booleanEnv semantics, so the two layers no longer diverge when RI_SENTRY_ENABLED=1 (main was strict-'true' only). - Add normalizePath regression tests for C:/Users/... and file:///C:/Users/... — the /Users/ branch already normalizes these (prefix-agnostic); the tests lock it in against regex regressions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): align source-map gates with runtime; widen free-text token scrubbing - Source-map upload gates (vite + webpack) now accept RI_SENTRY_ENABLED='1' as well as 'true', matching the runtime/booleanEnv semantics so a build configured with '1' still symbolicates (previously: events on, maps off). - Free-text scrubber now redacts Bearer/Basic auth scheme credentials and OAuth-prefixed token names (access_token, refreshToken, ...), which the previous assignment pattern missed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): disable release-health session tracking (consent bypass) Default session integrations emit release-health envelopes on load/navigation that are NOT events, so they bypass the beforeSend consent gate and would send usage telemetry for opted-out users. Disable them in all three layers: - web + Electron renderer: BrowserSession - main: MainProcessSession Also align the Electron renderer's `release` to riConfig.app.version (same source as the web init and the Vite upload plugin) for consistency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): delete hidden source maps even when upload fails filesToDeleteAfterUpload only runs after a successful upload, and the upload errorHandler is intentionally non-fatal — so a failed upload (bad token, 5xx, network) left the emitted .js.map files in the output dir to be packaged. Delete them in the errorHandler too (both vite + webpack) so maps never ship regardless of upload outcome. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): keep debug_meta in Tier-1 so anonymous crashes symbolicate minimizeEvent dropped debug_meta and minimizeFrame dropped abs_path, so no-consent (Tier-1) events could not be matched to uploaded source maps and showed minified frames. Keep debug_meta (code_file + debug_id) and abs_path, normalizing any user path defensively. These carry no PII — build paths + debug-id UUIDs — so anonymous stacks become readable without weakening the Tier-1 redaction. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): scrub secrets in structured-bag string values; normalize request url scrubSensitiveData only redacts by key name, so a secret inside a string value (e.g. a token/credential in a breadcrumb's data.url) passed through on the consented path. Add scrubSecretsDeep, applied to extra/contexts/request/ breadcrumb data, so string values are also free-text scrubbed. Also run normalizePath over request.url to strip an OS account name from a Windows file:// page URL (matching how stack-frame paths are handled). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): skip native crashReporter in Mac App Store builds Electron's crashReporter is unsupported under the MAS App Sandbox. Guard process.mas in initCrashReporter so MAS builds skip native minidumps while JS-level Sentry reporting continues to work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): error boundary message wording * refactor(sentry): trim comments; guard renderer/web init with try/catch Addresses review feedback on the PR: - Trim comments across the Sentry modules to short why-only notes (per the comments rule in #6091); drop how/story comments and stale doc references. - Wrap Sentry.init in try/catch in the web and Electron-renderer initSentry (matching the main process) so a Sentry init failure can't break app startup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 3 个月前 | |
#5500 Replace deprecated sqlite3 with better-sqlite3 (#5754) * chore(deps): replace sqlite3 with better-sqlite3 in project * chore(deps): migrate from sqlite3 to better-sqlite3 in e2e tests * fix(tests): improve feature flag assertions in GET-features tests | 6 个月前 | |
fix(scripts): fail the TS baseline check when tsc crashes (#6434) * fix(scripts): fail loudly when tsc dies instead of reporting zero errors The baseline check read tsc's diagnostics off a pipe, so tsc's exit status was discarded. An out-of-memory abort produces exit 134 and no stdout, which the parser turns into an empty error list, so the check concluded every recorded error had been fixed and told the developer to refresh the baseline. Doing that wrote an empty baseline and dropped 1287 recorded UI errors, exiting 0. `tscheck:force` skipped the comparison entirely and wrote the empty baseline outright. Run tsc from the script instead of piping into it, and treat any exit status other than 0, 1 or 2 (or death by signal) as a run that never reported its diagnostics. All three commands now refuse to touch the baseline and say that tsc ran out of memory. * fix(scripts): reject compiler crashes that exit 1 with no diagnostics A tsc run killed by an uncaught exception exits 1 with an empty stdout and a stack trace on stderr. Exit 1 is also a legitimate diagnostics status, so the status check let those runs through, the parser turned the empty output into zero errors, and both `tscheck` and `tscheck:force` went on to replace the baseline with an empty snapshot. Require a non-zero exit to carry at least one parsed diagnostic. A compiler that failed but reported nothing says nothing about the real error count, whatever its status. * refactor(scripts): move tsc crash detection into a separate wrapper Revert ts-error-check.ts to its original form and move the crash-detection logic (spawn tsc, check exit status/signal, refuse to touch the baseline on a crash) into a new tsc-safe-run.ts, which forwards parsed diagnostics to the unmodified ts-error-check.ts over stdin, same as the old shell pipe did. Keeps ts-error-check.ts byte-identical to main so it stays easy to sync with the copy of this script kept in another repo. * fix(scripts): resolve tsx as a JS entry instead of a bare spawn spawnSync('tsx', ...) relies on PATH/shell lookup, which fails on Windows where npm exposes tsx through a .cmd shim. Resolve tsx/cli the same way tsc is already resolved here and launch it via process.execPath, so no shell is involved. | 1 个月前 | |
Add auto-update strategy: notify vs auto mode (#6326) * 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. | 2 个月前 | |
Dev: Apply eslint & prettier suggestions (#4500) * backend * desktop * UI | 1 年前 | |
Drop root tsconfig and decompose into per-area configs (#5909) * refactor: drop root tsconfig and decompose into per-area configs Replaces the monolithic root tsconfig.json with scoped tsconfigs for the areas that actually need them: desktop (paths for webpack TsconfigPathsPlugin), playwright tests, stories, and configs (for ts-node loading webpack TS configs). ESLint's root parserOptions.project switches to `true` (auto-discover nearest tsconfig), so api/ui/desktop/playwright/storybook/stories each resolve to their own project. scripts/prebuild.js is converted to CJS and configs/webpack.paths.ts to .js so prebuild can run as plain Node without ts-node. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: drop tsconfig.json from Dockerfile COPY after root removal Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: convert DeleteSourceMaps.js to CJS After dropping allowJs from configs/tsconfig.json, Node 22's module syntax detection treats the ESM-syntax .js file as ESM, where __dirname is not defined. Converting to CJS keeps it compatible with the existing import in the webpack configs (esModuleInterop unwraps module.exports as default). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: anchor desktop tsconfig baseUrl at repo root for path resolution tsconfig-paths-webpack-plugin couldn't resolve aliases when the desktop tsconfig used baseUrl: "./" with parent-directory paths (../api/src, ../ui/src). Switching to baseUrl: "../.." mirrors the original root tsconfig layout — paths reference from repo root. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: document split tsconfig layout for contributors and AI - Add TypeScript Configuration section in CONTRIBUTING.md listing each per-area tsconfig and its purpose. - Add a project-local Claude skill (.ai/skills/tsconfigs) covering the layout, webpack/ts-node/eslint wiring, and how to add new path aliases or TS folders. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: replace TsconfigPathsPlugin with explicit webpack aliases The plugin silently fails to resolve desktopSrc/apiSrc/uiSrc paths when loaded with an explicit configFile pointing at the desktop tsconfig. Switching to webpack's resolve.alias removes the dependency on the plugin's tsconfig reading and is functionally equivalent for our four stable aliases. The desktop tsconfig still defines the same paths for TypeScript and ESLint resolution. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(skill): update tsconfigs skill after dropping TsconfigPathsPlugin Webpack now uses explicit resolve.alias entries instead of reading the desktop tsconfig via the plugin. New aliases for the electron bundle must be added in both places. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * refactor: consolidate stories/configs tsconfigs into a narrow root Introduces a focused root tsconfig.json that covers stories/** and configs/** for ESLint discovery and ts-node webpack-config loading. Drops configs/tsconfig.json and stories/tsconfig.json which were doing essentially the same job. Desktop keeps its own tsconfig — it owns cross-area paths (desktopSrc/apiSrc/uiSrc/apiClient) that don't belong in a catch-all root meant for stories/configs/scripts. TS_NODE_PROJECT updated to ./tsconfig.json. Skill + CONTRIBUTING updated. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert "refactor: consolidate stories/configs tsconfigs into a narrow root" This reverts commit 7a897cd14e8b2cb6ac0a4c99bb91892ffe78f3c6. * fix(configs): drop .ts extension from webpack.config import Caused TS2691 when typechecking the configs/ project. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> | 4 个月前 | |
RI-8113 Add Sentry error tracking for the Electron app (#6073) * RI-7977: setup Sentry projects * remove sentry from api * update sentry env variables * link electron sentry project * remove docs * chore: reconcile yarn.lock after rebase onto main Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): report main-process test crash via captureException A synchronous throw inside the globalShortcut callback is swallowed by Electron's native dispatch and never reaches Sentry's uncaughtException handler, so Cmd/Ctrl+Shift+K reported nothing. Capture the error explicitly instead, matching the shortcut's non-crashing intent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add RI-8113 production-readiness design Two-tier consent model inside Sentry (anonymous Tier 1 / consented Tier 2), scrubbing security-review checklist, early-crash + consent-caching handling, and mapping to the RI-8113 scope. Intended for Legal/Security review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): record Legal/Security decisions in readiness doc Tier-1 allowlist accepted; IP not tracked; region confirmation pending (EU recommended); retention defaulted to 90 days. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): record Sentry org region as US (residency decision pending) Org is US-region (per DSN host). Region is fixed at org creation, so Legal should confirm US is acceptable for anonymized crash data, or an EU org must be created before launch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): confirm US region approved (residency resolved) Sentry is an org-approved vendor; all data stored in US. No EU org needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): two-tier consent gating + shared scrubbing (RI-8113) Implements the consent model from docs/sentry-production-readiness.md: - Shared, SDK-agnostic scrubbing module (ui/src/services/sentry) used by both the main process and renderer so the layers cannot drift: scrubEvent (redacts extra/contexts/request/breadcrumbs, normalizes stack-frame paths, strips server_name/IP) + minimizeEvent (Tier 1 anonymous allowlist under a shared sentinel id). - Main process: default-deny consent flag cached in electron-store for a synchronous boot read; beforeSend sends full (scrubbed) events with consent and minimized anonymous events without; breadcrumbs gated on consent; native crashReporter upload gated behind consent (start-once); setConsent() updates the tier at runtime. - Renderer: beforeSend self-gates per-event via checkIsAnalyticsGranted. - Consent plumbing: useSentryConsentSync pushes agreements.analytics to the main process over IPC (setSentryConsent) on startup and on toggle. - Unit tests for the scrubbing module. Note: autoSessionTracking/serverName options dropped where the Sentry v10 type no longer accepts them (renderer); server_name is cleared per-event. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(desktop): type-correct rollup external in vite.main.config The PoC added a predicate function into rollup's `external` array, which only accepts string | RegExp — a TS2769 overload error surfaced after the rebase pulled in newer vite/rollup types. Fold the module list, regex patterns, and the api-dist predicate into a single `external` function (behavior-preserving). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(test): preserve subpaths in @redislabsdev->@redis-ui jest mapping @redis-ui/components v44 (pulled in by the rebase) imports icons via subpaths, e.g. @redislabsdev/redis-ui-icons/multicolor. The moduleNameMapper matched only the bare package name and dropped the subpath, so the mapped module resolved to the package root and LoaderLargeIcon was undefined — styled(undefined) crashed every UI test suite at setup. Anchor each mapping and capture the optional subpath ($1) so deep imports survive the rename. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): redesign ErrorBoundary fallback (RI-8113) Make the title the visual focal point (was small/faded vs the button), mute the supporting copy, and replace the alarming brand-red action with the calm primary blue (recovery, not crash). Colors are theme-aware via the persisted document.body theme class and mirror redis-ui neutral/ primary tokens — inlined because the boundary renders above ThemeProvider, where useTheme()/themed CSS variables are unavailable when a crash is caught. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): adjust ErrorBOundary copy * refactor(sentry): split reporting from the error boundary Separate the generic ErrorBoundary (catch + fallback UI + onError callback) from SentryErrorBoundary (a thin wrapper that injects Sentry reporting). Fixes a real robustness gap: the Sentry capture call previously ran unguarded in componentDidCatch, so if it threw, the error escaped the boundary and the fallback UI never rendered. ErrorBoundary now invokes onError inside try/catch, so a reporting failure can never prevent the fallback from showing. The generic boundary is also reusable/testable without any Sentry dependency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): adjust ErrorBoundary copy * refactor(sentry): split ErrorBoundary into types/styles/constants/utils Follow the component-folder convention: extract ErrorBoundaryProps/State and Palette to .types.ts, the inline CSSProperties to .styles.ts, the palettes + copy to .constants.ts, and getPalette to .utils.ts. The component file is now just the boundary logic + markup. Styles stay plain CSSProperties (not styled-components) because the boundary renders above ThemeProvider; the rationale lives in the constants/styles file headers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(sentry): add ErrorBoundary tests Cover the fallback rendering, custom fallback, onError forwarding, and the robustness guarantee that the fallback still renders when onError throws. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add source-maps decision (version-only release + debug IDs) Record §9: source maps are required for real debugging value; decision is release=pkg.version (no per-build SHA) + debug IDs for bundle/map matching, SHA as metadata only. Captures current build state, implementation outline, and the build-determinism open question. Also mark ErrorBoundary refinement done. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): upload source maps via bundler plugins (RI-8113) Add @sentry/vite-plugin (renderer) and @sentry/webpack-plugin (main), gated on SENTRY_AUTH_TOKEN so they are a no-op for local/dev builds. When the token is present (CI) they generate hidden source maps, inject debug IDs into bundle+map, upload to Sentry, and delete the maps so they never ship in the app. Release name = pkg.version (matches the runtime release); debug IDs handle bundle/map matching, so no per-build SHA is needed. Wire the env vars into all four build pipelines, and add the missing RI_SENTRY_UI_DSN (the renderer Sentry layer reads it but it was never passed). New CI config required (see readiness doc): SENTRY_AUTH_TOKEN (secret), SENTRY_ORG / SENTRY_PROJECT_UI / SENTRY_PROJECT_ELECTRON (vars), and the RI_SENTRY_UI_DSN secret. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): mark source maps implemented; list required CI secrets/vars Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): RI_ prefix source-map env vars + report from web build 1. Prefix the source-map env vars with RI_ for consistency: RI_SENTRY_AUTH_TOKEN / RI_SENTRY_ORG / RI_SENTRY_PROJECT_UI / RI_SENTRY_PROJECT_ELECTRON (vite + webpack configs and all four pipelines). Note: the auth token is build-time only and must never be read via import.meta.env in client code. 2. Initialize Sentry in the web entry (index.tsx) via a new services/sentryWeb.ts using @sentry/react, mirroring the Electron renderer (consent-gated two-tier reporting, shared scrubbing). All three targets now report: Electron main, Electron renderer, and web/docker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): UI config uses RI_SENTRY_UI_DSN, not the electron DSN A PoC commit (link electron sentry project) repointed the UI sentry.dsn at RI_SENTRY_ELECTRON_DSN, so the renderer and web reported to the Electron project and RI_SENTRY_UI_DSN was never read. Point it back at the UI DSN. Also document that this sentry block is runtime-overridable per host via the domainConfig merge in config/index.ts — the channel the cloud deployment will use to point the web build at its own Sentry project (no refactor of the init code needed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(sentry): add cloud (RedisInsight-Cloud) compatibility note Capture that this PR is forward-compatible with the cloud runtime-config approach (getConfig deep-merges per-host domainConfig; init reads config not env; sync resolution = no re-init), the additive cloud work, and the exact integration point. Records that cloud serves a prebuilt S3 web artifact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): single RI_SENTRY_DSN for all layers Consolidate the split RI_SENTRY_ELECTRON_DSN / RI_SENTRY_UI_DSN into one RI_SENTRY_DSN shared by the Electron main process, renderer, and web — one Sentry project, filtered by platform/environment within it (no second project to maintain). Update the main init, UI config, webpack EnvironmentPlugin, all four pipelines, and the readiness doc. Also drop the redundant source-map comment lines from the workflow env blocks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): single RI_SENTRY_PROJECT for source-map uploads With one Sentry project, the renderer and main source-map uploads target the same project. Collapse RI_SENTRY_PROJECT_UI / RI_SENTRY_PROJECT_ELECTRON into a single RI_SENTRY_PROJECT (vite + webpack configs, all four pipelines, doc). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): default RI_SENTRY_ENVIRONMENT to development in main bundle The webpack EnvironmentPlugin defaulted RI_SENTRY_ENVIRONMENT to 'production' while the runtime code and UI config default to 'development'. Align it to 'development' and fix the stale doc comment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): stop tracking the production-readiness doc Keep the readiness/planning doc local-only (added to .git/info/exclude), like docs/pr-plan-RI-7682-decouple-fe-be.md. It should not land in the PR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * revert(test): drop jest mapper change; pin @redis-ui to main's 44.0.2 The jest.config.cjs subpath-mapping change wasn't actually needed — it was masking an unintended lockfile drift. package.json specs match main (^44.0.2 etc.), but the lockfile had drifted @redis-ui to 44.1.0/6.11.0/ 15.1.0/3.8.0 (44.1.0 introduced the @redislabsdev/*/subpath imports that broke the old mapper). main pins 44.0.2, where the original mapper works. Pin the four @redis-ui packages back to main's resolved versions (Sentry SDKs untouched at 10.39.0/7.8.0) and revert jest.config.cjs to match main. Tests pass and type-check is clean at 44.0.2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: restore api/yarn.lock to match main The rebase resolved the api/yarn.lock conflict with --theirs (the month-old PoC lockfile) and it was never reconciled, leaving ~1300 lines of stale churn against main even though redisinsight/api/package.json is identical to main. The PoC removed its API Sentry deps, so there is no API dependency change on this branch — restore main's api/yarn.lock (frozen-lockfile consistent with the unchanged package.json). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: rebuild root yarn.lock as main + Sentry subtree only The rebase-era reinstall had drifted hundreds of unrelated transitive deps (babel, jest, inquirer, colordx, @electron/get, rollup, ...) within their caret ranges, bloating the diff vs main. Rebuild from main's lockfile and re-add only the Sentry deps, pinning @sentry/react@10.39.0 and @sentry/electron@7.8.0 (the pair that dedupes @sentry/core — newer 10.57/ 7.13 resolve a duplicate core and fail type-check). @redis-ui stays at main's 44.0.2. Net result: diff vs main is now just the Sentry/OpenTelemetry subtree (+ magic-string 0.30.19->0.30.21, pulled transitively). frozen-lockfile consistent, type-check clean, tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): drop verbose comments Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): make source-map upload failures non-fatal Add an errorHandler to both bundler plugins so a failed upload (Sentry outage, bad token, network blip) warns and continues instead of failing the build — matching the cloud-ui convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): gate source-map generation+upload on RI_SENTRY_ENABLED Previously the upload was gated only on RI_SENTRY_AUTH_TOKEN, so a build with the token but RI_SENTRY_ENABLED=false would still generate and upload maps — and since generation was token-only while the deleting plugin was gated separately, those maps could ship inside the asar. Couple both map generation and upload to (auth token AND RI_SENTRY_ENABLED === 'true') in the vite and webpack configs, so a disabled build produces no maps at all. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): read RI_SENTRY_ENABLED from vars, not secrets RI_SENTRY_ENABLED is a non-sensitive flag and is configured as a Repository variable, but the pipelines read it from secrets.* — which silently resolved to empty, disabling Sentry everywhere. Read it from vars.* so the repository variable is actually picked up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): correct error-boundary theme detection + tidy logging - getPalette read lowercase 'theme_light/dark' but themeService writes the Theme enum value uppercase ('theme_LIGHT'/'theme_DARK'), so it never matched and always fell back to OS/dark. Use the Theme enum to build the class name. - Replace console.log with console.warn in the renderer Sentry services and drop the eslint-disable (no console.log in production code); remove the noisy success-init logs. - Fix stale setConsent JSDoc (revoke does not close the client). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style(sentry): prettier-format scrubbing spec Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: refresh desktop tscheck baseline (-6 from vite.main.config fix) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): tag events with app.layer (electron-main/renderer/web) Distinguishes which layer a crash came from — a dimension not otherwise captured (renderer and web are both javascript-platform). OS stays in the auto-captured os context. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(sentry): label source-map bundles by build OS via dist Set the upload dist to the build OS (macos/windows/linux from process.platform on each per-OS CI runner) so the per-platform source-map bundles are distinguishable in Sentry's Source Maps view. inject: false keeps dist on the uploaded bundle only (release is already set in Sentry.init) — events are untouched and still match via debug IDs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(build): raise vite build heap to 8192 (source-map OOM on macOS CI) Enabling hidden source maps + the Sentry upload plugin pushed the renderer vite build over the V8 heap limit, OOM-crashing build:renderer (SIGABRT) only on the macOS runner (~7GB RAM vs more on linux/windows). Bump NODE_OPTIONS=--max-old-space-size=8192 on the vite build, matching the repo's existing stats script and the cloud-ui convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): use process.platform directly for source-map dist Drop the cosmetic darwin->macos map; process.platform (darwin/win32/linux) is fine as the dist label. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(sentry): remove PoC crash-trigger code Remove the test crash triggers added during the PoC: the Cmd+Shift+K/C global shortcuts and triggerTestCrash/triggerNativeCrash imports in app.ts, the Test Helpers block (triggerTestCrash/triggerNativeCrash) in sentry.ts, and the Crash Handler / Crash React buttons in HelpMenu.tsx. HelpMenu.tsx returns to 0 diff vs main; app.ts keeps only initSentry(). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): wire renderer IPC bridge via @sentry/electron/preload The renderer SDK (@sentry/electron/renderer) relays events to the main process over an IPC bridge that the preload script must establish. Without it the renderer falls back to the unsupported `sentry-ipc://` protocol ("URL scheme not supported" / "failed to establish connection with the Electron main process"), so renderer-side errors (React errors, the error boundary) were never reported — only main-process crashes were. Importing `@sentry/electron/preload` sets up the bridge. The package is a root dependency and not externalized by webpack.config.base, so it is bundled into preload.js (prod webpack and dev vite alike). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): correct web source-map deletion path and release Address two Cursor Bugbot findings on the web/Docker build path: - filesToDeleteAfterUpload was hardcoded to the Electron renderer outDir (`../dist/renderer`), so web builds (outDir `./dist`) uploaded hidden source maps but never deleted them — they could ship in the artifact. Use the build's actual `outDir` glob instead. - sentryWeb.ts set `release` from redisinsight/ui/package.json (2.66.0) while the Vite upload plugin uses defaultConfig.app.version (redisinsight/package.json, 3.6.0). Web events and uploaded maps would disagree on release and fail to symbolicate. Use riConfig.app.version, the same source the upload plugin uses. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): gate native crash minidumps on consent; init renderer early Addresses AI review findings on the Sentry PR: - Disable @sentry/electron's default minidump integration. It starts Electron's crashReporter at init and uploads minidumps (process memory) via the SDK transport regardless of analytics consent — bypassing the Tier-1 gate (beforeSend cannot scrub a minidump attachment) and conflicting with our own consent-gated crashReporter.start. Native crashes now flow only through the consent-gated initCrashReporter. - Honour consent revocation/grant at runtime: setConsent now toggles crashReporter.setUploadToServer so minidump uploads stop immediately on revoke and resume on re-grant, instead of only taking effect next launch. - Initialize the renderer Sentry before the windowId IPC round-trip so renderer errors during early startup are captured (matching the web entrypoint). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(sentry): remove unused main-process exports captureException, setUser and isSentryInitialized are no longer referenced in production code (the PoC crash triggers that used them were removed). Dropping them keeps the main-process Sentry surface to initSentry/setConsent. Note: anonymity for non-consenting users does not depend on setUser — the Tier-1 path (minimizeEvent) already stamps the shared NON_TRACKING_ANONYMOUS_ID on every no-consent event. This commit is isolated so the sentry-tracking-crash branch can restore the crash-test helpers by reverting just this commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): redact secrets embedded in free-text event fields scrubSensitiveData only redacts by key name, so a secret living inside a string value — most notably a Redis connection URI in a thrown error (redis://user:pass@host) — passed through untouched on the consented path (beforeSend returns scrubEvent's result directly; only Tier 1 minimized it). Add scrubSecretsInText, applied in scrubEvent to the free-text fields: event.message, exception.values[].value, breadcrumbs[].message, request.url/query_string, and stack-frame source context. It redacts URI userinfo credentials and password/token/secret/apiKey assignments. Runs on both tiers (defense-in-depth); best-effort/heuristic, not a guarantee. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): accept RI_SENTRY_ENABLED=1 in main; cover Windows file URLs - Main process now enables Sentry on 'true' OR '1', matching the renderer/web booleanEnv semantics, so the two layers no longer diverge when RI_SENTRY_ENABLED=1 (main was strict-'true' only). - Add normalizePath regression tests for C:/Users/... and file:///C:/Users/... — the /Users/ branch already normalizes these (prefix-agnostic); the tests lock it in against regex regressions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): align source-map gates with runtime; widen free-text token scrubbing - Source-map upload gates (vite + webpack) now accept RI_SENTRY_ENABLED='1' as well as 'true', matching the runtime/booleanEnv semantics so a build configured with '1' still symbolicates (previously: events on, maps off). - Free-text scrubber now redacts Bearer/Basic auth scheme credentials and OAuth-prefixed token names (access_token, refreshToken, ...), which the previous assignment pattern missed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): disable release-health session tracking (consent bypass) Default session integrations emit release-health envelopes on load/navigation that are NOT events, so they bypass the beforeSend consent gate and would send usage telemetry for opted-out users. Disable them in all three layers: - web + Electron renderer: BrowserSession - main: MainProcessSession Also align the Electron renderer's `release` to riConfig.app.version (same source as the web init and the Vite upload plugin) for consistency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): delete hidden source maps even when upload fails filesToDeleteAfterUpload only runs after a successful upload, and the upload errorHandler is intentionally non-fatal — so a failed upload (bad token, 5xx, network) left the emitted .js.map files in the output dir to be packaged. Delete them in the errorHandler too (both vite + webpack) so maps never ship regardless of upload outcome. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): keep debug_meta in Tier-1 so anonymous crashes symbolicate minimizeEvent dropped debug_meta and minimizeFrame dropped abs_path, so no-consent (Tier-1) events could not be matched to uploaded source maps and showed minified frames. Keep debug_meta (code_file + debug_id) and abs_path, normalizing any user path defensively. These carry no PII — build paths + debug-id UUIDs — so anonymous stacks become readable without weakening the Tier-1 redaction. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): scrub secrets in structured-bag string values; normalize request url scrubSensitiveData only redacts by key name, so a secret inside a string value (e.g. a token/credential in a breadcrumb's data.url) passed through on the consented path. Add scrubSecretsDeep, applied to extra/contexts/request/ breadcrumb data, so string values are also free-text scrubbed. Also run normalizePath over request.url to strip an OS account name from a Windows file:// page URL (matching how stack-frame paths are handled). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): skip native crashReporter in Mac App Store builds Electron's crashReporter is unsupported under the MAS App Sandbox. Guard process.mas in initCrashReporter so MAS builds skip native minidumps while JS-level Sentry reporting continues to work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sentry): error boundary message wording * refactor(sentry): trim comments; guard renderer/web init with try/catch Addresses review feedback on the PR: - Trim comments across the Sentry modules to short why-only notes (per the comments rule in #6091); drop how/story comments and stale doc references. - Wrap Sentry.init in try/catch in the web and Electron-renderer initSentry (matching the main process) so a Sentry init failure can't break app startup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 3 个月前 | |
Be/feature/ri 5876 fix start electron dev mode (#4021) * Change the wording on the native browser authentication page * RI-5876-Fix start electron dev mode Initial working POC - to be cleaned * RI-5876 Fix start electron dev mode - cleanup * RI-5876 Fix Electron in dev mode -> fix for window validation in dev (POC) * RI-5876 Fix start electron dev mode - clean up and hardcoded values * RI-5876 fix start electron dev mode - fixed auth flow for dev with tcp * RI-5876 Fix start electron dev mode - cleanup * RI-5876 fix start electron dev - cleanup * RI-5876 fix electron dev mode - further cleanup and removal of * RI-5876 * RI-5876 Fix start electron dev mode * RI-5876 fix electron dev mode - removed hardcoded if statement * RI-5876 fix electron dev mode - removed unused dependency * RI-5876 cleanup * RI-5876 cleanup * RI-5876 cleanup * RI-5876 cleanup * RI-5876 - cleaned up console.logs * RI-5876 fixed eslint errors * RI-6876 fixed api test (#4022) * Ri 5876 fix start electron dev mode (#4023) * refactoring * #RI-6061 - fix overflow * #RI-6062 - add initial commands json * changes from main * #RI-6026 - support apply functions, filter expressions, reducer functions * #RI-6026 - add tests, fix tests * #RI-6026 - remove console.log * #RI-6027 - add completion types for query fields * #RI-6027 - remove commented code * add profile and explain tests * fixes * add waiter because of slow work of suggestions * add env variable for local * add env * add method for selecting query * #RI-6091 - fix highlighting #RI-6093 - fix expression suggestions * init implementation * #RI-6079 - update colors * test for APPLY, FILTER and REDUCE * fix tests + small rework * fix tests * fix tests * test for suggestions for fields * add migrations * #RI-5992 - update search and query history * #RI-6079 - update colors #RI-6099 - highlight fields * #RI-6108 - fix clear results #RI-6109 - fix history #RI-6110 - fix profile/explain * add tests for search history * remove unused meta * #RI-6086 - fix number of args next to count #RI-6088 - fix multiple arguments * revert theme * Dynamically show multiple byte formats * #RI-6100 - merge colors * #RI-6111 - fix suggestions * fix vector * #RI-6119 - move browser pages from tabs to menu * #RI-6119 - add tests, fix test * Add support for 1000 base which is used for network metrics * Remove console log * refactoring * fix some issues * #RI-6085 - fix sending query * #RI-6089 - add support ft commands * #RI-6089 - fix suggestions * #RI-6137 - update quotes and colors * #RI-6135 - cover no indexes case * fix last page context * #RI-6135 - update link * #RI-6135 - fix tests * add test when there is no index * RI-6089_support-ft-commands * RI-6141 update rdi last connection on each connect * #RI-6151 - initial implementation of search suggestions in the workbench * RI-6191 fixed text * RI-6153 renamed and added tooltips to dry-run panel tabs * #RI-6151 - search suggestions in the workbench, refactoring * #RI-6151 - fix pr comments * Fixed tests flagged by Maria * remove separate tab * RI-6141 await rdiClient before updating * Update README.md * fix part of tests * temp fix * recommendation fix * fix for tutorials * fix for tutorials#2 * #RI-6173, #RI-6177, #RI-6178, #RI-6182, #RI-6183 - fix bugs * Update README.md * #RI-6158 - Migrate build workflows from CircleCI to Github Actions * fix monitor typo * #RI-6158 - Migrate build workflows from CircleCI to Github Actions * #RI-6158 - Migrate build workflows from CircleCI to Github Actions * #RI-6158 - Migrate build workflows from CircleCI to Github Actions * #RI-6158 - Migrate build workflows from CircleCI to Github Actions * update response * #RI-6203 - fix suggestions * unskip * #RI-6158 - Turn off auto run Unit tests * #RI-6158 - Turn off auto run Unit tests * #RI-6158 - Add $ENV to docker build * add fix for headers * comment check * #RI-6132 - update sanitizer * Delete .github/README.md * remove brocken commands * #RI-6217 - fix suggestions #RI-6218 - fix cypher editor * small refactoring * update existing tests * Fix zero byte case * update root dependencies * update * remove opening by keyboard * move to newest class-transformer and class-validator * #RI-6221 - fix arguments in details * update jest * update root dependencies * fix tests * fix unit tests * upgrade nest packages * the rest of nestjs libraries * fix the rest of the modules + electron * setup codeql to ignore test files/folders * exclude api/test folder from codeql analysis * upgrade all the packages * upgrade all the packages * #RI-6222 - fix auto-suggest at first column * start refactoring * bump ip * fix pr comments * bump ts-node * fix minifying * ts fixes * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * test * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6228 - fix load all, composite args * add ui tests * fix * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * #RRI-6172 - remove search page * fix2 * rollback class-transform to 0.3.x (0.3.1) * upgrade nestjs + okta packages. cleanup resolutions * degrade nest-form-data * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * test * #RI-6213 - Migrate release workflows from CircleCI to Github Actions * RI-6220 removed rdi pipeline template * upgrade webpack * upgrade msw/cookie * RI-6225 social button fix * e2e/feature/RI-6220_remove-rdi-pipeline-template * RI-6240 fix tooltip style * #RI-6234 - fix error showing when no indexes * RI-6171 User cannot create vector index using form * e2e/bugfix/tsconfig-fix * RI-6171 User cannot create vector index using form - updated tests * Simplified check based on suggestion from Roman * e2e/bugfix/fir-delete-all-keys-redis * #RI-6208 - improve switch between redis and search syntax, add command scope #RI-6211 - fix highlighting when there are several the same args * #RI-6226 - add sorting for list of commands #RI-6244 - fix finding of command * e2e/feature/RI-6226_change_sorting_for_ft * fix ts issue * fix ITests * fix detail token * fix ITests * Fix Dockerfile * RI-6876 fixed api test --------- Co-authored-by: Roman Sergeenko <roman.sergeenko@softeq.com> Co-authored-by: vlad-dargel <u.darhel@aisnovations.com> Co-authored-by: Vlad <vladislav.darhel@softeq.com> Co-authored-by: ArtemHoruzhenko <artem.horuzhenko@redis.com> Co-authored-by: mariasergeenko <maria.sergeenko@softeq.com> Co-authored-by: Gnanesh <gnaneshkunal@outlook.com> Co-authored-by: kchepikava <krystsina.chepikava@softeq.com> Co-authored-by: ViktarStarastsenka <99594890+ViktarStarastsenka@users.noreply.github.com> Co-authored-by: zalenskiSofteq <egor.zalenski@softeq.com> Co-authored-by: yangw <yang.wu@daocloud.io> * RI-5876 removed the custom-tutorials submitted from testin * RI-5876 yarn.lock updates * added a command to run api, ui and desktop at the same time * RI-5876 Renamed new command * RI-5876 updated postinstall scripts * RI-5876 fixes around the build flow * fixes around the build * RI-5876 WIP (build works without window ids - bug) * RI-5876 WIP build updates * RI-5876 WIP builds * RI-5876 rollback on some changes * RI-5876 clean up * RI-5876 cleanup * RI-5876 cleanup * RI-5876 cleanup * RI-5876 cleanup * RI-5876 cleanup * RI-5876 circular dependency solved * RI-5876 resolved dependency and all changes * RI-5876 clean up * RI-5876 fixed wrong enum import * RI-5876 cleaning up the PR * removed unused file * RI-5876 cleanup unused variables * RI-5876 cleanedup electron-dev conig * RI-5876 simplified electron-builder.dev * RI-5876 removed unused properties * RI-5876 removed unecesary differences * RI-5876 cleared up feedback (process.env.development checks and unused files) * RI-5876 Cleared up PR feedback * RI-5876 removed unused file * RI-5876 - PR feedback from Artem * RI-6876 cleared up prettier issue * RI-5876 - feedback from Artem - abstraction for the TCP approach on desktop side * RI-5876 - further PR improvements and cleanup * reverted yarn.lock to main's * rollback to main --------- Co-authored-by: Roman Sergeenko <roman.sergeenko@softeq.com> Co-authored-by: vlad-dargel <u.darhel@aisnovations.com> Co-authored-by: Vlad <vladislav.darhel@softeq.com> Co-authored-by: ArtemHoruzhenko <artem.horuzhenko@redis.com> Co-authored-by: mariasergeenko <maria.sergeenko@softeq.com> Co-authored-by: Gnanesh <gnaneshkunal@outlook.com> Co-authored-by: kchepikava <krystsina.chepikava@softeq.com> Co-authored-by: ViktarStarastsenka <99594890+ViktarStarastsenka@users.noreply.github.com> Co-authored-by: zalenskiSofteq <egor.zalenski@softeq.com> Co-authored-by: yangw <yang.wu@daocloud.io> | 1 年前 | |
RI-7682 Self-contain UI tsconfig and clean up dead apiSrc aliases (#5901) * RI-7682 Self-contain UI tsconfig and drop dead apiSrc FE aliases Phase 3 of the FE/BE decoupling. The UI workspace already has zero `apiSrc/*` / `src/*` imports (PR #5885) and the lint guard blocks new ones at `error` level. This PR cleans up the residual configuration that pretended the alias was still in use on the UI side, and detaches the UI's tsconfig from the misleading root indirection. Toolchain - `redisinsight/ui/tsconfig.json` is now self-contained: inlines the compilerOptions previously inherited from the root, and declares its own `paths` for `uiSrc/*`, `apiClient(/**)`, and `desktopSrc/*` only. `yarn type-check:ui` now type-checks the UI surface in isolation. - Root `tsconfig.json` keeps its full `compilerOptions` + `include` -- it is still the eslint parser project for files outside the UI/API overrides (playwright, stories, etc.) and the resolver for `tsconfig-paths-webpack-plugin` in the desktop main webpack build. Header comment documents the three jobs it now serves. - `.storybook/tsconfig.json` re-extends `redisinsight/ui/tsconfig.json` directly instead of the root. - ESLint UI override's `parserOptions.project` -> `redisinsight/ui/tsconfig.json`. Dead alias removal (no consumer in the UI workspace) - `redisinsight/ui/vite.config.mjs` -- drop `apiSrc` alias - `redisinsight/ui/src/packages/vite.config.mjs` -- drop `apiSrc` alias - `redisinsight/desktop/vite.renderer.config.ts` -- drop `apiSrc` alias (renderer doesn't bundle main-process code) - `.storybook/vite.config.ts` -- drop `apiSrc` alias - `jest.config.cjs` -- drop `apiSrc/(.*)` moduleNameMapper - `.eslintrc.js` -- drop `apiSrc/**` from the UI override's `import/order.pathGroups`; keep it in the root-level pathGroups since desktop's source still legitimately imports through `apiSrc/*` (embedded-API architecture; out of scope). Kept untouched - `redisinsight/desktop/vite.main.config.ts` -- its `resolve-imports` plugin still maps `apiSrc/*` to the api/dist bundle for embedded use. - The `no-restricted-imports` rule in `.eslintrc.js` -- still the active guard preventing UI regressions. - Root tsconfig `paths` -- `apiSrc/*` and `src/*` stay; desktop main webpack still resolves through them via TsconfigPathsPlugins(). Verification - yarn lint clean (1-time eslint cache rebuild on the `.eslintrc.js` hash change) - yarn type-check:ui 1953 errors (-151 vs the prior root-based baseline of 2104; UI-only subset 1925->1925, flat. Drop comes from no longer compiling desktop/playwright/stories under `type-check:ui`) - yarn build:ui succeeds - yarn build:renderer succeeds (electron variant) - yarn build:main succeeds (load-bearing check: TsconfigPathsPlugins still resolves apiSrc/*, uiSrc/*, desktopSrc/*) - yarn build-sb succeeds - jest smoke (browser slices + commands-history + key-details + database-analysis): 17 suites, 622 tests, all pass Refs RI-7682 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * RI-7682 Drop obsolete FE-side BE-coupling guardrails and stale docs Follow-on to the self-contained UI tsconfig commit. With the UI's toolchain no longer carrying `apiSrc`/`src` aliases (vite, jest, storybook, packages, desktop renderer), the FE has no way to import from the BE codebase even by accident -- module resolution fails at every stage. The remaining guardrails and documentation that pointed the UI at `apiSrc/*` are now stale. - `.eslintrc.js`: drop the `no-restricted-imports` rule that warned against `apiSrc/*` / `src/*` group imports. With no resolver resolving those patterns in the UI workspace, the build chain is the enforcement now. Also fix the UI override's `parserOptions.project` to point at `redisinsight/ui/tsconfig.json` rather than the root tsconfig -- the UI is now type-checked against its own self-contained config. - `tsconfig.json`: drop the explanatory header comment introduced in the prior commit. The root tsconfig's role is whatever its content shows; the comment was a smell. - `.github/copilot-instructions.md`, `.ai/rules/code-quality.md`, `.ai/rules/backend.md`: stop listing `apiSrc/*` as a UI-side alias (it isn't), point AI tooling at `apiClient` for UI consumers of BE-defined types, and correct the backend rule that referenced `apiSrc/*` instead of `src/*` (the BE's actual self-alias). The remaining `apiSrc/*` references in the repo (root tsconfig paths, root eslint pathGroups, `configs/webpack.paths.ts`, the desktop sources, the API workspace's package/tsconfig) are all legitimate or out of scope for FE/BE decoupling. Refs RI-7682 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * RI-7682 Clean up unused apiSrc aliases in BE/build configs Per-file audit of the remaining `apiSrc` references that aren't in desktop sources or the root tsconfig (which is still needed by the desktop main webpack bundle until the desktop decoupling PR). - redisinsight/api/tsconfig.json: drop the `apiSrc/*` path alias. The BE workspace has zero imports through `apiSrc/*` (verified with `grep -rEn "from 'apiSrc/'" redisinsight/api`); BE code uses `src/*` for self-references. - redisinsight/api/package.json: drop the matching `apiSrc/(.*)` jest moduleNameMapper entry for the same reason. - redisinsight/api/package.tmp.json: delete. Orphaned duplicate of package.json with stale relative paths (`../../node_modules/.bin/jest`, pre-monorepo layout) and no consumer anywhere in the repo (CI, scripts, configs). - configs/webpack.paths.ts: drop the `apiSrcPath` const + export. Unused -- `tsconfig-paths-webpack-plugin` reads root tsconfig's `paths` directly; no external consumer of this constant. - .eslintignore: add `storybook-static`. Pre-existing oversight that surfaced once `yarn build-sb` was actually run in CI/dev. Refs RI-7682 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * RI-7682 Move IParsedDeepLink to UI electron constants; drop desktopSrc from UI tsconfig `ConfigElectron.tsx` had the one and only UI->desktop import: a type (`IParsedDeepLink`) used as the payload shape of the `IpcOnEvent.deepLinkAction` IPC event. The desktop's deep-link handler already imports `IpcOnEvent` from `uiSrc/electron/constants` -- the event name lives on the UI side. Move the payload type alongside it so both sides of the IPC contract live in the UI workspace, and the UI stops reaching into desktop source. - redisinsight/ui/src/electron/constants/deepLink.ts: new file with the `IParsedDeepLink` interface (verbatim copy of the desktop's prior declaration). - redisinsight/ui/src/electron/constants/index.ts: re-export. - redisinsight/ui/src/electron/components/ConfigElectron/ConfigElectron.tsx: import from `uiSrc/electron/constants`. - redisinsight/desktop/src/lib/app/deep-link.handlers.ts: drop the local declaration; import the type from `uiSrc/electron/constants` alongside `IpcOnEvent`. - redisinsight/desktop/src/utils/resolveHtmlPath.ts: import from `uiSrc/electron/constants` rather than from the desktop sibling. With no UI file importing through `desktopSrc/*`, drop that alias from `redisinsight/ui/tsconfig.json` paths. The UI no longer claims any visibility into desktop source -- the dependency arrow points one way (desktop -> uiSrc) which matches the existing IPC plumbing. Refs RI-7682 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> | 5 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 1 年前 | ||
| 1 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 6 个月前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 1 年前 | ||
| 4 个月前 | ||
| 3 个月前 | ||
| 1 年前 | ||
| 5 个月前 |