TREK 3.2.0
TREK becomes a platform. A sandboxed Plugin System with a community registry, one-click installs and a full author SDK. Collections — a personal place library that lives outside your trips. Public transit routing right in the planner, no API key needed. AI booking import for the confirmations structured parsing can't read. On top: per-user Appearance & theming, a robust offline mode with real conflict resolution, video in journeys and files, subscribable calendar feeds, an in-app help centre — and Vietnamese as language number 22.
No breaking changes — all 19 database migrations run automatically on startup, and Collections and AI Parsing stay off until you enable them.
Plugin System
TREK is now extensible. Anyone can build a plugin — a dashboard widget, a full page, or a headless integration — and self-hosters can browse a community registry and install it with one click, without ever touching TREK's source. Plugins run with real OS-level isolation behind an explicit permission model, and the whole system ships with an author toolchain that takes you from scaffold to published registry entry in a handful of commands. (#1415)
- Three plugin types — widgets render on the dashboard (sidebar card or a
heroslot on the boarding-pass bar), pages get their own entry in the navigation, and integrations run headless server logic (API routes + scheduled jobs) - Real isolation, not a label — every active plugin runs as its own OS process under Node's permission model: it cannot read
trek.dbor any TREK secret, write files, spawn processes, or load native addons; its data lives in a separate per-plugin SQLite file - Capability permissions — a plugin declares what it needs (own database, membership-checked trip reads, public user profiles, namespaced WebSocket broadcasts, per-host outbound HTTP) and TREK's RPC host only exposes what was granted — an ungranted call is unreachable, not merely refused
- Egress guard with SSRF backstop — all outbound traffic (fetch, sockets, UDP, even DNS) is restricted to the plugin's declared hosts, and connections to loopback/private/link-local/metadata addresses are refused even for allow-listed hosts
- Sealed plugin UI — pages and widgets render in sandboxed, opaque-origin iframes with a locked-down per-plugin CSP; a plugin's frontend can never read your session cookie or the surrounding TREK page
- Registry with one-click install — Admin → Plugins → Discover browses the public TREK-Plugins registry; installing verifies the artifact's pinned SHA-256 (plus an optional Ed25519 author signature), safely unpacks it, and registers it inactive — nothing runs until you flip the toggle
- Review before you install — the detail view lists in plain language what a plugin can access, which hosts it talks to, and what it will ask you to configure, alongside a Reviewed badge for maintainer-scanned versions and an honest disclaimer about what the sandbox does and doesn't guarantee
- Re-consent on updates — an update that requests new permissions or new outbound hosts is installed but left off until you approve the exact delta; an update can never silently widen a plugin's access
- A real management surface — search, type/status filters, Update all, per-plugin health, error log, a capability audit log, restart, and uninstall with the choice to keep or delete the plugin's data
trek-plugin-sdkon npm —npx trek-plugin-sdk createscaffolds a plugin,devruns it locally against a mock host that enforces your manifest's permission grants exactly like the TREK host (no TREK instance needed; the OS sandbox and egress guard apply inside a real TREK), andpublishdoes the entire release — pack → GitHub release → preflight → auto-opened registry PR — in one command- Koffi, the reference plugin — TREK's mascot ships as a worked example: an animated suitcase hero widget driven by your real trip data, published in the registry
- On by default, with a kill switch — the plugin system is available out of the box, but installed plugins still have to be activated one by one, so nothing third-party runs until you turn a specific plugin on; set
TREK_PLUGINS_ENABLED=falseto switch the whole system off (installed plugins stay on disk, deactivated) - Hardened by adversarial audit — two dedicated audit passes (threat model: malicious plugin author, malicious artifact) before merge closed sandbox-escape, SSRF, decompression-bomb, DoS and consent-bypass findings
Docs: Plugins · Plugin Development · Plugin Permissions · Publishing a Plugin
Collections — A Personal Place Library
A place you saved used to exist only inside its trip. The new Collections addon gives every user a place library outside of any trip: keep named lists of spots you've discovered — a "Norway someday" wishlist, "Best coffee in Lisbon" — copy places into and out of any trip, and share lists with other users. Enable it under Admin → Addons to get the new /collections page. (#1081)
- Named lists — each with a colour, description, links and a cover image (upload or search Unsplash); a built-in All saved view unions your whole library
- Idea / Want to go / Visited — a per-place status you cycle with one tap, plus status and category filters
- List + map layout — lists rail, places list and a persistent map side by side, with a full-map toggle and a place detail sheet; mobile keeps a list/map switch
- Save from a trip — "Save to collection" in the place inspector and context menus, plus a bulk action that copies every selected trip place into a chosen list (duplicates are skipped)
- Copy to trip — saved places copy into any trip with name, description, category, notes, price, coordinates, photo and tags; the trip's add-place modal gains a Saved places picker sorted by proximity to the trip
- Bulk actions — select-all, bulk delete, bulk copy-to-trip, and move or duplicate a selection into another list
- Sharing with member roles — invite other users to a list (accept/decline, like Vacay fusion) with per-member roles: viewer, editor or admin, enforced on the server and synced live
- Dashboard widget — your lists as compact badges on the dashboard, hideable per user
- Custom labels — each list can define its own labels (e.g. Berlin, Hamburg, Ostsee in a "Germany 2026" list) to group its places. Create/rename/recolor/delete them in a label manager, assign them from a place's detail sheet or in bulk from the selection toolbar, and filter both the list and the map by label (multi-select, any-match). Labels are shared with everyone on the list — managing and assigning needs edit rights, filtering is open to all members
Full guide: Collections
Public Transit Routing
Google-Maps-style public transit directions, right in the planner — with no paid provider. Routing comes from Transitous, the community-run MOTIS service built on open GTFS feeds: free, open data, no API key required. (#1065)
- Automated transport mode — the Add-transport dialog gets a Manual / Automated switch; Automated embeds the transit search, and a new tram button on each day header opens it with that day preset
- Journey search — from/to stop search with the day's own places and hotels as quick picks, depart/arrive time, mode filters (train, subway, tram, bus, ferry, cable car) and ranking by best route, fewer transfers or less walking
- Readable results — itinerary cards with local times, duration, transfers and walking minutes, line badges in their official colors, and an expandable stop-by-stop breakdown with platforms, headsigns and operators
- First-class transit entries — a saved journey is its own reservation type: the day timeline renders the legs inline and folds the full itinerary out in place, and the Transports tab lists journeys in their own section
- Journey view — duration / transfers / walking stat tiles, inline title rename, notes with a markdown toolbar, and a "Change route" action that re-runs the search pre-seeded with the journey's endpoints
- Real paths on the map — journeys draw along the actual rail and bus alignments in each line's color, with walks as dotted connectors, on both map renderers
- Right times, right slot — times are station-local, transfer waits count toward the duration, and after-midnight arrivals land on the next trip day
- Self-host friendly — the server proxies Transitous (authenticated, rate-limited, cached); point
TRANSIT_API_URLat your own MOTIS instance for zero third-party egress
Also on the map: booking route endpoint labels now default to off for a calmer look — re-enable them anytime in Settings.
Docs: Transport: Flights, Trains & Cars
AI Booking Import
Booking import no longer gives up on documents KDE Itinerary can't read. The new opt-in AI Parsing addon adds an LLM fallback that extracts flights, trains, buses, ferries, rental cars, hotels, restaurants and event tickets from unstructured confirmations — with first-class support for self-hosted local models. Based on work by @jubnl. (#1301, #1318)
- Bring your own model — Local (Ollama), OpenAI — including any OpenAI-compatible endpoint via a custom base URL — or Anthropic; Anthropic reads the original PDF natively (scans included), the others work on the extracted text
- Runs only when needed — structured parsing still goes first; the AI is asked only about files it can't read, and every AI result is flagged for review
- Reliable on local models — a layered extraction router makes exactly one schema-constrained call per document (a multi-leg flight comes back as all its legs at once), then deterministically backfills booking reference, total price, currency and overnight arrival dates from the document itself
- Qwen3-8B recommended, one-click pull — the admin config lists your installed Ollama models and pulls the recommended
qwen3:8bwith a live progress bar; NuExtract models are supported too — configure them under the OpenAI-compatible provider, where they're detected and driven through their native template format - Review before save — each parsed booking opens the normal edit modal pre-filled; nothing is written to the trip until you confirm
- Parses in the background — the upload modal closes immediately; a progress widget tracks the parse, survives a page reload, and offers one-click review when done
- Everything lands connected — venues become geocoded trip places, hotel bookings create the accommodation on the matching days, the parsed price becomes a linked Cost, and the source document is attached to the booking
- Richer bookings — seat, class, platform and price are captured; hotels bring their address, rental cars their company, events their venue with phone and website
- Instance-wide or per-user — admins can pin one provider and model for everyone in Admin → Addons, or each user configures their own under Settings → Integrations (API keys stored encrypted)
Appearance — Make TREK Yours
A new Settings → Appearance tab lets every user personalize TREK's look — per user, saved to your account, with a live preview. The default reproduces TREK's current look exactly, so nothing changes until you opt in. (#950, #951, #1025, #1271, #1370)
- Seven color schemes — Default, High Contrast, Indigo, Teal, Rose, Amber and Violet, each with separate light- and dark-mode palettes
- Custom accent color — pick your own accent (independently for light and dark) from swatches or a free picker, with a live contrast hint
- Text size — an "Everything" slider (80–160 %) plus per-size sliders for Large / Medium / Normal / Small text, each with a live sample; the whole app resizes as you drag
- Readability (experimental) — turn transparency off for solid, higher-contrast surfaces app-wide, a Compact density that tightens spacing, and a reduce-motion toggle
- Dashboard widgets, per device — show or hide each dashboard widget independently on desktop and mobile; the layout reflows to use the freed space
- No more theme flash — a pre-paint boot script applies your saved appearance before the first frame
- One-click reset — back to stock TREK anytime
Alongside it, settings got a spring clean: the old Display tab is now General (split into "Language & region" and "Travel & map"), and the eleven flat admin tabs are grouped into Users, Configuration, Integrations and Maintenance sections.
In-App Help Centre
The TREK wiki is now built into the app: open Help from the profile menu (or /help) to browse the full documentation without leaving TREK. (#1373)
- Full docs, TREK-styled — section navigation, search, themed markdown rendering; wiki links open in-app
- Always current — your server fetches the wiki from GitHub and caches it, so documentation updates appear without a redeploy; if GitHub is unreachable, the last cached copy is served
- Private by design — your browser never talks to GitHub; help pages and images are proxied through your own instance
Robust Offline Mode
Offline support graduates from a passive cache to something you control: go offline on purpose, decide what each device stores, and resolve sync conflicts instead of silently losing edits. (#1135)
- Force offline mode — a new switch under Settings → Offline downloads everything first, then runs the whole app from local cache and queues every change; the override survives app restarts, and flipping it off replays the queue
- Prepare for offline — a one-tap, progress-tracked download of trip data, documents and map tiles that waits for every download to actually finish before reporting "ready"
- Choose what to store — turn map-tile storage off to keep only trip data and documents, and toggle offline storage per trip; evicting a trip keeps its unsynced edits
- Conflict detection instead of silent overwrites — offline edits to places and packing items carry the version they were based on; if someone changed the item in the meantime, the edit surfaces as a conflict instead of clobbering the newer change
- Keep mine / keep theirs — resolve each conflict side by side in Settings → Offline, or set a default rule (ask, always mine, always server)
- Smarter status pill — the connectivity indicator now distinguishes forced offline, queued changes, unresolved conflicts and failed syncs
Docs: Offline Mode and PWA
Video Support
TREK's memories are no longer photos-only: upload and play videos in the journey gallery and the trip file manager, and link videos straight from your Immich library. (#823)
- Video upload in the journey gallery — mp4, m4v, webm and mov up to 500 MB per clip; a poster frame and duration are captured in your browser, and the clip is stored as-is (no server-side transcoding)
- Plyr video player — videos open in the lightbox with a clean, consistent player; the grid shows the poster with a play badge
- Smooth seeking — local and linked videos stream with HTTP Range support, so jumping around the timeline is instant
- Immich videos — the Immich picker (timeline and albums) now lists videos alongside photos; linked videos stream through Immich's transcoded playback endpoint with full seek support
- Videos in the trip file manager — attach clips to places and reservations like any other file, with the same player; documents keep their own 50 MB limit
- Shared journeys included — public journey share links show and play videos too
Community Feature Pack
Six of the most-requested features from GitHub Discussions land in one pack. (#1384, #1387)
- Booking links — reservations get a dedicated Link field; save the booking URL once and open it straight from the reservation card (#935)
- Markdown files render inline —
.mdfiles open as a formatted (and sanitized) preview right in the file manager, tables and all (#1345) - Reorder packing & to-do lists — drag items into any order; the order saves instantly and syncs to the whole trip (#969)
- Three-tier packing sharing — every packing item is Common (the group pool), Personal (only you see it) or Shared with specific people; a new Shared / My list switch separates the group pool from your own packing (#858)
- "I can bring that too" — pledge to co-bring a common item, or copy it onto your personal list with one click; every item shows who's bringing it (#858)
- Transfer trip ownership — hand a trip over to any member from the members dialog; the former owner stays on as a regular member (#973)
- Guest members — add travel companions who don't have a TREK account: guests can be assigned to costs, packing, to-dos and activities like any member, but can never sign in, never receive notifications and never appear outside their trip (#1362, #1291)
Costs — Split Modes & Filters
The Costs addon gains proper Splitwise-style split modes — contributed by @Zorth — and quicker ways through long expense lists. (#1338, #1407)
- Equally / Custom / Ticket splits — split equally, enter exact per-traveler amounts that must balance to the total, or itemize a receipt line by line and assign each line to specific travelers, with cent-perfect shares (#1338)
- Fair rounding — equal splits distribute leftover cents deterministically and rotate who pays the extra cent, so nobody is systematically overcharged across a trip
- Filter by category and day — two new dropdowns narrow the ledger to one category and/or a single day, with a per-day total banner, composing with search and the all/mine/owed filters (#1407)
- Existing "paid by" expenses keep working and settle exactly as before
Docs: Budget Tracking
Invites & Joining Trips
Getting companions into a trip no longer requires adding them by hand. (#1143, #1402, #1405)
- Trip invite links — every trip's Share panel can hold one rotating invite link (
/join/<token>); anyone with a TREK account who opens it joins as a member, signed-out visitors log in first and land back on the invite - Regenerate or disable anytime — rotating the link instantly invalidates the old URL; managing it requires the trip's share permission
- Trip-bound registration invites — an admin registration invite can be bound to a trip: whoever registers through it (password or SSO) is automatically added to that trip
Docs: Invite Links · Trip Members and Sharing · Admin: Users and Invites
Subscribable Calendar Feeds
TREK trips can now live in your calendar. Alongside the one-time .ics download, every trip — or all your trips at once — can expose a secret, revocable feed URL that Google Calendar, Apple Calendar and Outlook keep in sync as your plan changes. Contributed by @michael-bohr. (#1307)
- Per-trip feed — the ICS button in the planner is now a menu: Download ICS for the classic export, Subscribe to calendar for a live feed
- All-trips feed — one combined feed for every trip you own, reachable from the dashboard; archived and long-finished trips drop out automatically
- One-click subscribe — Add to Google Calendar, a
webcal://handoff for Apple Calendar / Outlook, and copyable links for everything else - Private by default, fully revocable — no feed exists until you enable it; regenerate the secret link (invalidating the old URL) or turn it off entirely at any time
- Full itinerary — the trip span, timed activities with locations, day notes and reservations — flights with their real local departure and arrival times and the full multi-leg route
Maps & Planner
- Multi-leg train bookings — a long-distance rail trip is usually several trains on one ticket, so trains get the same multi-leg route editor as flights: an ordered chain of stations with an Add stop button, and per-leg train number, platform, seat and departure/arrival day + time. The whole station chain draws on the map, and each leg slots into its own day in the plan (independently reorderable). Single-station and pre-existing trains keep working unchanged (#1150)
- Real road routes for car, bus, taxi & bicycle bookings — these transport bookings now follow actual roads on the map instead of a straight line. Geometry is fetched on demand from the public OSRM router (driving for car/bus/taxi, cycling for bicycle); the straight line shows until it loads and stays if routing fails, very long hops (~2000 km+) skip routing, and trains/cruises/ferries keep their straight line. Works on both map renderers
- Marker clustering on the GL map — place markers on the Mapbox/MapLibre renderer now group into count bubbles on zoom-out, matching the Leaflet map (#1385)
- Consistent hover card on the GL map — hovering a place shows the same slim name/category/address card as the Leaflet map (#1388)
- Day selection fits the whole route — selecting a day zooms the map to the day's route as well as its stops, so a detour or ferry leg stays in view (#1128)
- Bulk "Change category" — select several places and apply one category to all of them from the selection toolbar, with undo (#1168)
- Bulk place updates via MCP — the new
bulk_update_placestool applies the same field values to up to 500 places in one call (#1117) — see MCP Tools and Resources - Open in OpenStreetMap — the place inspector gains an OpenStreetMap button next to Google Maps — a handy hand-off to OSM-based apps like Organic Maps (#880)
- Route distances inline on mobile — the per-day Route button in the mobile plan sheet shows that day's leg distances in place (#1374)
- Year on trip dates — dashboard cards, the boarding-pass hero and planner day headers include the year whenever it isn't the current one (#1323)
- Context-aware "+" button — the mobile bottom-nav "+" now matches the active trip tab: Bookings adds a booking, Transports a transport, Costs an expense, everywhere else a place (#1349)
Trips & Quality of Life
- Unsplash cover search — find a trip cover by keyword right in the create/edit dialog, with photographer attribution and no API key; chosen photos are downloaded into your instance's uploads, so covers can't link-rot. Contributed by @hykilpikonna (#1277)
- Faster date picking — the date picker now drills down from days to months to years for quick jumps, and a keyboard mode lets you type the date in your locale's format. Contributed by @gcettuzz (#1170)
- OIDC profile pictures — SSO users who never uploaded an avatar get their identity provider's
pictureclaim as avatar; an uploaded avatar always wins (#1399, #1403)
Internationalization
- Tiếng Việt — TREK now ships a complete Vietnamese translation, bringing the total to 22 languages. Contributed by @leeduc (#1368)
Self-Hosting & Ops
- Helm: bring your own storage —
persistence.data.existingClaim/persistence.uploads.existingClaimbind the chart to PVCs you manage yourself, andpersistence.enabled: falsenow falls back to an ephemeralemptyDir. Contributed by @yael-tramier (#1355) - No more silent admin-credential ignores —
ADMIN_EMAIL/ADMIN_PASSWORDonly apply on the first boot of an empty database; the server now logs a clear warning when they're set but ignored (#1339, #1344) - Admin recovery script — locked out?
docker exec -it trek node server/reset-admin.jsresets (or creates) the admin account with a generated one-time password (#1339) - Plain-HTTP login, explained — the most common install trap (production build over plain
http://silently dropping the secure session cookie) now shows an explanation and the fix right on the login page instead of a dead end (#1373) - Troubleshooting guides — new wiki sections for the can't-log-in-after-setup scenario and the snap-Docker
no-new-privilegesstartup failure (#1343, #1344): Troubleshooting - README refresh — all eight gallery screenshots re-captured on the current UI, including Collections
Developer & API
- OpenAPI / Swagger API docs — TREK now ships an interactive REST API reference. Set
TREK_API_DOCS_ENABLED=trueand browse/api/docsfor a full Swagger UI with "try it out"; the raw spec is at/api/docs-json(OpenAPI 3) and/api/docs-yamlfor generating typed clients or importing into Postman. Request bodies are derived automatically from the same Zod validators the routes enforce, so the docs never drift. Off by default — the spec enumerates the whole surface including admin routes, so it's an explicit opt-in; authorize once with a session JWT via the Bearer button (#1412)
Fixes
A broad pass over community-reported bugs across the planner, map, bookings, costs, Atlas, AirTrail sync, the PWA and mobile.
- No phantom routes between flights — two transports on the same day no longer draw a bogus airport-to-airport driving route between them (#1394)
- Per-day Route button — on mobile, tapping a day's Route button computes that day's route, not the previously selected day's (#1392)
- Google Maps route includes hotels — "open in Google Maps" now bookends the day with its accommodation, matching the drawn route (#1372)
- Multi-day accommodation scroll — selecting a multi-day accommodation no longer yanks the plan list from day to day (#1375)
- Compass on small screens — the reset-orientation compass now shows on mobile too (#1377)
- Stable cost settlement — balances are netted in the trip's currency and converted once, so exchange-rate changes no longer drift balances or invent phantom micro-payments (#1382)
- Transport-only countries count as visited — a country reached only by a flight or train booking now counts as visited on the dashboard and in Atlas (#1366)
- Hotel booking dates — a hotel linked to an accommodation shows just its stay range, and the range stays correct after edits (#1383)
- Link a place to any booking — every non-hotel booking type can link an existing trip place, pre-filling title and address (#1353)
- Touch drag-and-drop — dragging places and days in the planner now works on Android and iOS (#1265)
- AirTrail: manually-entered flights — flights without scheduled times now import their departure/arrival times, and already-imported flights pick them up on the next sync (#1336)
- PWA starts offline again — opening the installed app without a connection loads the cached app instead of the browser's "no internet" page, while auth walls (Cloudflare Access, Pangolin) are still detected for re-login (#1346)
- Mobile GPS button — the locate button sits above the day-detail panel instead of hiding behind it (#1348)
- Place search autofocus — the search field focuses automatically when the add-place dialog opens — thanks @jufy111 (#1340)
- Polish translation — travel buddies are now "Współpodróżnicy" instead of "Towarzysze" (#1390)
- MCP streams stay connected — the SSE stream now sends a keep-alive ping (every 25 s by default) so reverse proxies with idle timeouts stop dropping it between tool calls, and ordinary admin saves no longer invalidate active MCP sessions (#1414)
- Date-line routes draw as one arc — transpacific flights and any route crossing the antimeridian no longer split into two disconnected polylines at the map edges, on both renderers (#1411)
- Map hover card no longer sticks — clicking an off-center place recenters the map, so the hover card is now cleared on marker click and camera moves instead of hanging around (#1404)
- Add a place by long-press / right-click on GL maps — the Mapbox/MapLibre map now opens the Add-Place form on a touch long-press and on right-click, so mobile and Macs (no middle button) can drop a place anywhere (#1398)
- KGS currency — the Kyrgyzstani som is now selectable as a trip, default and expense currency (#1400)
Contributors
Thanks to everyone who contributed to 3.2.0:
Stats
| Metric | Value |
|---|---|
| Commits | 220 |
| Merged PRs | 39 |
| Files changed | 1,052 |
| Lines added | 61,000+ |
| Contributors | 9 |
| New wiki pages | 6 |
Upgrading
docker pull mauriceboe/trek:3.2.0
docker compose up -dAll 19 database migrations run automatically on startup — no manual steps, no breaking changes. Worth knowing:
- Plugins are on by default — the Admin → Plugins panel is available out of the box (installed plugins still need per-plugin activation before anything runs); set
TREK_PLUGINS_ENABLED=falseto switch the system off. See Plugins - Collections and AI Parsing ship disabled — enable them under Admin → Addons
- API docs are off by default — set
TREK_API_DOCS_ENABLED=trueto expose the interactive OpenAPI/Swagger reference at/api/docs; leave it off in production, since the spec includes admin endpoints - Large video uploads — if TREK sits behind a reverse proxy, raise its request-body limit (e.g. nginx
client_max_body_size) to make use of the 500 MB video cap - Markdown uploads —
md/markdownwere added to the default upload allowlist; if you overrode the allowed file types in the admin panel, add them there yourself - Behavior change — map booking-route endpoint labels now default to off; re-enable them in Settings
- Calendar feed links — set
APP_URLbehind a reverse proxy so subscribable feed URLs are canonical - All new environment variables (
TRANSIT_API_URL,TREK_PLUGINS_*,TREK_API_DOCS_ENABLED, and theMCP_SSE_KEEPALIVE/MCP_SESSION_TTLtunables) are optional and have sensible defaults
What's Changed
All 39 merged pull requests
- feat(date-picker): add month/year drill-down navigation and keyboard input trigger by @gcettuzz in #1170
- [+] Add unsplash search to trip covers by @hykilpikonna in #1277
- feat(feeds): subscribable ICS calendar feeds for trips by @michael-bohr in #1307
- Reliable, non-blocking LLM booking extraction by @mauriceboe in #1318
- Splitwise like costs by @Zorth in #1338
- Added focus to search places in placeFormModal by @jufy111 in #1340
- docs(wiki): document the snap Docker + no-new-privileges startup failure by @mauriceboe in #1343
- fix(setup): warn when ADMIN_EMAIL/ADMIN_PASSWORD are ignored, ship reset-admin by @mauriceboe in #1344
- fix(airtrail): import departure/arrival times for manually-entered flights by @mauriceboe in #1347
- fix(pwa): stop unregistering the service worker on offline boot by @mauriceboe in #1350
- fix(map): keep the mobile GPS button above the day-detail panel by @mauriceboe in #1351
- feat(mobile): context-aware bottom-nav + button per trip tab by @mauriceboe in #1352
- feat(helm): Allow to use existing PVC with customised names by @yael-tramier in #1355
- feat(i18n): add Vietnamese translations by @leeduc in #1368
- Customizable appearance: themes, transparency, text size and dashboard widgets by @mauriceboe in #1370
- feat: in-app help wiki + clearer plain-HTTP login error by @mauriceboe in #1373
- feat: bulk place updates via MCP (#1117) + year on trip dates (#1323) by @mauriceboe in #1376
- feat(places): bulk "change category" from the selection toolbar (#1168) by @mauriceboe in #1378
- feat(map): include the day's route in the map fit (#1128) by @mauriceboe in #1379
- Robust offline mode: force-offline, selective storage and conflict resolution by @mauriceboe in #1380
- Video in the journey gallery: local upload, Plyr player and Immich linking by @mauriceboe in #1381
- Community feature requests: markdown files, booking links, list reorder, private packing, ownership transfer, guest members by @mauriceboe in #1384
- Packing list sharing (#858) + GL map marker clustering (#1385) by @mauriceboe in #1387
- fix(map): match the GL place hover tooltip to the Leaflet map by @mauriceboe in #1388
- feat(collections): Overall Places / Collections addon (#1081) by @mauriceboe in #1391
- fix: back-merge v3.1.4 hotfixes into dev (#1371) by @mauriceboe in #1395
- fix: batch of reported bug fixes (planner, budget, atlas, bookings, mobile) by @mauriceboe in #1396
- feat(planner): add an Open in OpenStreetMap button to the place inspector by @mauriceboe in #1397
- feat(planner): show a day's route distances inline on mobile by @mauriceboe in #1401
- feat(oidc): use the picture claim as avatar when none is uploaded by @mauriceboe in #1403
- feat(trips): trip invite links + optional trip binding on admin invites by @mauriceboe in #1405
- feat(costs): category + day expense filters · fix(admin): CustomSelect invite trip picker by @mauriceboe in #1407
- feat(planner): public transit routing via Transitous (#1065) by @mauriceboe in #1408
- feat(plugins): Plugin System by @mauriceboe in #1415
- fix(plugin-sdk): scaffolded plugins can actually require the SDK by @mauriceboe in #1422
- ci(plugin-sdk): publish workflow on Node 22 by @mauriceboe in #1423
- feat(plugins): enable plugins by default + v3.2.0 wiki docs by @mauriceboe in #1424
- fix: work through the open issue tracker (#1414 #1411 #1404 #1398 #1400 #1412) by @mauriceboe in #1425
- test(collections): fix the CollectionPlaceDetail suite for the labels feature by @mauriceboe in #1427
PR #1425 is a rebase-merged batch that also folds in multi-leg train bookings (#1150), the real road-route booking overlays, the OpenAPI/Swagger docs (#1412) and the per-collection custom labels — those shipped as commits, not separate PRs.
New Contributors
- @gcettuzz made their first contribution in #1170
- @michael-bohr made their first contribution in #1307
- @Zorth made their first contribution in #1338
- @yael-tramier made their first contribution in #1355
- @leeduc made their first contribution in #1368
Full Changelog: v3.1.4...v3.2.0