From 64d2e1087b2b7a59bcff91ddff5e384a10cd2eb1 Mon Sep 17 00:00:00 2001 From: J3vb <192430104+J3vb@users.noreply.github.com> Date: Thu, 27 Aug 2026 22:12:52 +0200 Subject: [PATCH] chore: merge main into dev to unblock the alpha.4 release PR (#1425) * ci(deps): bump anthropics/claude-code-action (#1404) Bumps the actions-dependencies group with 1 update: [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action). Updates `anthropics/claude-code-action` from 1.0.193 to 1.0.199 - [Release notes](https://github.com/anthropics/claude-code-action/releases) - [Commits](https://github.com/anthropics/claude-code-action/compare/9d7150bc8a3dae8149739a88019d192b579ad90c...dcb57747bfceeaa1fa72638cae52295d1d853d4a) --- updated-dependencies: - dependency-name: anthropics/claude-code-action dependency-version: 1.0.199 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): pin rfd to tauri-plugin-dialog's major to unblock the cargo group (#1406) The cargo-dependencies group PR (#1405) fails Rust Unit Tests on Linux: error: failed to run custom build command for `rfd v0.17.2` You need to choose at least one backend: `gtk3` or `xdg-portal` features for x86_64-linux rfd is not really ours. It arrives in the tree via tauri-plugin-dialog, which pins ^0.16; we declare it directly only for the fatal-startup message box in lib.rs, where the Tauri app never finished building and the plugin has no AppHandle to run a dialog through. Cargo unifies features only within a semver-compatible version group, so while both wanted ^0.16 there was a single rfd in the graph and the plugin's backend features covered our `default-features = false` declaration too. Bumping our direct dep to 0.17 forks rfd into two crates: the plugin keeps 0.16.0 with its features, ours resolves to 0.17.2 with none, and rfd 0.17 added a build.rs assertion that aborts the Linux build when no backend feature is set. Confirmed in the PR's lockfile, which carries both 0.16.0 and 0.17.2. Adding a Linux backend feature would be the wrong fix: it would paper over the fork and still build rfd twice on every platform for one error dialog. Our version has to track the plugin's instead, so ignore semver-minor rfd updates (0.16 -> 0.17 for a 0.x crate) until tauri-plugin-dialog moves. Patch updates inside 0.16.x still flow. The remaining five crates in the group are unaffected; `windows` in fact consolidates 3 versions down to 2. Cargo.toml is comment-only here - no dependency, feature, or lockfile change - so the build is untouched. Co-authored-by: Claude Opus 5 (1M context) * chore(deps): bump log (#1407) Bumps the cargo-dependencies group with 1 update in the /Client/tauri-client/src-tauri directory: [log](https://github.com/rust-lang/log). Updates `log` from 0.4.33 to 0.4.34 - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.33...0.4.34) --- updated-dependencies: - dependency-name: log dependency-version: 0.4.34 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci(deps): bump anthropics/claude-code-action (#1408) Bumps the actions-dependencies group with 1 update: [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action). Updates `anthropics/claude-code-action` from 1.0.199 to 1.0.200 - [Release notes](https://github.com/anthropics/claude-code-action/releases) - [Commits](https://github.com/anthropics/claude-code-action/compare/dcb57747bfceeaa1fa72638cae52295d1d853d4a...24dcd50c0568f0fc9e9211213a4fd2d9eb15c4e0) --- updated-dependencies: - dependency-name: anthropics/claude-code-action dependency-version: 1.0.200 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(client): strip tags to a fixpoint inside sanitizePassApprox CodeQL alert 17 (js/incomplete-multi-character-sanitization, high) fires on the single-pass `input.replace(/<[^>]*>/g, "")`: a lone replace can in principle splice a fresh `<...>` out of the text either side of what it removed. echoNormalize already loops sanitizePassApprox to a fixpoint, so that was absorbed one level up and the output is unchanged -- but the repetition is now where a reader (and the query) can see it. sanitizePassApprox is a comparison normalizer, never rendered output: its only consumer is the `===` echo match in isUnreconciledEcho. Not a sanitization boundary, so this is a legibility fix, not a security one. Client suite 5257/5257, tsc, lint, hygiene all green. Co-Authored-By: Claude Opus 5 (1M context) * fix(client): put the strip-tags replace inside the loop body The previous form hoisted the `replace` into the `for` header's init expression, so CodeQL still reported it (alert 18, line 217 col 21) -- js/incomplete-multi-character-sanitization only credits a repeated replacement when the call sits in the loop *body*, which is also the shape the rule's own guidance shows. Same fixpoint, same output; `while (out.includes("<"))` gives the loop a real condition instead of `for (;;)`. Client suite 5257/5257, tsc, lint, prettier green. Co-Authored-By: Claude Opus 5 (1M context) --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) --- .github/dependabot.yml | 12 ++++++++++++ .github/workflows/claude.yml | 2 +- Client/src-tauri/Cargo.lock | 4 ++-- Client/src-tauri/Cargo.toml | 8 ++++++++ Client/src/stores/messages.store.ts | 15 ++++++++++++++- 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f35ed01f..a9cc122e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -145,6 +145,18 @@ updates: ignore: - dependency-name: "*" update-types: ["version-update:semver-major"] + # rfd rides into the tree on tauri-plugin-dialog, which pins ^0.16, and we + # declare it directly only for the fatal-startup dialog in lib.rs (there is + # no AppHandle yet, so the plugin API is unusable at that point). Cargo + # unifies features only within a semver-compatible group, so bumping our + # direct dep to 0.17 forks rfd in two: the plugin keeps 0.16 with its + # backend features, ours gets 0.17 with none, and rfd 0.17's build.rs then + # aborts the Linux build demanding `gtk3` or `xdg-portal` (PR #1405). Even + # where it links, it just builds rfd twice. Our version must track the + # plugin's -- drop this entry once tauri-plugin-dialog moves to 0.17. + # Patch updates within 0.16.x still flow through. + - dependency-name: "rfd" + update-types: ["version-update:semver-minor"] # GitHub Actions - package-ecosystem: github-actions diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index b0a577e4..6d35dc97 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -59,7 +59,7 @@ jobs: - name: Run Claude Code id: claude - uses: anthropics/claude-code-action@9d7150bc8a3dae8149739a88019d192b579ad90c # v1 + uses: anthropics/claude-code-action@24dcd50c0568f0fc9e9211213a4fd2d9eb15c4e0 # v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} diff --git a/Client/src-tauri/Cargo.lock b/Client/src-tauri/Cargo.lock index 78efa3b7..118f0a5c 100644 --- a/Client/src-tauri/Cargo.lock +++ b/Client/src-tauri/Cargo.lock @@ -2472,9 +2472,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "lru-slab" diff --git a/Client/src-tauri/Cargo.toml b/Client/src-tauri/Cargo.toml index ee2f18cb..333d4bcd 100644 --- a/Client/src-tauri/Cargo.toml +++ b/Client/src-tauri/Cargo.toml @@ -93,6 +93,14 @@ zeroize = "1" # Encodes the DPAPI ciphertext for the JSON fallback store. Already in the tree # via the tauri/rustls stack, so this costs no extra build. base64 = "0.22" +# Native message box for the fatal-startup path in lib.rs, where the Tauri app +# never built and tauri-plugin-dialog has no AppHandle to run through. Already +# in the tree via that same plugin, so this costs no extra build -- but only +# while the versions match: the plugin pins ^0.16, and Cargo unifies features +# only within a semver-compatible group. Moving this to 0.17 forks rfd into two +# crates, and the copy without the plugin's backend features fails rfd 0.17's +# build.rs on Linux. Pinned to the plugin in .github/dependabot.yml; bump both +# together or neither. rfd = { version = "0.16", default-features = false } # Desktop-only plugins (no mobile bundle target). single-instance carries the diff --git a/Client/src/stores/messages.store.ts b/Client/src/stores/messages.store.ts index f2fe52b9..a4cefaa6 100644 --- a/Client/src/stores/messages.store.ts +++ b/Client/src/stores/messages.store.ts @@ -207,7 +207,20 @@ function sanitizePassApprox(s: string): string { .replace(/'/g, "'") .replace(/ /g, " ") .replace(/&/g, "&"); - const stripTags = (input: string): string => input.replace(/<[^>]*>/g, ""); + // Repeated rather than a single pass: a lone `replace` can in principle + // splice a fresh `<...>` out of the text either side of what it removed. + // echoNormalize's own fixpoint loop already absorbed that, so this is + // output-identical -- it just puts the repetition where a reader (and + // CodeQL's js/incomplete-multi-character-sanitization) can see it. + const stripTags = (input: string): string => { + let out = input; + while (out.includes("<")) { + const next = out.replace(/<[^>]*>/g, ""); + if (next === out) break; + out = next; + } + return out; + }; return unescapeOnce(stripTags(unescapeOnce(s))); }