Commit Graph
950 Commits
Author SHA1 Message Date
SnapOtter ed177e7cc1 fix(landing): simplify footer copyright to product name only
Drop verbose company registration details (entity name, UEN, country)
from the footer -- legal entity info already lives in the Terms page.
2026-06-08 11:51:49 +08:00
SnapOtter 862ff172ef fix(landing): correct API reference link in footer
Footer linked to /api which has no index page, causing a 404.
Point to /api/rest to match the docs site navigation.
2026-06-08 11:51:05 +08:00
SnapOtterandGitHub 6f276b4ef0 feat(a11y): WCAG 2.2 AA accessibility compliance (#209)
* feat(a11y): add i18n keys for ARIA labels and screen reader text

* fix(security): harden API against pentest findings

- Default TRUST_PROXY=false to prevent XFF rate limit bypass (PT-01)
- Return 400 instead of 500 on malformed JSON input (PT-03)
- Default MAX_PIPELINE_STEPS=20 to prevent DoS (PT-04)
- Validate clientJobId length (max 128) across all routes (PT-06)
- Add security headers to all reply.hijack() streaming responses (PT-07)
- Sanitize usernames in audit log to prevent stored XSS (PT-08)
- Block TRACE method with 405 response (PT-10)
- Add 429 RateLimited response to OpenAPI spec (PT-12)
- Default MAX_SVG_SIZE_MB=50 to limit SVGZ decompression (PT-13)
- Pin Dockerfile base images by digest
- Sanitize OIDC IdP error and sub claim in audit log
- Sync Docker compose/Dockerfile defaults with env.ts

* feat(a11y): convert all hardcoded aria-labels to i18n keys

Replace 49 hardcoded aria-label="..." strings across 25 files with
their corresponding t.a11y.* and t.common.* i18n references. Add
useTranslation import and hook call to 15 components that lacked it.
Zero hardcoded aria-labels remain in the codebase.

* feat(a11y): add aria-labels to icon-only buttons, aria-hidden on decorative icons, sr-only status text

* feat(a11y): add aria-live regions for processing status announcements

* feat(a11y): add skip-nav link, route announcer, main content landmark, and page h1 elements

* feat(a11y): add prefers-reduced-motion support, preserve functional spinners

* feat(a11y): add useFocusTrap hook for modal focus management

* feat(a11y): add focus trapping and dialog roles to all modals

* feat(a11y): add toggle switch roles, form labels, and error association

* fix(a11y): fix contrast failures, touch targets, and add nav landmark to sidebar

* fix(a11y): add role=switch to remaining toggle buttons found in verification sweep
2026-06-07 23:32:41 +08:00
SnapOtter ace41168bc fix(security): harden API against pentest findings
- Default TRUST_PROXY=false to prevent XFF rate limit bypass (PT-01)
- Return 400 instead of 500 on malformed JSON input (PT-03)
- Default MAX_PIPELINE_STEPS=20 to prevent DoS (PT-04)
- Validate clientJobId length (max 128) across all routes (PT-06)
- Add security headers to all reply.hijack() streaming responses (PT-07)
- Sanitize usernames in audit log to prevent stored XSS (PT-08)
- Block TRACE method with 405 response (PT-10)
- Add 429 RateLimited response to OpenAPI spec (PT-12)
- Default MAX_SVG_SIZE_MB=50 to limit SVGZ decompression (PT-13)
- Pin Dockerfile base images by digest
- Sanitize OIDC IdP error and sub claim in audit log
- Sync Docker compose/Dockerfile defaults with env.ts
2026-06-07 21:54:27 +08:00
SnapOtterandGitHub 73b259462a fix: resolve 7 bugs from QA sweep (#208)
- Fix selective metadata stripping (P1): use Sharp's keepExif()/keepIccProfile()
  instead of broken withMetadata({}) that preserved everything
- Fix meme font mapping (P1): add ArchivoBlack and ComicNeue fonts, map
  arial-black and comic-sans to correct TTF files instead of Anton
- Fix meme contentType (P2): detect actual output format from Sharp metadata
  instead of hardcoding image/png
- Fix info/text-overlay/color-palette i18n (P2): wire up existing translation
  keys that were imported but never used
- Fix info and color-palette displayMode (P2): change from before-after to
  no-comparison since neither tool produces a processed image
- Add missing i18n keys across all 21 locales
- Update displayMode test assertions
2026-06-07 18:27:09 +08:00
SnapOtterandGitHub 5a32e29b8c fix(security): security audit and hardening (#207)
* fix(security): harden SVG sanitizer, rate limiting, and analytics defaults

- SVG: add control-char stripping in href values to block whitespace/null-byte
  obfuscated javascript: URIs; block <feImage> with external href (SSRF via
  SVG filter primitives); expand test suite to 32 inline bypass payloads
- Rate limiting: add per-route limits on tool endpoints (60/min) and batch
  (20/min); fix compose files defaulting RATE_LIMIT_PER_MIN to 0 which mapped
  to 50,000 in code; simplify rate limit registration to use env.ts default
- Analytics: default ANALYTICS_ENABLED to false so self-hosters do not
  unknowingly send telemetry
- Docker: add --max-time 5 and -s flags to compose healthcheck curl commands

* fix: remove stale login limit bypass, reduce error log noise, clean up fixtures

- Fix getLoginAttemptLimit() ignoring LOGIN_ATTEMPT_LIMIT when global rate
  limit exceeded 1000/min, which let the global limit override the stricter
  per-route login brute-force protection
- Downgrade rate limit 429 responses from error to warn level in the global
  error handler to avoid log noise and unnecessary Sentry reports
- Log 4xx client errors at warn level instead of error level
- Remove 11 orphaned SVG attack fixture files replaced by inline test payloads
2026-06-07 10:43:52 +08:00
SnapOtter 46bb09f03a fix: resolve CI lint and test failures
- Apply biome formatting fixes to web app components
- Add required S3 credentials to loadEnv test when STORAGE_MODE=s3
- Update bento-grid test tool counts from 52 to 53 for html-to-image
2026-06-06 21:51:43 +08:00
SnapOtter 6b037e3abc feat: add html file upload mode to html-to-image tool 2026-06-06 21:45:39 +08:00
SnapOtter 8512c518b2 chore: use snapotter.com as placeholder URL for html-to-image tool 2026-06-06 21:45:39 +08:00
SnapOtter 5bcc357725 chore: update tool counts and references for html-to-image (53 tools) 2026-06-06 21:45:39 +08:00
SnapOtter a8b79f9da5 docs: add html-to-image tool to API docs, OpenAPI, and LLM docs 2026-06-06 21:45:39 +08:00
SnapOtter f8cfa17bd6 feat: register html-to-image in frontend tool registry 2026-06-06 21:45:39 +08:00
SnapOtter af1220cab1 feat: add frontend store and components for html-to-image tool 2026-06-06 21:45:38 +08:00
SnapOtter 5760d6723f feat: add browser service shutdown to server lifecycle 2026-06-06 21:45:38 +08:00
SnapOtter d9959d6686 feat: implement html-to-image API route with SSRF protection 2026-06-06 21:45:38 +08:00
SnapOtter da5b248582 feat: add browser service singleton for html-to-image captures 2026-06-06 21:45:38 +08:00
SnapOtter 0e850ba5e0 feat: add playwright dependency for html-to-image tool
Install playwright in apps/api for the browser-based screenshot
service that will power the HTML to Image tool.
2026-06-06 21:45:38 +08:00
SnapOtter f64cbdda4e fix: block hex IPv4-mapped IPv6 in SSRF guard
The WHATWG URL parser canonicalizes dotted IPv4-mapped IPv6 literals
(e.g. ::ffff:127.0.0.1) to hex form (::ffff:7f00:1). The SSRF guard
only checked the dotted form, so hex literals bypassed the private-IP
classifier and allowed access to loopback, cloud metadata, and RFC1918
addresses.

Decode hex IPv4-mapped suffixes to dotted IPv4 before the private-range
check.

Reported-by: tonghuaroot
2026-06-06 20:27:48 +08:00
SnapOtter 3b84fab765 feat: add enterprise licensing and S3 storage backend
Add the enterprise package with Ed25519 license key validation and
feature gating. Enterprise code lives in the public repo under a
proprietary license (Cal.com/PostHog model), protected legally, not
by code hiding.

Implement S3-compatible storage backend as the first enterprise
feature. The file-storage module now delegates to either local
filesystem or S3 based on STORAGE_MODE env var. Works with AWS S3,
Cloudflare R2, DigitalOcean Spaces, MinIO, and any S3-compatible
provider. Workspace files remain local (ephemeral processing).

New env vars: STORAGE_MODE, S3_BUCKET, S3_REGION, S3_ENDPOINT,
S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_FORCE_PATH_STYLE,
S3_PREFIX, SNAPOTTER_LICENSE_KEY.

Tested against MinIO: 10 S3 integration tests + 82 existing tests
pass with zero regressions.
2026-06-06 20:17:49 +08:00
SnapOtter 66e503730d fix: resolve 6 production Sentry errors
- Prevent @fastify/static double-registration crash via decorateReply guard
- Fix non-ASCII filename header encoding (X-Output-Filename + RFC 5987 Content-Disposition)
- Add EACCES error handling to all startup mkdir calls with actionable messages
- Add WAL autocheckpoint and journal size limit to prevent unbounded SQLite growth
- Fix Python sidecar EPIPE handling to reject pending requests and trigger restart
- Ensure Docker entrypoint creates all subdirectories before chown
2026-06-06 16:05:59 +08:00
SnapOtter 9f2498f0d2 docs: add legal entity info to landing footer, terms, and privacy pages
SnapOtter is a product of Chocolate Wafers General Trading Pte. Ltd.
(UEN 202527149C), registered in Singapore. Surfaces company identity
in the footer copyright, a "Who We Are" section on the terms page,
and a "Data Controller" section on the privacy page.
2026-06-06 12:06:27 +08:00
SnapOtter 357f39ed7b fix: update landing word cloud with current tool list
Add Meme, Erase Object, Text Overlay, AI Expand, Compose, Split,
Enhance Faces, Replace Color, Beautify, Closeup. Remove Flip
(not a standalone tool) and Open Source (not a tool).
2026-06-06 11:41:10 +08:00
SnapOtter cfe3c1a2b3 fix: refine landing hero layout and spacing
Clean headline break, two-tier subtitle with tool list and lighter
attributes line, more vertical breathing room.
2026-06-06 11:38:48 +08:00
SnapOtter fa897148a4 docs: update hero copy across landing page and docs
Clearer messaging: "50+ image tools. One Docker container." on landing,
"Self-Hosted Image Toolkit" on docs.
2026-06-06 11:22:30 +08:00
SnapOtter fe0cbd32b2 fix: use correct i18n key path for noToolsFound in tool palette 2026-06-06 10:38:34 +08:00
SnapOtter 91c66eb4be fix: resolve all QA report issues from 2026-06-05 sweep
Merges 77 QA issue fixes across routing, editor, i18n, pipeline,
and settings. Includes catch-all 404 page, keyboard shortcuts,
export filename, password validation, selection masking, brush flow,
eraser modes, feather control, pipeline persistence, RTL properties,
license info, and i18n for all 21 locales.
2026-06-06 10:37:36 +08:00
SnapOtter 643df59ca1 fix: add missing i18n keys to en.ts and all locale files
Ensures all 21 locale files have: pageNotFound, licenseLabel,
noStepsHeading, searchToolsPlaceholder, and expanded files section
with 20 keys. Updates passwordTooShort to match backend validation.
2026-06-06 10:37:23 +08:00
SnapOtter d373ac83dc feat: mobile-responsive settings dialog, homepage, nav, and toast
- Settings dialog: full-screen on mobile with horizontal pill nav,
  card-based user/team tables, compact audit log, stacked SettingRow
- HomePage: stacked mobile layout with horizontal quick actions,
  tablet-friendly panel widths (w-64 lg:w-80)
- Extract MobileBottomNav component with safe-area-inset padding
- Add MobileBottomNav to fullscreen grid page
- Larger touch targets on hamburger, sidebar close, bottom nav items
- Toast repositioned to top-center on mobile (avoids bottom nav overlap)
- PWA viewport-fit=cover for notch devices
- Fix useMediaQuery null guard for test environment compatibility
2026-06-05 23:18:55 +08:00
SnapOtter 190d5c84bf fix: resolve remaining QA issues -- editor features, masking, persistence, Playwright tests
Phase 1 quick fixes:
- Add isInputFocused() guard to Cmd+A/D/T/J shortcuts (P1-7)
- Add Go Home button to tool-not-found page (P2-30)
- Fix hardcoded "Import from Library" string in file library modal (P2-28)
- Fix TeamEntry.id type from number to string to match API (P2-6)
- Add eye toggle to confirm password field (P2-10)
- Add Apply/Cancel buttons to Free Transform options bar (P2-14)

Phase 2 state fixes:
- Add sessionStorage persistence to pipeline store (P1-26)
- Fix Free Transform 0 dimensions by falling back to selection bounds (P1-6)

Phase 3 editor features:
- Constrain brush/eraser drawing within active selection bounds (P1-5)
- Add feather radius control to selection options (P2-21)
- Add flow control slider to brush options (P2-22)
- Add brush/block mode selector to eraser options (P2-23)
- Add estimated file size display to export dialog (P2-18)

Phase 4:
- Add Playwright e2e tests for key fixes (404 page, routing, pipeline persistence, export dialog)
2026-06-05 23:14:57 +08:00
SnapOtter 37f8ebcf66 Merge branch 'feat/remove-bg-improvements' 2026-06-05 23:05:33 +08:00
SnapOtter 80957f6e10 feat: improve remove background with edge smoothing, color decontamination, output formats
- Expose birefnet-hr-matting in UI (People/Ultra) and fix model defaults
  (People/Max now uses birefnet-matting for true alpha matting)
- Add output format selector (PNG/WebP/AVIF) with lossless alpha support
- Add edge smoothing post-processing (Off/Light/Medium/Strong) via
  morphological mask refinement to reduce gray halo artifacts
- Add color decontamination to remove background color spill from
  semi-transparent edge pixels
- Thread new settings through full stack: frontend -> API schema ->
  Python sidecar -> Sharp effects pipeline
- Add i18n keys for all 21 locales
- Add unit tests for new option serialization (3 tests)
- Add integration tests for new settings validation (4 tests)
2026-06-05 23:05:25 +08:00
SnapOtter 07e12754ba fix: resolve QA report issues across routing, editor, i18n, and pipeline
- Add /tools/:toolId legacy redirect and catch-all 404 page (P1-12, P1-13)
- Add Shift+O dodge/burn/sponge cycle and Ctrl+Y redo shortcut (P1-3, P1-4)
- Fix Fit on Screen menu action to properly compute fit zoom (P1-8)
- Add filename input to editor export dialog (P1-2)
- Fix password validation mismatch: frontend now requires 8 chars (P1-11)
- Add license info to Settings About section (P1-9)
- Replace hardcoded strings in dropzone, files, pipeline with i18n keys (P1-17 to P1-25)
- Add 20+ missing i18n keys to all 21 locale files
- Translate Japanese editor.shapes and settings.aiFeatures sections (P1-19, P1-20)
- Fix RTL: use logical CSS properties in sidebar, files, app-layout (P2-24 to P2-26)
- Add single-file download button to pipeline results (P1-28)
- Fix compress step settings restoration on pipeline load (P1-27)
- Increase mobile nav touch targets to 44px minimum (P2-29)
2026-06-05 22:31:28 +08:00
SnapOtter 6a8d9dcd8d feat: implement 6 research-backed mobile responsive features
- Bottom sheet for mobile tool settings (replaces top-collapsible panel)
- Pinch-to-zoom and wheel zoom on image viewer via @use-gesture/react
- Replace all vh units with dvh for dynamic viewport height
- Vertical before-after comparison on mobile devices
- Konva multi-touch pinch-to-zoom on editor canvas
- Container queries for adaptive tool settings + touch-friendly CSS
2026-06-05 22:30:43 +08:00
SnapOtterandGitHub 91e90b390e fix: recover SSE connections on mobile tab visibility change (#204)
* fix: extend SSE result retention from 2 to 10 minutes for mobile recovery

* fix: check server health on tab visibility change for mobile recovery

* fix: recover feature install SSE on tab visibility change

* fix: reconnect SSE on tab visibility change in tool processor

* fix: reconnect SSE on tab visibility change in pipeline processor

* test: add visibility recovery tests for connection monitor
2026-06-05 22:28:24 +08:00
SnapOtter 807bd0cf85 fix: reconnect SSE on tab visibility change in pipeline processor 2026-06-05 21:51:34 +08:00
SnapOtter 4d8cc2dcf7 fix: reconnect SSE on tab visibility change in tool processor 2026-06-05 21:49:23 +08:00
SnapOtter 2b92109aee fix: recover feature install SSE on tab visibility change 2026-06-05 21:45:32 +08:00
SnapOtter fbc70272dd fix: check server health on tab visibility change for mobile recovery 2026-06-05 21:45:27 +08:00
SnapOtter 005fe1d982 fix: extend SSE result retention from 2 to 10 minutes for mobile recovery 2026-06-05 21:43:55 +08:00
SnapOtterandGitHub 01421640b5 fix: resolve file library Open File bug, upload reliability, and SSE proxy timeouts (#203)
The Open File button in the Files section did nothing due to a race
condition where the home page reset the file store on mount before files
from handleOpenFile could render. Upload on the files page used fetch
with no timeout, progress, or retry, causing silent failures on mobile
and slow connections. SSE connections for job progress had no keepalive
pings, allowing reverse proxies to kill idle streams.
2026-06-05 19:01:40 +08:00
SnapOtter bec3b1e289 feat: add shape fill/stroke transparency, RGBA color picker, and dash styles
Closes #193. Shapes now support no-fill and no-stroke toggles for drawing
outlines or fill-only shapes. Adds RGBA color picker with opacity control,
stroke dash styles (solid/dashed/dotted), and i18n for all shape labels.
2026-06-05 16:40:57 +08:00
SnapOtter e03c6089af feat: support downloadFn-based model manifests and improve install error messages
Add support for models defined via downloadFn/args (rembg_session,
hf_snapshot) in bundle verification, recovery, and uninstall paths.
Previously only path-based models were tracked, so bundles using
rembg or HF snapshot downloads appeared broken after install.

Also improve pip install error messages with user-friendly hints for
common failures (basicsr build issues, OOM, disk full) and add better
error context for rembg session download failures.
2026-06-04 22:27:44 +08:00
SnapOtterGitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1616ad1a5a chore(deps-dev): bump dev-deps group + fix vitest 3.2.6 mock resolution (#197)
* chore(deps-dev): bump the dev-deps group across 1 directory with 7 updates

Bumps the dev-deps group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.15` | `2.4.16` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `3.2.4` | `3.2.6` |
| [turbo](https://github.com/vercel/turborepo) | `2.9.14` | `2.9.16` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `3.2.4` | `3.2.6` |
| [@types/opentype.js](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/opentype.js) | `1.3.9` | `1.3.10` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `6.4.2` | `6.4.3` |
| [vitepress-plugin-llms](https://github.com/okineadev/vitepress-plugin-llms) | `1.12.2` | `1.13.1` |

Updates `@biomejs/biome` from 2.4.15 to 2.4.16
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.16/packages/@biomejs/biome)

Updates `@vitest/coverage-v8` from 3.2.4 to 3.2.6
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v3.2.6/packages/coverage-v8)

Updates `turbo` from 2.9.14 to 2.9.16
- [Release notes](https://github.com/vercel/turborepo/releases)
- [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md)
- [Commits](https://github.com/vercel/turborepo/compare/v2.9.14...v2.9.16)

Updates `vitest` from 3.2.4 to 3.2.6
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v3.2.6/packages/vitest)

Updates `@types/opentype.js` from 1.3.9 to 1.3.10
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/opentype.js)

Updates `vite` from 6.4.2 to 6.4.3
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.4.3/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.4.3/packages/vite)

Updates `vitepress-plugin-llms` from 1.12.2 to 1.13.1
- [Release notes](https://github.com/okineadev/vitepress-plugin-llms/releases)
- [Commits](https://github.com/okineadev/vitepress-plugin-llms/compare/v1.12.2...v1.13.1)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.4.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 3.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: turbo
  dependency-version: 2.9.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: vitest
  dependency-version: 3.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@types/opentype.js"
  dependency-version: 1.3.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: vite
  dependency-version: 6.4.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: vitepress-plugin-llms
  dependency-version: 1.13.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(test): resolve vitest 3.2.6 mock path breakage for posthog-node and @sentry/node

Add posthog-node and @sentry/node to vitest resolve aliases (matching
the existing pattern for all other api-workspace packages) and switch
the analytics test mocks from fragile relative node_modules paths to
bare specifiers. Vitest 3.2.6 changed how it matches mock paths through
pnpm symlinks after vi.resetModules(), causing 9 analytics test failures.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-04 22:22:40 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ed8cea7dc9 chore(deps): bump the production-deps group across 1 directory with 15 updates (#195)
Bumps the production-deps group with 15 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@neplex/vectorizer](https://github.com/neplextech/vectorizer) | `0.0.5` | `0.1.0` |
| [@scalar/fastify-api-reference](https://github.com/scalar/scalar/tree/HEAD/integrations/fastify) | `1.57.2` | `1.57.5` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `10.53.1` | `10.55.0` |
| [js-yaml](https://github.com/nodeca/js-yaml) | `4.1.1` | `4.2.0` |
| [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.34.3` | `5.35.9` |
| [tsx](https://github.com/privatenumber/tsx) | `4.22.1` | `4.22.4` |
| [zxing-wasm](https://github.com/Sec-ant/zxing-wasm) | `3.0.3` | `3.1.0` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.6` | `19.2.7` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.6` | `19.2.7` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.53.1` | `10.55.0` |
| [posthog-js](https://github.com/PostHog/posthog-js) | `1.374.0` | `1.377.0` |
| [react-colorful](https://github.com/omgovich/react-colorful) | `5.6.1` | `5.7.0` |
| [react-konva](https://github.com/konvajs/react-konva) | `19.2.3` | `19.2.4` |
| [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) | `7.15.1` | `7.16.0` |
| [zustand](https://github.com/pmndrs/zustand) | `5.0.13` | `5.0.14` |



Updates `@neplex/vectorizer` from 0.0.5 to 0.1.0
- [Release notes](https://github.com/neplextech/vectorizer/releases)
- [Commits](https://github.com/neplextech/vectorizer/compare/v0.0.5...v0.1.0)

Updates `@scalar/fastify-api-reference` from 1.57.2 to 1.57.5
- [Release notes](https://github.com/scalar/scalar/releases)
- [Changelog](https://github.com/scalar/scalar/blob/main/integrations/fastify/CHANGELOG.md)
- [Commits](https://github.com/scalar/scalar/commits/HEAD/integrations/fastify)

Updates `@sentry/node` from 10.53.1 to 10.55.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.53.1...10.55.0)

Updates `js-yaml` from 4.1.1 to 4.2.0
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/commits)

Updates `posthog-node` from 5.34.3 to 5.35.9
- [Release notes](https://github.com/PostHog/posthog-js/releases)
- [Changelog](https://github.com/PostHog/posthog-js/blob/main/packages/node/CHANGELOG.md)
- [Commits](https://github.com/PostHog/posthog-js/commits/posthog-node@5.35.9/packages/node)

Updates `tsx` from 4.22.1 to 4.22.4
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](https://github.com/privatenumber/tsx/compare/v4.22.1...v4.22.4)

Updates `zxing-wasm` from 3.0.3 to 3.1.0
- [Release notes](https://github.com/Sec-ant/zxing-wasm/releases)
- [Changelog](https://github.com/Sec-ant/zxing-wasm/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Sec-ant/zxing-wasm/compare/v3.0.3...v3.1.0)

Updates `react` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react)

Updates `react-dom` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react-dom)

Updates `@sentry/react` from 10.53.1 to 10.55.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.53.1...10.55.0)

Updates `posthog-js` from 1.374.0 to 1.377.0
- [Release notes](https://github.com/PostHog/posthog-js/releases)
- [Changelog](https://github.com/PostHog/posthog-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PostHog/posthog-js/compare/posthog-js@1.374.0...posthog-js@1.377.0)

Updates `react-colorful` from 5.6.1 to 5.7.0
- [Release notes](https://github.com/omgovich/react-colorful/releases)
- [Changelog](https://github.com/omgovich/react-colorful/blob/master/CHANGELOG.md)
- [Commits](https://github.com/omgovich/react-colorful/commits/5.7.0)

Updates `react-konva` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/konvajs/react-konva/releases)
- [Commits](https://github.com/konvajs/react-konva/compare/v19.2.3...v19.2.4)

Updates `react-router-dom` from 7.15.1 to 7.16.0
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.16.0/packages/react-router-dom)

Updates `zustand` from 5.0.13 to 5.0.14
- [Release notes](https://github.com/pmndrs/zustand/releases)
- [Commits](https://github.com/pmndrs/zustand/compare/v5.0.13...v5.0.14)

---
updated-dependencies:
- dependency-name: "@neplex/vectorizer"
  dependency-version: 0.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: "@scalar/fastify-api-reference"
  dependency-version: 1.57.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-deps
- dependency-name: "@sentry/node"
  dependency-version: 10.55.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: js-yaml
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: posthog-node
  dependency-version: 5.35.9
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: tsx
  dependency-version: 4.22.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-deps
- dependency-name: zxing-wasm
  dependency-version: 3.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: react
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-deps
- dependency-name: react-dom
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-deps
- dependency-name: "@sentry/react"
  dependency-version: 10.55.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: posthog-js
  dependency-version: 1.377.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: react-colorful
  dependency-version: 5.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: react-konva
  dependency-version: 19.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-deps
- dependency-name: react-router-dom
  dependency-version: 7.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: zustand
  dependency-version: 5.0.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-04 21:49:06 +08:00
SnapOtter 59bbe2b5e0 fix: use crypto.getRandomValues() for password generation
Math.random() is not cryptographically secure. Replace with
crypto.getRandomValues() in both generatePassword() functions
to resolve CodeQL js/insecure-randomness alerts.
2026-05-20 16:04:57 +08:00
SnapOtter e70fca054a fix: replace hardcoded "52 tools" with "50+" across all copy
Future-proofs marketing text so it doesn't need updating every time
a tool is added.
2026-05-20 14:45:45 +08:00
SnapOtter dfbc4cfd59 chore(release): 1.17.1
Bump version across all workspaces, update changelog, release notes,
OpenAPI spec, bug report template, and OpenSSF badge answers.
2026-05-18 19:10:56 +08:00
SnapOtterandGitHub 8b85a8c386 fix: update all renamed Lucide icons and make icon test dynamic (#150)
- FileEdit -> FilePen (bulk-rename tool)
- Wand2 -> Wand (object eraser)
- Columns -> Columns2 (stitch tool)
- Add Expand to ICON_MAP (ai-canvas-expand)
- Make icon-map test derive icon lists from shared constants instead
  of hardcoding names, preventing future breakage on icon renames
2026-05-18 17:09:14 +08:00
SnapOtterandGitHub 27bbdb6e8a fix: update renamed Lucide icons (Wand2 -> Wand, Columns -> Columns2) (#149)
Lucide v0.577 dropped Wand2 and Columns from the icons object used
for dynamic lookup. Named exports still exist as aliases, but the
landing site and tools index use icons[name] which fails silently.

Updates shared constants and web app icon-map to use the current names.
2026-05-18 16:50:30 +08:00
SnapOtterandGitHub dfddaef260 feat: add /tools index page and fix navbar links on subpages (#148)
- Add /tools hub page listing all 52 tools grouped by category with
  CollectionPage + ItemList schema markup
- Include /tools in dynamic sitemap at priority 0.9
- Fix Features and Pricing nav links using relative anchors (#features,
  #pricing) that broke on subpages by prefixing with /
2026-05-18 16:46:58 +08:00