Skip to content

Releases: Skare69/clipshelf

v0.9.0

Choose a tag to compare

@Skare69 Skare69 released this 07 Oct 13:41

New features

  • Add outbox entry delete and load-older paging
  • Bound the outbox and reject shares visibly when full

Bug fixes

  • Refuse restore from non-file-backed sqlite databases
  • Reject setup passwords similar to the admin email
  • Authenticate admin token sessions for reauthentication
  • Fetch direct media once under the media size bound
  • Bound whole-fetch deadline across slow reads and address retries
  • Normalize null screening key, keep re-typed llm key on endpoint move
  • Snapshot the default collection before scheduling
  • Decline asset downloads whose content type mismatches the viewer
  • Show the rejected share count on the hub
  • Keep collection and entry load errors visible
  • Drop stale library pages and advance the offset only on success
  • Android: changing the server endpoint now needs a fresh password sign-in at the new server. The app no longer accepts a matching public instance id as proof and never sends the existing session token to the new server. After the change, the app revokes the old server's session (best effort).
  • Separate receipt-mismatch pause from auth pause and harden outbox persistence
  • Dedup cased github keys against legacy lowercase entries and tombstones
  • Mark required confirm dialog fields
  • Screen legacy imports outside the transaction
  • Bound logout revocation attempts per call
  • Chain outbox continuation instead of backoff after 50 rows
  • Replay committed shares, accept charsequence extras, gate setup readiness
  • Refill worker slots on completion and keep staging ownership-safe
  • Make deploy probes unique and non-destructive
  • Honor historical GitHub removal keys
  • Correct server import, retry, and view behavior
  • Guard backup and restore publication
  • Guard exporter links and runtime image audit
  • Preserve Android HTTP errors and asset bounds
  • Wait up to 40 minutes for the release before attaching the apk
  • Separate android durable completions from activity ui updates
  • Make restore asset publication crash-safe
  • Route expired import sessions through shared auth loss
  • Make offline logout revocation explicit
  • Expect tzdata on every platform in the license inventory
  • Issue invitation links from the approved canonical origin
  • Whitelist the third-party notices in the docker build context
  • Create the gradle build dir before the license deps dump
  • Check license inventory against the multistage image build
  • Contain android session tokens to the verified origin
  • Reject malformed docker release versions
  • Give ci android builds tag history
  • Stamp monotonic android release versions
  • Enforce concurrent browser import request identity
  • Tombstone every contributor on owner entry moderation
  • Prevent private admin response caching

Changes

  • API error schema change: /api/ error responses now carry detail (a message) and, for field errors, errors (a list). The old error and code keys are gone, so clients that read error or code must read detail instead. This includes the 409 response when an import file was already imported to a different collection. 405 and CSRF responses do not change.
  • Add python clipshelf.py clean: it lists staging work that finished more than 30 days ago (paths and sizes) and deletes nothing. clean --execute deletes exactly the listed paths. Known issue: at release commit e2233859, clean --execute fails with RuntimeError (nested data lock) and deletes nothing. Commit fadab36 (card 9c3e4a9f) fixes this on main.
  • Android: turn off OS cloud backup of app data (android:allowBackup="false"). The endpoint, account identity, encrypted session token, and outbox no longer go into Android cloud backups. On Android 12 and later, this flag does not stop device-to-device transfer.
  • Android release builds for a v* tag now attach the signed APK to the GitHub release.
  • The Docker image and CI now install Python dependencies from the hash-locked requirements.lock (pip install --require-hashes). The image pins python:3.13-slim by digest, and CI pins its GitHub Actions by commit.
  • Ship THIRD_PARTY_NOTICES.md in the Docker image and in the Android app assets. The image license label is now MIT AND GPL-2.0-only.
  • Build/test: mutation testing runs the full CI suite per mutation run
  • Build/test: resolve each Robolectric android-all version separately for the test artifact seed
  • Build/test: seed Robolectric artifacts through Gradle and stop leaking test JVM threads
  • Build/test: the dependency lock gate tolerates platform-conditional pins
  • Remove an unused SecureRandom import
  • Derive outbox pager visibility from the row count
  • Expose the outbox drain loop as a jvm test seam
  • Drop dead frontend selectors and exports
  • Remove the unused persisted Android admin flag
  • Exclude sqlite compiler tools from the runtime image

v0.8.4 - queued capture endpoint semantics

Choose a tag to compare

@Skare69 Skare69 released this 03 Oct 13:10

Docs

  • Decided the queued Android capture endpoint semantics (review finding A10): a queued share is bound by identity (server instance + account), never by the capture-time hostname. Delivery posts through the active profile's endpoint, and only after that endpoint proves the same identity — a settings-verified host change under the same instance/account moves queued transport, every drain re-verifies identity before any POST, and a receipt must match the row's identity or delivery blocks. A different server or account never acquires queued rows. The outbox row's endpoint column is documented as capture-time provenance for the outbox screen, never a routing input. No behavior change.

Image: ghcr.io/skare69/clipshelf:0.8.4 (amd64 + arm64).

v0.8.3 - contain failed android asset temp files

Choose a tag to compare

@Skare69 Skare69 released this 03 Oct 12:50

Bug fixes

  • Android asset viewing no longer leaves partial temporary files in the app cache when a download fails or exceeds the size limit; the staging file is now deleted on every error path.

Image: ghcr.io/skare69/clipshelf:0.8.3 (amd64 + arm64).

v0.8.2 - ruff and pip-audit CI gates

Choose a tag to compare

@Skare69 Skare69 released this 28 Sep 21:49

CI

  • Added a ruff lint gate (conservative E/F plus built-in Django rules, scoped to the clipshelf package via ruff.toml), running before the Django checks in the python CI job.
  • Added a blocking pip-audit dependency audit of requirements.txt; the current pins audit clean, so no upgrades.

Code cleanup

  • Removed an unused import in clipshelf/acquisition.py and an unused variable binding in the member-add API (clipshelf/views.py). No behavior change.

Image: ghcr.io/skare69/clipshelf:0.8.2 (amd64 + arm64).

No APK changes.

v0.8.1 - sidebar icons

Choose a tag to compare

@Skare69 Skare69 released this 25 Sep 22:43

Nav icons

The sidebar views (Library, Inbox, Collections, Settings, Admin) got inline SVG icons in the same Material style as the in-app action icons. Static markup - they render before JavaScript boots, in the mobile drawer too.

Image: ghcr.io/skare69/clipshelf:0.8.1 (amd64 + arm64). No APK changes.

v0.8.0 - UI overhaul

Choose a tag to compare

@Skare69 Skare69 released this 25 Sep 21:44

UI overhaul

One reskin, zero behavior change: the whole stylesheet was rewritten on a new design system while every class, template, and line of JS stayed put.

  • Warm graphite surfaces with a brass accent replace the legacy M3 purple; light and dark both tuned for contrast.
  • Serif display stack for the brand and view headers; wider measures and a calmer type scale.
  • The library grid is now a gapless, hairline-ruled sheet instead of floating cards; status badges became quiet outline chips (filled only for errors); forms got uppercase labels, taller inputs, and consistent focus rings.
  • Motion is native CSS: cards and captures reveal on scroll (scroll-driven animations, progressive enhancement), cards lift on hover, thumbnails ease-zoom. prefers-reduced-motion still disables all of it.
  • No new dependencies, no webfonts, no third-party requests — same single-image deployment.

Image: ghcr.io/skare69/clipshelf:0.8.0 (amd64 + arm64). No APK changes. Hard-reload once; afterwards upgrades propagate on normal reloads.

v0.7.3 - transport seams made public

Choose a tag to compare

@Skare69 Skare69 released this 23 Sep 14:19

Changes

  • The two transport adapters are now public and documented as the test seam: interpretation.post() (the one HTTP call to the LLM endpoint) and judgment.ask() (the one screening request). Same code, honest names - test fakes are first-class users of the interface instead of reaching past an underscore.

Deployment

Image: ghcr.io/skare69/clipshelf:0.7.3 (amd64 + arm64). No APK changes this release.

v0.7.2 - native ES modules, no more hard reloads

Choose a tag to compare

@Skare69 Skare69 released this 23 Sep 13:46

Changes

  • The web app is split into native ES modules (core.js = transport/state/chrome, panels.js = library/inbox/collections/settings, admin.js = admin) with app.js as the entry — still no build step, no framework, no new requests. Script and CSS tags now carry ?v=<version>, so upgrades no longer require a hard reload.

Deployment

Image: ghcr.io/skare69/clipshelf:0.7.2 (amd64 + arm64). No APK changes this release. One normal reload after upgrading; hard reloads are no longer needed for future upgrades.

v0.7.0 - Job owns its lifecycle

Choose a tag to compare

@Skare69 Skare69 released this 23 Sep 12:19

Changes

  • Job owns its lifecycle: every state rewrite now goes through one of six methods on the model (mark_running, defer, mark_blocked, mark_done, fail, requeue), replacing the scattered field-write sites across worker, views, and services. requeue carries its own not-while-active rule; fail owns the bounded-retry/backoff policy. No behavior change; no payload change.

Deployment

Image: ghcr.io/skare69/clipshelf:0.7.0 (amd64 + arm64). No APK changes this release.

v0.6.6 - verdicts projected by the server

Choose a tag to compare

@Skare69 Skare69 released this 23 Sep 11:42

Changes

  • Job payloads carry the verdicts: guardrail (state-scoped) and screening_warnings. The web app dropped its error-string matching and renders the projections; the Android app shows "Guardrail blocked — findings withheld" and a screened warning count on the entry detail. CONTEXT.md added as the domain glossary.

Deployment

Image: ghcr.io/skare69/clipshelf:0.6.6 (amd64 + arm64). APK attached, same signing key — installs over the previous one. Hard-reload the web app after upgrading.