Commit Graph
1003 Commits
Author SHA1 Message Date
SnapOtter 79897fcdb0 test: fix brush test assertion for hardness visibility 2026-05-07 19:22:50 +08:00
SnapOtter 8208acfb78 fix: restore missing text options and font loader, wire text tool options bar, fix e2e test selectors 2026-05-07 19:13:36 +08:00
SnapOtter 3cc4ec87d7 fix: resolve 15 critical/high/medium issues from self-review
CRITICAL fixes:
- #14: Render source image on canvas via Konva Image + use-image hook
- #3: Wire move tool handlers (onClick, onDragEnd, onTransformEnd, draggable)
  to all CanvasObjectRenderer shapes
- #4: Implement image object rendering for fill/gradient output
- #2: Show fallback text in histogram panel when no imageData provided
- #1: Forward all args in zundo handleSet debounce wrapper

HIGH fixes:
- #5: Track raw screen cursor position for brush overlay instead of
  using canvas-space coordinates
- #6: Export dialog uses Konva stage.toDataURL via module-level ref
  instead of DOM querySelector for correct export at any zoom/pan
- #7: Add _historyVersion increment to setAdjustment, resetAdjustments,
  toggleFilter, and setFilterParam for undo tracking
- #8: Include lastAction in partialize so history labels display correctly

MEDIUM fixes:
- #10: Move useEditorShortcuts from EditorCanvas to EditorPage with
  save/export callbacks
- #11: Remove _historyVersion increment from updateObject to prevent
  brush strokes from flooding undo history
- #12: Apply Konva filters (Brighten, Contrast, HSL, Blur, Grayscale,
  Sepia, Invert, Pixelate, Emboss, Posterize, Noise, Solarize,
  Threshold, Kaleidoscope) to source image node based on store state
2026-05-07 10:00:12 +08:00
SnapOtter e11e3660d9 test: add editor E2E test specs 2026-05-07 09:29:01 +08:00
SnapOtter 4a96d4b217 test: add editor store and types unit tests (161 tests) 2026-05-07 09:27:47 +08:00
SnapOtter 76501c4fb3 feat: add editor polish (mobile handling, loading states, accessibility)
- Show desktop-recommended message on mobile viewports (<768px)
- Add LoadingOverlay component for canvas loading/progress states
- Add ARIA tablist/tab/aria-selected to right panel tabs
- Add "Open in Editor" link in review panel after tool processing
2026-05-07 09:16:20 +08:00
SnapOtter 791bc2d3ce feat: wire editor options bar, right panel, and canvas rendering 2026-05-07 09:12:03 +08:00
SnapOtter f0941e4aec fix: resolve type errors in selection/crop/transform tools 2026-05-06 23:37:31 +08:00
SnapOtter 0f42ceca83 Merge branch 'worktree-agent-a82b6128' into feat/image-editor
# Conflicts:
#	apps/web/package.json
#	apps/web/src/stores/editor-store.ts
#	apps/web/src/types/editor.ts
#	pnpm-lock.yaml
2026-05-06 23:30:42 +08:00
SnapOtter 01dcfa624b feat: add selection, crop, transform tools and supporting infrastructure for image editor
Implements Agent 2 deliverables for the image editor: move tool with Konva
Transformer and smart guide snapping, rectangular/elliptical marquee and
lasso selection with marching ants animation, magic wand flood fill, crop
tool with darkened overlay and rule-of-thirds grid, free transform with
numeric inputs, context menu with z-ordering and clipboard operations,
rulers with drag-to-create guides, smart alignment guides, and canvas/image
resize dialogs. Also creates the shared editor types and Zustand store with
full layer management, z-ordering, clipboard, guide, and document operations.
2026-05-06 23:29:29 +08:00
SnapOtter 1d59997db5 Merge branch 'worktree-agent-a39efeb4' into feat/image-editor
# Conflicts:
#	apps/web/src/components/editor/editor-right-panel.tsx
2026-05-06 23:29:25 +08:00
SnapOtter 2ae97a6c88 feat: add history panel, keyboard shortcuts, export dialog, and navigator minimap
Implement Agent 7 features for the image editor:
- History panel with undo/redo list, action icons, and state jumping
- 51+ keyboard shortcuts via react-hotkeys-hook (tools, modifiers, clipboard)
- Export dialog with PNG/JPEG/WebP format, quality, resize, clipboard copy
- Navigator minimap with viewport rectangle, drag-to-pan, zoom slider
- Autosave/recovery system with localStorage and recovery banner
- Project save/load (.snapotter JSON format)
- Unsaved changes warning via beforeunload
- Paste from system clipboard support
2026-05-06 23:28:29 +08:00
SnapOtter 7c5bd10e80 Merge branch 'worktree-agent-ac1b61d3' into feat/image-editor 2026-05-06 23:24:55 +08:00
SnapOtter 87bbf2f889 feat: add drawing and shape tools for image editor
Implement 8 tool hooks, 7 options bar components, and 1 fill dialog:

Tools:
- Brush: Konva.Line with smooth strokes, hardness via shadowBlur
- Eraser: brush with globalCompositeOperation destination-out
- Shape: Rectangle, Ellipse, Line, Arrow, Polygon, Star with Shift constraint
- Fill (Paint Bucket): scanline flood fill with tolerance and contiguous mode
- Gradient: linear/radial via drag gesture on offscreen canvas
- Clone Stamp: Alt+click source, paint cloned pixels with aligned mode
- Dodge/Burn/Sponge: per-pixel brightness/saturation manipulation by range
- Pixel Brush: blur (box blur), sharpen (unsharp), smudge (directional blend)

Options bars:
- Brush: size/opacity/hardness sliders
- Shape: type selector, fill/stroke color, stroke width, corner radius, sides
- Fill: tolerance slider, contiguous checkbox
- Gradient: linear/radial toggle, opacity, reverse
- Clone Stamp: size/opacity/hardness, aligned toggle
- Dodge/Burn: tool toggle, range dropdown, exposure/flow sliders
- Pixel Brush: tool toggle, size, strength

Common:
- Fill Dialog: Shift+Backspace modal with foreground/background/color/white/black/50% gray
2026-05-06 23:24:34 +08:00
SnapOtter 6238925c38 Merge branch 'worktree-agent-a87ea474' into feat/image-editor 2026-05-06 23:24:09 +08:00
SnapOtter c4bcb12173 feat: add adjustments, filters, levels, curves, histogram, and effects panels for image editor
Implements Features 17, 18, 35, 36, 41, 42, 43 for the editor:
- SliderRow reusable component (label + range + numeric input)
- AdjustmentsPanel with 8 adjustment sliders (brightness, contrast,
  hue, saturation, luminance, exposure, vibrance, warmth)
- Auto adjustments: Auto Tone, Auto Contrast, Auto Color, Auto Enhance
- Levels section with per-channel control, histogram display, black/white
  point, gamma, and output range sliders
- Curves section with 200x200 interactive graph, cubic spline
  interpolation, per-channel support, and 9 presets
- 12 filter controls: toggle (grayscale, sepia, invert, solarize) and
  slider (blur, sharpen, noise, pixelate, emboss, posterize, threshold,
  kaleidoscope)
- Additional blur types: motion blur, radial blur, surface blur
- Vignette with amount/midpoint/roundness/feather sliders
- Grain with amount/size/roughness sliders
- HistogramPanel with RGB channel overlays and stats (mean, stddev, median)
- Reset All and Apply action buttons
- 150ms debounce on adjustment sliders, 300ms on histogram updates
2026-05-06 23:23:45 +08:00
SnapOtter 7e2a7adbd2 Merge branch 'worktree-agent-af61ea3e' into feat/image-editor 2026-05-06 23:23:24 +08:00
SnapOtter a9547f5944 feat: add color system panel, eyedropper tool, and color swatch components
Color panel with foreground/background swatches, react-colorful picker
popover, HEX/RGB/HSL input modes, recent colors row, swap (X) and reset (D).
Eyedropper tool samples composited pixels via stage.toCanvas() with 1x1/3x3/5x5
sample size options, alt+click for background color.
2026-05-06 23:23:05 +08:00
SnapOtter fedb7bc2e3 feat: add layers panel with blend modes, effects, and drag reorder
Implements the layer management panel for the image editor (Features 16, 40):
- Blend mode dropdown (16 modes) and opacity slider for active layer
- Layer list with visibility/lock toggles, thumbnails, and inline rename
- Pointer-based drag reorder (not HTML5 drag API)
- Right-click context menu: Duplicate, Merge Down, Flatten All, Delete
- Layer effects section: Drop Shadow, Inner Shadow, Outer Glow, Stroke
- Each effect with enable/disable toggle and full parameter controls
- Wired into EditorRightPanel as the "Layers" tab content
2026-05-06 23:22:24 +08:00
SnapOtter 9eae8369bb feat: wire editor route, sidebar, mobile nav, and i18n 2026-05-06 23:14:30 +08:00
SnapOtter 08a2119564 feat: add editor layout components, welcome screen, and editor page
Create the four-zone editor layout shell (toolbar, options bar, status
bar, right panel), welcome screen with drag-and-drop and new document
dialog, and the main editor page with clipboard paste and URL loading.
2026-05-06 23:12:59 +08:00
SnapOtter 155783ca86 feat: add canvas system and utility components for image editor
Create canvas zoom hook with smooth Konva.Tween transitions, icon button
component, cursor management with brush overlay, and editor canvas with
checkerboard background, ResizeObserver sizing, and grid overlay.
2026-05-06 23:08:32 +08:00
SnapOtter eb6f3c33ac feat: add image editor type definitions and zustand store
Add complete type system for the editor (ToolType, CanvasObject, EditorLayer,
EditorState, etc.) and the central Zustand store with zundo undo/redo middleware,
50-entry history limit, 500ms throttle, and O(1) _historyVersion equality checks.
2026-05-06 23:05:33 +08:00
SnapOtter 711ddf8deb chore: add konva, react-konva, and editor dependencies 2026-05-06 23:01:47 +08:00
SnapOtter c9b24ada78 ci: add Trivy container vulnerability scan to release pipeline
Scans the amd64 Docker image for CRITICAL/HIGH CVEs with available fixes
before publishing multi-arch manifests. Results upload to GitHub Security tab
as SARIF. Blocks release if fixable vulnerabilities are found.
2026-05-06 22:39:49 +08:00
SnapOtter 7d081b5081 fix: replace Discord member count badge with static join badge 2026-05-06 22:03:43 +08:00
SnapOtter d705c863e3 Merge feat/transparency-fixer: add PNG Transparency Fixer tool
New AI-powered tool that fixes fake transparent PNGs in one click.
Uses BiRefNet HR-matting (2048x2048) with Sharp defringe post-processing.
2026-05-06 21:57:46 +08:00
SnapOtter 371cd6f485 chore: remove temporary Docker playwright config 2026-05-06 21:57:34 +08:00
SnapOtter dabab32798 Merge fix/121-qr-logo-not-working: QR code logo causes preview to vanish
fix: QR code logo causes preview to vanish and become unrecoverable

The QR code generator's logo feature was broken in production (Docker)
due to three interacting issues:

1. The CSP connect-src directive did not include data:, so the
   qr-code-styling library's internal XHR to convert logo data URLs to
   blobs was silently blocked.

2. crossOrigin: "anonymous" was unnecessarily set on imageOptions for
   data URLs.

3. The logo options used a conditional spread that omitted the image key
   when no logo was set, but the library's deep merge preserved the
   stale data URL.

Closes #121
2026-05-06 21:41:29 +08:00
SnapOtter 8f9ba701be fix: QR code logo causes preview to vanish and become unrecoverable
The QR code generator's logo feature was broken in production (Docker)
due to three interacting issues:

1. The CSP connect-src directive did not include data:, so the
   qr-code-styling library's internal XHR to convert logo data URLs to
   blobs was silently blocked. The library has no onerror handler, so the
   render promise hung forever after the container was already cleared.

2. crossOrigin: "anonymous" was unnecessarily set on imageOptions for
   data URLs, which can cause canvas taint issues.

3. The logo options used a conditional spread that omitted the image key
   when no logo was set. The library's update() deep-merges options, so
   removing the logo preserved the stale data URL and the QR stayed
   broken even after logo removal.

Closes #121
2026-05-06 21:38:12 +08:00
SnapOtter 84e62e6132 refactor: rename tool display name to "PNG Transparency Fixer" 2026-05-06 18:53:37 +08:00
SnapOtter c47ec34021 fix: show tool name instead of bundle name in install prompt, add queued state 2026-05-06 18:47:34 +08:00
SnapOtter c0550fb2cf fix(ci): ignore 3 new Pillow CVEs blocked by ML dependency constraints
Pillow 11.1.0 has CVE-2026-42308, CVE-2026-42310, CVE-2026-42311
(fixed in 12.2.0). Upgrading to Pillow 12.x requires validating
compatibility with rembg, realesrgan, mediapipe, and codeformer.
2026-05-06 10:40:30 +08:00
SnapOtter 75e48f2738 test: add transparency-fixer to GUI AI tools and tools-all E2E tests 2026-05-06 10:39:15 +08:00
SnapOtter eb3d0828cb docs: add transparency-fixer endpoint documentation 2026-05-05 23:24:22 +08:00
SnapOtter 4745e435a4 test: add Playwright E2E tests for transparency-fixer tool 2026-05-05 23:17:24 +08:00
SnapOtter c263834037 test: add integration tests for transparency-fixer tool 2026-05-05 23:14:42 +08:00
SnapOtter 52f355ef8f feat: register transparency-fixer in frontend tool registry 2026-05-05 23:09:15 +08:00
SnapOtter 06d6c0ef1e feat: add transparency-fixer settings component 2026-05-05 23:09:10 +08:00
SnapOtter b1959e977d fix: improve defringe quality and add defensive guards in transparency-fixer 2026-05-05 23:07:14 +08:00
SnapOtter 423711ac42 feat: add transparency-fixer API route with defringe post-processing 2026-05-05 23:03:07 +08:00
SnapOtter d5a808dbc7 feat: register transparency-fixer in shared constants, features, and i18n 2026-05-05 22:58:30 +08:00
SnapOtter 9db19a01a2 feat: add BiRefNet HR-matting model download and manifest entry 2026-05-05 22:56:31 +08:00
SnapOtter a329dac004 fix: guard against division-by-zero in HR-matting predict and register session in installer
The BiRefNetHRMattingSession.predict normalization crashes when all
pixels share the same value (ma == mi). Use a guarded denominator so
uniform-alpha inputs produce a zero mask instead of a NaN explosion.

Also adds _register_birefnet_hr_matting() to install_feature.py so the
HR-matting model can be downloaded during feature installation, matching
the existing registration in remove_bg.py.
2026-05-05 22:54:43 +08:00
SnapOtter a44f6c7592 feat: add BiRefNet HR-matting model support for transparency fixer 2026-05-05 22:49:41 +08:00
SnapOtter 563c420d86 ci: add workflow_dispatch trigger to CI workflow
Allows manual re-runs when GitHub-hosted runners are unresponsive.
2026-05-05 22:46:39 +08:00
SnapOtter 5e45cb292b test: increase QR max-size test timeout to 180s for CI
The 10000x10000 QR generation exceeds 120s on GitHub-hosted runners.
2026-05-05 22:31:53 +08:00
SnapOtter 83fa0a39dc test: add fake transparency PNG fixture for transparency-fixer tool 2026-05-05 21:50:43 +08:00
SnapOtter d46510138f fix: custom logo not showing in sidebar and silent upload failures
The desktop sidebar never rendered the custom logo because only mobile
views used the customLogo state. Added a logo section at the top of
the desktop sidebar that displays the custom logo (or the default
OtterLogo when none is set).

The upload handler used raw fetch() without checking response.ok, so
HTTP 4xx errors (e.g. file too large) were silently ignored and the UI
falsely reported success. Now checks response status and surfaces the
server error message.

Closes #125
2026-05-05 21:45:51 +08:00
SnapOtter f856c26fcb fix: upscale tool times out on CPU-only systems (NAS/low-power hardware)
The upscale function called runPythonWithProgress without a timeout parameter,
defaulting to the bridge's 10-minute hard limit. On CPU-only systems like
Synology NAS devices, Real-ESRGAN 4x upscaling easily exceeds this for modest
images. Additionally, when the timeout fired on the dispatcher path, the Python
process was left running and blocked all subsequent AI operations.

This fix adds an adaptive timeout based on input megapixels, scale factor, and
GPU availability (180s/effective-MP on CPU, 30s/effective-MP on GPU, floor of
10 minutes). It also kills the dispatcher on timeout so subsequent requests can
proceed via a fresh restart.

Closes #119
2026-05-05 21:14:56 +08:00