Several RBAC features from feat/rbac-permissions were silently lost
during the merge into main. This restores and completes them:
- Add permissions and teamName to login/session API responses
- Export Permission and Role types from shared package
- Filter settings tabs by user permissions in frontend
- Extend useAuth hook with role, permissions, and hasPermission
- Restrict teams listing to admin only
- Add admin override for API keys, files, and pipelines listing
- Add ownership scoping to file access, download, and delete routes
- Register userFileRoutes in integration test server
- Mock auth import in unit permissions test to avoid SQLite lock
Replace requireAuth with requirePermission("pipelines:own") on pipeline
save/list/delete routes. Admin users with pipelines:all can see and
delete all pipelines. Unauthorized delete returns 404 to avoid leaking
resource existence.
Migrate settings, teams, branding, and user management routes to use
the new permission-based authorization system. Remove requireAdmin
function entirely.
Create the RBAC permission module that maps roles to permissions and
provides a requirePermission middleware to replace requireAdmin. Update
the test server to use requirePermission for the admin health check.
Merge CPU, CUDA, and lite Docker images into a single unified image.
One tag (latest) works on all platforms: amd64 (NVIDIA CUDA) and arm64 (CPU).
GPU auto-detected at runtime. All ML models and packages baked in.
Key changes:
- Platform-conditional Dockerfile (nvidia/cuda on amd64, node on arm64)
- tini as PID 1 for proper signal handling
- Fix FILES_STORAGE_PATH data loss bug
- Fix RealESRGAN upscaler (was broken, always fell back to Lanczos)
- Fix PaddleOCR language codes and stdout corruption
- Simplified CI/CD (single build, single tag)
- Expanded model pre-download with verification
- Shutdown timeout, improved health endpoint
- Remove unused lama-cleaner
Replace static llms.txt and llms-full.txt with auto-generated versions
that stay in sync with docs on every build. The plugin also generates
per-page .md files for individual page fetching by LLMs.
Users running lite mode had no way to tell why AI tools were greyed out.
Now the public health endpoint reports the variant, and a visible banner
appears in the tool panel when running in lite mode.
- Replace OpenCV Haar Cascades with MediaPipe for face detection, using
short-range model first with full-range fallback for better accuracy
- Add auto-orient to remove-background route for EXIF-rotated photos
- Change default background removal model from u2net to birefnet-general-lite
- Fix flaky test by setting SQLite busy_timeout before journal_mode pragma
Co-authored-by: Siddharth Kumar Sah <siddharth123sk@gmail.com>
Batch progress was broken because JobProgress events lacked a `type`
field. The frontend checks `data.type === "batch"` to distinguish batch
from single-file SSE events, so batch progress was silently discarded
and multi-file processing appeared stuck at 15%.
Also improves the processing UX for non-AI (Sharp-based) tools: the
progress bar now pulses during the server processing phase and shows
a "This may take a moment" hint after 10 seconds.
Co-authored-by: Siddharth Kumar Sah <siddharth123sk@gmail.com>
AI routes (remove-background, erase-object, ocr, blur-faces, upscale)
were silently swallowing errors - failures returned HTTP 422 to the
client but never appeared in server logs. This made it impossible for
self-hosters to diagnose issues like 504 timeouts from reverse proxies.
Adds request.log.info() at processing start (tool name, image size, key
settings) and request.log.error() in catch blocks, matching the existing
tool-factory pattern.
Co-authored-by: Siddharth Kumar Sah <siddharth123sk@gmail.com>
* feat: add resolveOutputFormat utility for input format preservation
* fix: preserve file order in batch processing with X-File-Results header
Collect all results before streaming the ZIP to guarantee upload order.
Replace X-File-Order with index-based X-File-Results header that maps
each upload index to its processed filename, handling failures and
duplicate filenames correctly.
Closes#13
* fix: use X-File-Results for index-based batch file matching
The frontend now matches processed files to entries by upload index
instead of fragile name/position matching.
* feat: preserve input format in smart-crop with quality control
Smart crop now outputs in the same format as the input (JPG in, JPG out)
instead of always converting to PNG. Adds an optional quality setting
(default 95) for lossy formats.
Closes#14
* feat: add output quality slider to smart crop settings UI
* feat: preserve input format in crop tool
* feat: preserve input format in color adjustment tools
Applies to brightness-contrast, saturation, color-channels, and
color-effects tool routes.
* refactor: avoid double encode in smart-crop content mode
For the simple trim path (no pad-to-square), chain .toFormat() on the
trim pipeline directly instead of creating a second Sharp instance.
This eliminates a redundant intermediate encode that degraded quality
for lossy formats. Also use trimmed.info dimensions instead of a
separate metadata() call for the pad-to-square path.
---------
Co-authored-by: Siddharth Kumar Sah <siddharth123sk@gmail.com>
Clickable localhost:1349 links are misleading on the GitHub Pages site
since users may not have Stirling Image running locally. Use plain path
references instead so it is clear these live on their own instance.
The links used /Stirling-Image/ (wrong casing) which VitePress then
prefixed with the base /stirling-image/, producing a double-prefixed
404 path. Remove the manual base so VitePress prepends it automatically.