Commit Graph
116 Commits
Author SHA1 Message Date
SnapOtter 0705de8f1b test: add axe a11y pass and device visual regression (phase 4c)
Add scoped axe accessibility audit (a11y.spec.ts, device-a11y.spec.ts)
scanning home, one tool per modality, editor, and login across desktop
chromium and mobile-chromium in EN and AR locales. Uses a committed
baseline (a11y-baseline.json) to gate on NEW critical/serious violations
while documenting existing debt.

Add device-visual.spec.ts with curated screenshots (home, resize tool,
settings dialog) on mobile-chromium and tablet-chromium. Six darwin
baselines generated; linux baselines deferred to the existing
update-visual-baselines workflow.

Trivial a11y fixes applied:
- Login page: outer div -> main (fixes landmark-one-main, reduces region)
- Editor page: outer div -> main for both desktop and mobile gate
- AppLayout main: add tabIndex={-1} for skip-link focusability

Updated DEVICE_SPECS regex to route device-visual and device-a11y specs.
Added @axe-core/playwright as a devDependency.
2026-06-20 03:44:26 +08:00
SnapOtter 620552569e feat!: SnapOtter 2.0.0
Bump all workspace package versions and APP_VERSION to 2.0.0, marking the
official 2.0 release. Removes the stale 1.x .release-notes.md artifact
(semantic-release regenerates release notes). The 2.0/multimodality docs
and rebrand already landed on main via #254 and #261, so this carries only
the version designation forward from the rebrand branch.

BREAKING CHANGE: SnapOtter 2.0 - the platform re-architecture (Postgres 17 +
Redis 8 + BullMQ durable jobs, 157 tools across five modalities) is the 2.0
release line, replacing the 1.x SQLite single-container architecture.
2026-06-17 14:33:09 +08:00
SnapOtterandGitHub ecc0a45f0e docs: per-tool reference pages for all 157 tools (+ fix docs build) (#261)
* fix(docs): keep gray-matter on js-yaml 3 so the docs site builds

The js-yaml >=4.2.0 override from #257 forced js-yaml 4 onto gray-matter (used by vitepress and vitepress-plugin-llms), which calls the removed yaml.safeLoad and broke `vitepress build`. Scope a gray-matter>js-yaml ^3.14.1 override so gray-matter keeps the v3 API (build-time, trusted frontmatter only) while app code stays on js-yaml 4.2.0+.

* docs: add per-tool reference pages for all 157 tools, with a modality sidebar

Generate /tools/<id> pages for the 104 tools that lacked one (video 29, audio 17, document 36, data 10, and 12 newer image tools), matching the existing page format (API endpoint, parameters from the OpenAPI spec, curl example, response, notes). Async/AI tools document the 202+SSE flow and feature-bundle requirement.

Sidebar: add Video / Audio / PDF & Documents / Data groups with per-tool links, fold the 12 new image tools into the existing image categories, and replace the placeholder rest.md-anchor group. Docs site builds cleanly (157 pages, no dead links).
2026-06-17 11:11:37 +08:00
SnapOtterandGitHub 79233ff19d chore(deps): patch Dependabot security advisories (esbuild, qs, uuid, yaml, js-yaml, babel, otel, rembg) (#257)
Resolve the actionable Dependabot alerts via pnpm overrides (for transitive deps) and a Python pin bump.

- pnpm overrides: esbuild >=0.28.1 (the lone high-severity alert), @babel/core >=7.29.6, @opentelemetry/core >=2.8.0, js-yaml >=4.2.0, qs >=6.15.2, uuid >=11.1.1, yaml >=2.8.3
- rembg 2.0.62 -> 2.0.75 in requirements.txt and requirements-gpu.txt

Verified: pnpm install, typecheck, lint, and full build all pass.

NOT included: the astro advisory requires Astro 5 -> 6 (a major, breaking framework upgrade), which warrants its own migration PR rather than a security bump.
2026-06-16 21:49:53 +08:00
SnapOtterandGitHub 17726ae59d docs: multi-modality rebrand, 2.0 architecture accuracy, and full OpenAPI coverage (#254)
* docs: rebrand from image-only to multi-modality across docs and metadata

SnapOtter expanded from image-only to 157 tools across 5 modalities
(image, video, audio, document/PDF, data). Update all product-level
copy, metadata, and i18n that still framed it as an image-only tool.

- README, package.json, root llms.txt: multi-modality framing, 157 tools
- OpenAPI info + tags, generated /llms.txt tagline (docs.ts)
- VitePress docs site: hero, getting-started, architecture, security,
  deployment, configuration, developer, supported-formats
- i18n: 10 product keys across all 21 locales (hero, app description,
  privacy notes, AI features, progress messages, getting-started)
- web/demo/landing meta + privacy copy, COMMUNITY_GUIDE, .env.example

Stale tool counts (53/50+/52/70+/35) corrected to 157 throughout.
Database/container deployment claims left unchanged (out of scope).

* docs: fix stale post-rebrand test assertions and README language list

- tests/e2e-docs/homepage.spec.ts: assert the current docs homepage (file toolkit, 157 tools, 5 modalities) instead of the old image-only strings
- tests/unit/api/docs-route.test.ts: sync the reproduced llms.txt tagline with docs.ts
- README.md: 21 languages with the correct list (add Swedish and Chinese Traditional, drop Czech which is not supported)

* docs: correct 2.0 architecture references (Postgres 17 + Redis 8, 3-container stack)

The docs and metadata still described the 1.x stack (SQLite, single container, p-queue). Update them to the current 2.0 reality.

- README: replace the broken single-container `docker run` quick-start with the real Docker Compose stack (app + Postgres 17 + Redis 8); fix the "no Redis, no Postgres" feature bullet
- package.json: description no longer claims a single container
- apps/docs: rewrite database.md for Postgres; configuration.md DB_PATH -> DATABASE_URL + REDIS_URL; architecture.md SQLite/p-queue/better-sqlite3 -> Postgres/BullMQ/pg and add media-engine + doc-engine; developer/security/deployment/docker-tags/getting-started/contributing compose examples now include postgres + redis; index.md + api/ai.md AI count 16 -> 19
- SECURITY.md: Drizzle (SQLite) -> (PostgreSQL)
- landing: enterprise/FeatureHighlights single-container wording; TrustSignals/ToolGrid 150+ -> 157 (dynamic); Pricing/FAQ 15 -> 19 AI tools

* docs(api): document all video, audio, document, and data tool endpoints in OpenAPI

The spec covered only image tools; the Scalar UI and the generated /llms.txt and /llms-full.txt inherited that gap. Add the 104 missing tool endpoints so the API docs match the code.

- Video: 29 endpoints (most long/async; auto-subtitles is AI)
- Audio: 17 (transcribe-audio is AI)
- Document/PDF: 36 (ocr-pdf is AI; conversions are long/async)
- Data: 10
- Image: 12 newer tools (background-replace, blur-background AI; histogram/lqip-placeholder/sprite-sheet custom responses; barcode-generate uses a JSON body)

Each schema is derived from the tool's Zod validator and executionHint (fast -> 200, long -> 202+SSE, AI adds 501 FeatureNotInstalledError, multi-file inputs as arrays), referencing the existing shared schemas. Tool path entries: 64 -> 168. Spec parses as valid YAML with no duplicate paths and only known $refs.
2026-06-16 18:04:52 +08:00
SnapOtter 9a61cb6af1 chore(deps-dev): bump the dev-deps group with 10 updates (#238)
Bumps @biomejs/biome, @testcontainers/postgresql, @testcontainers/redis,
@tailwindcss/vite, @types/node, @types/react, @types/yauzl, tailwindcss,
semantic-release, turbo.
2026-06-15 15:03:19 +08:00
SnapOtter c451b939c7 feat(jobs)!: SnapOtter 2.0 phase 2 job spine: async queues, worker pools, object storage, admin dashboard (#217) 2026-06-13 10:17:13 +08:00
SnapOtterandGitHub 1c724d5d21 feat(db)!: SnapOtter 2.0 phase 1 foundation: postgres, migrator, compose stack (#216)
* feat(infra): add dev compose stack with postgres and redis

* fix(infra): comment dev env defaults until wired; harden dev compose restart and start_period

* chore(deps): add pg driver and testcontainers for postgres migration

* feat(db): translate schema to drizzle pg-core (timestamptz, boolean, pgEnum, jsonb)

Schema translation (apps/api/src/db/schema.ts):
- sqlite-core -> pg-core, all 10 tables preserved 1:1
- integer(mode:'timestamp') -> timestamp({ withTimezone: true })
- integer(mode:'boolean') -> boolean
- jobs.status text enum -> pgEnum('job_status') with same 4 values
- 7 columns changed from text to jsonb: jobs.inputFiles, jobs.settings,
  pipelines.steps, apiKeys.permissions, roles.permissions,
  auditLog.details, userFiles.toolChain
- settings.value stays text, jobs.error stays text, jobs.progress stays real

jsonb call-site sweep (removed JSON.stringify on writes, JSON.parse on reads):
- apps/api/src/routes/roles.ts: permissions read/write (3 sites)
- apps/api/src/routes/api-keys.ts: permissions write + read (2 sites)
- apps/api/src/routes/audit-log.ts: details read (1 site)
- apps/api/src/routes/pipeline.ts: steps write + read (2 sites)
- apps/api/src/routes/progress.ts: inputFiles write (2 sites)
- apps/api/src/routes/tool-factory.ts: toolChain read + write (2 sites)
- apps/api/src/routes/user-files.ts: toolChain read + write (4 sites)
- apps/api/src/permissions.ts: roles.permissions read (1 site)
- apps/api/src/lib/audit.ts: details write (1 site)
- apps/api/src/plugins/auth.ts: apiKeys.permissions read (1 site)

* refactor(db): type jsonb columns via $type and note raw CTE conversion requirements

* feat(db): archive sqlite migrations and generate postgres baseline

* chore(db): dockerignore legacy migrations, add archive breadcrumb, fix trailing newline

* feat(db): pg pool connection, advisory-locked boot migrations, DATABASE_URL config

* fix(db): friendly fatal on unreachable postgres, idempotent closeDb, lock-key convention note

* refactor(db): async drizzle calls in plugins, lib, permissions

* fix(api): analytics never throws, typed permission guard, single-query session invalidation

* refactor(db): async drizzle calls across all routes and bootstrap

Convert every route file and index.ts from sync SQLite drizzle
patterns to async node-postgres drizzle:

- .all() removed (bare await on select)
- .get() converted to destructured [row] = await ...
- .run() removed (bare await on insert/update/delete)
- .changes replaced with .rowCount (null-guarded) in progress.ts
- sqlite import removed from user-files.ts; raw CTEs converted to
  await db.execute(sql`...`) with postgres-dialect recursive CTEs
- ChainRow types updated: tool_chain is parsed jsonb (string[] | null),
  created_at is Date (timestamptz) with no * 1000 conversion
- All requirePermission() guard calls awaited (security: unawaited
  async guard returns truthy Promise, bypassing permission check)
- All hasEffectivePermission() and getPermissions() calls awaited
- All auditLog() calls awaited (preserves write-before-response order)
- trackEvent() and captureException() left un-awaited (fire-and-forget
  by design, guaranteed never-throw)
- ensureAnonymousUser(), startCleanupCron(), recoverStaleJobs() awaited
  in bootstrap sequence
- ensureInstanceId() and ensureDefaultSettings() made async

Files converted: 14 (index.ts + 12 route files + tools/index.ts)

* fix(db): await async checkStorageQuota in user-files upload/save routes

* fix(db): await checkStorageQuota in save-result route (missed second call site)

* feat(db): sqlite-to-postgres migrator with CLI and first-boot import

* fix(db): migrator error context, honest force semantics, boot-hook fatal, null-variance tests

* test: run suite against per-file postgres databases via testcontainers

- Add tests/global-setup.ts: spins up a Postgres testcontainer,
  creates a migrated template database once per vitest run.
- Rewrite tests/setup/per-fork-env.ts: each test file (forks pool)
  clones the template into its own database via CREATE DATABASE ...
  TEMPLATE, preserving the same per-file isolation granularity.
- Update vitest.config.ts: add globalSetup, pg alias, update comment.
- Fix tests/integration/test-server.ts: remove DB_PATH mkdir, async
  runMigrations, async db operations, remove SQLite WAL checkpoint.
- Fix 21 unit test db/index mocks: add pool and closeDb exports.
- Fix 8 unit test files: add async/await for now-async permission,
  audit, and analytics functions.
- Fix 18 integration test files: convert sync .run()/.all()/.get()
  to async drizzle patterns, add async to callbacks.
- Production change: apps/api/src/routes/teams.ts: cast COUNT(*)
  to ::int so Postgres returns a number instead of bigint string.

* fix(db): seed built-in roles, reject NUL bytes, cast COUNT, serialize job persists

- Seed built-in roles (admin, editor, user) at boot via ensureBuiltinRoles()
  with onConflictDoNothing, restoring data that legacy SQLite migration 0007
  provided via INSERT statements (the pg baseline is DDL-only).
- Reject NUL bytes in login credentials with 401 (postgres rejects \x00 in
  text columns; valid usernames never contain NUL, matching 1.x behavior).
- Cast COUNT(*)::int in user-files, audit-log, and roles listing queries so
  postgres returns a JS number instead of bigint-as-string.
- Serialize fire-and-forget job progress DB writes per jobId so the final
  "completed" status is never overwritten by a late-arriving "processing"
  write (race condition exposed by async postgres round-trips).

* test: fix teams race, seed roles in test server, poll for job status

- Add missing await to resetTeams() in teams PUT beforeEach (the async
  delete raced with the subsequent insert under postgres).
- Call ensureBuiltinRoles() in test server bootstrap so integration tests
  have the same built-in roles as production.
- Replace fixed 100ms flushPersist delay with a polling helper that waits
  for terminal job status, eliminating timing-dependent failures caused by
  postgres network round-trip latency.

* test: make heic temp-file cleanup assertion resilient to concurrent workers

Use a set-based diff instead of raw file count when checking that
decodeHeic cleans up temp files. Other concurrent test workers can
create heic-in-*/heic-out-* files in the shared tmpdir, inflating the
"after" count and causing spurious failures under full-suite load.

* fix(db): align builtin-role seed to post-0010 legacy state; test polish

* feat(docker): three-container compose (app, postgres, redis) with boot wait and migrations

* fix(docker): set TEST_DATABASE_URL so containerized tests skip testcontainers

* chore(docker): test compose project name, clearer 1.x upgrade comment, unref probe timer

* feat(enterprise): enforce D15 license boundary; move s3 storage into packages/enterprise

* fix(enterprise): restore lazy aws-sdk loading; community installs load no s3 code at boot

* fix(enterprise): boundary check catches dynamic imports; document getS3 concurrency

* feat(db)!: SnapOtter 2.0 phase 1 foundation: postgres, migrator, compose stack

BREAKING CHANGE: SQLite is no longer the runtime database. Deployments now
require Postgres (and Redis, used from phase 2). Existing installs migrate
with SQLITE_MIGRATE_PATH or 'pnpm --filter @snapotter/api migrate:sqlite'.

* fix(ci): postgres service + fresh e2e database per run; ignore unfixable torch CVE-2025-3000
2026-06-13 10:15:23 +08:00
SnapOtterandGitHub 4ec39c556f test: testing overhaul -- CI e2e gates, parallel suites, generated matrices, mutation testing (#215)
Closes the "e2e never runs in CI" hole. Adds per-PR e2e smoke gate,
nightly full-suite workflows, parallel vitest forks (per-fork DBs),
Playwright parallel/serial/visual projects against production builds,
metadata-generated test suites (drift guards, hostile inputs, format
matrix, pairwise settings, property-based fuzz), Stryker mutation
testing, Schemathesis API fuzz, coverage ratchet, and fixes for three
session-poisoning bugs that caused 200+ serial-bucket failures.

Bug fix included: favicon/split/bulk-rename could hang clients forever
when ZIP streaming failed after reply.hijack().
2026-06-10 22:01:13 +08:00
SnapOtter 8792080982 fix(deps): patch Dependabot security alerts
- Pillow 11.1.0 -> 12.2.0 (6 CVEs: OOB writes, decompression bomb, DoS)
- rembg 2.0.62 -> 2.0.75 (SSRF + path traversal in server component)
- @fastify/static ^8.1.0 -> ^9.1.3 (path traversal + route guard bypass)
- Remove redundant @fastify/static pnpm override
- Dismiss stale esbuild alert (already at 0.28.0)
- Dismiss file-type alert (16.5.4 is dev-only via @types/potrace)
2026-06-10 19:08:08 +08:00
SnapOtter 012e2136ee fix(security): resolve 13 HIGH Trivy CVEs in npm dependencies
- Override glob>=10.5.0 (CVE-2025-64756 command injection)
- Override minimatch>=9.0.6 (CVE-2026-26996/27903/27904 ReDoS)
- Override tar>=7.5.11 (CVE-2026-23745/23950/24842/26960/29786/31802
  path traversal and arbitrary file overwrite)
- picomatch>=4.0.4 already overridden (CVE-2026-33671 ReDoS)
- Add .trivyignore for pnpm 9.x CVEs (CVE-2025-69262/69263) that
  require a major version bump to pnpm 10.x
- Restore Trivy as a blocking gate with trivyignore support
- Restore scan dependency in manifest job
2026-06-08 16:32:52 +08:00
SnapOtter 9931d6899c chore(release): 1.17.2 2026-06-08 14:45:44 +08:00
SnapOtter 1d7bc00d2d fix(docker): use CUDA 12.6 index for PaddlePaddle GPU and revert version
- fix(ocr): change paddlepaddle-gpu from --extra-index-url to --index-url
  for the CUDA 12.6 package index. With --extra-index-url, pip could
  resolve from PyPI (CUDA 11 build) instead of the cu126 index, causing
  "libcusolver.so.11: undefined symbol" errors on CUDA 12 containers.

- revert version to 1.17.1 (v1.17.2 release was deleted)
2026-06-08 14:36:59 +08:00
SnapOtter 9a1d3d25f4 fix(docker): resolve 4 release-blocking issues from validation
- fix(rate-limit): treat RATE_LIMIT_PER_MIN=0 as unlimited (50k/min)
  instead of blocking all requests. @fastify/rate-limit interprets
  max:0 as "allow zero requests," breaking fresh container startups.

- fix(docker): add libgles2 for MediaPipe face detection tools.
  blur-faces, red-eye-removal, enhance-faces, and passport-photo
  failed with "libGLESv2.so.2 not found" on all headless containers.

- fix(docker/arm64): remove conflicting system libheif1 to avoid
  ABI symbol mismatch with our custom libheif 1.21.2 build.
  heif-convert failed with "undefined symbol: heif_get_plugin_directories."

- fix(docker/arm64): pre-install wheel+setuptools in base Python venv
  so basicsr can build from source on arm64 (no pre-built wheel).
  This unblocks upscale-enhance and photo-restoration bundles.
2026-06-08 14:07:55 +08:00
SnapOtter 06d1822491 test: expand test coverage across all layers (+1,157 tests)
Fix 2 failing unit tests (landing hero text mismatch) and broken
coverage tooling (brace-expansion v5 override breaking minimatch).
Add ~1,097 new test cases via 14-agent parallel expansion:

- Unit: +290 tests (AI bridge, image-engine, stores, API helpers)
- Integration: +504 tests (all tools, cross-format matrix, adversarial)
- E2E: +363 tests (navigation, tool UI, batch/pipeline, settings,
  visual regression, accessibility, performance, cross-browser)

Total: 4,223 unit + 6,057 integration + 1,563 E2E = 11,843 tests
2026-06-06 19:37:29 +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
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
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0bfbe31fe0 chore(deps-dev): bump the dev-deps group with 13 updates (#147)
Bumps the dev-deps group with 13 updates:

| Package | From | To |
| --- | --- | --- |
| [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.4.8` | `2.4.15` |
| [@playwright/test](https://github.com/microsoft/playwright) | `1.58.2` | `1.60.0` |
| [@semantic-release/github](https://github.com/semantic-release/github) | `12.0.6` | `12.0.8` |
| [@semantic-release/release-notes-generator](https://github.com/semantic-release/release-notes-generator) | `14.1.0` | `14.1.1` |
| [jsdom](https://github.com/jsdom/jsdom) | `29.0.1` | `29.1.1` |
| [turbo](https://github.com/vercel/turborepo) | `2.8.20` | `2.9.14` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.19.15` | `22.19.19` |
| [@types/pdfkit](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/pdfkit) | `0.17.5` | `0.17.6` |
| [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.2.2` | `4.3.0` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.2.2` | `4.3.0` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `6.4.1` | `6.4.2` |
| [vitepress-plugin-llms](https://github.com/okineadev/vitepress-plugin-llms) | `1.12.0` | `1.12.2` |
| [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss) | `4.2.4` | `4.3.0` |

Updates `@biomejs/biome` from 2.4.8 to 2.4.15
- [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.15/packages/@biomejs/biome)

Updates `@playwright/test` from 1.58.2 to 1.60.0
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.58.2...v1.60.0)

Updates `@semantic-release/github` from 12.0.6 to 12.0.8
- [Release notes](https://github.com/semantic-release/github/releases)
- [Commits](https://github.com/semantic-release/github/compare/v12.0.6...v12.0.8)

Updates `@semantic-release/release-notes-generator` from 14.1.0 to 14.1.1
- [Release notes](https://github.com/semantic-release/release-notes-generator/releases)
- [Commits](https://github.com/semantic-release/release-notes-generator/compare/v14.1.0...v14.1.1)

Updates `jsdom` from 29.0.1 to 29.1.1
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Commits](https://github.com/jsdom/jsdom/compare/v29.0.1...v29.1.1)

Updates `turbo` from 2.8.20 to 2.9.14
- [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.8.20...v2.9.14)

Updates `@types/node` from 22.19.15 to 22.19.19
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/pdfkit` from 0.17.5 to 0.17.6
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/pdfkit)

Updates `@tailwindcss/vite` from 4.2.2 to 4.3.0
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/@tailwindcss-vite)

Updates `tailwindcss` from 4.2.2 to 4.3.0
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/tailwindcss)

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

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

Updates `@tailwindcss/postcss` from 4.2.4 to 4.3.0
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/@tailwindcss-postcss)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.4.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@playwright/test"
  dependency-version: 1.60.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: "@semantic-release/github"
  dependency-version: 12.0.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@semantic-release/release-notes-generator"
  dependency-version: 14.1.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: jsdom
  dependency-version: 29.1.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: turbo
  dependency-version: 2.9.14
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: "@types/node"
  dependency-version: 22.19.19
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@types/pdfkit"
  dependency-version: 0.17.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: tailwindcss
  dependency-version: 4.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: vite
  dependency-version: 6.4.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: vitepress-plugin-llms
  dependency-version: 1.12.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-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:41:09 +08:00
SnapOtterandGitHub ec6ff3d8a8 chore: harden OpenSSF Scorecard from 4.3 to ~7.0 (#142)
Token-Permissions (0 -> 10): Set permissions: {} at workflow top level
across all 7 workflows, moved write scopes to per-job minimum.

SAST (0 -> 10): Added CodeQL workflow for JavaScript/TypeScript and
Python analysis on push, PR, and weekly schedule.

Vulnerabilities (0 -> ~8): Added 13 pnpm overrides to patch transitive
dependency vulnerabilities (38 -> 2 remaining, both in dev-only tools).

Pinned-Dependencies (5 -> 8-9): Pinned all Docker FROM images to SHA
digests, pinned pip-audit version in CI, pinned pip version in
Dockerfile.
2026-05-18 15:57:17 +08:00
SnapOtter 398f65cd3f chore: add demo dir to gitignore and local wiki dev scripts 2026-05-18 10:20:04 +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 4e64ee2779 fix(security): comprehensive security audit and hardening
Auth: login rate limit 30/min (was 500), global rate limit 1000/min (was
unlimited), password/username max lengths on all Zod schemas, session
invalidation on role change, API key legacy scan bounded to 100 keys.

SVG: hardened regex sanitizer with CDATA stripping, XML entity decoding,
set/animate/iframe/embed blocking, comprehensive data: URI blocking,
use element external href blocking. 11 attack payload fixtures added.

SSRF: fixed DNS rebinding TOCTOU by pinning resolved IPs via custom
HTTP/HTTPS agents. Added 6to4 and NAT64 to blocked IPv6 ranges.

Docker: capability dropping (cap_drop ALL + minimal cap_add), resource
limits (4g/8g mem, 512/1024 pids), healthcheck timeout, password
removed from startup banner, default password warning comments.

Network: CSP and HSTS applied in all environments (not just production),
stack traces removed from all error responses, internal paths stripped
from error details, per-route rate limits on uploads (60/min) and URL
fetches (200/hour).

Files: exclusive temp file creation (O_EXCL), disk space circuit
breaker, per-user storage quotas, settings payload 64KB size guard.

Python sidecar: script name allowlist in dispatcher, minimal environment
for subprocess spawns.

Dependencies: fixed 6 production CVEs (drizzle-orm, fastify, fast-uri,
@fastify/static, next, archiver/lodash). Pinned all GitHub Actions to
SHA hashes.

114 security tests added. Full OWASP Top 10 penetration test matrix
verified against production Docker container (30/30 pass after
hardening).
2026-05-13 21:33:50 +08:00
SnapOtter 9f23a1b39f chore: bump version to 1.16.0 for Docker release
88 commits since v1.15.11 including feat commits.
2026-05-01 20:39:41 +08:00
SnapOtter fc8b549d78 fix: gate captureException on user consent and fix HEIC PII scrubbing
captureException now checks isRequestOptedIn before forwarding errors
to Sentry, closing a gap where server errors leaked to an external
service even when no user had consented. The PII scrubbing regex is
also fixed: he[ic]f? failed to match .heic due to word-boundary
behavior and is replaced with hei[cf]? which correctly covers .heic,
.heif, and .hei.

Adds 88 new analytics tests across unit, integration, and e2e layers
proving PostHog/Sentry are never invoked when analytics is disabled or
users have not consented, plus full 7-day reminder lifecycle coverage.
2026-04-29 23:47:19 +08:00
SnapOtter 7abcd5e26a test: add Playwright configs for landing and docs e2e tests 2026-04-27 21:51:56 +08:00
SnapOtter 8bc8b18f90 fix: version constant and CPU torch install for Docker release
- Bump APP_VERSION to 1.15.11 (was hardcoded at 1.15.9, causing
  health endpoint to report wrong version in Docker images)
- Fix cpu_fallback_packages() splitting --index-url into separate
  pip install arguments, breaking torch install on CPU-only amd64
2026-04-25 08:49:31 +08:00
SnapOtter 291e4092cd fix: make libmagickcore-extra conditional for multi-arch Docker builds
arm64 uses Debian bookworm (libmagickcore-6.q16-6-extra) while amd64
uses Ubuntu 24.04 (libmagickcore-6.q16-7-extra). Probing both variants
prevents build failures on the arm64 platform.
2026-04-25 07:32:02 +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 babca4cf97 test: comprehensive test coverage expansion (+965 tests)
Add 42 new test files covering all untested tool routes, image engine
internals, AI sidecar bridge, Zustand stores, and cross-format
compatibility. Expand e2e-docker suite with 7 spec files covering all
48 tools against a real Docker container.

Unit tests:
- Image engine: format detection, MIME mapping, metadata parsing, pipeline
- AI bridge: sidecar lifecycle, all 11 tool functions (mocked)
- Web stores: 14 Zustand stores (collage, settings, features, analytics, etc.)
- API helpers: format decoders, page range, file validation

Integration tests:
- 25 tool routes that had zero dedicated tests
- Cross-format matrix: 17 input formats x 3 tools
- Edge cases: zero-byte files, corrupted headers, path traversal, XSS, SQL injection
- Concurrent request handling and pipeline edge cases

E2E-Docker (Playwright against real container):
- 7 spec files: essential, adjustment, conversion, creative, utility, AI, pipeline
- Custom buildMultipart helper for multi-file tool uploads
- AI tools gracefully skip when sidecar not installed

Fixtures:
- Organized test media: formats/ (18 formats) + content/ (17 content types)
- Reduced from 3.1 GB unorganized samples to 33 MB structured fixtures

Bug fix:
- color-adjustments: gamma exposure used invalid single-param gamma() for
  positive values; fixed to use two-param gamma(gammaIn, gammaOut) form
2026-04-23 17:12:02 +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 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
fb33a46a64 feat: SOTA overhaul of automate pipeline page (#53)
* feat(find-duplicates): upgrade to 128-bit dHash with metadata and thumbnails

* feat(find-duplicates): add custom-results display mode and duplicate store

* feat(find-duplicates): add results overview grid and detail comparison view

* feat(find-duplicates): overhaul settings with sensitivity presets and download actions

* feat(find-duplicates): update i18n description

* chore: replace jsqr with zxing-wasm for barcode reading

* feat(barcode-read): rewrite backend with zxing-wasm for all barcode types

* feat(barcode-read): rewrite frontend with multi-file, results table, progress, export

- Multi-file sequential processing with per-file progress
- Structured results table with type badges and copy per-result
- Copy All and Export CSV functionality
- Thorough scan toggle (maps to tryHarder in zxing-wasm)
- Before/after view shows annotated image with bounding boxes
- Updated tool description in constants and i18n

* feat(stitch): update tool name and description for redesign

* feat(stitch): add grid layout, alignment, border, radius, quality, and new resize modes

* feat(stitch): redesign settings UI with grid, alignment, border, radius, quality

* test(stitch): add stitch to e2e tool navigation suite

* feat(vectorize): redesign with dual-engine backend and preset-driven UI

- Backend: potrace for B&W, VTracer (@neplex/vectorizer) for full-color vectorization
- Frontend: 5 presets (logo, illustration, photo, sketch, custom)
- Settings: color precision, gradient step, detail, smoothing, corner threshold, invert
- Updated OpenAPI spec and i18n description

* feat(border): redesign with presets, shadow, padding color, swatches

- Add 8 one-click presets (Clean White, Gallery Black, Shadow, Rounded, Polaroid, Vintage, Minimal, Cinematic)
- Implement proper shadow rendering with blur, offset X/Y, color, opacity
- Add padding color control (was hardcoded white)
- Add color swatches for quick color selection
- Wrap in form for Enter key submission
- Add smart validation (requires at least one effect active)
- Align frontend/backend slider ranges
- Organize UI with sections and collapsible shadow toggle

* feat(split): overhaul image splitting with live grid overlay and tile preview

- Add interactive-split display mode with SplitCanvas component
- Live SVG grid overlay on uploaded image showing split boundaries
- Two split modes: Grid (NxM) and Tile Size (px dimensions)
- 9 grid presets (2x1, 1x2, 2x2, 3x1, 1x3, 3x3, 2x3, 3x2, 4x4)
- Output format selection (original/PNG/JPG/WebP) with quality slider
- Post-split tile preview thumbnails with individual download
- Download All as ZIP button
- HEIC/HEIF preview with loading spinner
- Backend: tile-size mode, output format conversion, quality control
- Zustand store for split state management

* feat(split): rewrite backend and frontend settings

Backend: tile-size mode, output format conversion, quality control.
Frontend: split modes, presets, format selector, tile preview grid.

* feat(border): add live CSS preview and remove before/after slider

- Add imageWrapperStyle prop to ImageViewer for live border preview
- Add onImageStyle callback through tool-page to settings components
- Change border displayMode to no-comparison (no slider)
- BorderControls sends live CSS styles (border, padding, radius, shadow)
- Preview updates instantly as user adjusts sliders or clicks presets

* fix: repair i18n file corrupted by formatter during merge conflict resolution

* feat(border): enable live CSS preview in right pane as settings change

* fix(border): keep CSS preview visible after processing for WYSIWYG consistency

* chore: add @dnd-kit/core and @dnd-kit/sortable for pipeline drag-and-drop

* feat(pipeline): add Zustand store for pipeline step management

* feat(automate): add pipeline step settings summary utility with tests

* feat(automate): add POST /api/v1/pipeline/batch for multi-file pipeline execution

* feat(automate): add usePipelineProcessor hook for single and batch pipeline execution

* fix(automate): pass settings prop to all pipeline step controls for state restoration

* feat(automate): rewrite pipeline builder with dnd-kit drag-and-drop and compact step cards

* feat(automate): rewrite page with two-panel layout, image preview, and batch support

* test(automate): update e2e tests for new two-panel pipeline layout

---------

Co-authored-by: Siddharth Kumar Sah <siddharth123sk@gmail.com>
2026-04-13 16:26:38 +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
semantic-release-bot d4d421d3ff chore(release): 1.10.0 [skip ci]
# [1.10.0](https://github.com/stirling-image/stirling-image/compare/v1.9.0...v1.10.0) (2026-04-07)

### Features

* add content-aware resize API route and registration ([d464942](https://github.com/stirling-image/stirling-image/commit/d464942cd9a7c1fecc837a14211e3fc5030d5cee))
* add content-aware resize toggle to resize settings UI ([aace4ca](https://github.com/stirling-image/stirling-image/commit/aace4caf0c5b10059a31e9dff5476d11b34b4323))
* add seam carving AI bridge module ([d3b6462](https://github.com/stirling-image/stirling-image/commit/d3b646207d3312aea9e12cc9435649b039bc4ac8))
* add seam carving Python script with face protection ([1460ab7](https://github.com/stirling-image/stirling-image/commit/1460ab7a4ad8235714ebd72ab1f8092baa456032))
2026-04-07 16:11:15 +00:00
semantic-release-bot 14deda12b8 chore(release): 1.9.0 [skip ci]
# [1.9.0](https://github.com/stirling-image/stirling-image/compare/v1.8.1...v1.9.0) (2026-04-07)

### Features

* add stitch API route handler ([1716468](https://github.com/stirling-image/stirling-image/commit/171646886f678b0f98140d378e675443bc7c737f))
* add stitch settings UI component ([330bfcf](https://github.com/stirling-image/stirling-image/commit/330bfcf162deeb30fb573702b554d304500eebde))
* register stitch component in web tool registry ([7ec5d86](https://github.com/stirling-image/stirling-image/commit/7ec5d86d9123696e84ebeae603ec09ce4c1477d3))
* register stitch route in API tool registry ([66520cd](https://github.com/stirling-image/stirling-image/commit/66520cdd0ee49bbecffdb3e248c03d2763aa5d08))
* register stitch tool in shared constants and i18n ([fbbbe70](https://github.com/stirling-image/stirling-image/commit/fbbbe70a35a6cd3cbc389503cff3333b85392871))
2026-04-07 14:21:16 +00:00
semantic-release-bot c598230331 chore(release): 1.8.1 [skip ci]
## [1.8.1](https://github.com/stirling-image/stirling-image/compare/v1.8.0...v1.8.1) (2026-04-07)

### Bug Fixes

* add variant diagnostics to health endpoint and lite mode banner ([3be388e](https://github.com/stirling-image/stirling-image/commit/3be388e12f8bc6a35d30b1b94e2772f9e005bccd))
2026-04-07 10:35:05 +00:00
semantic-release-bot cd2db4afdd chore(release): 1.8.0 [skip ci]
# [1.8.0](https://github.com/stirling-image/stirling-image/compare/v1.7.7...v1.8.0) (2026-04-06)

### Bug Fixes

* filter unsafe round-trip keys server-side in editMetadata ([a430e91](https://github.com/stirling-image/stirling-image/commit/a430e913245f6c83194cc1e47c34a327d80840d5))

### Features

* add edit-metadata API route with inspect and edit endpoints ([5284d5e](https://github.com/stirling-image/stirling-image/commit/5284d5ece5dd393bf346f29d4d95b506f0c87c94))
* add edit-metadata UI component with granular strip support ([492eeb0](https://github.com/stirling-image/stirling-image/commit/492eeb0f962b50db598b5ac50cc9c2ceea9ce605))
* add EditMetadataOptions type and exif-reader dep to image-engine ([723c794](https://github.com/stirling-image/stirling-image/commit/723c79491ecbfc9795ba6bbdacc8e47caa903719))
* extract shared metadata parsing utilities into image-engine ([7fba05e](https://github.com/stirling-image/stirling-image/commit/7fba05e1dccb4fd370848bf6b20276a9edffbd86))
* implement editMetadata operation in image-engine ([939bb04](https://github.com/stirling-image/stirling-image/commit/939bb049413202a4df37d1affa3765cd9a41e9e2))
* register edit-metadata in shared constants and i18n ([6ac366b](https://github.com/stirling-image/stirling-image/commit/6ac366b1556b285c6764927267fcb3b885b90fe9))
2026-04-06 14:09:07 +00:00