chore(tauri): auto-sync version from package.json to Cargo.toml + tauri.conf.json#65
Conversation
…y, Appearance Prevents crashes when persisted settings from older app versions lack advancedEditor, accessibility, or themeCustomization objects. Each section now reads from a defaults-merged local object so missing nested fields can never crash the page. Refs: P0-2, PR #62 alternative
Adds crash-prevention tests for AdvancedEditor, Accessibility, and Appearance sections when their respective nested settings objects are undefined (pre-v1.8 persisted state). Refs: P0-2
…stomization, add missing normalizeAccessibilitySettings import
…ags, deps, vendor forks
…odule extraction Adds tests for the branch-coverage gaps identified in the audit: - GDPR redaction vs preservation branches - Log level branches (debug/info/warn/error) - withContext merging and nesting - Error formatting in args - Module extraction with/without [Prefix] - Cache limit, formatting, and clear Refs: P1-2
…4.30 + 31 transitive bumps
…ri.conf.json Adds scripts/sync-tauri-version.mjs and wires it into predev/prebuild so the desktop version can never drift from the web version again. Refs: P2-4
|
CodeAnt AI is reviewing your PR. Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
storycraft-studio | b2e6aea | May 30 2026, 10:05 PM |
|
|
||
| describe('sanitizeLogContext', () => { | ||
| it('redacts keys matching sensitive pattern', () => { | ||
| const ctx = { apiKey: 'secret', userToken: 'tok', myPassword: 'pw' }; |
There was a problem hiding this comment.
Suggestion: Replace the hardcoded sensitive-looking credential values with clearly synthetic, non-secret placeholders (or generated fixture values) so no plaintext secret/token/password literals are committed, even in tests. [custom_rule_security]
Severity Level: Critical 🚨
Why it matters? 🤔
The test hardcodes values that look like credentials or secrets (apiKey, userToken, myPassword) directly in source. Even though they are only test fixtures, the custom security guidance is to avoid committing plaintext secret-like literals, so this is a real rule violation.
Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** tests/unit/services/logger.test.ts
**Line:** 19:19
**Comment:**
*Custom Rule Security: Replace the hardcoded sensitive-looking credential values with clearly synthetic, non-secret placeholders (or generated fixture values) so no plaintext secret/token/password literals are committed, even in tests.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| port: 3000, | ||
| host: '0.0.0.0', | ||
| // QNBS-v3: Default to loopback for security; opt-in to 0.0.0.0 via VITE_DEV_HOST for Codespaces. | ||
| host: process.env['VITE_DEV_HOST'] || '127.0.0.1', |
There was a problem hiding this comment.
Suggestion: The new default binds the dev server strictly to IPv4 loopback (127.0.0.1). On environments where localhost resolves to IPv6 first (::1), vite dev can become unreachable even on the same machine. Use localhost (or a dual-stack-safe default) instead of forcing IPv4-only binding. [api mismatch]
Severity Level: Major ⚠️
- ❌ `pnpm dev` unreachable via localhost on IPv6-first hosts.
- ⚠️ Developers must override VITE_DEV_HOST to restore access.Steps of Reproduction ✅
1. Ensure environment variable `VITE_DEV_HOST` is unset so the default branch in
`vite.config.ts:31-35` is used (`server.host` falls back to `'127.0.0.1'`).
2. Start the dev server by running `pnpm dev` (script `dev": "vite"` in
`package.json:11-15`), which uses `vite.config.ts` and binds the dev server to host
`127.0.0.1` and port `3000` as configured at `vite.config.ts:31-35`.
3. On a machine where `localhost` resolves to the IPv6 loopback `::1` first (common on
IPv6-first configurations), open a browser and navigate to `http://localhost:3000`.
4. Observe that the browser attempts to connect to `::1:3000`, but the Vite dev server is
only listening on IPv4 `127.0.0.1:3000` (per `server.host` at `vite.config.ts:34`),
resulting in connection failure until the user explicitly sets `VITE_DEV_HOST=0.0.0.0` or
`VITE_DEV_HOST=localhost`.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** vite.config.ts
**Line:** 34:34
**Comment:**
*Api Mismatch: The new default binds the dev server strictly to IPv4 loopback (`127.0.0.1`). On environments where `localhost` resolves to IPv6 first (`::1`), `vite dev` can become unreachable even on the same machine. Use `localhost` (or a dual-stack-safe default) instead of forcing IPv4-only binding.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| preview: { | ||
| port: 4173, | ||
| host: '0.0.0.0', | ||
| host: process.env['VITE_DEV_HOST'] || '127.0.0.1', |
There was a problem hiding this comment.
Suggestion: The same IPv4-only default is also applied to preview mode, so vite preview can fail to be reachable in IPv6-first localhost setups. Keep preview host aligned with a dual-stack-safe default rather than hardcoding IPv4 loopback. [api mismatch]
Severity Level: Major ⚠️
- ❌ `pnpm preview` inaccessible via localhost on IPv6-first hosts.
- ⚠️ Requires preview host override for affected developers.Steps of Reproduction ✅
1. Ensure environment variable `VITE_DEV_HOST` is unset so the preview configuration in
`vite.config.ts:37-40` uses the default `host: '127.0.0.1'` for the `preview` block.
2. Build the app and start preview by running `pnpm build` (script `build": "vite build"`
at `package.json:33-35`) followed by `pnpm preview` (script `preview": "vite preview"` at
`package.json:37-38`), which uses the `preview.host` and `preview.port` settings at
`vite.config.ts:37-40`.
3. On a machine where `localhost` resolves to IPv6 loopback `::1` first, open a browser
and navigate to `http://localhost:4173`.
4. Observe that the browser connects to `::1:4173` while the Vite preview server is only
bound to IPv4 `127.0.0.1:4173` (per `preview.host` at `vite.config.ts:39`), causing
preview to be unreachable until `VITE_DEV_HOST` is explicitly set to a dual-stack-safe
value such as `localhost`.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** vite.config.ts
**Line:** 39:39
**Comment:**
*Api Mismatch: The same IPv4-only default is also applied to preview mode, so `vite preview` can fail to be reachable in IPv6-first localhost setups. Keep preview host aligned with a dual-stack-safe default rather than hardcoding IPv4 loopback.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| const cargoRe = /^version = "[^"]+"/m; | ||
| const cargoNew = cargo.replace(cargoRe, `version = "${version}"`); | ||
| if (cargoNew !== cargo) { |
There was a problem hiding this comment.
Suggestion: The Cargo update path can silently do nothing when the TOML formatting changes (for example version="x.y.z" without spaces), because it relies on a very strict regex and then treats an unchanged string as "already in sync". Add an explicit "pattern not found" check and fail with a non-zero exit so version drift is not hidden. [incomplete implementation]
Severity Level: Major ⚠️
- ❌ Tauri desktop binary ships with outdated Cargo package version.
- ⚠️ Autoupdater may misdetect installed version from Cargo manifest.
- ⚠️ Version drift undetected because sync script reports success.Steps of Reproduction ✅
1. In `/workspace/StoryCraft-Studio/package.json` line 4, change the app version to
`"version": "1.20.0"` so the desired version is `1.20.0`.
2. In `/workspace/StoryCraft-Studio/src-tauri/Cargo.toml` line 3, change the version line
from `version = "1.19.0"` to `version="1.19.0"` (no spaces around `=`), so Cargo.toml is
now both out of date and formatted differently from the regex `^version =`.
3. Ensure `/workspace/StoryCraft-Studio/src-tauri/tauri.conf.json` line 4 has `"version":
"1.20.0",` so only Cargo.toml is out of sync with `package.json`.
4. Run `pnpm run predev` or `pnpm run prebuild`, which invoke `node
scripts/sync-tauri-version.mjs` via the `predev`/`prebuild` scripts in `package.json`
lines 13 and 16; during execution, `scripts/sync-tauri-version.mjs` reads Cargo.toml at
line 29, applies `cargoRe = /^version = "[^"]+"/m` at line 30 and `cargo.replace(...)` at
line 31, finds no match for `version="1.19.0"`, leaves `cargoNew === cargo` so the `if
(cargoNew !== cargo)` block at line 32 is skipped and `changed` stays `false`,
tauri.conf.json already matches so lines 38–46 also do not flip `changed`, and the script
prints `[sync-tauri-version] Already in sync.` at lines 48–49 even though Cargo.toml still
contains the old version.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** scripts/sync-tauri-version.mjs
**Line:** 30:32
**Comment:**
*Incomplete Implementation: The Cargo update path can silently do nothing when the TOML formatting changes (for example `version="x.y.z"` without spaces), because it relies on a very strict regex and then treats an unchanged string as "already in sync". Add an explicit "pattern not found" check and fail with a non-zero exit so version drift is not hidden.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| const tauriRe = /"version":\s*"[^"]+"/; | ||
| const tauriNew = tauriConf.replace(tauriRe, `"version": "${version}"`); | ||
| if (tauriNew !== tauriConf) { |
There was a problem hiding this comment.
Suggestion: The Tauri config update also assumes the version regex always matches; if the key format changes, the script will skip the update and still print "Already in sync." Add a required-match validation before replacement and exit with error if no version field is found. [incomplete implementation]
Severity Level: Major ⚠️
- ❌ Tauri config version can diverge without failing sync.
- ⚠️ Updater endpoints use tauri.conf.json version for releases.
- ⚠️ Build pipeline passes despite missing Tauri version field.Steps of Reproduction ✅
1. In `/workspace/StoryCraft-Studio/package.json` line 4, keep the app version at
`"version": "1.20.0"` and in `/workspace/StoryCraft-Studio/src-tauri/Cargo.toml` line 3
keep `version = "1.20.0"`, so Cargo.toml and package.json are in sync.
2. In `/workspace/StoryCraft-Studio/src-tauri/tauri.conf.json`, replace the top-level
`"version": "1.19.0",` line 4 with a differently named field such as `"appVersion":
"1.19.0",` so there is no `"version":` key matching the regex
`/\"version\":\s*\"[^\"]+\"/`.
3. Run `pnpm run prebuild` (or `pnpm run predev`), which executes `node
scripts/sync-tauri-version.mjs` via the `prebuild`/`predev` scripts in `package.json`
lines 13 and 16.
4. When `scripts/sync-tauri-version.mjs` runs, it reads tauri.conf.json at line 39 and
applies `tauriRe = /"version":\s*"[^"]+"/` and `tauriConf.replace(tauriRe, ...)` at lines
40–41; because the `"version"` key is missing, `tauriNew === tauriConf` so the `if
(tauriNew !== tauriConf)` block at line 42 is skipped, Cargo was already in sync so
`changed` remains `false`, and the script logs `[sync-tauri-version] Already in sync.` at
lines 48–49 even though the effective Tauri app version field in tauri.conf.json has
diverged or is no longer enforced.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** scripts/sync-tauri-version.mjs
**Line:** 40:42
**Comment:**
*Incomplete Implementation: The Tauri config update also assumes the version regex always matches; if the key format changes, the script will skip the update and still print "Already in sync." Add a required-match validation before replacement and exit with error if no version field is found.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| @@ -18,11 +21,13 @@ const PRESET_IDS: Exclude<AccessibilityPresetId, 'custom'>[] = [ | |||
|
|
|||
| export const AccessibilitySection: FC = () => { | |||
| const { t, settings, handleSettingChange } = useSettingsViewContext(); | |||
| // QNBS-v3: Defensive merge — old persisted states may lack accessibility entirely. | |||
| const accessibility = normalizeAccessibilitySettings(settings.accessibility); | |||
There was a problem hiding this comment.
Suggestion: This newly added import/use of normalizeAccessibilitySettings breaks the existing unit-test module mock contract: tests/unit/settings/AccessibilitySection.test.tsx mocks accessibilitySchema but does not export normalizeAccessibilitySettings, so Vitest will throw at module load (No "normalizeAccessibilitySettings" export is defined on the mock). Update the test mock to include that export (or use a partial mock that preserves real exports). [api mismatch]
Severity Level: Critical 🚨
- ❌ AccessibilitySection unit test file fails at import time.
- ❌ CI pipeline fails whenever unit tests are executed.Steps of Reproduction ✅
1. Open `tests/unit/settings/AccessibilitySection.test.tsx` and observe the mock at line
59 (from Grep): `vi.mock('../../../features/settings/accessibilitySchema', () => ({
accessibilityPresetDefaults: ... }))` — this mock only defines
`accessibilityPresetDefaults` on the mocked module (lines 10–20 in the BulkRead snippet).
2. Note that after the mocks, the test imports the component at line 27: `import {
AccessibilitySection } from '../../../components/settings/AccessibilitySection';`
(verified in `tests/unit/settings/AccessibilitySection.test.tsx`).
3. In `components/settings/AccessibilitySection.tsx` (lines 5–8 from BulkRead), the
component imports both `accessibilityPresetDefaults` and `normalizeAccessibilitySettings`
from `../../features/settings/accessibilitySchema`, and uses
`normalizeAccessibilitySettings(settings.accessibility)` at line 25 to compute the
`accessibility` object.
4. When you run the Vitest suite including
`tests/unit/settings/AccessibilitySection.test.tsx` (e.g., via your standard test
command), Vitest resolves the mocked `../../../features/settings/accessibilitySchema`
module; because the mock factory only returns `{ accessibilityPresetDefaults: ... }` and
omits `normalizeAccessibilitySettings`, the ESM import in `AccessibilitySection.tsx`
requests a named export that the mock does not provide, causing Vitest to throw a runtime
error during module load (before any `describe`/`it` blocks execute) about the missing
`normalizeAccessibilitySettings` export on the mock module.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** components/settings/AccessibilitySection.tsx
**Line:** 5:25
**Comment:**
*Api Mismatch: This newly added import/use of `normalizeAccessibilitySettings` breaks the existing unit-test module mock contract: `tests/unit/settings/AccessibilitySection.test.tsx` mocks `accessibilitySchema` but does not export `normalizeAccessibilitySettings`, so Vitest will throw at module load (`No "normalizeAccessibilitySettings" export is defined on the mock`). Update the test mock to include that export (or use a partial mock that preserves real exports).
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix|
CodeAnt AI finished reviewing your PR. |
…tion, CLAUDE.md trim Security — Scorecard Pinned-Dependencies: - Dockerfile: pin node:22-alpine and nginx:1.27-alpine to SHA digests (#46,#47) - .devcontainer/Dockerfile: pin base image SHA, graphifyy==0.8.26, download-then-sha256sum pattern for nodesource/rustup installers, starship v1.25.1 with verified tarball (#60-#64) Security — Scorecard Token-Permissions: - deploy-cloudflare-pages.yml: add top-level permissions:contents:read (#55); remove unnecessary deployments:write — wrangler uses API token, not GitHub token (#65) - mutation.yml: remove unnecessary checks:write — Stryker reporters write local files only (#66) A11y — WCAG AA contrast in CommandPalette: - text-white/80 → text-white and text-white/70 → text-white on --sc-accent selected option (contrast ratios 3.79/4.31/4.02 < 4.5:1 threshold; full-opacity white ≥ 4.5:1) - SaveStatusIndicator: text-green-400 → var(--sc-success-fg) (design token, theme-safe) - NavigatorPanel: <li> wrapper → <div> to avoid nested <li> axe violation E2E stabilization: - helpers.ts + export.spec.ts: add .first() to AI Configuration button (strict mode fix) - a11y.spec.ts: waitForSpaReady instead of domcontentloaded (avoids nav-destroyed evaluate) - lora-wizard.spec.ts: ensureBlankProject before clickNavItem (#sidebar not rendered without project) - playwright.config.ts: PLAYWRIGHT_REUSE_SERVER env var support for VRT job - package.json: test:vrt uses PLAYWRIGHT_REUSE_SERVER=true Docs: - CLAUDE.md: trim from 41.9k to 39.9k chars (remove duplicate quality-gate blocks, timeout-prevention, deprecated sprint-handoff refs, minor verbose one-liners) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
User description
Summary
Eliminates the recurring version drift between web () and desktop (, ).
Changes
Verification
Refs: P2-4
CodeAnt-AI Description
Prevent settings crashes, sync desktop version automatically, and tighten local/dev defaults
What Changed
advancedEditor,accessibility, orthemeCustomization; the pages now open and keep working with default values.package.jsonautomatically, and the Tauri config is updated to the new release version.127.0.0.1by default instead of all network interfaces, with an opt-in env var for shared dev setups.Impact
✅ Fewer settings-page crashes from older saved data✅ No web/desktop version drift✅ Safer local development and tighter desktop app loading rules💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.