Commit Graph
664 Commits
Author SHA1 Message Date
ashim-hq 37277e5c09 fix: resolve ONNX CUDA fallback, Docker e2e infrastructure, and all test failures
- Add safe_onnx_session() to gpu.py with graceful CUDA EP → CPU fallback
- Replace bare ort.InferenceSession() calls across colorize, restore, inpaint, remove_bg
- Add libcublas-12-6 to production Dockerfile for ONNX Runtime CUDA EP
- Add skipIfFeatureNotInstalled guards to remove-bg, blur-faces, smart-crop, ocr, noise-removal e2e specs
- Add AI tool install prompt detection in tools-all.spec.ts
- Add smart-crop to PYTHON_SIDECAR_TOOLS so frontend shows install prompt correctly
- Create Dockerfile.test.dockerignore to include tests/ in test image builds
- Add libheif-examples and exiftool to Dockerfile.test for HEIC and metadata tests
- Regenerate visual regression baselines for Docker/Linux and skip on non-Docker platforms
2026-04-20 20:53:54 +08:00
ashim-hq f67a03bb36 fix: resolve all audit findings — e2e coverage, feature system hardening, visual baselines
- Add 8 new E2E specs for AI tools (upscale, enhance-faces, colorize,
  restore-photo, erase-object, smart-crop, passport-photo, red-eye-removal)
  closing all HIGH/MEDIUM coverage gaps from the test matrix audit
- Fix ensureAiDirs() crash on non-Docker environments by gating on
  isDockerEnvironment() — prevents ENOENT when /data doesn't exist
- Bump torch 2.6.0→2.7.0 and torchvision 0.21.0→0.22.0 in feature
  manifest for broader Python version compatibility
- Add Python 3.14 version guard warning in install_feature.py
- Remove duplicate torchvision shims from upscale.py and enhance_faces.py
  (dispatcher.py already handles this at startup)
- Remove orphaned tools.batch i18n key and dead pipeline-builder filter
- Regenerate 4 visual regression baselines for current UI state
- Add data-testid to passport-photo generate button for E2E testability
2026-04-20 18:47:59 +08:00
ashim-hq e7eea34080 fix: resolve basicsr/torchvision shim bug, lint warnings, and code formatting
The torchvision compatibility shim for basicsr 1.4.2 was missing the
parent-package binding and only proxied a single attribute, causing
upscale and enhance-faces to fail at import time. The fix adds a
__getattr__ proxy for all attributes, binds the shim to the parent
package, and installs it in the dispatcher at startup for defense-in-depth.

Also removes unused anyInstalling variable, redundant `as any` cast,
and applies Biome formatting fixes across the codebase.
2026-04-20 17:03:17 +08:00
AshimandClaude Opus 4.6 39e27635c8 fix: audit fixes for cross-platform correctness
- Fix NameError in restore.py: face enhancement loop used undefined
  variable `i`, now uses enumerate()
- Fix gpu.py ONNX fallback: previous smoke-test with empty bytes
  always raised, making GPU detection unreachable via the ONNX path.
  Now uses nvidia-smi hardware check after confirming CUDA EP is
  compiled in — works on Linux, Windows, and gracefully fails on macOS
- Fix cpu_fallback_packages stripping CUDA-specific index URLs when
  replacing paddlepaddle-gpu with paddlepaddle for CPU-only systems

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 15:28:35 +08:00
AshimandClaude Opus 4.6 01d30cfb61 fix: pin torch cu126 for GPU compatibility and fix cross-platform bugs
- Pin torch==2.6.0+cu126 and torchvision==0.21.0+cu126 in feature
  manifest to prevent NCCL symbol mismatch on CUDA 12.6 base images
- Move lpips after torch in install order to prevent wrong version
  resolution from PyPI
- Add einops to upscale-enhance common deps (required by SCUNet)
- Update cpu_fallback_packages to handle multi-package CUDA torch
  entries on amd64 without GPU
- Fix gpu.py ONNX CUDA detection: replace hardcoded .so path with
  cross-platform session smoke-test
- Fix os.dup(1) crashes on Windows in upscale, enhance_faces, and
  noise_removal by wrapping in try/except with sys.stderr fallback
- Guard top-level numpy/cv2 imports in colorize.py and restore.py
  with helpful error messages
- Add weights_only=False fallback for torch.load in noise_removal
- Fix integration tests to accept 501 for uninstalled AI features
  and 422 for missing system tools (exiftool, libheif)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 15:17:08 +08:00
ashim-hq ac5fdfb841 fix: update e2e tests for current UI, increase timeouts for CPU environments, and fix auth bypass bug
- Fix SKIP_MUST_CHANGE_PASSWORD not affecting login/session API responses,
  causing frontend redirect even when the env var was set after user creation
- Increase Docker Playwright timeouts (test: 600s, expect: 60s, AI processing: 300s)
  to support CPU-only self-hosted environments
- Increase default rate limit from 100 to 50000 req/min for self-hosted deployments
- Fix OCR tests: use filechooser pattern (Dropzone has no static file input),
  correct enhance checkbox default, rewrite for actual fixture behavior
- Fix remove-bg tests: update quality labels (Balanced→HD, Best→Max)
- Fix noise-removal skip guard: use waitFor() instead of instant isVisible()
- Fix automate pipeline save test: clean up stale E2E pipelines before assertion
2026-04-20 15:03:56 +08:00
ashim-hq e20418c3e1 feat: enhance noise removal tool tests and update Docker configurations for GPU support 2026-04-20 12:27:07 +08:00
ashim-hq d3c3ce0e32 feat: update Docker configuration for improved GPU support and streamline service definitions 2026-04-20 11:11:40 +08:00
AshimandClaude Opus 4.6 6edb92c242 feat: add output filename suffixes, CPU fallback for GPU packages, and fix e2e tests
- Add tool-specific suffix to output filenames so downloads don't overwrite originals (batch & single-tool routes)
- Skip deleting shared models when uninstalling a bundle that shares models with another installed bundle
- Auto-detect NVIDIA GPU and swap GPU-only pip packages (onnxruntime-gpu, paddlepaddle-gpu) for CPU equivalents
- Refactor docker-compose with YAML anchors and explicit cpu/gpu profiles
- Add libheif-plugin-x265 to Dockerfile
- Fix install-all queue logic to handle concurrent individual installs and clear stale errors
- Unify playwright docker config to use same test dir with API_URL env var
- Fix flaky e2e selectors, rename Strip Metadata → Remove Metadata, handle collage custom dropzone, improve fallback test image generation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 10:56:47 +08:00
ashim-hq 92c0579a49 fix: resolve all a11y lint warnings in collage preview
Add proper ARIA roles and keyboard handlers to interactive overlays,
replace drag handle div with semantic button element.
2026-04-19 21:21:54 +08:00
ashim-hq 6202f9f69e fix: prevent progress bar from jumping backwards during install
The store set an initial 5% optimistically, then SSE sent real progress
starting from 0%, causing the bar to visibly drop. Now progress only
moves forward — both SSE and polling paths use Math.max to never
regress below the current value.
2026-04-19 21:20:01 +08:00
ashim-hq e4a73210ac chore: set compose project name to ashim
Shows as "ashim" in Docker Desktop instead of the directory name "docker".
2026-04-19 21:16:59 +08:00
ashim-hq b78e0741b3 fix: only show bundle counter in install indicator during batch install
The bottom-right install indicator showed "1/6 installed" even when
installing a single bundle, implying all 6 would be installed. Now the
counter only appears during "Install All" operations.
2026-04-19 21:15:17 +08:00
ashim-hq 62dd1ae211 refactor: unify feature install UI with global store, add healthcheck and GPU profile to compose
Replace FeatureInstallPrompt's local SSE/polling with useFeaturesStore
so install progress, errors, and recovery are handled globally — works
across navigation, logout/login, and partial downloads. Shows fun
progress messages and ETA matching the settings page.

Add compose healthcheck and optional GPU profile (--profile gpu).
2026-04-19 21:00:19 +08:00
ashim-hq fc98037eb1 fix: show loading spinner instead of error for HEIC preview, default fullscreen details to visible
Replace static "Preview not available" and "Cannot preview this image
format" messages with a loading spinner in ImageViewer and SplitCanvas,
since HEIC files get server-side conversion and the preview appears
after a few seconds. Also default showDetails to true on /fullscreen.
2026-04-19 20:38:51 +08:00
ashim-hq 5c897f3c1d fix: show download badge on home page inline tool list
The home page's file-uploaded view rendered its own tool list without
checking AI feature install status, so download icons disappeared after
uploading a file. Now both Quick Actions and All Tools sections show the
download badge consistently with the sidebar ToolPanel.
2026-04-19 20:20:53 +08:00
ashim-hq 8c83d7efcd fix: handle HEIC images in blur-faces and red-eye-removal, show warning when no faces detected 2026-04-19 19:52:23 +08:00
ashim-hq 10bdc24a4a feat: on-demand AI feature install with progress indicators 2026-04-19 19:52:14 +08:00
ashim-hq 771f786528 fix: ensure progress bar is visible for at least 800ms 2026-04-19 17:25:55 +08:00
ashim-hq 8495a0de2d feat: add progress bar to collage processing
Uses XMLHttpRequest upload progress to track image upload (0-80%),
then shows "Processing collage..." for the server-side compositing
phase (80-100%). Progress bar with percentage shown in the preview area.
2026-04-19 17:12:12 +08:00
ashim-hq 889ce1dd26 fix: make fit/fill toggle prominent with label, enlarge zoom controls 2026-04-19 17:04:11 +08:00
ashim-hq bc73078264 fix: fill cell background color when using contain fit mode 2026-04-19 16:52:29 +08:00
ashim-hq efede1ae4a fix: include objectFit in default cell transform fallback 2026-04-19 16:47:24 +08:00
ashim-hq bb241d6044 feat: add per-cell fit/fill toggle to collage tool
Adds objectFit property to CellTransform (cover/contain). When set to
"contain", the entire image is shown within the cell with background
color fill. Toggle button in the cell controls toolbar switches between
modes. Server-side rendering handles both modes via Sharp.
2026-04-19 16:41:35 +08:00
ashim-hq a7094f3fa4 fix: resolve collage UX bugs - broken pan, scroll zoom, control visibility
- Fix pan: use `movement` (cumulative) instead of `delta` (per-frame)
  in useDrag — delta accumulation against static memo was wrong
- Fix wheel zoom: replace useWheel with direct DOM addEventListener
  using { passive: false } so preventDefault() works and page doesn't
  scroll while zooming
- Fix controls: remove auto-hide timer, keep zoom slider and reset
  button visible while cell is selected
2026-04-19 16:27:45 +08:00
ashim-hq aaa807dae9 fix: address code review feedback on collage-preview
- Import CellTransform type instead of inline duplicate
- Remove unnecessary MutableRefObject cast (React 19)
- Restore biome-ignore for useSemanticElements on cell div
- Add role/aria-label to drag handle and zoom controls
- Remove fragile onPointerDown stopPropagation on drag handle
- Remove unused containerRef
2026-04-19 16:01:19 +08:00
ashim-hq e510708e16 feat: add use-gesture pan/zoom/pinch, dnd-kit reorder, visible controls, and HEIC spinner to collage 2026-04-19 15:56:02 +08:00
ashim-hq a8dd2d7422 feat: add HEIC preview support to collage store 2026-04-19 15:50:18 +08:00
ashim-hq 1a16b86a01 fix: add HEIC/HEIF extensions to file input accept attributes across tools 2026-04-19 15:49:37 +08:00
ashim-hq 7a29e6161e refactor: extract shared HEIC preview utility from file-store 2026-04-19 15:47:24 +08:00
ashim-hq db1137d94b chore: add @use-gesture/react for collage touch interactions 2026-04-19 15:46:02 +08:00
ashim-hq 12c4d4de6f fix: update tool installation checks and refactor stdout JSON parsing in AI modules 2026-04-19 12:13:26 +08:00
ashim-hq dc7ba119f8 Merge branch 'main' into feat/on-demand-ai-features 2026-04-18 12:19:42 +08:00
ashim-hq 15a63e57c3 chore: remove docs/superpowers from tracking (local-only) 2026-04-18 12:19:31 +08:00
ashim-hq 546cf52222 fix: install lock used server PID causing permanent stale lock
The lock file stored process.pid (Node server PID) which is always
alive. When releaseInstallLock wasn't called (e.g., error path),
the lock persisted forever, making the bundle stuck in "installing"
and blocking all future installs.

Fix: remove PID from lock entirely. Use simple file existence as
mutex. On server startup, unconditionally delete any lock file.
2026-04-18 11:39:20 +08:00
ashim-hq fa9c94f7ad fix: subscribe to bundles array reactively in ToolCard for download badge
The previous selector returned the isToolInstalled function reference
which never changes, so the component didn't re-render when bundles
loaded. Now subscribes to the bundles array directly via useMemo.
2026-04-18 11:34:22 +08:00
ashim-hq 46739a135e fix: use absolute path for install script (cwd is /app/apps/api in Docker) 2026-04-18 10:58:37 +08:00
ashim-hq 3eab3d5391 fix: tool page race condition on refresh and install error reporting
- Subscribe to features store reactively in ToolPage so refresh shows
  install prompt correctly instead of the tool UI
- Show loading state while features are being fetched for AI tools
- Capture stdout from install script for better error messages
- Keep last 20 stderr lines for error context instead of just exit code
- Clear install progress on success (was leaving stale state)
- Pass PIP_CACHE_DIR to install subprocess
2026-04-18 10:55:22 +08:00
ashim-hq 3b2612ac72 fix: don't send Content-Type: application/json with empty POST body 2026-04-18 10:48:20 +08:00
ashim-hq 2a94cdc024 fix: add FEATURE_NOT_INSTALLED guard to all 10 remaining AI tool routes
The guard was only present on restore-photo.ts and the createToolRoute
factory. All other AI tools used custom route handlers that bypassed
the check entirely, allowing requests to reach the Python sidecar even
when the feature bundle was not installed. This adds an early 501
response before any multipart parsing or file processing.
2026-04-18 10:23:14 +08:00
ashim-hq d7b6037b3d fix: use MODELS_PATH env var for AI model paths instead of hardcoded /opt/models
The on-demand feature download system stores models at /data/ai/models/
(set via MODELS_PATH env var), but all Python scripts hardcoded
/opt/models/ as the base path. Each script now reads MODELS_PATH and
falls back to /opt/models for backward compatibility.
2026-04-18 10:17:01 +08:00
ashim-hq 28462c8f60 test: add comprehensive feature bundle tests (e2e + unit edge cases)
E2E tests cover feature API responses, tool route 501 guards for all 11
AI tools, batch endpoint guards, and GUI interactions (install prompt,
settings panel, sidebar badges). Unit tests add edge cases for duplicate
tool detection, unknown bundle/tool lookups, and TOOL_BUNDLE_MAP integrity.
2026-04-18 03:01:18 +08:00
ashim-hq b259f765de feat: strip ML packages from Docker image, bootstrap AI venv on first run
Remove all ML pip installs (onnxruntime, rembg, realesrgan, paddlepaddle,
mediapipe, codeformer), model downloads, and post-install fixups from the
Dockerfile. The base image now ships only Node.js + Sharp + Python with
numpy/Pillow/opencv. AI features are installed on-demand at runtime via
the feature manifest and install_feature.py script.

Key changes:
- Remove SKIP_MODEL_DOWNLOADS build arg (no longer needed)
- Remove apt-get purge of build-essential (needed for runtime pip installs)
- Remove PaddleX symlinks and facexlib weight directory setup
- Add COPY of feature-manifest.json and install_feature.py
- Update PYTHON_VENV_PATH to /data/ai/venv, add MODELS_PATH and DATA_DIR
- Entrypoint bootstraps AI venv from /opt/venv on first container start
  with crash-safe temp directory pattern
2026-04-18 02:57:47 +08:00
ashim-hq 645324cde6 feat: add AI Features settings panel for managing feature bundles 2026-04-18 02:54:44 +08:00
ashim-hq 6e9a79191a feat: add FeatureInstallPrompt component for uninstalled AI tool pages
Show an install prompt instead of the normal tool UI when an AI feature
bundle is not installed. Admins see a one-click install button with SSE
progress tracking and polling fallback; non-admins see a message to
contact their administrator.
2026-04-18 02:50:56 +08:00
ashim-hq fe1ae8436d feat: add download badge to uninstalled AI tools in tool grid
Show a download icon on AI tools that are not yet installed, and fetch
feature status on mount in both the sidebar tool panel and fullscreen
grid page.
2026-04-18 02:47:42 +08:00
ashim-hq 0b9c760e5e feat: add frontend features store and FEATURE_NOT_INSTALLED error handling
Add Zustand features store for tracking AI feature bundle state with
fetch, refresh, isToolInstalled, and getBundleForTool methods. Extend
parseApiError to return structured FeatureNotInstalledError objects
when the backend returns FEATURE_NOT_INSTALLED, and handle them in
both tool and pipeline processor hooks with user-friendly messages.
2026-04-18 02:45:43 +08:00
ashim-hq 494bb3d78b feat: add feature gating to Python sidecar dispatcher
Check installed.json before exec()-ing AI scripts so that requests
for uninstalled feature bundles return a structured error instead
of crashing with an ImportError. Also sets U2NET_HOME to the
bundled model directory when present.
2026-04-18 02:42:34 +08:00
ashim-hq 3c3aa74e98 feat: add FEATURE_NOT_INSTALLED guards to API tool routes
Return 501 with structured error when an AI tool's feature bundle
is not installed, preventing Python ImportError crashes. Guards
added to tool-factory, batch, pipeline (both validation loops),
and restore-photo custom route.
2026-04-18 02:40:16 +08:00
ashim-hq 7ffbd5e3c6 feat: add Python install script for on-demand AI feature bundles
Reads the feature manifest, installs pip packages (common + arch-specific),
downloads models in parallel with atomic rename, and writes installed.json.
Includes disk space pre-check, NCCL conflict handling, retry logic, and
progress reporting via stderr JSON lines. Also updates the feature route
to pass manifestPath and modelsDir as CLI arguments.
2026-04-18 02:37:43 +08:00