Commit Graph
127 Commits
Author SHA1 Message Date
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0dadca3b99 chore(deps): bump the production-deps group across 1 directory with 17 updates (#144)
Bumps the production-deps group with 17 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@scalar/fastify-api-reference](https://github.com/scalar/scalar/tree/HEAD/integrations/fastify) | `1.49.5` | `1.57.2` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `10.49.0` | `10.53.1` |
| [fflate](https://github.com/101arrowz/fflate) | `0.8.2` | `0.8.3` |
| [p-queue](https://github.com/sindresorhus/p-queue) | `9.1.0` | `9.3.0` |
| [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.29.5` | `5.34.2` |
| [sharp](https://github.com/lovell/sharp) | `0.33.5` | `0.34.5` |
| [tsx](https://github.com/privatenumber/tsx) | `4.21.0` | `4.22.1` |
| [zxing-wasm](https://github.com/Sec-ant/zxing-wasm) | `3.0.2` | `3.0.3` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.4` | `19.2.6` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.4` | `19.2.6` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `0.469.0` | `0.577.0` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.49.0` | `10.53.1` |
| [posthog-js](https://github.com/PostHog/posthog-js) | `1.370.0` | `1.373.5` |
| [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.13.1` | `7.15.1` |
| [zustand](https://github.com/pmndrs/zustand) | `5.0.12` | `5.0.13` |



Updates `@scalar/fastify-api-reference` from 1.49.5 to 1.57.2
- [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.49.0 to 10.53.1
- [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.49.0...10.53.1)

Updates `fflate` from 0.8.2 to 0.8.3
- [Release notes](https://github.com/101arrowz/fflate/releases)
- [Changelog](https://github.com/101arrowz/fflate/blob/master/CHANGELOG.md)
- [Commits](https://github.com/101arrowz/fflate/compare/v0.8.2...v0.8.3)

Updates `p-queue` from 9.1.0 to 9.3.0
- [Release notes](https://github.com/sindresorhus/p-queue/releases)
- [Commits](https://github.com/sindresorhus/p-queue/compare/v9.1.0...v9.3.0)

Updates `posthog-node` from 5.29.5 to 5.34.2
- [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.34.2/packages/node)

Updates `sharp` from 0.33.5 to 0.34.5
- [Release notes](https://github.com/lovell/sharp/releases)
- [Commits](https://github.com/lovell/sharp/compare/v0.33.5...v0.34.5)

Updates `tsx` from 4.21.0 to 4.22.1
- [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.21.0...v4.22.1)

Updates `zxing-wasm` from 3.0.2 to 3.0.3
- [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.2...v3.0.3)

Updates `react` from 19.2.4 to 19.2.6
- [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.6/packages/react)

Updates `react-dom` from 19.2.4 to 19.2.6
- [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.6/packages/react-dom)

Updates `lucide-react` from 0.469.0 to 0.577.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.577.0/packages/lucide-react)

Updates `@sentry/react` from 10.49.0 to 10.53.1
- [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.49.0...10.53.1)

Updates `posthog-js` from 1.370.0 to 1.373.5
- [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.370.0...posthog-js@1.373.5)

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.13.1 to 7.15.1
- [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.15.1/packages/react-router-dom)

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

---
updated-dependencies:
- dependency-name: "@scalar/fastify-api-reference"
  dependency-version: 1.57.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: "@sentry/node"
  dependency-version: 10.53.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: "@sentry/react"
  dependency-version: 10.53.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: fflate
  dependency-version: 0.8.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-deps
- dependency-name: lucide-react
  dependency-version: 0.577.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: p-queue
  dependency-version: 9.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: posthog-js
  dependency-version: 1.373.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: posthog-node
  dependency-version: 5.34.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: react
  dependency-version: 19.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  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-dom
  dependency-version: 19.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  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.15.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: sharp
  dependency-version: 0.34.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: tsx
  dependency-version: 4.22.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-deps
- dependency-name: zustand
  dependency-version: 5.0.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-deps
- dependency-name: zxing-wasm
  dependency-version: 3.0.3
  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-05-18 16:39:47 +08:00
SnapOtter 3e06d68f4f chore: bump version to 1.17.0 and update docs for release
- Bump all workspace package versions to 1.17.0
- Update APP_VERSION constant and OpenAPI spec
- Update AI tool count from 15 to 16 across docs and i18n
- Update tool table with AI Canvas Expand, Meme Generator, Beautify
- Add image editor, OIDC, and 20 languages to README features
- Add release notes for v1.17.0
- Add JSON-LD structured data and SEO improvements to landing/docs
2026-05-16 12:48:02 +08:00
SnapOtter 5b5767990b fix: tighten target-size compression tolerance from 5% to 1%
The binary search exited early at 5% tolerance, producing output like
48.3KB for a 50KB target. Reducing to 1% with 12 iterations makes the
output much closer to the requested target.
2026-05-11 16:29:14 +08:00
SnapOtter e6a35265ef fix: target-size compression now respects the target
The binary search found the right quality but sharp(buffer).toBuffer()
re-encoded at default quality 80, inflating the output (e.g. 50KB target
producing 90KB). Replaced buffer-wrapping with proper Sharp pipelines
that include .toFormat() with the proven quality. Also added progressive
dimension reduction when quality alone cannot reach the target, and
tightened tolerance to only accept at-or-below-target results.
2026-05-11 16:19:40 +08:00
SnapOtter 78ca9720e7 fix: sync all workspace package versions to 1.16.0 2026-05-10 20:19:02 +08:00
SnapOtter 7b1f09f5d0 fix: CLAHE tile size and alpha channel corruption in image enhancement
CLAHE width/height is tile size in pixels, not tile count. A 3px tile on
a 992x1088 image created ~330x360 independent histogram regions, producing
crosshatch/etching artifacts. Now uses image_dimension/8 (clamped 8-256)
for ~8 tiles per axis. Also strips alpha before enhancement and re-joins
after to prevent CLAHE/normalise/linear from corrupting transparency.
2026-05-09 15:20:55 +08:00
SnapOtter bdcfb6647c fix: sync frontend preset multipliers and fix sharpen type error
Add clahe and normalise entries to frontend PRESET_MULTIPLIERS to match
backend. Fix SharpenOptions to use m1 (not flat) per Sharp 0.34 types.
2026-05-09 11:26:49 +08:00
SnapOtter b61be9e438 fix: replace enhancement pipeline with CLAHE + normalise + gamma
CLAHE provides adaptive local contrast, normalise stretches the
histogram, and gamma adjusts exposure perceptually. Replaces the old
modulate/linear pipeline that compounded errors and darkened images.
Preset multipliers now include clahe and normalise entries.

Key fixes beyond the spec:
- maxSlope rounded to integer (Sharp requirement)
- White balance uses linear() instead of recomb() to avoid float-cast
  that breaks CLAHE in the libvips pipeline
- CLAHE tile size adapts to image dimensions (1x1 for tiny images)
- Gamma clamped to Sharp's valid range (1.0-3.0)
- Normalise lower/upper correctly mapped to percentile cutoffs
2026-05-09 11:24:00 +08:00
SnapOtter 5434762acc fix: recalibrate enhancement scoring with dead zones
Contrast score now uses linear stdevLum/1.2 centered at 50 (was
miscalibrated 25-75 range centered at 75). Corrections use dead zones
(score 40-60 = zero) so well-exposed images get near-zero adjustments
instead of being darkened.
2026-05-09 11:07:36 +08:00
SnapOtter 136a4a0752 Merge branch 'feat/format-support-expansion'
# Conflicts:
#	README.md
#	apps/web/src/components/layout/app-layout.tsx
2026-05-08 16:21:11 +08:00
SnapOtter c4c9852afc refactor: use named ColorBlindnessOptions interface in operation signature 2026-05-08 15:14:42 +08:00
SnapOtter 0b6a970912 feat: add color blindness simulation image-engine operation
Add colorBlindness() operation with 8 simulation matrices (Vienot/Machado)
for protanopia, deuteranopia, tritanopia, protanomaly, deuteranomaly,
tritanomaly, achromatopsia, and blue cone monochromacy.
2026-05-08 15:11:36 +08:00
SnapOtter 80961c0187 feat: add JXL to all tool format selectors, expand convert with BMP/ICO/JP2/QOI, add server-side editor export 2026-05-08 00:19:19 +08:00
SnapOtter 390b5adb8c feat: add QOI codec, format encoders (BMP/ICO/JP2/QOI), fix JXL output bug 2026-05-08 00:09:55 +08:00
SnapOtter 5c9fa2de49 feat: add decode pipelines for JP2, EPS, QOI, DDS, CUR, DPX, FITS, PPM, SVGZ, APNG
Add input decode support for 10 new image format families:

- JPEG 2000 (JP2/J2K): opj_decompress with ImageMagick fallback
- EPS: ImageMagick + Ghostscript delegate with 50MB size guard
- DDS: ImageMagick decode, first frame extraction
- CUR: reuses ICO decoder (structurally identical)
- DPX/Cineon: ImageMagick with sRGB colorspace conversion
- FITS: ImageMagick with normalize + sRGB conversion
- QOI: stub decoder (real codec deferred to Task 4)
- PPM/PGM/PBM/PFM: Sharp-native via libvips (no CLI decoder needed)
- SVGZ: gzip decompression with bomb protection before SVG sanitization
- APNG: accepted via extension, decoded as PNG first frame by Sharp

Updates magic bytes, MIME mappings, and frontend accept lists across
all file picker entry points (dropzone, tool page, file upload, editor).
2026-05-08 00:05:50 +08:00
SnapOtter c0fb5896bb feat: add RAW magic bytes to image-engine detect.ts and MIME entries for 17 new RAW formats 2026-05-08 00:00:39 +08:00
SnapOtter 979a833978 fix: resolve analytics data gaps and resize validation failures
- Fix resize 20% failure rate: add Zod refine requiring at least one
  dimension, enforce integer/max constraints, clamp percentage scaling
  to minimum 1px, and guard against missing metadata in withoutEnlargement
- Fix PostHog init race condition: move consent check before async import
  so frontend events (search, pageview) are no longer silently dropped
- Fix identify() passing nested $set/$set_once wrappers instead of flat
  properties, so version person property now appears on PostHog profiles
- Add error_code and error_message to failed tool_used analytics events
  for debugging tool failures from PostHog
2026-05-06 23:21:45 +08:00
SnapOtter ff8dcf63c7 fix: resolve 14 security, correctness, and robustness issues found during QA sweep
Security fixes:
- Add auth + ownership check to thumbnail endpoint (was unauthenticated)
- Validate ExifTool fieldsToRemove against safe tag name pattern
- Add SVG sanitization to pipeline execute and batch endpoints
- Replace basename() with sanitizeFilename() in 16 tool routes
- Escape SQL LIKE wildcards in file search to prevent pattern injection
- Improve settings HTML tag validation pattern

Bug fixes:
- Skip autoOrient for SVG inputs in pipeline (prevents misinterpretation)
- Remove double-encode in compress targetSize (was degrading quality)
- Fix bg-effects alpha value from 255 to 1.0 (Sharp expects float)
- Guard download stream error handler against headers-already-sent race
- Use O_EXCL atomic file creation for install lock (fixes TOCTOU race)
- Truncate collage file array to template image count

UX fixes:
- Accept empty JSON bodies on POST endpoints (install/uninstall)
- Custom JSON content type parser that treats empty body as {}
2026-05-01 18:11:49 +08:00
SnapOtter bd84728588 docs: comprehensive API sync and documentation audit
- Rewrite OpenAPI spec to match actual code (988 lines changed):
  - Fix ToolResponse schema (add previewUrl, savedFileId)
  - Fix Error schema shape ({error, details} not {statusCode, error, message})
  - Fix POST /api/auth/register URL (was /api/auth/users)
  - Fix login/session responses (7 missing user fields + expiresAt)
  - Fix 8 endpoints returning 204 → 200 with {ok: true}
  - Fix pipeline execute field name (steps → pipeline)
  - Fix API keys response key (keys → apiKeys)
  - Fix settings response wrapper, teams UUID type
  - Rewrite 7 major tool response schemas (info, barcode-read,
    find-duplicates, compare, remove-background, upscale, ocr, blur-faces)
  - Fix files/save-result (JSON → multipart), files/upload (201 + array)
  - Fix SSE progress schema (integers not arrays)
  - Add 422/501 error responses to AI and processing tools
  - Fix settings required → optional on 29 tool endpoints
  - Add 5 missing color adjustment fields to alias endpoints
- Rewrite rest.md tool parameter descriptions (12 tools fixed)
- Add Tool Sub-Routes section to rest.md (11 endpoints)
- Fix file library, settings, pipeline, auth docs in rest.md
- Fix API key hashing description (SHA-256 → scrypt)
- Fix "GitHub Pages" → "Cloudflare Pages" in architecture + deployment docs
- Fix tool count "45+" → "47" across all doc surfaces
- Fix branding endpoint paths in rest.md (/branding/logo → /settings/logo)
2026-04-25 07:17:45 +08:00
SnapOtter 7f62bc32db test: expand coverage to 3,382 tests across all layers
- Unit: 1,353 tests (42 files) — +256 new tests covering AI bridge
  modules, image-engine sharpen/optimize-for-web, Zustand stores, and
  icon-map validation
- Integration: 1,640 tests (57 files) — +826 new tests across all
  tool routes, pipeline/progress/batch infrastructure, user-files,
  edit-metadata, and a 321-test cross-format matrix
- E2E-Docker: 389 passing (20 spec files) — 6 new spec files for
  batch processing, format conversion, layout, optimization,
  watermark/overlay, and pipeline chains. Tests verified against fresh
  Docker container with all 6 AI bundles installed.

Bug fixes discovered during testing:
- fix(compress): SVG/BMP/exotic formats crashed Sharp encoder — added
  format-safety fallback to PNG
- fix(rate-limit): increase default login attempt limit from 10 to 500
  per minute — previous value caused false test failures and is too
  restrictive for a self-hosted app
- fix(auth.setup): wait for consent button visibility before clicking
  to prevent flaky E2E-Docker auth setup
2026-04-24 22:43:14 +08:00
SnapOtter 0309e0f680 chore: deploy to Cloudflare Pages and update branding
- Add Cloudflare Pages deployment for landing page (snapotter.com) and
  docs (docs.snapotter.com)
- Create deploy-landing.yml and update deploy-docs.yml workflows
- Update CI to ignore apps/landing/** paths
- Fix logo transparency (remove white background) across all apps
- Recreate social-preview.png with SnapOtter branding
- Update all docs URLs from GitHub Pages to docs.snapotter.com
- Update VitePress config: light theme default, fix llms.txt paths
- Add .vitepress/cache/ and .env.* to gitignore
2026-04-24 18:06:29 +08:00
ashim-hq 7920fbfd20 chore: fix pre-existing biome formatting issues 2026-04-21 23:25:41 +08:00
ashim-hq 966d7abaf0 fix: AVIF compress fails because Sharp metadata reports heif not avif
Sharp's metadata() returns format:"heif" for AVIF files. The compress
function was using this raw value without normalizing through FORMAT_MAP,
so toFormat("heif",...) was called which requires a compression option.
Now both explicit and detected formats go through FORMAT_MAP, mapping
heif→avif correctly.
2026-04-21 10:27:02 +08:00
ashim-hq dc9160746e fix: ICO needs CLI decode, AVIF compress missing options, remove JXL output
- ICO: Sharp cannot decode ICO files. Added ImageMagick-based ICO decoder
  that extracts the largest embedded image. Added ICO to CLI_DECODED_FORMATS
  and SERVER_PREVIEW_EXTENSIONS. Removed from BROWSER_PREVIEWABLE sets.
- AVIF compress: Sharp's AVIF encoder requires effort option. Added
  formatOpts() helper that supplies effort:4 for AVIF format.
- JXL output: Docker's bundled libvips lacks the JXL encoder plugin.
  Removed JXL as a convert output target to avoid guaranteed failures.
  JXL remains fully supported as an input format.
2026-04-21 10:20:08 +08:00
ashim-hq 2aadb66031 feat: add support for JXL, Camera RAW, ICO, TGA, PSD, EXR, HDR image formats
Extends the platform to handle 7 new image format families alongside
the existing AVIF support gap-fill. Uses the established HEIC decoder
pattern (CLI decode → PNG → Sharp) for formats Sharp can't handle
natively: Camera RAW via dcraw_emu/LibRaw, PSD/TGA/EXR/HDR via
ImageMagick. JXL and ICO are Sharp-native. Adds server-side preview
for non-browser-displayable formats and JXL as a new convert output
target. All 27 validateImageBuffer callers updated with filename for
extension-based format detection.
2026-04-21 09:59:57 +08:00
ashim-hq c738f16107 fix: support AVIF compress and fix hardcoded content type 2026-04-20 22:13:53 +08:00
ashim-hq ae411f2d72 chore(release): 1.15.9 [skip ci] 2026-04-17 23:26:26 +08:00
semantic-release-bot 95af281584 chore(release): 1.15.8 [skip ci]
## [1.15.8](https://github.com/ashim-hq/ashim/compare/v1.15.7...v1.15.8) (2026-04-17)

### Bug Fixes

* copy Node.js from official image instead of apt-get install ([536125e](https://github.com/ashim-hq/ashim/commit/536125ec9fbc5758bdd3e8f0f4c44253de2231c7))
2026-04-17 07:36:40 +00:00
semantic-release-bot caa2160ef8 chore(release): 1.15.7 [skip ci]
## [1.15.7](https://github.com/ashim-hq/ashim/compare/v1.15.6...v1.15.7) (2026-04-17)

### Bug Fixes

* add retry with backoff for apt-get update on CUDA base image ([3d6db5a](https://github.com/ashim-hq/ashim/commit/3d6db5a32d3f9292d5476e9bd80c1f06624fa316))
2026-04-17 07:04:40 +00:00
semantic-release-bot 23dae8d152 chore(release): 1.15.6 [skip ci]
## [1.15.6](https://github.com/ashim-hq/ashim/compare/v1.15.5...v1.15.6) (2026-04-17)

### Performance Improvements

* parallelize model downloads and switch to registry cache ([79c4ed6](https://github.com/ashim-hq/ashim/commit/79c4ed6a359b008dedeb154a55e2764ee0e3d9fa))
2026-04-17 06:55:08 +00:00
semantic-release-bot 2fd0c00564 chore(release): 1.15.5 [skip ci]
## [1.15.5](https://github.com/ashim-hq/ashim/compare/v1.15.4...v1.15.5) (2026-04-17)

### Bug Fixes

* exclude e2e-docker tests from Vitest runner ([8df18c5](https://github.com/ashim-hq/ashim/commit/8df18c56a6c69e2a188cf0e7c97e692cd4c0e7ec))
2026-04-17 06:41:05 +00:00
semantic-release-bot 3dc98374e2 chore(release): 1.15.4 [skip ci]
## [1.15.4](https://github.com/ashim-hq/ashim/compare/v1.15.3...v1.15.4) (2026-04-17)

### Bug Fixes

* verbose error handling, batch processing, and multi-file support ([3223960](https://github.com/ashim-hq/ashim/commit/32239600ae6ce30628e77e61a805ca0a167b5068))
* verbose errors, batch processing, multi-file support ([#1](https://github.com/ashim-hq/ashim/issues/1)) ([8b87cf8](https://github.com/ashim-hq/ashim/commit/8b87cf888c6194e2af427a180607d7c53a1d15b9))
2026-04-17 06:21:10 +00:00
semantic-release-bot b76b9a1878 chore(release): 1.15.3 [skip ci]
## [1.15.3](https://github.com/ashim-hq/ashim/compare/v1.15.2...v1.15.3) (2026-04-16)

### Bug Fixes

* retry apt-get update on transient mirror sync errors (Acquire::Retries=3) ([cec7163](https://github.com/ashim-hq/ashim/commit/cec71632d0c868c3a413b813ff15baccc8fa8cdd))
2026-04-16 19:46:27 +00:00
semantic-release-bot 59e6f2f28c chore(release): 1.15.2 [skip ci]
## [1.15.2](https://github.com/ashim-hq/ashim/compare/v1.15.1...v1.15.2) (2026-04-16)

### Bug Fixes

* use GHCR_TOKEN with write:packages scope for GHCR login ([e14414f](https://github.com/ashim-hq/ashim/commit/e14414f3061981b1454dc7d4504c64ec01db945e))
2026-04-16 18:13:08 +00:00
semantic-release-bot fd1eb9c781 chore(release): 1.15.1 [skip ci]
## [1.15.1](https://github.com/ashim-hq/ashim/compare/v1.15.0...v1.15.1) (2026-04-16)

### Bug Fixes

* **docker:** create /opt/models unconditionally so chown works in CI ([93ce289](https://github.com/ashim-hq/ashim/commit/93ce2891cc26afc93f01168d008927d3d356c1a9))
* **docker:** run frontend builder on BUILDPLATFORM to fix esbuild crash under QEMU ([6a3ad0d](https://github.com/ashim-hq/ashim/commit/6a3ad0d496e291b30a3f719ca079c43ce7aab705))
* resolve runtime model path mismatch for non-root Docker user ([f28792a](https://github.com/ashim-hq/ashim/commit/f28792a5ed78221f38cf2f3c80cae9f24cd7f5e3))
2026-04-16 15:46:06 +00:00
Siddharth Kumar Sah 9cd91edee1 chore(release): 1.15.0
Bump all workspace packages from 1.14.0 to 1.15.0.
2026-04-15 23:17:31 +08:00
Siddharth Kumar Sah 93c588b239 fix(lint): resolve all biome warnings across API, web, and image-engine
API:
- Replace string concatenation with template literals (batch, pipeline,
  tool-factory, content-aware-resize, passport-photo, remove-background)
- Remove unused imports (teams, color-adjustments, image-enhancement)
- Replace non-null assertions with guard clauses in bg-effects and stitch
- Use optional chaining in docs route

Image-engine:
- Remove unused OutputFormat imports (compress, convert)
- Use local variables instead of reassigning parameters (optimize-for-web, sharpen)

Web:
- Fix useExhaustiveDependencies: remove genuinely redundant deps, add
  biome-ignore comments for intentional patterns (src prop, cleanup fns)
- Replace non-null assertions with null-safe alternatives
- Add accessible titles to inline SVGs (color-settings, image-enhancement-settings)
- Fix noLabelWithoutControl: associate labels via htmlFor/id or use <span>
  (image-to-base64-settings, edit-metadata-settings, qr-generate-settings)
- Replace div[role="button"] with <button> (pdf-to-image-settings)
- Use stable keys instead of array indices (collage-preview, collage-settings)
- Fix noStaticElementInteractions in collage-preview (role="none")
- Remove unused function parameters and imports
2026-04-14 22:15:37 +08:00
Siddharth Kumar Sah 85b1cfc10a chore: rename Stirling-Image to ashim across entire codebase
Complete rebrand from Stirling-Image to ashim following the project
move to https://github.com/ashim-hq/ashim.

Changes across 117 files:
- Package scope: @stirling-image/* → @ashim/*
- GitHub URLs: stirling-image/stirling-image → ashim-hq/ashim
- Docker Hub: stirlingimage/stirling-image → ashimhq/ashim
- GitHub Pages: stirling-image.github.io → ashim-hq.github.io
- All branding text: "Stirling Image" → "ashim"
- Docker service/volumes/user: stirling → ashim
- Database: stirling.db → ashim.db
- localStorage keys: stirling-token → ashim-token
- Environment variables: STIRLING_GPU → ASHIM_GPU
- Python cache dirs: .cache/stirling-image → .cache/ashim
- SVG filter IDs, test prefixes, and all other references
2026-04-14 20:55:42 +08:00
5be8be3dc3 feat: add Optimize for Web tool (#68)
* feat(image-engine): add OptimizeForWebOptions type

* feat(image-engine): add optimizeForWeb operation

* feat(shared): add optimize-for-web tool definition and i18n

* feat(api): add optimize-for-web route with preview endpoint

* feat(web): add optimize-for-web settings component with live preview

* feat(web): register optimize-for-web in tool registry

* fix(web): align toggle switch translate with codebase pattern

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-14 16:16:04 +08:00
58cdbe50b4 feat: SOTA sharpening tool with 3 methods and 7 presets (#56)
* feat(sharpening): add SharpenAdvancedOptions type for multi-method sharpening

* feat(sharpening): implement 3-method sharpen engine (adaptive, USM, high-pass)

* feat(sharpening): add dedicated API route with Zod validation

* feat(sharpening): register tool in constants, i18n, and suggested tools

* feat(sharpening): add settings UI with presets, methods, and advanced controls

* feat(sharpening): register tool in frontend registry with before-after display

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 19:12:09 +08:00
a8c7b92ca5 feat: SOTA image enhancement with one-click auto-improve (#55)
* feat(image-enhancement): add analysis and correction types

* feat(image-enhancement): implement auto-enhance analysis and correction engine

* test(image-enhancement): add unit tests for auto-enhance engine

* feat(image-enhancement): add API route with analyze endpoint and register in constants/i18n

* feat(image-enhancement): add UI component with mode selector, intensity slider, and analysis badges

* test(image-enhancement): add integration and e2e tests

* fix(image-enhancement): use modulate instead of gamma for exposure correction

Sharp's gamma() only accepts values between 1.0 and 3.0, but brightening
underexposed images computed gamma < 1.0. Switch to modulate({ brightness })
which handles both brightening and darkening correctly.

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 17:48:53 +08:00
34ec840b72 docs(api): achieve 100% endpoint coverage in OpenAPI spec and VitePress docs (#54)
Add 12 previously undocumented routes to the OpenAPI 3.1 specification:
content-aware-resize, edit-metadata (+ inspect), stitch, pdf-to-image
(+ info, preview), gif-tools/info, remove-background/effects, preview,
pipeline/tools, and pipeline/batch. Fix license from MIT to AGPL-3.0,
correct DELETE /files response from 204 to 200 with body, and update
VitePress API docs (rest.md tool table, ai.md model parameters). Also
register the sharpen operation in the image-engine OPERATION_MAP so it
can be used as a standalone pipeline step.

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 17:30:08 +08:00
Siddharth Kumar Sah 6c58f12262 feat: overhaul remove-background with effects pipeline, consolidate color tools
Remove Background:
- Two-phase flow: AI removes bg once, then effects adjust instantly
- Blur background effect with real-time CSS preview (portrait mode)
- Drop shadow effect with opacity control
- Gradient backgrounds with presets, custom colors, and angle
- Custom background image upload (including HEIC/HEIF)
- Solid color backgrounds moved from Python to Node.js/Sharp
- Effects-only API endpoint for instant re-renders without AI re-run
- HEIC/HEIF input support (decoded before passing to Python/rembg)
- Passport/ID photo checkbox defaults ON for People subject
- Before/after slider preserved when no effects active
- 15 comprehensive Playwright e2e tests

Color Tools:
- Consolidated 4 tools (brightness-contrast, saturation, color-channels,
  color-effects) into single "Adjust Colors" tool
- Added exposure, temperature, tint, hue, sharpness controls
- SVG filter-based live preview for all adjustments
- Backward-compatible URL redirects from old tool paths

Other fixes:
- Favicon tool: download button instead of auto-download
- Batch processing: HEIC filename extension fix
- File store: processedFilename field for proper batch downloads
2026-04-12 17:53:16 +08:00
Siddharth Kumar Sah dde70f70ad feat: comprehensive HEIC/HEIF support and edit-metadata ExifTool overhaul
- Add ensureSharpCompat() helper for automatic HEIC detection and decode
- Fix HEIC support in all 14 custom-route tools (image-to-pdf, split,
  barcode-read, compose, collage, stitch, compare, find-duplicates,
  color-palette, watermark-image, vectorize, favicon, info, branding)
- Fix PdfPagePreview using store's decoded blobUrl instead of raw File
- Add onError fallback in ImageViewer for unrenderable formats
- Fix image-to-pdf progress bar with flushSync for reliable rendering
- Add ExifTool backend for edit-metadata (GPS, keywords, IPTC, dates)
- Rename Strip Metadata to Remove Metadata with interactive Leaflet map
- Fix user-files thumbnail generation for stored HEIC files
- Fix info tool stats() histogram for HEIC via decoded buffer
- Skip HEIC preprocessing in batch route for metadata tools
2026-04-12 08:50:19 +08:00
Siddharth Kumar Sah 6f5283019b feat: full HEIF/HEIC support, content-aware resize performance fix, UI improvements
- Add bidirectional HEIF support: decode (input) and encode (output) via system heif-convert/heif-enc
- Add server-side WebP preview generation for non-browser-previewable formats (HEIC, TIFF)
- Fix content-aware resize failing on HEIF input (decode before passing to caire)
- Fix content-aware resize timeout on large images by downscaling to max 1200px and using JPEG intermediate
- Add HEIF as target format in convert tool
- Add loading spinner for HEIF preview decode in file store
- Fix file picker not accepting HEIF files (explicit .heic,.heif,.hif extensions)
- Extend frontend timeout for medium tools to 180s with 45s progress animation
- Redesign rotate controls with preset buttons and compact flip section
- Remove misleading savings percentage from convert tool
2026-04-11 23:27:44 +08:00
Siddharth Kumar Sah b8227c45b9 feat(crop): improve UI and fix batch crop for multi-file
- Replace Rule of Thirds button with checkbox for clearer toggle
- Show side-by-side comparison after crop instead of overlay slider
- Add custom aspect ratio option with W:H number inputs
- Fix batch crop failing on files with different dimensions by
  sending percentage-based coordinates instead of absolute pixels
- Add failed-file error state display in tool page
2026-04-11 14:47:46 +08:00
semantic-release-bot 2ac7b6875b chore(release): 1.14.0 [skip ci]
# [1.14.0](https://github.com/stirling-image/stirling-image/compare/v1.13.0...v1.14.0) (2026-04-10)

### Bug Fixes

* add FILES_STORAGE_PATH to Dockerfile ENV to prevent data loss ([b575243](https://github.com/stirling-image/stirling-image/commit/b575243e9a0cb2ac4567d785a74e57dea912e9e2))
* add shutdown timeout and improve health endpoint ([986ad37](https://github.com/stirling-image/stirling-image/commit/986ad37bb5e6644dd93521018a1bcd2d6243f502))
* address code review findings before merge ([caf65bc](https://github.com/stirling-image/stirling-image/commit/caf65bc4697ddfea27674b56fd2e8de847edc734))
* correct PaddleOCR language codes for model download and OCR ([e1ee571](https://github.com/stirling-image/stirling-image/commit/e1ee57103c201f104b737c2719d0014d4912d4b2))
* force CPU mode in download_models.py for build-time compatibility ([b4b59a7](https://github.com/stirling-image/stirling-image/commit/b4b59a7500375bc2e65cb0050e5308b07610d2cf))
* handle paddlepaddle-gpu CUDA import at build time gracefully ([0083a74](https://github.com/stirling-image/stirling-image/commit/0083a741a9a3924ccc37c4e622c2980a8a41f1a3))
* install cuda-compat stubs for build-time PaddlePaddle import ([d31d665](https://github.com/stirling-image/stirling-image/commit/d31d66556ef0aa7c20a73a94f5d95b54b99fbb8a))
* load RealESRGAN pretrained weights for actual AI upscaling ([fa9569c](https://github.com/stirling-image/stirling-image/commit/fa9569c920d6bdac094dcd661fc5cf3b4be3f17a))
* revert to npx tsx in CMD for pnpm compatibility ([e55253d](https://github.com/stirling-image/stirling-image/commit/e55253dee03f9e93187d50e0ffb66b423a1230c0))
* simplify smoke test to CPU-only imports for build-time compat ([3481663](https://github.com/stirling-image/stirling-image/commit/34816639609cbccab91a5cad5760fea769c4b565))
* skip RealESRGAN import check on arm64 in smoke test ([1e2ef52](https://github.com/stirling-image/stirling-image/commit/1e2ef5284686253ae33e05411a515369b7f41a3e))
* split paddlepaddle-gpu and paddleocr installs, use --extra-index-url ([74183e8](https://github.com/stirling-image/stirling-image/commit/74183e8dc1e3d8f90cff4484f5526c3c3dfba9a6))
* suppress ML library stdout noise in ocr.py and upscale.py ([c0b419d](https://github.com/stirling-image/stirling-image/commit/c0b419de21acb92b243ef78191dff6a2153c5961))
* use PaddlePaddle GPU package index for CUDA wheels ([dd9528f](https://github.com/stirling-image/stirling-image/commit/dd9528f53c9bcf148842ab94f14a4ebd5ae223ec))
* use platform-specific mediapipe version for arm64 compatibility ([7face19](https://github.com/stirling-image/stirling-image/commit/7face19238f54cfea02d453b697e34b50ccd9d21))

### Features

* expand model pre-download with verification and smoke test ([a9e3b96](https://github.com/stirling-image/stirling-image/commit/a9e3b9688776a51efd2f42cae810de425cf1d9cf))
* simplify CI to single unified Docker build ([b385a2e](https://github.com/stirling-image/stirling-image/commit/b385a2eabb255f7a8fe2d3720a358ff5bf254310))
* simplify compose to single file, add log rotation ([84f7057](https://github.com/stirling-image/stirling-image/commit/84f7057a49850b7a47440099ec2caad8d3b87efe))
* unified Docker image with GPU auto-detection ([6c3eb3b](https://github.com/stirling-image/stirling-image/commit/6c3eb3b876cee0301d5fb3ed8324a3c8e92b1307))
2026-04-10 14:13:37 +00:00
semantic-release-bot aa4e5cac8d chore(release): 1.13.0 [skip ci]
# [1.13.0](https://github.com/stirling-image/stirling-image/compare/v1.12.0...v1.13.0) (2026-04-10)

### Bug Fixes

* complete RBAC implementation lost during merge ([cc8a272](https://github.com/stirling-image/stirling-image/commit/cc8a27239b02a63ca88abc3e363c8a46f89674e8))

### Features

* add backend permission map and requirePermission middleware ([1a99571](https://github.com/stirling-image/stirling-image/commit/1a995711535a1525e709cdd7bff75361f457e942))
* add permission checks and admin override to API key routes ([d776680](https://github.com/stirling-image/stirling-image/commit/d776680f2d2342e35b84821792d6c24ae7e0ffbc))
* add permission checks and admin override to pipeline routes ([59f40db](https://github.com/stirling-image/stirling-image/commit/59f40dbfd4a97f8691b5fbbf6d338063c389987b))
* add permission checks and ownership scoping to user-files routes ([86ba698](https://github.com/stirling-image/stirling-image/commit/86ba69825a1dd87c9f868d79cd806b7d594cce1b))
* add shared Permission and Role types ([2f594e9](https://github.com/stirling-image/stirling-image/commit/2f594e96057c72bf107f3012426e87af5f97eb94))
* add tools:use permission check to tool, batch, pipeline, and upload routes ([885ace5](https://github.com/stirling-image/stirling-image/commit/885ace54f09b3301989f8aa404c15f60e19c054d))
* extend useAuth hook with role and permissions from session ([e0ba8be](https://github.com/stirling-image/stirling-image/commit/e0ba8be7b3211299c8cde90b2d22e7796eee2206))
* filter settings tabs by user permissions, remove admin fallback ([bcbd24a](https://github.com/stirling-image/stirling-image/commit/bcbd24a2395b93b64dbbf638ba0138f9ec9ba9da))
* include permissions and teamName in login/session responses ([4943177](https://github.com/stirling-image/stirling-image/commit/49431772ec6a02eae8aced48da92ef87a6c89afb))
* replace requireAdmin with requirePermission on all routes ([af7f57d](https://github.com/stirling-image/stirling-image/commit/af7f57d52f49c8f8412876639076084c96eba284))
2026-04-10 13:26:01 +00:00
semantic-release-bot b20039eddf chore(release): 1.12.0 [skip ci]
# [1.12.0](https://github.com/stirling-image/stirling-image/compare/v1.11.0...v1.12.0) (2026-04-10)

### Features

* unified Docker image with GPU auto-detection ([#37](https://github.com/stirling-image/stirling-image/issues/37)) ([b0083e2](https://github.com/stirling-image/stirling-image/commit/b0083e2b083d0bf52b6a576f7ef67fbff0cc8cbe))
2026-04-10 05:45:42 +00:00
semantic-release-bot 7bc979f677 chore(release): 1.11.0 [skip ci]
# [1.11.0](https://github.com/stirling-image/stirling-image/compare/v1.10.0...v1.11.0) (2026-04-07)

### Features

* **docs:** auto-generate llms.txt via vitepress-plugin-llms ([6a362d6](https://github.com/stirling-image/stirling-image/commit/6a362d6443cd85ac58a46f5b5cf29f9b6ff3020c))
2026-04-07 16:53:54 +00:00