cicadel

Changelog

#Unreleased

Nothing yet.

#v0.2.8 — 2026-11-14

Component escape hatches and URL reversal from components. No breaking changes. Upgrade all five modules to v0.2.8 together.

  • Inline SVG (DX-09): .templ files may contain <svg> drawings made of allowlisted vector elements and presentation attributes, with text, expressions and control flow. Scripts, styles, foreignObject, links, images, animation, event handlers, spread attributes, component calls, external href and non-fragment url() references stay compile errors.
  • Added ui.LoadIcons (DX-09): loads a directory of .svg icon files, checks each against the same policy at startup and renders them with Icons.Icon(name, class) (decorative, aria-hidden) or Icons.Labeled(name, class, label).
  • Added typed style values (DX-09): style={ ui.Style(ui.Prop("width", ui.Percent(40))) } with Px, Rem, Em, Percent, Vw, Vh, Number, Color and ImageURL, allowlisted properties and custom properties. Static style="…" attributes remain rejected; expression style attributes are now accepted. Settings.StyleAttributes (CICADEL_STYLE_ATTRIBUTES) adds style-src-attr 'unsafe-inline' to the policy.
  • Added ui.Script and ui.JSONData (DX-09): external scripts by URL or static app path (module, defer, async, integrity, crossorigin) and JSON data islands that cannot close their element.
  • Added ui.Embed and Settings.FrameSources (DX-30): allow-listed iframes for third-party players. FrameSources (CICADEL_FRAME_SOURCES) is added to the policy as frame-src and is the origin allow-list ui.Embed enforces at render time. Settings.Policy returns the header sent.
  • Added urls.Reverse(ctx, name, params...), urls.Current, urls.Namespace, urls.WithRouter and urls.RouterFrom (DX-15). The application puts its router into every request, command, Start hook and Application.Context, and the router records the matched route name, so components can write href={ urls.Reverse(ctx, "blog:post", "slug", p.Slug) }.

#v0.2.7 — 2026-11-13

Production request handling for browser applications: HTML error pages, login redirects, per-route body limits and htmx response helpers. No breaking changes. Upgrade all five modules to v0.2.7 together.

  • Added errorpages (DX-04): errorpages.Middleware replaces plain-text 4xx/5xx responses (the router’s 404/405, http.Error, CSRF failures) with a rendered HTML page for clients that accept HTML, and recovers panics as a 500 page, logging the stack with the request ID and calling an optional Report hook. Pages show fixed copy, never the handler’s message. htmx partial requests get HX-Reswap: none and a cicadel:error event instead of a page. Generated projects install it through project/errors.go (GlobalMiddleware, ErrorPage) with a styled project/errors.templ. See docs/error-pages.md.
  • Added bodylimit (DX-29): settings.MaxBodyBytes is now a per-request default that bodylimit.Limit(n) or bodylimit.Set raise or lower before the body is read. forms/upload uses Config.MaxBytes as the request limit, so upload routes accept large files while other routes keep the small default. See docs/request-limits.md.
  • contrib/accounts (DX-02, DX-03): Browser.LoginRequired(loginURL) redirects anonymous visitors to sign in with a safe ?next= (unsafe methods without it, htmx via HX-Redirect), and the sign-in page returns there. Browser.Middleware no longer caps every wrapped body at 8 KiB; the account pages keep their own 8 KiB bound. The anonymous account and change-password pages also redirect with next.
  • Added htmx response helpers (DX-08): htmx.Trigger, TriggerDetail, Redirect, Location, Refresh, Retarget, Reswap, Reselect, PushURL, ReplaceURL and CSRFHeaders. Navigation helpers accept only local paths.
  • layout.Props gains Lang and Dir (DX-10; <html lang dir>, validated) and CSRFToken, which sends the token as X-CSRF-Token on every htmx request.
  • Added response.LocalPath. response.Redirect now also rejects targets with whitespace or control characters, such as /\t/evil.test, which browsers turn into the protocol-relative //evil.test.
  • Added security.CSRFFailureMessage.
  • startproject and startapp emit gofmt-formatted Go (DX-25).

#v0.2.6 — 2026-11-12

The accounts app emits typed, transactional events. No breaking changes. Upgrade all five modules to v0.2.6 together.

  • contrib/accounts declares and emits typed events: UserCreated, LoggedIn, LoginFailed, LoggedOut and PasswordChanged (listed by accounts.Events() and included in Descriptor/Service.App). Payloads carrying Tx are emitted inside the account transaction, so handler writes commit with the change, a handler error rolls it back, and database.OnCommit(e.Tx, fn) defers side effects. Service.Create, Login, Logout, ChangePassword and ResetPassword now run through database.Atomic; Create returns a zero User when it fails. Accounts now requires core v0.2.5. See docs/events.md.

#v0.2.5 — 2026-11-12

Adds typed application events, the event-hook contract for installable packages. No breaking changes. Upgrade all five modules to v0.2.5 together.

  • Added typed application events (SVC-08), the package-system event-hook contract. The new events package declares an event with events.New[T](owner, name); an app lists the events it emits in App.Events and its handlers, created with Event.Handle, in App.Subscriptions. cicadel.New builds an immutable dispatcher and fails when an app declares another app’s event, a declaration is duplicated or its name reused, or a subscription names an event no installed app declares. Event.Emit runs handlers synchronously in app dependency order, stops at the first error (*events.HandlerError), checks cancellation before each handler and bounds nested emission (events.MaxDepth, events.ErrDepth). Requests, Start and cleanup hooks, app commands and every manage.go command carry the dispatcher; the new Application.Context(ctx) attaches it, the signing keys and the static manifest for other work such as jobs, and Application.Events() returns the dispatcher. manage.go apps lists emits and handles lines. See docs/events.md.
  • First-party app manifests (accounts, formsets, migrations, querygen) report the module version selected by the build, read from Go build information, instead of a fixed v0.1.0. manage.go apps now shows the real version; checkout builds without a released version report v0.0.0.
  • Generated projects subscribe in the new project/events.go, and the startpackage template declares and emits a typed Greeted event with a subscriber test.

#v0.2.4 — 2026-11-11

Adds typed per-package settings and completes the readiness checklist. No breaking changes. Upgrade all five modules to v0.2.4 together.

  • Formset saves (contrib/formsets) now run through database.Atomic, so model-form hooks registered with database.OnCommit during a formset Save run after the formset commits instead of failing with database.ErrNoTransaction.
  • Added the typed per-package settings contract (DEV-04). An app declares a struct whose setting:"NAME" fields (,secret for credentials) may be overridden by CICADEL_<APP>_<NAME>; it returns App.Settings: settings.NewPackage(options) and reads Package.Value(). cicadel.New resolves settings from Settings.Env before Start, rejects key collisions with project settings and other apps, and check/check --json report <app>:settings:invalid naming the key, never the value. manage.go apps lists keys and values with secrets redacted. New: settings.NewPackage, Package, LoadPackage, PackageSettings, Field, PackagePrefix, CoreKeys, Redacted, Settings.Env, App.Settings, Application.PackageSettings, AppSettings. The startpackage scaffold uses it, and contrib/accounts Options now declares CICADEL_ACCOUNTS_SESSION_LIFETIME, _RECOVERY_LIFETIME, _IDLE_TIMEOUT and _BCRYPT_COST with Options.Validate; generated projects wire them through AccountOptions. No breaking changes. See docs/package-settings.md.

#v0.2.3 — 2026-11-11

Adds transaction post-commit hooks and moves to Go 1.26.11 for a standard-library security fix. No breaking changes. Upgrade all five modules to v0.2.3 together and raise your project’s go line to 1.26.11.

  • Added transaction post-commit hooks (DB-03): database.Atomic runs a function in a PostgreSQL transaction (a savepoint when nested) and database.OnCommit(tx, fn) registers a callback that runs after the outermost transaction commits, in registration order. Hooks are discarded on rollback, on failed commit and with a rolled-back savepoint; outside an Atomic transaction OnCommit returns database.ErrNoTransaction. Hook errors and panics are logged and cannot undo the commit; hooks receive a context without the caller’s cancellation. Model form (Bound.Create/Update) and administration saves now run through database.Atomic, so AfterSave hooks can register post-commit work; formsets adopt it once that module requires this release. See docs/transactions.md.
  • Require Go 1.26.11 (was 1.26.10) in every module and in generated projects, picking up the standard-library net/http fix for GO-2026-6859. Projects should raise the go line in go.mod to 1.26.11; with the default GOTOOLCHAIN=auto the toolchain is downloaded automatically.

#v0.2.2 — 2026-11-11

Adds signed, expiring tokens with secret-key rotation. No breaking changes: existing projects keep working, and check --deploy warns until CICADEL_SECRET_KEY is set. Upgrade all five modules to v0.2.2 together.

  • Added the signing package (SEC-04): purpose-bound, timestamped, URL-safe tokens signed with HMAC-SHA256 under per-purpose derived keys; Verify with a maximum age, VerifyNoExpiry, typed SignJSON/VerifyJSON[T], ErrInvalid/ErrExpired/ErrNoKey, a one-minute clock-skew bound and WithClock for tests. New settings SecretKey (CICADEL_SECRET_KEY) and SecretKeyFallbacks (CICADEL_SECRET_KEY_FALLBACKS) sign with the current key and verify with previous ones during rotation. Handlers use signing.For(r.Context(), purpose); commands and jobs use Application.Signer. cicadel secretkey generates a key, check --deploy reports settings:secret_key when none is set, and apptest.Settings() uses the fixed apptest.TestSecretKey. See docs/signing.md.

#v0.2.1 — 2026-11-10

Adds security headers and HTTPS policy. No breaking changes: existing projects keep their behavior until they opt in. Upgrade all five modules to v0.2.1 together.

  • Added security-header defaults and HTTPS policy (SEC-03). New settings: HSTSSeconds (CICADEL_HSTS_SECONDS), SecureRedirect (CICADEL_SECURE_REDIRECT), TrustedProxies (CICADEL_TRUSTED_PROXIES) and ContentSecurityPolicy (CICADEL_CONTENT_SECURITY_POLICY), with settings.DefaultContentSecurityPolicy and settings.HSTSYear. security.IsHTTPS reports HTTPS through TLS or a trusted proxy. Generated projects enable HSTS and the default policy; existing projects keep their behavior and get check --deploy warnings until they opt in. See docs/security-headers.md.
  • Added the versioning standard to docs/releases.md: patches carry fixes and backward-compatible additions, the minor version moves only when a milestone is complete, and v1.0 requires Django-level completeness.

#v0.2.0 — 2026-11-10

Adds pagination and flash messages, the first two open core gaps, and fixes two v0.1.0 problems. No breaking changes: upgrade all five modules to v0.2.0 together.

  • Added paginate: validated page parsing, ordered GORM pagination in one read-only snapshot, slice pagination, query-preserving relative links, Django-style elided page ranges and the accessible paginate.Nav component.
  • Fixed management.ExitCode returning success for errors whose wrapped cause is nil. cicadel ui check now exits 1 on type errors instead of 0, and manage.go commands report such failures.
  • The core modules now require each other at v0.1.0, so each builds on its own with GOWORK=off; v0.1.0’s modules pinned an older framework revision without App.Static. CI builds the migrations and query-generation modules standalone.
  • Added flash: session-backed, consume-once messages with info/success/warning/error levels, size limits and the accessible flash.List component. See docs/pagination-and-messages.md.

#v0.1.0 — 2026-11-10

First release. The core framework is ready for building applications: projects and apps, settings, routing, GORM models with recorded PostgreSQL migrations, typed components with Tailwind and htmx, forms, accounts with sessions and CSRF, static files, email, logging, test helpers and installable packages. From this release, APIs follow the stability guarantee in docs/releases.md; the root module and the contrib/accounts, contrib/formsets, contrib/migrations and contrib/querygen modules are released together at the same version. Next: pagination and flash messages.

Install: go run github.com/fauzaanu/cicadel/cmd/cicadel@v0.1.0 startproject myapp example.com/myapp.

#Changes included in v0.1.0

  • Added typed static-file contributions: App.Static publishes app-owned public files at /static/<app>/ with content-hashed, immutably cached URLs, revalidated authored names, static.URL request resolution, settings.StaticURL/CICADEL_STATIC_URL (local path or https CDN prefix) and an offline collectstatic command writing hashed files plus manifest.json. Accounts, the starter project, startapp, startpackage and the component-library example now use it; the /accounts/style.css and /static/app.css routes are replaced and ComponentAssets paths are now relative to App.Static. See docs/static-files.md.

  • Made accounts and formsets standard project defaults; added offline makemigrations and generatequeries management commands from the shared model registry.

  • Consolidated migration application, planning, verification, adoption and recovery on the recorded-history runner. Removed the separate database.Migrate/Migrator executor; existing Goose histories require verified adoption.

  • Preserved first-party handwritten SQL with reviewed historical manifests and verified legacy serial/unique/timestamp-default support. Updated application guides and installable contracts to describe core defaults.

  • Breaking: renamed Yutqin to Cicadel, including Go modules and packages, CLI executables, environment variables, generated artifacts, cache paths, and framework-owned database identifiers.

  • Added typed installable runtime model catalogs with explicit app/table/type ownership, offline validation and isolated discovery. Recorded migrations remain authoritative.

  • Completed application foundation tooling: all operational settings overrides and redacted diagnostics, sorted command help and exit statuses, structured/deployment checks, and safe component/CSS rebuild/restart through cicadel dev. Added generated-executable and reload acceptance tests; see docs/foundation.md.

  • Added a green-and-black Tailwind default theme and optional startproject --accounts browser starter with compiled login/recovery/reset/account/password-change pages, CSRF protection, PostgreSQL cookie sessions and shared account revocation.

  • Added SMTP with verified STARTTLS/implicit TLS, batch connection reuse, MIME alternatives and attachments, CC/BCC, reply-to and console/file/capture/discard backends.

  • Added named logging configuration with levels, filters, propagation, JSON/text/custom handlers, file rotation, optional error email, grouped credential redaction, correlated panic records and private GORM timing.

  • Reconciled current authentication, component, PostgreSQL migration, mail and logging documentation; administration remains a separate later battery.

  • Completed standalone typed forms and accessible widgets; added revision-based stale-edit detection, bounded upload fields with compensating cleanup and multipart CSRF integration, and atomic model-form/formset administration. See docs/forms-completion.md.

  • Added core contrib/formsets: bounded related-row collections with scoped identities, add/delete limits, parent locking, transactional hooks and atomic saves; added the core Form.InTransaction composition API.

  • Added forms/model: explicit GORM field allowlists, typed binding, scoped relationship checks, authorized row-locked updates, safe constraint errors and transactional validation/save hooks. Verified with PostgreSQL concurrency and rollback tests; see docs/model-forms.md.

  • Added the installable-app foundation: manifests, API/dependency compatibility checks, namespaced commands/checks/resources, route-scoped middleware and per-host startup/cleanup.

  • Added startpackage, generated project/apps.go, manage.go apps, and apptest.Check; tested independent Go-module install/upgrade/removal and PostgreSQL migration/data retention.

  • Implemented React/Cotton-inspired compiled component UI; retained legacy Go templates for compatibility and completed the component-engine acceptance checks.

  • Added a source-linked Django battery inventory with explicit support decisions and completion criteria.

  • Reclassified existing integrations as partial batteries; model-driven PostgreSQL migrations now have a documented supported subset, other database backends are excluded, and broader package-system contracts remain planned.

  • Removed the experimental native locale package; i18n/l10n and GIS are third-party-only by design.

  • Django-familiar project/app scaffolding, typed settings, explicit app registration and management commands.

  • Standard HTTP routing with namespaced reversal, escaped embedded templates, response helpers and static assets.

  • PostgreSQL/GORM integration and locked, versioned Goose migrations.

  • Sessions, password primitives, CSRF protection, bounded forms and explicit authorization.

  • Working articles and catalog/admin examples with real HTTP/database tests.

  • API helpers, mail transport/capture, bounded storage/cache, observability hooks and River jobs.

  • PostgreSQL integration/race tests, fuzz targets, generated-project validation, vulnerability checks and performance baselines.

Requires Go 1.26.10+ to incorporate standard-library security fixes. No upgrade migration is required from a prior Cicadel release because none has been published by this implementation.

Type to search this version.