Releases: ZechCodes/Skrift
Releases · ZechCodes/Skrift
v0.1.0a85
Bug Fixes
- CSP nonce no longer breaks inline styles —
'unsafe-inline'instyle-srcis now preserved. CSP nonces only cover<style>elements, not inlinestyle=""attributes, so the previous replacement was blocking legitimate inline styles. Nonces are now only injected intoscript-src. (#114)
v0.1.0a84
API Key Authentication
This release adds built-in API key support for programmatic access to Skrift.
New Features
- API keys — Generate bearer tokens (
sk_...) scoped to specific permissions or roles - Key rotation — Zero-downtime key rotation via refresh tokens (
skr_...) - Route guards —
APIKeyAuth()andAPIKeyOnly()markers to declare API-compatible routes - Admin UI — Full key management at
/admin/api-keys(create, edit, revoke, rotate, delete) - Configuration —
api_keyssection inapp.yamlfor defaults (expiration, max keys per user, refresh token TTL)
Usage
curl -H "Authorization: Bearer sk_..." https://example.com/api/pagesfrom skrift.auth.guards import auth_guard, APIKeyAuth, Permission
@get("/api/pages", guards=[auth_guard, APIKeyAuth(), Permission("manage-pages")])
async def list_pages(self): ...See the API Keys documentation for full details.
v0.1.0a83
Improvements
- Reorganized Claude Code skills from system-oriented to developer-task-oriented structure
- New skills:
skrift-db(database/models),skrift-frontend(templates/themes/assets/CSP),skrift-events(hooks + SSE notifications),skrift-push(Web Push) - Merged overlapping skills: auth + oauth2, hooks + notifications
- Removed low-value standalone skills (observability, theming, hooks)
- All skills updated with cross-references to related skills
v0.1.0a82
v0.1.0a81
v0.1.0a80
v0.1.0a79
v0.1.0a78
Bug Fixes
- Fix gzip compression crash on Python 3.13 — Added
SafeGzipCompressionfacade that catchesValueErrorfromGzipFilefinalizer when clients disconnect before the response completes - Fix push subscription cleanup — Use explicit
is not Nonecheck for expired subscription detection to avoid false negatives on falsy response objects
v0.1.0a77
Changes since v0.1.0a76
- Timeseries dismissed notifications: Store dismissed notification events as TIMESERIES so disconnected clients receive them on reconnect via
get_since.Notification.dismissed()now uses its own UUID with the target ID inpayload["notification_id"].
v0.1.0a76
Changes since v0.1.0a75
Web Push notifications now fully opt-in
- PushController must be explicitly enabled in
app.yaml— no push routes, hooks, or service worker are registered by default - Users enable push by adding
skrift.controllers.push:PushControllerto theirapp.yamlcontrollers list - Service worker route (
/sw.js) auto-expands when PushController is loaded - CSRF exclusions for push endpoints only added when push is enabled
setup_push_hook()only runs when push is enabled- Updated docs and Claude skill to reflect the opt-in approach