Releases: vinicq/md-bridge
Release list
v0.12.0
This release makes md-bridge safe to run as a self-hosted public service: a same-origin deploy topology, optional access control and rate limiting, work and queue limits with safe defaults, and a local access log with an operations guide. The web app also gains the Mermaid render toggle on the md-to-pdf screen. The deploy guide (deployment/oracle-cloud) covers the public-deployment specifics.
Added
- Same-origin production topology. The official deploy serves the web app and the API behind one origin with Caddy, with the request body cap enforced at the proxy as well as the app and a deploy smoke check that fetches both the served page and the API. (#435)
- Optional access control and rate limiting. Set
MD_BRIDGE_API_TOKENto require an API key (X-API-Keyheader) on the file-upload routes, andMD_BRIDGE_RATE_LIMIT(withMD_BRIDGE_RATE_WINDOW_SECONDS, default 60) to rate-limit requests. Both are off in the bare app; the official deploy recipe enables rate limiting. The upload cap is configurable viaMD_BRIDGE_MAX_UPLOAD_MB(default 500). (#436) - Work and queue limits. Heavy conversions run behind a concurrency gate with a wait queue and a per-request timeout:
MD_BRIDGE_MAX_CONCURRENCY(default 2),MD_BRIDGE_QUEUE_MAX(default 8),MD_BRIDGE_QUEUE_WAIT_SECONDS(default 10), andMD_BRIDGE_CONVERT_TIMEOUT_SECONDS(default 300). Over capacity returns 503 and an exceeded timeout returns 504;MD_BRIDGE_MAX_PDF_PAGES(default 0, unlimited) rejects an oversized PDF with 422. (#437) - Local access log and operations guide. A middleware logs one line per non-health
/apirequest (method, path, status, duration), never the document content. The bootstrap compose caps on-disk logs, and the deploy guide gains rollback, diagnosis, and backup sections. Local-only: no metrics endpoint, no external exporter. (#438) - Render Mermaid toggle on the md-to-pdf screen. The md-to-pdf page exposes the existing
render_mermaidoption as a switch, off by default. A fenced ```mermaid block renders to a diagram; a block that fails to parse stays as its source code. (#439)
Changed
- Conversion concurrency and timeout now default on. Unlike the opt-in auth and rate-limit knobs, the work limits ship with safe defaults: at most two heavy conversions at once and a 300-second per-request timeout. A single-user local install is unaffected in practice; a busy deployment no longer lets unbounded parallel renders compete for memory. Set the env vars above to tune, or the timeout to
0to disable it. (#437)
Full changelog: v0.11.0...v0.12.0
v0.11.0
The web app gains a settings home, a local history, and reusable presets, and the converter learns to read text trapped inside images. Conversion defaults are unchanged: the new converter option is opt-in and off by default, and the web features are additive and browser-local.
Added
- Per-image OCR (#140): with
ocr_images=all, eligible embedded images are run through OCR and the recognized text is inlined next to each image. Bounded to the 50 largest candidates per document that clear a size and page-area floor and are not CMYK, and skipped when the full-pageneeds_ocrpre-pass fires. Opt-in: it needs the optional OCR extra plus theMD_BRIDGE_OCR_ENABLEDenvironment variable, and it forces inline base64 images. See docs/API.md. - Preferences page (#64): a
/preferencespage for default language, default PDF theme, dark mode, and reduce-motion, cleared by a single Reset. No server, no accounts. - Local conversion history (#63): the pdf-to-md page keeps a browser-local list of recent conversions (metadata only, capped at 20 newest-first), with Re-download and Re-run while the tab session is alive.
- Conversion presets (#62): the md-to-pdf page can save the current theme and custom CSS as a named preset and re-apply it in one click, with JSON import and export. Capped at 12 per format pair.
Full changelog: v0.10.0...v0.11.0
v0.10.0
Seven opt-in converter heuristics, each off by default, so a document converted with the defaults is byte-identical to 0.9.0.
Added
- Table column alignment (#175): with
table_column_align, the separator row carries the GFM alignment markers (:---,---:,:---:) detected from each column's text extent. - Tight and loose lists (#168):
tight_loose_listspreserves a PDF list's spacing as CommonMark tight or loose lists;list_loose_threshold(1.5x the dominant body font size by default) sets the cutoff. - Image width hints (#169):
image_width_hintsemits each image's source width as a{width=N}attr-list hint, converted from PDF points to CSS pixels so a round-trip keeps the original size. Needswith_images. - Image click links (#170):
image_link_anchorskeeps an image's click-through as[](target). The document post-passes recognize the construct and operate on the external target. Needswith_images. - Nested ordered lists (#194):
nested_ordered_listskeeps a nested ordered sublist's own start number and indents it four spaces per level so the renderer nests it. - Grid tables (#166):
multiline_table_format=gridemits a Pandoc grid table for a table with a multi-line cell, so the line breaks survive. Rendering a grid table back to a PDF needs the optionalgrid-tablesextra (markdown-grids, MIT). Adopted in ADR-001. - Definition lists (#161):
detect_definition_listsemitsTerm/: definitionfor a glossary layout, a run of at least two term/definition pairs. Conservative guards keep false positives low. Adopted in ADR-001.
Dependencies
Bumped the nginx base image (#425), the web typescript-eslint group (#426), @testing-library/jest-dom to 7 (#427), the CI actions group (#428), and actions/setup-python to 7 (#429).
Full changelog: v0.9.0...v0.10.0
v0.9.0: callouts, highlights, and richer Markdown rendering
md-bridge 0.9.0 teaches the renderer to speak more of the Markdown dialect it already declares. Five features land on the Markdown to PDF side, plus two opt-in additions on the PDF to Markdown side. Every change is additive: a document that does not use the new syntax renders exactly as before.
Added
- GFM alert callouts.
> [!NOTE],> [!TIP],> [!IMPORTANT],> [!WARNING], and> [!CAUTION]render as a bordered box with an icon and a localized label (EN/PT/ES) instead of a plain blockquote. (#159) - Custom containers.
::: warning…:::blocks (the MkDocs/VuePress admonition syntax) render as the same callout box; the common names map onto the five types. (#164) - Highlighted text. PDF text-highlight annotations become
==text==(opt-inextract_highlights), and==text==renders to<mark>in the PDF. (#162) - Strikethrough and task lists.
~~text~~renders as<del>, and- [ ]/- [x]render as a disabled GitHub-style checkbox. (#143) - Figure anchors. A numbered figure caption gives its image a stable
{#fig-N}id for cross-references (opt-inemit_figure_anchors). (#165)
Notes
- No new dependency: every feature is a small python-markdown extension, so the default install stays lean. Each dialect addition is recorded as an amendment to ADR-001.
- Opt-in options (
extract_highlights,emit_figure_anchors) default off, so existing conversions are byte-identical. - Known gaps, tracked for later:
==and callouts do not yet render in the DOCX output or the web preview (#412), highlights inside table cells are not extracted (#413), and table id anchors need a renderer that can round-trip them (#414).
Full changelog: v0.8.0...v0.9.0
v0.8.0: theme library and converter polish
Added
- Theme library at
/themes: a grid of every theme, a family filter (serif / sans / mono), a live preview that stacks the theme and optional custom CSS over the base in an isolated frame, a read-only view of the theme CSS, and buttons to use a theme or download its.css. Previews render realistic samples (article, resume, email, contract, blog). (#392, #398) - Ten new PDF themes: letter, manuscript, newsprint, notebook, novel, resume, slate, slides, techbook, whitepaper, bringing the catalogue to 21. Each is a CSS overlay on the base stylesheet. (#393)
- Mermaid diagrams in md-to-pdf: a
mermaidcode fence renders to a diagram at print time through a vendored bundle, offline and deterministic, no CDN. Opt-in viarender_mermaid, off by default. (#394) - Live theme preview in md-to-pdf: pasted Markdown is shown styled by the selected theme before converting, no round-trip. (#397)
- Custom CSS in md-to-pdf: an optional CSS block layers after the theme, shown live in the preview and applied to the PDF. Empty by default, so output is unchanged when unused. (#395)
- Format-matrix status filter on Home: All / Shipped / Roadmap / Wanted, each with a count. (#396)
Full changelog: v0.7.0...v0.8.0
v0.7.0: OpenAPI TypeScript client and styled blockquotes
Added
- Generated OpenAPI TypeScript client (#32). The web app types every request and response against the FastAPI schema instead of hand-written interfaces.
python -m app.export_openapisnapshots the schema,npm run gen:apiturns it into the committed TypeScript types, and a CI step regenerates both and fails on any diff, so the client cannot drift from the backend. CONTRIBUTING documents the flow. - Styled blockquotes in the Markdown preview (#218). Quotes emitted by
detect_blockquotesrender with an accent side-rule, a soft tint, and muted italic text instead of the browser default. Quoted text and quoted links both meet WCAG AA in light and dark themes.
Full changelog: v0.6.0...v0.7.0
v0.6.0: self-contained images, offline renderer, batch a11y
Sixth release. It makes converted Markdown self-contained, hardens the Markdown to PDF renderer against network and filesystem access, bounds the OCR pre-pass, and finishes a round of batch accessibility and localization work.
Highlights
Self-contained Markdown. pdf-to-md can embed extracted images as base64 data: URIs, so a single .md travels intact (API with_images, CLI --inline-images). GFM task lists are recognized behind an opt-in flag. (#372, #373, #172)
Offline, safer rendering. The Markdown to PDF renderer no longer fetches external resources and blocks network egress, WebSocket, popup, and file: escapes, so a hostile document cannot reach the network or the filesystem through Chromium. (#363, #369, #371)
Bounded OCR. MD_BRIDGE_OCR_MAX_PAGES caps how many pages the OCR pre-pass rasterizes, and MD_BRIDGE_OCR_PAGE_TIMEOUT (default 60s) bounds how long a single page may take. A timed-out page returns ocr_failed naming the page instead of pinning the worker. (#208, #364)
Batch accessibility and i18n. Keyboard reorder is discoverable through aria-describedby and a live region, replacing the deprecated aria-grabbed; toasts are keyboard-dismissable; and the batch and chrome strings are fully localized in en/pt/es. (#354, #355, #358)
Fixes
Content-Disposition is well-formed for any filename (#362), invalid options return 422 instead of crashing the handler (#361), a corrupt or non-PDF upload returns the error envelope (#360, #370), the success toast no longer fires over a failed batch (#353), removing a batch item mid-run aborts it (#357), a stale theme slug falls back to default (#356), the drop-zone highlight stops flickering (#359), and uploads are read once instead of buffered twice (#365).
v0.5.0
What's changed since v0.4.0
- chore(deps): bump the docker-web group across 1 directory with 2 updates (#325) by @dependabot[bot]
- chore(deps): bump playwright/python from v1.60.0-noble to v1.61.0-noble in /apps/api in the docker-api group across 1 directory (#331) by @dependabot[bot]
- fix(api): pin PyMuPDF and falsegreen below the next boundary (#335) by @homesellerq-coder
- feat(converter): derive image alt text from a caption line below the image (#149) (#323) by @vinicq
- feat(converter): smart-typography ASCII folding for quotes, ellipsis, dashes (#171) (#322) by @vinicq
- feat(converter): extract abbreviation glossary as *[abbr]: definitions (#163) (#321) by @vinicq
- chore(docs): correct ko4lax credits (a11y, not infra) (#320) by @vinicq
- chore(docs): credit homesellerq-coder for code+test+doc (#319) by @vinicq
- feat(converter): pair quote attribution with the blockquote above it (#173) (#318) by @vinicq
- chore(docs): credit homesellerq-coder for code+test (#317) by @vinicq
- feat(converter): emit deterministic heading anchor slugs (#152) (#316) by @vinicq
- feat(converter): emit reference-style links for repeated URLs (#158) (#315) by @vinicq
- feat(converter): emit autolinks for bare URLs and emails (#157) (#314) by @vinicq
- chore(deps): bump node from
3ad34cato9c0e1e5in /apps/web in the docker-web group (#309) by @dependabot[bot] - chore(deps): group Dependabot minor/patch updates per ecosystem (#307) by @vinicq
- fix(web): resync package-lock with linux-only optional deps (#308) by @vinicq
- chore(deps): bump node from
144769eto3ad34cain /apps/web (#295) by @dependabot[bot] - refactor(web): replace compare/options panes with batch queue on pdf-to-md (#304) by @vinicq
- fix(api): filter _IncludedRouter in route-existence test (#305) by @vinicq
🚀 Features
🔨 Maintenance
- chore(deps-web): bump the web-npm-dependencies group in /apps/web with 4 updates (#340) by @dependabot[bot]
- chore(deps-ci): bump the ci-actions group with 8 updates (#341) by @dependabot[bot]
- chore(deps-web): bump the web-npm-dependencies group across 1 directory with 8 updates (#338) by @dependabot[bot]
- chore(deps-web): bump @types/node from 25.9.3 to 26.1.0 in /apps/web (#327) by @dependabot[bot]
- chore(deps-ci): bump the ci-actions group across 1 directory with 3 updates (#337) by @dependabot[bot]
- chore(deps-ci): bump dependabot/fetch-metadata from 2.5.0 to 3.1.0 (#330) by @dependabot[bot]
- chore(deps-ci): bump actions/checkout from 6.0.3 to 7.0.0 (#329) by @dependabot[bot]
- chore(deps-web): bump undici from 7.25.0 to 7.28.0 in /apps/web (#324) by @dependabot[bot]
- chore(deps-ci): bump codecov/codecov-action from 5.5.4 to 7.0.0 (#313) by @dependabot[bot]
- chore(deps-ci): bump amannn/action-semantic-pull-request from 5 to 6 (#312) by @dependabot[bot]
- chore(deps-web): bump the web-npm-dependencies group in /apps/web with 3 updates (#310) by @dependabot[bot]
- chore(deps-ci): bump ossf/scorecard-action from 2.4.0 to 2.4.3 in the ci-actions group (#311) by @dependabot[bot]
- chore(deps-ci): bump github/codeql-action from 4.36.0 to 4.36.2 (#298) by @dependabot[bot]
- chore(deps-ci): bump treosh/lighthouse-ci-action from 512cc908a55bfb0ad231facca52adf3d3a651df4 to 3e7e23fb74242897f95c0ba9cabad3d0227b9b18 (#299) by @dependabot[bot]
- chore(deps-ci): bump docker/setup-qemu-action from 3.7.0 to 4.1.0 (#301) by @dependabot[bot]
- chore(deps-web): bump @types/node from 25.9.1 to 25.9.3 in /apps/web (#303) by @dependabot[bot]
- chore(deps-web): bump eslint from 10.4.1 to 10.5.0 in /apps/web (#296) by @dependabot[bot]
- chore(deps-web): bump vite from 8.0.14 to 8.0.16 in /apps/web (#297) by @dependabot[bot]
- chore(deps-web): bump typescript-eslint from 8.61.0 to 8.61.1 in /apps/web (#300) by @dependabot[bot]
- chore(deps-web): bump eslint-plugin-react-refresh from 0.5.2 to 0.5.3 in /apps/web (#302) by @dependabot[bot]
- chore(deps-ci): bump docker/setup-buildx-action from 3.12.0 to 4.1.0 (#286) by @dependabot[bot]
- chore(deps-ci): bump release-drafter/release-drafter from 6.4.0 to 7.3.1 (#284) by @dependabot[bot]
- chore(deps-ci): bump actions/checkout from 6.0.2 to 6.0.3 (#285) by @dependabot[bot]
- chore(deps-web): bump typescript-eslint from 8.60.1 to 8.61.0 in /apps/web (#288) by @dependabot[bot]
- chore(deps-web): bump react-router-dom from 7.16.0 to 7.17.0 in /apps/web (#291) by @dependabot[bot]
- chore(deps-web): bump shell-quote and concurrently in /apps/web (#293) by @dependabot[bot]
- chore(deps-web): bump @vitest/coverage-v8 from 4.1.7 to 4.1.8 in /apps/web (#289) by @dependabot[bot]
- chore(deps-web): bump @types/react from 19.2.15 to 19.2.17 in /apps/web (#287) by @dependabot[bot]
Full changelog: v0.4.0...v0.5.0
v0.4.0 — DOCX export, PDF themes, H4-H6 headings
What's changed since v0.3.0
- feat(web): link language workshop from footer (#273) by @zhouzhou626
- feat(web): language workshop page to edit and export locale translations (#214) by @lvupupui
- feat(converter): detect more languages in code fences (#213) by @lvupupui
🚀 Features
- feat(converter): escape line-start markdown specials in literal prose (#283) by @vinicq
- feat(web): md-to-docx converter page (/convert/md-to-docx) (#279) by @vinicq
- feat(web): format hub matrix on home (#277) by @vinicq
- feat(web): add page-setup panel to md-to-pdf (#275) by @vinicq
- feat(converter): per-request page size, margins, and running header/footer (#243) (#272) by @vinicq
- feat(api): format registry + Markdown to DOCX converter (#60) (#271) by @vinicq
- feat(web): side-by-side source-PDF preview on /pdf-to-md (#15) (#256) by @vinicq
- feat(web): per-conversion options panel wiring live schema flags (#59) (#250) by @vinicq
- feat(web): theme picker on /md-to-pdf (#24) (#247) by @vinicq
- feat(themes): real academic, business, and minimal CSS templates (#22) (#244) by @vinicq
- feat(api): theme registry + GET /api/themes + options.theme (#23) (#242) by @vinicq
- feat(converter): pair footer footnotes with body refs behind a flag (#148) (#235) by @vinicq
- feat(converter): reach heading levels H4-H6 (#234) by @vinicq
- feat(converter): preserve hard line breaks from PDF layout (#232) by @vinicq
- feat(converter): introduce HTML emission allow-list policy (#222) by @vinicq
- feat(converter): subtract recurrent page headers and footers (#221) by @vinicq
- feat(converter): cluster font sizes into heading bands (#220) by @vinicq
- feat(converter): detect blockquotes from sustained-indent body blocks (#217) by @vinicq
- feat(converter): detect Fira Code, Source Code Pro and friends as monospace (#215) by @vinicq
🐛 Bug fixes
- fix(docker): make the test profiles build and run from a clean cache (#230) by @vinicq
- fix(web): meet WCAG AA contrast for the converting batch label (#224) by @vinicq
- fix(converter): keep multi-paragraph blockquotes as one quote (#219) by @vinicq
📖 Documentation
- docs(i18n): trilingual docs site (PT + ES) with language selector (#29) (#269) by @vinicq
- docs: declare the canonical Markdown dialect (ADR-001) (#223) by @vinicq
🔨 Maintenance
- test(renderer): lock setext heading and HTML comment input (#282) by @vinicq
- chore(ci): adopt falsegreen as a test-honesty gate (#281) by @vinicq
- test(web): stabilize the flaky webkit batch sequential test (#280) by @vinicq
- test(web): harden format hub route-integrity guards (#278) by @vinicq
- chore(deps): bump node from 24-alpine to 26-alpine in /apps/web (#258) by @dependabot[bot]
- chore(deps-root): bump concurrently from 9.2.1 to 10.0.3 (#260) by @dependabot[bot]
- chore(deps-web): bump react-router-dom from 7.15.1 to 7.16.0 in /apps/web (#263) by @dependabot[bot]
- chore(deps-ci): bump actions/deploy-pages from 4.0.5 to 5.0.0 (#261) by @dependabot[bot]
- chore(deps-ci): bump actions/upload-pages-artifact from 3.0.1 to 5.0.0 (#259) by @dependabot[bot]
- chore(deps-ci): bump docker/login-action from 3.7.0 to 4.2.0 (#257) by @dependabot[bot]
- test(regression): pixel-diff gate for the Markdown to PDF themes (#245) (#270) by @vinicq
- test: tighten 4 false-green-prone assertions (#267) (#268) by @vinicq
- chore(deps-web): bump eslint from 10.4.0 to 10.4.1 in /apps/web (#266) by @dependabot[bot]
- chore(deps-web): bump react-dom from 19.2.6 to 19.2.7 in /apps/web (#264) by @dependabot[bot]
- chore(deps-web): bump typescript-eslint from 8.60.0 to 8.60.1 in /apps/web (#262) by @dependabot[bot]
- ci(web): mark workspace safe.directory in update-snapshots (#248) (#255) by @vinicq
- ci(web): drop jq in update-snapshots, use gh --jq (#248) (#254) by @vinicq
- ci(web): fix webkit data-theme race and add CI retries (#246) (#252) by @vinicq
- ci(web): install gh in the update-snapshots container (#248) (#251) by @vinicq
- ci(web): visual regression baselines via Playwright screenshots (#16) (#240) by @vinicq
- test(backend): broaden the PDF fixture corpus (#28) (#238) by @vinicq
- chore(docs): credit @lvupupui for tests and translation (#231) by @vinicq
- chore(docs): credit @lvupupui (#216) by @vinicq
Full changelog: v0.3.0...v0.4.0
v0.3.0 — automatic trilingual OCR, pure-Markdown output
What's changed since v0.2.3
- ci(web): add Lighthouse budgets (#106) by @alucard210319
- ci: add Codecov coverage upload (#107) by @0exec
- feat(api): optional Tesseract pre-pass for scanned PDFs (#86) by @0exec
- fix(web): use descriptive PDF preview iframe title (#87) by @zhouzhou626
- feat(web): implement dark mode theme (#75) by @GiulianaCDA
🚀 Features
- feat(ocr): enable OCR by default when the Tesseract stack is installed (#207) by @vinicq
- feat(ocr): default to eng+por+spa so OCR auto-handles EN/PT/ES (#199) (#203) by @vinicq
- feat(converter): detect and emit GFM strikethrough (#142) (#201) by @vinicq
- feat(web): add a download-all zip button to BatchPanel (closes #137) (#190) by @vinicq
- feat(web): make the needs_ocr warning prominent and handle ocr_required (closes #139) (#185) by @vinicq
- feat(api): block scanned PDFs with 422 ocr_required (part of #139) (#183) by @vinicq
- feat(web): honor prefers-reduced-motion globally (#132) by @vinicq
- feat(web): add global focus-visible ring with theme tokens (#130) by @vinicq
- feat(api): detect code blocks in pdf-to-md (#110) by @vinicq
- feat(ci): auto-update branches of stale auto-merge PRs (#85) by @vinicq
- feat(ci): auto-credit external contributors on PR merge (#80) by @vinicq
- feat(ci): auto-assign PR author when a pull request opens (#78) by @vinicq
- feat(ci): issue-claim Action with /claim and /take commands (#70) by @vinicq
🐛 Bug fixes
- fix(converter): stop a full-width rule being read as strikethrough (#202) (#210) by @vinicq
- fix(converter): nest a code block under its list item (#197) (#209) by @vinicq
- fix(converter): emit pure Markdown for small text and superscript (#141) (#200) by @vinicq
- fix(renderer): parse YAML front matter with safe_load (#150) (#198) by @vinicq
- fix(converter): keep multi-paragraph list items inside one item (#167) (#196) by @vinicq
- fix(converter): keep ordered lists contiguous instead of one item per paragraph (closes #144) (#193) by @vinicq
- fix(converter): escape literal Markdown punctuation in body text (closes #155) (#191) by @vinicq
- fix(api): silence MuPDF native stderr and route warnings to the logger (#180) by @vinicq
- fix(infra): stop nginx buffering large API responses to disk (#182) by @vinicq
- fix(web): time out and allow skipping stuck batch items (#179) by @vinicq
- fix(web): close color-contrast gaps across themes and locales (#131) by @vinicq
- fix(web): pause Toast auto-dismiss on hover and focus (#115) by @vinicq
- fix(ci): preserve existing contributor categories in credit workflow (#113) by @vinicq
- fix(ci): unblock board-sync and issue-claim workflows (#74) by @vinicq
📖 Documentation
- docs(changelog): cut v0.3.0 (#211) by @vinicq
- docs(deploy): dedicated Render free-tier walkthrough (#116) by @vinicq
- docs(contributing): document repository secrets (#103) by @vinicq
- docs(readme): link new MkDocs pages from the header (#102) by @vinicq
- docs: add deployment recipes page (#98) by @vinicq
- docs: add api recipes page (#97) by @vinicq
- docs: add faq page (#93) by @vinicq
- docs: add heuristics page (#92) by @vinicq
- docs(security): document new Pinned-Dependencies paths from #86 + Maintained (#90) by @vinicq
- docs: add architecture page to the MkDocs site (#79) by @vinicq
🔨 Maintenance
- chore(dev): portable backend interpreter + remove orphan pair log (#206) by @vinicq
- chore(deps): resync requirements files with pyproject (#205) by @vinicq
- chore(converter): resolve #144 review nits (#195) by @vinicq
- chore: ignore stray uv.lock (#189) by @vinicq
- chore(api): silence successful /api/health probes in the uvicorn access log (#181) by @vinicq
- chore(deps-ci): bump github/codeql-action from 4.35.5 to 4.36.0 (#122) by @dependabot[bot]
- chore(deps-ci): bump docker/build-push-action from 6.19.2 to 7.2.0 (#120) by @dependabot[bot]
- chore(deps-ci): bump docker/metadata-action from 5.10.0 to 6.1.0 (#124) by @dependabot[bot]
- chore(deps): bump nginx from
2f07d83to8b1e787in /apps/web (#119) by @dependabot[bot] - chore(deps): bump node from
e71ac5eto7c6af15in /apps/web (#118) by @dependabot[bot] - chore(deps-web): bump vite from 8.0.13 to 8.0.14 in /apps/web (#129) by @dependabot[bot]
- chore(deps-web): bump @types/node from 25.9.0 to 25.9.1 in /apps/web (#125) by @dependabot[bot]
- chore(deps-web): bump vitest from 4.1.6 to 4.1.7 in /apps/web (#126) by @dependabot[bot]
- chore(deps-web): bump typescript-eslint from 8.59.4 to 8.60.0 in /apps/web (#121) by @dependabot[bot]
- chore(ci): align dependabot commit prefixes with semantic-pr rules (#128) by @vinicq
- chore(deps-web): bump @types/react from 19.2.14 to 19.2.15 in /apps/web (#123) by @dependabot[bot]
- test(web): cross-browser Playwright matrix (Firefox + WebKit) (#117) by @vinicq
- chore(docs): credit @pink (#114) by @vinicq
- chore: pair log entry (#111) by @vinicq
- chore(docs): credit @alucard210319 (#108) by @vinicq
- chore(deploy): add render.yaml blueprint (#101) by @vinicq
- chore(docs): backfill changelog unreleased with 2026-05-22 work (#100) by @vinicq
- chore: remove orphan hook and unused social-preview asset (#91) by @vinicq
- chore(docs): credit 0exec for code+doc+test+infra on #86 (#89) by @vinicq
- chore(docs): credit zhouzhou626 for a11y on #87 (#88) by @vinicq
- chore: remove CONTRIBUTOR-WALKTHROUGH.md (#82) by @vinicq
- chore: explain empty except blocks to clear CodeQL py/empty-except (#84) by @vinicq
- chore(security): bump pypdf, markdown, python-multipart past 26 GHSAs (#83) by @vinicq
- chore(docs): credit @GiulianaCDA for the dark mode work (#81) by @vinicq
- chore(security): pin Docker base images to sha256 digest (#77) by @vinicq
- chore(security): pin Actions to SHA + scope workflow permissions (#76) by @vinicq
- chore(ci): mirror Projects v2 board workflows in a reviewable Action (#68) by @vinicq
Full changelog: v0.2.3...v0.3.0