// dev log
Daily Update
What shipped to the 0xCMS Worker, straight from the commit log.
2026-09-08
SECURITY HARDENING
c2d27acRevocable access sessions bind every access token to a live session and current user role, so logout, deletion, and role demotion take effect immediately. Refresh sessions now have a seven-day rolling expiry with a 30-day absolute lifetime.
c2d27acPublic-media and plugin-file isolation requires a media_files registration before either public media route serves an object; plugin API files remain private even when a key overlaps public media. Authorization runs before thumbnail-cache lookup.
c2d27acHost-approved plugin capabilities make concrete blueprint access, trusted plugin UI, and plugin file prefixes administrator decisions. New and existing plugins default to sandboxed UI unless trusted UI is explicitly approved.
c2d27acSafer live editing and request handling requires the exact Origin and a live session for WebSockets, rechecks idle sockets, and adds bounded request, upload, plugin-file, state, asset, and network-fetch limits.
2026‑08‑24
5 commits · safer viewer onboarding and runtime appearance controls
New accounts now begin with least-privilege viewer access, while administrators can personalise the CMS interface with a saved primary colour and system-font stack. The viewer landing page and credit profile flow also receive focused usability fixes.
ea01114Least-privilege viewer dashboard provisions every new OAuth account as a viewer, regardless of provider role claims. Signed-in viewers can load /admin, their profile, and authenticated view assets while content and mutation routes remain capability-protected.
9799a53Translated viewer landing page routes the viewer dashboard strings through the client-view translation catalogue so its welcome, privacy, and app guidance text follows the selected UI locale.
85a4918Viewer status icon adds the missing lock-closed SVG symbol used by the viewer dashboard.
c50a022Zero-balance credit profile hides wallet transfer and shared-pool donation controls when a user has no credit balance, avoiding actions that cannot succeed.
323b1e5Runtime font and primary-colour settings adds validated primary-colour and font choices to System settings. The saved appearance reskins admin accent states and the login screen with CSS variables, including accessible foreground ink and dark/light colour ramps, without a redeploy.
2026‑08‑23
1 commit · preserved plugin access in fresh installs
New CMS installations now retain the existing access model for plugin administration when their role permissions are created from the consolidated baseline migration.
4ae1cfbPlugin-access baseline migration adds an idempotent plugin:access grant for roles that already carried a plugin-defined permission, matching the existing-install migration while leaving new databases with no plugin permissions unchanged.
2026‑08‑22
3 commits · safer plugin identity, scalable bulk actions and streamlined Apple setup
The plugin platform now pins each manifest identity to its registered Worker and restricts plugin-defined permissions to that identity’s namespace. Bulk publish and unpublish actions replace per-page database and target work with bounded set-based batches, and the setup wizard can now create and upload Apple’s rotating client-secret JWT.
28bf7fePinned plugin identities and namespaced permissions binds a manifest ID to one registry row on first use, refuses duplicate or changed identities until an administrator re-approves them, and revokes prior capability approvals on an approved rename. Plugin permissions must use that plugin’s <manifest-id>:<capability> namespace; non-admin access to plugin pages also requires the CMS-side plugin:access permission.
2853f8eSet-based bulk publishing batches submission-mirror checks, D1 publish writes, tag catalogues and publish-target work for bulk publish and unpublish actions. This avoids the previous N+1 request pattern and keeps larger bounded slices within Worker and D1 subrequest limits.
b0156d3Apple setup creates its client secret moves ES256 JWT creation into npm run setup when Apple is enabled, validates the downloaded .p8 key and IDs, derives the key ID from AuthKey_<key-id>.p8 when possible, and keeps the standalone generator for renewal before Apple’s six-month limit.
2026‑08‑16
1 commit · reliable plugin updates and type slugs
Plugin page saves now report success reliably after D1 update triggers run, while runtime page and block type slugs can retain underscores for clearer integration-friendly identifiers.
8b91af0Reliable plugin page updates treats a zero-row write as the only version conflict for PUT /__cms/pages/:id, preventing a false 409 after a D1 trigger or index write has successfully saved the page. The runtime type normaliser also preserves _ in page and block type slugs.
2026‑08‑14
1 commit · live weight feedback after reordering
Page-list reordering now refreshes each affected draft weight in place and immediately shows when that ordering differs from the live page, so editors can publish the changed order without losing their place in the list.
a3e4f6bLive weight synchronisation returns the final weights for the visible reordered window, updates the dashboard controls without a reload, and reveals the existing publish-to-sync action whenever a draft weight diverges from its published value.
2026‑08‑13
2 commits · drag-and-drop page and navigation ordering
Editors can now arrange a single page type directly from its dashboard list, while administrators can drag-sort the main and Settings sidebar links. Both flows retain precise weight controls for fine tuning.
231c688Safe page-list reordering adds handle-only drag and drop for an unfiltered, single-page-type list. The server verifies the rendered window is still current, caps sequences at 5,000 pages, renumbers with gaps for manual adjustments, and records an audit event.
31618e4Drag-sortable sidebar settings replaces the settings tables with reusable drag controls for main and Settings navigation items, including visibility, icon, and weight configuration while preserving the System anti-lockout guard.
2026‑08‑12
1 commit · page-title-aware bulk replacement
Bulk search-and-replace now treats a page title as first-class editable content, so a consistent rename can update both page names and matching structured fields in one reviewed operation.
73cb7f1Page-name bulk replacement includes page.name in the replacement preview and updates it alongside matching lect text. Changed pages retain their version history and lifecycle update events, even when only the name changes.
2026‑08‑11
5 commits · safer viewer access, reviewed text replacement and Apple sign-in
Signed-in viewers now land on a safe dashboard rather than being locked out of the CMS shell. Editors can preview a bounded set of proposed text replacements before confirming a bulk change, and Apple is enabled as a production OAuth provider with a local client-secret generator.
138949fViewer dashboard and previewed bulk replacement lets permission-less signed-in users reach /admin and their profile while keeping every protected editor route closed. Advanced Search gains a Search & Replace flow that previews up to 100 pages and 500 changes before confirmation, supports selected or filtered scopes, and reuses the bounded bulk-action path.
8005766Apple sign-in enabled adds apple to ENABLED_PROVIDERS, configures the CMS Services ID, and supplies npm run apple:client-secret to generate the Apple client-secret JWT from the team, key, and Services ID details.
2026‑08‑10
4 commits · safer plugins and conflict-free co-editing
Collaboration now merges concurrent rich-text changes at character level, while the plugin platform gains explicit browser trust boundaries, host-managed file storage, and operator-managed tenant configuration. Read-only roles are also kept out of editable page forms.
2fc061bYjs CRDT collaboration and plugin trust levels replace whole-field rich-text conflicts with per-field Y.Text documents in PageSyncDO. Plugins now declare server-only, sandboxed-ui, or trusted-ui; sandboxed UI runs in an opaque-origin iframe while server-only plugins cannot expose admin UI.
4eebc7eScoped plugin file API adds authenticated /__cms/files access to the CMS R2 media bucket. A plugin must declare a path prefix and an administrator must approve it; overlapping prefixes are reserved globally, and list/read/write/delete operations remain bounded and no-store.
3cf00a4Tenant variables in the plugin manager lets operators view and update manifest-declared tenant variables through the authenticated plugin configuration endpoint, with values scoped to the canonical CMS tenant.
06d80dfRead-only editor guard redirects users without content:write from /admin/pages/:id/edit to the equivalent read view, preserving the original query string and keeping collaboration assets out of review-only sessions.
2026‑08‑09
1 commit · safer tenant-specific plugin setup
Plugins can now declare which deployment variables belong in a newly connected CMS tenant. The enrollment handshake carries names only; the plugin SDK copies matching non-empty values after the one-time ticket is redeemed, keeping each tenant’s setup isolated without exposing secrets on the wire.
181003aValidated tenant KV variables adds manifest tenantVars/tenant_vars support for automatic plugin enrollment. Names must be unique uppercase identifiers and cannot collide with SDK connection fields; existing tenant-specific overrides remain in place when a connection is rotated.
2026‑08‑08
2 commits · clearer tag sync and faster external content loading
The Tags screen now shows publication-sync feedback only when a sync has actually succeeded or failed, keeping the normal management view free from empty status banners.
ea445daAccurate sync-status banners makes the Liquid tags view distinguish blank query values from real messages, so success and error banners do not appear on an ordinary visit.
008e974Batched plugin page resources adds authenticated POST /__cms/pages/list-batch for loading up to 20 independently sorted page-type lists in one D1 batch. Plugins can optionally group each bounded result by a tag taxonomy, including untagged pages, while page-type access and request limits remain enforced.
2026‑08‑07
6 commits · safer bulk tag management and published catalogues
Editors can now apply or remove tags across many pages from the dashboard and advanced search. The workflow respects the existing page and tag records, updates only pages that actually change, and makes taxonomy maintenance more practical for large content sets.
5c32545Bulk tag assignment adds an Add tags action for selected pages or a filtered result set, with tags grouped by taxonomy. It skips existing links, records normal page-update lifecycle events, and uses the existing bounded bulk-action path.
f7f66b4Bulk tag removal adds the matching Remove tags action. Pages without a selected tag are safely skipped, while changed pages receive an accurate update time and lifecycle notification.
a7a3c7cReliable new-tag form lets the tag editor derive a usable slug when one is omitted, avoiding a server error during tag creation.
060e0baDeletion-safe tag changes confirms requested tag records still exist while a bulk removal runs, preventing stale selections from affecting page-tag links.
48ead8fPublished tag catalogue mirrors complete tag records to D1 and plugin publish targets, not just page-tag links. Creating, editing, reordering, moving, deleting, or renaming a tag or taxonomy now keeps public readers in sync; the Tags admin also provides a bounded Sync published backfill for existing sites.
f6a48a4Consolidated published migration folds the published-tag schema into the baseline migration, keeping fresh published D1 installs aligned with the catalogue.
2026‑08‑05
4 CMS commits · configurable language defaults and clearer admin feedback
Language configuration is now a first-class content setting, so the CMS can use the enabled locale that fits a site rather than a fixed default. The page workspace and dashboard also gained more precise status, translation and publishing feedback, while rich-text fields are easier to scan and edit.
24737ffConfigurable default content language adds a Languages-admin selector backed by content.default_language. The selected enabled locale flows through content configuration, tag labels and admin APIs, and the CMS protects it from being disabled or deleted.
17e7cebMore legible page editing improves field-label layout, shows the current draft/live/scheduled/ended state beside page identity, supplies a safe default field renderer, and adds live word and character counts to richtext/md.
59213c2Publishing-aware page weights keeps dashboard weight changes clearly separate from live content, warns when the live weight differs from the draft, and offers an explicit publish path to synchronise it.
32af684Translated page-list and editor chrome localises page-list headings, counts and scheduled/ended status copy, and uses the active UI language for editor titles and save-and-publish controls.
2026‑08‑04
4 commits · a calmer, more adaptable page editor
The page editor has been reorganised around the page identity and the work at hand. Metadata, collaborators and publishing controls now have clearer homes, while structured content can stay compact without losing editing or reordering controls. The supporting client renderer keeps those behaviours consistent after a client-side render.
9845567Focused editing layout elevates the page name, slug and page type, groups page settings more deliberately, and improves the responsive editor and sidebar details for smaller screens.
7934d68Compact publishing and collaboration controls gives publishing schedule and actions a dedicated collapsible panel, places collaborator management beside page attribution, and keeps the editor's structured-field copy/paste tools readily available.
a40b624Remembered structured-editor sections makes item groups and individual items collapsible, persisting their open state per page in the browser. The client-rendered path now supplies stable keys too, so dynamic renders retain the same experience; flash URLs are also cleaned after display.
b4741e7Dependency maintenance refreshes the project's checked dependencies to keep the Worker toolchain current.
2026‑08‑03
5 commits · resilient page creation and composable admin views
Plugin page creation now remains reliable for long generated slugs, while the Liquid admin shell gains safer rendering and reusable, configuration-driven page chrome. Core templates and shared view sections are consolidated under src/core, leaving feature-owned screens beside their optional capabilities.
5baecceLong-slug-safe collision checks replaces LIKE matching with indexed lexical ranges when plugin page creation checks generated slug suffixes. Long titles, such as shipment EDM subjects, no longer exceed D1's pattern limit.
f79f605Safe Liquid layout rendering validates the layout syntax and keeps body explicitly raw only at the trusted render boundary, while exposing standard header and layout content slots.
664febbShared admin page chrome introduces reusable page-header and form-actions sections, then drives headings, back links and actions through template configuration across core and feature views. This removes duplicated markup while retaining each screen's route-specific controls.
c3f549Core template ownership moves always-on TypeScript templates from src/templates to src/core/templates, making the core-versus-feature boundary explicit in both Worker code and view assembly.
2026‑08‑02
10 commits · aligned content stores and droppable admin views
The private CMS and published D1 databases now share the same page and tag-table vocabulary, while draft version selection is derived from immutable history instead of a mutable pointer. The admin view tree now follows the same core-plus-feature profile boundary as Worker code and schema, so disabled capabilities no longer ship their screens or translations.
20fbcecAligned D1 page tables standardizes both CMS and published stores on pages and page_tags, with explicit migration scripts for existing databases. The database boundary, rather than divergent table names, now separates draft/admin content from published reads.
3fb342bHistory-derived active version removes draft_pages.current_page_version_id; the newest immutable page_versions record defines the active draft. The companion migration also removes the draft-page parent cascade so child records are handled deliberately.
c331c8aProfiled admin views moves each optional feature's Liquid templates, browser assets and locale fragments beside its code, then assembles only enabled views into dist/views. Wrangler now runs the build before deployment, preventing missing generated assets in CI and direct deploys.
3a080a6Refined admin chrome adds a sidebar toggle and improves credit-balance wrapping, keeping the responsive admin navigation compact without losing access to controls.
2026‑07‑31
2 commits · host-owned plugin state
Plugins can now retain a CMS-specific connection or preference without putting that host-owned data in the plugin Worker. The new state contract keeps each CMS tenant's record within its own D1 database and removes it when the plugin is cleanly unregistered.
b7bddfaHost-owned plugin state adds authenticated GET, PUT and DELETE /__cms/state endpoints for opaque JSON values, namespaced by the caller's manifest ID. Keys, value size and per-plugin entry count are bounded; state is cleaned up with the plugin and is explicitly not a secrets store.
c337f31State API guide documents the /__cms/state routes, host-versus-plugin ownership model, limits and the safe handling of missing migrations for plugin authors and operators.
2026‑07‑30
5 commits · multi-currency billing and resilient plugin enrollment
Credits are now a self-contained, multi-currency feature: operators can price actions in ordinary credits or premium diamonds without tying the CMS core to billing. Plugin enrollment also recovers cleanly when a tenant was already cached before KV configuration became available.
fd39484Diamond wallets adds a separate diamond currency alongside credits. Each currency has its own user wallet, shared pool and append-only ledger; a diamond-priced action cannot spend ordinary credits, and plugins can declare which wallet a cost uses.
6b3250bDroppable credit engine moves currencies, billing contracts and the credits implementation behind the generated feature-service registry. Profiles can install credits independently, while profiles without it keep priced actions free and avoid importing billing into core.
63034b6Cached tenant recovery reconnects an auto-enrolled plugin tenant when its cached record has no KV configuration, so an operator can complete tenant setup without first manually clearing the cached enrollment.
2026‑07‑26
24 commits · composable feature profiles and a clearer core architecture
0xCMS is now organised around a stable core and independently selectable feature slices. A single profile generates the Worker registries and fresh-install schema, while explicit extension points keep optional plugins, publishing, administration and infrastructure from becoming hidden core dependencies.
7c07f96Generated feature profiles makes cms.features.json the source of truth for enabled features. The build generates registries and assembles schema fragments, so a fresh deployment includes only its selected feature code and tables.
3f2a6f2Dependency-safe profiles rejects a profile when a selected feature depends on one that is switched off, rather than leaving a deployment to fail later at runtime.
046137eCore-to-feature boundaries moves shared rendering, HTTP, authentication, Durable Objects and publishing beneath src/core/, with extension points used by feature slices instead of reverse imports.
eba1701Self-contained platform slices consolidates the plugin platform under src/features/plugins/, alongside the other optional capabilities, and documents the resulting layout for operators and contributors.
e5dac63Clearer runtime content types renames the database-managed content-type feature to runtime-content-types and moves generated registries to src/generated/, keeping build output distinct from optional features.
60725edOptional background jobs makes the jobs slice independently droppable. With it installed, long plugin actions and search bulk actions use durable queue work; without it, the CMS safely falls back to bounded synchronous handling.
47ca3c7Profile-aware menu settings hides controls for features excluded from a build and preserves their saved sidebar state, so re-enabling a feature does not unexpectedly leave its navigation switched off.
2026‑07‑25
12 commits · portable editor values and streamlined plugin tenancy
Editors can move a complete set of structured values between pages or languages without rebuilding a form by hand. Compatible multi-tenant plugins can now be connected from the CMS through a short-lived, single-use enrollment exchange, while the platform groundwork moves schema and feature ownership into clearly bounded slices.
8cf70b7Copy and paste page fields adds a structured-editor clipboard for all lect-encoded settings, content, blocks and items. It remaps the current language on paste, reports unmatched target fields, confirms replacement, and offers manual clipboard fallbacks when browser permissions are unavailable.
44a1bd1Automatic plugin tenant connection lets plugins declaring autoTenant complete CMS tenancy setup from the admin UI. A five-minute, hashed single-use ticket is bound to the registered HTTPS URL; only the plugin can redeem it once through /__cms/tenant/claim for its pairwise secret.
e4f4245Feature-owned schema fragments assembles migrations from the SQL fragments beside each feature, with tests that verify every supported profile can execute and be removed without breaking the rest of the Worker.
2026‑07‑23
4 commits · richer fields, drag sorting and resilient plugin localization
The structured editor gains reusable field choices for uploads and scored responses, while item order can now be rearranged directly with a drag handle. Rich text keeps its inline formatting reliable next to punctuation and CJK content, and plugins without translation catalogs no longer trigger missing-locale requests.
708ae42Reliable rich text and drag sorting preserves word joiners when converting Markdown so inline emphasis stays intact beside punctuation and CJK text. Client-rendered item groups now include accessible drag handles that update their existing weight fields before save.
98e022eFile, range and rating page fields adds reusable file, range and rating snippets. Files upload under /media/files/; ranges provide labelled discrete choices; ratings provide keyboard-accessible star choices with a no-JavaScript fallback.
4922f52Optional plugin navigation locales keeps manifest labels intact for plugins that do not opt into i18n, rather than looking up translation keys which do not exist.
5da8296Opt-in plugin locale requests passes the manifest i18n setting through plugin client views, so locale JSON is fetched only from plugins that provide a catalog.
2026‑07‑22
1 commit · safer local plugin previews
Plugin pages served from a local CMS can now show images from a local development server, without relaxing the production policy.
c4dde2bLocal plugin image CSP builds the full-document plugin img-src policy from the current CMS URL. Only localhost and 127.0.0.1 CMS pages permit loopback HTTP images; production retains the stricter 'self' data: https: policy.
2026‑07‑21
2 commits · faster media previews and dependency maintenance
Media pickers now generate compact previews at the edge without exposing the private media bucket. The new path keeps the existing safety behaviour and reliably serves the original file whenever a thumbnail cannot be made.
2c3bec6Images-bound media thumbnails changes /media-preview/* to create cached 100×100 WebP cover thumbnails from private R2 objects through the Cloudflare Images binding. Missing bindings or objects, non-image and oversized files, and decode failures safely fall back to the original object while retaining media security headers.
46d92ebDependency lock refresh updates package-lock.json to keep the resolved package set current.
2026‑07‑19
4 commits · Markdown rich-text editing and client build maintenance
Content authors now have a richer Markdown workflow in the page editor. The new field keeps rich text, Markdown and stored HTML in sync, while the supporting client bundle and dependencies have been documented and streamlined.
9f1548eMarkdown rich-text editor adds the richtext/md page field with synchronized rich-text, Markdown and HTML modes. The default page and block body fields now use it, with bundled client assets, translated controls and safe restoration of previously double-escaped HTML.
9cd2f10Clearer Markdown editing switches the dark Markdown textarea to white text for better contrast and readability.
319f203Documented client bundling documents the esbuild pipeline for rich-text browser code and updates the Worker tooling dependencies.
4a59337Lean internal API surface removes unused admin, role and publishing exports without changing runtime behaviour.
2026‑07‑18
4 commits · plugin setup helpers, localized fields and consolidated schema
Plugin operators can now copy their registration secret and tenant KV connection values straight from the CMS, with clear temporary success feedback. The release also makes shared page-field snippets translation-aware and consolidates credit subscriptions into the initial CMS schema.
b271f8eTenant KV setup helpers adds copyable Tenant KV key/value details beside each plugin's shared secret, making Worker configuration faster and less error-prone.
63a300fCopy success feedback gives plugin-form copy buttons a localized Copied! state, Clipboard API support and a textarea fallback.
3c8ef68Localized page-field snippets lets text, email, number, textarea, picture, select and switch fields resolve translated labels, placeholders and option labels through i18n keys while retaining plain-text fallbacks.
e297eaaConsolidated credit-subscription schema folds credit_subscriptions into 0001_initial_schema.sql, leaving a single baseline migration for new CMS installs.
2026‑07‑17
18 commits · recurring credits, localized administration, bulk workflows and deployment hardening
Expanded the CMS into a more international, subscription-ready platform: admins can work in their chosen language and timezone, plugins can bill recurring credits, and configuration- or plugin-owned page types can be safely extended without changing their base definitions. This release also tightens the Worker’s rendering and request boundaries and improves the installation path.
6932e40Recurring plugin credits and type extensions adds credit_subscriptions, scheduled advance/arrears billing, ledger integration, and Plugin API subscription/usage endpoints. Admins can also append blocks and taxonomies to configuration- or plugin-defined page types while their owned definitions remain protected.
f77e725Localized admin and timezone settings localizes the admin UI with database-backed locale overrides, makes the system timezone configurable, and carries the selected locale consistently through admin, auth, profile and settings flows.
25f30ccLocalized plugin management brings plugin assets, credits, limits and page-type management into the same translated admin experience.
0ab2945Profile language selector adds a compact language control to the admin profile menu, retaining the locale across return paths and logout.
dfdc453Sharper editor and dashboard workflows improves responsive dashboard/plugin actions and editor layouts, with clearer translated controls and page-reference behaviour.
431709eReliable privacy controls keeps privacy toggles correctly positioned in scrollable admin tables and moves recurring-credit migration coverage into the current schema path.
927432aSafer rendering and origin configuration hardens rendered and proxied plugin content, while making canonical-origin enforcement opt-in for deployments that require it.
9e78ac2Auth and SSRF hardening strengthens authentication and server-side request checks with expanded security regression coverage.
d00661aInteractive Cloudflare setup adds an installation script to guide Cloudflare configuration; a6ba4e8, bc4498a and 6b8c4dc refresh dependencies, client rendering and migration-contract coverage.
f8407feBulk dashboard editing and richer translation tools adds selectable page rows and bulk actions, page-type filtering, a searchable parent-tag picker, and translation management that compares bundled locale values with database overrides.
bacbe74Reliable bulk search types resolves page types directly from D1 for dashboard bulk advanced searches, including types no longer present in the active blueprint; 6e4876b localizes the related confirmation dialogs.
31f2aa4Cleaner trash and tag actions moves page-type context into linked trash-list badges and replaces the tag table's text edit link with an accessible icon action.
2026‑07‑16 · security review
pre-open-source hardening
Completed a code-level review of authentication, authorization, plugins, structured input, response caching, and dependencies before the host-source announcement. The fixes are covered by regression tests; this is a security review, not a certification or substitute for an independent penetration test.
- ✓Delegation boundaries prevent user and role managers from granting or assigning authority beyond their own, and draft/search/trash reads now require an appropriate content capability.
- ✓Dedicated Plugin API credentials make
/__cms fail closed for legacy rows without a row secret; the global fallback is never accepted inbound.
- ✓Apple identity verification now checks the RS256 signature, JWK
kid, issuer, audience, expiry, and OAuth nonce.
- ✓Hostile-input hardening rejects malformed or oversized plugin manifests and removes prototype-mutating keys from plugin config and stored lect JSON.
- ✓Verification completed with 535 tests, a clean TypeScript check, and zero known npm advisories in both production and complete dependency trees.
Remaining trust boundary: proxied plugin pages and approved plugin JavaScript run on the CMS origin. Install only audited plugins and grant the minimum assets and delegated scopes required.
2026‑07‑16
7 commits · language administration, credit visibility and durable form protection
Added a runtime language and translation administration surface, made plugin pricing and limits easier for every admin to inspect, and strengthened request consistency and duplicate-submit handling across the Worker.
6479917Language and translation administration adds /admin/settings/languages and /admin/settings/translations for managing locales, fallback order, content/UI enablement, and database-backed translation overrides. It also tightens admin and Plugin API authorization checks.
5aefef7Credit summary adds a read-only /admin/settings/credits overview of enabled plugin charges, effective prices and usage limits.
78c568fLimits at a glance expands that summary with effective quota limits and scopes, and lets all signed-in admins view it while showing configuration links only to plugin managers.
4c33c6bDurable duplicate-submit protection moves single-use _cms_once form-token claims from D1 to sharded Durable Objects, serializing matching submissions without D1 contention and retaining safe retry release behavior.
5a976daConsistent D1 request sessions starts each Worker request, queue job and scheduled task on a primary D1 session so later reads can observe earlier writes while safely using current replicas.
2eeaaf4Simpler fresh installs folds the migration history into complete initial private and published schemas, making a new 0xCMS database setup a single baseline step.
0824f92Plugin registration guidance refreshes runtime plugin registration configuration and documentation, including the distinct inbound and outbound secret boundaries.
2026‑07‑16
3 commits · batch publishing, duplicate-submit protection and dashboard navigation
Added a scoped bulk-publish operation to the Plugin API, protected admin POST forms from accidental replay,
and made the configured CMS brand a direct link back to the admin dashboard.
a30d577Plugin batch publish API adds POST /__cms/pages/publish for up to 100 draft page IDs. It enforces plugin authentication and page-type scope, rejects invalid or duplicate IDs, returns per-item publish errors including partial target failures, and emits publish hooks through the existing pipeline.
25288c2Single-use admin submit tokens signs per-form _cms_once tokens and atomically claims them in D1, preventing duplicate POSTs from double-clicks, resubmits and retries while releasing a claim when downstream work fails. It also preserves return_to on publish and unpublish actions.
229df8eLinked admin branding makes the configured site title and icon in desktop and mobile admin navigation link directly to /admin.
2026‑07‑14
13 commits · Plugin API scale, unified type admin, import/export plugins, media and credits
Made large Plugin API lookups safe within D1 bind limits, unified page/block type administration and plugin page creation,
and moved CSV tools into a dedicated import-export plugin. Also added a permission-controlled media content list with
page-reference links, kept Pages navigation stable for custom admin homes, and expanded plugin capabilities and credits.
d1c302bScalable Plugin API lookups binds page IDs and slugs as JSON arrays through json_each(?), so large ids/slugs lookups and include_tags=1 lists stay below D1’s 100-parameter limit.
c5f2adcUnified type administration and creation consolidates page-type and block-type CRUD into shared type-admin routes and views, while single and batch Plugin API page creation now use one validated flow for parent/ID resolution, limits, credits, writes and hooks.
07a281cImport/export plugin foundation moves built-in CSV tools into a dedicated plugin and expands the Plugin API with content metadata, tag ensuring and bulk lookup support for import/export workflows.
5c8b636Dictionary build cleanup removes the obsolete Chinese-character dictionary generation script, leaving the existing generated search data in place without an unused network-dependent build step.
c4d7b8dMedia content list adds the permission-controlled /admin/settings/content page, listing R2 media objects with metadata, cursor pagination, and links to the draft pages that reference each file.
7aa8badStable Pages navigation keeps the Pages sidebar entry available when a custom admin home is configured, so users can always return to the content list from the admin navigation.
e6993f6Plugin taxonomy discovery adds contentTypes.taxonomies to the plugin page-types screen, showing defined page types, taxonomies and delegated access in separate sections with links and test coverage.
36a1e62Plugin-defined page types exposes contentTypes.blueprint alongside delegated read/write scopes, so the admin clearly separates page types defined by a plugin from its requested access.
3f662bdGeneralized submission ingest treats any live-only page as a submission mirror, adds a dedicated submission hook, and protects mirror history from publish and unpublish operations without relying on hard-coded page types.
e6e8e1cReliable plugin navigation keeps plugin sidebar items active across deep routes and page-edit return flows, and scrolls the active item into view when the mobile menu opens.
98d10e4Concurrent refresh grace accepts recently rotated refresh tokens for a short grace window, preventing parallel admin requests from being incorrectly revoked while preserving expiry checks.
a80c19cOptional live page status adds include_live_status=1 to /pages and /pages/:id, returning isPublished without extra requests.
a5bad97Shared credit pool and transfers adds a site-wide credit pool that can cover shortfalls, accept user donations and admin adjustments, support permissioned grants and user-to-user transfers, and report pool balances through the credit API.
2026‑07‑13
3 commits · bulk Plugin API writes, operational limits and publish projections
Expanded plugin operations with transactional bulk page updates and per-second limits, and added owner-defined
publish-time lect projections so live content can be minimized consistently across all publishing targets.
6bff14aPublish-time lect projections adds plugin-defined contentTypes.publishLect rules during snapshot builds, enforces blueprint ownership, and applies the matching draft projection to live-versus-draft comparisons so projected page types do not show false permanent drift.
b7f6cb9Per-second plugin limits adds the per_second operational limit scope, with optional page_type, updated normalization and admin messaging, and no CMS usage counting for that plugin-enforced limit.
9c70291Bulk Plugin API page updates introduces PATCH /pages/batch for transactional plugin page-lect updates with version history and per-item errors, preallocates page and version IDs to reduce D1 subrequests, and extends batch tests and duplicate slug-family handling.
2026‑07‑12
5 commits · auto-republish, shared field assets and restore cleanup
Added plugin-declared auto-republish behavior for live plugin page types, made admin page fields more
reliable after client-side re-renders and plugin-view sanitization, and simplified legacy trash restore handling.
9347cf0Auto-publish PR merge merges the plugin page type auto-republish work from auto-publish-gpt into the main CMS history.
6640b8fAuto-republish plugin page types adds plugin-declared autoPublishTypes so eligible live plugin-owned pages republish automatically on save, avoids duplicate update hooks in that path, updates flash messaging, and covers republish plus draft-only behavior in route tests.
8f1995dShared page-ref asset moves the page reference combobox logic into /assets/page-ref.js, loads it from both layouts, removes the inline snippet script, and keeps editor actions visible with a sticky action row.
6a0009cShared picture field asset extracts picture preview and upload behavior into views/assets/picture-field.js so picture fields keep working after client-side rendering and sanitized plugin HTML.
1da7d48Legacy restore snapshot cleanup removes the old special-case restore path for trashed pages without preserved version history and updates the restore query helper comments to match current behavior.
2026‑07‑11
1 commit · tenant-aware plugin auth headers
Strengthened secret-authenticated plugin requests by carrying a normalized tenant identifier through
admin proxying, edit views, hooks, publish targets, and background jobs.
4012cd2Tenant-aware plugin auth headers propagates x-cms-tenant, centralizes auth header setup with pluginTenantId, and uses constant-time plugin write-back secret checks while adding coverage for CANONICAL_ORIGIN tenant behavior.
2026‑07‑10
2 commits · plugin navigation labels and API errors
Polished plugin-facing details by using plugin labels for single-item navigation entries and returning
clearer forbidden page type errors from the Plugin API.
ca7b693Single-item plugin nav labels uses each plugin's label when only one navigation item is registered, keeping admin sidebars easier to scan.
db5ba6fForbidden page type API errors gives Plugin API callers more specific feedback when a page type is outside their allowed scope.
2026‑07‑08
3 commits · hook batching, field projection and pointer indexes
Improved Plugin API performance and response shaping with batched plugin hooks, optional page field
projection, and indexed pointer filter queries.
7b4955eBatched plugin hooks and field projection reduces repeated hook work and lets Plugin API page responses include only requested fields.
27b7f82cms-api.ts follow-up tightens the Plugin API implementation after the field projection changes.
69cc5ffPointer filter indexes adds D1 indexes and query updates so pointer-based filters are faster under advanced search and Plugin API usage.
2026‑07‑07
13 commits · bulk operations, validation, RSVP ingestion and Plugin API naming
Expanded advanced search into a safer bulk operations surface with async admin jobs, batching,
lifecycle logging, and queue configuration. The same day also added page create validation,
RSVP submission ingestion, Plugin API naming cleanup, a mobile dropdown fix, and default-timezone
version timestamps.
dff9ffbPage create ID validation validates incoming IDs and parent references before creating pages through the Plugin API.
17c87f8Guest import confirm action revert removes the queued guest import confirmation path after review.
2a9fc6dQueued guest import confirm action originally routed guest import confirmation through the admin job queue.
1d18f7eBulk unpublish optimization improves bulk unpublish handling across D1, R2, and Worker publish adapters while adding lifecycle logging.
865de78Admin jobs queue for bulk operations enables the Worker queue configuration used by long-running bulk actions.
337b579All-scope bulk action fix makes all-results bulk actions ignore visible row selections so the requested scope is applied correctly.
4850329Batched advanced search bulk actions chunks bulk work into smaller admin job batches for more predictable processing.
a47960bAsync bulk search operations moves advanced search bulk actions onto admin jobs instead of doing all work during the request.
c046559Advanced search bulk actions adds bulk controls, search utilities, admin rendering support, styles, Liquid view updates, and route tests.
3622924RSVP submissions into draft pages ingests incoming RSVP submissions into draft page records with supporting indexes, admin routing, and tests.
5e6ee33Plugin API naming cleanup renames remaining F1 references across routes and tests so the plugin-facing API language is consistent.
6d7c93aPlugin config dropdown overflow fix keeps the configuration menu inside the mobile viewport.
3bc97d4Default-timezone version timestamps formats page version history using the configured timezone.
2026‑07‑06
9 commits · plugin search, scopes, credits & action UI
Expanded plugin-facing admin capabilities with advanced page search, wildcard page-type scopes,
custom update actions, user credit visibility, paginated credit history, and a cleaner plugin
action menu.
4fd73f0Advanced plugin page search gives plugins richer page lookup tools.
b0c1c8dUsers view refresh updates users.liquid after the account and credit UI changes.
32fd45bCustom version actions allows page updates to record a more specific version action.
d42f41fWildcard page-type scopes lets plugin permissions cover matching page-type families.
27ef9c9Sidebar credit balance shows the current user's credit balance in the admin sidebar.
acab94fPaginated credit history keeps profile credit logs manageable as usage grows.
552c578Plugin management view update refreshes plugins-manage.liquid after the action layout changes.
f1a0014Plugin action layout refactor reorganizes plugin management controls for clearer spacing and grouping.
8f378f3Grouped plugin action dropdown consolidates repeated plugin actions into a dropdown pattern.
2026‑07‑05
4 commits · plugin quotas, credit billing & branding
Added the first credit and quota controls around plugins: configurable quota limits, credit billing,
safer atomic credit updates, and a branded app icon on the login screen.
846d0a6Atomic credit updates uses RETURNING so credit changes can be applied and read back reliably.
6db3e38Credit billing system introduces the billing foundation for credit-backed plugin usage.
5ce3871Configurable plugin quotas adds quota limits that can be tuned per deployment.
bf29f50Branded login icon uses the app icon on the login page for a more consistent entry point.
2026‑07‑04
2 commits · admin home, purge controls & approved assets
Added more operator control over the admin experience: the home screen can now be configured,
destructive purge paths are gated more deliberately, and approved plugin assets are exposed
inside plugin-rendered edit views.
4f23d17Approved assets in edit views exposes approved plugin assets while rendering plugin-owned edit experiences.
b623e41Configurable admin home and purge gating lets admins choose the home destination while tightening access around purge actions.
2026‑07‑03
15 commits · plugin create views, taxonomies, settings & page history
A broad platform day for plugin-owned admin surfaces: create and read-only page views landed,
plugin taxonomies became first-class in admin, tags moved toward weighted taxonomy slugs,
system branding/sidebar settings arrived, and page version maintenance became safer.
dd2745aPlugin create views and tag filtering lets plugins own create forms while improving tag-based filters.
b50543fTaxonomy slug migration and batch reorder moves tags to taxonomy_slug and adds batch reordering.
0295564Tag weights and config taxonomy options adds ordering and configuration options for taxonomy-backed tags.
8f77447Branding and sidebar system settings exposes admin configuration for the site brand and sidebar behavior.
3f31690Admin sidebar menu settings adds management for sidebar menu configuration.
812dd33Plugin-defined taxonomies supports plugin-provided taxonomy definitions in admin.
9789741Page version deletion and cleanup adds maintenance tools for historical page versions.
2115037Draft ID preservation keeps draft IDs stable when publishing content to D1.
01bce75Editor sync and feature coverage adds tests around editor sync behavior and feature flows.
81407d6Plugin-rendered read-only views lets plugins render read-only page views.
ad4dcdaType admin and editor helpers refactors shared helpers for type administration and editor flows.
e2b5c51Plugin page-type access approvals adds an approval path for plugin access to page types.
8468f50Plugin asset revision queries fixes revision query handling for plugin assets.
fcad6b2Immutable plugin view assets serves plugin view files with immutable caching.
723b6a7Admin session keepalive keeps sessions alive while working in admin pages.
2026‑07‑02
7 commits · plugin assets, cache-busting & mobile admin
Tightened plugin-admin access, expanded the approved asset pipeline, added revision-aware cache
busting for admin and plugin assets, and improved the mobile admin header.
20f2594Auto-hiding mobile admin header improves mobile navigation behavior.
d51fe1dPlugin worker revision cache-busting uses plugin worker revisions to bust asset caches.
4b7e1caRevisioned admin assets adds revision handling for admin assets and plugin caching.
4ccdaa6Plugin camera and WASM opt-in lets plugins opt into camera and WASM security allowances.
1e86047Asset approval integrity adds integrity hashes to the plugin asset approval UI.
495584dApproved asset serving serves plugin assets after approval.
c5691eeManifest-gated plugin admin checks plugin admin access against manifest permissions.
2026‑07‑01
5 commits · live pages & multilingual search
Improved the editorial dashboard for live content: live-only pages can be pulled back into drafts,
listings query live pages directly, and search now understands Chinese variant text.
c0b498ePull-to-draft adds a draft recovery flow for live-only pages.
19e1788Live-page pagination queries live pages directly with paged results.
ca6f9caChinese variant search expands page search across character variants.
0c47a03Generated character maps replaces opencc-js.
8cd04b5Dashboard filters adds status filters and Chinese search.
2026‑06‑30
6 commits · plugin jobs, fields & trash restore
Rounded out plugin-driven admin workflows with queueable jobs, richer form-field rendering,
fixed pagefield snippet resolution, and filtered bulk restore for trash.
ff6905cClient render update refreshes the client-rendered admin layer.
2de6739leading-relaxed utility adds the text utility to admin styles.
6c6007dPagefield snippet paths fixes view-base resolution.
2330c63Form field templates adds templates and required-field support.
12ed982Queueable plugin jobs lets plugin actions schedule admin jobs.
1d116d1Filtered bulk restore restores trash items scoped by filters.
2026‑06‑29
16 commits · table tooling, privacy & bulk operations
A broad admin polish day: collection-aware bulk actions, page duplication, table filtering,
privacy masking, color labels, and several missing utility classes for the CMS shell.
803c050Pointer-based collection selection improves bulk-operation targeting.
8a4ad16Bulk page duplication adds the duplication API endpoint.
a3a95c7Color picker and delete confirms refines label interactions and prompts.
39e5c03Null page_id coercion fixes CMS API handling.
9e2ed54Nested event session test adds regression coverage.
466d709Duplicate icon asset adds the icon used by duplication actions.
a6dffddColor tag picker introduces the color-label picker feature.
c659093Name masking handles middle-dot names and Latin tokens more cleanly.
7f32612Privacy table masking refines table-level masking.
112a58ePII field masking adds masking for sensitive table fields.
f0cda7fAuth provider loading shows feedback while selecting a provider.
bb0fba5iOS form zoom fix prevents mobile zoom on admin forms.
f553189Table filters adds the table-filter asset and integration.
5e37123Width and truncation utilities fills missing layout classes.
0a62e00Spacing and layout utilities expands admin utility coverage.
2b72cdeTailwind utility coverage adds missing classes used by views.
2026‑06‑28
9 commits · profile, users & OAuth
Added the admin profile surface and rounded out account-linking controls, Microsoft OAuth, user
deletion safeguards, and identity-provider visibility.
0e5d83cScoped client template cache isolates cached templates by view base path.
62b7a8bIdentity providers in user list shows linked providers in admin users.
de926c1Apple provider disabled removes Apple from enabled providers.
51114afUser deletion safeguards adds protected admin user deletion.
831da67Microsoft OAuth config enables Microsoft OAuth settings.
c4c239eAdmin form actions polishes form footer actions.
94c0abdOAuth disconnect adds profile support for disconnecting providers.
e30596fExplicit account linking requires link=1 for OAuth linking.
bb19ae0Admin profile page adds the profile view.
2026‑06‑27
7 commits · OAuth, actions & plugin hardening
Focused on authentication breadth and plugin-admin hardening, including multi-provider identity
linking, unified icon actions, sanitized plugin HTML, and iframe isolation experiments.
0db7f95Microsoft and Apple OAuth adds support for additional providers.
426e4c4Multi-provider identity linking links multiple OAuth identities to one account.
075cc02Unified action buttons standardizes admin action buttons with icon variants.
3da2ca1Security and client views hardens plugin client-rendered views.
c3a2d14Plugin HTML sanitization prevents XSS in plugin-admin HTML.
0b10a9fIframe isolation revert reverts the sandboxed iframe isolation change.
221ca0fSandboxed iframe isolation initially isolates plugin admin views.
2026‑06‑26
16 commits · client rendering, permissions & responsive admin
Shifted core views toward client rendering, externalized the SVG sprite, strengthened plugin
permissions, and improved cache behavior, mobile navigation, table layout, and page-store utilities.
6cd16f7Admin API and plugin access hardens permission checks.
0fefa60Dependency cleanup removes emmet and liquidjs.
13de3faSecurity helpers and media routes refactors shared code.
aee9befPage-store utilities extracts helpers and adds withLiveStatus.
639488cEmpty pointer values preserves empty pointers instead of deleting them.
5529676Dashboard table positioning adds relative positioning.
f7843cdPlugin-defined permissions exposes plugin permissions in roles/admin.
0c63fb3Mobile sidebar nav updates the sidebar to a full-page menu.
b450994View revision cache-busting adds revision-aware view caching.
088468dLoading and cache headers fixes placeholders and cache headers.
eca65ecReactive reorder rows keeps reorderable rows reactive to DOM changes.
bf81d6aDefault layout update refreshes default.liquid.
580574cClient-rendered views switches admin views and adds proxies.
8428fdf0xCMS site title renames the site title.
62b430bExternal SVG sprite serves icons through a sprite.
7029cabTable container styles standardizes table containers and widths.
2026‑06‑25
16 commits · batching, trash & UI
Massive progress on administrative efficiency: introduced batch operations for page weights and
deletions, overhauled the trash system with pagination and granular purging, and added a
comprehensive light theme for the admin UI.
16fc14f
Bulk Page Weight Updates
Added POST /admin/pages/batch-weight to apply bulk weight updates using
DB batch commits. Includes strict input validation and optimized prepared statements to
minimize round-trips.
69927c5
Drag-and-Drop Row Reordering
Injected client-side logic to enable drag-and-drop reordering for any table with data-reorder.
Automatically posts new ordering sequences to the backend via fetch.
09ec980
Enhanced Trash Management
The trash view now supports type-based filtering, item counts, and granular purge options
(e.g., purge only items trashed in the last hour).
f1c154c
Batch Soft-Delete for Pages
Introduced DELETE /pages/batch to move multiple draft pages to trash
in a single D1 transaction, significantly reducing API overhead for bulk cleanup.
ca5b6c8
Admin Light Theme
Added a full light theme stylesheet using CSS custom properties, ensuring a high-contrast,
conventional Tailwind aesthetic as an alternative to the default dark mode.
44b43cc
Batch Page Creation
Optimized page creation with bulk D1 inserts and unique slug allocation within a single batch,
capped at 100 items per request for stability.
Additional 2026‑06‑25 commits
915f714Add batch page-weight endpoint and tests.
991d77cUpdate admin.css.
57ae3f3Add pagination and empty-all action to trash.
1a17419Update cms-api.ts.
623a270Update cms-api.ts.
6b740d8Preserve plugin redirects and clean empty pointers.
589aefdAdd blockNamesFor and boolean field snippet.
13a08feUpdate routes.test.ts.
d34d691Show plugin block types and settings nav.
a6dcd7fShow Lect JSON diff in editor previews.
2026‑06‑24
7 commits · plugin editing & APIs
Earlier in the cycle: a native-editor escape hatch, opt-in same-origin framing for plugins,
a richer pages API, and plugin edit-view support.
73c2f62?native=1 editor bypass — documented the query flag and added tests confirming the built-in editor is served and the flag survives form actions and redirects.
8afddb2Native-editor escape hatch — ?native=1 / ?editor=cms forces the built-in CMS editor even when a plugin would render the edit view; preferNativeEditor + withNativeFlag thread it through action URLs.
e02ec18datetime.liquid — new page-field snippet.
4ae4f64/api/pages/:type enhanced with search and id lookup.
6393900Opt-in same-origin framing for plugins.
4d7c8f2Plugin edit view support added.
93505b6Preserve editor return_to across pages.
2026‑06‑23
16 commits · plugins, schemas & trash history
Turned the plugin system into a managed platform with DB-backed registration, per-plugin secrets,
plugin-contributed page types, navigation, read APIs, write-back support, and richer timezone/schema foundations.
95b6eafExtend schema: timezones, trash versions, plugins.
91b4f86Add page timezone support.
e9502c9Set defaultLanguage to 'mis' and add locales.
034ca0cAdd basic switch pagefield snippet.
779b8a4Remove dump test; conditionally render table header.
85128a3Add test that dumps admin HTML.
b5ecfe0Support plugin readTypes and show plugin names.
db35601Preserve original parent for trashed pages.
078a0d9Decode percent-encoded plugin titles.
21dd862Update plugins.ts.
2c13f49Add per-plugin secret and rotation support.
3dcccd2Add plugin write-back API and trash support.
6caef21Support plugin nav in admin layout.
ca73d5fSupport plugin-contributed page types in admin.
c4816caAdd PLUGIN_SECRET to .dev.vars.example.
6405277Add DB-backed plugin registry and admin UI.
2026‑06‑22
14 commits · permissions, layout helpers & editor scope
Added role and user administration, made admin UI permission-aware, reduced route rendering boilerplate,
and refined editor language scope, taxonomy fallback, and structured editor controls.
3241a8eReplace inline weight form with read-only view.
438cd24Create basic.liquid.
a69351dRedirect to edit with language; scope editor form.
3189919Update CMS config and regenerate admin CSS.
15330d3Update routes.test.ts.
6a2474bRemove revert button and update taxonomy fallback.
6417922Merge pull request #5 from LionRockJS/refactor/reduce-boilerplate.
71290feAdd renderPage helper to cut route render boilerplate.
1c1ff3fAdd adminLayout helper to cut template boilerplate.
c93a50eMake admin UI permission-aware.
9153280Add separate tag:write permission.
54925e8Add input bg class in editor and regenerate admin CSS.
0f23bc7Compact weight inputs in structured editor.
20261ccAdd roles/users admin and permission system.
2026‑06‑21
5 commits · database-defined content model
Moved more content configuration into the database with page types, block types, renamed taxonomies,
unique draft slugs, cache fixes, and regenerated admin utility styles.
8a2a407Add DB-backed block types and admin UI.
c602735Rename tag_types and tag_lists to taxonomies.
2d53bfdEnsure unique draft slugs; cache and lect fixes.
d01f7b0Add database-defined page types and admin UI.
ad31713Regenerate admin.css Tailwind utilities.
2026‑06‑20
2 commits · publish adapter merge
Brought the publish-adapter branch into the mainline and added example plugin publish targets with tests.
001de3cMerge branch publish-adapters.
c1d96b7Add example publish plugins and tests.
2026‑06‑12
2 commits · pluggable publish targets
Added the publish-target architecture, including D1, R2, and plugin fan-out paths.
ab15ce8Merge pull request #4 from LionRockJS/publish-adapters.
1d350adAdd pluggable publish targets: d1, r2, plugin.
2026‑06‑11
2 commits · editor metadata & presence cleanup
Improved editor metadata display, safer lect parsing, and simplified presence storage behavior.
dccc8afDisplay modifier name and safely parse lect.
12c93daRemove presence table; add avatar fallback.
2026‑06‑10
11 commits · security hardening
A security-heavy day: stricter CSP and JWT claims, fail-closed CSRF, hardened cookies, upload protections,
rate limiting, registration controls, audit logging, and plugin proxy safeguards.
e7641d9Add presence handling to PageSync DO and routes.
0e47957Merge pull request #3 from LionRockJS/security-hardening.
78e2891Enforce sensitive cache headers and plugin secret.
d941293Resolve P3: capability-based RBAC and plugin shared-origin mitigation.
9f3b9c0Merge pull request #2 from LionRockJS/security-hardening.
1fc713bSession hygiene, registration allowlist, audit logging.
80b3cd9Plugin proxy header allowlist, CSV filename encoding, presence validation.
7f5397dFail-closed CSRF checks, __Host- auth cookies, POST-only logout.
8b20692Strict CSP with local Tailwind build and per-request nonces; JWT issuer/audience.
7601059Add IP-keyed rate limiting to auth and upload endpoints.
10336e1Harden media upload and serving against stored XSS.
2026‑06‑09
9 commits · CRDT collaboration, presence & plugins
Added the collaborative editing foundation with PageSync, CRDT operations, WebSocket attachment,
presence tracking, multi-user tests, plugin integration, and modular admin route organization.
3b27d05Sanitize WebSocket fields and omit avatar relay.
99c3d7eAdd PageSync multi-user tests; relax editor.
2d4cdfcCRDT: per-user ops, reset and save handling.
151951cImprove CRDT sync, WebSocket attachment, and presence interval.
e4c9b20Update editor.liquid.
83e1fe0Add PageSync DO and editor CRDT sync.
6642664Add presence tracking: DB, API, UI.
bf3850cAdd plugin system and integrate plugins.
bfb92b5Refactor admin into modular routes and utilities.
2026‑06‑08
1 commit · published DB isolation
Split published content into its own D1 database so public readers can be isolated from draft/admin data.
0dd60f3Split published content into separate D1 DB.
2026‑06‑07
6 commits · CSV import/export & dashboard scale
Expanded operational content management with localized CSV import/export, draft exports,
lect-derived fields, dashboard pagination, import shortcuts, and batched lookups.
31f03deAdd bulk CSV import and batched lookups.
27c134cAdd CSV import links to admin dashboard.
6e4d3b0Add pagination to admin dashboard.
b8a1f02Include lect-derived fields in CSV exports.
dde2e0dAdd CSV export for draft pages.
e10bb9aSupport localized CSV import/export.
2026‑06‑06
6 commits · CSV workflows & editor references
Added CSV import modes, preview/confirmation flow, import/export foundations, parent-page APIs,
dynamic editor comboboxes, and advanced-search blueprint options.
85a7752Add CSV import modes and UI options.
561c2edAdd CSV import preview and confirmation flow.
43ae6c3Update dashboard.liquid.
34c308bAdd parent-pages API and dynamic editor combobox.
da29d3cAdd CSV import/export and parent combobox.
7e5d1faAdd blueprint path options for advanced search.
2026‑06‑05
5 commits · advanced search
Built the advanced-search surface with multi-type criteria, locked page-type routes,
dashboard search, and redirect behavior from admin searches.
603d6b5Redirect admin searches to advanced-search.
2fb2cbbAdd dashboard search and lock advanced-search type.
6feaccaUse path param for advanced-search page type.
55cbb73Advanced search: multi-type and dynamic criteria.
1ae0fb7Add advanced search feature and UI tweaks.
2026‑06‑04
11 commits · media, structured editor & initial schema
Added private R2 media uploads, Cloudflare image previews, error response cleanup, draft metadata,
initial schema consolidation, item weights, and structured-editor improvements.
4093cbbServe thumbnails via /media-preview with resize.
d8e97c8Add Cloudflare image preview and upload guidance.
aed7522Add X-CMS-Error header to error responses.
b9a137cReturn JSON for forbidden admin/api requests.
7f1fa8bReturn JSON for admin upload auth errors.
64f27b4Add private R2 media uploads and tests.
b3906f2Add draft metadata to created/merged lects.
0e8101bConsolidate migrations into initial schema.
02444c6Add page creator and editors metadata.
f1c58e1Add implicit item weights and sort items.
90231e6Structured editor: block attrs, tags, live-diff.
2026‑06‑03
23 commits · admin views, lect migration & mobile UI
A large admin build-out: responsive templates, Liquid/JSON view experiments, editor and tag parity,
lect migration, version-table unification, CSP/referer fixes, and package updates.
9257a97Respect secure cookies; UI/accessibility tweaks.
c09dbb3Add package-lock and update package.json.
d1e1f00Delete package-lock.json.
642c768Update package-lock.json.
6e7d5cfUpdate dashboard.liquid.
fbcb905Update dashboard.liquid.
64fd421Make admin UI responsive and mobile-friendly.
9ca0b0bSwitch from Liquid to JSON template views.
71091a5Add JSON template rendering and Emmet integration.
932cbf7Load Liquid templates via VIEWS fetcher.
413ee79Use LiquidJS templates for admin views.
767988bUpdate index.ts.
40b0b40Refactor tag admin routes to use page components.
a7d6277Add admin templates and editor improvements.
9eee329Update auth.ts.
248e1ccUnify page version tables into page_versions.
67ada5bMigrate original structured content to lect.
93a9dd5Update editor.ts.
b0d1e10Show default-language value as placeholder.
ddc57afAdd favicon route; fix editor URL and CSP.
74d1da1Update editor.ts.
fb45883Add page-type datalist and referer checks.
f775ce1Add admin CMS parity: originals, tags, media.
2026‑06‑02
4 commits · database bindings & roles
Consolidated content database bindings, supported comma-separated roles, and expanded origin checks.
f6d4794Support allowed origins in security checks.
0f66f41Consolidate D1 databases into single DB binding.
fc9db3dUnify content DB into single CONTENT_DB.
5937543Support comma-separated user roles and utilities.
2026‑06‑01
1 commit · OAuth and headers
Added multi-provider OAuth support and security headers.
dc62ba2Support multi-provider OAuth and security headers.
2026‑05‑30
9 commits · auth, trash & dependencies
Established the early auth/data split with AUTH_DB, trash workflow, Eventuai OAuth integration,
dependency upgrades, config updates, and the repository root commit.
25adf0aUpdate wrangler.toml.
4fd286cUpdate login.ts.
ca123a2Add Eventuai OAuth provider and role sync.
565df36Upgrade esbuild, TypeScript, Wrangler, and Hono.
5993d38Add cms-trash DB and update AUTH_DB id.
372e5a5Add AUTH_DB and move auth data off LIVE.
93b3909Add trash soft-delete workflow.
c415a99Merge pull request #1 from LionRockJS/copilot/create-database-migration-for-content.
409f105Initial commit.
2026‑05‑29
2 commits · first CMS plan and Worker implementation
Started the project with the initial implementation plan and the first Cloudflare Worker CMS scaffold:
OAuth 2.1, dual JWTs, and live/draft database workflow.
505b671Add Cloudflare Worker CMS with OAuth 2.1, dual JWT, and LIVE/DRAFT database workflow.
f53cdcbInitial plan.
Generated from the 0xCMS Worker commit log · last updated 2026‑07‑26