Commit Graph
1126 Commits
Author SHA1 Message Date
James Brunton 09e548fbac Fix a11y on DividerWithText (#7482)
# Description of Changes
Nightlies are currently failing with an a11y issue on the
DividerWithText story. This fixes the a11y issue.

<img width="1440" height="1240" alt="image"
src="https://github.com/user-attachments/assets/c1623583-a68c-46d9-8cdb-453aca5ac20d"
/>
2026-08-13 11:10:31 +01:00
brios 1447ed8b62 refactor(redact): replace PDFBox-based text redaction with JPDFium (#7364)
# Description of Changes

Refactors automatic text redaction to use JPDFium-based redaction/text
removal instead of PDFBox

Changes:

* The `RedactController` now uses the JPDFium native redaction engine
(`PdfRedactor.redact`) as the primary method for PDF redaction, with
automatic fallback to the manual redaction service if JPDFium fails or
throws an exception. This improves reliability and leverages more robust
native features when available.
* Regex patterns provided by the user are now validated before redaction
begins, ensuring invalid patterns are rejected early with clear error
messages.
* The code now trims and filters out empty or excessively long redaction
terms, preventing unnecessary processing and potential errors.


<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have run `task check` to verify linters, typechecks, and tests
pass
- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-13 11:10:10 +01:00
staticdevandReece Browne c3802ac1ef fix(frontend): remove Automate operation timeout (#7082)
# Description of Changes

Remove the hard-coded five-minute client-side timeout from Automate
operations.

- Remove `AUTOMATION_CONSTANTS.OPERATION_TIMEOUT`.
- Let normal Automate requests use the API client's default no-timeout
behavior, matching regular tool execution.
- Preserve an explicitly supplied `AutomationProcessingOptions.timeout`
without applying a finite default.
- Add regression coverage verifying that Automate does not send a
client-side timeout by default.

Large PDF operations such as compression can legitimately take more than
five minutes. Previously, Axios aborted the frontend request after
300,000 ms even when the server and reverse proxy allowed the operation
to continue. The backend could continue processing while the frontend
discarded the result.

No significant implementation challenges were encountered.

Closes #7081 

## Testing

The following frontend checks passed:

- Proprietary frontend TypeScript typecheck
- ESLint with zero warnings
- Circular dependency check
- Theme colour lint
- Prettier formatting check
- Focused `automationExecutor.test.ts` regression test
- Complete Vitest suite: 165 test files and 1,354 tests passed

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(not applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(not applicable; no user-facing configuration changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(not applicable)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)
(not applicable)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(not applicable; no visual changes)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.

Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
2026-08-12 15:30:53 +00:00
Ludy fdc1682863 chore: relocate frontend static assets and improve backend-only resource handling (#7171)
# Description of Changes

Move favicons, SVGs, and images from backend resources to frontend
public directory. Update Gradle build to copy sample files in
backend-only mode. Fix og-metadata image references for shared-sign
feature. Update .gitignore to exclude generated/frontend-managed assets
from backend.


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-12 15:27:20 +00:00
Ludy 10ed0f9f73 deps: upgrade Stripe frontend libraries to latest compatible versions (#7110)
# Description of Changes

## What was changed
- Upgraded `@stripe/react-stripe-js` from `4.0.2` to `6.8.0`.
- Upgraded `@stripe/stripe-js` from `7.9.0` to `9.10.0`.
- Updated `package-lock.json` to reflect the new dependency versions.

## Why the change was made
- Keep Stripe frontend dependencies up to date with the latest supported
releases.
- Align `@stripe/react-stripe-js` with its required peer dependency on
`@stripe/stripe-js` `>=9.5.0 <10.0.0`.
- Benefit from the latest bug fixes, improvements, and compatibility
updates provided by the Stripe SDKs.


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-12 15:18:41 +00:00
Ludy 84804d7ce3 fix(frontend): allow null users in mock API options (#7357)
# Description of Changes

Updated the frontend test helper type to allow `user: null` in
`MockAppApiOptions`.

This aligns the TypeScript definition with the existing test usage for
unauthenticated scenarios and resolves the frontend typecheck error in
`login-agreement-modal.spec.ts`.

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-12 15:12:07 +00:00
dependabot[bot] be684942b7 build(deps): bump dompurify from 3.4.12 to 3.4.13 in /frontend (#7367)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.12 to
3.4.13.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cure53/DOMPurify/releases">dompurify's
releases</a>.</em></p>
<blockquote>
<h2>DOMPurify 3.4.13</h2>
<ul>
<li>Fixed an issue with hook removal during <code>IN_PLACE</code>
sanitization, thanks <a
href="https://github.com/koyokr"><code>@​koyokr</code></a></li>
<li>Fixed an issue with hooks potentially bypassing the clone guard,
thanks <a
href="https://github.com/AkshayjainG"><code>@​AkshayjainG</code></a></li>
<li>Fixed an issue with DOM clobbering via <code>ownerDocument</code>
during <code>IN_PLACE</code>, thanks <a
href="https://github.com/AkshayjainG"><code>@​AkshayjainG</code></a></li>
<li>Bumped several dependencies where possible</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/cure53/DOMPurify/commit/3067f774676975de12306effd6db6ad7a9a8c17f"><code>3067f77</code></a>
release: 3.4.13 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1562">#1562</a>)</li>
<li>See full diff in <a
href="https://github.com/cure53/DOMPurify/compare/3.4.12...3.4.13">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dompurify&package-manager=npm_and_yarn&previous-version=3.4.12&new-version=3.4.13)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/Stirling-Tools/Stirling-PDF/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-12 15:08:59 +00:00
Anthony Stirling dc75d399bc Editor url role routing (#7409)
# Description of Changes

- `/` is now a router, not a page: signed-in users go to the processor
or the editor by role. The editor lives at `/editor`.
- `/editor` never routes — always the editor, so processor users have a
URL that won't bounce them.
- Core and desktop keep the editor at `/` (no processor, nothing to
route between).
- `/editor` signed out → `/login` → back to `/editor` after signing in.
- Signed-out visitors aren't redirected: `/` renders the app and Landing
owns it (login page / SaaS inline sign-in / backend-down screen).
- `RootGate` wraps the app instead of being its own route, so nothing
boots on the way to the processor and nothing remounts on the way to the
editor.
- Login resolves its own destination instead of bouncing through `/`.
- Replaces the old once-per-login `LoginLandingRedirect` +
sessionStorage flag. Landing flag and Settings preference unchanged.
- Separate commit: theme-lint crashed on files deleted in the working
tree (`git ls-files` is the index view). Any branch deleting a source
file hit it.
- Sign-out untouched. Tool routes stay top-level, so no deep links or
SEO break.


Future PR to allow users to configure their own routing from / for their
profile

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-12 10:09:18 +00:00
Reece Browne c2e8c3fa71 a11y: empty the grandfathered Storybook baseline (1,058 → 0) (#7309)
## What

Empties the light Storybook accessibility baseline — **1,058
grandfathered violations across 846 stories → 0** — so a new violation
fails the gate instead of being silently absorbed. Also burns the dark
baseline **812 → 56**; every entry left is one `main` already
grandfathers.

## The defect, repeated everywhere

A colour picked as a **fill**, chosen to carry a white label at 3:1,
reused as **text**, where the floor is 4.5:1. It recurred through status
accents, filled buttons, form labels, Mantine's light and outline
variants, CSS declarations, inline styles and the generated accent ramp.

Three systemic causes account for most of it:

- **Mantine's semantic slots were never bound.** `-text`, `-outline`,
`-light-color`, `-filled` and `-dimmed` all default to the hue's solid
fill. Both resolvers now pin them to the accessible ink for the active
scheme.
- **The tint ladder was compressed.** `--color-<hue>-50/100/200` pointed
at saturated 400-level primitives, so every "tint" background rendered
as a fill.
- **Text was faded with `opacity`**, pushing already-muted copy below
the floor. Each site now recedes via ink or surface, which is what
conveyed the state anyway.

## Dark mode

The colour resolver's dark half was empty, so dark fell through to
Mantine's stock palette — and fixing the naming violations unmasked the
contrast sitting underneath them. Both schemes now share one slot map,
since most slots are written in tokens that already flip.

The dark-only fixes: `--c-text-subtle` (3.0:1, used in 478 places), the
error and section-label inks, and the accent ramp's text step — which
light reaches by mixing toward black and dark has to reach by mixing
toward white.

## Also

- New `--c-*-solid` tokens for fills that must carry a white label,
distinct from the `--c-<tone>` values used for surfaces, borders and
icons.
- A `data-user-content-preview` opt-out for nodes rendering a facsimile
of the user's own document — WCAG governs the interface, not content
authored through it.

## Verification

- `task frontend:check:all` — green.
- Changed-set gate, both schemes, after the final rebase: **366 stories,
0 regressions**.
- Full sweep at the prior base — light **1,447 stories / 0 violations**,
dark **1,448 / 0 regressions**. The dark re-record was confirmed
key-by-key to be a strict subset of `main`'s, so nothing new is
grandfathered.

Roughly 28% of what this clears is naming and structure (`button-name`,
`label`, `aria-*`) and has no visual signature; the rest is contrast.
2026-08-12 09:06:05 +00:00
Reece Browne 34819ae502 Draw signatures on a phone via QR code in the Sign tool (#7335)
# Description of Changes

Scan a QR code in the Sign tool, draw your signature on your phone, and
it appears on your desktop ready to place. Rides the mobile scanner's
existing transfer sessions — no new backend endpoints.

**Desktop:** a **Mobile upload** button above the signature source
selector shows a QR code. When the signature arrives, the modal closes,
it lands in the matching source, and **placement activates
automatically** — click the PDF to place.

**Phone:** a new public `/mobile-sign` page with three tabs (same order
as the desktop sources):

- **Draw** → canvas signature. Touch-first pad (pointer events,
DPR-aware, smoothed strokes, undo/clear, black/blue ink, 3 pen sizes),
exported as a transparent PNG cropped to the ink. Compact layout in
phone landscape.
- **Photo** → image signature. "Take a photo" opens the camera directly;
"From gallery" opens the picker. A preview of the current image
signature now shows in the desktop's Image source (previously arrival
was invisible until placement — also fixes this for saved image
signatures).
- **Type** → text signature. Travels as data (text + font + colour), so
it stays *editable* on the desktop. Fonts are the sign tool's own
text-mode list.

**Security:** the transfer endpoints are unauthenticated by design
(10-min sessions, files deleted after download — same model as the
scanner). The desktop treats every arrival as untrusted: images only,
and the text payload is clamped field by field.

**Config:** new `system.enableMobileSignature` flag (default on),
independent of `enableMobileScanner`; the shared endpoints accept
either. The Tauri desktop app serves a self-contained `mobile-sign.html`
(draw-only), mirroring `mobile-upload.html`.

**Refactor:** the session lifecycle (create/poll/download/expiry) moved
out of `MobileUploadModal` into a shared `useMobileTransferSession`
hook; the scanner modal now uses it, behaviour unchanged.

Also fixes two bugs hit along the way: the signature pad collapsing to
its 150px intrinsic height (indefinite parent height), and a setState
loop in `SignSettings` when text parameters are set programmatically
(draft-sync effects ping-ponging).

## Screenshots

| Desktop: QR entry | Phone: draw | Desktop: received |
|---|---|---|
| ![QR
modal](https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/pr-7335-assets/shot-1-qr-modal.png)
| ![Phone draw
tab](https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/pr-7335-assets/shot-2-phone-draw.png)
| ![Signature
received](https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/pr-7335-assets/shot-3-desktop-received.png)
|

## How to test

1. Open the app on an address your phone can reach (not `localhost`),
Sign tool → **Mobile upload**, scan the QR.
2. Draw → **Send to computer** → it becomes the active canvas signature
and placement is live: click the PDF to place.
3. Photo tab → arrives in the Image source with a preview. Type tab →
arrives editable in the Text source.
4. Flags: `enableMobileSignature: false` hides the button; signature
still works with the scanner disabled.

Verified end-to-end (all three kinds, portrait/landscape/tablet) plus
`task frontend:check` and the touched backend tests.

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [x] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have run `task check` to verify linters, typechecks, and tests
pass
- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-11 16:36:51 +00:00
Ludy 35ac74b049 fix(ui): improve mobile language selector positioning (#7158)
# Description of Changes

- Made the language selector dropdown responsive on mobile devices.
- Limited the dropdown width to the available viewport width.
- Changed the language grid to use two columns on small screens.
- Added a scrollable maximum height to prevent the dropdown from
overflowing the settings dialog.
- Updated only:
  - `frontend/editor/src/core/components/shared/LanguageSelector.tsx`
-
`frontend/editor/src/core/components/shared/LanguageSelector.module.css`

The change improves usability on narrow mobile screens, where the
previous fixed-width four-column layout caused the language selector to
overflow horizontally.

before:
<img width="1920" height="1032" alt="image"
src="https://github.com/user-attachments/assets/85eeca25-4aad-4280-8a11-18db4899deec"
/>

after:
<img width="1920" height="1080" alt="image"
src="https://github.com/user-attachments/assets/8b3ccc12-fc1f-4949-88b6-4ca65354a3f9"
/>


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-11 14:18:02 +00:00
brios b56e62caec refactor(sidebar): Replace custom sidebars (bookmark, attachment etc...) with reusable sidebar component (#7143)
# Description of Changes


This helps keeps them consistent and similar/same in regards to design,
colour scheme and so on. Generally, we would want to improve upon this,
as UX bit lacking here and there e.g., with the button
fluidness/conssitency what the button does. Bookmark open sidebar
editor, the other two redirects to the page, those may be made more
consistent.


Changes:

* Refactored `AttachmentSidebar`, `BookmarkSidebar`, and
`CommentsSidebar` to use the new `SidebarBase` component, replacing
custom header, search, and layout code for a more consistent and
maintainable UI.
* Added search functionality to `CommentsSidebar`, including filtering
by comment content and author, and displaying a message when no comments
match the search.
* Updated search placeholders and empty state messages for attachments,
bookmarks, and comments to use translation keys, improving localization
and user feedback.


### New

<img width="1490" height="1816" alt="image"
src="https://github.com/user-attachments/assets/71de659e-388e-4aef-bf03-4c5ee7948a2f"
/>


### Old

<img width="1574" height="1726" alt="image"
src="https://github.com/user-attachments/assets/4604653c-865f-4e75-9737-4b61237efcc6"
/>


<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [X] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [X] I have run `task check` to verify linters, typechecks, and tests
pass
- [X] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-11 14:17:36 +00:00
James Brunton 998e851130 Support using Convert in Pipelines (#7290)
# Description of Changes
Convert tool is currently unavailable in pipelines because it's a very
complex tool so conversions to and from the backend types was previously
skipped for time. This PR redesigns the tool setup so that it can be
used in pipelines and the existing editor/automate uses. There's
probably more work to do one day to have a proper second look at Convert
because the rest of the code has changed so much since it was first
written, but this adds a bit of type safety to it and at least adopts
the bidirectional tool APIs so we're moving in the right direction.

<img width="1263" height="581" alt="image"
src="https://github.com/user-attachments/assets/58d64894-05a4-41e0-a840-3202dd8e0e39"
/>

<img width="1244" height="578" alt="image"
src="https://github.com/user-attachments/assets/79285c2d-6777-4df7-a8fa-1453cb8a8258"
/>

<img width="1249" height="584" alt="image"
src="https://github.com/user-attachments/assets/8ced6bb5-817f-4911-9ada-c3707a777243"
/>

<img width="1245" height="510" alt="image"
src="https://github.com/user-attachments/assets/d01a083c-fb76-4c8c-a526-99613afc2608"
/>
2026-08-11 10:40:45 +00:00
Anthony Stirling 8db44ddbaf feat(policies): default Security policy to run on export (#7407)
# Description of Changes

default Security policy to run on export and not import 
---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-11 10:38:20 +00:00
Anthony Stirling e6680c4cf5 fix(auth): remove signup page from self-hosted builds (#7406)
# Description of Changes

remove signup page from self-hosted builds since all signups are either
default or done via admins
---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-11 10:16:28 +00:00
stirlingbot[bot] bbaff8d6c4 Sync portal docs from docs repo (#7408)
Auto-generated by stirlingbot[bot].

Regenerates `frontend/editor/src/portal/generated/docsManifest.json`
from the Stirling docs repo via `npm run docs:sync`.

Signed-off-by: stirlingbot[bot] <stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2026-08-10 16:55:34 +00:00
EthanHealy01 c929386442 Record policy-run failures as durable, actionable events (Review Flow PR 1) (#7269)
# Description of Changes

PR 1 of the failure-notification work: a durable, team-scoped record of
**why a policy run failed**, surfaced in the portal with the triage
actions each failure allows.

Today a failed policy run is not quite invisible, but it is unusable:
the ledger marks the file `ERROR`, and the audit aspect keeps the
exception message and status code. Nothing classifies either one,
nothing surfaces them, and neither offers a next step. If the file came
from a folder, bucket or webhook there is also no user watching, so
nobody learns it never made it through. This adds the record and the
read surface; the remediation that acts on documents comes later (see
below).

## What this does

**A failure kind registry as data.** `FailureKind` describes what can go
wrong: a stable wire id, i18n keys, an English fallback, and four facets
the review surface needs (`Stage`, `Severity`, `Remedy`, `Scope`). It is
shaped like the existing `ExceptionUtils.ErrorCode` and *links* to that
vocabulary rather than replacing it.

**Classification off structured codes, not message matching.** Policy
steps dispatch over loopback HTTP, so a tool's 4xx arrives as a
`RestClientResponseException` whose body is the Problem Details document
carrying `errorCode`. `FailureClassifier` reads that. Anything
unrecognised becomes `UNKNOWN`, which is the point: every failed run
gets an addressable record from day one, and which kinds to promote next
is answered by production frequency rather than guesswork.

**Actions declared by a kind, implemented as beans.** A kind lists the
`FailureActionId`s it offers; behaviour lives in `FailureAction` beans
resolved by id — the idiom this codebase already uses for `InputSource`,
`PolicyOutputSink` and `PolicyTrigger`. A kind cannot be sent an action
it never declared (400), so an incoherent pairing is unreachable rather
than merely unrendered. A new kind ships as a registry entry plus copy:
no new endpoint, no UI change.

**Repeat folding.** Recording folds a genuine repeat into the existing
incident instead of inserting again, keyed on `(team_id, dedup_key)`.
That matters for a snapshot-mode source that re-lists every file on each
sweep: the same broken file is one incident, not one per sweep. Distinct
files keep distinct rows. The unique constraint is enforced by the
database, and a writer that loses the insert race folds into the
winner's row.

One granularity caveat worth naming: nothing populates `file_id` in this
PR, so every row has it NULL. A FILE-scoped kind therefore dedups on
`policy + run` rather than `policy + file`. That still yields one row
per document for the sources shipped here, because the folder, S3 and
webhook sources each start one run per file; it stops holding as soon as
a single run carries several documents, which is why editor-origin
reporting (item 3 below) populates `file_id`.

**No document identity is stored.** No file name, no content. `fileId`
is an opaque reference only the owner's own client can resolve locally.
`detail` keeps the raw message (the only diagnostic an `UNKNOWN` failure
has) with anything path- or filename-shaped stripped on the way in,
capped at 2,000 characters. `PolicyExecutor`'s type-mismatch message now
reports the *extension* rather than the filename, since that message
becomes the stored `detail`.

**Access.** Reads and triage are leader-only, gated exactly the way
`PolicyController` gates policy editing, with the single-user carve-out
when login is disabled. Every read and write is scoped to the caller's
own team from the authenticated principal — there is no team parameter
on the API.

Self-hosted needs no migration: the table is created from the entity by
`ddl-auto=update`, as with every other table.

## What this does not do yet

- **Actions are incident dispositions, not document dispositions.**
Acknowledge and Dismiss change how a failure is displayed and touch
nothing else — not the document, not the processed-file ledger, not the
run, not any output destination. That is what makes them safe to offer
against `UNKNOWN`, and why there is no Approve/Release yet.
- **Two kinds only.** `INPUT_PASSWORD_PROTECTED` and `UNKNOWN`.
Everything else classifies as `UNKNOWN` and shows its raw message.
- **Editor-origin failures are not reported.** Every row is `PROCESSOR`.
`FailureOrigin.EDITOR` and `API` exist in the enum but nothing writes
them.
- **The list is dev-only for now.** The section renders behind
`import.meta.env.DEV`, so it ships in no production bundle. The
endpoints are live and gated.
- **No retention or per-team cap** on `file_run_events`. Tracked
separately.
- **No suspend-and-prompt.** `PolicyInputRequiredException` and the
engine's `suspend()` exist but nothing throws it, so a run cannot pause
to ask for a password today.
- **SaaS needs a migration** in `Stirling-PDF-SaaS` (`CREATE TABLE IF
NOT EXISTS stirling_pdf.file_run_events`), per the convention documented
at `app/saas/src/main/resources/application-saas.properties:21`.

## What follows in later PRs

1. **Map the remaining error codes to specific kinds** — corrupted file,
OCR unavailable, output destination unreachable, entitlement refusals,
and so on — each with its own copy and its own action set, replacing
today's `UNKNOWN` catch-all with a named notification in the review UI.
2. **Real remediation actions** attached to those kinds: fix (supply a
password and resume), skip (drop this file, continue the batch), and
decline (reject an incoming file outright), acting on the held document
rather than only on the incident row. This is where the
suspend-and-prompt path gets wired.
3. **Editor-origin reporting**, so a failure a user hits in the editor
lands in the same queue as one from a bucket.
4. **The user-facing review surface**: notifications with a sticky
review section, per-file badges, and an export gate, with the dev-only
list here replaced by the real thing.

## How to test

Needs a SaaS or proprietary build with login enabled, and an account
that leads a team.

1. Create a policy in the Processor with any step (Auto-redact is fine)
and a source you can drop files into.
2. Upload two files that will fail it: **a password-protected PDF**, and
**a corrupted PDF** (truncate a valid one, or rename a `.csv` to
`.pdf`).
3. Let the policy run and fail on both.
4. Go to the portal's **Documents** view and scroll to **Failures** (dev
builds only).

Expect two rows:

- **Password-protected document** — classified from `E004`, with the
kind's own labels **"I'll unlock this"** and **"Skip this file"** rather
than generic wording.
- **Unrecognised failure** — the corrupted file, classified `UNKNOWN`
(`E001` is not claimed by a kind yet), showing its raw message with
generic **Acknowledge** / **Dismiss**.

Neither row contains a file name anywhere, including in the raw message.
Press **Show raw JSON** to read exactly what the server returned. Acting
on a row transitions it and comes back with both buttons disabled and a
reason.

Re-running the same batch increments the occurrence count on the
existing rows rather than adding new ones; two *different*
password-protected files produce two separate rows.

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
2026-08-10 16:45:13 +00:00
James Brunton 0ff4ef629c New Pipeline UI redesign (#7202)
# Description of Changes
Supersedes #7144.

Redesign the Processor New Pipeline page to use a graph-based interface.
Far from perfect at this stage but I'm pretty happy with the
interactions on the graph itself. The bar at the top needs some work to
make it prettier and more clear what everything is for, but I'd rather
get this in and do changes in a follow-up PR because this is big enough
on its own and leaves us better than where we were before.

<img width="1270" height="598" alt="image"
src="https://github.com/user-attachments/assets/fa16f7d0-058d-4929-83a2-3c8e42859970"
/>

<img width="1511" height="788" alt="image"
src="https://github.com/user-attachments/assets/bbeb411f-dbf9-43c9-9b34-28b3a5917e5b"
/>

<img width="1261" height="754" alt="image"
src="https://github.com/user-attachments/assets/380fca1f-eed6-44fe-819d-c10598472583"
/>

<img width="1256" height="653" alt="image"
src="https://github.com/user-attachments/assets/59e9a673-b026-43a9-b7f1-ebaf89236df2"
/>

<img width="1216" height="726" alt="image"
src="https://github.com/user-attachments/assets/b34ae323-6842-44d5-b054-eacf08647ad7"
/>
2026-08-10 16:05:05 +00:00
ConnorYohandReece Browne 35a861f4f8 feat(editor): move endpoint availability onto TanStack Query (#7285)
# Description of Changes

> Stacked on #7264, sibling of #7283. Independent of #7283 — the only
overlap is two additive lines in `core/query/keys.ts` and
`core/api/config.ts`. Either can merge first.

## The problem

`useEndpointConfig` kept its own cache: a module-level `globalFetchDone`
boolean, a mutable `globalEndpointCache` object, and a
`resetGlobalCache()` called from the JWT listener. Which consumer
mounted first decided who paid for the request, and nothing invalidated
it except a page reload.

## End state

One shared query for the whole availability map; each of the 12
consumers projects the endpoints it asked for. **251 lines to 101**,
same return shape, no consumer changes.

| | Before | After |
|---|---|---|
| Cross-consumer cache | `globalFetchDone` + mutable module object |
query key |
| Invalidation | `resetGlobalCache()` mutating that object |
`invalidateQueries` |
| Per-endpoint check | own `useState` triple | query keyed by endpoint |

Behaviour kept deliberately:

- **Unknown endpoints and any failure still read as enabled.** This
fires before auth settles, and disabling every tool on a hiccup is worse
than letting one call fail later.
- **`retry` is off for the availability map.** The fallback *is* the
answer, so retrying only doubles a request every logged-out visitor
makes on load.

## Desktop is untouched

`desktop/hooks/useEndpointConfig.ts` shadows this module entirely — no
shared code, so core converting doesn't affect it and there's no
half-migrated state.

It's 482 lines of orchestration rather than fetching: dependency-ready
gating, `tauriBackendService` and `selfHostedServerMonitor`
subscriptions, a 2.5s timeout retry for backend startup, a legacy
`?endpoints=` fallback for old servers, and SaaS-routing optimism that
rewrites disabled endpoints to enabled. It also has no test coverage to
convert against, and it decides whether tools appear at all in the
desktop app.

That's a different job from this one and wants its own review. Next PR.

## Testing

9 new tests: projection onto the requested subset, one request across
consumers, unknown-endpoint fallback, failure fallback with no retry,
empty-list no-fetch, JWT invalidation, and the three single-endpoint
cases.

`task frontend:check` green: 1677 tests across 192 files, typecheck on
all five flavours, eslint, dpdm, prettier.

Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
2026-08-10 12:42:44 +00:00
Anthony Stirling 59ed4f5fd1 Fix automate unrunnable tools (#7311)
# Description of Changes

Fix automate unrunnable tools


## Problem

- Remove Image failed in Automate with `Tool operation not supported:
removeImage`
- Its registry entry had `operationConfig: undefined` even though the
config existed and was already tested
- The Automate picker only filtered on `supportsAutomate`, never on
`operationConfig` — so broken tools were selectable and failed only at
run time

## Fixes

- Wire up `removeImage` and `pageLayout` operation configs (both already
existed, just never registered)
- Exclude `validateSignature` (report tool, not on the operationConfig
seam) and `scannerEffect` (no frontend implementation) via
`supportsAutomate: false`
- Picker now also filters on `operationConfig`, so this class of bug
can't reach users again
- `overlay-pdfs` returns 400 instead of 500 when overlay files or mode
are missing
- Fix `new URL().pathname` Windows path bug that stopped 2 test suites
from loading

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-10 11:14:56 +00:00
Reece Browne 7bf18cc4c7 Storybook: render off the app's real theme CSS, stop hardcoding story colours, and gate a11y in dark mode too (#7187)
## What

Makes Storybook render components with the same CSS the app gives them.

- The preview loaded the token primitives but **not the editor's
semantic token layer** (`styles/theme.css`), so components styled on
those variables rendered unthemed — three onboarding stories were
importing it by hand to stop their modal surfaces rendering transparent.
It's now loaded in the preview and the workarounds are gone.
- **Portal stories render inside the `.portal-scope` wrapper** PortalApp
mounts, so the portal's scoped reset and typography apply to them
exactly as in the app — and, deliberately, to nothing else.
- The folder stories invented their own hex colours, two of which aren't
values the app's `FOLDER_COLOR_PALETTE` can produce. They now use the
palette, so they can't drift from what a user can actually pick.

Deliberately does **not** load `tailwind.css` — tailwind is on its way
out of the editor, so matching the token layer alone is the target
state.

## Story colours route through the tokens, enforced

Stories were exempt from the `code-colors` lint, and it showed:
hardcoded hexes for surfaces the tokens already name (chat bubbles,
borders, demo backgrounds), `var(--x, #hex)` fallbacks that mask a
renamed token by silently painting the stale colour, and mocked category
accents for which real `--color-cat-*` tokens exist.

- Styling literals now use tokens; the dead fallbacks are stripped.
- The stories exemption is removed from `theme-lint`, so this can't
regress.
- Colours that are **the datum itself** — `ColorInput` values, signature
ink, per-policy accents, brand-mark swatches — stay literal via
`theme-allow-color`, hoisted to named consts so the exemption and its
reason sit together.

A practical side effect: stories styled on tokens actually respond to
the dark-mode toolbar toggle, which is what makes a dark-theme a11y pass
meaningful later.

## The a11y gate now runs dark as well as light

Contrast is most of what axe reports and it is theme-dependent, so a
light-only gate left half the surface unmeasured — and it only becomes
measurable at all once the tokens above actually flip. `SCAN_THEME=dark`
pins the theme for a whole scan run, every a11y task runs both themes,
and each theme has its own baseline:

- **light** re-recorded against the themed rendering (the old baseline
measured colours the app never shows): 831 stories with violations
- **dark** recorded for the first time: 798 stories with violations, 980
story-rule pairs, zero render failures across the full sweep

Verified end to end: dark scans measure against dark surfaces (`#18181b`
vs `#ffffff`), both baselines self-check clean, and a live scan of
stories that changed on main after recording passes both gates.
Nightly's timeout doubles for the second sweep.

## Testing

Typecheck (all variants), ESLint and Prettier pass. Onboarding, folder,
portal and control stories render in the browser scan (39/39) with the
per-story CSS imports removed; every story touched by the colour sweep
renders too (58/58). `task frontend:lint:colors` passes with stories
included.
2026-08-10 11:06:18 +00:00
James Brunton af5f54274d Add defaults to calculations for ToolIO (#7289)
# Description of Changes
Currently when calculating the output file type for some tools, the
system will get it wrong because it doesn't know about what the default
parameters in tools are, so if it doesn't have a value for some key,
it'll just bail out and say "it might not be compatible". This PR adds
logic to `ToolIO` to read the default values set for the parameters if
the tool has `ToolIOCase`s and takes them into account when figuring out
the output type. I've built it with horrible Java reflection magic to
avoid having to specify the default for params twice, which will make it
impossible for the defaults to disagree with each other. This just runs
once at startup so there's negligible performance impact.

The change is easily tested with Change Parameters, which is just
`add-password` behind the scenes but with the password params omitted
(so Change Password is always PDF->PDF, never encrypted like Add
Password).

Also (somewhat hackily) fixes a bug I noticed where saving a Change
Permissions step then leaving and returning to the pipeline will cause
the step to be reloaded as Add Password. I've added a system to
disambiguate tools which share the same endpoint (which is only these
two currently).

## Currently

<img width="455" height="135" alt="image"
src="https://github.com/user-attachments/assets/c8867d6a-599b-4f21-a2db-4a1b6ac22d73"
/>

## Now

<img width="415" height="122" alt="image"
src="https://github.com/user-attachments/assets/bd8d1bab-f00a-421b-8c91-5af0d2ad5335"
/>
2026-08-10 11:00:16 +00:00
James Brunton cfaf777f2b Fix more any type usages in frontend code (#7334)
# Description of Changes
Continued effort towards removing all uses of the any type in our
frontend code (last PR was #7326). This PR fixes 7 more folders and
removes them from the exclude list. All of them were localised within
the folder in the exclude list so again were pretty easy to fix.
2026-08-10 10:40:47 +00:00
Anthony Stirling faba9f53ea Update all translations (#7380)
# Description of Changes

Update all translations

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-09 12:45:32 +01:00
Ludy c1275763af chore(i18n): localize hardcoded UI strings across editor components (#7172)
# Description of Changes

This PR replaces multiple hardcoded English UI strings with translation
keys to improve localization consistency throughout the editor.

### What was changed

- Added new translation entries for:
  - AI chat panel header and empty state
  - Generic dropdown placeholders and empty states
  - Generic input placeholder (`Enter value`)
  - Tool renderer "tool not found" message
  - Signature pen size placeholder
- Updated shared components to use translated fallback placeholders
instead of hardcoded English text:
  - `DropdownListWithFooter`
  - `EditableSecretField`
  - `GroupedFormatDropdown`
  - `LanguagePicker`
  - `PenSizeSelector`
- Localized the AI chat panel:
  - Assistant title
  - Empty state message
  - Input placeholder
- Localized the fallback error message displayed when a tool cannot be
resolved.

### Why the change was made

Several shared UI components and the AI assistant interface contained
hardcoded English strings, preventing proper localization and creating
an inconsistent multilingual experience. Moving these strings into the
translation system ensures they can be translated alongside the rest of
the application and provides reusable defaults for shared components.


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-09 12:44:39 +01:00
kastenherri 3260f5415d localization/formFill: Improve german translation and add localization (#7255)
# Description of Changes
The formFill tool name and description as well as the notification popup
for forms were missing their german translations. There were also some
hardcoded text elements in the UI.

Added translations of formFill-related tags and new tags and translation
method for hardcoded strings.

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [x] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation
- [x] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have run `task check` to verify linters, typechecks, and tests
pass
- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.

---------

Signed-off-by: Carsten Drewes <c.drewes@stud.uni-hannover.de>
2026-08-09 12:44:16 +01:00
albanobattistella 0286c716de Updated Italian translation (#7353) 2026-08-09 10:38:24 +00:00
stirlingbot[bot] 4ed2f15122 Update Frontend 3rd Party Licenses (#7329)
Auto-generated by stirlingbot[bot]

This PR updates the frontend license report based on changes to
package.json dependencies.

Signed-off-by: stirlingbot[bot] <stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2026-08-08 21:44:18 +01:00
dependabot[bot] fde1e5bb2a build(deps-dev): bump the react group across 1 directory with 2 updates (#7337)
Bumps the react group with 2 updates in the /frontend directory:
[@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react)
and
[@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).

Updates `@types/react` from 19.2.17 to 19.2.18
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/react-dom` from 19.2.3 to 19.2.4
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-08 21:43:42 +01:00
James Brunton 37a48aa7a7 Replace ESLint and dpdm with Oxlint (#7330)
# Description of Changes
Smaller scope than #6689 to try and get this finished.

Replace ESLint and dpdm with Oxlint, a TS linter written in Rust so its
performance is dramatically better than the existing tools we use.

## Speed improvement
- Current ESLint run: 13.76s
- Current dpdm run: 3.59s
- Total time: 17.35s
- New Oxlint run: 0.90s

So Oxlint is about a 20x speed improvement.

## Differences
When I last tried to do this, we could recreate our rules identically
with Oxlint, but that's not true any more. Oxlint has no current
equivalent for ESLint's `no-restricted-syntax` rule, which we were using
to ban usages of `<button>` and stuff in specific components to try and
encourage them to use our shared UI. This is a very recent addition to
our linting config, and personally I'm willing to drop it for now at
least. We can still ban specific imports in files, so the files which we
were trying to enforce shared UI will still ban directly importing
Mantine, so that'll probably be most of the cases still caught, but I
think there are other ways we can encourage using the shared UI beyond
just using the linter for it.

I did try building a custom TS rule for it and it only slowed it down a
tiny bit (it took 1.1s) but it had to be built on an unreleased alpha
API which just sounds like a maintenance headache we don't need to deal
with for a rule that we don't really need.
2026-08-07 16:02:11 +00:00
James Brunton 408f9ef148 Fix any type usages in frontend code (#7326)
# Description of Changes
Continued effort towards removing all uses of the `any` type in our
frontend code. This PR fixes 10 more folders and removes them from the
exclude list. All of them were really simple fixes.
2026-08-07 13:49:19 +00:00
EthanHealy01andAnthony Stirling cff6549a40 fix(frontend): keep file persistence working when IndexedDB refuses blobs (#7314)
# Description of Changes

Fixes the WebKit nightly failures ([run
31067620195](https://github.com/Stirling-Tools/Stirling-PDF/actions/runs/31067620195/attempts/1)):
8 tests failed on `stubbed-webkit` only, and every one of them logs the
same thing in its trace:

```
IndexedDB add error: UnknownError: Error preparing Blob/File data to be stored in object store
```

## What broke

`storeStirlingFile` stores the `File` itself in IndexedDB, so multi-GB
uploads are persisted by reference and never materialize in JS memory.
That came in with #7175 (`data: stirlingFile` replacing `data: await
stirlingFile.arrayBuffer()`), which is a real memory win and worth
keeping.

WebKit refuses blob values whenever it can't write the blob's backing
file, and rejects the request with the error above. The rejection was
only `console.error`d, so on WebKit **no upload ever persisted**, and
everything that reads the bytes back behaved as if the upload never
happened:

- `file-state-across-tools` — file gone after navigating; the sidebar
shows "No files yet"
- `compare` — `FileSelectorPicker: upload failed`, so the slot stays
`data-slot-state="empty"`
- `classification-grouping` / `classification-heuristic-upload` — the
label backfill and thumbnails read from IDB (`not in IndexedDB (likely
remote-only stub)`), so files land in "Recent" with no category headers

Chromium and Firefox store blobs fine, and PR CI only runs the `stubbed`
(chromium) project, so nightly was the only gate that could catch it.

## The fix

Try the blob first, keep a fallback:

- `storeStirlingFile`'s `add` is extracted into `addFileRecord` so it
can run twice
- if the value was a Blob and the failure is `UnknownError` /
`DataCloneError`, re-add the record with an `ArrayBuffer` copy and set
`blobValuesSupported = false`, so later files in that session go
straight to the copy path instead of losing the blob attempt every time
- deliberately narrow: `QuotaExceededError` and `ConstraintError` still
propagate, because a copy would fail the same way and retrying would
hide the real cause
- dropped two internal `console.error`s: every caller already reports
(`addFiles`, `FileSelectorPicker`, `zipFileService` collects into
`result.errors`), so they were duplicate noise

Every writer goes through `storeStirlingFile` (uploads, the file picker,
zip extraction, folder automation, `IndexedDBContext`), so this one seam
covers all of them. The read paths already accept either shape (`new
Blob([record.data], ...)`).

Net effect: Chromium and Firefox keep the no-copy path; engines that
refuse blobs degrade to the pre-#7175 behaviour instead of silently
losing files. On such an engine a very large file can still exhaust
renderer memory — the fallback warns about exactly that. Fixing that
properly means chunked storage, which is out of scope here.

## Verification

Reproduced and confirmed the cause by A/B on a branch that predates
#7175: as-is 8/8 pass on WebKit, and applying only #7175's `data:
stirlingFile` line reproduces the exact CI failure set.

| Check | Result |
|---|---|
| `stubbed-webkit`: the 8 nightly failures +
`classification-heuristic-upload` | 9 passed |
| `stubbed-webkit`: `files-page`, `page-editor-rotation`,
`encrypted-pdf-unlock` | 32 passed, 1 skipped |
| `stubbed` (chromium): the same specs + `files-page` | 35 passed, 1
skipped |
| Frontend unit suite | 210 files, 1797 passed |
| `typecheck:core`, `typecheck:proprietary`, eslint, prettier | clean |

New unit coverage in `fileStorage.blobFallback.test.ts` pins the
contract over `fake-indexeddb` with `add` instrumented to count blob vs
copy attempts: blob path when accepted, blob-then-copy when refused (and
readable back), one attempt only for later files, and quota not retried.

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Testing (if applicable)

- [x] Frontend typecheck (core + proprietary), eslint, prettier, the
unit suite, and the affected Playwright specs on chromium and webkit all
pass

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2026-08-07 14:36:46 +01:00
dependabot[bot] 1867c8f285 build(deps): bump js-yaml from 4.2.0 to 4.3.1 in /frontend (#7322)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.2.0 to 4.3.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/nodeca/js-yaml/blob/4.3.1/CHANGELOG.md">js-yaml's
changelog</a>.</em></p>
<blockquote>
<h2>4.3.1 - 2026-07-31</h2>
<h3>Security</h3>
<ul>
<li>[backport] Remove quadratic complexity from <code>!!omap</code>
duplicate key detection.</li>
</ul>
<h2>4.3.0 - 2026-06-27</h2>
<h3>Added</h3>
<ul>
<li>[backport] Added <code>maxTotalMergeKeys</code> (10000) loader
option to limit the total number of
keys processed by YAML merge (<code>&lt;&lt;</code>) across one
<code>load()</code> / <code>loadAll()</code> call.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Restore umd builds back to es5.</li>
</ul>
<h3>Removed</h3>
<ul>
<li>[backport] <code>maxMergeSeqLength</code> replaced with
<code>maxTotalMergeKeys</code> for limiting YAML merge
processing.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nodeca/js-yaml/commit/86e91b815b8794c3c73a179c1770871e37ec2df8"><code>86e91b8</code></a>
4.3.1 released</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/c3cc4b0bb9ddb9af2dd9b61e0d56f5ce7983cd4a"><code>c3cc4b0</code></a>
Backport quadratic complexity fix for !!omap</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/33d05b5d29a8c21360f620f7e1c1706e24522eda"><code>33d05b5</code></a>
4.3.0 released</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/663bfab6db2b4a146a9366fd685f069345be4ddb"><code>663bfab</code></a>
Drop demo publish, to not override new v5 one.</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/1cb8c7b94bf75e15116869c1c0482dcb22785986"><code>1cb8c7b</code></a>
Add v4-legacy tag for publish</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/02f27afad532763263cd2b6be35c24ee8e1f6157"><code>02f27af</code></a>
Restore umd builds back to es5</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/8be84edaf15e7c394fa3b813179d1bcc280e87fb"><code>8be84ed</code></a>
Fix es5 compatibility</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/59423c6f8cdc78742ac00e25a4dd39ef16b702e4"><code>59423c6</code></a>
Replace <code>maxMergeSeqLength</code> option with
<code>maxTotalMergeKeys</code> (more robust). Ba...</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/6842ef6a02df01ca7282ea01dc3c70787710c05d"><code>6842ef6</code></a>
doc polish</li>
<li>See full diff in <a
href="https://github.com/nodeca/js-yaml/compare/4.2.0...4.3.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=js-yaml&package-manager=npm_and_yarn&previous-version=4.2.0&new-version=4.3.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/Stirling-Tools/Stirling-PDF/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-07 14:01:11 +01:00
Matheus SaitoandAnthony Stirling fa11034a99 Added Measurement Scale Support for Architectural Drawings (#6121) (#6215)
Fix #6121 
# Description of Changes

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes (#6121 )
-->
This PR expands the viewer ruler/measurement tool with real-world scale
support. Users can now apply preset scales, define custom scales,
calibrate a scale by drawing a reference measurement and entering its
known real-world distance, and view measurements with scaled real-world
values.

It also refactors PDF `/Measure` and `/VP` scale extraction out of
`EmbedPdfViewer` into a dedicated utility, centralizes ruler state
management in a dedicated hook, persists ruler measurements and selected
scales per file during the browser session, remembers the last
calibration unit locally, and updates the ruler overlay so measurements
remain aligned with the PDF page during rotation and scrolling.

**New Files**

- `RulerMeasurementLayer.tsx` - Renders ruler measurements in the SVG
overlay, including lines, points, labels, page/scaled values, delete
controls, live previews, clear controls, and label visibility modes.
    
- `RulerScaleSettingsButton.tsx` - Adds the scale settings
button/popover to the viewer toolbar.
    
- `ScaleCalibrationDialog.tsx` - Provides the calibration modal where
users enter a known real-world distance to calculate the scale
automatically.
    
- `ScaleSettingsPanel.tsx` - Provides preset scales, custom scale input,
calibration entry point, active scale display, and reset controls.
    
- `useMeasurementManager.ts` - Centralizes ruler state, custom scale
state, calibration flow, per-file measurements, session persistence, and
loading of PDF-derived scale data.
    
- `measurementPreferences.ts` - Persists the last calibration unit in
`localStorage`.
    
- `measurementTypes.ts` - Defines shared measurement, point, scale, page
scale, and viewport scale types.
    
- `measurementUtils.ts` - Provides unit conversion, scale calculation,
validation, formatting, calibration helpers, and session storage
helpers.
    
- `measurementUtils.test.ts` - Adds unit tests for scale calculations,
unit conversion, preset parsing, ratio derivation, and calibration.
    
- `pdfMeasurementExtraction.ts` - Moves PDF `/Measure` and `/VP` scale
extraction into a dedicated utility.
    

**Changed Files**

- `EmbedPdfViewer.tsx` - Removes inline PDF scale extraction and
delegates ruler/measurement state to `useMeasurementManager`; integrates
the ruler overlay, custom scale support, restored measurements, and
calibration dialog.
    
- `LocalEmbedPDF.tsx` - Adds page-level metadata used by the ruler
overlay, including page width, height, and native page rotation.
    
- `RotateAPIBridge.tsx` - Adds immediate rotation update propagation so
ruler measurements can update their page-anchored positions during
rotation changes.
    
- `RulerOverlay.tsx` - Refactors the ruler overlay to use shared
measurement types/utilities, support custom scales, calibration
measurements, restored measurements, measurement change listeners,
rotation-aware positioning, and scroll compensation, also holding Alt
key will activate pass-through behavior so labels do not block ruler
interactions.
    
- `useViewerWorkbenchBarButtons.tsx` - Adds the ruler scale settings
action and coordinates ruler, pan mode, and calibration behavior.
    
- `ViewerContext.tsx` - Adds immediate rotation notification support
used by ruler measurements while viewer rotation changes are applied.
    
- `en-GB/translation.toml` and `en-US/translation.toml` - Add UI text
for scale settings, calibration actions, ruler measurement values, and
ruler label controls.


---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [x] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [x] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

Current scale panel : 

<img width="1316" height="515" alt="Captura de tela de 2026-05-31
21-57-53"
src="https://github.com/user-attachments/assets/df0ffb7d-4546-450c-8380-409658852a87"
/>

Current calibration input : 

<img width="1021" height="522" alt="Captura de tela de 2026-05-31
21-59-52"
src="https://github.com/user-attachments/assets/e17c14e7-fec7-42e9-af48-33ef825acb6c"
/>

Example of usage : 

<img width="1316" height="760" alt="Captura de tela de 2026-05-31
22-31-01"
src="https://github.com/user-attachments/assets/fcd3578e-1eaa-42d3-b30b-3fc87c796f90"
/>


### Testing (if applicable)

- [X] I have run `task check` to verify linters, typechecks, and tests
pass
- [X] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2026-08-07 09:53:33 +00:00
kastenherriandAnthony Stirling 84b0b69fe7 Frontend: de-DE: fix inconsistent translation (#6536)
# Description of Changes
Change description text for hotkey settings in the german locale to
"Kürzel ändern" to match the change button.

before:
<img width="731" height="246" alt="stirling-inconsistency-shortcut"
src="https://github.com/user-attachments/assets/a0e4bcb9-d2b6-4759-a7cd-75632176eebd"
/>
 
after:
<img width="776" height="254" alt="hotkey-inconsistency-fix"
src="https://github.com/user-attachments/assets/e0da4d26-f923-4e15-922f-e0e5e21f062f"
/>

Closes #6535 

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [x] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2026-08-07 09:29:13 +00:00
James Brunton 18516b88ff Fix hidden circular dependency in watched folders code (#7308)
# Description of Changes
The restructuring of the frontend PR (#7062) has highlighted a couple of
issues with the source which are currently hidden due to the structure
of the code. This PR fixes the issues in Watched Folders:
- There's a circular dependency in TS code
- The `.gitignore` file excludes the watched folders dir by accident
2026-08-07 09:00:18 +00:00
ConnorYohandReece Browne 75be292176 feat(editor): move app config onto TanStack Query (#7283)
# Description of Changes

> Stacked on #7264 — review that first. This diff is against its branch.

## The problem

`AppConfigContext` hand-rolled a query client: a `fetchCountRef` dedupe
guard, an exponential-backoff retry loop with its own `sleep()`, a
`hasResolvedConfig` flag, and manual 401/5xx branching. All to fetch one
endpoint that 80 files read.

## End state

Same provider, same public contract, React Query underneath. **250 lines
to 142**, and no consumer file changes.

| | Before | After |
|---|---|---|
| Dedupe | `fetchCountRef` guard | query key |
| Retry | `for` loop + `sleep()` + backoff maths | `retry` +
`retryDelay` |
| 401 | caught in the component, sets default config | `fetchAppConfig`
returns the default — the retry predicate and error state only see real
failures |
| Auth pages | early return inside the fetch | `enabled` |
| Resolved-yet tracking | `hasResolvedConfig` state | derived from the
query |

`fetchAppConfig` moves to `core/api/config.ts` with the simulation hook
and request options, so the context no longer knows how config is
fetched.

**Behaviour change:** config survives a provider remount instead of
refetching. That matters on desktop, where a connection-mode switch
remounts the tree — and #7264's cache reset already clears it on exactly
that transition.

## Testing

The existing 12-case contract test passes unchanged apart from the query
wrapper. It caught a real mistake: `failureCount` is 0-based in v5, so
`<= maxRetries` gave one attempt too many.

Four cases added — cached remount, `maxRetries` honoured, 4xx not
retried, `autoFetch` off.

`task frontend:check` green: 1672 tests across 191 files, typecheck on
all five flavours, eslint, dpdm, prettier.

## Coming next

| PR | Scope |
|---|---|
| 3 | `useEndpointConfig` — core (251 lines) plus a 482-line desktop
override with its own dependency polling. Split out of this PR;
different risk profile, and it deserves its own review. |
| 4 | `useAdminSettings` (20 consumers) and the config sections |
| 5 | Polling loops → `refetchInterval` |
| 6 | Finish the Processor, collapse to one client |
| 7 | Tool execution — mutation state only |

---------

Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
2026-08-07 08:53:13 +00:00
brios fd1c955648 refactor(ui): redesign VersionTimeline UI (#7162)
# Description of Changes

I felt the old VersionTimeline was a bit too crowded/not very "good"
looking so i had a crack at redesigning it. Mainly aimed for:

- less info
- less crowding
- more spacing

### New


<img width="884" height="1172" alt="image"
src="https://github.com/user-attachments/assets/070eab35-80b8-408d-9917-b111c433ae4f"
/>


### Old

<img width="882" height="770" alt="image"
src="https://github.com/user-attachments/assets/a074ba2e-79e3-4a8d-9491-ad3a8c432b98"
/>


<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [X] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [X] I have run `task check` to verify linters, typechecks, and tests
pass
- [X] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-07 08:52:13 +00:00
Ludy fa2eb67124 deps(frontend): align dependency scopes and remove redundant ESLint packages (#6991)
# Description of Changes

This change reorganizes frontend dependencies by moving development-only
packages into `devDependencies`, removing obsolete packages, and
updating several development tooling dependencies to newer versions.

### What was changed

- Moved runtime-independent packages to `devDependencies`:
  - `@iconify/react`
  - `globals`
- Removed unused TypeScript ESLint packages:
  - `@typescript-eslint/eslint-plugin`
  - `@typescript-eslint/parser`
- Updated development dependencies:
  - `@iconify-json/material-symbols` → `1.2.83`
  - `@iconify/utils` → `3.1.4`
  - `globals` → `17.7.0`

These changes reduce redundant dependency declarations and ensure
packages are classified according to their actual usage. The main
challenge was distinguishing direct dependencies from packages already
provided transitively by frontend tooling.


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-06 14:56:12 +00:00
Ludy 86d4a34476 deps: Upgrade posthog-js to 1.405.2 (#7115)
# Description of Changes

- Updated the frontend `posthog-js` dependency from `^1.268.0` to
`^1.405.2`.
- Refreshed `frontend/package-lock.json` and updated related PostHog
transitive dependencies.
- Removed obsolete OpenTelemetry and protobuf-related transitive
packages no longer required by the newer PostHog version.
- The existing PostHog APIs used by Stirling-PDF remain compatible.

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-06 13:54:44 +00:00
ConnorYoh 74c53001cf fix(saas): give auth-bootstrap data fetching a single owner (#7194)
## The problem

Three pieces of user data (pro status, avatar metadata, profile picture)
were being fetched from four different places: `initializeAuth` on
mount, the `SIGNED_IN` handler, the `TOKEN_REFRESHED` handler, and the
post-upgrade path.

On a fresh login the first two both see a session, so everything got
fetched twice. It didn't stop after login either — Supabase re-fires
`SIGNED_IN` on token refresh and tab-visibility wakeups, so a refresh
that emitted both events cost around 7 Supabase reads.

## The fix

All four call sites now go through one `loadUserData(session)` that is
idempotent per identity.

The guard key is `user.id` + `is_anonymous`:

- not the access token, which changes on every refresh and would defeat
the guard entirely
- the anonymous flag matters because a guest to authenticated upgrade
keeps the same user id, and that is the one case where the data
genuinely does need reloading

**Per login: 6 fetches to 3. A repeat `SIGNED_IN` or `TOKEN_REFRESHED`
fetches nothing.** The tests count real calls rather than asserting on
shape.

## Two behaviour changes worth naming

- `initializeAuth` now awaits the full load, so the initial spinner also
waits on the profile-picture URL. Net login is still faster, since an
entire duplicate pass is gone.
- A tab-wake `SIGNED_IN` no longer revalidates entitlements. That
revalidation was accidental rather than designed — `refreshProStatus()`
is the intended path, and post-checkout is already handled by
`CheckoutContext`.

## Scope

Supabase-origin traffic only. This does not touch the ~20 authenticated
requests hitting `SupabaseAuthenticationFilter`, because those go to the
Stirling backend rather than the hosted Supabase project. That is a
separate problem and is unmeasured, so it needs measuring before
anything is optimised. Remaining items (a double `/api/v1/team/my`
fetch, an effect keyed on `[user]` identity in `FolderContext`, the
`portalAccess` spinner flash, and caching the auth filter's per-request
Postgres round-trips) are tracked separately.

## Verification

```
npx tsc --noEmit --project editor/src/saas/tsconfig.json   # exit 0
npx eslint --max-warnings=0 editor/src/saas/auth            # exit 0
npx prettier --check editor/src/saas/auth/                  # clean
npx vitest run --project saas                               # 75 passed (20 files)
```
2026-08-06 13:05:24 +00:00
dependabot[bot] 8476d3cdec build(deps-dev): bump eslint from 10.1.0 to 10.8.0 in /frontend in the eslint group across 1 directory (#7274)
Bumps the eslint group with 1 update in the /frontend directory:
[eslint](https://github.com/eslint/eslint).

Updates `eslint` from 10.1.0 to 10.8.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/eslint/releases">eslint's
releases</a>.</em></p>
<blockquote>
<h2>v10.8.0</h2>
<h2>Features</h2>
<ul>
<li><a
href="https://github.com/eslint/eslint/commit/2fee9bb7416116cbed4d8c8100b1ae713b6356a1"><code>2fee9bb</code></a>
feat: export <code>ConfigObject</code> from <code>eslint/config</code>
(<a
href="https://redirect.github.com/eslint/eslint/issues/21082">#21082</a>)
(sethamus)</li>
</ul>
<h2>Bug Fixes</h2>
<ul>
<li><a
href="https://github.com/eslint/eslint/commit/6b8d2f7589b8a7c8b91b8ca2a2ef6d46178760d8"><code>6b8d2f7</code></a>
fix: escape reserved characters in rule id in <code>html</code>
formatter (<a
href="https://redirect.github.com/eslint/eslint/issues/21129">#21129</a>)
(Francesco Trotta)</li>
<li><a
href="https://github.com/eslint/eslint/commit/90910715011211a20d011d807d398a7005127f35"><code>9091071</code></a>
fix: prevent <code>no-unreachable-loop</code> crash when all loop types
are ignored (<a
href="https://redirect.github.com/eslint/eslint/issues/21116">#21116</a>)
(Pixel)</li>
<li><a
href="https://github.com/eslint/eslint/commit/e23fafe8d4b15355adef6cdebef414c3a2019454"><code>e23fafe</code></a>
fix: prefer-object-spread add semicolon when adding parenthesis (<a
href="https://redirect.github.com/eslint/eslint/issues/21081">#21081</a>)
(synthex-byte)</li>
<li><a
href="https://github.com/eslint/eslint/commit/20b5ad052360a443786a202e94624a3f81846511"><code>20b5ad0</code></a>
fix: quadratic-time regex in <code>prefer-template</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21096">#21096</a>)
(Milos Djermanovic)</li>
<li><a
href="https://github.com/eslint/eslint/commit/8b6f6c0b33411f34485512456d94f221daf7321f"><code>8b6f6c0</code></a>
fix: apply ignore configs to computed methods in class-methods-use-this
(<a
href="https://redirect.github.com/eslint/eslint/issues/21094">#21094</a>)
(Pixel)</li>
<li><a
href="https://github.com/eslint/eslint/commit/b2c608c014a396800a24a89343265d0616bee2d8"><code>b2c608c</code></a>
fix: NewExpression with parenthesized callee in
<code>preserve-caught-error</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21083">#21083</a>)
(Francesco Trotta)</li>
</ul>
<h2>Documentation</h2>
<ul>
<li><a
href="https://github.com/eslint/eslint/commit/6ddf8587e5cfeeb7328332601bb76d98b8a198ea"><code>6ddf858</code></a>
docs: fix broken Specify Parser Options anchor link (<a
href="https://redirect.github.com/eslint/eslint/issues/21106">#21106</a>)
(Minsu)</li>
<li><a
href="https://github.com/eslint/eslint/commit/784dfbe98f0222426fd200153a5ce2e5624151f0"><code>784dfbe</code></a>
docs: Clarify <code>no-eq-null</code> description (<a
href="https://redirect.github.com/eslint/eslint/issues/21120">#21120</a>)
(Park Harin)</li>
<li><a
href="https://github.com/eslint/eslint/commit/7ec733a3ba5acb053a73ac656030a3879aa48fda"><code>7ec733a</code></a>
docs: Fix typos and grammar in glossary (<a
href="https://redirect.github.com/eslint/eslint/issues/21095">#21095</a>)
(Marry (Subin Yang))</li>
<li><a
href="https://github.com/eslint/eslint/commit/92bb13f13065db72d62454b9830d3ae52db15c76"><code>92bb13f</code></a>
docs: replace quake link (<a
href="https://redirect.github.com/eslint/eslint/issues/21108">#21108</a>)
(Jung Hyeon Jun)</li>
<li><a
href="https://github.com/eslint/eslint/commit/68eb4a57572409dbdcfeb3bc5c92ddbba46bc770"><code>68eb4a5</code></a>
docs: fix broken Specify Globals anchor links in rule pages (<a
href="https://redirect.github.com/eslint/eslint/issues/21103">#21103</a>)
(Minsu)</li>
<li><a
href="https://github.com/eslint/eslint/commit/d28f697e0d32d7446c825fd89c362db028450134"><code>d28f697</code></a>
docs: replace Code Climate CLI links with Qlty CLI links (<a
href="https://redirect.github.com/eslint/eslint/issues/21099">#21099</a>)
(Jung Hyeon Jun)</li>
<li><a
href="https://github.com/eslint/eslint/commit/eccc68d42564e46bc9020d19ec52d2988f3b7bfa"><code>eccc68d</code></a>
docs: correct --suppressions-location option description (<a
href="https://redirect.github.com/eslint/eslint/issues/21093">#21093</a>)
(Ga eun Lee)</li>
<li><a
href="https://github.com/eslint/eslint/commit/c5963f74bfa82a5b7ccc0607dcdcc695b8c97a31"><code>c5963f7</code></a>
docs: Update README (GitHub Actions Bot)</li>
</ul>
<h2>Chores</h2>
<ul>
<li><a
href="https://github.com/eslint/eslint/commit/4fbf46d140120ae838db08cbe49544c985956490"><code>4fbf46d</code></a>
test: pin <code>webpack</code> version to 5.108.4 (<a
href="https://redirect.github.com/eslint/eslint/issues/21137">#21137</a>)
(Francesco Trotta)</li>
<li><a
href="https://github.com/eslint/eslint/commit/2d063e224e9bb0ccb0a28c120f7e380a8d62f320"><code>2d063e2</code></a>
chore: update HTTP URLs to HTTPS in JSDoc and comments (<a
href="https://redirect.github.com/eslint/eslint/issues/21101">#21101</a>)
(Bo Hyun Kim)</li>
<li><a
href="https://github.com/eslint/eslint/commit/eccbe7bc9257a6c99880468e452c8dfafbf47f74"><code>eccbe7b</code></a>
test: add error locations to <code>no-class-assign</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21123">#21123</a>)
(devoil)</li>
<li><a
href="https://github.com/eslint/eslint/commit/e7d1e4373bf626f8da76d62ce024c28928bc99bc"><code>e7d1e43</code></a>
ci: bump actions/setup-go from 6 to 7 (<a
href="https://redirect.github.com/eslint/eslint/issues/21118">#21118</a>)
(dependabot[bot])</li>
<li><a
href="https://github.com/eslint/eslint/commit/e9d66d0cde1a7752c29dee53ab7b62632835a87a"><code>e9d66d0</code></a>
ci: bump actions/setup-node from 6 to 7 (<a
href="https://redirect.github.com/eslint/eslint/issues/21119">#21119</a>)
(dependabot[bot])</li>
<li><a
href="https://github.com/eslint/eslint/commit/ee225b60c26f0cc5f4d71641888a5bd2ec5626d6"><code>ee225b6</code></a>
test: Add error location details to <code>no-eq-null</code> rule (<a
href="https://redirect.github.com/eslint/eslint/issues/21117">#21117</a>)
(Park Harin)</li>
<li><a
href="https://github.com/eslint/eslint/commit/044a627fa3e28ee1410d515acc5378eb4b49f8ba"><code>044a627</code></a>
chore: update minimatch to ^10.2.5 (<a
href="https://redirect.github.com/eslint/eslint/issues/21107">#21107</a>)
(김채영)</li>
<li><a
href="https://github.com/eslint/eslint/commit/fb09aa8ff09730d3ccf68859e065f99666b52466"><code>fb09aa8</code></a>
chore: update ecosystem plugins (<a
href="https://redirect.github.com/eslint/eslint/issues/21115">#21115</a>)
(ESLint Bot)</li>
<li><a
href="https://github.com/eslint/eslint/commit/5abd878740fe417fd8a910cac3741f2a0317b365"><code>5abd878</code></a>
test: add error locations to <code>no-proto</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21114">#21114</a>)
(Gihyeon Jeong / 정기현)</li>
<li><a
href="https://github.com/eslint/eslint/commit/9715887ec94a5ff936447d7b680d039fbe2f0541"><code>9715887</code></a>
test: Add error location details to <code>no-div-regex</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21110">#21110</a>)
(Park Harin)</li>
<li><a
href="https://github.com/eslint/eslint/commit/a746ec6ea4a2249b1eb3f512264da5f4d5f7c886"><code>a746ec6</code></a>
test: add error locations to <code>no-new-wrappers</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21109">#21109</a>)
(Gihyeon Jeong / 정기현)</li>
<li><a
href="https://github.com/eslint/eslint/commit/8dde64570e240f3ef8af873d59a752db6d8519aa"><code>8dde645</code></a>
test: add error locations to <code>no-ex-assign</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21102">#21102</a>)
(devoil)</li>
<li><a
href="https://github.com/eslint/eslint/commit/13ab0ec447650c079d8a5e5d67222f79e69c741e"><code>13ab0ec</code></a>
test: add error locations to <code>no-label-var</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21098">#21098</a>)
(Gihyeon Jeong / 정기현)</li>
<li><a
href="https://github.com/eslint/eslint/commit/a99906ffb8342dde03336b5c6372b5658f21d5f2"><code>a99906f</code></a>
test: Add error location details to <code>no-delete-var</code> rule (<a
href="https://redirect.github.com/eslint/eslint/issues/21105">#21105</a>)
(Park Harin)</li>
<li><a
href="https://github.com/eslint/eslint/commit/c47e8dc9bbfba797430db45ae08cb6f7392cfc9d"><code>c47e8dc</code></a>
chore: add missing backticks to <code>languages/js/index.js</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21104">#21104</a>)
(beeen)</li>
<li><a
href="https://github.com/eslint/eslint/commit/0174428dd7543d118cf67a823b98dd97032fe68c"><code>0174428</code></a>
chore: add missing backticks to <code>translate-cli-options.js</code>
(<a
href="https://redirect.github.com/eslint/eslint/issues/21097">#21097</a>)
(dongkyu lee)</li>
<li><a
href="https://github.com/eslint/eslint/commit/3d36589a4917326500f0707bb41745160f387d00"><code>3d36589</code></a>
chore: add missing backticks to <code>serialization.js</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21091">#21091</a>)
(이규환)</li>
<li><a
href="https://github.com/eslint/eslint/commit/dcc9312c1081931de0fe1b555fbb6aa82fe696b9"><code>dcc9312</code></a>
test: add error locations to <code>eqeqeq</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21090">#21090</a>)
(Ga eun Lee)</li>
<li><a
href="https://github.com/eslint/eslint/commit/2710b182472cd1a95e4aff6186cb2c4fbadb4ee0"><code>2710b18</code></a>
ci: Add explicit permissions to rebuild-docs-sites workflow (<a
href="https://redirect.github.com/eslint/eslint/issues/21089">#21089</a>)
(Marry (Subin Yang))</li>
<li><a
href="https://github.com/eslint/eslint/commit/5d2f8663ee60701e9036b0b0933a12efd9d93269"><code>5d2f866</code></a>
chore: update dependency prettier to v3.9.5 (<a
href="https://redirect.github.com/eslint/eslint/issues/21086">#21086</a>)
(renovate[bot])</li>
<li><a
href="https://github.com/eslint/eslint/commit/d584e31098f262563b97dc5d5f23a63a187879a0"><code>d584e31</code></a>
chore: fix failing ecosystem test for <code>eslint-plugin-unicorn</code>
(<a
href="https://redirect.github.com/eslint/eslint/issues/21084">#21084</a>)
(Francesco Trotta)</li>
<li><a
href="https://github.com/eslint/eslint/commit/bf3eda049bd690f1e9a5a0c4520a6329b3e4ec85"><code>bf3eda0</code></a>
chore: update ecosystem plugins (<a
href="https://redirect.github.com/eslint/eslint/issues/21079">#21079</a>)
(ESLint Bot)</li>
</ul>
<h2>v10.7.0</h2>
<h2>Features</h2>
<ul>
<li><a
href="https://github.com/eslint/eslint/commit/cf2a9bf2d982642f760370c15f1196f4658f4e27"><code>cf2a9bf</code></a>
feat: add errorClassNames option to preserve-caught-error rule (<a
href="https://redirect.github.com/eslint/eslint/issues/21032">#21032</a>)
(sethamus)</li>
<li><a
href="https://github.com/eslint/eslint/commit/f8b873aae53610b80b5c1005606716e05ed3b91f"><code>f8b873a</code></a>
feat: max-nested-callbacks option for constructor callbacks (<a
href="https://redirect.github.com/eslint/eslint/issues/21063">#21063</a>)
(fnx)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/eslint/eslint/commit/749dfed106f44d77bf3af2402ebfae20cdbf59ee"><code>749dfed</code></a>
10.8.0</li>
<li><a
href="https://github.com/eslint/eslint/commit/4bd0d75b22ffd44809a92659f113c972c5be0770"><code>4bd0d75</code></a>
Build: changelog update for 10.8.0</li>
<li><a
href="https://github.com/eslint/eslint/commit/4fbf46d140120ae838db08cbe49544c985956490"><code>4fbf46d</code></a>
test: pin <code>webpack</code> version to 5.108.4 (<a
href="https://redirect.github.com/eslint/eslint/issues/21137">#21137</a>)</li>
<li><a
href="https://github.com/eslint/eslint/commit/6ddf8587e5cfeeb7328332601bb76d98b8a198ea"><code>6ddf858</code></a>
docs: fix broken Specify Parser Options anchor link (<a
href="https://redirect.github.com/eslint/eslint/issues/21106">#21106</a>)</li>
<li><a
href="https://github.com/eslint/eslint/commit/784dfbe98f0222426fd200153a5ce2e5624151f0"><code>784dfbe</code></a>
docs: Clarify <code>no-eq-null</code> description (<a
href="https://redirect.github.com/eslint/eslint/issues/21120">#21120</a>)</li>
<li><a
href="https://github.com/eslint/eslint/commit/6b8d2f7589b8a7c8b91b8ca2a2ef6d46178760d8"><code>6b8d2f7</code></a>
fix: escape reserved characters in rule id in <code>html</code>
formatter (<a
href="https://redirect.github.com/eslint/eslint/issues/21129">#21129</a>)</li>
<li><a
href="https://github.com/eslint/eslint/commit/2d063e224e9bb0ccb0a28c120f7e380a8d62f320"><code>2d063e2</code></a>
chore: update HTTP URLs to HTTPS in JSDoc and comments (<a
href="https://redirect.github.com/eslint/eslint/issues/21101">#21101</a>)</li>
<li><a
href="https://github.com/eslint/eslint/commit/eccbe7bc9257a6c99880468e452c8dfafbf47f74"><code>eccbe7b</code></a>
test: add error locations to <code>no-class-assign</code> (<a
href="https://redirect.github.com/eslint/eslint/issues/21123">#21123</a>)</li>
<li><a
href="https://github.com/eslint/eslint/commit/2fee9bb7416116cbed4d8c8100b1ae713b6356a1"><code>2fee9bb</code></a>
feat: export <code>ConfigObject</code> from <code>eslint/config</code>
(<a
href="https://redirect.github.com/eslint/eslint/issues/21082">#21082</a>)</li>
<li><a
href="https://github.com/eslint/eslint/commit/e7d1e4373bf626f8da76d62ce024c28928bc99bc"><code>e7d1e43</code></a>
ci: bump actions/setup-go from 6 to 7 (<a
href="https://redirect.github.com/eslint/eslint/issues/21118">#21118</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/eslint/eslint/compare/v10.1.0...v10.8.0">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-06 12:20:27 +00:00
posthog-eu[bot] 5c319f13cb Fix pt-BR download label mislabeled as "Baixar (JSON)" (#7043)
# Description of Changes

- **What:** Corrected the pt-BR (Brazilian Portuguese) `download`
translation from `"Baixar (JSON)"` to `"Baixar"` in
`frontend/editor/public/locales/pt-BR/translation.toml`, in both the
root table (line 32) and the `[fileManager]` section (line 3577).
- **Why:** The generic `download` key flows through
`useFileActionTerminology` (`download: t("download", "Download")`) into
the shared download button rendered on tool-result screens (e.g.
`ReviewToolStep`). Because the string was `"Baixar (JSON)"`, every
tool's Download button showed "Baixar (JSON)" for pt-BR users — implying
a JSON export regardless of the actual output format. This mislabeling
was locale-wide (all pt-BR users, all tool downloads). Session
autocapture confirmed the confusion: a pt-BR user on `/convert`
repeatedly clicked a button whose text was exactly "Baixar (JSON)", then
abandoned the flow. Nothing crashed — it's a confusing label, not a
functional break.
- **Scope / verification:** en-US uses plain `"Download"` for this key
and pt-PT already uses `"Transferir"`; no other locale carried the
`"(JSON)"` suffix on the download key, so the defect was isolated to
pt-BR. Only translation values changed — no keys added/removed, so
translation counts are unaffected.

Note: I scoped this to the mislabel — the exact symptom users observed.
The report also mentions the download being a silent anchor-click with
no success toast; that's a separate, broader UX enhancement in
`ReviewToolStep`/`WorkbenchBar`/`downloadService`, so it's intentionally
left out of this focused translation fix.

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Translations (if applicable)

- [x] Only a value correction in `pt-BR`; no translation tags added or
removed.

---
*Created with [PostHog Code](https://posthog.com/code?ref=pr) from [an
inbox
report](posthog-code://inbox/019f655d-bd60-78c2-ba59-98c23243ed57).*

Co-authored-by: posthog-eu[bot] <226701856+posthog-eu[bot]@users.noreply.github.com>
2026-08-06 12:13:30 +00:00
dependabot[bot] ddc0baa41d build(deps-dev): bump ip-address from 10.2.0 to 10.4.0 in /frontend (#7278)
Bumps [ip-address](https://github.com/beaugunderson/ip-address) from
10.2.0 to 10.4.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/beaugunderson/ip-address/releases">ip-address's
releases</a>.</em></p>
<blockquote>
<h2>v10.4.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Add GitHub Actions CI by <a
href="https://github.com/beaugunderson"><code>@​beaugunderson</code></a>
in <a
href="https://redirect.github.com/beaugunderson/ip-address/pull/213">beaugunderson/ip-address#213</a></li>
<li>Keep the package loadable on node 12, and enforce it by <a
href="https://github.com/beaugunderson"><code>@​beaugunderson</code></a>
in <a
href="https://redirect.github.com/beaugunderson/ip-address/pull/216">beaugunderson/ip-address#216</a></li>
<li>Validate the byte arrays Address6 is given by <a
href="https://github.com/beaugunderson"><code>@​beaugunderson</code></a>
in <a
href="https://redirect.github.com/beaugunderson/ip-address/pull/217">beaugunderson/ip-address#217</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/beaugunderson/ip-address/compare/v10.3.1...v10.4.0">https://github.com/beaugunderson/ip-address/compare/v10.3.1...v10.4.0</a></p>
<h2>v10.3.1</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/beaugunderson/ip-address/compare/v10.3.0...v10.3.1">https://github.com/beaugunderson/ip-address/compare/v10.3.0...v10.3.1</a></p>
<h2>v10.3.0</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/beaugunderson/ip-address/compare/v10.2.2...v10.3.0">https://github.com/beaugunderson/ip-address/compare/v10.2.2...v10.3.0</a></p>
<h2>v10.2.2</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/beaugunderson/ip-address/compare/v10.2.1...v10.2.2">https://github.com/beaugunderson/ip-address/compare/v10.2.1...v10.2.2</a></p>
<h2>v10.2.1</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/beaugunderson/ip-address/compare/v10.2.0...v10.2.1">https://github.com/beaugunderson/ip-address/compare/v10.2.0...v10.2.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/fbb8db28f1559842b7191cab7d8ea6408ed82f7b"><code>fbb8db2</code></a>
10.4.0</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/45a2b11ec254a2e5620de66e248adcb33d16e669"><code>45a2b11</code></a>
Validate the byte arrays Address6 is given (<a
href="https://redirect.github.com/beaugunderson/ip-address/issues/217">#217</a>)</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/bac8810b3935cab123316a4bc5ebaa22db140299"><code>bac8810</code></a>
Keep the package loadable on node 12, and enforce it (<a
href="https://redirect.github.com/beaugunderson/ip-address/issues/216">#216</a>)</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/9b3d8488d15e6bfe5f5503867b088ce056723e08"><code>9b3d848</code></a>
Add a security policy and a README section on security posture</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/e84a7b381d02cb97ed114023e44133efae151254"><code>e84a7b3</code></a>
Order the README API reference Address4, Address6, AddressError</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/015160b85ee60b39548219817a5de3c4e828a6d6"><code>015160b</code></a>
Collapse each class in the README API reference</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/34061a897d526b7a063c3605402cd30a8363a035"><code>34061a8</code></a>
Pin checkout and setup-node to commits in the release job</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/c5fae5d9bdfe8ded7f4ca01a3d3ea8d97f8f1277"><code>c5fae5d</code></a>
Pin action-gh-release to a commit and move it to 3.0.2</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/e0ef0484193218b0d28cfbb53795bc44ddb3cc21"><code>e0ef048</code></a>
Replace CircleCI with GitHub Actions</li>
<li><a
href="https://github.com/beaugunderson/ip-address/commit/5e3ceb779aee6ad3f33264e66225e8e7584ab612"><code>5e3ceb7</code></a>
Add GitHub Actions CI across Node 20, 22, 24 and 25 (<a
href="https://redirect.github.com/beaugunderson/ip-address/issues/213">#213</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/beaugunderson/ip-address/compare/v10.2.0...v10.4.0">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for ip-address since your current version.</p>
</details>
<details>
<summary>Install script changes</summary>
<p>This version adds <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ip-address&package-manager=npm_and_yarn&previous-version=10.2.0&new-version=10.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/Stirling-Tools/Stirling-PDF/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-06 12:00:50 +00:00
brios 934ad180cb fix(ui): handle 404 policy error on upload without toast popup (#7254)
# Description of Changes

Fixes policy error pop-ups that sometimes happen upon upload.

Changes:
- Improved the error handling in `runPolicyOnFile` to log detailed debug
information when policy dispatch fails, making it easier to trace issues
such as missing policies or backend errors.
- Updated the `runStoredPolicy` function to pass `{ suppressErrorToast:
true }` to the API client, preventing error toasts from appearing in the
UI when the policy run fails.

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [X] I have run `task check` to verify linters, typechecks, and tests
pass
- [X] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-06 10:16:15 +00:00
briosandAnthony Stirling 9aaf417303 perf(ui): lazy-load MobileScannerPage and optimize bundle splitting (#7122)
# Description of Changes


This pull request improves the frontend's performance and code
organization by optimizing how certain pages are loaded and by updating
the application's bundle splitting strategy.

Changes:
* Updated the `manualChunks` configuration in `vite.config.ts` to more
granularly split vendor dependencies into separate chunks based on their
library or usage, which can improve caching and load performance.
* Updated MobileScanner code to be lazy loaded

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2026-08-06 10:11:26 +00:00
brios cc1c6bc9e3 style(people): Fix convert dropdown single-category formatting and admin table header styling (#7139)
# Description of Changes

The dropdown table with the people looked out-place mainly due to the
blue, i think... this simplifies and make more consistent with the rest
of the "new" UI and not so aggresive with the colour schema.


### New:

<img width="2204" height="852" alt="image"
src="https://github.com/user-attachments/assets/0e329092-a532-445b-a27d-7afbd0a16d4c"
/>


### Old:

<img width="2210" height="838" alt="image"
src="https://github.com/user-attachments/assets/6e251d6f-f22c-4b9e-aebf-96e7fea40144"
/>



<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [X] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [X] I have run `task check` to verify linters, typechecks, and tests
pass
- [X] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-06 10:01:46 +00:00
brios 732a602503 style(scanner-effect): remove padding from ToolButton of Scanner-effect (#7205)
# Description of Changes


### New
<img width="1650" height="612" alt="image"
src="https://github.com/user-attachments/assets/3046ad8e-b7a5-4fb6-b941-04ae7dcda4e4"
/>



### Old
<img width="1756" height="730" alt="image"
src="https://github.com/user-attachments/assets/e722146e-bebb-4744-9e95-4eee11444623"
/>

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [X] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [X] I have run `task check` to verify linters, typechecks, and tests
pass
- [X] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-06 10:00:43 +00:00
brios e5c6ceedc5 fix(ui): resolve double scrollbar issue in Sidebar Categories modal (#7142)
# Description of Changes

Resolves double scrollbar design bug.

### New

<img width="1036" height="990" alt="image"
src="https://github.com/user-attachments/assets/454a521c-7ccf-4ebc-98be-22f13b107abe"
/>


### Old

<img width="1036" height="984" alt="image"
src="https://github.com/user-attachments/assets/c2847698-e625-48da-a5bc-e6b68050a426"
/>


<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-08-06 10:00:25 +00:00
EthanHealy01 789be2d351 Non-blocking classification, pipelined batch enforcement, and selector-based file-state re-renders (#7085)
## Goal

Three related improvements to how policies and file state behave in the
editor: classification no longer blocks the user, policy enforcement
pipelines across a batch upload instead of waiting for the whole drop,
and file-state changes no longer re-render the entire UI.

## 1. Classification never blocks (and never versions)

Classification is metadata-only — it reads a document and records
labels; it never rewrites the file. Previously it ran like an
enforcement policy: it blocked viewing/editing behind the "Enforcing
policy…" overlay, forked a new versioned child (an `automate` entry in
version history), and could run before other policies — letting the user
in, then a later enforcement policy would fork a version and drop their
edits.

Now classification:
- **Never blocks.** A classification run never marks a file `enforcing`
(badge map + viewer overlay both skip it), so the file stays fully
viewable/editable while it runs.
- **No version bump, no history entry.** Its result is stamped onto the
file's existing stub in place (workspace + IndexedDB) — the labels just
appear as tags. It targets the document's *current leaf*, so an edit
made during the async run still gets the tags; a run that completes with
no outputs settles cleanly instead of pinning in-flight.
- **Always runs last** in an enforcement chain (regardless of configured
order, pinned at persist-time too), so every enforcement policy finishes
forking versions before the user is let in.

## 2. Pipeline policy enforcement across a batch upload

Dropping ~50 files enforced policies only *after the whole drop finished
scanning* — every file got the "Enforcing policy" overlay together, then
processing began. Root cause: the chunked `ADD_FILES` dispatches in
`addFiles` were never separated by an event-loop yield, so React batched
them into a single commit and the enforcement effect fired once over the
full list.

**Fix** (`core/contexts/file/fileActions.ts`): after each chunk, `await`
that chunk's IndexedDB writes, then yield a macrotask so React commits
the rows and runs the enforcement dispatch *before* the next chunk
scans. Files start enforcing as their rows land, overlapping with the
rest of the drop. Persistence is streamed per chunk (the policy auto-run
reads bytes from IndexedDB with no in-memory fallback).

**Second fix — bounded dispatch window**
(`proprietary/components/policies/usePolicyAutoRun.ts`): even with
streamed dispatch, the drop still *looked* serial — each dispatch POSTs
the file's bytes, and firing them all at once saturates the browser's
per-origin connection pool, so the status polls and output downloads of
already-running files queued behind the pending uploads; nothing visibly
progressed until the last upload drained. Dispatch is now gated behind a
small concurrency window (4), keeping connections free so early files
run, poll, and complete while later ones are still dispatching. The
first status poll also fires at 500ms (then the normal 2s cadence) so
fresh runs show real progress immediately. The batch test asserts the
window (dispatches overlap but never exceed 4).

## 3. Selector subscriptions for file state (no more whole-UI
re-renders)

`FileContext` published `{state, selectors}` through a plain React
context, so **every** consumer re-rendered on **every** state change —
one file's new version re-rendered the entire workspace.

**Phase 1 — infra** (`file/contexts.ts`, `file/fileHooks.ts`,
`FileContext.tsx`): the state context is replaced by a stable
subscription store (`FileStoreContext`); hooks are rebuilt on
`useSyncExternalStoreWithSelector` (the `use-sync-external-store` shim
react-redux uses — new direct dep, React 19 compatible). Each consumer
now re-renders only when its selected slice changes:
- `useStirlingFileStub(id)` → only that file's record
- `useAllFiles` → file-list changes only (immune to selection/UI churn)
- `useFileSelection`/`useSelectedFiles` → selection + the *selected*
files' records only
- `useFileUI` → its three UI scalars; `useFileContext` → files + pinned
slices
- `useFileState` keeps its whole-state contract for existing broad
consumers

A render-count test (`fileHooks.selector.test.tsx`) locks the bail-out
contract.

**Phase 2 — hot-path rows**: sidebar `FileItem` is memoized (with stable
empty-array props), so one file's change re-renders one row, not the
list. Active Files thumbnails were already memoized.

**Phase 3 — narrow the hottest consumers**: always-mounted whole-state
consumers migrated to slices — `Workbench`, `EmbedPdfViewer`, `Viewer`,
`NonPdfViewer`, `WorkbenchBar`, `ViewerContext`, `ViewerShareButton`,
`ZoomAPIBridge`, `ViewerAnnotationControls`, `ConvertSettings`,
`DismissAllErrorsButton`, `FileEditorThumbnail`,
`usePageEditorDropdownState`, `useSaveShortcut`, plus a new
non-subscribing `useFileSelectors()` for event-time reads
(`ReviewToolStep`, `useViewerReadAloud`, `useExitWarning`). Net effect:
selection/UI churn no longer re-renders the viewer/workbench, and a
version landing touches only components observing the files slice.

Broad readers (`FileSidebar`, `PageEditor`, `FileEditor`, `Redact`,
`FormFill`) deliberately stay on `useFileState` — they read most of the
state anyway.

**Hardening**: store notifications run in a layout effect (subscribers
re-render before paint — no stale frames), and outside production
`useFileSelectors()` wraps its selectors to `console.error` if one is
invoked during render (those reads don't subscribe, so render-time use
would silently go stale — not statically lintable, so it's guarded at
runtime; the full test suite passes under the guard).

## 4. Policy indicators: shared icons, non-blocking run chip, no pulse

- Badges and enforcement overlays now take their glyph from the shared
`policyCategoryIcon` map (the same source the processor's catalogue
uses) — label icon for classification, shield for security — instead of
a hardcoded shield everywhere.
- A non-blocking run (classification) shows a small accent-tinted pill
in the top-right of the Active Files card (category icon + loader) and
the normal spinning badge in the sidebar, via a new `background` badge
flag that nothing gates on. When the run finishes, the tagged files keep
a plain category badge.
- The post-run pulse/glow on sidebar badges is gone (with its `recent`
plumbing): spinner while running, static category icon when done.

## Verification

Full CI gate locally: `og:check`, `typecheck:all` (all variants),
`lint`, `format:check`, `build`, `test` (1366 — incl. the render-count
contract test, the classification-order/import unit tests, and the
61-file batch integration test driving the real dispatch → poll → import
→ chain effects), `storybook:build` — all green.

## Held for follow-up (not in this PR)

- **Reuse one PDFium engine across viewer file switches** (kills the
per-open "Loading PDF Engine" rebuild). Implemented on branch
`viewer/reuse-pdfium-engine`, but review found a confirmed leak
(orphaned PDFium handles when switching files mid-load); needs an
in-flight-load teardown before shipping.
2026-08-05 16:31:24 +00:00