Lucide v0.577 dropped Wand2 and Columns from the icons object used
for dynamic lookup. Named exports still exist as aliases, but the
landing site and tools index use icons[name] which fails silently.
Updates shared constants and web app icon-map to use the current names.
- Add /tools hub page listing all 52 tools grouped by category with
CollectionPage + ItemList schema markup
- Include /tools in dynamic sitemap at priority 0.9
- Fix Features and Pricing nav links using relative anchors (#features,
#pricing) that broke on subpages by prefixing with /
* feat: add 52 per-tool SEO landing pages and public changelog
- Create individual landing pages for all 52 tools at /tools/{slug}
with search-intent title tags, unique FAQs (156 Q&As), per-tool
features, and rich schema markup (BreadcrumbList, WebApplication,
HowTo, FAQPage)
- Replace static sitemap.xml with dynamic generation including all
tool URLs
- Refactor bento grid to import from @snapotter/shared (eliminates
330 lines of duplicated tool data) and link cards to tool pages
- Add @snapotter/shared as workspace dependency to landing site
- Add public changelog page to docs site with curated release notes
from v1.8 through v1.17
- Update docs nav and sidebar with changelog link
* feat: enhance SEO and performance with updated metadata, robots.txt, and llms.txt
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.
Sharp can read HEIF container headers (metadata succeeds) but cannot
decode HEVC pixels (stats fails with "No decoding plugin installed").
Unconditionally pre-decode HEIF files via heif-dec CLI before any Sharp
operations, matching the createToolRoute factory behavior.
Render custom background layers (solid color, image, checkerboard) and
drop shadow in the after panel, constrained to the actual image content
area. Supports remove-bg tool preview effects.
Handle OOM kills (exit code 137) with actionable memory guidance,
filter ANSI/progress noise from error output, add --no-cache-dir to
pip installs, reduce download concurrency to 2, and bump default
container memory from 4g to 6g.
Only show "X% smaller/larger" badges on compress and optimize-for-web
where file size reduction is the goal. All other tools no longer display
irrelevant size percentage data in the results pane.
- New apps/demo/ that reuses apps/web components with mocked API layer
- Full UI shell: login, change password, analytics consent, dashboard, all tool pages
- Stateful mock tracks session flow (password change, analytics consent)
- Demo banner with link to GitHub repo
- Processing attempts show info message with GitHub link
- Deployed to Cloudflare Pages as static site (no backend)
Also links demo across all surfaces:
- README: "Live Demo" badge
- Landing navbar: "Try Demo" CTA button (replaces "Book a Demo")
- Landing hero: "No sign-ups. No credit card." tagline
- Docs getting-started: "Try before installing" tip box
Other changes:
- Docs: move NVIDIA GPU section above GHCR, demote GHCR to collapsed details
- Fix before-after slider checkerboard background for transparency
- Fix remove-bg preview reset when no effects applied
Replace Organization schema with WebSite schema, add SiteNavigationElement
for Documentation/FAQ/GitHub/Contact/Discord. Add BreadcrumbList to FAQ
and Contact pages. Remove outdated og-image.svg (source already uses PNG).
Update sitemap with lastmod and changefreq.
Add a "Generate strong password" button with Sparkles icon to the
Add Members form in Settings > People. Generated passwords are shown
in plain text with a copy button and an amber warning to copy before
creating the user. Also upgraded the button style on the change
password page to match. Translated copy/warning strings for all 21
locales.
Closes#139
Remove overflow-hidden from table wrappers that was clipping the
actions dropdown menu. Apply rounded corners directly to header and
last-row elements to preserve the visual appearance.
Closes#139
Fold the sponsor call-to-action into the Contributing section as a
natural bullet point instead of a standalone heavy section. Remove
the large badge buttons. Keep star history chart under Contributing.
Add a pink "Fund Development" button component to the docs site nav
bar (left of Star on GitHub), matching the landing page style.
Remove the plain-text nav link that replaced the heart icon.
Add pink heart-styled "Fund Development" button to landing page
navbar (left of Star on GitHub) and mobile menu. Rename "Sponsor"
to "Fund Development" in the open-source section. Replace icon-only
heart in docs socialLinks with a named "Fund Development" nav link.
Remove Ko-fi from FUNDING.yml since GitHub Sponsors is now active.
Add sponsor badge to README badge row and support section. Add
sponsor button to landing page open-source section and footer.
Add heart icon social link to docs site nav bar.
- Separate unit tests (fast, no system deps) from integration test
shards to prevent vi.mock db leakage across test types
- Fix hero test: update expected subtitle to match current copy
- Fix FAQ test: add missing json-ld alias in vitest config and mock
- Integration tests run in 4 parallel shards (30min timeout each)
The full test suite takes ~100 minutes sequentially. Split into 4
parallel shards using Vitest's --shard flag so each completes in
~25 minutes. Removed coverage from CI (was causing overhead without
being reported anywhere). 30-minute timeout per shard as safety net.
The sample.heif was 8736x5856 (2.5MB), causing each processing
operation to take 17-38s in CI. Resized to 1432x960 (224KB) and added
a 15-minute timeout to the test job.
Rewrite contributing page to match new CONTRIBUTING.md with PR types,
CLA process, and good-first-issue links. Update translation guide to
encourage direct PRs instead of issue-only workflow.
- CODEOWNERS: use @snapotter-hq username instead of non-existent team
- PR template: use absolute URLs (relative links break in PR body)
- CLA: strengthen entity definition with successor/assignee clause
- CLA workflow: store signatures on dedicated branch, add owner to allowlist
- CONTRIBUTING: clarify approval means the "approved" label, reword CCLA
- Bug template: allow "running from source" for developer contributors
Add full contribution infrastructure: CLA with broad sublicensing
rights for dual-licensing, CONTRIBUTING.md with scope rules and dev
setup, CLA Assistant workflow, CODEOWNERS, SUPPORT.md, PR template,
updated issue templates with contribution prompts, and declarative
label config.
The <img src> tag cannot send Authorization headers, so thumbnail
requests returned 401 and browsers displayed the alt text (filename)
instead of the image. Replaced with AuthImage component that fetches
via fetch() with proper auth headers and renders blob URLs.
- 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
- Grant admin role to anonymous user when AUTH_ENABLED=false
- Add DEFAULT_TOOL_VIEW env var (sidebar|fullscreen)
- Hide auth-dependent settings sections when auth disabled
- Fix session endpoint to return admin role consistently
- Seed anonymous user row in DB to satisfy FK constraints
- Add 25 new tests covering anonymous mode behavior
Closes#135
When AUTH_ENABLED=false, seed an "anonymous" user row in the users
table so API keys, pipelines, and user files don't fail with FK
constraint violations. Previously, the synthetic anonymous user only
existed in memory (attached by the middleware), but any DB operation
referencing userId "anonymous" would violate foreign key constraints.
Also adds 25 new tests covering:
- Integration: ensureAnonymousUser, FK constraints, settings save,
API key and pipeline operations for anonymous mode
- Frontend: useAuth hook anonymous happy path (role, permissions,
hasPermission, session endpoint bypass)
- Frontend: settings dialog nav filtering (authRequired hides
security/people/teams/roles when auth disabled)
- Backend: session endpoint returns admin role when auth disabled
The GET /api/auth/session endpoint still returned role "user" and
user-level permissions when AUTH_ENABLED=false, inconsistent with the
middleware which now assigns role "admin". Fix the session endpoint to
match so API clients get the correct role.
- Filter known client-error noise (rate limit, empty body, unsupported
media type, content-length mismatch, premature close) from Sentry
via beforeSend to stop 644 events of non-actionable noise
- Sanitize x-output-filename header to prevent TypeError on non-ASCII
filenames in optimize-for-web preview (23 events)
- Handle EPIPE on Python dispatcher stdin write with graceful fallback
to per-request spawning instead of crashing (NODE-W)
- Map EACCES on storage directory/file write to proper 503 status
instead of generic 500 (NODE-P, 3 events)