- file-preview.ts: validate the :id URL param against a safe charset and
restrict the original-name extension to alphanumerics before they feed
filesystem paths (closes 9 CodeQL js/path-injection; defense-in-depth on
top of the existing DB lookup).
- media-input.ts: require the SRT/VTT timecode structure to detect a subtitle
rather than a bare '-->' (closes CodeQL js/bad-tag-filter; also rejects
non-subtitle files that merely contain '-->').
- tests/e2e/helpers.ts: build the sharp script path via JSON.stringify
instead of single-quote-only replace (CodeQL js/incomplete-sanitization,
high: backslashes were not escaped). Proper fix, no suppression.
- landing CategoryCards: rename the file-modality marketing card to
"File Tools" (matches the Image/Video/Audio Tools siblings and is
unique vs the 23 "Files" tool pills, which broke the e2e locator).
Modality label stays "Files" everywhere it is the actual modality.
#280 left 10 section-prefixed custom-route files mis-indented and one
unsorted import block in the new landing section-index page. Fixed via
biome formatter (api) and manual import sort (landing). No config change
(biome.json is hook-protected); no suppression. pnpm lint + typecheck
now exit 0.
The fifth user-facing group is now Image, Video, Audio, PDF, Files
(internal modality id stays "file"; section.ts "files" was already
"Files"). Updates modality.ts label + comment, all 21 i18n locales
(categories.data "Data Files"->"Files", modalities.documentsAndFiles
"PDF & Data"->"PDF & Files", dead homePage.data), landing cards/hero
search/tools filter, docs headings, and e2e modality-tab assertions
(/^Data/ -> /^Files/, which had been failing).
#276's overhauled integration tests + QA sweep scripts hit the old
sectionless /api/v1/tools/<id> routes, which 404 after #280 made routes
section-prefixed. Ran scripts/rewrite-tool-paths.ts for literal URLs and
converted dynamic /api/v1/tools/${id} constructions to apiToolPath().
Negative-test paths (nonexistent/fake tools) intentionally left raw.
- Add || true after inference commands so set -e doesn't kill the
script before we reach the meaningful error message (exit code 3)
- Fix colorize settings: use "model" not "method" (matching colorize.py)
- Use larger font (size=40) and image (400x100) for OCR test so
PaddleOCR reliably recognizes the text
- Add || result="" fallback for stdout-capture smoke tests (OCR,
transcription) to prevent set -e on command substitution failure
The verify job runs between build and publish, gating HuggingFace
upload on per-bundle smoke tests. Each of the 14 bundle variants
(7 bundles x 2 arches) is verified independently: SHA256 checksum,
tarball extraction, Python import checks, and functional inference.
- validate models field in bundle.json
- pipe JSON via stdin instead of triple-quote embedding (injection safety)
- add PNG magic byte validation for background-removal output
- add dimension assertion for upscale-enhance output
- add fixture existence guards before smoke tests
- use --no-index for offline fixup wheel install
Verifies bundle tarballs in 4 phases: SHA256 integrity, extraction
and install into the base venv, Python import checks per bundle,
and a functional inference smoke test per bundle.
- fixture-integrity: probe media via media-engine probeMedia (resolves the
bundled static ffmpeg) instead of bare system ffprobe, which is ENOENT in CI;
gate on ffmpegAvailable() like the other media tests
- a11y: regenerate a11y-baseline.json to include the mobile device keys (the
baseline only had desktop keys, so the mobile a11y scan saw them as new)
- device-visual: tag @visual and exclude it from the PR mobile-smoke gate
(darwin-only screenshots cannot pass on linux; nightly + update-visual-baselines
still run it to seed linux goldens)
- Remove media-30s.mp4 and media-30s.wav from gen-synthetic-content.mjs
(these are committed real heroes, not synthetics to regenerate)
- Add skip-if-exists guards to all generators to prevent manifest hash
breakage from encoder-version differences
- Add --force flag to gen-synthetic-content.mjs for deliberate overwrite
- Fix generate-test-fixtures.mjs to skip encrypted.pdf if it exists
(qpdf AES encryption uses random IVs, non-deterministic)
- Fill provenance for 14 newly-scanned manifest entries after Phase 6b moves
- Verify all three generators produce expected output against new layout
Move all fixture files from flat/mixed dirs (content/, media/, documents/,
formats/, hostile/, root loose) into the modality-first hierarchy:
image/{valid,formats,edge,hostile}, video/{valid,formats,hostile},
audio/{valid,formats,hostile}, document/{valid,formats,edge,hostile},
data/valid/, security/. Update index.ts paths, fixtureDir aliases,
all literal refs in 17 e2e/qa/script files, manifest.json, and the
three generator scripts. 163 files moved, 0 dropped, 100 new tests
from expanded document scan.
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.
Phase 3 replaced these with real device-emulated specs
(device-mobile.spec.ts, device-tablet.spec.ts) that use actual Pixel 7,
iPhone 14, iPad, and Galaxy Tab emulation with touch, DPR, and proper
/:modality/:toolId routes. The old specs used bare viewport resizing and
bare routes (/resize) that 404 on the prod-build preview server.
Removed:
- gui-visual-mobile.spec.ts (27 tests)
- gui-visual-tablet.spec.ts (27 tests)
- gui-responsive.spec.ts (82 tests)