Skip to content

Releases: tedydonel/Heisenberg

v0.0.4: CSP nonce support

Choose a tag to compare

@tedydonel tedydonel released this 27 Aug 14:32

What's Changed

Added

  • CSP nonce support for inline styles and scripts. Heisenberg now reads the CSP nonce from Vite::useCspNonce() (when available) and adds nonce="..." to every inline <style>, <script>, and <link rel="stylesheet"> tag. This allows Heisenberg to work correctly in apps that enforce nonce-based Content Security Policy without requiring 'unsafe-inline'.
  • README now includes CSP nonce setup instructions for Laravel apps using Vite.
  • README now includes a complete email system quick-start guide with code examples for registering variables, sending via the mailable, rendering directly, and using the admin batch ZIP export.

Changed

  • All Blade templates updated to emit nonce="{{ heisenberg_csp_nonce() }}" on inline <style>, <script>, and <link rel="stylesheet"> tags.

Upgrade note: After installing v0.0.4, run composer dump-autoload in your host app. If you use CSP nonces, add Vite::useCspNonce() to your service provider's boot() method.

Heisenberg v0.0.3 — Host-app compatibility fix

Choose a tag to compare

@tedydonel tedydonel released this 27 Aug 12:31

Heisenberg v0.0.3 — Host-app compatibility fix

This patch fixes two issues that broke the editor when used inside a host Laravel application (e.g., LangeSky):

Component namespace collision resolved — Heisenberg's Blade components (x-ui.tabs, x-live.canvas, etc.) were registered without a namespace, so a host app's identically-named components would shadow them. This caused the editor to render without any CSS or JavaScript. All components are now namespaced under heisenberg:: (e.g., x-heisenberg::ui.tabs).

Asset URLs now use named routes — Hard-coded paths like /heisenberg-assets/editor.css broke when the app was deployed behind a URL prefix. These now use route() helpers.

Upgrade: Update your Composer constraint to ^0.0.3 and run composer update heisenberg/heisenberg. Clear cached views and config (php artisan view:clear && php artisan config:clear).

Heisenberg v0.0.2 - email personalization, builder phases, URL-filter XSS fix

Choose a tag to compare

@tedydonel tedydonel released this 27 Aug 06:49

What's new in 0.0.2

This release is dominated by the email subsystem and two fixes that touch every surface.

✉️ Email personalization (host variables + admin batch export)

  • Host-defined email variables: register any dotted key with a typed formatter contract and a safe non-secret sample. Six built-in types ship (text, url, email, number, boolean, date).
  • Strict context-aware interpolation before rich-text sanitization / URL filtering, with value-free aggregated errors for unknown tokens, missing values, formatter failures, and target mismatches.
  • Per-recipient EmailRenderer and HeisenbergMailable seams across MIME subject, HTML, plain text, size accounting, and CID embeds — while preserving legacy token-free calls.
  • Sample-only public/editor preview, size, and single HTML/EML export. Runtime maps are never read from author-facing GET query strings, bodies, or headers.
  • Email-only authoring picker (subject, rich text, compatible text settings, URL settings) inserting literal {{ dotted.key }} tokens via text nodes / setRangeText, never innerHTML.
  • Admin-only, all-or-nothing batch ZIP export (email.generate, default admin) of exactly N recipients × requested locales as HTML or EML. Recipients are explicit value maps; Heisenberg still does not own SMTP, subscribers, campaigns, or recipient discovery.
  • Usage docs (docs/email-personalization.md) and compile-checked host examples (examples/EmailVariables/).

🧱 Builder / editor

  • Single-row content model — one post carries every configured locale instead of separate translation rows.
  • Native threaded comments, moderation, a public thread API, and shared-surface route wiring.
  • SEO persistence, scoring, sitemap, hreflang, and opt-in public post routes.
  • User-saved block patterns, quick-inserter browse-all, number-stepper UI, gradient values, nested/per-state fonts, and expanded column/inspector controls.
  • Responsive featured-image rendering in the public preview.
  • Deep published-config merging plus heisenberg:config-diff.

🔒 Security

  • javascript: URL-filter XSS bypass fix in BlockRenderer::safeUrl() / NullMediaResolver::safeUrl(): control characters inside the scheme are stripped before parsing (e.g. java\tscript:…), with regression coverage for all obfuscated variants.
  • target="_blank" now emits rel="noopener noreferrer".
  • ThemeRepository::save() writes with LOCK_EX.

🐛 Notable fixes

  • Autosave no longer reverts queued status/slug/date; schedule/publish timestamps no longer drift with viewer timezone.
  • Email rendering matches authored content, including translated block attributes.
  • Discussion settings target the real toggle input; disabled commenting keeps a frozen thread while hosts can choose how to display it.
  • Duplicated blocks get fresh IDs; navigator selection, child toolbar targeting, column flex-basis, heading specificity, icon theming, and font-family quoting fixed.
  • AI assistant icon lookup, translation preservation, prompt-size limits, composer height, SEO scoring and sitemap locale assumptions.

Built against

  • PHP 8.2 / 8.3 / 8.4 × Laravel 11 / 12 / 13, prefer-lowest + prefer-stable — all green on 14c9037f.
  • Full suite: 1539 tests / 6121 assertions (email wave alone: 8 feat(email) commits).

Install

composer require heisenberg/heisenberg
php artisan migrate
php artisan storage:link

Open /editor and start writing.

Heisenberg v0.0.1 - first public release

Choose a tag to compare

@tedydonel tedydonel released this 10 Aug 17:37

The first tagged release of Heisenberg: a block-based content engine and bilingual blog backend for Laravel, with zero host coupling - your app keeps its users, routes and pages; Heisenberg brings the editor and the content model.

composer require heisenberg/heisenberg
php artisan migrate
php artisan storage:link

Open /editor and start writing.

Highlights

🧱 Block engine & editor

  • Twelve block types — headings, paragraphs, images, buttons, quotes, lists, icons, separators, embeds, and nestable groups/columns — each defined by a JSON contract, validated server-side, rendered through a sanitizing pipeline
  • Full authoring chrome: inspector, floating toolbar, navigator tree, undo/redo, revisions, autosave with optimistic locking, drag & drop, dark mode
  • Visual ⇄ Code view: the whole document round-trips through a compact shortcode dialect

📝 Content management

  • Post lifecycle: draft → review → published / scheduled / archived, tier-gated
  • Categories & tags, featured image, authored table of contents, per-post layout and discussion settings
  • Bilingual (en/fr) editor UI and per-locale content columns

🖼️ Media library

  • Drag-drop uploads with per-file progress cards, responsive image variants, bilingual alt/caption metadata
  • Virus-scan seam, extension allowlist, collision-safe naming, no PHP in the public read path
  • Role-scoped permissions: viewers browse, authors upload and manage their own, editors manage all

🔌 Built for integration

  • No native users — your users authorize through the RoleGate contract with four canonical roles (admin / editor / author / viewer), read from Spatie permissions or a plain role column
  • Host-owned templates — point template_root at your app, declare page chrome (featured image, TOC, comments, breadcrumbs, share…) in a validated JSON contract, render with your own Blade views
  • Provider contracts with null defaults for everything Heisenberg doesn't own: comments, post views, related posts, SEO meta

🤖 AI writing assistant & MCP

  • Bring your own provider (Anthropic, OpenAI, or any OpenAI-compatible endpoint) — keys stored write-only and encrypted
  • The assistant writes to the live canvas through validated tool calls, streams its reasoning, and remembers conversations
  • MCP both ways: connect external MCP servers to the assistant, or expose Heisenberg as a draft-only, bearer-token MCP server for external agents

Requirements

PHP ^8.2 · Laravel 11 / 12 / 13 · Livewire ^4.3
Optional: intervention/image ^3.9 for responsive variants (v4 is not compatible)

Documentation

Start with the README; the full specification lives in docs/.