bengal-chirp 0.6.0
Chirp 0.6.0
Focus: make larger hypermedia apps easier to assemble, route, deploy, and debug without weakening Chirp's return-type and contract-check model.
This release adds mounted-app composition, named routes with reverse URL generation, richer startup diagnostics, an in-process benchmark suite, and production defaults for Railway deployments. It also tightens several correctness paths around cache keys, shell outlets, block-scoped forms, Kida 0.8 template references, and cross-thread event delivery.
Highlights
Mounted app composition
app.mount_app(prefix, sub_app) hoists a pre-freeze Chirp app into a parent app at a URL prefix. Sub-app routes are path-prefixed, middleware/hooks/loaders/contract checks are appended, template extension points merge with parent-wins semantics, and dropped merge entries are surfaced as mount_app_merge INFO issues.
Mounted sub-apps are consumed after mounting. Calling sub_app.freeze() or sub_app.run() raises RuntimeError, avoiding an accidental half-mounted standalone runtime. See docs/routing/mounting.md and docs/rfcs/005-mount-app.md for merge rules and unsupported state.
Named routes and url_for
Mounted filesystem pages now receive default dotted names (/contacts/{contact_id} -> contacts.contact_id, / -> index), with per-page overrides via module-level name = "...". Reverse routes with:
app.url_for("contacts.contact_id", contact_id=42)or from templates:
{{ url_for("contacts.contact_id", contact_id=42) }}Path params are percent-encoded, remaining kwargs become query parameters, and None values are dropped. A new route_names contract check fails app.check() when two different paths claim the same route name.
DevTools Swap Doctor
Expanded htmx activity rows now explain swap behavior from the server's point of view: effective hx-* inheritance, selector-match checks, target presence, render intent, render-plan context, broad-target warnings, full-document fragment smells, and no-op swap detection. Overlapping htmx requests keep diagnostics attached to the correct row through XHR correlation when available.
New scaffolded apps include AGENTS.md guidance for activating DevTools, and browser-capable agents can discover the diagnostics API with:
window.ChirpHtmxDebug.help()Contract coverage and page handlers
chirp check --coverage reports coverage counters for POST form contracts, mounted page contracts, app-shell targets, and OOB regions. Contract output is grouped by concern and includes total elapsed time.
The new page_handlers contract check catches filesystem page.py files that define no recognized handler (get, post, other HTTP method names, or handler) before requests fall through to a runtime 404/500. Handler-shaped typos such as def handle, def GET, and def index emit warnings.
ChirpUI 0.6 and Kida 0.8
Chirp's optional ui extra and scaffolded projects now require chirp-ui>=0.6.0. use_chirp_ui(app) injects ChirpUI's packaged starter theme after chirpui.css, while new scaffolds keep app-owned static/theme.css as the override slot. app.check() now reports ChirpUI 0.6 manifest/runtime metadata and emits chirpui_runtime INFO when app templates import ChirpUI without use_chirp_ui(app).
Kida moves to >=0.8.0. Contract checks now resolve relative template references (./, ../) and configured @alias/ prefixes before dead-template and inherited swap-safety analysis.
Production defaults
AppConfig.from_env() now recognizes Railway environments: it falls back to Railway's PORT, binds to 0.0.0.0 when Railway is detected, and includes RAILWAY_PUBLIC_DOMAIN plus healthcheck.railway.app in default allowed_hosts when CHIRP_ALLOWED_HOSTS is absent. New deployment docs cover production and Railway setup.
Chirp's docs build dependency now requires bengal>=0.3.2 so non-workspace production builds pick up Bengal's latest build fixes.
Fixed
- Cache keys now include query string and htmx response shape so paginated views, full-page responses, boosted responses, and local fragments do not collide under
CacheMiddleware. - Shell outlets keep boosted navigation responses selectable by inherited
hx-selectcontracts, andapp.check()warns when broad shell targets/selectors are missing outlet metadata. - Form contracts now respect nested template blocks and Kida control tags when validating block-scoped
FormContractentries. - Cross-thread event delivery in
ReactiveBus,ToolEventBus, PostgreSQL LISTEN helpers, and the standalone chat example is handed back to each subscriber's owning event loop. - Example drift was cleaned up across ChirpUI and standalone examples, including the new
examples/chirpui/forum_shellreference app.
Dependencies
chirp-ui>=0.6.0kida-templates>=0.8.0bengal-pounce>=0.6.0
Upgrading
:::{tab-set}
:::{tab-item} UV
uv pip install --upgrade "bengal-chirp>=0.6.0":::
:::{tab-item} pip
pip install --upgrade "bengal-chirp>=0.6.0":::
:::{/tab-set}