Released wojciechpolak/dud v2.7.0
Added
  • Add dud --tui, a full-screen client with the same main actions as the interactive menu: send, receive, git, peers, status, setup, and tools. Support peer and dead drop transfers, Git checkpoints, delivery status, encryption keys, configuration inspection, and scoped local-state management. Existing CLI commands and the interactive menu retain their behavior.
  • Initialize devices and pair peers through invitation creation and acceptance inside the TUI. Display the pairing code, server, and expiry while waiting; resume interrupted pairing with the same alias. Codes and enrollment secrets stay out of command arguments and command output.
  • Include transfer progress, cancellation with command cleanup, verified collection previews, and explicit consent for destructive operations. Adapt text contrast to the terminal background and support Esc or Left arrow for menu navigation while preserving cursor movement in text fields.
Released wojciechpolak/glifestream v2.2.0
[2.2.0] - 2026-10-14
Added
  • Four new themes, each following the system's light or dark mode: broadsheet, the front page of a newspaper; phosphor, a green terminal that prints on green-bar paper in light mode; riso, a risograph-printed zine; and dotfiles, a riced terminal, with tmux's status line on top and the entries as vim buffers. They load nothing from other sites: their text is set in system fonts, and riso carries Anton (SIL Open Font License) for its headings as a WOFF2 of its own. On a wide screen broadsheet lays the stream out as a front page: the lead story across, the others in two ruled columns. default stays the theme a site starts with.
  • With more than two themes, "Change theme" opens a small list of them, with the one in use checked, instead of stepping to the next theme on each click. With two, it still switches to the other one.
  • The top bar marks its link to the page shown, Home, Public or Settings, with aria-current="page", which a screen reader announces and a theme can draw.
  • THEMES picks the themes a visitor can switch between, and DEFAULT_THEME the one a visitor starts with, from the environment. A theme of your own in RUN_DIR/static/themes/<name>/ needs only its name in THEMES: its pipeline bundle is made for it. manage.py check reports an empty THEMES, a name a theme cannot go by and a DEFAULT_THEME that THEMES lacks.
  • An entry can fold to lines of its own: "Fold long entries" among the composer's more options, for a new post or an edited entry, overrides the reader's preference and the site default. 0 never folds the entry; empty leaves it to them.
Fixed
  • On a phone, where the top bar is pinned, the keys j and k, and the other jumps to an entry or a form, no longer leave it under the bar.
  • In the default theme, a sidebar taller than the window, as one with many services and lists is, hid its bottom, "Change theme" among it, until the stream ended. It is now pinned by its bottom, so all of it scrolls into view; one that fits stays pinned by its top as before.
  • Behind a proxy that ends TLS, such as Cloudflare, links to the site itself started with http://: in the Atom and JSON feeds, in the friends' login and in the OAuth redirect URI shown in settings. SECURE_PROXY_SSL_HEADER=1 makes Django take a request that the proxy marks with X-Forwarded-Proto: https for an HTTPS one. The bundled nginx template passes that header on, and docker-compose.yml passes the setting to the app.
Security
  • The initial administrator no longer gets the password admin. create_initial_user takes it from INITIAL_ADMIN_PASSWORD or generates one and prints it once, so a Docker Compose start still needs no setup. An existing account that still has admin gets a new password the same way at the next start. Until the forced password change is done, the admin site is closed too.
  • Markup from remote services is escaped or sanitized where it was stored or shown as it came: Mastodon and PixelFed statuses and their repost attribution, Bluesky facets and embeds, Flickr and YouTube media, web feed titles, and links whose scheme is not HTTP(S). Video and audio players are built through DOM APIs, not from markup with the media ID put in.
  • A remote image of more than 25 megapixels is not decoded.
  • The WebSub challenge is answered as plain text, and only for a subscribe or an unsubscribe.
  • A search keeps the stream's own filters. An anonymous visitor's search found drafts, inactive entries and entries of services kept off the home stream.
Released wojciechpolak/dproxy v1.3.0
Security
  • Reject ECH configurations whose supported public name matches the relay hostname, so mandatory ECH cannot expose that hostname in outer SNI.
  • Keep authentication-failure limiting bounded and active at capacity by evicting the oldest source instead of blocking the whole relay or dropping a new source's failures.
  • Reject deprecated IPv6 site-local addresses and zone-scoped addresses as non-global destinations.
  • Redact malformed pin and TOML array values from configuration errors.
  • Upgrade the build and runtime baseline to Go 1.26.9.
Fixed
  • Pin Make recipes to the Go version declared in go.mod, preventing analyzer export-data incompatibilities when the host Go version is newer.
Released wojciechpolak/obsidian-daily-echoes 1.2.0
Added
  • A Year view, next to Day #, that lists every daily note from one year, newest first and grouped by month. It opens on the current year. The command is "Daily Echoes: Show year".
  • Arrows in every mode to step to other dates: a day at a time in Day and Day #, a week in Week, a month in Month, and to the previous or next year with notes in Year. Clicking the label between them returns to today.
Changed
  • Note previews load as they scroll into view, so long lists open faster.
  • The line above the list now names the window it shows, such as 18–24 July, instead of the mode.
Released wojciechpolak/dud v2.5.0
Added
  • Report the server application version in dud doctor, dud capabilities, and their JSON output. Peer servers publish it on capability discovery without changing the deterministic capability document.
  • Add Go static analysis: gocyclo, errcheck, deadcode, goimports, govulncheck, and staticcheck, plus a multichecker bundling the golang.org/x/tools analyzers that go vet leaves off. They are declared in tools/, a module separate from the two that ship, so nothing they depend on reaches the client binary, and tools/go.sum fixes the version of each one. npm run analyze:go runs them; the analyzers that report nothing block through npm run check, and the rest report on pull requests.
  • Add npm run check:tidy, which fails if go mod tidy would change any module, so the pinned analyzer set always matches what the build uses.
Removed
  • Remove headV2ChunkUploadPart, a chunk upload probe nothing called. Its removal makes deadcode report nothing, so that analyzer now blocks.
  • Stop reading the deprecated tar.Header.Xattrs and matching the deprecated tar.TypeRegA when inspecting a collection archive. An extended attribute arrives as a SCHILY.xattr.* record that the record check already rejects, and the reader reports a pre-POSIX regular file as tar.TypeReg, so both reads were redundant.
Changed
  • Build govulncheck from the pinned tools module instead of installing it at job time, so the scanner that runs is the version tools/go.sum hashes.
  • Verify the Go language version of every module against .github/supported-versions.json, not the client module alone.
  • Declare the terminal echo restore function inside the branch that uses it, so a visible prompt no longer assigns a value nothing reads.
  • Promote staticcheck to a blocking analyzer. ST1005 is off. Every error string it reported opens with the proper noun "Git", which the check reads as a sentence opening.
  • Promote errcheck to a blocking analyzer. Every deferred Close, Remove, and terminal restore whose failure cannot change the result now discards its error explicitly. -blank and -asserts are off: a _ = here marks a discard the author chose, and a bare type assertion reads a field whose type a validator has already checked or whose type the standard library documents.
Fixed
  • Add the exact dud peer resume PEER and follow-up dud receive PEER commands to sequence-gap errors, and warn that the sender must resend skipped deliveries.
  • Report a failed write of a command's own output. dud flush, dud test, and dud upload --json pass a response body through to standard output, and a short write there exited 0 as though the whole body had been written.
Released wojciechpolak/glifestream v2.1.0
[2.1.0] - 2026-10-10
Added
  • An Upgrades tab in settings brings old entries up to today's markup. It shows each entry before and after, and changes nothing until the owner applies it. Dates stay as they are, and every upgrade can be reverted.
  • YouTube and Vimeo upgrades: a 320×180 thumbnail without black bars, an https:// link, no dead Flash media. Entries that only change markup can be applied at once. A video the provider no longer has can be replaced with another copy, found from the review page.
  • A music card for posts about a track: cover, title, artist, a YouTube player and search links to Spotify, Apple Music, YouTube Music, Deezer, Tidal and Bandcamp. The composer adds one from its "Music track" fields.
  • A Music upgrade turns old thesixtyone.com and Spotify posts into music cards.
  • The editor shows a post's videos as players. A video address pasted on its own becomes one at once, and the video button puts another video in the selected player.
  • A live preview under the composer shows the post, or the entry being edited, as the stream will show it, while it is written.
  • The editor shows a post's music card as it will look, and the "Music track" fields edit it. Editing a post keeps its class, which can be changed too.
  • Editing an entry shows and saves its "draft" and "friends only" checkboxes. The class of an imported entry shows as locked.
  • An "HTML source" button in the editor shows the HTML a post will be saved with, to change; publishing the post saves it.
  • A "Videos in posts" upgrade brings the players in posts up to date and can give a post another copy of a video that is gone.
Changed
  • Video players carry data-id instead of id. A user-scripts.js that looks a player up by id should use data-id.
  • The Media RSS of a post's YouTube video points at its embed player, not the Flash one YouTube no longer serves.
  • On a screen 920px wide or narrower the top bar has one menu button. Its menu shows the full e-mail address and the links with their labels, instead of a cut-off address and bare icons.
Fixed
  • Editing a post no longer turns its videos into linked pictures, and the editor shows the post's pictures instead of broken images.
  • The Docker container makes the media directories writable for Gunicorn on every start, not only on the first. On an older installation the web process could not save thumbnails, for example for an upgrade preview.

dproxy is my HTTPS and WebSocket proxy over an ECH-protected WSS relay. Application TLS stays end to end. Repo and setup: github.com/wojciechpolak/dproxy

GitHub - wojciechpolak/dproxy: Discreet HTTPS and WebSocket proxy over an ECH-protected WSS relay, preserving end-to-end application TLS.

Discreet HTTPS and WebSocket proxy over an ECH-protected WSS relay, preserving end-to-end application TLS. - wojciechpolak/dproxy

GitHub - wojciechpolak/dproxy: Discreet HTTPS and WebSocket proxy over an ECH-protected WSS relay, preserving end-to-end application TLS.

Released wojciechpolak/glifestream v2.0.0
[2.0.0] - 2026-09-30
Covers everything since the v1.4 tag (March 2021). This is a large span of work, so only the significant changes are listed.
Added
  • Mastodon support, including OAuth 2.0 authentication, context cards with reply hydration, and video embeds.
  • Bluesky/ATProto support, including native video embeds, reposts in the home timeline, context cards with reply hydration, and improved linkification and media expansion.
  • PixelFed support.
  • GitHub support, for a user's public activity or, with an OAuth 2.0 token or a personal access token, the activity they follow. Settings picks what to import: new repositories and releases by default, and stars, forks, pull requests, issues and pushes on request. Unchecking a kind hides its entries already imported. Releases published by automation are included.
  • Dark Mode.
  • Progressive Web App (PWA) support and Web Share integration.
  • Mastodon and Bluesky in the share box. Mastodon goes through share.joinmastodon.org, which asks for the reader's server.
  • Docker-based deployment: Dockerfile, Compose setup, a separate Nginx service, and a GitHub Actions workflow publishing container images with build attestations.
  • Worker daemon that replaces cron-driven fetches, with a retry-capable fetch scheduler and improved fetch failure handling.
  • Service status tab in user settings.
  • Fetch retries with backoff. A temporary failure is retried after one minute, doubling on each further failure up to the service's interval, and a longer Retry-After from the remote wins. A failure that retrying cannot fix waits at least a day. The status tab shows how many times in a row a service has failed. FETCH_RETRY_BASE_SEC and FETCH_TERMINAL_DELAY_SEC set the delays.
  • A fetch timeout, FETCH_JOB_TIMEOUT_SEC (15 minutes by default). A service whose fetch hangs no longer stops the worker from fetching the others; it is recorded as timed out and retried with backoff.
  • Magic Link SSO as the new backend for the "Friends Only" mode.
  • --uploads-list-orphans (also manage.py worker_cleanup) reports uploaded files that no entry, Media row or template of the owner uses, such as the files of a deleted selfpost. It only lists them: gLifestream never moves or deletes an upload. The worker runs the report monthly and prints it to its log, with a warning when most uploads look unused, which points to a database that does not match MEDIA_ROOT.
  • docs/ARCHITECTURE.md, describing the module layers, what each module owns, and how requests, imports and WebSub pushes move through the code. The layers are checked with import-linter (uv run lint-imports), in ./scripts/check and in CI.
  • INSTALL.md covers backups, upgrades with and without Docker, systemd units for the web process and the worker, and the worker's maintenance schedule (WORKER_MAINTENANCE_JOBS), which replaces the crontab older versions needed.
  • Forced password change flow for initial admin accounts.
  • ./scripts/bootstrap, a one-command local setup. It installs the dependencies, writes a .env with random secrets, migrates the database, compiles translations, creates the media directories and the initial admin user. It is safe to run again and never overwrites an existing .env.
  • A welcome entry for new installations, with first steps and a video player, instead of a bare "Hello, World!". manage.py load_initial_data loads it with the starting services into an empty database, both in Docker and in ./scripts/bootstrap; --no-welcome leaves the entry out. A new installation also gets a starting About box and copyright footer (user-about.html, user-copyright.html in run/templates/). In the Compose stack FEED_AUTHOR_NAME defaults to "gLifestream" instead of "YOUR NAME".
  • Test infrastructure: pytest suite, Playwright E2E coverage (including OAuth and Bluesky service flows), optional visual regression testing, and coverage
Full release notes
Released wojciechpolak/dproxy v1.2.0
Added
  • Optional mTLS (mutual TLS) on the inner TLS session, as pinned client certificates rather than a client CA. A remote configured with client_pins requires a client certificate whose SPKI digest is in that set, verified during the handshake before HELLO is read and metered by the authentication rate limiter. Clients set client_identity_file; the identity is created on first use with owner-only permissions and its client_pin is printed at startup. The shared token remains mandatory in every mode, the dproxy/1 protocol is unchanged, and a remote without client_pins behaves exactly as before.
Released wojciechpolak/obsidian-daily-echoes 1.0.5
Fixed
  • Recent entries no longer all read "earlier this year". The "how long ago" label now counts in days, weeks, months or years, so a note from yesterday reads "yesterday" and one from three days ago reads "3 days ago". Week, Month and Day-of-month surface such entries once "Include current year" is on.
  • A short gap across New Year now counts the real gap. A note from 31 December read on 2 January says "2 days ago" instead of "1 year ago". Entries near an anniversary still round up to whole years, so 363 days remains "1 year ago".
Released wojciechpolak/dproxy v1.1.0
Added
  • Native Windows amd64 and arm64 CLI binaries, Windows configuration discovery, private ACL validation for credentials, and Windows CI coverage.
  • A fixture-only make benchmark harness for tunnel setup, steady-state throughput, concurrent-session throughput, live-session heap, CPU and allocation profiles, and the production remote Docker image.
Released wojciechpolak/dud v2.4.0
Added
  • Add native Windows client support for AMD64 and ARM64, including Windows console prompts, Ctrl+C cleanup, per-user DACLs, non-blocking file locks, disk-space checks, atomic file replacement, and rooted collection extraction. Publish reproducible .exe release assets and run Windows-specific tests on windows-latest.
Changed
  • Reject collection paths, automatic output names, peer aliases, and profile names that Windows cannot store safely, including reserved device names, alternate data stream syntax, trailing dots or spaces, and invalid characters. Apply the same checks on every platform so paired devices agree on valid local names.
Released wojciechpolak/time-tracker v2.0.0
[2.0.0] - 2026-09-12
Added
  • Optional Google Firestore database backend.
  • Material confirm dialog replacing the native browser confirm().
  • Unit test suite (Vitest), Playwright end-to-end tests, and visual regression testing.
  • GitHub Pages workflow publishing the app as a static site.
Changed
  • Redesigned the UI with a warm, minimal "paper" Material 3 theme.
  • Migrated state management to NgRx Signal Store and adopted Angular Signals.
  • Switched to a zoneless application with OnPush change detection throughout.
  • Upgraded Angular to v22 and Node.js to v24.
  • Adopted strict TypeScript and upgraded Zod to v4.
  • Migrated linting from ESLint to Oxlint, formatting to Oxfmt, and the test runner to Vitest.
Security
  • Bumped multiple dependencies to address security advisories.
Released wojciechpolak/dud v2.3.0
Added
  • Add dud peer reset PEER for an authenticated peer relationship reset. Both devices sign the same transcript before the server atomically activates a fresh relationship ID and cryptographic generation. Reset preserves the peer alias, device trust, canonical origin, repository identity, and managed Git refs. The next Git push sends a complete checkpoint.
  • Advertise peer relationship reset support during pairing and reject reset proposals before changing local state when either endpoint lacks it. Peer status, doctor, and JSON output report the proposal ID, both consents, server activation, exact abandoned-delivery counts, and the recovery command for an interrupted reset.
  • Add durable peer relationship reset records to the memory, SQLite, and D1 backends. D1 deployments must apply migration 0003_relationship_resets.sql before serving reset requests.
Fixed
  • Fix rollback detection across the independent peer data and control chains. Signed outgoing high-water marks advertise queued work and do not halt a peer that has not read it. Contradictions against retained signed acknowledgements still halt the relationship and record both values, the field name, control descriptor, and relationship ID.
  • Allow dud peer revoke PEER --yes to revoke a halted relationship without advancing either delivery chain. The client preserves the halt evidence and records the local profile as revoked after the server confirms revocation.
Released wojciechpolak/clocwork v1.0.0
The interface is settled, which is all this number says. The action's inputs, the command line flags and the projects.toml schema are what 1.x will keep, and @v1 now follows the line the way @v0 followed 0.x. @v0 stays on 0.9.2 and will not move again.
Nothing here changes what the tool does. Everything a 0.9.2 run wrote, a 1.0.0 run writes identically.
Changed
  • LICENSE is now the GPL-3.0 text verbatim, and the section 7 additional permission that puts generated reports outside the licence moved to EXCEPTION.md. GitHub matches a licence file whole, so the notice that used to open LICENSE cost the repository its licence label entirely. The terms are unchanged, and both files ship in the wheel and the sdist.
Released wojciechpolak/clocwork v0.9.2
Added
  • --repo, a repeatable flag holding what a [[project]] repo key holds: a directory or a clone URL. Given one, no config file is read at all, so clocwork --repo . counts the directory you are in and clocwork --repo https://github.com/you/repo counts a repository you have not checked out, neither of them needing a projects.toml. Per-project settings stay in the file, so name, url, private, branch, vcs and the exclusions are unavailable this way, and a remote counted like this takes its default branch. --out defaults to out/ in the working directory. --repo and --config cannot be given together.
  • A GitHub Action at the repository root, so a workflow is one step: uses: wojciechpolak/clocwork@v0 with repos: .. It installs cloc and runs the tool straight out of its own checkout, with no pip install, because there is nothing to install. It reports out-dir, files and skipped, forwards --format, --layout, --by and the two SVG headings, and takes everything else through args, one argument per line. A project that could not be counted is a warning and the report is still written; fail-on-skipped makes it an error. Linux and macOS runners are supported, and Windows is refused with a message. The action writes files and never edits your README, so commit them with something like stefanzweifel/git-auto-commit-action.
  • A floating v0 tag, moved to each stable release by the release workflow, so a workflow can follow the 0.x line instead of pinning every version. It becomes v1 when the version does, and a re-run of an older tag never walks it backwards.
  • --date {minute,day,month,none} sets how precise the generated-at stamp is. It is the only thing left in the output that a rerun over unchanged code changes by itself, so --date none makes two runs write identical bytes and a scheduled job commits only when the code moved. The default is unchanged, and the key is settable in the config's [cli] table.
Fixed
  • Every run failed under cloc 1.98, which is what apt install cloc gives you on Ubuntu and therefore what most CI has. clocwork passed --hide-rate, and 1.98 closes the header that flag shortens with a trailing comma, so the output was not JSON and every project was skipped as unreadable. The flag only ever suppressed fields that parse_cloc_json drops along with the rest of the header, so it is gone rather than worked around.
  • A repo ending in .. took its name from that segment, so repo = "../thing/.." produced a project called ... The name now comes off the normalised directory.
Released wojciechpolak/clocwork v0.9.1
Added
  • A Homebrew tap, wojciechpolak/homebrew-clocwork. brew install wojciechpolak/clocwork/clocwork installs the release wheel into a virtualenv of its own and brings cloc along. The formula is generated by scripts/render-homebrew-formula and written by the release workflow, which installs it on macOS and Linux before pushing it to the tap.
Changed
  • --config now reads projects.toml from the working directory when there is one there, falling back to the file beside the package as before. --out defaults to out/ beside whichever config file was used, which is already how root, cache and [cli] out resolve. A bare clocwork therefore works from an installed copy, which previously looked for its project list in site-packages. Nothing moves in a checkout: the working directory is the repository root and both answers name the same file.
Released wojciechpolak/clocwork v0.9.0
First public release. clocwork reads a list of projects from projects.toml, runs cloc once per project, and turns the counts into one report by language, by project, and in total.
A project's repo is either a directory on this machine or a URL. Given a URL, clocwork clones it with --depth 1 --single-branch and counts the clone, so the tool runs where nothing is checked out, a CI job for instance. Clones live under $XDG_CACHE_HOME/clocwork. [defaults] cache and --cache move them. Later runs fetch rather than clone again, and --no-fetch skips the network to count what is already there.
Licensed GPL-3.0-or-later, with an additional permission under section 7 that puts the generated reports outside the licence, so a card can be embedded under any terms.
Released wojciechpolak/dud v2.2.0
Added
  • Add DUD_DROP_BASE_URL and DUD_PEER_BASE_URL so each transfer mode can select its bootstrap origin independently. DUD_BASE_URL remains the shared fallback, and a paired peer still uses the origin pinned in its profile.
  • Add resumable chunked peer transfers, negotiated through server capabilities and signed peer acknowledgements. Regular files larger than 16 MiB stream into a private encrypted spool, and dud sync PEER resumes queued uploads after a connection failure or process restart.
  • Resume downloads from verified encrypted chunks when repeating dud receive PEER. The receiver verifies the complete plaintext and installs the output atomically before advancing its receive watermark.
  • Show live progress on stderr for peer send, receive, sync, and Git push/fetch. This covers single payloads, work within resumable chunks, verified reusable chunks, and queued retries. Terminals enable progress by default; --progress forces newline-delimited output and --no-progress disables it. Updates report the phase, encoded bytes, fixed-width percentage, rate, ETA, and elapsed time without changing JSON or stdout results. Dead drop commands keep their existing output.
  • Report resumable transfers with descriptor digests and bytes remaining in dud peer show, dud doctor, and JSON output. Add dud peer abandon PEER --id DIGEST --yes to discard a saved transfer.
  • Add durable upload leases, chunk storage, retry-safe commits, and cleanup across the memory, SQLite/filesystem, and D1/R2 backends. Uploads reserve their full ciphertext size and stay out of the inbox until commit.
Changed
  • Support up to 1 GiB of plaintext per chunked peer delivery, bounded by the server's staged-byte quota, which defaults to 200 MiB per capability.
  • Add numbered D1 migration 0002_chunk_uploads.sql for resumable upload storage. Apply pending migrations before deploying the Worker; existing relationships are preserved. The self-hosted server applies its SQLite schema migration on startup.
Released wojciechpolak/dud v2.1.0
Added
  • Add incremental peer Git synchronization with explicit selection, automatic complete-checkpoint recovery, bounded pack validation, and a complete checkpoint after every 16 persisted incrementals.
  • Install the client with Homebrew on macOS and Linux: brew install wojciechpolak/dud/dud. The formula builds from the release tag with the flags release binaries use, and installs age, git, and qrencode alongside it. The name must be qualified: Homebrew's own index carries an unrelated formula named dud, so a bare brew install dud resolves to that one, and the two cannot be installed at the same time.
  • Publish the tap formula from each stable release. scripts/render-homebrew-formula.mjs renders it from the release tag and the checksum of that tag's archive, and .github/workflows/homebrew.yml commits the result to wojciechpolak/homebrew-dud. Pre-release tags never reach the tap, and the workflow can be dispatched by hand to backfill a stable tag.
Released wojciechpolak/obsidian-daily-echoes 1.0.2
Added
  • README now shows a screenshot of the panel, in light and dark variants.
Fixed
  • Entries from the previous calendar year are no longer labelled "earlier this year" when fewer than 365 days have passed. The "how long ago" label now uses the calendar-year difference, so a note from 24 July 2025 read on 22 July 2026 correctly reads "1 year ago". This affected Week and Day-of-month, whose windows reach past today's month and day.
  • Snippet previews no longer end in a stray -… when the truncation point lands on a list bullet or heading whose text falls outside the limit.
Released wojciechpolak/on-this-day v3.0.0
[3.0.0] - 2026-07-08
Added
  • New theme system and refreshed application UI.
  • Playwright end-to-end test coverage, with optional visual regression testing (VRT).
  • GitHub attestations for container image publishing.
Changed
  • Upgrade to Nuxt 4.
  • Upgrade to Node.js 24.
  • Migrate from ESLint to oxlint, and add oxfmt for formatting.
  • Optimize Docker image build and runtime.
  • Harden TypeScript types.
Fixed
  • Improve error handling.
  • Fix ICS description HTML cleanup.
  • Fix caching behavior.

Keyboard shortcuts

j
Next entry
k
Previous entry
?
Show or hide this list