Skip to content

fix(ai): bundle @tauri-apps/plugin-http in the Tauri desktop build (#266) - #272

Merged
qnbs merged 4 commits into
mainfrom
fix/desktop-local-server-external
Jul 28, 2026
Merged

fix(ai): bundle @tauri-apps/plugin-http in the Tauri desktop build (#266)#272
qnbs merged 4 commits into
mainfrom
fix/desktop-local-server-external

Conversation

@qnbs

@qnbs qnbs commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the still-open half of #266: after #269 merged, the desktop .deb/.msi build stopped discovering a running Ollama/LM Studio even though CORS noise was gone (reported by @gellenburg on the reopened issue).

Root cause: vite.config.ts's rollupOptions.external unconditionally externalized every @tauri-apps/* package from every vite build, including the exact build Tauri's beforeBuildCommand invokes to produce the packaged app. Since services/localServerHttp.ts's @tauri-apps/plugin-http import is dynamic, this left an unresolvable bare module specifier in the shipped desktop bundle — confirmed with a real build + real-Chromium repro producing TypeError: Failed to resolve module specifier '@tauri-apps/plugin-http'. Every caller's catch classified this identically to a genuinely-down server: no CORS console noise (nothing reached the network layer), and no discovery, even with Ollama/LM Studio running.

tauri dev was unaffected (Vite's dev server doesn't apply rollupOptions), so this only surfaced in packaged builds — and the existing unit test mocks @tauri-apps/plugin-http via vi.mock, which bypasses real module resolution and structurally can't catch this class of bug.

Fix

  • Extracted the existing Tauri-build detection (resolveViteBase.ts's TAURI_ENV_PLATFORM/TAURI_PLATFORM check) into a shared isTauriBuild() export, and made rollupOptions.external conditional on it. Verified via a simulated Tauri build (TAURI_ENV_PLATFORM=linux pnpm run build) that @tauri-apps/plugin-http now bundles into its own real chunk, referenced via a resolved relative import rather than a bare specifier. The web/PWA build is unaffected — those code paths are gated by isTauriRuntime() and never exercised there.
  • Hardened services/localServerHttp.ts's resolveFetch(): a failed plugin import now throws a distinct LocalServerError('plugin_unavailable') (logged), instead of silently folding into the generic 'unreachable' classification — so a future regression of this class fails loudly instead of looking like a dead server.
  • Updated ADR-0012 with the build-pipeline gap and fix, and the CHANGELOG.

Note: this branch's base (local main) also carries one small unrelated housekeeping commit (chore(docs): trim root CLAUDE.md and migrate feature patterns to nested files) that predates this fix and isn't part of it — flagging for transparency in review.

Also discovered, explicitly out of scope for this PR: the web/Vercel build already bundles all @tauri-apps/* packages regardless of this fix (confirmed via a git-stash A/B test against the unmodified code) — a pre-existing bundle-size issue, not a functional bug, since isTauriRuntime() gates those paths from ever executing in a browser. Left for a separate follow-up.

Test plan

  • pnpm run lint — clean
  • pnpm run typecheck — clean
  • pnpm exec vitest run tests/unit/resolveViteBase.test.ts tests/unit/localServerHttp.test.ts tests/unit/localServerHttpPluginUnavailable.test.ts tests/unit/ollamaService.test.ts — 40/40 passing
  • Simulated Tauri build (TAURI_ENV_PLATFORM=linux pnpm run build) — confirmed @tauri-apps/plugin-http resolves into a real bundled chunk, no unresolved bare specifier
  • Plain web build — confirmed unaffected (same base, same asset paths as before)
  • Real tauri build + manual Ollama/LM Studio smoke test on the packaged .deb/.msi (not feasible in this environment — flagging for manual verification before merge if possible)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed a regression in packaged desktop builds where local-server discovery (Ollama/LM Studio/vLLM) could fail again.
    • Improved the AI “test connection” flow to show clearer, accurate messages when the desktop HTTP plugin isn’t available (no longer treated as an unreachable server).
  • Localization
    • Added provider- and failure-specific AI connection test error messages across supported languages.
  • Tests
    • Added unit coverage for desktop plugin-unavailable behavior and structured error handling.
  • Documentation
    • Updated relevant ADR/feature guidance with the desktop connectivity regression and new behavior notes.

qnbs and others added 2 commits July 28, 2026 01:23
…ed files

Root CLAUDE.md exceeded the large-file warning threshold (50,377 chars).
Removes content duplicated from the user-global ~/.claude/CLAUDE.md and the
derivable tech-stack line, and moves the per-feature "Current Patterns"
subsections into nested CLAUDE.md files that load only when Claude works
under that directory (features/plotBoard, services/proForge, services,
tests, components, services/copilot, services/voice, services/cloudSync,
features/lora).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
)

vite.config.ts's rollupOptions.external unconditionally externalized every
@tauri-apps/* package from every vite build, including the exact build
Tauri's beforeBuildCommand invokes to produce the .deb/.msi. Since
services/localServerHttp.ts's @tauri-apps/plugin-http import is dynamic,
externalizing it left an unresolvable bare module specifier in the shipped
desktop bundle -- confirmed with a real build + real-Chromium repro
(TypeError: Failed to resolve module specifier '@tauri-apps/plugin-http').
Every caller's catch classified this identically to a genuinely-down
server: no CORS console noise (nothing reached the network layer) and no
Ollama/LM Studio discovery, even with both running -- exactly the symptom
reported on issue #266 after #269 merged.

tauri dev was unaffected (Vite's dev server doesn't apply rollupOptions),
so the regression only surfaced in packaged builds, and the existing unit
test mocks @tauri-apps/plugin-http via vi.mock, which bypasses real module
resolution and structurally cannot catch this class of bug.

Fix: extract the existing Tauri-build detection (resolveViteBase.ts's
TAURI_ENV_PLATFORM/TAURI_PLATFORM check) into a shared isTauriBuild()
export and make rollupOptions.external conditional on it -- the desktop
build now bundles @tauri-apps/plugin-http into its own chunk (verified:
the real plugin implementation is bundled and referenced via a resolved
relative import, not a bare specifier); the web/PWA build is unchanged
(those code paths are gated by isTauriRuntime() and never exercised
there).

Also hardens services/localServerHttp.ts's resolveFetch(): a failed
plugin-http import now throws a distinct LocalServerError('plugin_unavailable')
and logs it, instead of silently falling through to the generic
'unreachable' classification -- cheap insurance against this exact
regression class recurring, undetectable by build-output inspection alone
next time.

Note: confirmed (via git stash A/B test) that the web build already
bundles all @tauri-apps/* packages regardless of this fix -- a
pre-existing, unrelated bundle-size issue (not a functional bug, since
isTauriRuntime() gates these paths from ever executing in a browser).
Out of scope for this fix; left for a separate follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
worldscript-studio Ready Ready Preview, Comment Jul 28, 2026 8:02am

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR fixes packaged Tauri local-server discovery by bundling Tauri HTTP plugins, classifying plugin-load failures distinctly, and returning structured provider connection errors for localized display. It also adds regression tests, changelog and ADR updates, translations, and nested repository guidance.

Changes

Packaged local-server discovery

Layer / File(s) Summary
Tauri build detection and bundling
config/resolveViteBase.ts, vite.config.ts, tests/unit/resolveViteBase.test.ts
Adds shared Tauri detection and bundles @tauri-apps/* for desktop builds while retaining web externalization.
Plugin failure classification and validation
services/localServerHttp.ts, services/ollamaService.ts, tests/unit/*, docs/adr/..., CHANGELOG.md
Classifies plugin import failures as plugin_unavailable, preserves the classification through Ollama checks, and documents and tests the behavior.
Structured connection results and localization
services/aiProviderService.ts, services/ollamaService.ts, components/settings/AiProviderCard.tsx, locales/*/settings.json, public/locales/*/bundle.json
Adds provider error kinds and interpolation parameters, localizes classified failures, and validates provider and UI behavior.

Repository and feature guidance

Layer / File(s) Summary
Repository implementation and testing guidance
CLAUDE.md, components/CLAUDE.md, services/CLAUDE.md, services/cloudSync/CLAUDE.md, services/copilot/CLAUDE.md, tests/CLAUDE.md
Documents AI fallback behavior, feature-flag updates, component patterns, service architecture, and deterministic test mocks.
Feature-specific architecture guidance
features/*/CLAUDE.md, services/proForge/CLAUDE.md, services/voice/CLAUDE.md
Adds architecture and workflow guidance for LoRA, Plot Board, ProForge, and voice features.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SettingsUI
  participant aiProviderService
  participant ollamaService
  participant localServerHttp
  participant TauriPluginHttp
  SettingsUI->>aiProviderService: test provider connection
  aiProviderService->>ollamaService: test Ollama connection
  ollamaService->>localServerHttp: fetch local server
  localServerHttp->>TauriPluginHttp: load desktop HTTP plugin
  TauriPluginHttp-->>localServerHttp: return response or import failure
  localServerHttp-->>ollamaService: return classified local-server result
  ollamaService-->>aiProviderService: return structured error kind
  aiProviderService-->>SettingsUI: render localized connection message
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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 name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main fix: bundling @tauri-apps/plugin-http in Tauri desktop builds.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/desktop-local-server-external

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

@codeant-ai

codeant-ai Bot commented Jul 28, 2026

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 394a1077
Scan Time: 2026-07-28 08:11:08 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 1.9% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED Rating S: No issues

View Full Results

@coderabbitai coderabbitai Bot 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: 5

🧹 Nitpick comments (1)
vite.config.ts (1)

127-133: 🩺 Stability & Availability | 🔵 Trivial

Run one packaged desktop smoke test before release.

The conditional Rollup setting is not validated by the helper unit tests, and tauri dev does not exercise Rollup output. Verify a real .deb/.msi can discover Ollama or LM Studio after packaging.

🤖 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 `@vite.config.ts` around lines 127 - 133, Validate the conditional Rollup
configuration around external by running a packaged desktop smoke test before
release: build a real .deb or .msi, install or launch it, and confirm local
Ollama or LM Studio discovery works. Do not rely on helper unit tests or tauri
dev as substitutes for packaged output validation.
🤖 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 `@config/resolveViteBase.ts`:
- Around line 19-20: Update isTauriBuild in config/resolveViteBase.ts so each
Tauri marker is recognized only when its value is trimmed and non-empty, while
preserving detection for valid values. Add regression cases in
tests/unit/resolveViteBase.test.ts covering empty and whitespace-only
TAURI_ENV_PLATFORM and TAURI_PLATFORM values.

In `@services/CLAUDE.md`:
- Line 13: Update the LanguageTool behavior description in the services
documentation to remove “degrades silently” and specify that network failures
produce sanitized logger output and/or a brief actionable user status. Keep
manuscript text excluded from logs and preserve the existing empty-result
fallback, while documenting the required async failure handling rather than
treating silent swallowing as expected.

In `@services/localServerHttp.ts`:
- Around line 82-85: Update the LocalServerError handling around the plugin load
failure to expose only the stable plugin_unavailable code or translation key at
the service boundary, rather than returning the hard-coded technical message
through ollamaService. Preserve the detailed cause for logging via
services/logger.ts, and ensure the UI translates the exposed code before
rendering user-facing text.

In `@services/voice/CLAUDE.md`:
- Line 5: Clarify the voice logging guidance near HybridIntentEngine and
VoiceCommandService: raw transcripts must never be logged, persisted, or
exposed, including through the IDB log sink. State that only appropriately
redacted event metadata may be stored, or remove the transcript-persistence
reference entirely.

In `@tests/CLAUDE.md`:
- Line 3: Update the useAppSelectorShallow test mock guidance to avoid
introducing any new biome-ignore suppression or explicit any usage. Replace the
untyped selector mock with a typed test helper/mock state that includes
plotBoard and keeps connections, subplots, and tensionOverrides under
project.present.data.

---

Nitpick comments:
In `@vite.config.ts`:
- Around line 127-133: Validate the conditional Rollup configuration around
external by running a packaged desktop smoke test before release: build a real
.deb or .msi, install or launch it, and confirm local Ollama or LM Studio
discovery works. Do not rely on helper unit tests or tauri dev as substitutes
for packaged output validation.
🪄 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: bc3cb309-d08e-49fd-bba3-0dc2ad8d99c6

📥 Commits

Reviewing files that changed from the base of the PR and between a7ffca0 and d0cfd02.

📒 Files selected for processing (19)
  • CHANGELOG.md
  • CLAUDE.md
  • components/CLAUDE.md
  • config/resolveViteBase.ts
  • docs/adr/0012-local-server-connectivity-tauri-http.md
  • features/lora/CLAUDE.md
  • features/plotBoard/CLAUDE.md
  • services/CLAUDE.md
  • services/cloudSync/CLAUDE.md
  • services/copilot/CLAUDE.md
  • services/localServerHttp.ts
  • services/ollamaService.ts
  • services/proForge/CLAUDE.md
  • services/voice/CLAUDE.md
  • tests/CLAUDE.md
  • tests/unit/localServerHttpPluginUnavailable.test.ts
  • tests/unit/ollamaService.test.ts
  • tests/unit/resolveViteBase.test.ts
  • vite.config.ts

Comment thread config/resolveViteBase.ts Outdated
Comment thread services/CLAUDE.md Outdated
Comment thread services/localServerHttp.ts
Comment thread services/voice/CLAUDE.md Outdated
Comment thread tests/CLAUDE.md Outdated
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
components/settings/AiProviderCard.tsx 33.33% 1 Missing and 1 partial ⚠️
services/aiProviderService.ts 87.50% 0 Missing and 2 partials ⚠️
services/localServerHttp.ts 85.71% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

- config/resolveViteBase.ts: isTauriBuild() now requires a trimmed,
  non-empty marker value -- an empty-string TAURI_ENV_PLATFORM/
  TAURI_PLATFORM (e.g. a CI matrix that sets it to "" to unset it) must
  not be read as a Tauri build. Regression tests added.

- services/CLAUDE.md: corrected LanguageTool's "degrades silently"
  wording -- the service actually logs via services/logger.ts and
  returns a distinguishable status, it just never blocks typing.

- Localized ALL of testAIConnection's failure paths across every
  provider (openai/ollama/anthropic/grok/gemini/webllm), not just the
  new plugin_unavailable branch CodeRabbit flagged: added a stable,
  i18n-mappable `kind` (+ `params` for interpolation) alongside the
  existing raw `error` string (kept for logs). AiProviderCard now
  translates via `settings.ai.testError.<kind>` when present, falling
  back to the raw string only when absent. New keys added to all 19
  locales. Also corrected the ollama desktop-required hard-gate message
  in aiProviderService.ts, which had drifted back to blaming CSP
  instead of CORS/Private Network Access (ADR-0012).

- services/voice/CLAUDE.md: clarified the transcript-logging guidance,
  which read ambiguously as if transcripts route into the IDB log sink;
  the code already never passes transcript text to services/logger.ts.

- tests/CLAUDE.md: clarified that the useAppSelectorShallow mock's
  `any` + biome-ignore documents an existing convention (10 test files
  already use it), not a new prescription -- noted a shared typed
  helper as a future refactor candidate rather than doing it here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@qnbs

qnbs commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@coderabbitai coderabbitai Bot 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: 8

🧹 Nitpick comments (1)
services/ollamaService.ts (1)

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

Use one immediate single-line QNBS-v3 annotation per substantive change.

The changed code either has no QNBS-v3 annotation or uses multi-line annotations. Replace these with one concise, adjacent single-line comment per cohesive change. As per coding guidelines, “For every non-trivial change, add one single-line QNBS-v3 comment explaining why the change exists.”

🤖 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 `@services/ollamaService.ts` around lines 190 - 192, Replace each multi-line or
missing annotation with one concise, adjacent single-line QNBS-v3 comment for
the substantive change at services/ollamaService.ts:190-192,
services/aiProviderService.ts:729-752,
components/settings/AiProviderCard.tsx:104-110,
tests/unit/ollamaService.test.ts:89-106,
tests/unit/aiProviderService.test.ts:239-270, and
tests/unit/settings/AiProviderCard.test.tsx:242-244. Ensure each comment
explains why that specific behavior or test change exists, without adding
multiple annotations for one cohesive change.

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 `@locales/fr/settings.json`:
- Line 252: Correct the French timeout message for settings.ai.testError.timeout
in locales/fr/settings.json to describe the Ollama connection timing out,
preserving the {{url}} placeholder, then regenerate
public/locales/fr/bundle.json so its corresponding translation matches the
corrected source.

In `@locales/hu/settings.json`:
- Around line 252-253: Update settings.ai.testError.timeout and
settings.ai.testError.unreachable in locales/hu/settings.json (252-253),
locales/is/settings.json (252-253), locales/it/settings.json (252-253),
locales/ja/settings.json (252-253), locales/ko/settings.json (252-253),
locales/pt/settings.json (252-253), locales/ru/settings.json (252-253),
locales/sv/settings.json (252-253), and locales/zh/settings.json (252-253) to
use provider-neutral translations while preserving the url and message
placeholders. Regenerate the corresponding entries in
public/locales/ar/bundle.json (1860-1861) and public/locales/de/bundle.json
(1860-1861) from the corrected source translations.
- Line 253: Remove the {{message}} interpolation from the user-facing
settings.ai.testError.unreachable translation in locales/hu/settings.json,
locales/is/settings.json, locales/it/settings.json, locales/ja/settings.json,
locales/ko/settings.json, locales/pt/settings.json, locales/ru/settings.json,
locales/sv/settings.json, and locales/zh/settings.json. Update the
unreachable-error handling in services/logger.ts to log the underlying exception
separately, then regenerate public/locales/ar/bundle.json and
public/locales/de/bundle.json so their corresponding translations no longer
include the interpolation.

In `@public/locales/es/bundle.json`:
- Around line 1860-1861: Update the Spanish translations for
settings.ai.testError.timeout and settings.ai.testError.unreachable to avoid
hard-coding “Ollama”; use provider-neutral wording or the configured
provider-name interpolation while preserving the existing URL and message
placeholders.

In `@public/locales/fi/bundle.json`:
- Line 1861: Update the `settings.ai.testError.unreachable` translation in the
Finnish locale to use the product name `Ollama` instead of `Ollamaa`, preserving
the rest of the message and placeholders.

In `@public/locales/hu/bundle.json`:
- Line 1860: Update the settings.ai.testError.timeout translation in the
Hungarian locale to remove the hardcoded Ollama provider name. Use
provider-neutral wording, or interpolate the actual provider consistently with
the result.kind lookup used by all AI providers.

In `@services/aiProviderService.ts`:
- Around line 874-880: Complete the unexpected error translation contract:
preserve kind: 'unexpected' in services/aiProviderService.ts:874-880, add a
rendered-error regression case in
tests/unit/settings/AiProviderCard.test.tsx:226-246, add
settings.ai.testError.unexpected to the source locale, then regenerate
public/locales/ko/bundle.json:1858-1866,
public/locales/pt/bundle.json:1858-1866,
public/locales/ru/bundle.json:1858-1866,
public/locales/sv/bundle.json:1858-1866, and
public/locales/zh/bundle.json:1858-1866.

In `@services/ollamaService.ts`:
- Around line 196-201: Update the error return in the Ollama request handling
flow to stop exposing the caught exception message through the user-facing error
and i18n params. Keep the raw transport details only in sanitized logger
context, and return an actionable localized failure using safe context such as
resolvedUrl; preserve the existing unreachable kind and failure shape.

---

Nitpick comments:
In `@services/ollamaService.ts`:
- Around line 190-192: Replace each multi-line or missing annotation with one
concise, adjacent single-line QNBS-v3 comment for the substantive change at
services/ollamaService.ts:190-192, services/aiProviderService.ts:729-752,
components/settings/AiProviderCard.tsx:104-110,
tests/unit/ollamaService.test.ts:89-106,
tests/unit/aiProviderService.test.ts:239-270, and
tests/unit/settings/AiProviderCard.test.tsx:242-244. Ensure each comment
explains why that specific behavior or test change exists, without adding
multiple annotations for one cohesive change.
🪄 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: 4a9a2b04-e989-4edb-873a-d80a405aca9c

📥 Commits

Reviewing files that changed from the base of the PR and between d0cfd02 and 6ff1db6.

📒 Files selected for processing (49)
  • components/settings/AiProviderCard.tsx
  • config/resolveViteBase.ts
  • locales/ar/settings.json
  • locales/de/settings.json
  • locales/el/settings.json
  • locales/en/settings.json
  • locales/es/settings.json
  • locales/eu/settings.json
  • locales/fa/settings.json
  • locales/fi/settings.json
  • locales/fr/settings.json
  • locales/he/settings.json
  • locales/hu/settings.json
  • locales/is/settings.json
  • locales/it/settings.json
  • locales/ja/settings.json
  • locales/ko/settings.json
  • locales/pt/settings.json
  • locales/ru/settings.json
  • locales/sv/settings.json
  • locales/zh/settings.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/CLAUDE.md
  • services/aiProviderService.ts
  • services/ollamaService.ts
  • services/voice/CLAUDE.md
  • tests/CLAUDE.md
  • tests/unit/aiProviderService.test.ts
  • tests/unit/ollamaService.test.ts
  • tests/unit/resolveViteBase.test.ts
  • tests/unit/settings/AiProviderCard.test.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/unit/resolveViteBase.test.ts
  • services/CLAUDE.md
  • config/resolveViteBase.ts

Comment thread locales/fr/settings.json Outdated
Comment thread locales/hu/settings.json Outdated
Comment thread locales/hu/settings.json Outdated
Comment thread public/locales/es/bundle.json Outdated
Comment thread public/locales/fi/bundle.json Outdated
Comment thread public/locales/hu/bundle.json Outdated
Comment thread services/aiProviderService.ts Outdated
Comment thread services/ollamaService.ts Outdated
- Made settings.ai.testError.timeout/unreachable provider-neutral --
  these keys are selected by the shared, provider-agnostic result.kind
  lookup in AiProviderCard, so hardcoding "Ollama" would misrepresent
  a future non-Ollama provider's timeout/unreachable failure as an
  Ollama one. Reworded across all 19 locales (also fixes the French
  wording that implied Ollama itself had expired, and makes the
  Finnish "Ollamaa" partitive-case reference moot since the word is
  gone entirely).

- Removed {{message}} interpolation from testError.unreachable and
  dropped `params.message` from testOllamaConnection's unreachable
  branch and testAIConnection's outer catch (CWE-209: raw transport
  exception text -- which can include internal detail -- must never
  reach the localized UI string). The technical message is now logged
  via services/logger.ts (new loggers in ollamaService.ts and
  aiProviderService.ts) instead, preserving it for diagnostics.

- Added the missing settings.ai.testError.unexpected key across all
  19 locales -- the catch-all branch already returned kind:
  'unexpected', but no translation existed, so the UI rendered the
  raw key string on any unforeseen connection-test failure. Added a
  regression test in AiProviderCard.test.tsx covering this exact case.

Verified: pnpm run i18n:check (2843 keys x 19 locales, clean),
pnpm run lint (clean), pnpm run typecheck (clean), and the full
AI-provider/ollama/AiProviderCard test suites (103 tests passing).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@qnbs

qnbs commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@coderabbitai coderabbitai Bot 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.

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

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

Missing QNBS-v3 comment on this new test.

The adjacent httpError test carries a QNBS-v3 explanatory comment; this new unexpected-failure regression test does not, breaking the established convention for non-trivial changes in this file.

✏️ Proposed fix
+  // QNBS-v3: regression test for the "unexpected" failure kind — ensures params-less
+  // technical error messages never leak past the i18n key into the rendered UI.
   it('desktop: an unexpected failure (no params) renders the translated key without crashing', async () => {

Based on coding guidelines: "Add one-line QNBS-v3 comments explaining why for non-trivial changes; use the language-appropriate comment syntax."

🤖 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/AiProviderCard.test.tsx` around lines 249 - 267, Add a
one-line QNBS-v3 explanatory comment immediately before the new desktop
unexpected-failure test, matching the adjacent httpError test’s convention and
using valid TypeScript comment syntax. Keep the test behavior unchanged.

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.

Nitpick comments:
In `@tests/unit/settings/AiProviderCard.test.tsx`:
- Around line 249-267: Add a one-line QNBS-v3 explanatory comment immediately
before the new desktop unexpected-failure test, matching the adjacent httpError
test’s convention and using valid TypeScript comment syntax. Keep the test
behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fd7be6e0-565b-4bf7-8b26-1ab9b8053ec2

📥 Commits

Reviewing files that changed from the base of the PR and between 6ff1db6 and 394a107.

📒 Files selected for processing (43)
  • locales/ar/settings.json
  • locales/de/settings.json
  • locales/el/settings.json
  • locales/en/settings.json
  • locales/es/settings.json
  • locales/eu/settings.json
  • locales/fa/settings.json
  • locales/fi/settings.json
  • locales/fr/settings.json
  • locales/he/settings.json
  • locales/hu/settings.json
  • locales/is/settings.json
  • locales/it/settings.json
  • locales/ja/settings.json
  • locales/ko/settings.json
  • locales/pt/settings.json
  • locales/ru/settings.json
  • locales/sv/settings.json
  • locales/zh/settings.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/aiProviderService.ts
  • services/ollamaService.ts
  • tests/unit/aiProviderService.test.ts
  • tests/unit/ollamaService.test.ts
  • tests/unit/settings/AiProviderCard.test.tsx
🚧 Files skipped from review as they are similar to previous changes (38)
  • locales/ja/settings.json
  • locales/el/settings.json
  • locales/fr/settings.json
  • locales/eu/settings.json
  • locales/fa/settings.json
  • locales/es/settings.json
  • locales/pt/settings.json
  • locales/it/settings.json
  • locales/ar/settings.json
  • locales/zh/settings.json
  • locales/ru/settings.json
  • locales/he/settings.json
  • locales/fi/settings.json
  • locales/is/settings.json
  • locales/ko/settings.json
  • public/locales/ru/bundle.json
  • locales/sv/settings.json
  • public/locales/ar/bundle.json
  • public/locales/pt/bundle.json
  • public/locales/el/bundle.json
  • public/locales/fi/bundle.json
  • locales/en/settings.json
  • public/locales/en/bundle.json
  • public/locales/de/bundle.json
  • public/locales/zh/bundle.json
  • public/locales/fa/bundle.json
  • public/locales/fr/bundle.json
  • locales/de/settings.json
  • public/locales/hu/bundle.json
  • public/locales/he/bundle.json
  • public/locales/eu/bundle.json
  • public/locales/sv/bundle.json
  • public/locales/is/bundle.json
  • public/locales/ko/bundle.json
  • locales/hu/settings.json
  • tests/unit/aiProviderService.test.ts
  • tests/unit/ollamaService.test.ts
  • services/aiProviderService.ts

@qnbs
qnbs merged commit 614e1df into main Jul 28, 2026
24 checks passed
@qnbs
qnbs deleted the fix/desktop-local-server-external branch July 28, 2026 08:16
@qnbs
qnbs restored the fix/desktop-local-server-external branch July 28, 2026 08:19
@qnbs
qnbs deleted the fix/desktop-local-server-external branch July 28, 2026 08:19
Sign up for free to 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.

1 participant