Skip to content

feat(desktop): native OS notifications (T3) - #306

Merged
qnbs merged 9 commits into
mainfrom
feat/tauri-native-notifications
Aug 1, 2026
Merged

feat(desktop): native OS notifications (T3)#306
qnbs merged 9 commits into
mainfrom
feat/tauri-native-notifications

Conversation

@qnbs

@qnbsqnbs commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

Adds opt-in native OS notifications for long-running background tasks in the Tauri desktop build (Phase 2 / T3):

  • Encrypted library backup export complete
  • Manuscript export complete
  • App updater ready to install
  • ProForge pipeline stage ready for review

Gated behind a new settings.desktop.desktopNotifications toggle (default off), only active in the Tauri runtime, permission-gated via @tauri-apps/plugin-notification.

Changes

  • services/desktop/desktopNotifications.ts — permission check/request/send wrapper, web no-op
  • hooks/useNativeNotifications.ts — requests OS permission once when the setting is enabled
  • app/listenerMiddleware.ts — new listener: ProForge stageCompleted → native notification
  • components/settings/DesktopSection.tsx — new Settings toggle
  • types.ts / settingsDefaults.ts / idbProjectStore.tsDesktopSettings.desktopNotifications field + backfill
  • src-tauri/ — registers tauri-plugin-notification + notification:default capability
  • i18n — new keys across all 19 locales (core translated; Beta/RTL backfilled with English fallback)
  • Tests — desktopNotifications.test.ts, useNativeNotifications.test.ts, listener middleware coverage, mock fixes for the new required field

Validation

  • pnpm run lint — clean
  • pnpm run typecheck — clean
  • pnpm run i18n:check — 19 locales, 2867 keys, parity OK
  • node scripts/check-suppressions.mjs — 52/52 baseline, no new suppressions
  • Targeted vitest run — 87 passed across 6 files
  • Rust build CI (tauri-build.yml) — dispatching separately since ci.yml doesn't compile src-tauri/

🤖 Generated with GitHub Copilot

Summary by CodeRabbit

  • New Features
    • Added opt-in desktop notifications for completed exports, ProForge stages, and available app updates.
    • Added a Desktop Notifications setting with native permission handling.
    • Notifications are localized across supported languages.
  • Bug Fixes
    • Existing saved settings now receive safe notification defaults.
    • Notifications are suppressed when disabled, unavailable, duplicated, or when an operation fails.
  • Documentation
    • Updated localization metrics and documented notification-related review behavior.

Adds opt-in native OS notifications for long-running background tasks
in the Tauri desktop build: encrypted library backup export, manuscript
export, app updater ready, and ProForge pipeline stage completion.
- services/desktop/desktopNotifications.ts: permission check/request/send
wrapper around @tauri-apps/plugin-notification, no-op on the web
- hooks/useNativeNotifications.ts: requests OS permission once when
settings.desktop.desktopNotifications is enabled in Tauri
- app/listenerMiddleware.ts: 9th listener category — ProForge
stageCompleted triggers a native notification when enabled
- components/settings/DesktopSection.tsx: new toggle in Settings
- types.ts / settingsDefaults.ts / idbProjectStore.ts: DesktopSettings
gains desktopNotifications (default false), backfilled on load
- src-tauri: registers tauri-plugin-notification + notification:default
capability
- i18n: new desktop.notify.*, desktop.settings.desktopNotifications*,
export.notify.* keys across all 19 locales (core translated, Beta/RTL
backfilled with English fallback)
- tests: desktopNotifications, useNativeNotifications, listener
middleware coverage for the new stageCompleted trigger, plus mock
fixes for the new required DesktopSettings field
Co-Authored-By: GitHub Copilot (Claude Sonnet 5) <noreply@github.com>
CopilotAI review requested due to automatic review settings August 1, 2026 06:58
@vercel

vercelBot commented Aug 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
worldscript-studioReadyReadyPreviewAug 1, 2026 10:57am

@deepsource-io

deepsource-ioBot commented Aug 1, 2026

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in 1e14049...2f84752 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

Important

Some issues found as part of this review are outside of the diff in this pull request and aren't shown in the inline review comments due to GitHub's API limitations. You can see those issues on the DeepSource dashboard.

PR Report Card

Overall GradeSecurity

Reliability

Complexity

Hygiene

Code Review Summary

AnalyzerStatusUpdated (UTC)Details
DockerAug 1, 2026 10:57a.m.Review ↗
JavaScriptAug 1, 2026 10:57a.m.Review ↗
PythonAug 1, 2026 10:57a.m.Review ↗
RustAug 1, 2026 10:57a.m.Review ↗
ShellAug 1, 2026 10:57a.m.Review ↗
SecretsAug 1, 2026 10:57a.m.Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

@coderabbitai

coderabbitaiBot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in:49 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b1e64c81-9d70-442e-83f9-1bfe3cfe9324

📥 Commits

Reviewing files that changed from the base of the PR and between f3a67cc and 2f84752.

📒 Files selected for processing (6)
  • .github/copilot-instructions.md
  • AGENTS.md
  • CLAUDE.md
  • hooks/useExportView.ts
  • hooks/useTauriUpdater.ts
  • tests/unit/settings/DataSection.test.tsx
📝 Walkthrough

Walkthrough

This change adds opt-in native desktop notifications for application updates, successful exports, encrypted library exports, and completed ProForge stages. It adds Tauri integration, localized notification text, persisted settings support, translation loading, and unit tests.

Changes

Desktop notification support

Layer / File(s)Summary
Notification platform and settings
services/desktop/..., hooks/useNativeNotifications.ts, src-tauri/..., types.ts, features/settings/..., components/settings/DesktopSection.tsx
The Tauri notification plugin and capability are registered. The desktopNotifications setting is persisted, normalized, displayed, and used for permission requests.
Notification workflows
app/listenerMiddleware.ts, hooks/useExportView.ts, hooks/useTauriUpdater.ts, components/settings/DataSection.tsx, services/i18n/staticTranslate.ts, App.tsx
Localized notifications are sent for completed ProForge stages, successful exports, encrypted library exports, and available updates.
Localization and validation
locales/*, public/locales/*, tests/unit/..., README.md, docs/DEEPSOURCE-REVIEW-LOOP.md
Notification strings and locale bundle entries are added. Tests cover permissions, settings, translations, notification gating, export results, updater behavior, and ProForge listeners. README metrics are updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
participant App
participant Settings
participant NotificationService
participant Tauri
participant TranslationService
App->>Settings: Read desktopNotifications
App->>NotificationService: Request permission when enabled
NotificationService->>Tauri: Check or request native permission
App->>TranslationService: Resolve localized title and body
App->>NotificationService: Send notification after task completion
NotificationService->>Tauri: Dispatch native notification
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 61.54% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: adding native OS notifications for the desktop application.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/tauri-native-notifications

Comment @coderabbitai help to get the list of available commands.

Comment threadhooks/useNativeNotifications.ts
…ce RS-R1000)
Split the single 26-complexity menu-building function into five small
per-submenu builders (build_file_menu/build_edit_menu/build_view_menu/
build_window_menu/build_help_menu). No behavior change — same menu
items, same order, same IDs.
Co-Authored-By: GitHub Copilot (Claude Sonnet 5) <noreply@github.com>

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds opt-in native desktop notifications for completed exports, backups, updater checks, and ProForge stages.

Changes:

  • Adds Tauri notification plugin integration and permission handling.
  • Adds persisted settings, UI controls, i18n keys, and notification triggers.
  • Adds targeted notification and settings tests.

Reviewed changes

Copilot reviewed 77 out of 78 changed files in this pull request and generated 7 comments.

Show a summary per file
FileDescription
types.tsAdds the desktop notification setting.
App.tsxInitializes notification permissions.
app/listenerMiddleware.tsNotifies on ProForge stage completion.
components/settings/DataSection.tsxNotifies after encrypted backup.
components/settings/DesktopSection.tsxAdds the notification toggle.
features/settings/settingsDefaults.tsDefaults notifications to off.
hooks/useExportView.tsNotifies after manuscript export.
hooks/useNativeNotifications.tsRequests OS notification permission.
hooks/useTauriUpdater.tsNotifies when updates are available.
services/desktop/desktopNotifications.tsImplements the Tauri notification wrapper.
services/storage/idbProjectStore.tsBackfills persisted settings.
src-tauri/Cargo.tomlAdds the Rust notification plugin.
src-tauri/capabilities/default.jsonGrants notification capability.
src-tauri/src/lib.rsRegisters the notification plugin.
package.jsonAdds the JavaScript notification package.
pnpm-lock.yamlLocks the new package.
tests/unit/desktopNotifications.test.tsTests notification service behavior.
tests/unit/languageToolClient.test.tsUpdates the settings fixture.
tests/unit/listenerMiddleware.test.tsTests ProForge notifications.
tests/unit/settings/DesktopSection.test.tsxTests the settings toggle.
tests/unit/useNativeNotifications.test.tsTests permission gating.
locales/ar/desktop.jsonAdds Arabic fallback keys.
locales/ar/export.jsonAdds Arabic fallback export keys.
locales/de/desktop.jsonAdds German desktop strings.
locales/de/export.jsonAdds German export strings.
locales/el/desktop.jsonAdds Greek fallback keys.
locales/el/export.jsonAdds Greek fallback export keys.
locales/en/desktop.jsonAdds English desktop strings.
locales/en/export.jsonAdds English export strings.
locales/es/desktop.jsonAdds Spanish desktop strings.
locales/es/export.jsonAdds Spanish export strings.
locales/eu/desktop.jsonAdds Basque fallback keys.
locales/eu/export.jsonAdds Basque fallback export keys.
locales/fa/desktop.jsonAdds Persian fallback keys.
locales/fa/export.jsonAdds Persian fallback export keys.
locales/fi/desktop.jsonAdds Finnish fallback keys.
locales/fi/export.jsonAdds Finnish fallback export keys.
locales/fr/desktop.jsonAdds French desktop strings.
locales/fr/export.jsonAdds French export strings.
locales/he/desktop.jsonAdds Hebrew fallback keys.
locales/he/export.jsonAdds Hebrew fallback export keys.
locales/hu/desktop.jsonAdds Hungarian fallback keys.
locales/hu/export.jsonAdds Hungarian fallback export keys.
locales/is/desktop.jsonAdds Icelandic fallback keys.
locales/is/export.jsonAdds Icelandic fallback export keys.
locales/it/desktop.jsonAdds Italian desktop strings.
locales/it/export.jsonAdds Italian export strings.
locales/ja/desktop.jsonAdds Japanese fallback keys.
locales/ja/export.jsonAdds Japanese fallback export keys.
locales/ko/desktop.jsonAdds Korean fallback keys.
locales/ko/export.jsonAdds Korean fallback export keys.
locales/pt/desktop.jsonAdds Portuguese fallback keys.
locales/pt/export.jsonAdds Portuguese fallback export keys.
locales/ru/desktop.jsonAdds Russian fallback keys.
locales/ru/export.jsonAdds Russian fallback export keys.
locales/sv/desktop.jsonAdds Swedish fallback keys.
locales/sv/export.jsonAdds Swedish fallback export keys.
locales/zh/desktop.jsonAdds Chinese fallback keys.
locales/zh/export.jsonAdds Chinese fallback export keys.
public/locales/ar/bundle.jsonRebuilds the Arabic runtime bundle.
public/locales/en/bundle.jsonRebuilds the English runtime bundle.
public/locales/he/bundle.jsonRebuilds the Hebrew runtime bundle.
public/locales/ko/bundle.jsonRebuilds the Korean runtime bundle.
public/locales/pt/bundle.jsonRebuilds the Portuguese runtime bundle.
public/locales/ru/bundle.jsonRebuilds the Russian runtime bundle.
public/locales/sv/bundle.jsonRebuilds the Swedish runtime bundle.
public/locales/zh/bundle.jsonRebuilds the Chinese runtime bundle.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Comment threadhooks/useExportView.ts Outdated
Comment threadhooks/useExportView.ts
Comment threadhooks/useTauriUpdater.ts
Comment threadsrc-tauri/Cargo.toml
Comment threadapp/listenerMiddleware.ts Outdated
Comment threadfeatures/settings/settingsDefaults.ts
Comment threadcomponents/settings/DataSection.tsx Outdated
@codeant-ai

codeant-aiBot commented Aug 1, 2026

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit:f3a67cc0
Scan Time: 2026-08-01 10:07:23 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality GateStatusDetails
Secrets✅ PASSED0 secrets found
Duplicate Code✅ PASSED0.3% duplicated
SAST✅ PASSEDNo security issues
Bugs✅ PASSEDRating S: No bugs
IAC✅ PASSEDRating S: No issues

View Full Results

qnbsand others added 3 commits August 1, 2026 09:05
Fixes the docs:check drift gate — 6 new desktop-notification keys
raised the total from 2861 to 2867 across all 19 locales.
Co-Authored-By: GitHub Copilot (Claude Sonnet 5) <noreply@github.com>
… wave on PR #306
Same pattern as PR #305 — DeepSource: JavaScript flags 63 pre-existing
issues across app/listenerMiddleware.ts (god-file) whenever it's touched.
Confirmed informational-only (not a required status check) and that none
of the findings land on the new code. No action taken per established
precedent (§4a.3, §11).
Co-Authored-By: GitHub Copilot (Claude Sonnet 5) <noreply@github.com>
- Cargo.lock: sync tauri-plugin-notification dependency via
`cargo metadata` (minimal-diff, no unrelated version bumps).
- useExportView: only send the 'export complete' desktop notification
when the export actually succeeded; PDF/DOCX/EPUB now report success/
failure instead of always resolving. Adds coverage for the failure
paths.
- useTauriUpdater: fix test suite that lacked a Redux <Provider> wrapper
(was passing accidentally, not exercising the real selector).
- settingsSlice: merge (not replace) desktop settings on setSettings so
a legacy/imported settings envelope that predates a new
DesktopSettings field (e.g. desktopNotifications) doesn't clobber it
back to undefined.
- listenerMiddleware: replace hardcoded English ProForge notification
strings with i18n via a new middleware-safe static translator
(services/i18n/staticTranslate.ts), since listener middleware runs
outside React and can't call useTranslation(). New
desktop.notify.proforgeStageReady{Title,Body} keys across all 19
locales (core 4 hand-translated, Beta/RTL backfilled with EN
fallback via check-i18n-keys.mjs --fix).
Refs: PR #306 review threads (Copilot reviewer findings #2-#7).
@socket-security

socket-securityBot commented Aug 1, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

DiffPackageSupply Chain
Security
VulnerabilityQualityMaintenanceLicense
Addedcargo/​tauri-plugin-notification@​2.3.390100100100100

View full report

Comment threadhooks/useExportView.ts
@codecov

codecovBot commented Aug 1, 2026

Copy link
Copy Markdown

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
hooks/useExportView.ts (1)

147-226: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add compliant QNBS-v3 comments next to each material change.

The existing Line 38 comment uses // QNBS-v3 (T3):, not the required // QNBS-v3: [reason / impact / value] format. The export-result changes and test changes also have no adjacent compliant annotation.

  • hooks/useExportView.ts#L147-L226: Add a QNBS-v3 comment for PDF success reporting.
  • hooks/useExportView.ts#L228-L296: Add a QNBS-v3 comment for DOCX success reporting.
  • hooks/useExportView.ts#L298-L351: Add a QNBS-v3 comment for EPUB success reporting.
  • hooks/useExportView.ts#L353-L414: Add a QNBS-v3 comment for notification gating.
  • tests/unit/hooks/useExportView.test.ts#L347-L421: Add a QNBS-v3 comment in the required format for notification-gating coverage.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@hooks/useExportView.ts` around lines 147 - 226, Update hooks/useExportView.ts
ranges 147-226, 228-296, 298-351, and 353-414 by adding adjacent comments for
the PDF, DOCX, EPUB success-reporting, and notification-gating changes,
respectively, using exactly the `// QNBS-v3: [reason / impact / value]` format.
Update tests/unit/hooks/useExportView.test.ts range 347-421 with a compliant
QNBS-v3 comment documenting the notification-gating coverage; replace the
existing noncompliant `// QNBS-v3 (T3):` comment with the required format.

Source: Coding guidelines

🧹 Nitpick comments (2)
App.tsx (1)

58-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the required QNBS-v3 rationale above the new import.

Line 58 adds a substantive TSX import, but no // QNBS-v3: ... comment is immediately above it. Add a one-line explanation.

As per coding guidelines: “Bei jeder inhaltlich relevanten TSX- oder JSX-Änderung einen einzeiligen // QNBS-v3: …-Kommentar unmittelbar über der Änderung verwenden.”

Suggested fix
+// QNBS-v3: Wire native notification permission bootstrap into the app shell.
import { useNativeNotifications } from './hooks/useNativeNotifications';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@App.tsx` at line 58, In App.tsx, add a one-line `// QNBS-v3: ...` rationale
immediately above the `useNativeNotifications` import, describing its purpose in
the notification integration.

Source: Coding guidelines

hooks/useTauriUpdater.ts (1)

16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the required one-line QNBS-v3 annotation format.

Both changed TypeScript files use forms that do not match the repository rule. Replace them with one single-line // QNBS-v3: [Grund / Impact / Kreativer Mehrwert] comment immediately above the related change.

  • hooks/useTauriUpdater.ts#L16-L16: replace // QNBS-v3 (T3): ... with the required colon-and-bracket format.
  • tests/unit/hooks/useTauriUpdater.test.ts#L28-L30: collapse the three-line annotation into one line in the required format.

As per coding guidelines, non-trivial TypeScript changes require one single-line QNBS-v3 comment in the specified format.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@hooks/useTauriUpdater.ts` at line 16, Replace the annotation above the
related change in hooks/useTauriUpdater.ts at lines 16-16 with one single-line
comment using the exact format “// QNBS-v3: [Grund / Impact / Kreativer
Mehrwert]”. Collapse the three-line annotation in
tests/unit/hooks/useTauriUpdater.test.ts at lines 28-30 into the same required
one-line format.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/listenerMiddleware.ts`:
- Around line 543-550: Replace the multi-line annotation above the listener
change in app/listenerMiddleware.ts lines 543-550 with one single-line QNBS-v3
comment using the required “QNBS-v3: [Grund / Impact / Kreativer Mehrwert]”
format. Apply the same single-line format to the permission-request annotation
in services/desktop/desktopNotifications.ts lines 16-17, and add a compliant
single-line comment directly above the static translation implementation in
services/i18n/staticTranslate.ts lines 1-12.
- Around line 553-555: Update the listener effect around the `effect` callback
to synchronously capture `listenerApi.getOriginalState()` before any
asynchronous work, and use that snapshot to read
`settings.desktop?.desktopNotifications` instead of `listenerApi.getState()`.
In `@components/settings/DataSection.tsx`:
- Around line 58-64: Update the dynamic import in the library export success
flow around sendDesktopNotification to handle rejected imports, including
chunk-load and module-evaluation failures. Add a rejection handler or equivalent
try/catch and report the error through the existing logger from
services/logger.ts while preserving the successful notification behavior.
- Around line 57-65: In the library export success flow, add the required
one-line QNBS-v3 rationale comment immediately above the
`settings.desktop?.desktopNotifications` conditional. Keep the existing dynamic
import and `sendDesktopNotification` behavior unchanged.
In `@features/settings/settingsDefaults.ts`:
- Line 9: Add an immediately preceding one-line QNBS-v3 rationale comment for
the new desktopNotifications setting in the settings defaults object, keeping
the comment directly adjacent to that property.
In `@features/settings/settingsSlice.ts`:
- Around line 155-158: Replace the multi-line or incorrectly formatted
annotations with one immediate QNBS-v3: comment for each substantive TypeScript
change: features/settings/settingsSlice.ts lines 155-158,
tests/unit/desktopNotifications.test.ts lines 3-5,
tests/unit/services/staticTranslate.test.ts lines 4-8, and types.ts lines
636-637; add one for each substantive mock change in
tests/unit/listenerMiddleware.test.ts lines 125-133, the regression coverage in
tests/unit/settingsSlice.test.ts lines 249-274, and the fixture contract update
in tests/unit/languageToolClient.test.ts lines 94-97. Each comment must use the
required Grund / Impact / Kreativer Mehrwert content.
In `@hooks/useTauriUpdater.ts`:
- Around line 40-45: Update the successful checkForUpdate notification flow in
useTauriUpdater so it tracks the last successfully notified result.version and
skips sending when the version matches. Only record the version after
sendDesktopNotification is invoked successfully, preserve notifications for new
versions, and add a regression test covering two checks that return the same
version.
- Line 55: Update the auto-check logic in useTauriUpdater so changes to the
I18nProvider’s t function do not recreate checkForUpdate or rerun the automatic
update check after mount. Keep notification translation access stable, or make
the autoCheck effect mount-only while preserving desktopNotificationsEnabled
behavior.
In `@public/locales/el/bundle.json`:
- Around line 998-1003: English notification strings remain in the generated
locale bundles. Add Greek, Basque, Persian, Finnish, and Hebrew translations for
the desktop notification labels in the corresponding locales/<lang>/desktop.json
files and export completion labels in locales/<lang>/export.json; then
regenerate public/locales/el/bundle.json (998-1003, 1087-1088),
public/locales/eu/bundle.json (998-1003, 1087-1088),
public/locales/fa/bundle.json (998-1003, 1087-1088),
public/locales/fi/bundle.json (998-1003, 1087-1088), and
public/locales/he/bundle.json (998-1003, 1087-1088). Do not edit generated
bundles directly.
In `@public/locales/sv/bundle.json`:
- Around line 998-1003: Translate the changed notification keys in
public/locales/sv/bundle.json at lines 998-1003 and 1087-1088, and
public/locales/zh/bundle.json at lines 998-1003 and 1087-1088, replacing English
values with the appropriate Swedish or Chinese translations; then regenerate
each locale bundle from its source locale tree.
In `@services/i18n/staticTranslate.ts`:
- Around line 39-42: Update the catch handler in the locale-bundle loading flow
to accept the caught error and log it through the existing logger from
services/logger.ts before returning the empty fallback bundle. Preserve the
inFlight.delete(lang) cleanup and fallback behavior.
In `@tests/unit/hooks/useTauriUpdater.test.ts`:
- Around line 213-228: The update notification test around useTauriUpdater
should verify interpolation of the pending update version, not only the
translation key. Extend the mockSendDesktopNotification assertion so the
notification body is also checked for the expected version value 2.0.0.
In `@tests/unit/listenerMiddleware.test.ts`:
- Around line 584-594: Update the desktop notification tests around
makeFullStore and stageCompleted to create a valid ProForge run and start the
structural stage before dispatching stageCompleted, so the notification
assertion exercises a real pipeline transition. Add a separate test asserting
that dispatching stageCompleted without a current run or active stage does not
call mockSendDesktopNotification.
---
Outside diff comments:
In `@hooks/useExportView.ts`:
- Around line 147-226: Update hooks/useExportView.ts ranges 147-226, 228-296,
298-351, and 353-414 by adding adjacent comments for the PDF, DOCX, EPUB
success-reporting, and notification-gating changes, respectively, using exactly
the `// QNBS-v3: [reason / impact / value]` format. Update
tests/unit/hooks/useExportView.test.ts range 347-421 with a compliant QNBS-v3
comment documenting the notification-gating coverage; replace the existing
noncompliant `// QNBS-v3 (T3):` comment with the required format.
---
Nitpick comments:
In `@App.tsx`:
- Line 58: In App.tsx, add a one-line `// QNBS-v3: ...` rationale immediately
above the `useNativeNotifications` import, describing its purpose in the
notification integration.
In `@hooks/useTauriUpdater.ts`:
- Line 16: Replace the annotation above the related change in
hooks/useTauriUpdater.ts at lines 16-16 with one single-line comment using the
exact format “// QNBS-v3: [Grund / Impact / Kreativer Mehrwert]”. Collapse the
three-line annotation in tests/unit/hooks/useTauriUpdater.test.ts at lines 28-30
into the same required one-line format.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7c1a4722-dc85-4db0-afb7-54611c6afb4a

📥 Commits

Reviewing files that changed from the base of the PR and between 1e14049 and 8e1799e.

⛔ Files ignored due to path filters (2)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (85)
  • App.tsx
  • README.md
  • app/listenerMiddleware.ts
  • components/settings/DataSection.tsx
  • components/settings/DesktopSection.tsx
  • docs/DEEPSOURCE-REVIEW-LOOP.md
  • features/settings/settingsDefaults.ts
  • features/settings/settingsSlice.ts
  • hooks/useExportView.ts
  • hooks/useNativeNotifications.ts
  • hooks/useTauriUpdater.ts
  • locales/ar/desktop.json
  • locales/ar/export.json
  • locales/de/desktop.json
  • locales/de/export.json
  • locales/el/desktop.json
  • locales/el/export.json
  • locales/en/desktop.json
  • locales/en/export.json
  • locales/es/desktop.json
  • locales/es/export.json
  • locales/eu/desktop.json
  • locales/eu/export.json
  • locales/fa/desktop.json
  • locales/fa/export.json
  • locales/fi/desktop.json
  • locales/fi/export.json
  • locales/fr/desktop.json
  • locales/fr/export.json
  • locales/he/desktop.json
  • locales/he/export.json
  • locales/hu/desktop.json
  • locales/hu/export.json
  • locales/is/desktop.json
  • locales/is/export.json
  • locales/it/desktop.json
  • locales/it/export.json
  • locales/ja/desktop.json
  • locales/ja/export.json
  • locales/ko/desktop.json
  • locales/ko/export.json
  • locales/pt/desktop.json
  • locales/pt/export.json
  • locales/ru/desktop.json
  • locales/ru/export.json
  • locales/sv/desktop.json
  • locales/sv/export.json
  • locales/zh/desktop.json
  • locales/zh/export.json
  • package.json
  • public/locales/ar/bundle.json
  • public/locales/de/bundle.json
  • public/locales/el/bundle.json
  • public/locales/en/bundle.json
  • public/locales/es/bundle.json
  • public/locales/eu/bundle.json
  • public/locales/fa/bundle.json
  • public/locales/fi/bundle.json
  • public/locales/fr/bundle.json
  • public/locales/he/bundle.json
  • public/locales/hu/bundle.json
  • public/locales/is/bundle.json
  • public/locales/it/bundle.json
  • public/locales/ja/bundle.json
  • public/locales/ko/bundle.json
  • public/locales/pt/bundle.json
  • public/locales/ru/bundle.json
  • public/locales/sv/bundle.json
  • public/locales/zh/bundle.json
  • services/desktop/desktopNotifications.ts
  • services/i18n/staticTranslate.ts
  • services/storage/idbProjectStore.ts
  • src-tauri/Cargo.toml
  • src-tauri/capabilities/default.json
  • src-tauri/src/lib.rs
  • tests/unit/desktopNotifications.test.ts
  • tests/unit/hooks/useExportView.test.ts
  • tests/unit/hooks/useTauriUpdater.test.ts
  • tests/unit/languageToolClient.test.ts
  • tests/unit/listenerMiddleware.test.ts
  • tests/unit/services/staticTranslate.test.ts
  • tests/unit/settings/DesktopSection.test.tsx
  • tests/unit/settingsSlice.test.ts
  • tests/unit/useNativeNotifications.test.ts
  • types.ts

Comment threadapp/listenerMiddleware.ts Outdated
Comment threadapp/listenerMiddleware.ts Outdated
Comment threadcomponents/settings/DataSection.tsx
Comment threadcomponents/settings/DataSection.tsx Outdated
Comment threadfeatures/settings/settingsDefaults.ts
Comment threadpublic/locales/el/bundle.json Outdated
Comment threadpublic/locales/sv/bundle.json Outdated
Comment threadservices/i18n/staticTranslate.ts Outdated
Comment threadtests/unit/hooks/useTauriUpdater.test.ts
Comment threadtests/unit/listenerMiddleware.test.ts
qnbs added 2 commits August 1, 2026 10:53
Add coverage for the fire-and-forget desktop notification dispatched
after a successful encrypted library export: verifies it fires when
enabled, is skipped when disabled, and never surfaces as an unhandled
promise rejection when the notification module itself fails. Also adds
a .catch() to the notification promise chain in DataSection.tsx so a
notification failure can never leak past its own best-effort scope.
Addresses PR #306 Copilot review finding on DataSection.tsx coverage.
- app/listenerMiddleware.ts: guard stageCompleted notification against
invalid/missing ProForge run or stage (thread #13)
- hooks/useExportView.ts: extract downloadPlainTextFormat() to reduce
handleDownload cyclomatic complexity (thread #1, DeepSource)
- locales/{el,eu,fa,fi,he,sv,zh}: translate desktop notification and
export completion strings, previously English fallback text
(threads #9, #10)
- tests/unit/listenerMiddleware.test.ts: add regression coverage for
invalid stageCompleted actions
Comment threadhooks/useExportView.ts
Comment threadhooks/useExportView.ts Outdated
Comment threadhooks/useExportView.ts Outdated
Comment threadhooks/useExportView.ts
Comment threadhooks/useTauriUpdater.ts
@qnbs

qnbs commented Aug 1, 2026

Copy link
Copy Markdown
OwnerAuthor

@coderabbitai review

@coderabbitai

coderabbitaiBot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
hooks/useExportView.ts (1)

404-408: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add the required adjacent QNBS-v3 comment.

Lines 404-408 add desktop notification behavior. Add one single-line QNBS-v3 comment immediately above this branch.

Proposed fix
+ // QNBS-v3: send a native completion notification only after a successful user-requested export.
if (exportSucceeded && desktopNotificationsEnabled) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@hooks/useExportView.ts` around lines 404 - 408, Add the required single-line
QNBS-v3 comment immediately above the exportSucceeded &&
desktopNotificationsEnabled branch in the export flow within useExportView,
leaving the existing sendDesktopNotification behavior unchanged.

Source: Coding guidelines

🧹 Nitpick comments (2)
tests/unit/settings/DataSection.test.tsx (1)

178-182: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use userEvent for the export interactions.

Lines 178-182 use fireEvent for user actions. Initialize userEvent.setup() in runEncryptedExport, then await each click and type operation.

Proposed fix
-import { fireEvent, render, screen, waitFor } from '`@testing-library/react`';+import { render, screen, waitFor } from '`@testing-library/react`';+import userEvent from '`@testing-library/user-event`';
async function runEncryptedExport(desktopNotifications: boolean) {
+ const user = userEvent.setup();
// ...
- fireEvent.click(screen.getByText('settings.data.libraryExport.button'));- fireEvent.change(screen.getByLabelText('settings.data.libraryExport.passphraseLabel'), {- target: { value: 'correct horse battery staple' },- });- fireEvent.click(screen.getByText('settings.data.libraryExport.confirm'));+ await user.click(screen.getByText('settings.data.libraryExport.button'));+ await user.type(+ screen.getByLabelText('settings.data.libraryExport.passphraseLabel'),+ 'correct horse battery staple',+ );+ await user.click(screen.getByText('settings.data.libraryExport.confirm'));

As per coding guidelines, “Use @testing-library/user-event for interactions.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/unit/settings/DataSection.test.tsx` around lines 178 - 182, Update
runEncryptedExport to initialize userEvent.setup() and replace the export flow’s
fireEvent.click and fireEvent.change calls with awaited userEvent click and
typing operations, including the library export button, passphrase input, and
confirmation.

Source: Coding guidelines

hooks/useTauriUpdater.ts (1)

45-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the required QNBS-v3 rationale comments.

The notification branch at Lines 45-50 and the dependency change at Line 61 are substantive TypeScript changes. Neither has an immediate single-line QNBS-v3 comment.

Proposed comments
+ // QNBS-v3: gate and deduplicate localized update-ready notifications.
if (desktopNotificationsEnabled && lastNotifiedVersionRef.current !== result.version) {
...
+ // QNBS-v3: re-check when the notification preference changes.
}, [desktopNotificationsEnabled]);

As per coding guidelines, substantive TypeScript changes require an immediate single-line QNBS-v3 rationale comment.

Also applies to: 61-61

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@hooks/useTauriUpdater.ts` around lines 45 - 50, Add immediate single-line
QNBS-v3 rationale comments for the notification branch in useTauriUpdater and
the dependency change at the referenced location, explaining the purpose of each
substantive TypeScript change without altering its behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@hooks/useExportView.ts`:
- Around line 15-16: Collapse the multi-line QNBS-v3 rationale at
hooks/useExportView.ts lines 15-16 into one single-line comment. Apply the same
single-line QNBS-v3 format to the mock rationale at
tests/unit/settings/DataSection.test.tsx lines 63-64, the notification-service
rationale at lines 70-71, and the test-suite rationale at lines 166-167,
preserving each explanation’s meaning.
In `@hooks/useTauriUpdater.ts`:
- Around line 16-18: Update the translator ref synchronization in
useTauriUpdater so tRef.current = t runs inside a useEffect with [t] rather than
during render. Place this synchronization effect before the automatic-check
effect, preserving checkForUpdate’s stable identity and preventing discarded
renders from exposing an uncommitted translator.
---
Outside diff comments:
In `@hooks/useExportView.ts`:
- Around line 404-408: Add the required single-line QNBS-v3 comment immediately
above the exportSucceeded && desktopNotificationsEnabled branch in the export
flow within useExportView, leaving the existing sendDesktopNotification behavior
unchanged.
---
Nitpick comments:
In `@hooks/useTauriUpdater.ts`:
- Around line 45-50: Add immediate single-line QNBS-v3 rationale comments for
the notification branch in useTauriUpdater and the dependency change at the
referenced location, explaining the purpose of each substantive TypeScript
change without altering its behavior.
In `@tests/unit/settings/DataSection.test.tsx`:
- Around line 178-182: Update runEncryptedExport to initialize userEvent.setup()
and replace the export flow’s fireEvent.click and fireEvent.change calls with
awaited userEvent click and typing operations, including the library export
button, passphrase input, and confirmation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2e29444-e172-4bb8-b6e4-85c65e7a4601

📥 Commits

Reviewing files that changed from the base of the PR and between 8e1799e and f3a67cc.

📒 Files selected for processing (37)
  • app/listenerMiddleware.ts
  • components/settings/DataSection.tsx
  • features/settings/settingsDefaults.ts
  • features/settings/settingsSlice.ts
  • hooks/useExportView.ts
  • hooks/useTauriUpdater.ts
  • locales/el/desktop.json
  • locales/el/export.json
  • locales/eu/desktop.json
  • locales/eu/export.json
  • locales/fa/desktop.json
  • locales/fa/export.json
  • locales/fi/desktop.json
  • locales/fi/export.json
  • locales/he/desktop.json
  • locales/he/export.json
  • locales/sv/desktop.json
  • locales/sv/export.json
  • locales/zh/desktop.json
  • locales/zh/export.json
  • public/locales/el/bundle.json
  • public/locales/eu/bundle.json
  • public/locales/fa/bundle.json
  • public/locales/fi/bundle.json
  • public/locales/he/bundle.json
  • public/locales/sv/bundle.json
  • public/locales/zh/bundle.json
  • services/desktop/desktopNotifications.ts
  • services/i18n/staticTranslate.ts
  • tests/unit/desktopNotifications.test.ts
  • tests/unit/hooks/useTauriUpdater.test.ts
  • tests/unit/languageToolClient.test.ts
  • tests/unit/listenerMiddleware.test.ts
  • tests/unit/services/staticTranslate.test.ts
  • tests/unit/settings/DataSection.test.tsx
  • tests/unit/settingsSlice.test.ts
  • types.ts
🚧 Files skipped from review as they are similar to previous changes (33)
  • types.ts
  • tests/unit/services/staticTranslate.test.ts
  • features/settings/settingsSlice.ts
  • tests/unit/languageToolClient.test.ts
  • locales/sv/export.json
  • locales/sv/desktop.json
  • locales/zh/export.json
  • services/desktop/desktopNotifications.ts
  • app/listenerMiddleware.ts
  • tests/unit/settingsSlice.test.ts
  • components/settings/DataSection.tsx
  • tests/unit/hooks/useTauriUpdater.test.ts
  • locales/el/export.json
  • locales/he/desktop.json
  • locales/fi/desktop.json
  • features/settings/settingsDefaults.ts
  • tests/unit/listenerMiddleware.test.ts
  • locales/eu/desktop.json
  • locales/el/desktop.json
  • locales/zh/desktop.json
  • public/locales/zh/bundle.json
  • public/locales/he/bundle.json
  • locales/he/export.json
  • locales/fa/export.json
  • services/i18n/staticTranslate.ts
  • locales/fa/desktop.json
  • public/locales/sv/bundle.json
  • public/locales/fi/bundle.json
  • public/locales/el/bundle.json
  • public/locales/fa/bundle.json
  • public/locales/eu/bundle.json
  • locales/eu/export.json
  • locales/fi/export.json

Comment threadhooks/useExportView.ts Outdated
Comment threadhooks/useTauriUpdater.ts Outdated
qnbs added 2 commits August 1, 2026 12:56
- collapse multi-line QNBS-v3 comments to single lines
- rename anchor elements from 'a' to 'anchor' in useExportView
- sync tRef via useEffect instead of mutating during render
- replace handleDownload if/else-if chain with a format lookup table
- switch DataSection encrypted-export test to userEvent
Add a hard one-physical-line rule for QNBS-v3 comments plus four other
recurring findings (anchor naming, ref-in-render mutation, userEvent
over fireEvent, lookup tables over if/else-if chains) to CLAUDE.md,
AGENTS.md, and .github/copilot-instructions.md so agents apply them
proactively instead of waiting for the review bot to flag them again.
@qnbs

qnbs commented Aug 1, 2026

Copy link
Copy Markdown
OwnerAuthor

@coderabbitai review

@coderabbitai

coderabbitaiBot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Comment threadhooks/useExportView.ts
@qnbs
qnbs merged commit 76d8cfa into mainAug 1, 2026
27 of 28 checks passed
@qnbs
qnbs deleted the feat/tauri-native-notifications branch August 1, 2026 11:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@qnbs